diff options
author | Adam <Adam@anope.org> | 2012-11-22 00:50:33 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2012-11-22 00:50:33 -0500 |
commit | d33a0f75a5c0c584fbb7cc0076da36d494f39494 (patch) | |
tree | 7b2274cc833c793c0f5595660cbd4d715de52ffd /src | |
parent | 368d469631763e9c8bf399980d0ac7c5b5664d39 (diff) |
Pretty large coding style cleanup, in source doc
cleanup, and allow protocol mods to depend on each
other
Diffstat (limited to 'src')
51 files changed, 2815 insertions, 3888 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f1f383397..b9d58f367 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,7 +119,6 @@ add_to_cpack_ignored_files("${SERVICES_BINARY}$" TRUE) configure_file(${Anope_SOURCE_DIR}/include/sysconf.h.cmake ${Anope_BINARY_DIR}/include/sysconf.h) # Go into the following directories and run their CMakeLists.txt as well -add_subdirectory(bin) add_subdirectory(tools) # Set Anope to be installed to the bin directory diff --git a/src/access.cpp b/src/access.cpp index 6b22ba871..863e0d41d 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "service.h" @@ -24,27 +25,27 @@ bool Privilege::operator==(const Privilege &other) const return this->name == other.name; } -std::vector<Privilege> PrivilegeManager::privs; +std::vector<Privilege> PrivilegeManager::Privileges; void PrivilegeManager::AddPrivilege(Privilege p) { unsigned i; - for (i = 0; i < privs.size(); ++i) + for (i = 0; i < Privileges.size(); ++i) { - Privilege &priv = privs[i]; + Privilege &priv = Privileges[i]; if (priv.rank > p.rank) break; } - privs.insert(privs.begin() + i, p); + Privileges.insert(Privileges.begin() + i, p); } void PrivilegeManager::RemovePrivilege(Privilege &p) { - std::vector<Privilege>::iterator it = std::find(privs.begin(), privs.end(), p); - if (it != privs.end()) - privs.erase(it); + std::vector<Privilege>::iterator it = std::find(Privileges.begin(), Privileges.end(), p); + if (it != Privileges.end()) + Privileges.erase(it); for (registered_channel_map::const_iterator cit = RegisteredChannelList->begin(), cit_end = RegisteredChannelList->end(); cit != cit_end; ++cit) { @@ -55,39 +56,39 @@ void PrivilegeManager::RemovePrivilege(Privilege &p) Privilege *PrivilegeManager::FindPrivilege(const Anope::string &name) { - for (unsigned i = privs.size(); i > 0; --i) - if (privs[i - 1].name.equals_ci(name)) - return &privs[i - 1]; + for (unsigned i = Privileges.size(); i > 0; --i) + if (Privileges[i - 1].name.equals_ci(name)) + return &Privileges[i - 1]; return NULL; } std::vector<Privilege> &PrivilegeManager::GetPrivileges() { - return privs; + return Privileges; } void PrivilegeManager::ClearPrivileges() { - privs.clear(); + Privileges.clear(); } AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service(o, "AccessProvider", n) { - providers.push_back(this); + Providers.push_back(this); } AccessProvider::~AccessProvider() { - std::list<AccessProvider *>::iterator it = std::find(providers.begin(), providers.end(), this); - if (it != providers.end()) - providers.erase(it); + std::list<AccessProvider *>::iterator it = std::find(Providers.begin(), Providers.end(), this); + if (it != Providers.end()) + Providers.erase(it); } -std::list<AccessProvider *> AccessProvider::providers; +std::list<AccessProvider *> AccessProvider::Providers; const std::list<AccessProvider *>& AccessProvider::GetProviders() { - return providers; + return Providers; } ChanAccess::ChanAccess(AccessProvider *p) : Serializable("ChanAccess"), provider(p) @@ -98,7 +99,7 @@ ChanAccess::~ChanAccess() { } -Serialize::Data ChanAccess::serialize() const +Serialize::Data ChanAccess::Serialize() const { Serialize::Data data; @@ -106,17 +107,17 @@ Serialize::Data ChanAccess::serialize() const data["ci"] << this->ci->name; data["mask"] << this->mask; data["creator"] << this->creator; - data["last_seen"].setType(Serialize::DT_INT) << this->last_seen; - data["created"].setType(Serialize::DT_INT) << this->created; - data["data"] << this->Serialize(); + data["last_seen"].SetType(Serialize::DT_INT) << this->last_seen; + data["created"].SetType(Serialize::DT_INT) << this->created; + data["data"] << this->AccessSerialize(); return data; } -Serializable* ChanAccess::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data) { - service_reference<AccessProvider> aprovider("AccessProvider", data["provider"].astr()); - ChannelInfo *ci = cs_findchan(data["ci"].astr()); + ServiceReference<AccessProvider> aprovider("AccessProvider", data["provider"].astr()); + ChannelInfo *ci = ChannelInfo::Find(data["ci"].astr()); if (!aprovider || !ci) return NULL; @@ -130,7 +131,7 @@ Serializable* ChanAccess::unserialize(Serializable *obj, Serialize::Data &data) data["creator"] >> access->creator; data["last_seen"] >> access->last_seen; data["created"] >> access->created; - access->Unserialize(data["data"].astr()); + access->AccessUnserialize(data["data"].astr()); if (!obj) ci->AddAccess(access); @@ -145,7 +146,7 @@ bool ChanAccess::Matches(const User *u, const NickCore *nc) const else if (u && Anope::Match(u->GetDisplayedMask(), this->mask)) return true; else if (nc) - for (std::list<serialize_obj<NickAlias> >::const_iterator it = nc->aliases.begin(); it != nc->aliases.end();) + for (std::list<Serialize::Reference<NickAlias> >::const_iterator it = nc->aliases.begin(); it != nc->aliases.end();) { const NickAlias *na = *it++; if (na && Anope::Match(na->nick, this->mask)) @@ -234,16 +235,16 @@ AccessGroup::AccessGroup() : std::vector<ChanAccess *>() { this->ci = NULL; this->nc = NULL; - this->SuperAdmin = this->Founder = false; + this->super_admin = this->founder = false; } bool AccessGroup::HasPriv(const Anope::string &name) const { - if (this->SuperAdmin) + if (this->super_admin) return true; else if (ci->GetLevel(name) == ACCESS_INVALID) return false; - else if (this->Founder) + else if (this->founder) return true; EventReturn MOD_RESULT; FOREACH_RESULT(I_OnGroupCheckPriv, OnGroupCheckPriv(this, name)); @@ -271,13 +272,13 @@ const ChanAccess *AccessGroup::Highest() const bool AccessGroup::operator>(const AccessGroup &other) const { - if (this->SuperAdmin) + if (this->super_admin) return true; - else if (other.SuperAdmin) + else if (other.super_admin) return false; - else if (this->Founder && !other.Founder) + else if (this->founder && !other.founder) return true; - else if (!this->Founder && other.Founder) + else if (!this->founder && other.founder) return false; const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); for (unsigned i = privs.size(); i > 0; --i) @@ -298,13 +299,13 @@ bool AccessGroup::operator>(const AccessGroup &other) const bool AccessGroup::operator<(const AccessGroup &other) const { - if (other.SuperAdmin) + if (other.super_admin) return true; - else if (this->SuperAdmin) + else if (this->super_admin) return false; - else if (other.Founder && !this->Founder) + else if (other.founder && !this->founder) return true; - else if (this->Founder && !other.Founder) + else if (this->founder && !other.founder) return false; const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); for (unsigned i = privs.size(); i > 0; --i) @@ -325,13 +326,13 @@ bool AccessGroup::operator<(const AccessGroup &other) const bool AccessGroup::operator>=(const AccessGroup &other) const { - if (this->SuperAdmin) + if (this->super_admin) return true; - else if (other.SuperAdmin) + else if (other.super_admin) return false; - else if (this->Founder) + else if (this->founder) return true; - else if (other.Founder) + else if (other.founder) return false; const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); for (unsigned i = privs.size(); i > 0; --i) @@ -352,13 +353,13 @@ bool AccessGroup::operator>=(const AccessGroup &other) const bool AccessGroup::operator<=(const AccessGroup &other) const { - if (other.SuperAdmin) + if (other.super_admin) return true; - else if (this->SuperAdmin) + else if (this->super_admin) return false; - else if (other.Founder) + else if (other.founder) return true; - else if (this->Founder) + else if (this->founder) return false; const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); for (unsigned i = privs.size(); i > 0; --i) diff --git a/src/account.cpp b/src/account.cpp new file mode 100644 index 000000000..b7dd5b51b --- /dev/null +++ b/src/account.cpp @@ -0,0 +1,80 @@ +/* + * + * (C) 2003-2012 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. + * + */ + +#include "services.h" +#include "account.h" +#include "modules.h" +#include "users.h" +#include "protocol.h" +#include "regchannel.h" + +std::set<IdentifyRequest *> IdentifyRequest::Requests; + +IdentifyRequest::IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass) : owner(o), account(acc), password(pass), dispatched(false), success(false) +{ + Requests.insert(this); +} + +IdentifyRequest::~IdentifyRequest() +{ + Requests.erase(this); +} + +void IdentifyRequest::Hold(Module *m) +{ + holds.insert(m); +} + +void IdentifyRequest::Release(Module *m) +{ + holds.erase(m); + if (holds.empty() && dispatched) + { + if (!success) + this->OnFail(); + delete this; + } +} + +void IdentifyRequest::Success(Module *m) +{ + if (!success) + { + this->OnSuccess(); + success = true; + } +} + +void IdentifyRequest::Dispatch() +{ + if (holds.empty()) + { + if (!success) + this->OnFail(); + delete this; + } + else + dispatched = true; +} + +void IdentifyRequest::ModuleUnload(Module *m) +{ + for (std::set<IdentifyRequest *>::iterator it = Requests.begin(), it_end = Requests.end(); it != it_end;) + { + IdentifyRequest *ir = *it; + ++it; + + ir->Release(m); + if (ir->owner == m) + delete ir; + } +} diff --git a/src/actions.cpp b/src/actions.cpp deleted file mode 100644 index 512a0fa52..000000000 --- a/src/actions.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* Various routines to perform simple actions. - * - * (C) 2003-2012 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. - */ - -#include "services.h" -#include "users.h" -#include "config.h" -#include "regchannel.h" -#include "channels.h" -#include "extern.h" - -/*************************************************************************/ - -/** - * Note a bad password attempt for the given user. If they've used up - * their limit, toss them off. - * @param u the User to check - * @return true if the user was killed, otherwise false - */ -bool bad_password(User *u) -{ - if (!u || !Config->BadPassLimit) - return false; - - if (Config->BadPassTimeout > 0 && u->invalid_pw_time > 0 && u->invalid_pw_time < Anope::CurTime - Config->BadPassTimeout) - u->invalid_pw_count = 0; - ++u->invalid_pw_count; - u->invalid_pw_time = Anope::CurTime; - if (u->invalid_pw_count >= Config->BadPassLimit) - { - u->Kill(Config->ServerName, "Too many invalid passwords"); - return true; - } - - return false; -} - -/*************************************************************************/ - - -/** - * Unban the user from a channel - * @param ci channel info for the channel - * @param u The user to unban - * @param full True to match against the users real host and IP - * @return void - */ -void common_unban(const ChannelInfo *ci, User *u, bool full) -{ - if (!u || !ci || !ci->c || !ci->c->HasMode(CMODE_BAN)) - return; - - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = ci->c->GetModeList(CMODE_BAN); - for (; bans.first != bans.second;) - { - Entry ban(CMODE_BAN, bans.first->second); - ++bans.first; - if (ban.Matches(u, full)) - ci->c->RemoveMode(NULL, CMODE_BAN, ban.GetMask()); - } -} - -/*************************************************************************/ diff --git a/src/base.cpp b/src/base.cpp index af2b38fde..5b8d828b6 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -1,20 +1,18 @@ -#include "services.h" -#include "modules.h" -#include "oper.h" -#include "account.h" -#include "regchannel.h" -#include "access.h" -#include "bots.h" +/* + * + * (C) 2003-2012 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + */ -std::map<Anope::string, std::map<Anope::string, Service *> > Service::services; +#include "services.h" +#include "anope.h" +#include "service.h" -void RegisterTypes() -{ - static SerializeType nc("NickCore", NickCore::unserialize), na("NickAlias", NickAlias::unserialize), bi("BotInfo", BotInfo::unserialize), - ci("ChannelInfo", ChannelInfo::unserialize), access("ChanAccess", ChanAccess::unserialize), logsetting("LogSetting", LogSetting::unserialize), - modelock("ModeLock", ModeLock::unserialize), akick("AutoKick", AutoKick::unserialize), badword("BadWord", BadWord::unserialize), - memo("Memo", Memo::unserialize), xline("XLine", XLine::unserialize); -} +std::map<Anope::string, std::map<Anope::string, Service *> > Service::Services; +std::map<Anope::string, std::map<Anope::string, Anope::string> > Service::Aliases; Base::Base() { @@ -22,19 +20,19 @@ Base::Base() Base::~Base() { - for (std::set<dynamic_reference_base *>::iterator it = this->References.begin(), it_end = this->References.end(); it != it_end; ++it) + for (std::set<ReferenceBase *>::iterator it = this->references.begin(), it_end = this->references.end(); it != it_end; ++it) { (*it)->Invalidate(); } } -void Base::AddReference(dynamic_reference_base *r) +void Base::AddReference(ReferenceBase *r) { - this->References.insert(r); + this->references.insert(r); } -void Base::DelReference(dynamic_reference_base *r) +void Base::DelReference(ReferenceBase *r) { - this->References.erase(r); + this->references.erase(r); } diff --git a/src/base64.cpp b/src/base64.cpp index df4189547..ae026d8ef 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt deleted file mode 100644 index d1cdb5d06..000000000 --- a/src/bin/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# If not on Windows, generate anoperc and install it along with mydbgen -if(NOT WIN32) - configure_file(${Anope_SOURCE_DIR}/src/bin/anoperc.in ${Anope_BINARY_DIR}/src/bin/anoperc) - install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/anoperc - DESTINATION ${BIN_DIR} - ) - -endif(NOT WIN32) diff --git a/src/bots.cpp b/src/bots.cpp index 7bb5ace5d..52753148f 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -1,8 +1,10 @@ /* + * * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org> * Copyright (C) 2008-2012 Anope Team <team@anope.org> * * Please read COPYING and README for further details. + * */ #include "services.h" @@ -10,17 +12,27 @@ #include "bots.h" #include "servers.h" #include "protocol.h" -#include "oper.h" +#include "xline.h" #include "regchannel.h" #include "channels.h" #include "config.h" #include "language.h" -#include "extern.h" #include "serialize.h" -serialize_checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo"); +Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo"); + +static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "CONF", "" }; +template<> const Anope::string* Flags<BotFlag>::flags_strings = BotFlagString; + +static const Anope::string BotServFlagStrings[] = { + "BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "GREET", "NOBOT", + "KICK_BOLDs", "KICK_COLORS", "KICK_REVERSES", "KICK_UNDERLINES", "KICK_BADWORDS", "KICK_CAPS", + "KICK_FLOOD", "KICK_REPEAT", "KICK_ITALICS", "KICK_AMSGS", "MSG_PRIVMSG", "MSG_NOTICE", + "MSG_NOTICEOPS", "" +}; +template<> const Anope::string* Flags<BotServFlag>::flags_strings = BotServFlagStrings; -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, "", ts6_uid_retrieve()), Flags<BotFlag, BI_END>(BotFlagString), 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"), botmodes(bmodes) { this->lastmsg = this->created = Anope::CurTime; this->introduced = false; @@ -32,13 +44,13 @@ BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const A // If we're synchronised with the uplink already, send the bot. if (Me && Me->IsSynced()) { - Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : (ircdproto ? ircdproto->DefaultPseudoclientModes : ""); + Anope::string tmodes = !this->botmodes.empty() ? ("+" + this->botmodes) : (IRCD ? IRCD->DefaultPseudoclientModes : ""); if (!tmodes.empty()) this->SetModesInternal(tmodes.c_str()); XLine x(this->nick, "Reserved for services"); - ircdproto->SendSQLine(NULL, &x); - ircdproto->SendClientIntroduction(this); + IRCD->SendSQLine(NULL, &x); + IRCD->SendClientIntroduction(this); this->introduced = true; } } @@ -48,10 +60,10 @@ BotInfo::~BotInfo() // If we're synchronised with the uplink already, send the bot. if (Me && Me->IsSynced()) { - ircdproto->SendQuit(this, ""); + IRCD->SendQuit(this, ""); this->introduced = false; XLine x(this->nick); - ircdproto->SendSQLineDel(&x); + IRCD->SendSQLineDel(&x); } for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) @@ -70,11 +82,11 @@ BotInfo::~BotInfo() BotListByUID->erase(this->uid); } -Serialize::Data BotInfo::serialize() const +Serialize::Data BotInfo::Serialize() const { Serialize::Data data; - data["nick"].setMax(64) << this->nick; + data["nick"].SetMax(64)/*XXX*/ << this->nick; data["user"] << this->ident; data["host"] << this->host; data["realname"] << this->realname; @@ -84,12 +96,12 @@ Serialize::Data BotInfo::serialize() const return data; } -Serializable* BotInfo::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data) { BotInfo *bi; if (obj) bi = anope_dynamic_static_cast<BotInfo *>(obj); - else if (!(bi = findbot(data["nick"].astr()))) + else if (!(bi = BotInfo::Find(data["nick"].astr()))) bi = new BotInfo(data["nick"].astr(), data["user"].astr(), data["host"].astr(), data["realname"].astr()); data["created"] >> bi->created; bi->FromString(data["flags"].astr()); @@ -100,7 +112,7 @@ void BotInfo::GenerateUID() { if (!this->uid.empty()) throw CoreException("Bot already has a uid?"); - this->uid = ts6_uid_retrieve(); + this->uid = Servers::TS6_UID_Retrieve(); (*BotListByUID)[this->uid] = this; UserListByUID[this->uid] = this; } @@ -139,7 +151,7 @@ void BotInfo::Assign(User *u, ChannelInfo *ci) ci->bi = this; if (ci->c && ci->c->users.size() >= Config->BSMinUsers) - this->Join(ci->c, &Config->BotModeList); + this->Join(ci->c, &ModeManager::DefaultBotModes); } void BotInfo::UnAssign(User *u, ChannelInfo *ci) @@ -178,7 +190,7 @@ void BotInfo::Join(Channel *c, ChannelStatus *status) if (c->FindUser(this) != NULL) return; - if (Config && ircdproto && Config->BSSmartJoin) + if (Config && IRCD && Config->BSSmartJoin) { std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList(CMODE_BAN); @@ -197,21 +209,21 @@ void BotInfo::Join(Channel *c, ChannelStatus *status) /* Should we be invited? */ if (c->HasMode(CMODE_INVITE) || (limit && c->users.size() >= limit)) - ircdproto->SendNotice(this, "@" + c->name, "%s invited %s into the channel.", this->nick.c_str(), this->nick.c_str()); + 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 (ircdproto) - ircdproto->SendJoin(this, c, status); + if (IRCD) + IRCD->SendJoin(this, c, status); FOREACH_MOD(I_OnBotJoin, OnBotJoin(c, this)); } void BotInfo::Join(const Anope::string &chname, ChannelStatus *status) { - Channel *c = findchan(chname); + Channel *c = Channel::Find(chname); return this->Join(c ? c : new Channel(chname), status); } @@ -220,7 +232,7 @@ void BotInfo::Part(Channel *c, const Anope::string &reason) if (c->FindUser(this) == NULL) return; - ircdproto->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : ""); + IRCD->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : ""); c->DeleteUser(this); } @@ -233,11 +245,6 @@ void BotInfo::OnMessage(User *u, const Anope::string &message) RunCommand(source, message); } -/** Link a command name to a command in services - * @param cname The command name - * @param sname The service name - * @param permission Permission required to execute the command, if any - */ void BotInfo::SetCommand(const Anope::string &cname, const Anope::string &sname, const Anope::string &permission) { CommandInfo ci; @@ -246,10 +253,6 @@ void BotInfo::SetCommand(const Anope::string &cname, const Anope::string &sname, this->commands[cname] = ci; } -/** Get command info for a command - * @param cname The command name - * @return A struct containing service name and permission - */ CommandInfo *BotInfo::GetCommand(const Anope::string &cname) { CommandInfo::map::iterator it = this->commands.find(cname); @@ -258,3 +261,24 @@ CommandInfo *BotInfo::GetCommand(const Anope::string &cname) return NULL; } +BotInfo* BotInfo::Find(const Anope::string &nick, bool nick_only) +{ + BotInfo *bi = NULL; + if (!nick_only && isdigit(nick[0]) && IRCD->RequiresID) + { + botinfo_map::iterator it = BotListByUID->find(nick); + if (it != BotListByUID->end()) + bi = it->second; + } + else + { + botinfo_map::iterator it = BotListByNick->find(nick); + if (it != BotListByNick->end()) + bi = it->second; + } + + if (bi) + bi->QueueUpdate(); + return bi; +} + diff --git a/src/botserv.cpp b/src/botserv.cpp deleted file mode 100644 index 04949b427..000000000 --- a/src/botserv.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* BotServ functions - * - * (C) 2003-2012 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. - */ - -/*************************************************************************/ - -#include "services.h" -#include "anope.h" -#include "protocol.h" -#include "bots.h" -#include "regchannel.h" -#include "language.h" -#include "extern.h" -#include "access.h" -#include "channels.h" -#include "account.h" - -BotInfo* findbot(const Anope::string &nick) -{ - BotInfo *bi = NULL; - if (isdigit(nick[0]) && ircdproto->RequiresID) - { - botinfo_map::iterator it = BotListByUID->find(nick); - if (it != BotListByUID->end()) - bi = it->second; - } - else - { - botinfo_map::iterator it = BotListByNick->find(nick); - if (it != BotListByNick->end()) - bi = it->second; - } - - if (bi) - bi->QueueUpdate(); - return bi; -} - - -/*************************************************************************/ - -/* Makes a simple ban and kicks the target - * @param requester The user requesting the kickban - * @param ci The channel - * @param u The user being kicked - * @param reason The reason - */ -void bot_raw_ban(User *requester, ChannelInfo *ci, User *u, const Anope::string &reason) -{ - if (!u || !ci) - return; - - if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u) - { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", translate(requester, ACCESS_DENIED)); - return; - } - - AccessGroup u_access = ci->AccessFor(u), req_access = ci->AccessFor(requester); - if (ci->HasFlag(CI_PEACE) && u != requester && u_access >= req_access) - return; - - if (matches_list(ci->c, u, CMODE_EXCEPT)) - { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", translate(requester, _("User matches channel except."))); - return; - } - - Anope::string mask; - get_idealban(ci, u, mask); - - ci->c->SetMode(NULL, CMODE_BAN, mask); - - /* Check if we need to do a signkick or not -GD */ - if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv("SIGNKICK"))) - ci->c->Kick(ci->bi, u, "%s (%s)", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str(), requester->nick.c_str()); - else - ci->c->Kick(ci->bi, u, "%s", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str()); -} - -/*************************************************************************/ - -/* Makes a kick with a "dynamic" reason ;) - * @param requester The user requesting the kick - * @param ci The channel - * @param u The user being kicked - * @param reason The reason for the kick - */ -void bot_raw_kick(User *requester, ChannelInfo *ci, User *u, const Anope::string &reason) -{ - if (!u || !ci || !ci->c || !ci->c->FindUser(u)) - return; - - if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u) - { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", translate(requester, ACCESS_DENIED)); - return; - } - - AccessGroup u_access = ci->AccessFor(u), req_access = ci->AccessFor(requester); - if (ci->HasFlag(CI_PEACE) && requester != u && u_access >= req_access) - return; - - if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !req_access.HasPriv("SIGNKICK"))) - ci->c->Kick(ci->bi, u, "%s (%s)", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str(), requester->nick.c_str()); - else - ci->c->Kick(ci->bi, u, "%s", !reason.empty() ? reason.c_str() : ci->bi->nick.c_str()); -} - diff --git a/src/channels.cpp b/src/channels.cpp index 501dd7146..41755b9c8 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -21,16 +22,15 @@ #include "users.h" #include "config.h" #include "access.h" -#include "extern.h" #include "sockets.h" +#include "chanserv.h" channel_map ChannelList; -/** Default constructor - * @param name The channel name - * @param ts The time the channel was created - */ -Channel::Channel(const Anope::string &nname, time_t ts) : Flags<ChannelFlag, 3>(ChannelFlagString) +static const Anope::string ChannelFlagString[] = { "CH_INABIT", "CH_PERSIST", "CH_SYNCING", "" }; +template<> const Anope::string* Flags<ChannelFlag>::flags_strings = ChannelFlagString; + +Channel::Channel(const Anope::string &nname, time_t ts) { if (nname.empty()) throw CoreException("A channel without a name ?"); @@ -46,7 +46,7 @@ Channel::Channel(const Anope::string &nname, time_t ts) : Flags<ChannelFlag, 3>( this->server_modetime = this->chanserv_modetime = 0; this->server_modecount = this->chanserv_modecount = this->bouncy_modes = this->topic_ts = this->topic_time = 0; - this->ci = cs_findchan(this->name); + this->ci = ChannelInfo::Find(this->name); if (this->ci) this->ci->c = this; @@ -55,8 +55,6 @@ Channel::Channel(const Anope::string &nname, time_t ts) : Flags<ChannelFlag, 3>( FOREACH_MOD(I_OnChannelCreate, OnChannelCreate(this)); } -/** Default destructor - */ Channel::~Channel() { FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this)); @@ -79,16 +77,16 @@ void Channel::Reset() { UserContainer *uc = *it; - ChannelStatus flags = *uc->Status; - uc->Status->ClearFlags(); + ChannelStatus flags = *uc->status; + uc->status->ClearFlags(); - if (findbot(uc->user->nick)) + if (BotInfo::Find(uc->user->nick)) { for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (flags.HasFlag(cm->Name)) + if (flags.HasFlag(cm->name)) this->SetMode(NULL, cm, uc->user->GetUID(), false); } } @@ -97,7 +95,7 @@ void Channel::Reset() this->CheckModes(); for (CUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it) - chan_set_correct_modes((*it)->user, this, 1, false); + this->SetCorrectModes((*it)->user, true, false); if (this->ci && Me && Me->IsSynced()) this->ci->RestoreTopic(); @@ -151,32 +149,32 @@ void Channel::CheckModes() if (!cm) continue; - if (cm->Type == MODE_REGULAR) + if (cm->type == MODE_REGULAR) { - if (!this->HasMode(cm->Name) && ml->set) + if (!this->HasMode(cm->name) && ml->set) this->SetMode(NULL, cm); - else if (this->HasMode(cm->Name) && !ml->set) + else if (this->HasMode(cm->name) && !ml->set) this->RemoveMode(NULL, cm); } - else if (cm->Type == MODE_PARAM) + else if (cm->type == MODE_PARAM) { /* If the channel doesnt have the mode, or it does and it isn't set correctly */ if (ml->set) { Anope::string param; - this->GetParam(cm->Name, param); + this->GetParam(cm->name, param); - if (!this->HasMode(cm->Name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param))) + if (!this->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param))) this->SetMode(NULL, cm, ml->param); } else { - if (this->HasMode(cm->Name)) + if (this->HasMode(cm->name)) this->RemoveMode(NULL, cm); } } - else if (cm->Type == MODE_LIST) + else if (cm->type == MODE_LIST) { if (ml->set) this->SetMode(NULL, cm, ml->param); @@ -186,36 +184,32 @@ void Channel::CheckModes() } } -void Channel::JoinUser(User *user) +UserContainer* Channel::JoinUser(User *user) { Log(user, this, "join"); - ChannelStatus *Status = new ChannelStatus(); + ChannelStatus *status = new ChannelStatus(); ChannelContainer *cc = new ChannelContainer(this); - cc->Status = Status; + cc->status = status; user->chans.push_back(cc); UserContainer *uc = new UserContainer(user); - uc->Status = Status; + uc->status = status; this->users.push_back(uc); if (this->ci && this->ci->HasFlag(CI_PERSIST) && this->creation_time > this->ci->time_registered) { Log(LOG_DEBUG) << "Changing TS of " << this->name << " from " << this->creation_time << " to " << this->ci->time_registered; this->creation_time = this->ci->time_registered; - ircdproto->SendChannel(this); + IRCD->SendChannel(this); this->Reset(); } + + return uc; } -/** Remove a user internally from the channel - * @param u The user - */ void Channel::DeleteUser(User *user) { - if (this->ci) - update_cs_lastseen(user, this->ci); - Log(user, this, "leaves"); FOREACH_MOD(I_OnLeaveChannel, OnLeaveChannel(user, this)); @@ -227,7 +221,7 @@ void Channel::DeleteUser(User *user) return; } - delete (*cit)->Status; + delete (*cit)->status; delete *cit; this->users.erase(cit); @@ -259,10 +253,6 @@ void Channel::DeleteUser(User *user) delete this; } -/** Check if the user is on the channel - * @param u The user - * @return A user container if found, else NULL - */ UserContainer *Channel::FindUser(const User *u) const { for (CUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it) @@ -271,14 +261,9 @@ UserContainer *Channel::FindUser(const User *u) const return NULL; } -/** Check if a user has a status on a channel - * @param u The user - * @param cms The status mode, or NULL to represent no status - * @return true or false - */ bool Channel::HasUserStatus(const User *u, ChannelModeStatus *cms) const { - if (!u || (cms && cms->Type != MODE_STATUS)) + if (!u || (cms && cms->type != MODE_STATUS)) throw CoreException("Channel::HasUserStatus got bad mode"); /* Usually its more efficient to search the users channels than the channels users */ @@ -286,31 +271,19 @@ bool Channel::HasUserStatus(const User *u, ChannelModeStatus *cms) const if (cc) { if (cms) - return cc->Status->HasFlag(cms->Name); + return cc->status->HasFlag(cms->name); else - return !cc->Status->FlagCount(); + return !cc->status->FlagCount(); } return false; } -/** Check if a user has a status on a channel - * Use the overloaded function for ChannelModeStatus* to check for no status - * @param u The user - * @param Name The Mode name, eg CMODE_OP, CMODE_VOICE - * @return true or false - */ bool Channel::HasUserStatus(const User *u, ChannelModeName Name) const { return HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(ModeManager::FindChannelModeByName(Name))); } -/** - * See if a channel has a mode - * @param Name The mode name - * @param param The optional mode param - * @return The number of modes set - */ size_t Channel::HasMode(ChannelModeName Name, const Anope::string ¶m) { if (param.empty()) @@ -322,80 +295,70 @@ size_t Channel::HasMode(ChannelModeName Name, const Anope::string ¶m) return 0; } -/** Get a list of modes on a channel - * @param Name A mode name to get the list of - * @return a pair of iterators for the beginning and end of the list - */ -std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> Channel::GetModeList(ChannelModeName Name) +std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> Channel::GetModeList(ChannelModeName mname) { - Channel::ModeList::iterator it = this->modes.find(Name), it_end = it; + Channel::ModeList::iterator it = this->modes.find(mname), it_end = it; if (it != this->modes.end()) - it_end = this->modes.upper_bound(Name); + it_end = this->modes.upper_bound(mname); return std::make_pair(it, it_end); } -/** Set a mode internally on a channel, this is not sent out to the IRCd - * @param setter The user who is setting the mode - * @param cm The mode - * @param param The param - * @param EnforeMLock true if mlocks should be enforced, false to override mlock - */ -void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) +void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { if (!cm) return; EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnChannelModeSet, OnChannelModeSet(this, setter, cm->Name, param)); + FOREACH_RESULT(I_OnChannelModeSet, OnChannelModeSet(this, setter, cm->name, param)); /* Setting v/h/o/a/q etc */ - if (cm->Type == MODE_STATUS) + if (cm->type == MODE_STATUS) { if (param.empty()) { - Log() << "Channel::SetModeInternal() mode " << cm->ModeChar << " with no parameter for channel " << this->name; + Log() << "Channel::SetModeInternal() mode " << cm->mchar << " with no parameter for channel " << this->name; return; } - User *u = finduser(param); + User *u = User::Find(param); if (!u) { - Log() << "MODE " << this->name << " +" << cm->ModeChar << " for nonexistant user " << param; + Log() << "MODE " << this->name << " +" << cm->mchar << " for nonexistant user " << param; return; } - Log(LOG_DEBUG) << "Setting +" << cm->ModeChar << " on " << this->name << " for " << u->nick; + Log(LOG_DEBUG) << "Setting +" << cm->mchar << " on " << this->name << " for " << u->nick; /* Set the status on the user */ ChannelContainer *cc = u->FindChannel(this); if (cc) - cc->Status->SetFlag(cm->Name); + cc->status->SetFlag(cm->name); /* Enforce secureops, etc */ - if (EnforceMLock) - chan_set_correct_modes(u, this, 0, false); + if (enforce_mlock) + this->SetCorrectModes(u, false, false); return; } - if (cm->Type != MODE_LIST) - this->modes.erase(cm->Name); - this->modes.insert(std::make_pair(cm->Name, param)); + if (cm->type != MODE_LIST) + this->modes.erase(cm->name); + this->modes.insert(std::make_pair(cm->name, param)); - if (param.empty() && cm->Type != MODE_REGULAR) + if (param.empty() && cm->type != MODE_REGULAR) { - Log() << "Channel::SetModeInternal() mode " << cm->ModeChar << " for " << this->name << " with a paramater, but its not a param mode"; + Log() << "Channel::SetModeInternal() mode " << cm->mchar << " for " << this->name << " with a paramater, but its not a param mode"; return; } - if (cm->Type == MODE_LIST) + if (cm->type == MODE_LIST) { ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); cml->OnAdd(this, param); } /* Channel mode +P or so was set, mark this channel as persistent */ - if (cm->Name == CMODE_PERM) + if (cm->name == CMODE_PERM) { this->SetFlag(CH_PERSIST); if (this->ci) @@ -403,68 +366,62 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anop } /* Check if we should enforce mlock */ - if (!EnforceMLock || MOD_RESULT == EVENT_STOP) + if (!enforce_mlock || MOD_RESULT == EVENT_STOP) return; this->CheckModes(); } -/** Remove a mode internally on a channel, this is not sent out to the IRCd - * @param setter The user who is unsetting the mode - * @param cm The mode - * @param param The param - * @param EnforceMLock true if mlocks should be enforced, false to override mlock - */ -void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) +void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { if (!cm) return; EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnChannelModeUnset, OnChannelModeUnset(this, setter, cm->Name, param)); + FOREACH_RESULT(I_OnChannelModeUnset, OnChannelModeUnset(this, setter, cm->name, param)); /* Setting v/h/o/a/q etc */ - if (cm->Type == MODE_STATUS) + if (cm->type == MODE_STATUS) { if (param.empty()) { - Log() << "Channel::RemoveModeInternal() mode " << cm->ModeChar << " with no parameter for channel " << this->name; + Log() << "Channel::RemoveModeInternal() mode " << cm->mchar << " with no parameter for channel " << this->name; return; } - BotInfo *bi = findbot(param); - User *u = bi ? bi : finduser(param); + BotInfo *bi = BotInfo::Find(param); + User *u = bi ? bi : User::Find(param); if (!u) { - Log() << "Channel::RemoveModeInternal() MODE " << this->name << "-" << cm->ModeChar << " for nonexistant user " << param; + Log() << "Channel::RemoveModeInternal() MODE " << this->name << "-" << cm->mchar << " for nonexistant user " << param; return; } - Log(LOG_DEBUG) << "Setting -" << cm->ModeChar << " on " << this->name << " for " << u->nick; + Log(LOG_DEBUG) << "Setting -" << cm->mchar << " on " << this->name << " for " << u->nick; /* Remove the status on the user */ ChannelContainer *cc = u->FindChannel(this); if (cc) - cc->Status->UnsetFlag(cm->Name); + cc->status->UnsetFlag(cm->name); - if (EnforceMLock) + if (enforce_mlock) { /* Reset modes on bots if we're supposed to */ if (this->ci && this->ci->bi && this->ci->bi == bi) { - if (Config->BotModeList.HasFlag(cm->Name)) + if (ModeManager::DefaultBotModes.HasFlag(cm->name)) this->SetMode(bi, cm, bi->GetUID()); } - chan_set_correct_modes(u, this, 0, false); + this->SetCorrectModes(u, false, false); } return; } - if (cm->Type == MODE_LIST && !param.empty()) + if (cm->type == MODE_LIST && !param.empty()) { - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = this->GetModeList(cm->Name); + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = this->GetModeList(cm->name); for (; its.first != its.second; ++its.first) if (Anope::Match(param, its.first->second)) { @@ -473,15 +430,15 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A } } else - this->modes.erase(cm->Name); + this->modes.erase(cm->name); - if (cm->Type == MODE_LIST) + if (cm->type == MODE_LIST) { ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); cml->OnDel(this, param); } - if (cm->Name == CMODE_PERM) + if (cm->name == CMODE_PERM) { this->UnsetFlag(CH_PERSIST); @@ -497,123 +454,92 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A /* Check for mlock */ - if (!EnforceMLock || MOD_RESULT == EVENT_STOP) + if (!enforce_mlock || MOD_RESULT == EVENT_STOP) return; this->CheckModes(); } -/** Set a mode on a channel - * @param bi The client setting the modes - * @param cm The mode - * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock - */ -void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) +void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { if (!cm) return; /* Don't set modes already set */ - if (cm->Type == MODE_REGULAR && HasMode(cm->Name)) + if (cm->type == MODE_REGULAR && HasMode(cm->name)) return; - else if (cm->Type == MODE_PARAM) + else if (cm->type == MODE_PARAM) { ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); if (!cmp->IsValid(param)) return; Anope::string cparam; - if (GetParam(cm->Name, cparam) && cparam.equals_cs(param)) + if (GetParam(cm->name, cparam) && cparam.equals_cs(param)) return; } - else if (cm->Type == MODE_STATUS) + else if (cm->type == MODE_STATUS) { - User *u = finduser(param); + User *u = User::Find(param); if (!u || HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(cm))) return; } - else if (cm->Type == MODE_LIST) + else if (cm->type == MODE_LIST) { ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - if (this->HasMode(cm->Name, param) || !cml->IsValid(param)) + if (this->HasMode(cm->name, param) || !cml->IsValid(param)) return; } ModeManager::StackerAdd(bi, this, cm, true, param); MessageSource ms(bi); - SetModeInternal(ms, cm, param, EnforceMLock); + SetModeInternal(ms, cm, param, enforce_mlock); } -/** - * Set a mode on a channel - * @param bi The client setting the modes - * @param Name The mode name - * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock - */ -void Channel::SetMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m, bool EnforceMLock) +void Channel::SetMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m, bool enforce_mlock) { - SetMode(bi, ModeManager::FindChannelModeByName(Name), param, EnforceMLock); + SetMode(bi, ModeManager::FindChannelModeByName(Name), param, enforce_mlock); } -/** Remove a mode from a channel - * @param bi The client setting the modes - * @param cm The mode - * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock - */ -void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool EnforceMLock) +void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { if (!cm) return; /* Don't unset modes that arent set */ - if ((cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && !HasMode(cm->Name)) + if ((cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && !HasMode(cm->name)) return; /* Don't unset status that aren't set */ - else if (cm->Type == MODE_STATUS) + else if (cm->type == MODE_STATUS) { - User *u = finduser(param); + User *u = User::Find(param); if (!u || !HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(cm))) return; } - else if (cm->Type == MODE_LIST) + else if (cm->type == MODE_LIST) { - if (!this->HasMode(cm->Name, param)) + if (!this->HasMode(cm->name, param)) return; } /* Get the param to send, if we need it */ Anope::string realparam = param; - if (cm->Type == MODE_PARAM) + if (cm->type == MODE_PARAM) { realparam.clear(); ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); - if (!cmp->MinusNoArg) - this->GetParam(cmp->Name, realparam); + if (!cmp->minus_no_arg) + this->GetParam(cmp->name, realparam); } ModeManager::StackerAdd(bi, this, cm, false, realparam); MessageSource ms(bi); - RemoveModeInternal(ms, cm, realparam, EnforceMLock); + RemoveModeInternal(ms, cm, realparam, enforce_mlock); } -/** - * Remove a mode from a channel - * @param bi The client setting the modes - * @param Name The mode name - * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock - */ -void Channel::RemoveMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m, bool EnforceMLock) +void Channel::RemoveMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m, bool enforce_mlock) { - RemoveMode(bi, ModeManager::FindChannelModeByName(Name), param, EnforceMLock); + RemoveMode(bi, ModeManager::FindChannelModeByName(Name), param, enforce_mlock); } -/** Get a param from the channel - * @param Name The mode - * @param Target a string to put the param into - * @return true on success - */ bool Channel::GetParam(ChannelModeName Name, Anope::string &Target) const { std::multimap<ChannelModeName, Anope::string>::const_iterator it = this->modes.find(Name); @@ -629,14 +555,7 @@ bool Channel::GetParam(ChannelModeName Name, Anope::string &Target) const return false; } -/*************************************************************************/ - -/** Set a string of modes on the channel - * @param bi The client setting the modes - * @param EnforceMLock Should mlock be enforced on this mode change - * @param cmodes The modes to set - */ -void Channel::SetModes(BotInfo *bi, bool EnforceMLock, const char *cmodes, ...) +void Channel::SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...) { char buf[BUFSIZE] = ""; va_list args; @@ -670,38 +589,38 @@ void Channel::SetModes(BotInfo *bi, bool EnforceMLock, const char *cmodes, ...) if (add) { - if (cm->Type != MODE_REGULAR && sep.GetToken(sbuf)) + if (cm->type != MODE_REGULAR && sep.GetToken(sbuf)) { - if (cm->Type == MODE_STATUS) + if (cm->type == MODE_STATUS) { - User *targ = finduser(sbuf); + User *targ = User::Find(sbuf); if (targ != NULL) sbuf = targ->GetUID(); } - this->SetMode(bi, cm, sbuf, EnforceMLock); + this->SetMode(bi, cm, sbuf, enforce_mlock); } else - this->SetMode(bi, cm, "", EnforceMLock); + this->SetMode(bi, cm, "", enforce_mlock); } else if (!add) { - if (cm->Type != MODE_REGULAR && sep.GetToken(sbuf)) + if (cm->type != MODE_REGULAR && sep.GetToken(sbuf)) { - if (cm->Type == MODE_STATUS) + if (cm->type == MODE_STATUS) { - User *targ = finduser(sbuf); + User *targ = User::Find(sbuf); if (targ != NULL) sbuf = targ->GetUID(); } - this->RemoveMode(bi, cm, sbuf, EnforceMLock); + this->RemoveMode(bi, cm, sbuf, enforce_mlock); } else - this->RemoveMode(bi, cm, "", EnforceMLock); + this->RemoveMode(bi, cm, "", enforce_mlock); } } } -void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts, bool EnforceMLock) +void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts, bool enforce_mlock) { if (source.GetServer()) { @@ -727,7 +646,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, User *setter = source.GetUser(); /* Removing channel modes *may* delete this channel */ - dynamic_reference<Channel> this_reference(this); + Reference<Channel> this_reference(this); spacesepstream sep_modes(mode); Anope::string m; @@ -760,24 +679,24 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, Log(LOG_DEBUG) << "Channel::SetModeInternal: Unknown mode char " << m[i]; continue; } - modestring += cm->ModeChar; + modestring += cm->mchar; } - if (cm->Type == MODE_REGULAR) + if (cm->type == MODE_REGULAR) { if (add) - this->SetModeInternal(source, cm, "", EnforceMLock); + this->SetModeInternal(source, cm, "", enforce_mlock); else - this->RemoveModeInternal(source, cm, "", EnforceMLock); + this->RemoveModeInternal(source, cm, "", enforce_mlock); continue; } - else if (cm->Type == MODE_PARAM) + else if (cm->type == MODE_PARAM) { ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); - if (!add && cmp->MinusNoArg) + if (!add && cmp->minus_no_arg) { - this->RemoveModeInternal(source, cm, "", EnforceMLock); + this->RemoveModeInternal(source, cm, "", enforce_mlock); continue; } } @@ -785,15 +704,15 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, if (sep_modes.GetToken(token)) { User *u = NULL; - if (cm->Type == MODE_STATUS && (u = finduser(token))) + if (cm->type == MODE_STATUS && (u = User::Find(token))) paramstring += " " + u->nick; else paramstring += " " + token; if (add) - this->SetModeInternal(source, cm, token, EnforceMLock); + this->SetModeInternal(source, cm, token, enforce_mlock); else - this->RemoveModeInternal(source, cm, token, EnforceMLock); + this->RemoveModeInternal(source, cm, token, enforce_mlock); } else Log() << "warning: Channel::SetModesInternal() recieved more modes requiring params than params, modes: " << mode; @@ -808,15 +727,27 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, Log(LOG_DEBUG) << source.GetName() << " is setting " << this->name << " to " << modestring << paramstring; } -/** Kick a user from a channel internally - * @param source The sender of the kick - * @param nick The nick being kicked - * @param reason The reason for the kick - */ +bool Channel::MatchesList(User *u, ChannelModeName mode) +{ + if (!this->HasMode(mode)) + return false; + + + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> m = this->GetModeList(mode); + for (; m.first != m.second; ++m.first) + { + Entry e(mode, m.first->second); + if (e.Matches(u)) + return true; + } + + return false; +} + void Channel::KickInternal(MessageSource &source, const Anope::string &nick, const Anope::string &reason) { User *sender = source.GetUser(); - User *target = finduser(nick); + User *target = User::Find(nick); if (!target) { Log() << "Channel::KickInternal got a nonexistent user " << nick << " on " << this->name << ": " << reason; @@ -825,7 +756,7 @@ void Channel::KickInternal(MessageSource &source, const Anope::string &nick, con BotInfo *bi = NULL; if (target->server == Me) - bi = findbot(nick); + bi = BotInfo::Find(nick); if (sender) Log(sender, this, "kick") << "kicked " << target->nick << " (" << reason << ")"; @@ -847,17 +778,11 @@ void Channel::KickInternal(MessageSource &source, const Anope::string &nick, con /* Bots get rejoined */ if (bi) { - bi->Join(this, &Config->BotModeList); + bi->Join(this, &ModeManager::DefaultBotModes); this->UnsetFlag(CH_INHABIT); } } -/** Kick a user from the channel - * @param bi The sender, can be NULL for the service bot for this channel - * @param u The user being kicked - * @param reason The reason for the kick - * @return true if the kick was scucessful, false if a module blocked the kick - */ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) { va_list args; @@ -881,7 +806,7 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) FOREACH_RESULT(I_OnBotKick, OnBotKick(bi, this, u, buf)); if (MOD_RESULT == EVENT_STOP) return false; - ircdproto->SendKick(bi, this, u, "%s", buf); + IRCD->SendKick(bi, this, u, "%s", buf); MessageSource ms(bi); this->KickInternal(ms, u->nick, buf); return true; @@ -894,16 +819,16 @@ Anope::string Channel::GetModes(bool complete, bool plus) for (std::multimap<ChannelModeName, Anope::string>::const_iterator it = this->modes.begin(), it_end = this->modes.end(); it != it_end; ++it) { ChannelMode *cm = ModeManager::FindChannelModeByName(it->first); - if (!cm || cm->Type == MODE_LIST) + if (!cm || cm->type == MODE_LIST) continue; - res += cm->ModeChar; + res += cm->mchar; if (complete && !it->second.empty()) { ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); - if (plus || !cmp->MinusNoArg) + if (plus || !cmp->minus_no_arg) params += " " + it->second; } } @@ -913,7 +838,7 @@ Anope::string Channel::GetModes(bool complete, bool plus) void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts) { - User *u = finduser(user); + User *u = User::Find(user); this->topic = newtopic; this->topic_setter = u ? u->nick : user; @@ -930,13 +855,13 @@ void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts) { - User *u = finduser(user); + User *u = User::Find(user); this->topic = newtopic; this->topic_setter = u ? u->nick : user; this->topic_ts = ts; - ircdproto->SendTopic(this->ci->WhoSends(), this); + IRCD->SendTopic(this->ci->WhoSends(), this); /* Now that the topic is set update the time set. This is *after* we set it so the protocol modules are able to tell the old last set time */ this->topic_time = Anope::CurTime; @@ -947,97 +872,55 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop this->ci->CheckTopic(); } -/** A timer used to keep the BotServ bot/ChanServ in the channel - * after kicking the last user in a channel - */ -class CoreExport ChanServTimer : public Timer +void Channel::Hold() { - private: - dynamic_reference<Channel> c; - - public: - /** Default constructor - * @param chan The channel - */ - ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan) - { - BotInfo *bi = findbot(Config->ChanServ); - if (!bi || !c) - return; - c->SetFlag(CH_INHABIT); - if (!c->ci || !c->ci->bi) - bi->Join(c); - else if (!c->FindUser(c->ci->bi)) - c->ci->bi->Join(c); - } - - /** Called when the delay is up - * @param The current time + /** A timer used to keep the BotServ bot/ChanServ in the channel + * after kicking the last user in a channel */ - void Tick(time_t) + class ChanServTimer : public Timer { - if (!c) - return; + private: + Reference<Channel> c; - c->UnsetFlag(CH_INHABIT); - - if (!c->ci || !c->ci->bi) + public: + /** Constructor + * @param chan The channel + */ + ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan) { - BotInfo *bi = findbot(Config->ChanServ); - if (bi) - bi->Part(c); + if (!ChanServ || !c) + return; + c->SetFlag(CH_INHABIT); + if (!c->ci || !c->ci->bi) + ChanServ->Join(c); + else if (!c->FindUser(c->ci->bi)) + c->ci->bi->Join(c); } - else if (c->users.size() == 1 || c->users.size() < Config->BSMinUsers) - c->ci->bi->Part(c); - } -}; -void Channel::Hold() -{ - new ChanServTimer(this); -} - -/*************************************************************************/ - -Channel *findchan(const Anope::string &chan) -{ - channel_map::const_iterator it = ChannelList.find(chan); - - if (it != ChannelList.end()) - return it->second; - return NULL; -} - -/*************************************************************************/ - -/* Is the given nick on the given channel? - This function supports links. */ + /** Called when the delay is up + * @param The current time + */ + void Tick(time_t) anope_override + { + if (!c) + return; -User *nc_on_chan(Channel *c, const NickCore *nc) -{ - if (!c || !nc) - return NULL; + c->UnsetFlag(CH_INHABIT); - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) - { - UserContainer *uc = *it; + 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); + } + }; - if (uc->user->Account() == nc) - return uc->user; - } - return NULL; + new ChanServTimer(this); } -/** - * Set the correct modes, or remove the ones granted without permission, - * for the specified user on ths specified channel. This doesn't give - * modes to ignored users, but does remove them if needed. - * @param user The user to give/remove modes to/from - * @param c The channel to give/remove modes on - * @param give_modes Set to 1 to give modes, 0 to not give modes - * @return void - **/ -void chan_set_correct_modes(const User *user, Channel *c, int give_modes, bool check_noop) +void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop) { ChannelMode *owner = ModeManager::FindChannelModeByName(CMODE_OWNER), *admin = ModeManager::FindChannelModeByName(CMODE_PROTECT), @@ -1045,46 +928,44 @@ void chan_set_correct_modes(const User *user, Channel *c, int give_modes, bool c *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP), *voice = ModeManager::FindChannelModeByName(CMODE_VOICE); - if (user == NULL || c == NULL) + if (user == NULL) return; - ChannelInfo *ci = c->ci; - - if (ci == NULL) + if (!this->ci) return; - Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << c->name << " (" << (give_modes ? "" : "not ") << "giving modes)"; + Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << this->name << " (" << (give_modes ? "" : "not ") << "giving modes)"; AccessGroup u_access = ci->AccessFor(user); if (give_modes && (!user->Account() || user->Account()->HasFlag(NI_AUTOOP)) && (!check_noop || !ci->HasFlag(CI_NOAUTOOP))) { if (owner && u_access.HasPriv("AUTOOWNER")) - c->SetMode(NULL, CMODE_OWNER, user->GetUID()); + this->SetMode(NULL, CMODE_OWNER, user->GetUID()); else if (admin && u_access.HasPriv("AUTOPROTECT")) - c->SetMode(NULL, CMODE_PROTECT, user->GetUID()); + this->SetMode(NULL, CMODE_PROTECT, user->GetUID()); if (op && u_access.HasPriv("AUTOOP")) - c->SetMode(NULL, CMODE_OP, user->GetUID()); + this->SetMode(NULL, CMODE_OP, user->GetUID()); else if (halfop && u_access.HasPriv("AUTOHALFOP")) - c->SetMode(NULL, CMODE_HALFOP, user->GetUID()); + this->SetMode(NULL, CMODE_HALFOP, user->GetUID()); else if (voice && u_access.HasPriv("AUTOVOICE")) - c->SetMode(NULL, CMODE_VOICE, user->GetUID()); + this->SetMode(NULL, CMODE_VOICE, user->GetUID()); } /* If this channel has secureops or the channel is syncing and they are not ulined, check to remove modes */ - if ((ci->HasFlag(CI_SECUREOPS) || (c->HasFlag(CH_SYNCING) && user->server->IsSynced())) && !user->server->IsULined()) + if ((ci->HasFlag(CI_SECUREOPS) || (this->HasFlag(CH_SYNCING) && user->server->IsSynced())) && !user->server->IsULined()) { if (owner && !u_access.HasPriv("AUTOOWNER") && !u_access.HasPriv("OWNERME")) - c->RemoveMode(NULL, CMODE_OWNER, user->GetUID()); + this->RemoveMode(NULL, CMODE_OWNER, user->GetUID()); if (admin && !u_access.HasPriv("AUTOPROTECT") && !u_access.HasPriv("PROTECTME")) - c->RemoveMode(NULL, CMODE_PROTECT, user->GetUID()); + this->RemoveMode(NULL, CMODE_PROTECT, user->GetUID()); - if (op && c->HasUserStatus(user, CMODE_OP) && !u_access.HasPriv("AUTOOP") && !u_access.HasPriv("OPDEOPME")) - c->RemoveMode(NULL, CMODE_OP, user->GetUID()); + if (op && this->HasUserStatus(user, CMODE_OP) && !u_access.HasPriv("AUTOOP") && !u_access.HasPriv("OPDEOPME")) + this->RemoveMode(NULL, CMODE_OP, user->GetUID()); if (halfop && !u_access.HasPriv("AUTOHALFOP") && !u_access.HasPriv("HALFOPME")) - c->RemoveMode(NULL, CMODE_HALFOP, user->GetUID()); + this->RemoveMode(NULL, CMODE_HALFOP, user->GetUID()); } // Check mlock @@ -1092,171 +973,43 @@ void chan_set_correct_modes(const User *user, Channel *c, int give_modes, bool c { const ModeLock *ml = it->second; ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name); - if (!cm || cm->Type != MODE_STATUS) + if (!cm || cm->type != MODE_STATUS) continue; if (Anope::Match(user->nick, ml->param) || Anope::Match(user->GetDisplayedMask(), ml->param)) { - if ((ml->set && !c->HasUserStatus(user, ml->name)) || (!ml->set && c->HasUserStatus(user, ml->name))) + if (ml->set != this->HasUserStatus(user, ml->name)) { if (ml->set) - c->SetMode(NULL, cm, user->GetUID(), false); + this->SetMode(NULL, cm, user->GetUID(), false); else if (!ml->set) - c->RemoveMode(NULL, cm, user->GetUID(), false); + this->RemoveMode(NULL, cm, user->GetUID(), false); } } } } -/*************************************************************************/ - -static const Anope::string EntryFlagString[] = { "ENTRYTYPE_NONE", "ENTRYTYPE_CIDR", "ENTRYTYPE_NICK_WILD", "ENTRYTYPE_NICK", "ENTRYTYPE_USER_WILD", "ENTRYTYPE_USER", "ENTRYTYPE_HOST_WILD", "ENTRYTYPE_HOST", "" }; - -/** Constructor - * @param mode What mode this host is for - can be CMODE_BEGIN for unknown/no mode - * @param _host A full nick!ident@host/cidr mask - */ -Entry::Entry(ChannelModeName mode, const Anope::string &_host) : Flags<EntryType>(EntryFlagString), modename(mode) +void Channel::Unban(const User *u, bool full) { - this->SetFlag(ENTRYTYPE_NONE); - this->cidr_len = 0; - this->mask = _host; - - Anope::string _nick, _user, _realhost; - size_t at = _host.find('@'); - if (at != Anope::string::npos) - { - _realhost = _host.substr(at + 1); - Anope::string _nickident = _host.substr(0, at); - - size_t ex = _nickident.find('!'); - if (ex != Anope::string::npos) - { - _user = _nickident.substr(ex + 1); - _nick = _nickident.substr(0, ex); - } - else - _user = _nickident; - } - else - _realhost = _host; - - if (!_nick.empty() && !str_is_pure_wildcard(_nick)) - { - this->nick = _nick; - if (str_is_wildcard(_nick)) - this->SetFlag(ENTRYTYPE_NICK_WILD); - else - this->SetFlag(ENTRYTYPE_NICK); - } + if (!this->HasMode(CMODE_BAN)) + return; - if (!_user.empty() && !str_is_pure_wildcard(_user)) + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = this->GetModeList(CMODE_BAN); + for (; bans.first != bans.second;) { - this->user = _user; - if (str_is_wildcard(_user)) - this->SetFlag(ENTRYTYPE_USER_WILD); - else - this->SetFlag(ENTRYTYPE_USER); - } - - if (!_realhost.empty() && !str_is_pure_wildcard(_realhost)) - { - size_t sl = _realhost.find_last_of('/'); - if (sl != Anope::string::npos) - { - try - { - sockaddrs addr(_realhost.substr(0, sl)); - /* If we got here, _realhost is a valid IP */ - - Anope::string cidr_range = _realhost.substr(sl + 1); - if (cidr_range.is_pos_number_only()) - { - _realhost = _realhost.substr(0, sl); - this->cidr_len = convertTo<unsigned int>(cidr_range); - this->SetFlag(ENTRYTYPE_CIDR); - Log(LOG_DEBUG) << "Ban " << _realhost << " has cidr " << static_cast<unsigned int>(this->cidr_len); - } - } - catch (const SocketException &) { } - } - - this->host = _realhost; - - if (!this->HasFlag(ENTRYTYPE_CIDR)) - { - if (str_is_wildcard(_realhost)) - this->SetFlag(ENTRYTYPE_HOST_WILD); - else - this->SetFlag(ENTRYTYPE_HOST); - } + Entry ban(CMODE_BAN, bans.first->second); + ++bans.first; + if (ban.Matches(u, full)) + this->RemoveMode(NULL, CMODE_BAN, ban.GetMask()); } } -/** Get the banned mask for this entry - * @return The mask - */ -const Anope::string Entry::GetMask() +Channel* Channel::Find(const Anope::string &name) { - return this->mask; -} - -/** Check if this entry matches a user - * @param u The user - * @param full True to match against a users real host and IP - * @return true on match - */ -bool Entry::Matches(const User *u, bool full) const -{ - bool ret = true; - - if (this->HasFlag(ENTRYTYPE_CIDR)) - { - try - { - if (full) - { - cidr cidr_mask(this->host, this->cidr_len); - sockaddrs addr(u->ip); - if (!cidr_mask.match(addr)) - ret = false; - } - /* If we're not matching fully and their displayed host isnt their IP */ - else if (u->ip != u->GetDisplayedHost()) - ret = false; - } - catch (const SocketException &) - { - ret = false; - } - } - if (this->HasFlag(ENTRYTYPE_NICK) && !this->nick.equals_ci(u->nick)) - ret = false; - if (this->HasFlag(ENTRYTYPE_USER) && !this->user.equals_ci(u->GetVIdent()) && (!full || - !this->user.equals_ci(u->GetIdent()))) - ret = false; - if (this->HasFlag(ENTRYTYPE_HOST) && !this->host.equals_ci(u->GetDisplayedHost()) && (!full || - (!this->host.equals_ci(u->host) && !this->host.equals_ci(u->chost) && !this->host.equals_ci(u->vhost) && - !this->host.equals_ci(u->ip)))) - ret = false; - if (this->HasFlag(ENTRYTYPE_NICK_WILD) && !Anope::Match(u->nick, this->nick)) - ret = false; - if (this->HasFlag(ENTRYTYPE_USER_WILD) && !Anope::Match(u->GetVIdent(), this->user) && (!full || - !Anope::Match(u->GetIdent(), this->user))) - ret = false; - if (this->HasFlag(ENTRYTYPE_HOST_WILD) && !Anope::Match(u->GetDisplayedHost(), this->host) && (!full || - (!Anope::Match(u->host, this->host) && !Anope::Match(u->chost, this->host) && - !Anope::Match(u->vhost, this->host) && !Anope::Match(u->ip, this->host)))) - ret = false; - - ChannelMode *cm = ModeManager::FindChannelModeByName(this->modename); - if (cm != NULL && cm->Type == MODE_LIST) - { - ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - if (cml->Matches(u, this)) - ret = true; - } + channel_map::const_iterator it = ChannelList.find(name); - return ret; + if (it != ChannelList.end()) + return it->second; + return NULL; } diff --git a/src/chanserv.cpp b/src/chanserv.cpp deleted file mode 100644 index 4456ce37c..000000000 --- a/src/chanserv.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* ChanServ functions. - * - * (C) 2003-2012 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. - */ - -/*************************************************************************/ - -#include "services.h" -#include "anope.h" -#include "regchannel.h" -#include "users.h" -#include "channels.h" -#include "access.h" -#include "account.h" - -ChannelInfo* cs_findchan(const Anope::string &chan) -{ - registered_channel_map::const_iterator it = RegisteredChannelList->find(chan); - if (it != RegisteredChannelList->end()) - { - it->second->QueueUpdate(); - return it->second; - } - - return NULL; -} - -/*************************************************************************/ - -/** Is the user the real founder? - * @param user The user - * @param ci The channel - * @return true or false - */ -bool IsFounder(const User *user, const ChannelInfo *ci) -{ - if (!user || !ci) - return false; - - if (user->SuperAdmin) - return true; - - if (user->Account() && user->Account() == ci->GetFounder()) - return true; - - return false; -} - -/*************************************************************************/ - -void update_cs_lastseen(User *user, ChannelInfo *ci) -{ - if (!ci || !user) - return; - - AccessGroup u_access = ci->AccessFor(user); - for (unsigned i = u_access.size(); i > 0; --i) - u_access[i - 1]->last_seen = Anope::CurTime; -} - -/*************************************************************************/ - -/* Returns the best ban possible for a user depending of the bantype - value. */ - -int get_idealban(const ChannelInfo *ci, User *u, Anope::string &ret) -{ - Anope::string mask; - - if (!ci || !u) - return 0; - - Anope::string vident = u->GetIdent(); - - switch (ci->bantype) - { - case 0: - ret = "*!" + vident + "@" + u->GetDisplayedHost(); - return 1; - case 1: - if (vident[0] == '~') - ret = "*!*" + vident + "@" + u->GetDisplayedHost(); - else - ret = "*!" + vident + "@" + u->GetDisplayedHost(); - - return 1; - case 2: - ret = "*!*@" + u->GetDisplayedHost(); - return 1; - case 3: - mask = create_mask(u); - ret = "*!" + mask; - return 1; - - default: - return 0; - } -} - diff --git a/src/command.cpp b/src/command.cpp index 6ae9275ca..92991e38b 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -1,13 +1,14 @@ /* + * * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org> * Copyright (C) 2008-2012 Anope Team <team@anope.org> * * Please read COPYING and README for further details. + * */ #include "services.h" #include "commands.h" -#include "extern.h" #include "users.h" #include "language.h" #include "config.h" @@ -17,6 +18,9 @@ #include "regchannel.h" #include "channels.h" +static const Anope::string CommandFlagString[] = { "CFLAG_ALLOW_UNREGISTERED", "CFLAG_STRIP_CHANNEL", "" }; +template<> const Anope::string* Flags<CommandFlag>::flags_strings = CommandFlagString; + CommandSource::CommandSource(const Anope::string &n, User *user, NickCore *core, CommandReply *r, BotInfo *bi) : nick(n), u(user), nc(core), reply(r), c(NULL), service(bi) { @@ -97,7 +101,7 @@ void CommandSource::Reply(const char *message, ...) va_list args; char buf[4096]; // Messages can be really big. - const char *translated_message = translate(this->nc, message); + const char *translated_message = Language::Translate(this->nc, message); va_start(args, message); vsnprintf(buf, sizeof(buf), translated_message, args); @@ -109,7 +113,7 @@ void CommandSource::Reply(const char *message, ...) void CommandSource::Reply(const Anope::string &message) { - const char *translated_message = translate(this->nc, message.c_str()); + const char *translated_message = Language::Translate(this->nc, message.c_str()); sepstream sep(translated_message, '\n'); Anope::string tok; @@ -117,7 +121,7 @@ void CommandSource::Reply(const Anope::string &message) this->reply->SendMessage(this->service, tok); } -Command::Command(Module *o, const Anope::string &sname, size_t min_params, size_t max_params) : Service(o, "Command", sname), Flags<CommandFlag>(CommandFlagStrings), MaxParams(max_params), MinParams(min_params), module(owner) +Command::Command(Module *o, const Anope::string &sname, size_t minparams, size_t maxparams) : Service(o, "Command", sname), max_params(maxparams), min_params(minparams), module(owner) { } @@ -163,7 +167,7 @@ const Anope::string &Command::GetDesc() const void Command::OnServHelp(CommandSource &source) { - source.Reply(" %-14s %s", source.command.c_str(), translate(source.nc, (this->GetDesc().c_str()))); + source.Reply(" %-14s %s", source.command.c_str(), Language::Translate(source.nc, this->GetDesc().c_str())); } bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) { return false; } @@ -176,7 +180,8 @@ void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcomma void RunCommand(CommandSource &source, const Anope::string &message) { - std::vector<Anope::string> params = BuildStringVector(message); + std::vector<Anope::string> params; + spacesepstream(message).GetTokens(params); bool has_help = source.service->commands.find("HELP") != source.service->commands.end(); CommandInfo::map::const_iterator it = source.service->commands.end(); @@ -202,7 +207,7 @@ void RunCommand(CommandSource &source, const Anope::string &message) } const CommandInfo &info = it->second; - service_reference<Command> c("Command", info.name); + ServiceReference<Command> c("Command", info.name); if (!c) { if (has_help) @@ -225,10 +230,10 @@ void RunCommand(CommandSource &source, const Anope::string &message) for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i) params.erase(params.begin()); - while (c->MaxParams > 0 && params.size() > c->MaxParams) + while (c->max_params > 0 && params.size() > c->max_params) { - params[c->MaxParams - 1] += " " + params[c->MaxParams]; - params.erase(params.begin() + c->MaxParams); + params[c->max_params - 1] += " " + params[c->max_params]; + params.erase(params.begin() + c->max_params); } source.command = it->first; @@ -239,7 +244,7 @@ void RunCommand(CommandSource &source, const Anope::string &message) if (MOD_RESULT == EVENT_STOP) return; - if (params.size() < c->MinParams) + if (params.size() < c->min_params) { c->OnSyntaxError(source, !params.empty() ? params[params.size() - 1] : ""); return; @@ -255,8 +260,8 @@ void RunCommand(CommandSource &source, const Anope::string &message) } bool had_u = source.GetUser(), had_nc = source.nc; - dynamic_reference<User> user_reference(source.GetUser()); - dynamic_reference<NickCore> nc_reference(source.nc); + Reference<User> user_reference(source.GetUser()); + Reference<NickCore> nc_reference(source.nc); c->Execute(source, params); if (had_u == user_reference && had_nc == nc_reference) { diff --git a/src/config.cpp b/src/config.cpp index be12c3479..48126cf7d 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -7,11 +7,11 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" #include "config.h" -#include "extern.h" #include "bots.h" #include "access.h" #include "opertype.h" @@ -28,7 +28,7 @@ /*************************************************************************/ -ConfigurationFile services_conf("services.conf", false); // Services configuration file name +ConfigurationFile ServicesConf("services.conf", false); // Services configuration file name ServerConfig *Config = NULL; static Anope::string UlineServers; @@ -38,7 +38,7 @@ static Anope::string NSDefaults; /*************************************************************************/ -ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), CSDefFlags(ChannelInfoFlagStrings), BSDefFlags(BotServFlagStrings) +ServerConfig::ServerConfig() { this->Read(); @@ -173,7 +173,7 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C if (this->Seed == 0) Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!"; - SetDefaultMLock(this); + ModeManager::UpdateDefaultMLock(this); if (IsFile(this->NameServer)) { @@ -208,8 +208,8 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C this->NameServer = "127.0.0.1"; } } - delete DNSEngine; - DNSEngine = new DNSManager(this->NameServer, this->DNSIP, this->DNSPort); + delete DNS::Engine; + DNS::Engine = new DNS::Manager(this->NameServer, this->DNSIP, this->DNSPort); if (this->CaseMap == "ascii") Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>()); @@ -363,27 +363,27 @@ void ServerConfig::ValidateHostname(const Anope::string &p, const Anope::string } } -bool ValidateNotEmpty(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +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!"); return true; } -bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) { - if (!data.GetInteger() && dotime(data.GetValue()) <= 0) + if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0) throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero!"); return true; } -bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (!config->NSRegistration.equals_ci("none") && !config->NSRegistration.equals_ci("disable")) { if (value.equals_ci("unconfirmedexpire")) { - if (!data.GetInteger() && dotime(data.GetValue()) <= 0) + 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 @@ -395,7 +395,7 @@ bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anop return true; } -bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data) { int port = data.GetInteger(); if (!port) @@ -405,7 +405,7 @@ bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string return true; } -bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data) +static bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data) { int bantype = data.GetInteger(); if (bantype < 0 || bantype > 3) @@ -413,7 +413,7 @@ bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string return true; } -bool ValidateNickServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateNickServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (!config->NickServ.empty()) { @@ -434,7 +434,7 @@ bool ValidateNickServ(ServerConfig *config, const Anope::string &tag, const Anop return true; } -bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (!config->ChanServ.empty()) { @@ -448,31 +448,13 @@ bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anop return true; } -bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) -{ - if (!config->MemoServ.empty()) - { - if (value.equals_ci("description")) - { - if (data.GetValue().empty()) - throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when MemoServ is enabled!"); - } - } - return true; -} - -bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (!config->BotServ.empty()) { - if (value.equals_ci("description")) + if (value.equals_ci("badwordsmax") || value.equals_ci("keepdata")) { - if (data.GetValue().empty()) - throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when BotServ is enabled!"); - } - else if (value.equals_ci("badwordsmax") || value.equals_ci("keepdata")) - { - if (!data.GetInteger() && dotime(data.GetValue()) <= 0) + 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")) @@ -484,36 +466,24 @@ bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope return true; } -bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) -{ - if (!config->HostServ.empty()) - { - if (value.equals_ci("description") && data.GetValue().empty()) - throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when HostServ is enabled!"); - } - return true; -} - -bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (config->LimitSessions) { if (value.equals_ci("maxsessionlimit") || value.equals_ci("exceptionexpiry")) { - if (!data.GetInteger() && dotime(data.GetValue()) <= 0) + 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; } -bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (!config->OperServ.empty()) { - if (value.equals_ci("description") && data.GetValue().empty()) - throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when OperServ is enabled!"); - else if (value.equals_ci("autokillexpiry") || value.equals_ci("chankillexpiry") || value.equals_ci("snlineexpiry") || value.equals_ci("sqlineexpiry")) + 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); @@ -521,17 +491,7 @@ bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anop return true; } -bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) -{ - if (!config->Global.empty()) - { - if (value.equals_ci("description") && data.GetValue().empty()) - throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when Global is enabled!"); - } - return true; -} - -bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data) +static bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data) { int nicklen = data.GetInteger(); if (!nicklen) @@ -548,7 +508,7 @@ bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string return true; } -bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (config->UseMail) { @@ -561,7 +521,7 @@ bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::s return true; } -bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) +static bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data) { if (config->GlobalOnCycle) { @@ -574,7 +534,7 @@ bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const return true; } -bool InitUplinks(ServerConfig *config, const Anope::string &) +static bool InitUplinks(ServerConfig *config, const Anope::string &) { if (!config->Uplinks.empty()) { @@ -722,7 +682,7 @@ static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::str o->config = true; o->password = password; o->certfp = certfp; - o->hosts = BuildStringVector(host); + spacesepstream(host).GetTokens(o->hosts); o->vhost = vhost; config->Opers.push_back(o); @@ -735,7 +695,7 @@ static bool DoneOpers(ServerConfig *config, const Anope::string &) { Oper *o = config->Opers[i]; - const NickAlias *na = findnick(o->name); + const NickAlias *na = NickAlias::Find(o->name); if (!na) // Nonexistant nick continue; @@ -796,7 +756,7 @@ static bool DoneInclude(ServerConfig *config, const Anope::string &) /*************************************************************************/ -bool InitModules(ServerConfig *, const Anope::string &) +static bool InitModules(ServerConfig *, const Anope::string &) { return true; } @@ -826,7 +786,7 @@ static bool DoneModules(ServerConfig *config, const Anope::string &) return true; } -bool InitLogs(ServerConfig *config, const Anope::string &) +static bool InitLogs(ServerConfig *config, const Anope::string &) { config->LogInfos.clear(); return true; @@ -853,15 +813,15 @@ static bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::str bool ldebug = values[11].GetBool(); LogInfo *l = new LogInfo(logage, rawio, ldebug); - l->Targets = BuildStringList(targets); - l->Sources = BuildStringList(source); - l->Admin = BuildStringList(admin); - l->Override = BuildStringList(override); - l->Commands = BuildStringList(commands); - l->Servers = BuildStringList(servers); - l->Channels = BuildStringList(channels); - l->Users = BuildStringList(users); - l->Normal = BuildStringList(normal); + 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); @@ -909,7 +869,7 @@ static bool DoCommands(ServerConfig *config, const Anope::string &, const Anope: 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 = findbot(service); + BotInfo *bi = BotInfo::Find(service); if (bi == NULL) throw ConfigException("Command " + name + " exists for nonexistant service " + service); @@ -992,7 +952,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope: 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 = findbot(nick); + BotInfo* bi = BotInfo::Find(nick); if (!bi) bi = new BotInfo(nick, user, host, gecos, modes); bi->SetFlag(BI_CONF); @@ -1014,7 +974,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope: chname = token.substr(ch); } bi->Join(chname); - Channel *c = findchan(chname); + Channel *c = Channel::Find(chname); if (!c) continue; // Can't happen @@ -1022,7 +982,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope: for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (cm && cm->Type == MODE_STATUS) + if (cm && cm->type == MODE_STATUS) c->RemoveMode(bi, cm, bi->nick); } /* Set the new modes */ @@ -1031,7 +991,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope: ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]); if (cm == NULL) cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j])); - if (cm && cm->Type == MODE_STATUS) + if (cm && cm->type == MODE_STATUS) c->SetMode(bi, cm, bi->GetUID()); } } @@ -1053,7 +1013,7 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope: if (found) continue; - Channel *c = findchan(chname); + Channel *c = Channel::Find(chname); if (c) bi->Part(c); } @@ -1069,7 +1029,7 @@ static bool DoneServices(ServerConfig *config, const Anope::string &) ++it; if (bi->HasFlag(BI_CONF) && services.count(bi->nick) == 0) - bi->destroy(); + bi->Destroy(); } services.clear(); return true; @@ -1123,7 +1083,7 @@ bool ConfigurationFile::IsOpen() const bool ConfigurationFile::Open() { this->Close(); - this->fp = (this->executable ? popen(this->name.c_str(), "r") : fopen((conf_dir + "/" + this->name).c_str(), "r")); + this->fp = (this->executable ? popen(this->name.c_str(), "r") : fopen((Anope::ConfigDir + "/" + this->name).c_str(), "r")); return this->fp != NULL; } @@ -1464,7 +1424,7 @@ 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(services_conf); + this->LoadConf(ServicesConf); ConfigItems configitems(this); @@ -1550,9 +1510,9 @@ void ServerConfig::Read() if (has_value) { #ifdef _WIN32 - long time = static_cast<long>(dotime(item)); + long time = static_cast<long>(Anope::DoTime(item)); #else - time_t time = dotime(item); + time_t time = Anope::DoTime(item); #endif vl.push_back(ValueItem(time)); } @@ -1648,7 +1608,7 @@ void ServerConfig::Read() } case DT_TIME: { - time_t time = dotime(vi.GetValue()); + 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; @@ -1665,10 +1625,10 @@ void ServerConfig::Read() } } - Log(LOG_DEBUG) << "End config " << services_conf.GetName(); + Log(LOG_DEBUG) << "End config " << ServicesConf.GetName(); for (int Index = 0; !Once[Index].empty(); ++Index) CheckOnce(Once[Index]); - Log() << "Done reading configuration file " << services_conf.GetName(); + Log() << "Done reading configuration file " << ServicesConf.GetName(); } void ServerConfig::LoadConf(ConfigurationFile &file) diff --git a/src/configreader.cpp b/src/configreader.cpp index 0bbdb0e49..ddcacfd26 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ /* Taken from: diff --git a/src/dns.cpp b/src/dns.cpp index 29c3134f7..d295aabf0 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -21,11 +22,13 @@ #include <netdb.h> #endif -DNSManager *DNSEngine = NULL; +using namespace DNS; + +Manager *DNS::Engine = NULL; Question::Question() { - this->type = DNS_QUERY_NONE; + this->type = QUERY_NONE; this->qclass = 0; } @@ -45,22 +48,22 @@ ResourceRecord::ResourceRecord(const Question &q) : Question(q) this->created = Anope::CurTime; } -DNSQuery::DNSQuery() +Query::Query() { - this->error = DNS_ERROR_NONE; + this->error = ERROR_NONE; } -DNSQuery::DNSQuery(const Question &q) +Query::Query(const Question &q) { this->questions.push_back(q); - this->error = DNS_ERROR_NONE; + this->error = ERROR_NONE; } -DNSRequest::DNSRequest(const Anope::string &addr, QueryType qt, bool cache, Module *c) : Timer(Config->DNSTimeout), Question(addr, qt), use_cache(cache), id(0), creator(c) +Request::Request(const Anope::string &addr, QueryType qt, bool cache, Module *c) : Timer(Config->DNSTimeout), Question(addr, qt), use_cache(cache), id(0), creator(c) { - if (!DNSEngine || !DNSEngine->udpsock) - throw SocketException("No DNSEngine"); - if (DNSEngine->udpsock->GetPackets().size() == 65535) + if (!DNS::Engine || !DNS::Engine->udpsock) + throw SocketException("No DNS::Engine"); + if (DNS::Engine->udpsock->GetPackets().size() == 65535) throw SocketException("DNS queue full"); do @@ -68,51 +71,51 @@ DNSRequest::DNSRequest(const Anope::string &addr, QueryType qt, bool cache, Modu static unsigned short cur_id = rand(); this->id = cur_id++; } - while (DNSEngine->requests.count(this->id)); + while (DNS::Engine->requests.count(this->id)); - DNSEngine->requests[this->id] = this; + DNS::Engine->requests[this->id] = this; } -DNSRequest::~DNSRequest() +Request::~Request() { - DNSEngine->requests.erase(this->id); + DNS::Engine->requests.erase(this->id); } -void DNSRequest::Process() +void Request::Process() { Log(LOG_DEBUG_2) << "Resolver: Processing request to lookup " << this->name << ", of type " << this->type; - if (!DNSEngine || !DNSEngine->udpsock) - throw SocketException("DNSEngine has not been initialized"); + if (!DNS::Engine || !DNS::Engine->udpsock) + throw SocketException("DNS::Engine has not been initialized"); - if (this->use_cache && DNSEngine->CheckCache(this)) + if (this->use_cache && DNS::Engine->CheckCache(this)) { Log(LOG_DEBUG_2) << "Resolver: Using cached result"; delete this; return; } - DNSPacket *p = new DNSPacket(&DNSEngine->addrs); - p->flags = DNS_QUERYFLAGS_RD; + Packet *p = new Packet(&DNS::Engine->addrs); + p->flags = QUERYFLAGS_RD; p->id = this->id; p->questions.push_back(*this); - DNSEngine->udpsock->Reply(p); + DNS::Engine->udpsock->Reply(p); } -void DNSRequest::OnError(const DNSQuery *r) +void Request::OnError(const Query *r) { } -void DNSRequest::Tick(time_t) +void Request::Tick(time_t) { Log(LOG_DEBUG_2) << "Resolver: timeout for query " << this->name; - DNSQuery rr(*this); - rr.error = DNS_ERROR_TIMEOUT; + Query rr(*this); + rr.error = ERROR_TIMEOUT; this->OnError(&rr); } -void DNSPacket::PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name) +void Packet::PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name) { if (name.length() + 2 > output_size) throw SocketException("Unable to pack name"); @@ -132,7 +135,7 @@ void DNSPacket::PackName(unsigned char *output, unsigned short output_size, unsi output[pos++] = 0; } -Anope::string DNSPacket::UnpackName(const unsigned char *input, unsigned short input_size, unsigned short &pos) +Anope::string Packet::UnpackName(const unsigned char *input, unsigned short input_size, unsigned short &pos) { Anope::string name; unsigned short pos_ptr = pos, lowest_ptr = input_size; @@ -145,9 +148,9 @@ Anope::string DNSPacket::UnpackName(const unsigned char *input, unsigned short i { unsigned short offset = input[pos_ptr]; - if (offset & DNS_POINTER) + if (offset & POINTER) { - if ((offset & DNS_POINTER) != DNS_POINTER) + if ((offset & POINTER) != POINTER) throw SocketException("Unable to unpack name - bogus compression header"); if (pos_ptr + 1 >= input_size) throw SocketException("Unable to unpack name - bogus compression header"); @@ -159,7 +162,7 @@ Anope::string DNSPacket::UnpackName(const unsigned char *input, unsigned short i compressed = true; } - pos_ptr = (offset & DNS_LABEL) << 8 | input[pos_ptr + 1]; + pos_ptr = (offset & LABEL) << 8 | input[pos_ptr + 1]; /* Pointers can only go back */ if (pos_ptr >= lowest_ptr) @@ -190,7 +193,7 @@ Anope::string DNSPacket::UnpackName(const unsigned char *input, unsigned short i return name; } -Question DNSPacket::UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos) +Question Packet::UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos) { Question question; @@ -208,7 +211,7 @@ Question DNSPacket::UnpackQuestion(const unsigned char *input, unsigned short in return question; } -ResourceRecord DNSPacket::UnpackResourceRecord(const unsigned char *input, unsigned short input_size, unsigned short &pos) +ResourceRecord Packet::UnpackResourceRecord(const unsigned char *input, unsigned short input_size, unsigned short &pos) { ResourceRecord record = static_cast<ResourceRecord>(this->UnpackQuestion(input, input_size, pos)); @@ -223,7 +226,7 @@ ResourceRecord DNSPacket::UnpackResourceRecord(const unsigned char *input, unsig switch (record.type) { - case DNS_QUERY_A: + case QUERY_A: { if (pos + 4 > input_size) throw SocketException("Unable to unpack resource record"); @@ -238,7 +241,7 @@ ResourceRecord DNSPacket::UnpackResourceRecord(const unsigned char *input, unsig record.rdata = addrs.addr(); break; } - case DNS_QUERY_AAAA: + case QUERY_AAAA: { if (pos + 16 > input_size) throw SocketException("Unable to unpack resource record"); @@ -254,8 +257,8 @@ ResourceRecord DNSPacket::UnpackResourceRecord(const unsigned char *input, unsig record.rdata = addrs.addr(); break; } - case DNS_QUERY_CNAME: - case DNS_QUERY_PTR: + case QUERY_CNAME: + case QUERY_PTR: { record.rdata = this->UnpackName(input, input_size, pos); break; @@ -269,15 +272,15 @@ ResourceRecord DNSPacket::UnpackResourceRecord(const unsigned char *input, unsig return record; } -DNSPacket::DNSPacket(sockaddrs *a) : DNSQuery(), id(0), flags(0) +Packet::Packet(sockaddrs *a) : Query(), id(0), flags(0) { if (a) addr = *a; } -void DNSPacket::Fill(const unsigned char *input, const unsigned short len) +void Packet::Fill(const unsigned char *input, const unsigned short len) { - if (len < DNSPacket::HEADER_LENGTH) + if (len < Packet::HEADER_LENGTH) throw SocketException("Unable to fill packet"); unsigned short packet_pos = 0; @@ -315,9 +318,9 @@ void DNSPacket::Fill(const unsigned char *input, const unsigned short len) this->additional.push_back(this->UnpackResourceRecord(input, len, packet_pos)); } -unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size) +unsigned short Packet::Pack(unsigned char *output, unsigned short output_size) { - if (output_size < DNSPacket::HEADER_LENGTH) + if (output_size < Packet::HEADER_LENGTH) throw SocketException("Unable to pack packet"); unsigned short pos = 0; @@ -339,7 +342,7 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size { Question &q = this->questions[i]; - if (q.type == DNS_QUERY_PTR) + if (q.type == QUERY_PTR) { sockaddrs ip(q.name); @@ -411,7 +414,7 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size switch (rr.type) { - case DNS_QUERY_A: + case QUERY_A: { if (pos + 6 > output_size) throw SocketException("Unable to pack packet"); @@ -426,7 +429,7 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size pos += 4; break; } - case DNS_QUERY_AAAA: + case QUERY_AAAA: { if (pos + 18 > output_size) throw SocketException("Unable to pack packet"); @@ -441,9 +444,9 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size pos += 16; break; } - case DNS_QUERY_NS: - case DNS_QUERY_CNAME: - case DNS_QUERY_PTR: + case QUERY_NS: + case QUERY_CNAME: + case QUERY_PTR: { if (pos + 2 >= output_size) throw SocketException("Unable to pack packet"); @@ -457,7 +460,7 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size memcpy(&output[packet_pos_save], &s, 2); break; } - case DNS_QUERY_SOA: + case QUERY_SOA: { if (pos + 2 >= output_size) throw SocketException("Unable to pack packet"); @@ -471,7 +474,7 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size if (pos + 20 >= output_size) throw SocketException("Unable to pack SOA"); - l = htonl(DNSEngine->GetSerial()); + l = htonl(DNS::Engine->GetSerial()); memcpy(&output[pos], &l, 4); pos += 4; @@ -504,25 +507,25 @@ unsigned short DNSPacket::Pack(unsigned char *output, unsigned short output_size return pos; } -DNSManager::TCPSocket::Client::Client(TCPSocket *ls, int fd, const sockaddrs &addr) : Socket(fd, ls->IsIPv6()), ClientSocket(ls, addr), Timer(5), tcpsock(ls), packet(NULL), length(0) +Manager::TCPSocket::Client::Client(TCPSocket *l, int fd, const sockaddrs &addr) : Socket(fd, l->IsIPv6()), ClientSocket(l, addr), Timer(5), tcpsock(l), packet(NULL), length(0) { Log(LOG_DEBUG_2) << "Resolver: New client from " << addr.addr(); } -DNSManager::TCPSocket::Client::~Client() +Manager::TCPSocket::Client::~Client() { Log(LOG_DEBUG_2) << "Resolver: Exiting client from " << clientaddr.addr(); delete packet; } -void DNSManager::TCPSocket::Client::Reply(DNSPacket *p) +void Manager::TCPSocket::Client::Reply(Packet *p) { delete packet; packet = p; SocketEngine::Change(this, true, SF_WRITABLE); } -bool DNSManager::TCPSocket::Client::ProcessRead() +bool Manager::TCPSocket::Client::ProcessRead() { Log(LOG_DEBUG_2) << "Resolver: Reading from DNS TCP socket"; @@ -536,12 +539,12 @@ bool DNSManager::TCPSocket::Client::ProcessRead() if (length >= want_len - 2) { SocketEngine::Change(this, false, SF_READABLE); - return DNSEngine->HandlePacket(this, packet_buffer + 2, length - 2, NULL); + return DNS::Engine->HandlePacket(this, packet_buffer + 2, length - 2, NULL); } return true; } -bool DNSManager::TCPSocket::Client::ProcessWrite() +bool Manager::TCPSocket::Client::ProcessWrite() { Log(LOG_DEBUG_2) << "Resolver: Writing to DNS TCP socket"; @@ -568,32 +571,32 @@ bool DNSManager::TCPSocket::Client::ProcessWrite() return true; /* Do not return false here, bind is unhappy we close the connection so soon after sending */ } -DNSManager::TCPSocket::TCPSocket(const Anope::string &ip, int port) : Socket(-1, ip.find(':') != Anope::string::npos), ListenSocket(ip, port, ip.find(':') != Anope::string::npos) +Manager::TCPSocket::TCPSocket(const Anope::string &ip, int port) : Socket(-1, ip.find(':') != Anope::string::npos), ListenSocket(ip, port, ip.find(':') != Anope::string::npos) { } -ClientSocket *DNSManager::TCPSocket::OnAccept(int fd, const sockaddrs &addr) +ClientSocket *Manager::TCPSocket::OnAccept(int fd, const sockaddrs &addr) { return new Client(this, fd, addr); } -DNSManager::UDPSocket::UDPSocket(const Anope::string &ip, int port) : Socket(-1, ip.find(':') != Anope::string::npos, SOCK_DGRAM) +Manager::UDPSocket::UDPSocket(const Anope::string &ip, int port) : Socket(-1, ip.find(':') != Anope::string::npos, SOCK_DGRAM) { } -DNSManager::UDPSocket::~UDPSocket() +Manager::UDPSocket::~UDPSocket() { for (unsigned i = 0; i < packets.size(); ++i) delete packets[i]; } -void DNSManager::UDPSocket::Reply(DNSPacket *p) +void Manager::UDPSocket::Reply(Packet *p) { packets.push_back(p); SocketEngine::Change(this, true, SF_WRITABLE); } -bool DNSManager::UDPSocket::ProcessRead() +bool Manager::UDPSocket::ProcessRead() { Log(LOG_DEBUG_2) << "Resolver: Reading from DNS UDP socket"; @@ -601,14 +604,14 @@ bool DNSManager::UDPSocket::ProcessRead() sockaddrs from_server; socklen_t x = sizeof(from_server); int length = recvfrom(this->GetFD(), reinterpret_cast<char *>(&packet_buffer), sizeof(packet_buffer), 0, &from_server.sa, &x); - return DNSEngine->HandlePacket(this, packet_buffer, length, &from_server); + return DNS::Engine->HandlePacket(this, packet_buffer, length, &from_server); } -bool DNSManager::UDPSocket::ProcessWrite() +bool Manager::UDPSocket::ProcessWrite() { Log(LOG_DEBUG_2) << "Resolver: Writing to DNS UDP socket"; - DNSPacket *r = !packets.empty() ? packets.front() : NULL; + Packet *r = !packets.empty() ? packets.front() : NULL; if (r != NULL) { try @@ -630,7 +633,7 @@ bool DNSManager::UDPSocket::ProcessWrite() return true; } -DNSManager::DNSManager(const Anope::string &nameserver, const Anope::string &ip, int port) : Timer(300, Anope::CurTime, true), listen(false), serial(0), tcpsock(NULL), udpsock(NULL) +Manager::Manager(const Anope::string &nameserver, const Anope::string &ip, int port) : Timer(300, Anope::CurTime, true), listen(false), serial(0), tcpsock(NULL), udpsock(NULL) { this->addrs.pton(nameserver.find(':') != Anope::string::npos ? AF_INET6 : AF_INET, nameserver, port); @@ -640,7 +643,7 @@ DNSManager::DNSManager(const Anope::string &nameserver, const Anope::string &ip, } catch (const SocketException &ex) { - Log() << "Unable to create socket for DNSManager: " << ex.GetReason(); + Log() << "Unable to create socket for Manager: " << ex.GetReason(); } try @@ -652,23 +655,23 @@ DNSManager::DNSManager(const Anope::string &nameserver, const Anope::string &ip, catch (const SocketException &ex) { /* This error can be from normal operation as most people don't use services to handle DNS queries, so put it in debug log */ - Log(LOG_DEBUG) << "Unable to bind DNSManager to port " << port << ": " << ex.GetReason(); + Log(LOG_DEBUG) << "Unable to bind Manager to port " << port << ": " << ex.GetReason(); } this->UpdateSerial(); } -DNSManager::~DNSManager() +Manager::~Manager() { delete udpsock; delete tcpsock; - for (std::map<unsigned short, DNSRequest *>::iterator it = this->requests.begin(), it_end = this->requests.end(); it != it_end; ++it) + for (std::map<unsigned short, Request *>::iterator it = this->requests.begin(), it_end = this->requests.end(); it != it_end; ++it) { - DNSRequest *request = it->second; + Request *request = it->second; - DNSQuery rr(*request); - rr.error = DNS_ERROR_UNKNOWN; + Query rr(*request); + rr.error = ERROR_UNKNOWN; request->OnError(&rr); delete request; @@ -677,15 +680,15 @@ DNSManager::~DNSManager() this->cache.clear(); - DNSEngine = NULL; + DNS::Engine = NULL; } -bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_buffer, int length, sockaddrs *from) +bool Manager::HandlePacket(ReplySocket *s, const unsigned char *const packet_buffer, int length, sockaddrs *from) { - if (length < DNSPacket::HEADER_LENGTH) + if (length < Packet::HEADER_LENGTH) return true; - DNSPacket recv_packet(from); + Packet recv_packet(from); try { @@ -697,7 +700,7 @@ bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_ return true; } - if (!(recv_packet.flags & DNS_QUERYFLAGS_QR)) + if (!(recv_packet.flags & QUERYFLAGS_QR)) { if (!listen) return true; @@ -707,9 +710,9 @@ bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_ return true; } - DNSPacket *packet = new DNSPacket(recv_packet); - packet->flags |= DNS_QUERYFLAGS_QR; /* This is a reponse */ - packet->flags |= DNS_QUERYFLAGS_AA; /* And we are authoritative */ + Packet *packet = new Packet(recv_packet); + packet->flags |= QUERYFLAGS_QR; /* This is a reponse */ + packet->flags |= QUERYFLAGS_AA; /* And we are authoritative */ packet->answers.clear(); packet->authorities.clear(); @@ -719,14 +722,14 @@ bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_ { const Question& q = recv_packet.questions[i]; - if (q.type == DNS_QUERY_AXFR || q.type == DNS_QUERY_SOA) + if (q.type == QUERY_AXFR || q.type == QUERY_SOA) { - ResourceRecord rr(q.name, DNS_QUERY_SOA); + ResourceRecord rr(q.name, QUERY_SOA); packet->answers.push_back(rr); - if (q.type == DNS_QUERY_AXFR) + if (q.type == QUERY_AXFR) { - ResourceRecord rr2(q.name, DNS_QUERY_NS); + ResourceRecord rr2(q.name, QUERY_NS); rr2.rdata = Config->DNSSOANS; packet->answers.push_back(rr2); } @@ -740,9 +743,9 @@ bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_ { const Question& q = recv_packet.questions[i]; - if (q.type == DNS_QUERY_AXFR) + if (q.type == QUERY_AXFR) { - ResourceRecord rr(q.name, DNS_QUERY_SOA); + ResourceRecord rr(q.name, QUERY_SOA); packet->answers.push_back(rr); break; } @@ -763,45 +766,45 @@ bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_ return true; } - std::map<unsigned short, DNSRequest *>::iterator it = DNSEngine->requests.find(recv_packet.id); - if (it == DNSEngine->requests.end()) + std::map<unsigned short, Request *>::iterator it = DNS::Engine->requests.find(recv_packet.id); + if (it == DNS::Engine->requests.end()) { Log(LOG_DEBUG_2) << "Resolver: Received an answer for something we didn't request"; return true; } - DNSRequest *request = it->second; + Request *request = it->second; - if (recv_packet.flags & DNS_QUERYFLAGS_OPCODE) + if (recv_packet.flags & QUERYFLAGS_OPCODE) { Log(LOG_DEBUG_2) << "Resolver: Received a nonstandard query"; - recv_packet.error = DNS_ERROR_NONSTANDARD_QUERY; + recv_packet.error = ERROR_NONSTANDARD_QUERY; request->OnError(&recv_packet); } - else if (recv_packet.flags & DNS_QUERYFLAGS_RCODE) + else if (recv_packet.flags & QUERYFLAGS_RCODE) { - DNSError error = DNS_ERROR_UNKNOWN; + Error error = ERROR_UNKNOWN; - switch (recv_packet.flags & DNS_QUERYFLAGS_RCODE) + switch (recv_packet.flags & QUERYFLAGS_RCODE) { case 1: Log(LOG_DEBUG_2) << "Resolver: format error"; - error = DNS_ERROR_FORMAT_ERROR; + error = ERROR_FORMAT_ERROR; break; case 2: Log(LOG_DEBUG_2) << "Resolver: server error"; - error = DNS_ERROR_SERVER_FAILURE; + error = ERROR_SERVER_FAILURE; break; case 3: Log(LOG_DEBUG_2) << "Resolver: domain not found"; - error = DNS_ERROR_DOMAIN_NOT_FOUND; + error = ERROR_DOMAIN_NOT_FOUND; break; case 4: Log(LOG_DEBUG_2) << "Resolver: not implemented"; - error = DNS_ERROR_NOT_IMPLEMENTED; + error = ERROR_NOT_IMPLEMENTED; break; case 5: Log(LOG_DEBUG_2) << "Resolver: refused"; - error = DNS_ERROR_REFUSED; + error = ERROR_REFUSED; break; default: break; @@ -813,21 +816,21 @@ bool DNSManager::HandlePacket(ReplySocket *s, const unsigned char *const packet_ else if (recv_packet.answers.empty()) { Log(LOG_DEBUG_2) << "Resolver: No resource records returned"; - recv_packet.error = DNS_ERROR_NO_RECORDS; + recv_packet.error = ERROR_NO_RECORDS; request->OnError(&recv_packet); } else { Log(LOG_DEBUG_2) << "Resolver: Lookup complete for " << request->name; request->OnLookupComplete(&recv_packet); - DNSEngine->AddCache(recv_packet); + DNS::Engine->AddCache(recv_packet); } delete request; return true; } -void DNSManager::AddCache(DNSQuery &r) +void Manager::AddCache(Query &r) { for (unsigned i = 0; i < r.answers.size(); ++i) { @@ -837,12 +840,12 @@ void DNSManager::AddCache(DNSQuery &r) } } -bool DNSManager::CheckCache(DNSRequest *request) +bool Manager::CheckCache(Request *request) { cache_map::iterator it = this->cache.find(request->name); if (it != this->cache.end()) { - DNSQuery record(*request); + Query record(*request); for (cache_map::iterator it_end = this->cache.upper_bound(request->name); it != it_end; ++it) { @@ -862,7 +865,7 @@ bool DNSManager::CheckCache(DNSRequest *request) return false; } -void DNSManager::Tick(time_t now) +void Manager::Tick(time_t now) { Log(LOG_DEBUG_2) << "Resolver: Purging DNS cache"; @@ -877,18 +880,18 @@ void DNSManager::Tick(time_t now) } } -void DNSManager::Cleanup(Module *mod) +void Manager::Cleanup(Module *mod) { - for (std::map<unsigned short, DNSRequest *>::iterator it = this->requests.begin(), it_end = this->requests.end(); it != it_end;) + for (std::map<unsigned short, Request *>::iterator it = this->requests.begin(), it_end = this->requests.end(); it != it_end;) { unsigned short id = it->first; - DNSRequest *req = it->second; + Request *req = it->second; ++it; if (req->creator && req->creator == mod) { - DNSQuery rr(*req); - rr.error = DNS_ERROR_UNLOADED; + Query rr(*req); + rr.error = ERROR_UNLOADED; req->OnError(&rr); delete req; @@ -897,25 +900,25 @@ void DNSManager::Cleanup(Module *mod) } } -void DNSManager::UpdateSerial() +void Manager::UpdateSerial() { serial = Anope::CurTime; } -uint32_t DNSManager::GetSerial() const +uint32_t Manager::GetSerial() const { return serial; } -DNSQuery DNSManager::BlockingQuery(const Anope::string &mask, QueryType qt) +Query Manager::BlockingQuery(const Anope::string &mask, QueryType qt) { Question question(mask, qt); - DNSQuery result(question); + Query result(question); int type = AF_UNSPEC; - if (qt == DNS_QUERY_A) + if (qt == QUERY_A) type = AF_INET; - else if (qt == DNS_QUERY_AAAA) + else if (qt == QUERY_AAAA) type = AF_INET6; addrinfo hints; diff --git a/src/encrypt.cpp b/src/encrypt.cpp index 154f600bf..0227be2ef 100644 --- a/src/encrypt.cpp +++ b/src/encrypt.cpp @@ -1,4 +1,4 @@ -/* Include file for high-level encryption routines. +/* * * (C) 2003-2012 Anope Team * Contact us at team@anope.org @@ -7,11 +7,11 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" #include "modules.h" -#include "extern.h" /******************************************************************************/ @@ -19,7 +19,7 @@ * @param src The source string * @param dest The destination strnig */ -void enc_encrypt(const Anope::string &src, Anope::string &dest) +void Anope::Encrypt(const Anope::string &src, Anope::string &dest) { EventReturn MOD_RESULT; FOREACH_RESULT(I_OnEncrypt, OnEncrypt(src, dest)); @@ -30,12 +30,12 @@ void enc_encrypt(const Anope::string &src, Anope::string &dest) * @param desc The destination string * @return true on success */ -bool enc_decrypt(const Anope::string &src, Anope::string &dest) +bool Anope::Decrypt(const Anope::string &src, Anope::string &dest) { size_t pos = src.find(':'); if (pos == Anope::string::npos) { - Log() << "Error: enc_decrypt() called with invalid password string (" << src << ")"; + Log() << "Error: Anope::Decrypt() called with invalid password string (" << src << ")"; return false; } Anope::string hashm(src.begin(), src.begin() + pos); diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 7ce28df13..2875a52df 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -1,11 +1,10 @@ /* + * * Copyright (C) 2002-2011 InspIRCd Development Team * Copyright (C) 2008-2012 Anope Team <team@anope.org> * * Please read COPYING and README for further details. * - * These classes have been copied from InspIRCd and modified - * for use in Anope. */ #include "services.h" @@ -70,11 +69,6 @@ const char *ci::ci_char_traits::find(const char *s1, int n, char c) return n >= 0 ? s1 : NULL; } -/** Compare two Anope::strings as ci::strings and find which one is less - * @param s1 The first string - * @param s2 The second string - * @return true if s1 < s2, else false - */ bool ci::less::operator()(const Anope::string &s1, const Anope::string &s2) const { return s1.ci_str().compare(s2.ci_str()) < 0; @@ -111,6 +105,34 @@ bool sepstream::GetToken(Anope::string &token) return false; } +bool sepstream::GetToken(Anope::string &token, int num) +{ + int i; + for (i = 0; i < num + 1 && !this->GetToken(token); ++i); + return i == num + 1; +} + +int sepstream::NumTokens() +{ + int i; + Anope::string token; + for (i = 0; this->GetToken(token); ++i); + return i; +} + +bool sepstream::GetTokenRemainder(Anope::string &token, int num) +{ + if (this->GetToken(token, num)) + { + if (!this->StreamEnd()) + token += sep + this->GetRemaining(); + + return true; + } + + return false; +} + const Anope::string sepstream::GetRemaining() { return Anope::string(n, tokens.end()); diff --git a/src/init.cpp b/src/init.cpp index 94ac7feb2..e831351ec 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -7,64 +7,26 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" #include "config.h" -#include "extern.h" #include "users.h" #include "protocol.h" #include "bots.h" -#include "oper.h" +#include "xline.h" #include "signals.h" #include "socketengine.h" #include "servers.h" +#include "language.h" #ifndef _WIN32 #include <sys/wait.h> #include <sys/stat.h> #endif -Anope::string conf_dir = "conf", db_dir = "data", modules_dir = "lib", locale_dir = "locale", log_dir = "logs"; - -ServerConfig::Uplink *uplink_server; - -void introduce_user(const Anope::string &user) -{ - /* Watch out for infinite loops... */ - time_t now = Anope::CurTime; - static time_t lasttime = now - 4; - if (lasttime >= now - 3) - { - quitmsg = "introduce_user loop detected"; - quitting = true; - return; - } - lasttime = now; - - User *u = finduser(user); - if (u) - { - BotInfo *bi = findbot(u->nick); - if (bi) - { - XLine x(bi->nick, "Reserved for services"); - ircdproto->SendSQLine(NULL, &x); - } - - ircdproto->SendClientIntroduction(u); - - if (bi) - { - bi->introduced = true; - - for (UChannelList::const_iterator cit = bi->chans.begin(), cit_end = bi->chans.end(); cit != cit_end; ++cit) - ircdproto->SendJoin(bi, (*cit)->chan, &Config->BotModeList); - } - } -} - -/*************************************************************************/ +Anope::string Anope::ConfigDir = "conf", Anope::DataDir = "data", Anope::ModuleDir = "lib", Anope::LocaleDir = "locale", Anope::LogDir = "logs"; /* Vector of pairs of command line arguments and their params */ static std::vector<std::pair<Anope::string, Anope::string> > CommandLineArguments; @@ -96,24 +58,13 @@ static void ParseCommandLineArguments(int ac, char **av) } } -/** Check if an argument was given on startup - * @param name The argument name - * @param shortname A shorter name, eg --debug and -d - * @return true if name/shortname was found, false if not - */ -bool GetCommandLineArgument(const Anope::string &name, char shortname) -{ - Anope::string Unused; - return GetCommandLineArgument(name, shortname, Unused); -} - /** Check if an argument was given on startup and its parameter * @param name The argument name * @param shortname A shorter name, eg --debug and -d * @param param A string to put the param, if any, of the argument * @return true if name/shortname was found, false if not */ -bool GetCommandLineArgument(const Anope::string &name, char shortname, Anope::string ¶m) +static bool GetCommandLineArgument(const Anope::string &name, char shortname, Anope::string ¶m) { param.clear(); @@ -129,6 +80,17 @@ bool GetCommandLineArgument(const Anope::string &name, char shortname, Anope::st return false; } +/** Check if an argument was given on startup + * @param name The argument name + * @param shortname A shorter name, eg --debug and -d + * @return true if name/shortname was found, false if not + */ +static bool GetCommandLineArgument(const Anope::string &name, char shortname = 0) +{ + Anope::string Unused; + return GetCommandLineArgument(name, shortname, Unused); +} + /*************************************************************************/ /* Remove our PID file. Done at exit. */ @@ -156,7 +118,7 @@ static void write_pidfile() atexit(remove_pidfile); } else - throw FatalException("Can not write to PID file " + Config->PIDFilename); + throw CoreException("Can not write to PID file " + Config->PIDFilename); } /*************************************************************************/ @@ -170,7 +132,7 @@ class SignalReload : public Signal { Log() << "Received SIGHUP: Saving databases & rehashing configuration"; - save_databases(); + Anope::SaveDatabases(); ServerConfig *old_config = Config; try @@ -196,14 +158,13 @@ class SignalExit : public Signal { #ifndef _WIN32 Log() << "Received " << strsignal(this->signal) << " signal (" << this->signal << "), exiting."; - quitmsg = Anope::string("Services terminating via signal ") + strsignal(this->signal) + " (" + stringify(this->signal) + ")"; + Anope::QuitReason = Anope::string("Services terminating via signal ") + strsignal(this->signal) + " (" + stringify(this->signal) + ")"; #else Log() << "Received signal " << this->signal << ", exiting."; - quitmsg = Anope::string("Services terminating via signal ") + stringify(this->signal); + Anope::QuitReason = Anope::string("Services terminating via signal ") + stringify(this->signal); #endif - - quitting = true; - save_databases(); + Anope::SaveDatabases(); + Anope::Quitting = true; } }; @@ -215,12 +176,12 @@ class SignalNothing : public Signal void OnNotify() { } }; -bool AtTerm() +bool Anope::AtTerm() { return isatty(fileno(stdout)) && isatty(fileno(stdin)) && isatty(fileno(stderr)); } -void Fork() +void Anope::Fork() { #ifndef _WIN32 kill(getppid(), SIGUSR2); @@ -240,29 +201,28 @@ static void parent_signal_handler(int signal) { if (signal == SIGUSR2) { - quitting = true; - return_code = 0; + Anope::Quitting = true; } else if (signal == SIGCHLD) { - quitting = true; - return_code = -1; + Anope::ReturnValue = -1; + Anope::Quitting = true; int status = 0; wait(&status); if (WIFEXITED(status)) - return_code = WEXITSTATUS(status); + Anope::ReturnValue = WEXITSTATUS(status); } } #endif -void Init(int ac, char **av) +void Anope::Init(int ac, char **av) { /* Set file creation mask and group ID. */ #if defined(DEFUMASK) && HAVE_UMASK umask(DEFUMASK); #endif - RegisterTypes(); + Serialize::RegisterTypes(); /* Parse command line arguments */ ParseCommandLineArguments(ac, av); @@ -270,14 +230,14 @@ void Init(int ac, char **av) if (GetCommandLineArgument("version", 'v')) { Log(LOG_TERMINAL) << "Anope-" << Anope::Version() << " -- " << Anope::VersionBuildString(); - throw FatalException(); + throw CoreException(); } if (GetCommandLineArgument("help", 'h')) { Log(LOG_TERMINAL) << "Anope-" << Anope::Version() << " -- " << Anope::VersionBuildString(); Log(LOG_TERMINAL) << "Anope IRC Services (http://www.anope.org)"; - Log(LOG_TERMINAL) << "Usage ./" << services_bin << " [options] ..."; + Log(LOG_TERMINAL) << "Usage ./" << Anope::ServicesBin << " [options] ..."; Log(LOG_TERMINAL) << "-c, --config=filename.conf"; Log(LOG_TERMINAL) << " --confdir=conf file direcory"; Log(LOG_TERMINAL) << " --dbdir=database directory"; @@ -296,98 +256,98 @@ void Init(int ac, char **av) Log(LOG_TERMINAL) << ""; Log(LOG_TERMINAL) << "Further support is available from http://www.anope.org"; Log(LOG_TERMINAL) << "Or visit us on IRC at irc.anope.org #anope"; - throw FatalException(); + throw CoreException(); } if (GetCommandLineArgument("nofork", 'n')) - nofork = true; + Anope::NoFork = true; if (GetCommandLineArgument("support", 's')) { - nofork = nothird = true; - ++debug; + Anope::NoFork = Anope::NoThird = true; + ++Anope::Debug; } if (GetCommandLineArgument("readonly", 'r')) - readonly = true; + Anope::ReadOnly = true; if (GetCommandLineArgument("nothird")) - nothird = true; + Anope::NoThird = true; if (GetCommandLineArgument("noexpire", 'e')) - noexpire = true; + Anope::NoExpire = true; if (GetCommandLineArgument("protocoldebug")) - protocoldebug = true; + Anope::ProtocolDebug = true; - Anope::string Arg; - if (GetCommandLineArgument("debug", 'd', Arg)) + Anope::string arg; + if (GetCommandLineArgument("debug", 'd', arg)) { - if (!Arg.empty()) + if (!arg.empty()) { - int level = Arg.is_number_only() ? convertTo<int>(Arg) : -1; + int level = arg.is_number_only() ? convertTo<int>(arg) : -1; if (level > 0) - debug = level; + Anope::Debug = level; else - throw FatalException("Invalid option given to --debug"); + throw CoreException("Invalid option given to --debug"); } else - ++debug; + ++Anope::Debug; } - if (GetCommandLineArgument("config", 'c', Arg)) + if (GetCommandLineArgument("config", 'c', arg)) { - if (Arg.empty()) - throw FatalException("The --config option requires a file name"); - services_conf = ConfigurationFile(Arg, false); + if (arg.empty()) + throw CoreException("The --config option requires a file name"); + ServicesConf = ConfigurationFile(arg, false); } - if (GetCommandLineArgument("confdir", 0, Arg)) + if (GetCommandLineArgument("confdir", 0, arg)) { - if (Arg.empty()) - throw FatalException("The --confdir option requires a path"); - conf_dir = Arg; + if (arg.empty()) + throw CoreException("The --confdir option requires a path"); + Anope::ConfigDir = arg; } - if (GetCommandLineArgument("dbdir", 0, Arg)) + if (GetCommandLineArgument("dbdir", 0, arg)) { - if (Arg.empty()) - throw FatalException("The --dbdir option requires a path"); - db_dir = Arg; + if (arg.empty()) + throw CoreException("The --dbdir option requires a path"); + Anope::DataDir = arg; } - if (GetCommandLineArgument("localedir", 0, Arg)) + if (GetCommandLineArgument("localedir", 0, arg)) { - if (Arg.empty()) - throw FatalException("The --localedir option requires a path"); - locale_dir = Arg; + if (arg.empty()) + throw CoreException("The --localedir option requires a path"); + Anope::LocaleDir = arg; } - if (GetCommandLineArgument("modulesdir", 0, Arg)) + if (GetCommandLineArgument("modulesdir", 0, arg)) { - if (Arg.empty()) - throw FatalException("The --modulesdir option requires a path"); - modules_dir = Arg; + if (arg.empty()) + throw CoreException("The --modulesdir option requires a path"); + Anope::ModuleDir = arg; } - if (GetCommandLineArgument("logdir", 0, Arg)) + if (GetCommandLineArgument("logdir", 0, arg)) { - if (Arg.empty()) - throw FatalException("The --logdir option requires a path"); - log_dir = Arg; + if (arg.empty()) + throw CoreException("The --logdir option requires a path"); + Anope::LogDir = arg; } /* Chdir to Services data directory. */ - if (chdir(services_dir.c_str()) < 0) + if (chdir(Anope::ServicesDir.c_str()) < 0) { - throw FatalException("Unable to chdir to " + services_dir + ": " + Anope::LastError()); + throw CoreException("Unable to chdir to " + Anope::ServicesDir + ": " + Anope::LastError()); } Log(LOG_TERMINAL) << "Anope " << Anope::Version() << ", " << Anope::VersionBuildString(); #ifdef _WIN32 - Log(LOG_TERMINAL) << "Using configuration file " << conf_dir << "\\" << services_conf.GetName(); + Log(LOG_TERMINAL) << "Using configuration file " << Anope::ConfigDir << "\\" << ServicesConf.GetName(); #else - Log(LOG_TERMINAL) << "Using configuration file " << conf_dir << "/" << services_conf.GetName(); + Log(LOG_TERMINAL) << "Using configuration file " << Anope::ConfigDir << "/" << ServicesConf.GetName(); #endif /* Initialize the socket engine */ @@ -405,12 +365,12 @@ void Init(int ac, char **av) Log(LOG_TERMINAL) << "*** documentation. Read the documentation files found in the 'docs'"; Log(LOG_TERMINAL) << "*** folder. Visit our portal located at http://www.anope.org/. Join"; Log(LOG_TERMINAL) << "*** our support channel on /server irc.anope.org channel #anope."; - throw FatalException("Configuration file failed to validate"); + throw CoreException("Configuration file failed to validate"); } #ifdef _WIN32 if (!SupportedWindowsVersion()) - throw FatalException(GetWindowsVersion() + " is not a supported version of Windows"); + throw CoreException(GetWindowsVersion() + " is not a supported version of Windows"); #else /* If we're root, issue a warning now */ if (!getuid() && !getgid()) @@ -421,7 +381,7 @@ void Init(int ac, char **av) sleep(3); } - if (!nofork && AtTerm()) + if (!Anope::NoFork && Anope::AtTerm()) { /* Install these before fork() - it is possible for the child to * connect and kill() the parent before it is able to install the @@ -444,12 +404,12 @@ void Init(int ac, char **av) sigemptyset(&mask); sigsuspend(&mask); - exit(return_code); + exit(Anope::ReturnValue); } else if (i == -1) { Log() << "Error, unable to fork: " << Anope::LastError(); - nofork = true; + Anope::NoFork = true; } /* Child doesn't need these */ @@ -466,11 +426,11 @@ void Init(int ac, char **av) for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) { it->second->server = Me; - ++Me->Users; + ++Me->users; } /* Announce ourselves to the logfile. */ - Log() << "Anope " << Anope::Version() << " starting up" << (debug || readonly ? " (options:" : "") << (debug ? " debug" : "") << (readonly ? " readonly" : "") << (debug || readonly ? ")" : ""); + Log() << "Anope " << Anope::Version() << " starting up" << (Anope::Debug || Anope::ReadOnly ? " (options:" : "") << (Anope::Debug ? " debug" : "") << (Anope::ReadOnly ? " readonly" : "") << (Anope::Debug || Anope::ReadOnly ? ")" : ""); new SignalReload(SIGHUP); new SignalExit(SIGTERM); @@ -478,8 +438,7 @@ void Init(int ac, char **av) new SignalNothing(SIGPIPE); /* Initialize multi-language support */ - Log(LOG_DEBUG) << "Loading Languages..."; - InitLanguages(); + Language::InitLanguages(); /* Initialize random number generator */ srand(Config->Seed); @@ -491,9 +450,9 @@ void Init(int ac, char **av) Module *protocol = ModuleManager::FindFirstOf(PROTOCOL); if (protocol == NULL) - throw FatalException("You must load a protocol module!"); + throw CoreException("You must load a protocol module!"); else if (ModuleManager::FindFirstOf(ENCRYPTION) == NULL) - throw FatalException("You must load at least one encryption module"); + throw CoreException("You must load at least one encryption module"); Log() << "Using IRCd protocol " << protocol->name; diff --git a/src/language.cpp b/src/language.cpp index c62a950aa..1e1f9e704 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -7,65 +7,71 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" #include "modules.h" #include "commands.h" #include "config.h" -#include "extern.h" +#include "language.h" #if GETTEXT_FOUND # include <libintl.h> #endif -std::vector<Anope::string> languages; -std::vector<Anope::string> domains; +std::vector<Anope::string> Language::Languages; +std::vector<Anope::string> Language::Domains; -void InitLanguages() +void Language::InitLanguages() { #if GETTEXT_FOUND - languages.clear(); + Log(LOG_DEBUG) << "Initializing Languages..."; + + Languages.clear(); spacesepstream sep(Config->Languages); Anope::string language; while (sep.GetToken(language)) { - if (!IsFile(locale_dir + "/" + language + "/LC_MESSAGES/anope.mo")) + if (!IsFile(Anope::LocaleDir + "/" + language + "/LC_MESSAGES/anope.mo")) { Log() << "Error loading language " << language << ", file does not exist!"; } else { Log(LOG_DEBUG) << "Found language file " << language; - languages.push_back(language); + Languages.push_back(language); } } - if (!bindtextdomain("anope", locale_dir.c_str())) + if (!bindtextdomain("anope", Anope::LocaleDir.c_str())) Log() << "Error calling bindtextdomain, " << Anope::LastError(); else - Log(LOG_DEBUG) << "Successfully bound anope to " << locale_dir; + Log(LOG_DEBUG) << "Successfully bound anope to " << Anope::LocaleDir; setlocale(LC_ALL, ""); #else - Log() << "Can not load languages, gettext is not installed"; + Log() << "Unable to initialize languages, gettext is not installed"; #endif } -const char *translate(const char *string) +const char *Language::Translate(const char *string) { - return anope_gettext(Config->NSDefLanguage.c_str(), string); + return Translate(Config->NSDefLanguage.c_str(), string); } -const char *translate(User *u, const char *string) +const char *Language::Translate(User *u, const char *string) { - return translate(u ? u->Account() : NULL, string); + if (u && u->Account()) + return Translate(u->Account(), string); + else + return Translate(string); } -const char *translate(const NickCore *nc, const char *string) +const char *Language::Translate(const NickCore *nc, const char *string) { - return anope_gettext(nc ? nc->language.c_str() : Config->NSDefLanguage.c_str(), string); + return Translate(nc ? nc->language.c_str() : Config->NSDefLanguage.c_str(), string); } #if GETTEXT_FOUND @@ -73,7 +79,7 @@ const char *translate(const NickCore *nc, const char *string) /* Used by gettext to make it always dynamically load language strings (so we can drop them in while Anope is running) */ extern "C" int _nl_msg_cat_cntr; -const char *anope_gettext(const char *lang, const char *string) +const char *Language::Translate(const char *lang, const char *string) { if (!string || !*string || !lang || !*lang) return string ? string : ""; @@ -95,8 +101,8 @@ const char *anope_gettext(const char *lang, const char *string) setlocale(LC_ALL, "en_US"); #endif const char *translated_string = dgettext("anope", string); - for (unsigned i = 0; translated_string == string && i < domains.size(); ++i) - translated_string = dgettext(domains[i].c_str(), string); + for (unsigned i = 0; translated_string == string && i < Domains.size(); ++i) + translated_string = dgettext(Domains[i].c_str(), string); #ifdef _WIN32 SetThreadLocale(MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT)); #else @@ -108,7 +114,7 @@ const char *anope_gettext(const char *lang, const char *string) return translated_string; } #else -const char *anope_gettext(const char *lang, const char *string) +const char *Language::Translate(const char *lang, const char *string) { return string != NULL ? string : ""; } diff --git a/src/logger.cpp b/src/logger.cpp index a76430435..f6058ab42 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -15,12 +16,14 @@ #include "channels.h" #include "users.h" #include "logger.h" -#include "extern.h" #include "config.h" #include "bots.h" #include "servers.h" #include "uplink.h" #include "protocol.h" +#include "global.h" +#include "operserv.h" +#include "chanserv.h" #ifndef _WIN32 #include <sys/time.h> @@ -33,9 +36,10 @@ static Anope::string GetTimeStamp() time_t t; if (time(&t) < 0) - throw CoreException("time() failed"); + t = Anope::CurTime; + tm tm = *localtime(&t); - if (debug) + if (Anope::Debug) { char *s; struct timeval tv; @@ -59,7 +63,7 @@ static inline Anope::string CreateLogName(const Anope::string &file, time_t t = strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm); - return log_dir + "/" + file + "." + timestamp; + return Anope::LogDir + "/" + file + "." + timestamp; } LogFile::LogFile(const Anope::string &name) : filename(name), stream(name.c_str(), std::ios_base::out | std::ios_base::app) @@ -71,15 +75,15 @@ Anope::string LogFile::GetName() const return this->filename; } -Log::Log(LogType type, const Anope::string &category, const BotInfo *b) : bi(b), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), Type(type), Category(category) +Log::Log(LogType t, const Anope::string &cat, const BotInfo *b) : bi(b), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), type(t), category(cat) { if (!bi && Config) - bi = findbot(Config->Global); + bi = Global; if (bi) - this->Sources.push_back(bi->nick); + this->sources.push_back(bi->nick); } -Log::Log(LogType type, CommandSource &source, Command *_c, const ChannelInfo *_ci) : nick(source.GetNick()), u(source.GetUser()), nc(source.nc), c(_c), chan(NULL), ci(_ci), s(NULL), m(NULL), Type(type) +Log::Log(LogType t, CommandSource &source, Command *_c, const ChannelInfo *_ci) : nick(source.GetNick()), u(source.GetUser()), nc(source.nc), c(_c), chan(NULL), ci(_ci), s(NULL), m(NULL), type(t) { if (!c) throw CoreException("Invalid pointers passed to Log::Log"); @@ -90,81 +94,80 @@ Log::Log(LogType type, CommandSource &source, Command *_c, const ChannelInfo *_c size_t sl = c->name.find('/'); this->bi = NULL; if (sl != Anope::string::npos) - this->bi = findbot(c->name.substr(0, sl)); + this->bi = BotInfo::Find(c->name.substr(0, sl)); if (this->bi == NULL && Config) - this->bi = findbot(Config->Global); - this->Category = c->name; + this->bi = Global; + this->category = c->name; if (this->bi) - this->Sources.push_back(this->bi->nick); + this->sources.push_back(this->bi->nick); if (u) - this->Sources.push_back(u->nick); - this->Sources.push_back(c->name); + this->sources.push_back(u->nick); + this->sources.push_back(c->name); if (ci) - this->Sources.push_back(ci->name); + this->sources.push_back(ci->name); } -Log::Log(const User *_u, Channel *ch, const Anope::string &category) : bi(NULL), u(_u), nc(NULL), c(NULL), chan(ch), ci(chan ? *chan->ci : NULL), s(NULL), m(NULL), Type(LOG_CHANNEL) +Log::Log(const User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u), nc(NULL), c(NULL), chan(ch), ci(chan ? *chan->ci : NULL), s(NULL), m(NULL), type(LOG_CHANNEL), category(cat) { if (!chan) throw CoreException("Invalid pointers passed to Log::Log"); if (Config) - this->bi = findbot(Config->ChanServ); - this->Category = category; + this->bi = ChanServ; if (this->bi) - this->Sources.push_back(this->bi->nick); + this->sources.push_back(this->bi->nick); if (u) - this->Sources.push_back(u->nick); - this->Sources.push_back(chan->name); + this->sources.push_back(u->nick); + this->sources.push_back(chan->name); } -Log::Log(const User *_u, const Anope::string &category, const BotInfo *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), Type(LOG_USER), Category(category) +Log::Log(const User *_u, const Anope::string &cat, const BotInfo *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat) { if (!u) throw CoreException("Invalid pointers passed to Log::Log"); if (!this->bi && Config) - this->bi = findbot(Config->Global); + this->bi = Global; if (this->bi) - this->Sources.push_back(this->bi->nick); - this->Sources.push_back(u->nick); + this->sources.push_back(this->bi->nick); + this->sources.push_back(u->nick); } -Log::Log(Server *serv, const Anope::string &category, const BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), Type(LOG_SERVER), Category(category) +Log::Log(Server *serv, const Anope::string &cat, const BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat) { if (!s) throw CoreException("Invalid pointer passed to Log::Log"); if (!this->bi && Config) - this->bi = findbot(Config->OperServ); + this->bi = OperServ; if (!this->bi && Config) - this->bi = findbot(Config->Global); + this->bi = Global; if (this->bi) - this->Sources.push_back(this->bi->nick); - this->Sources.push_back(s->GetName()); + this->sources.push_back(this->bi->nick); + this->sources.push_back(s->GetName()); } -Log::Log(const BotInfo *b, const Anope::string &category) : bi(b), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), Type(LOG_NORMAL), Category(category) +Log::Log(const BotInfo *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat) { if (!this->bi && Config) - this->bi = findbot(Config->Global); + this->bi = Global; if (this->bi) - this->Sources.push_back(bi->nick); + this->sources.push_back(bi->nick); } -Log::Log(Module *mod, const Anope::string &category) : bi(NULL), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), Type(LOG_MODULE), Category(category) +Log::Log(Module *mod, const Anope::string &cat) : bi(NULL), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat) { if (m) - this->Sources.push_back(m->name); + this->sources.push_back(m->name); } Log::~Log() { - if (nofork && debug && this->Type >= LOG_NORMAL && this->Type <= LOG_DEBUG + debug - 1) + if (Anope::NoFork && Anope::Debug && this->type >= LOG_NORMAL && this->type <= LOG_DEBUG + Anope::Debug - 1) std::cout << GetTimeStamp() << " Debug: " << this->BuildPrefix() << this->buf.str() << std::endl; - else if (nofork && this->Type <= LOG_TERMINAL) + else if (Anope::NoFork && this->type <= LOG_TERMINAL) std::cout << GetTimeStamp() << " " << this->BuildPrefix() << this->buf.str() << std::endl; - else if (this->Type == LOG_TERMINAL) + else if (this->type == LOG_TERMINAL) std::cout << this->BuildPrefix() << this->buf.str() << std::endl; for (unsigned i = 0; Config && i < Config->LogInfos.size(); ++i) { @@ -178,7 +181,7 @@ Anope::string Log::BuildPrefix() const { Anope::string buffer; - switch (this->Type) + switch (this->type) { case LOG_ADMIN: { @@ -233,9 +236,9 @@ Anope::string Log::BuildPrefix() const break; buffer += "CHANNEL: "; if (this->u) - buffer += this->u->GetMask() + " " + this->Category + " " + this->chan->name + " "; + buffer += this->u->GetMask() + " " + this->category + " " + this->chan->name + " "; else - buffer += this->Category + " " + this->chan->name + " "; + buffer += this->category + " " + this->chan->name + " "; break; } case LOG_USER: @@ -263,13 +266,13 @@ Anope::string Log::BuildPrefix() const return buffer; } -LogInfo::LogInfo(int logage, bool rawio, bool ldebug) : LogAge(logage), RawIO(rawio), Debug(ldebug) +LogInfo::LogInfo(int la, bool rio, bool ldebug) : log_age(la), raw_io(rio), debug(ldebug) { } LogInfo::~LogInfo() { - for (std::map<Anope::string, LogFile *>::iterator it = this->Logfiles.begin(), it_end = this->Logfiles.end(); it != it_end; ++it) + for (std::map<Anope::string, LogFile *>::iterator it = this->logfiles.begin(), it_end = this->logfiles.end(); it != it_end; ++it) { LogFile *f = it->second; @@ -277,7 +280,7 @@ LogInfo::~LogInfo() f->stream.close(); delete f; } - this->Logfiles.clear(); + this->logfiles.clear(); } void LogInfo::AddType(std::list<Anope::string> &list, const Anope::string &type) @@ -300,29 +303,29 @@ bool LogInfo::HasType(LogType ltype, const Anope::string &type) const switch (ltype) { case LOG_ADMIN: - list = &this->Admin; + list = &this->admin; break; case LOG_OVERRIDE: - list = &this->Override; + list = &this->override; break; case LOG_COMMAND: - list = &this->Commands; + list = &this->commands; break; case LOG_SERVER: - list = &this->Servers; + list = &this->servers; break; case LOG_CHANNEL: - list = &this->Channels; + list = &this->channels; break; case LOG_USER: - list = &this->Users; + list = &this->users; break; case LOG_TERMINAL: return true; case LOG_RAWIO: - return debug ? true : this->RawIO; + return debug ? true : this->raw_io; case LOG_DEBUG: - return debug ? true : this->Debug; + return debug ? true : this->debug; case LOG_DEBUG_2: case LOG_DEBUG_3: case LOG_DEBUG_4: @@ -330,7 +333,7 @@ bool LogInfo::HasType(LogType ltype, const Anope::string &type) const case LOG_MODULE: case LOG_NORMAL: default: - list = &this->Normal; + list = &this->normal; break; } @@ -361,15 +364,15 @@ void LogInfo::ProcessMessage(const Log *l) if (!l) throw CoreException("Bad values passed to LogInfo::ProcessMessages"); - else if (!this->HasType(l->Type, l->Category)) + else if (!this->HasType(l->type, l->category)) return; - if (!this->Sources.empty()) + if (!this->sources.empty()) { bool log = false; - for (std::list<Anope::string>::const_iterator it = this->Sources.begin(), it_end = this->Sources.end(); it != it_end; ++it) + for (std::list<Anope::string>::const_iterator it = this->sources.begin(), it_end = this->sources.end(); it != it_end; ++it) { - if (std::find(l->Sources.begin(), l->Sources.end(), *it) != l->Sources.end()) + if (std::find(l->sources.begin(), l->sources.end(), *it) != l->sources.end()) { log = true; break; @@ -379,45 +382,45 @@ void LogInfo::ProcessMessage(const Log *l) return; } - for (std::list<Anope::string>::iterator it = this->Targets.begin(), it_end = this->Targets.end(); it != it_end; ++it) + for (std::list<Anope::string>::iterator it = this->targets.begin(), it_end = this->targets.end(); it != it_end; ++it) { const Anope::string &target = *it; Anope::string buffer = l->BuildPrefix() + l->buf.str(); if (target[0] == '#') { - if (UplinkSock && l->Type <= LOG_NORMAL && Me && Me->IsSynced()) + if (UplinkSock && l->type <= LOG_NORMAL && Me && Me->IsSynced()) { - Channel *c = findchan(target); + Channel *c = Channel::Find(target); if (!c || !l->bi) continue; - ircdproto->SendPrivmsg(l->bi, c->name, "%s", buffer.c_str()); + IRCD->SendPrivmsg(l->bi, c->name, "%s", buffer.c_str()); } } else if (target == "globops") { - if (UplinkSock && l->bi && l->Type <= LOG_NORMAL && Me && Me->IsSynced()) + if (UplinkSock && l->bi && l->type <= LOG_NORMAL && Me && Me->IsSynced()) { - ircdproto->SendGlobops(l->bi, "%s", buffer.c_str()); + IRCD->SendGlobops(l->bi, "%s", buffer.c_str()); } } else { LogFile *log = NULL; - std::map<Anope::string, LogFile *>::iterator lit = this->Logfiles.find(target); - if (lit != this->Logfiles.end()) + std::map<Anope::string, LogFile *>::iterator lit = this->logfiles.find(target); + if (lit != this->logfiles.end()) { log = lit->second; if (log && log->GetName() != CreateLogName(target)) { delete log; - this->Logfiles.erase(lit); + this->logfiles.erase(lit); log = new LogFile(CreateLogName(target)); - this->Logfiles[target] = log; + this->logfiles[target] = log; - if (this->LogAge) + if (this->log_age) { - Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->LogAge); + Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age); if (IsFile(oldlog)) { unlink(oldlog.c_str()); @@ -433,11 +436,11 @@ void LogInfo::ProcessMessage(const Log *l) Log() << "Unable to open logfile " << log->GetName(); } delete log; - this->Logfiles.erase(lit); + this->logfiles.erase(lit); log = NULL; } } - else if (lit == this->Logfiles.end()) + else if (lit == this->logfiles.end()) { log = new LogFile(CreateLogName(target)); @@ -452,7 +455,7 @@ void LogInfo::ProcessMessage(const Log *l) log = NULL; } else - this->Logfiles[target] = log; + this->logfiles[target] = log; } if (log) diff --git a/src/mail.cpp b/src/mail.cpp index 152d525f5..030922f5c 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -7,28 +7,28 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ - #include "services.h" #include "mail.h" #include "config.h" -MailThread::MailThread(const Anope::string &smpath, const Anope::string &sf, const Anope::string &mailto, const Anope::string &addr, const Anope::string &subject, const Anope::string &message) : Thread(), SendMailPath(smpath), SendFrom(sf), MailTo(mailto), Addr(addr), Subject(subject), Message(message), DontQuoteAddresses(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->SendMailPath), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->DontQuoteAddresses), success(false) { } -MailThread::~MailThread() +Mail::Message::~Message() { - if (Success) - Log(LOG_NORMAL, "mail") << "Successfully delivered mail for " << MailTo << " (" << Addr << ")"; + if (success) + Log(LOG_NORMAL, "mail") << "Successfully delivered mail for " << mail_to << " (" << addr << ")"; else - Log(LOG_NORMAL, "mail") << "Error delivering mail for " << MailTo << " (" << Addr << ")"; + Log(LOG_NORMAL, "mail") << "Error delivering mail for " << mail_to << " (" << addr << ")"; } -void MailThread::Run() +void Mail::Message::Run() { - FILE *pipe = popen(SendMailPath.c_str(), "w"); + FILE *pipe = popen(sendmail_path.c_str(), "w"); if (!pipe) { @@ -36,22 +36,22 @@ void MailThread::Run() return; } - fprintf(pipe, "From: %s\n", SendFrom.c_str()); - if (this->DontQuoteAddresses) - fprintf(pipe, "To: %s <%s>\n", MailTo.c_str(), Addr.c_str()); + fprintf(pipe, "From: %s\n", send_from.c_str()); + if (this->dont_quote_addresses) + fprintf(pipe, "To: %s <%s>\n", mail_to.c_str(), addr.c_str()); else - fprintf(pipe, "To: \"%s\" <%s>\n", MailTo.c_str(), Addr.c_str()); - fprintf(pipe, "Subject: %s\n", Subject.c_str()); - fprintf(pipe, "%s", Message.c_str()); + fprintf(pipe, "To: \"%s\" <%s>\n", mail_to.c_str(), addr.c_str()); + fprintf(pipe, "Subject: %s\n", subject.c_str()); + fprintf(pipe, "%s", message.c_str()); fprintf(pipe, "\n.\n"); pclose(pipe); - Success = true; + success = true; SetExitState(); } -bool Mail(User *u, NickCore *nc, const BotInfo *service, const Anope::string &subject, const Anope::string &message) +bool Mail::Send(User *u, NickCore *nc, const BotInfo *service, const Anope::string &subject, const Anope::string &message) { if (!nc || !service || subject.empty() || message.empty()) return false; @@ -64,7 +64,7 @@ bool Mail(User *u, NickCore *nc, const BotInfo *service, const Anope::string &su return false; nc->lastmail = Anope::CurTime; - Thread *t = new MailThread(Config->SendMailPath, Config->SendFrom, nc->display, nc->email, subject, message); + Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message); t->Start(); return true; } @@ -79,7 +79,7 @@ bool Mail(User *u, NickCore *nc, const BotInfo *service, const Anope::string &su else { u->lastmail = nc->lastmail = Anope::CurTime; - Thread *t = new MailThread(Config->SendMailPath, Config->SendFrom, nc->display, nc->email, subject, message); + Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message); t->Start(); return true; } @@ -88,13 +88,13 @@ bool Mail(User *u, NickCore *nc, const BotInfo *service, const Anope::string &su } } -bool Mail(NickCore *nc, const Anope::string &subject, const Anope::string &message) +bool Mail::Send(NickCore *nc, const Anope::string &subject, const Anope::string &message) { if (!Config->UseMail || !nc || nc->email.empty() || subject.empty() || message.empty()) return false; nc->lastmail = Anope::CurTime; - Thread *t = new MailThread(Config->SendMailPath, Config->SendFrom, nc->display, nc->email, subject, message); + Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message); t->Start(); return true; @@ -109,7 +109,7 @@ bool Mail(NickCore *nc, const Anope::string &subject, const Anope::string &messa * @param email Email to Validate * @return bool */ -bool MailValidate(const Anope::string &email) +bool Mail::Validate(const Anope::string &email) { bool has_period = false; diff --git a/src/main.cpp b/src/main.cpp index 2cbacbb0f..82cd1af90 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,32 +8,15 @@ * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING); if not, write to the - * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "services.h" #include "timers.h" -#include "extern.h" -#include "uplink.h" #include "config.h" -#include "protocol.h" -#include "servers.h" #include "bots.h" -#include "dns.h" #include "signals.h" #include "socketengine.h" +#include "uplink.h" #ifndef _WIN32 #include <limits.h> @@ -41,37 +24,23 @@ #include <process.h> #endif -/******** Global variables! ********/ - -/* Command-line options: (note that configuration variables are in config.c) */ -Anope::string services_dir; /* -dir dirname */ -Anope::string services_bin; /* Binary as specified by the user */ -Anope::string binary_dir; /* Used to store base path for Anope */ -int debug = 0; /* -debug */ -bool readonly = false; /* -readonly */ -bool nofork = false; /* -nofork */ -bool nothird = false; /* -nothrid */ -bool noexpire = false; /* -noexpire */ -bool protocoldebug = false; /* -protocoldebug */ - -/* Set to 1 if we are to quit */ -bool quitting = false; -int return_code = 0; - -/* Set to true if we are restarting */ -bool restarting = false; +/* Command-line options: */ +int Anope::Debug = 0; +bool Anope::ReadOnly = false, Anope::NoFork = false, Anope::NoThird = false, Anope::NoExpire = false, Anope::ProtocolDebug = false; +Anope::string Anope::ServicesDir; +Anope::string Anope::ServicesBin; -/* Contains a message as to why services is terminating */ -Anope::string quitmsg; +int Anope::ReturnValue = 0; +bool Anope::Quitting = false; +bool Anope::Restarting = false; +Anope::string Anope::QuitReason; -/* At what time were we started? */ -time_t start_time = time(NULL); +static Anope::string BinaryDir; /* Full path to services bin directory */ +time_t Anope::StartTime = time(NULL); time_t Anope::CurTime = time(NULL); -/******** Local variables! ********/ - -/*************************************************************************/ +int Anope::CurrentUplink = -1; class UpdateTimer : public Timer { @@ -80,202 +49,13 @@ class UpdateTimer : public Timer void Tick(time_t) { - save_databases(); - } -}; - -UplinkSocket *UplinkSock = NULL; -int CurrentUplink = -1; - -static void Connect(); - -class ReconnectTimer : public Timer -{ - public: - ReconnectTimer(int wait) : Timer(wait) { } - - void Tick(time_t) - { - try - { - Connect(); - } - catch (const SocketException &ex) - { - Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (CurrentUplink + 1) << " (" << Config->Uplinks[CurrentUplink]->host << ":" << Config->Uplinks[CurrentUplink]->port << "): " << ex.GetReason(); - } + Anope::SaveDatabases(); } }; -UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[CurrentUplink]->ipv6), ConnectionSocket(), BufferedSocket() -{ - UplinkSock = this; -} - -UplinkSocket::~UplinkSocket() +void Anope::SaveDatabases() { - if (ircdproto && Me && !Me->GetLinks().empty() && Me->GetLinks()[0]->IsSynced()) - { - FOREACH_MOD(I_OnServerDisconnect, OnServerDisconnect()); - - for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) - { - User *u = it->second; - - if (u->server == Me) - { - /* Don't use quitmsg here, it may contain information you don't want people to see */ - ircdproto->SendQuit(u, "Shutting down"); - BotInfo* bi = findbot(u->nick); - if (bi != NULL) - bi->introduced = false; - } - } - - ircdproto->SendSquit(Me, quitmsg); - - this->ProcessWrite(); // Write out the last bit - } - - for (unsigned i = Me->GetLinks().size(); i > 0; --i) - if (!Me->GetLinks()[i - 1]->HasFlag(SERVER_JUPED)) - Me->GetLinks()[i - 1]->Delete(Me->GetName() + " " + Me->GetLinks()[i - 1]->GetName()); - - UplinkSock = NULL; - - Me->SetFlag(SERVER_SYNCING); - - if (AtTerm()) - { - if (static_cast<unsigned>(CurrentUplink + 1) == Config->Uplinks.size()) - { - quitting = true; - quitmsg = "Unable to connect to any uplink"; - return_code = -1; - } - else - { - new ReconnectTimer(1); - } - } - else if (!quitting) - { - int Retry = Config->RetryWait; - if (Retry <= 0) - Retry = 60; - - Log() << "Disconnected, retrying in " << Retry << " seconds"; - new ReconnectTimer(Retry); - } -} - -bool UplinkSocket::Read(const Anope::string &buf) -{ - process(buf); - return true; -} - -void UplinkSocket::OnConnect() -{ - Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (CurrentUplink + 1) << " " << Config->Uplinks[CurrentUplink]->host << ":" << Config->Uplinks[CurrentUplink]->port; - ircdproto->SendConnect(); - FOREACH_MOD(I_OnServerConnect, OnServerConnect()); -} - -void UplinkSocket::OnError(const Anope::string &error) -{ - Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (CurrentUplink + 1) << " (" << Config->Uplinks[CurrentUplink]->host << ":" << Config->Uplinks[CurrentUplink]->port << ")" << (!error.empty() ? (": " + error) : ""); -} - -UplinkSocket::Message::Message() : server(NULL), user(NULL) -{ -} - -UplinkSocket::Message::Message(const Server *s) : server(s), user(NULL) -{ -} - -UplinkSocket::Message::Message(const User *u) : server(NULL), user(u) -{ - if (!u) - server = Me; -} - -UplinkSocket::Message::~Message() -{ - Anope::string message_source = ""; - - if (this->server != NULL) - { - if (this->server != Me && !this->server->HasFlag(SERVER_JUPED)) - { - Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << this->server->GetName() << " who is not from me?"; - return; - } - - message_source = this->server->GetSID(); - } - else if (this->user != NULL) - { - if (this->user->server != Me && !this->user->server->HasFlag(SERVER_JUPED)) - { - Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << this->user->nick << " who is not from me?"; - return; - } - - const BotInfo *bi = findbot(this->user->nick); - if (bi != NULL && bi->introduced == false) - { - Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << bi->nick << " when not introduced"; - return; - } - - message_source = this->user->GetUID(); - } - - if (!UplinkSock) - { - if (!message_source.empty()) - Log(LOG_DEBUG) << "Attempted to send \"" << message_source << " " << this->buffer.str() << "\" with UplinkSock NULL"; - else - Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" with UplinkSock NULL"; - return; - } - - if (!message_source.empty()) - { - UplinkSock->Write(":" + message_source + " " + this->buffer.str()); - Log(LOG_RAWIO) << "Sent: :" << message_source << " " << this->buffer.str(); - } - else - { - UplinkSock->Write(this->buffer.str()); - Log(LOG_RAWIO) << "Sent: " << this->buffer.str(); - } -} - -static void Connect() -{ - if (static_cast<unsigned>(++CurrentUplink) >= Config->Uplinks.size()) - CurrentUplink = 0; - - ServerConfig::Uplink *u = Config->Uplinks[CurrentUplink]; - - new UplinkSocket(); - if (!Config->LocalHost.empty()) - UplinkSock->Bind(Config->LocalHost); - FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect()); - DNSQuery rep = DNSManager::BlockingQuery(u->host, u->ipv6 ? DNS_QUERY_AAAA : DNS_QUERY_A); - Anope::string reply_ip = !rep.answers.empty() ? rep.answers.front().rdata : u->host; - Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (CurrentUplink + 1) << " " << u->host << " (" << reply_ip << "), port " << u->port; - UplinkSock->Connect(reply_ip, u->port); -} - -/*************************************************************************/ - -void save_databases() -{ - if (readonly) + if (Anope::ReadOnly) return; EventReturn MOD_RESULT; @@ -283,8 +63,6 @@ void save_databases() Log(LOG_DEBUG) << "Saving databases"; } -/*************************************************************************/ - std::vector<Signal *> Signal::SignalHandlers; void Signal::SignalHandler(int signal) @@ -321,7 +99,7 @@ Signal::~Signal() /** The following comes from InspIRCd to get the full path of the Anope executable */ -Anope::string GetFullProgDir(const Anope::string &argv0) +static Anope::string GetFullProgDir(const Anope::string &argv0) { char buffer[PATH_MAX]; #ifdef _WIN32 @@ -333,7 +111,7 @@ Anope::string GetFullProgDir(const Anope::string &argv0) { Anope::string fullpath = buffer; Anope::string::size_type n = fullpath.rfind("\\"); - services_bin = fullpath.substr(n + 1, fullpath.length()); + Anope::ServicesBin = fullpath.substr(n + 1, fullpath.length()); return fullpath.substr(0, n); } #else @@ -342,14 +120,14 @@ Anope::string GetFullProgDir(const Anope::string &argv0) { Anope::string remainder = argv0; - services_bin = remainder; - Anope::string::size_type n = services_bin.rfind("/"); + Anope::ServicesBin = remainder; + Anope::string::size_type n = Anope::ServicesBin.rfind("/"); Anope::string fullpath; - if (services_bin[0] == '/') - fullpath = services_bin.substr(0, n); + if (Anope::ServicesBin[0] == '/') + fullpath = Anope::ServicesBin.substr(0, n); else - fullpath = Anope::string(buffer) + "/" + services_bin.substr(0, n); - services_bin = services_bin.substr(n + 1, remainder.length()); + fullpath = Anope::string(buffer) + "/" + Anope::ServicesBin.substr(0, n); + Anope::ServicesBin = Anope::ServicesBin.substr(n + 1, remainder.length()); return fullpath; } #endif @@ -362,16 +140,16 @@ Anope::string GetFullProgDir(const Anope::string &argv0) int main(int ac, char **av, char **envp) { - binary_dir = GetFullProgDir(av[0]); - if (binary_dir[binary_dir.length() - 1] == '.') - binary_dir = binary_dir.substr(0, binary_dir.length() - 2); + BinaryDir = GetFullProgDir(av[0]); + if (BinaryDir[BinaryDir.length() - 1] == '.') + BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2); #ifdef _WIN32 - Anope::string::size_type n = binary_dir.rfind('\\'); + Anope::string::size_type n = BinaryDir.rfind('\\'); #else - Anope::string::size_type n = binary_dir.rfind('/'); + Anope::string::size_type n = BinaryDir.rfind('/'); #endif - services_dir = binary_dir.substr(0, n); + Anope::ServicesDir = BinaryDir.substr(0, n); /* Clean out the module runtime directory prior to running, just in case files were left behind during a previous run */ ModuleManager::CleanupRuntimeDirectory(); @@ -383,9 +161,9 @@ int main(int ac, char **av, char **envp) try { /* General initialization first */ - Init(ac, av); + Anope::Init(ac, av); } - catch (const FatalException &ex) + catch (const CoreException &ex) { Log() << ex.GetReason(); return -1; @@ -393,11 +171,11 @@ int main(int ac, char **av, char **envp) try { - Connect(); + Uplink::Connect(); } catch (const SocketException &ex) { - Log(LOG_TERMINAL) << "Unable to connect to uplink #" << CurrentUplink << " (" << Config->Uplinks[CurrentUplink]->host << ":" << Config->Uplinks[CurrentUplink]->port << "): " << ex.GetReason(); + Log(LOG_TERMINAL) << "Unable to connect to uplink #" << Anope::CurrentUplink << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << "): " << ex.GetReason(); } /* Set up timers */ @@ -405,7 +183,7 @@ int main(int ac, char **av, char **envp) UpdateTimer updateTimer(Config->UpdateTimeout); /*** Main loop. ***/ - while (!quitting) + while (!Anope::Quitting) { Log(LOG_DEBUG_2) << "Top of main loop"; @@ -420,7 +198,7 @@ int main(int ac, char **av, char **envp) SocketEngine::Process(); } - if (restarting) + if (Anope::Restarting) { FOREACH_MOD(I_OnRestart, OnRestart()); } @@ -429,9 +207,9 @@ int main(int ac, char **av, char **envp) FOREACH_MOD(I_OnShutdown, OnShutdown()); } - if (quitmsg.empty()) - quitmsg = "Terminating, reason unknown"; - Log() << quitmsg; + if (Anope::QuitReason.empty()) + Anope::QuitReason = "Terminating, reason unknown"; + Log() << Anope::QuitReason; delete UplinkSock; @@ -446,14 +224,15 @@ int main(int ac, char **av, char **envp) OnShutdown(); #endif - if (restarting) + if (Anope::Restarting) { - chdir(binary_dir.c_str()); - av[0] = const_cast<char *>(("./" + services_bin).c_str()); - execve(services_bin.c_str(), av, envp); + chdir(BinaryDir.c_str()); + Anope::string sbin = "./" + Anope::ServicesBin; + av[0] = const_cast<char *>(sbin.c_str()); + execve(Anope::ServicesBin.c_str(), av, envp); Log() << "Restart failed"; - return_code = -1; + Anope::ReturnValue = -1; } - return return_code; + return Anope::ReturnValue; } diff --git a/src/memoserv.cpp b/src/memos.cpp index 13d4d04d6..2b221b03a 100644 --- a/src/memoserv.cpp +++ b/src/memos.cpp @@ -7,9 +7,9 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ - #include "services.h" #include "modules.h" #include "service.h" @@ -19,14 +19,17 @@ #include "account.h" #include "regchannel.h" -Memo::Memo() : Flags<MemoFlag>(MemoFlagStrings), Serializable("Memo") { } +static const Anope::string MemoFlagString[] = { "MF_UNREAD", "MF_RECEIPT", "" }; +template<> const Anope::string* Flags<MemoFlag>::flags_strings = MemoFlagString; + +Memo::Memo() : Serializable("Memo") { } -Serialize::Data Memo::serialize() const +Serialize::Data Memo::Serialize() const { Serialize::Data data; data["owner"] << this->owner; - data["time"].setType(Serialize::DT_INT) << this->time; + data["time"].SetType(Serialize::DT_INT) << this->time; data["sender"] << this->sender; data["text"] << this->text; data["flags"] << this->ToString(); @@ -34,13 +37,13 @@ Serialize::Data Memo::serialize() const return data; } -Serializable* Memo::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* Memo::Unserialize(Serializable *obj, Serialize::Data &data) { - if (!memoserv) + if (!MemoServService) return NULL; bool ischan; - MemoInfo *mi = memoserv->GetMemoInfo(data["owner"].astr(), ischan); + MemoInfo *mi = MemoServService->GetMemoInfo(data["owner"].astr(), ischan); if (!mi) return NULL; @@ -85,7 +88,7 @@ void MemoInfo::Del(unsigned index) { if (index >= this->memos->size()) return; - this->GetMemo(index)->destroy(); + this->GetMemo(index)->Destroy(); this->memos->erase(this->memos->begin() + index); } @@ -95,7 +98,7 @@ void MemoInfo::Del(Memo *memo) if (it != this->memos->end()) { - memo->destroy(); + memo->Destroy(); this->memos->erase(it); } } diff --git a/src/messages.cpp b/src/messages.cpp index 774816e44..62170e24e 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -14,43 +15,45 @@ #include "users.h" #include "protocol.h" #include "config.h" -#include "extern.h" #include "uplink.h" #include "opertype.h" #include "messages.h" #include "servers.h" #include "channels.h" -bool CoreIRCDMessageAway::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +using namespace Message; + +bool Away::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { FOREACH_MOD(I_OnUserAway, OnUserAway(source.GetUser(), params.empty() ? "" : params[0])); return true; } -bool CoreIRCDMessageCapab::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Capab::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { if (params.size() == 1) { spacesepstream sep(params[0]); Anope::string token; while (sep.GetToken(token)) - Capab.insert(token); + Servers::Capab.insert(token); } else for (unsigned i = 0; i < params.size(); ++i) - Capab.insert(params[i]); + Servers::Capab.insert(params[i]); return true; } -bool CoreIRCDMessageError::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Error::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Log(LOG_TERMINAL) << "ERROR: " << params[0]; - quitmsg = "Received ERROR from uplink: " + params[0]; + Anope::QuitReason = "Received ERROR from uplink: " + params[0]; + Anope::Quitting = true; return true; } -bool CoreIRCDMessageJoin::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Join::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *user = source.GetUser(); const Anope::string &channels = params[0]; @@ -70,46 +73,94 @@ bool CoreIRCDMessageJoin::Run(MessageSource &source, const std::vector<Anope::st Anope::string channame = cc->chan->name; FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan)); cc->chan->DeleteUser(user); - FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame), channame, "")); + FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, Channel::Find(channame), channame, "")); } user->chans.clear(); continue; } - Channel *chan = findchan(channel); - /* Channel doesn't exist, create it */ - if (!chan) - chan = new Channel(channel, Anope::CurTime); + std::list<SJoinUser> users; + users.push_back(std::make_pair(ChannelStatus(), user)); + + Channel *chan = Channel::Find(channel); + SJoin(source, channel, chan ? chan->creation_time : Anope::CurTime, "", users); + } + + return true; +} + +void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::list<SJoinUser> &users) +{ + Channel *c = Channel::Find(chan); + bool keep_their_modes = true; + + if (!c) + { + c = new Channel(chan, ts ? ts : Anope::CurTime); + c->SetFlag(CH_SYNCING); + } + /* Some IRCds do not include a TS */ + else if (!ts) + ; + /* Our creation time is newer than what the server gave us, so reset the channel to the older time */ + else if (c->creation_time > ts) + { + c->creation_time = ts; + c->Reset(); + } + /* Their TS is newer, don't accept any modes from them */ + else if (ts > c->creation_time) + keep_their_modes = false; + + /* Update the modes for the channel */ + if (keep_their_modes && !modes.empty()) + c->SetModesInternal(source, modes); + + for (std::list<SJoinUser>::const_iterator it = users.begin(), it_end = users.end(); it != it_end; ++it) + { + const ChannelStatus &status = it->first; + User *u = it->second; EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(user, chan)); + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); + + /* Add the user to the channel */ + UserContainer *cc = c->JoinUser(u); - /* Join the user to the channel */ - chan->JoinUser(user); - /* Set the proper modes on the user */ - chan_set_correct_modes(user, chan, 1, true); + /* Update their status internally on the channel */ + *cc->status = status; - /* Modules may want to allow this user in the channel, check. - * If not, CheckKick will kick/ban them, don't call OnJoinChannel after this as the user will have - * been destroyed + /* Set whatever modes the user should have, and remove any that + * they aren't allowed to have (secureops etc). */ - if (MOD_RESULT != EVENT_STOP && chan && chan->ci && chan->ci->CheckKick(user)) + 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(user, chan)); + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); } - return true; + /* Channel is done syncing */ + if (c->HasFlag(CH_SYNCING)) + { + c->UnsetFlag(CH_SYNCING); + /* Sync the channel (mode lock, topic, etc) */ + c->Sync(); + } } - -bool CoreIRCDMessageKick::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Kick::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &channel = params[0]; const Anope::string &users = params[1]; const Anope::string &reason = params.size() > 2 ? params[2] : ""; - Channel *c = findchan(channel); + Channel *c = Channel::Find(channel); if (!c) return true; @@ -121,9 +172,9 @@ bool CoreIRCDMessageKick::Run(MessageSource &source, const std::vector<Anope::st return true; } -bool CoreIRCDMessageKill::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Kill::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - User *u = finduser(params[0]); + User *u = User::Find(params[0]); BotInfo *bi; if (!u) @@ -132,9 +183,22 @@ bool CoreIRCDMessageKill::Run(MessageSource &source, const std::vector<Anope::st /* Recover if someone kills us. */ if (u->server == Me && (bi = dynamic_cast<BotInfo *>(u))) { + static time_t last_time = 0; + + if (last_time == Anope::CurTime) + { + Anope::QuitReason = "Kill loop detected. Are Services U:Lined?"; + Anope::Quitting = true; + return true; + } + last_time = Anope::CurTime; + bi->introduced = false; - introduce_user(bi->nick); - bi->RejoinAll(); + IRCD->SendClientIntroduction(bi); + bi->introduced = true; + + for (UChannelList::const_iterator cit = bi->chans.begin(), cit_end = bi->chans.end(); cit != cit_end; ++cit) + IRCD->SendJoin(bi, (*cit)->chan, (*cit)->status); } else u->KillInternal(source.GetSource(), params[1]); @@ -142,8 +206,28 @@ bool CoreIRCDMessageKill::Run(MessageSource &source, const std::vector<Anope::st return true; } +bool Message::Mode::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +{ + if (IRCD->IsChannelValid(params[0])) + { + Channel *c = Channel::Find(params[0]); + + if (c) + c->SetModesInternal(source, params[2], 0); + } + else + { + User *u = User::Find(params[0]); + + if (u) + u->SetModesInternal("%s", params[1].c_str()); + } + + return true; +} + /* XXX We should cache the file somewhere not open/read/close it on every request */ -bool CoreIRCDMessageMOTD::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool MOTD::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Server *s = Server::Find(params[0]); if (s != Me) @@ -152,23 +236,23 @@ bool CoreIRCDMessageMOTD::Run(MessageSource &source, const std::vector<Anope::st FILE *f = fopen(Config->MOTDFilename.c_str(), "r"); if (f) { - ircdproto->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", Config->ServerName.c_str()); + IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", Config->ServerName.c_str()); char buf[BUFSIZE]; while (fgets(buf, sizeof(buf), f)) { buf[strlen(buf) - 1] = 0; - ircdproto->SendNumeric(372, source.GetSource(), ":- %s", buf); + IRCD->SendNumeric(372, source.GetSource(), ":- %s", buf); } fclose(f); - ircdproto->SendNumeric(376, source.GetSource(), ":End of /MOTD command."); + IRCD->SendNumeric(376, source.GetSource(), ":End of /MOTD command."); } else - ircdproto->SendNumeric(422, source.GetSource(), ":- MOTD file not found! Please contact your IRC administrator."); + IRCD->SendNumeric(422, source.GetSource(), ":- MOTD file not found! Please contact your IRC administrator."); return true; } -bool CoreIRCDMessagePart::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Part::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.GetUser(); const Anope::string &reason = params.size() > 1 ? params[1] : ""; @@ -178,7 +262,7 @@ bool CoreIRCDMessagePart::Run(MessageSource &source, const std::vector<Anope::st while (sep.GetToken(channel)) { - dynamic_reference<Channel> c = findchan(channel); + Reference<Channel> c = Channel::Find(channel); if (!c || !u->FindChannel(c)) continue; @@ -193,22 +277,22 @@ bool CoreIRCDMessagePart::Run(MessageSource &source, const std::vector<Anope::st return true; } -bool CoreIRCDMessagePing::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Ping::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - ircdproto->SendPong(params.size() > 1 ? params[1] : Me->GetSID(), params[0]); + IRCD->SendPong(params.size() > 1 ? params[1] : Me->GetSID(), params[0]); return true; } -bool CoreIRCDMessagePrivmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Privmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &receiver = params[0]; Anope::string message = params[1]; User *u = source.GetUser(); - if (ircdproto->IsChannelValid(receiver)) + if (IRCD->IsChannelValid(receiver)) { - Channel *c = findchan(receiver); + Channel *c = Channel::Find(receiver); if (c) { FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message)); @@ -229,7 +313,7 @@ bool CoreIRCDMessagePrivmsg::Run(MessageSource &source, const std::vector<Anope: } else if (Config->UseStrictPrivMsg) { - const BotInfo *bi = findbot(receiver); + const BotInfo *bi = BotInfo::Find(receiver); if (!bi) return true; Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick; @@ -237,7 +321,7 @@ bool CoreIRCDMessagePrivmsg::Run(MessageSource &source, const std::vector<Anope: return true; } - BotInfo *bi = findbot(botname); + BotInfo *bi = BotInfo::Find(botname); if (bi) { @@ -253,12 +337,12 @@ bool CoreIRCDMessagePrivmsg::Run(MessageSource &source, const std::vector<Anope: Anope::string buf = message; buf.erase(buf.begin()); buf.erase(buf.end() - 1); - ircdproto->SendCTCP(bi, u->nick, "%s", buf.c_str()); + IRCD->SendCTCP(bi, u->nick, "%s", buf.c_str()); } else if (message.substr(0, 9).equals_ci("\1VERSION\1")) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - ircdproto->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircdproto->GetProtocolName().c_str(), enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); + 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() : "unknown", Anope::VersionBuildString().c_str()); } return true; } @@ -270,14 +354,14 @@ bool CoreIRCDMessagePrivmsg::Run(MessageSource &source, const std::vector<Anope: return true; } -bool CoreIRCDMessageQuit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Quit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &reason = params[0]; User *user = source.GetUser(); Log(user, "quit") << "quit (Reason: " << (!reason.empty() ? reason : "no reason") << ")"; - NickAlias *na = findnick(user->nick); + NickAlias *na = NickAlias::Find(user->nick); if (na && !na->nc->HasFlag(NI_SUSPENDED) && (user->IsRecognized() || user->IsIdentified(true))) { na->last_seen = Anope::CurTime; @@ -289,7 +373,7 @@ bool CoreIRCDMessageQuit::Run(MessageSource &source, const std::vector<Anope::st return true; } -bool CoreIRCDMessageSQuit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool SQuit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Server *s = Server::Find(params[0]); @@ -306,7 +390,7 @@ bool CoreIRCDMessageSQuit::Run(MessageSource &source, const std::vector<Anope::s return true; } -bool CoreIRCDMessageStats::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Stats::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.GetUser(); @@ -315,92 +399,92 @@ bool CoreIRCDMessageStats::Run(MessageSource &source, const std::vector<Anope::s case 'l': if (u->HasMode(UMODE_OPER)) { - ircdproto->SendNumeric(211, source.GetSource(), "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime"); - ircdproto->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - start_time)); + 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)); } - ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); + IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); break; case 'o': case 'O': /* Check whether the user is an operator */ if (!u->HasMode(UMODE_OPER) && Config->HideStatsO) - ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); + IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); else { for (unsigned i = 0; i < Config->Opers.size(); ++i) { Oper *o = Config->Opers[i]; - const NickAlias *na = findnick(o->name); + const NickAlias *na = NickAlias::Find(o->name); if (na) - ircdproto->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); + IRCD->SendNumeric(243, source.GetSource(), "O * * %s %s 0", o->name.c_str(), o->ot->GetName().c_str()); } - ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); + IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); } break; case 'u': { - time_t uptime = Anope::CurTime - start_time; - ircdproto->SendNumeric(242, source.GetSource(), ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); - ircdproto->SendNumeric(250, source.GetSource(), ":Current users: %d (%d ops); maximum %d", usercnt, opcnt, maxusercnt); - ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); + time_t uptime = Anope::CurTime - Anope::StartTime; + IRCD->SendNumeric(242, source.GetSource(), ":Services up %d day%s, %02d:%02d:%02d", uptime / 86400, uptime / 86400 == 1 ? "" : "s", (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); + IRCD->SendNumeric(250, source.GetSource(), ":Current users: %d (%d ops); maximum %d", UserListByNick.size(), OperCount, MaxUserCount); + IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); break; } /* case 'u' */ default: - ircdproto->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); + IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]); } return true; } -bool CoreIRCDMessageTime::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Time::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { time_t t; time(&t); struct tm *tm = localtime(&t); char buf[64]; strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm); - ircdproto->SendNumeric(391, source.GetSource(), "%s :%s", Config->ServerName.c_str(), buf); + IRCD->SendNumeric(391, source.GetSource(), "%s :%s", Config->ServerName.c_str(), buf); return true; } -bool CoreIRCDMessageTopic::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Topic::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - Channel *c = findchan(params[0]); + Channel *c = Channel::Find(params[0]); if (c) c->ChangeTopicInternal(source.GetSource(), params[1], Anope::CurTime); return true; } -bool CoreIRCDMessageVersion::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Version::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - ircdproto->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircdproto->GetProtocolName().c_str(), enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str()); + 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() : "unknown", Anope::VersionBuildString().c_str()); return true; } -bool CoreIRCDMessageWhois::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +bool Whois::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - User *u = finduser(params[0]); + User *u = User::Find(params[0]); if (u && u->server == Me) { - const BotInfo *bi = findbot(u->nick); - ircdproto->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str()); + const BotInfo *bi = BotInfo::Find(u->nick); + 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) - ircdproto->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str()); - ircdproto->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str()); + 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()); if (bi) - ircdproto->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)); - ircdproto->SendNumeric(318, source.GetSource(), "%s :End of /WHOIS list.", params[0].c_str()); + 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()); } else - ircdproto->SendNumeric(401, source.GetSource(), "%s :No such user.", params[0].c_str()); + IRCD->SendNumeric(401, source.GetSource(), "%s :No such user.", params[0].c_str()); return true; } diff --git a/src/misc.cpp b/src/misc.cpp index cd7516b76..7196a1534 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -1,4 +1,3 @@ - /* Miscellaneous routines. * * (C) 2003-2012 Anope Team @@ -8,12 +7,12 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" #include "version.h" #include "modules.h" -#include "extern.h" #include "lists.h" #include "config.h" #include "bots.h" @@ -24,37 +23,6 @@ #include <sys/types.h> #include <sys/stat.h> -ExtensibleItem::ExtensibleItem() -{ -} - -ExtensibleItem::~ExtensibleItem() -{ -} - -void ExtensibleItem::OnDelete() -{ - delete this; -} - -/*************************************************************************/ - -/** Check if a file exists - * @param filename The file - * @return true if the file exists, false if it doens't - */ -bool IsFile(const Anope::string &filename) -{ - struct stat fileinfo; - if (!stat(filename.c_str(), &fileinfo)) - return true; - - return false; -} - - -/*************************************************************************/ - NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(true), desc(descending) { Anope::string error; @@ -134,18 +102,18 @@ bool NumberList::InvalidRange(const Anope::string &) return true; } -ListFormatter &ListFormatter::addColumn(const Anope::string &name) +ListFormatter &ListFormatter::AddColumn(const Anope::string &name) { this->columns.push_back(name); return *this; } -void ListFormatter::addEntry(const ListEntry &entry) +void ListFormatter::AddEntry(const ListEntry &entry) { this->entries.push_back(entry); } -bool ListFormatter::isEmpty() const +bool ListFormatter::IsEmpty() const { return this->entries.empty(); } @@ -235,7 +203,7 @@ void InfoFormatter::Process(std::vector<Anope::string> &buffer) Anope::string s; for (unsigned i = it->first.length(); i < this->longest; ++i) s += " "; - s += Anope::string(translate(this->nc, it->first.c_str())) + ": " + it->second; + s += Anope::string(Language::Translate(this->nc, it->first.c_str())) + ": " + it->second; buffer.push_back(s); } @@ -249,18 +217,16 @@ Anope::string& InfoFormatter::operator[](const Anope::string &key) return this->replies.back().second; } -/** - * dotime: Return the number of seconds corresponding to the given time - * string. If the given string does not represent a valid time, - * return -1. - * - * A time string is either a plain integer (representing a number - * of seconds), or an integer followed by one of these characters: - * "s" (seconds), "m" (minutes), "h" (hours), or "d" (days). - * @param s String to convert - * @return time_t - */ -time_t dotime(const Anope::string &s) +bool Anope::IsFile(const Anope::string &filename) +{ + struct stat fileinfo; + if (!stat(filename.c_str(), &fileinfo)) + return true; + + return false; +} + +time_t Anope::DoTime(const Anope::string &s) { if (s.empty()) return -1; @@ -297,15 +263,7 @@ time_t dotime(const Anope::string &s) return 0; } -/*************************************************************************/ - -/** - * Expresses in a string the period of time represented by a given amount - * of seconds (with days/hours/minutes). - * @param seconds time in seconds - * @return buffer - */ -Anope::string duration(const time_t &t, const NickCore *nc) +Anope::string Anope::Duration(time_t t, const NickCore *nc) { /* We first calculate everything */ time_t days = (t / 86400); @@ -314,58 +272,50 @@ Anope::string duration(const time_t &t, const NickCore *nc) time_t seconds = (t) % 60; if (!days && !hours && !minutes) - return stringify(seconds) + " " + (seconds != 1 ? translate(nc, _("seconds")) : translate(nc, _("second"))); + return stringify(seconds) + " " + (seconds != 1 ? Language::Translate(nc, _("seconds")) : Language::Translate(nc, _("second"))); else { bool need_comma = false; Anope::string buffer; if (days) { - buffer = stringify(days) + " " + (days != 1 ? translate(nc, _("days")) : translate(nc, _("day"))); + buffer = stringify(days) + " " + (days != 1 ? Language::Translate(nc, _("days")) : Language::Translate(nc, _("day"))); need_comma = true; } if (hours) { buffer += need_comma ? ", " : ""; - buffer += stringify(hours) + " " + (hours != 1 ? translate(nc, _("hours")) : translate(nc, _("hour"))); + buffer += stringify(hours) + " " + (hours != 1 ? Language::Translate(nc, _("hours")) : Language::Translate(nc, _("hour"))); need_comma = true; } if (minutes) { buffer += need_comma ? ", " : ""; - buffer += stringify(minutes) + " " + (minutes != 1 ? translate(nc, _("minutes")) : translate(nc, _("minute"))); + buffer += stringify(minutes) + " " + (minutes != 1 ? Language::Translate(nc, _("minutes")) : Language::Translate(nc, _("minute"))); } return buffer; } } -Anope::string do_strftime(const time_t &t, const NickCore *nc, bool short_output) +Anope::string Anope::strftime(time_t t, const NickCore *nc, bool short_output) { tm tm = *localtime(&t); char buf[BUFSIZE]; - strftime(buf, sizeof(buf), translate(nc, _("%b %d %H:%M:%S %Y %Z")), &tm); + strftime(buf, sizeof(buf), Language::Translate(nc, _("%b %d %H:%M:%S %Y %Z")), &tm); if (short_output) return buf; if (t < Anope::CurTime) - return Anope::string(buf) + " " + Anope::printf(translate(nc, _("(%s ago)")), duration(Anope::CurTime - t).c_str(), nc); + return Anope::string(buf) + " " + Anope::printf(Language::Translate(nc, _("(%s ago)")), Duration(Anope::CurTime - t).c_str(), nc); else - return Anope::string(buf) + " " + Anope::printf(translate(nc, _("(%s from now)")), duration(t - Anope::CurTime).c_str(), nc); + return Anope::string(buf) + " " + Anope::printf(Language::Translate(nc, _("(%s from now)")), Duration(t - Anope::CurTime).c_str(), nc); } -/*************************************************************************/ - -/** - * Generates a human readable string of type "expires in ..." - * @param na Nick Alias - * @param seconds time in seconds - * @return buffer - */ -Anope::string expire_left(const NickCore *nc, time_t expires) +Anope::string Anope::Expires(time_t expires, const NickCore *nc) { if (!expires) - return translate(nc, NO_EXPIRE); + return Language::Translate(nc, NO_EXPIRE); else if (expires <= Anope::CurTime) - return translate(nc, _("expires momentarily")); + return Language::Translate(nc, _("expires momentarily")); else { char buf[256]; @@ -374,21 +324,21 @@ Anope::string expire_left(const NickCore *nc, time_t expires) if (diff >= 86400) { int days = diff / 86400; - snprintf(buf, sizeof(buf), translate(nc, days == 1 ? _("expires in %d day") : _("expires in %d days")), days); + snprintf(buf, sizeof(buf), Language::Translate(nc, days == 1 ? _("expires in %d day") : _("expires in %d days")), days); } else { if (diff <= 3600) { int minutes = diff / 60; - snprintf(buf, sizeof(buf), translate(nc, minutes == 1 ? _("expires in %d minute") : _("expires in %d minutes")), minutes); + snprintf(buf, sizeof(buf), Language::Translate(nc, minutes == 1 ? _("expires in %d minute") : _("expires in %d minutes")), minutes); } else { int hours = diff / 3600, minutes; diff -= hours * 3600; minutes = diff / 60; - snprintf(buf, sizeof(buf), translate(nc, hours == 1 && minutes == 1 ? _("expires in %d hour, %d minute") : (hours == 1 && minutes != 1 ? _("expires in %d hour, %d minutes") : (hours != 1 && minutes == 1 ? _("expires in %d hours, %d minute") : _("expires in %d hours, %d minutes")))), hours, minutes); + snprintf(buf, sizeof(buf), Language::Translate(nc, hours == 1 && minutes == 1 ? _("expires in %d hour, %d minute") : (hours == 1 && minutes != 1 ? _("expires in %d hour, %d minutes") : (hours != 1 && minutes == 1 ? _("expires in %d hours, %d minute") : _("expires in %d hours, %d minutes")))), hours, minutes); } } @@ -396,181 +346,6 @@ Anope::string expire_left(const NickCore *nc, time_t expires) } } -/*************************************************************************/ - -/** Checks if a username is valid - * @param ident The username - * @return true if the ident is valid - */ -bool IsValidIdent(const Anope::string &ident) -{ - if (ident.empty() || ident.length() > Config->UserLen) - return false; - for (unsigned i = 0; i < ident.length(); ++i) - { - const char &c = ident[i]; - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-') - ; - else - return false; - } - - return true; -} - -/** Checks if a host is valid - * @param host The host - * @param true if the host is valid - */ -bool IsValidHost(const Anope::string &host) -{ - if (host.empty() || host.length() > Config->HostLen) - return false; - - if (Config->VhostDisallowBE.find_first_of(host[0]) != Anope::string::npos) - return false; - else if (Config->VhostDisallowBE.find_first_of(host[host.length() - 1]) != Anope::string::npos) - return false; - - int dots = 0; - for (unsigned i = 0; i < host.length(); ++i) - { - if (host[i] == '.') - ++dots; - if (Config->VhostChars.find_first_of(host[i]) == Anope::string::npos) - return false; - } - - return Config->VhostUndotted || dots > 0; -} - -/*************************************************************************/ - -/** - * Get the token - * @param str String to search in - * @param dilim Character to search for - * @param token_number the token number - * @return token - */ -Anope::string myStrGetToken(const Anope::string &str, char dilim, int token_number) -{ - if (str.empty() || str.find(dilim) == Anope::string::npos) - return token_number ? "" : str; - - Anope::string substring; - sepstream sep(str, dilim); - - for (int i = 0; i < token_number + 1 && !sep.StreamEnd() && sep.GetToken(substring); ++i); - - return substring; -} - -/*************************************************************************/ - -/** - * Get the Remaining tokens - * @param str String to search in - * @param dilim Character to search for - * @param token_number the token number - * @return token - */ -Anope::string myStrGetTokenRemainder(const Anope::string &str, const char dilim, int token_number) -{ - if (str.empty() || str.find(dilim) == Anope::string::npos) - return token_number ? "" : str; - - Anope::string substring; - sepstream sep(str, dilim); - - for (int i = 0; i < token_number + 1 && !sep.StreamEnd() && sep.GetToken(substring); ++i); - - if (!sep.StreamEnd()) - substring += dilim + sep.GetRemaining(); - return substring; -} - -/*************************************************************************/ - -/** - * Is the given nick a network service - * @param nick to check - * @param int Check if botserv bots - * @return int - */ -bool nickIsServices(const Anope::string &tempnick, bool bot) -{ - if (tempnick.empty()) - return false; - - Anope::string nick = tempnick; - - size_t at = nick.find('@'); - if (at != Anope::string::npos) - { - Anope::string servername = nick.substr(at + 1); - if (!servername.equals_ci(Config->ServerName)) - return false; - nick = nick.substr(0, at); - } - - const BotInfo *bi = findbot(nick); - if (bi) - return bot ? true : bi->HasFlag(BI_CORE); - return false; -} - -/*************************************************************************/ - -/** - * Number of tokens in a string - * @param str String - * @param dilim Dilimiter - * @return number of tokens - */ -int myNumToken(const Anope::string &str, char dilim) -{ - if (str.empty()) - return 0; - int counter = 0; - for (size_t idx = 0, len = str.length(); idx <= len; ++idx) - if (str[idx] == dilim || idx == len) - ++counter; - return counter; -} - -/*************************************************************************/ - -/** Build a string list from a source string - * @param src The source string - * @return a list of strings - */ -std::list<Anope::string> BuildStringList(const Anope::string &src, char delim) -{ - sepstream tokens(src, delim); - Anope::string token; - std::list<Anope::string> Ret; - - while (tokens.GetToken(token)) - Ret.push_back(token); - - return Ret; -} - -std::vector<Anope::string> BuildStringVector(const Anope::string &src, char delim) -{ - sepstream tokens(src, delim); - Anope::string token; - std::vector<Anope::string> Ret; - - while (tokens.GetToken(token)) - Ret.push_back(token); - - return Ret; -} - -/*************************************************************************/ - bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case_sensitive, bool use_regex) { size_t s = 0, m = 0, str_len = str.length(), mask_len = mask.length(); @@ -583,7 +358,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case if (r == NULL || r->GetExpression() != stripped_mask) { - service_reference<RegexProvider> provider("Regex", Config->RegexEngine); + ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); if (provider) { try @@ -675,13 +450,6 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case return m == mask_len; } -/** Returns a sequence of data formatted as the format argument specifies. - ** After the format parameter, the function expects at least as many - ** additional arguments as specified in format. - * @param fmt Format of the Message - * @param ... any number of parameters - * @return a Anope::string - */ Anope::string Anope::printf(const char *fmt, ...) { va_list args; @@ -692,35 +460,6 @@ Anope::string Anope::printf(const char *fmt, ...) return buf; } - -/*************************************************************************/ - -/** - * Check if the given string is some sort of wildcard - * @param str String to check - * @return 1 for wildcard, 0 for anything else - */ -bool str_is_wildcard(const Anope::string &str) -{ - return str.find_first_of("*?") != Anope::string::npos; -} - -/** - * Check if the given string is a pure wildcard - * @param str String to check - * @return 1 for pure wildcard, 0 for anything else - */ -bool str_is_pure_wildcard(const Anope::string &str) -{ - return str.find_first_not_of('*') == Anope::string::npos; -} - -/*************************************************************************/ - -/** Converts a string to hex - * @param the data to be converted - * @return a anope::string containing the hex value - */ Anope::string Anope::Hex(const Anope::string &data) { const char hextable[] = "0123456789abcdef"; @@ -750,10 +489,6 @@ Anope::string Anope::Hex(const char *data, unsigned len) return rv; } -/** Converts a string from hex - * @param src The data to be converted - * @param dest The destination string - */ void Anope::Unhex(const Anope::string &src, Anope::string &dest) { size_t len = src.length(); @@ -827,12 +562,7 @@ int Anope::VersionMajor() { return VERSION_MAJOR; } int Anope::VersionMinor() { return VERSION_MINOR; } int Anope::VersionPatch() { return VERSION_PATCH; } -/** - * Normalize buffer stripping control characters and colors - * @param A string to be parsed for control and color codes - * @return A string stripped of control and color codes - */ -Anope::string normalizeBuffer(const Anope::string &buf) +Anope::string Anope::NormalizeBuffer(const Anope::string &buf) { Anope::string newbuf; diff --git a/src/modes.cpp b/src/modes.cpp index c14e09f70..ae550d788 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -4,11 +4,11 @@ * Copyright (C) 2008-2012 Anope Team <team@anope.org> * * Please read COPYING and README for further details. + * */ #include "services.h" #include "modules.h" -#include "extern.h" #include "config.h" #include "sockets.h" #include "protocol.h" @@ -23,70 +23,52 @@ std::vector<ChannelMode *> ModeManager::ChannelModes; std::vector<UserMode *> ModeManager::UserModes; /* Number of generic modes we support */ -unsigned GenericChannelModes = 0, GenericUserModes = 0; -/* Default mlocked modes */ -ChannelInfo::ModeList def_mode_locks; +unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0; -/** Parse the mode string from the config file and set the default mlocked modes - */ -void SetDefaultMLock(ServerConfig *config) -{ - for (ChannelInfo::ModeList::iterator it = def_mode_locks.begin(), it_end = def_mode_locks.end(); it != it_end; ++it) - delete it->second; - def_mode_locks.clear(); +/* Default channel mode lock */ +ChannelInfo::ModeList ModeManager::DefaultModeLocks; - Anope::string modes; - spacesepstream sep(config->MLock); - sep.GetToken(modes); +/* Default modes bots have on channels */ +ChannelStatus ModeManager::DefaultBotModes; - 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]); +static const Anope::string UserModeNameStrings[] = { + "UMODE_BEGIN", - 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->ModeChar << " with no param?"; - continue; - } + "UMODE_SERV_ADMIN", "UMODE_BOT", "UMODE_CO_ADMIN", "UMODE_FILTER", "UMODE_HIDEOPER", "UMODE_NETADMIN", + "UMODE_REGPRIV", "UMODE_PROTECTED", "UMODE_NOCTCP", "UMODE_WEBTV", "UMODE_WEBIRC", "UMODE_WHOIS", "UMODE_ADMIN", "UMODE_DEAF", + "UMODE_GLOBOPS", "UMODE_HELPOP", "UMODE_INVIS", "UMODE_OPER", "UMODE_PRIV", "UMODE_GOD", "UMODE_REGISTERED", + "UMODE_SNOMASK", "UMODE_VHOST", "UMODE_WALLOPS", "UMODE_CLOAK", "UMODE_SSL", "UMODE_SOFTCALLERID", "UMODE_CALLERID", + "UMODE_COMMONCHANS", "UMODE_HIDDEN", "UMODE_STRIPCOLOR", "UMODE_INVISIBLE_OPER", "UMODE_RESTRICTED", "UMODE_HIDEIDLE", - if (cm->Type != MODE_LIST) // Only MODE_LIST can have duplicates - { - ChannelInfo::ModeList::iterator it = def_mode_locks.find(cm->Name); - if (it != def_mode_locks.end()) - { - delete it->second; - def_mode_locks.erase(it); - } - } - def_mode_locks.insert(std::make_pair(cm->Name, new ModeLock(NULL, adding == 1, cm->Name, param))); - } - } - } + "" +}; +template<> const Anope::string* Flags<UserModeName>::flags_strings = UserModeNameStrings; - /* Set Bot Modes */ - config->BotModeList.ClearFlags(); - for (unsigned i = 0; i < config->BotModes.length(); ++i) - { - ChannelMode *cm = ModeManager::FindChannelModeByChar(config->BotModes[i]); +static const Anope::string ChannelModeNameStrings[] = { + "CMODE_BEGIN", - if (cm && cm->Type == MODE_STATUS) - config->BotModeList.SetFlag(cm->Name); - } -} + /* Channel modes */ + "CMODE_BLOCKCOLOR", "CMODE_FLOOD", "CMODE_INVITE", "CMODE_KEY", "CMODE_LIMIT", "CMODE_MODERATED", "CMODE_NOEXTERNAL", + "CMODE_PRIVATE", "CMODE_REGISTERED", "CMODE_SECRET", "CMODE_TOPIC", "CMODE_AUDITORIUM", "CMODE_SSL", "CMODE_ADMINONLY", + "CMODE_NOCTCP", "CMODE_FILTER", "CMODE_NOKNOCK", "CMODE_REDIRECT", "CMODE_REGMODERATED", "CMODE_NONICK", "CMODE_OPERONLY", + "CMODE_NOKICK", "CMODE_REGISTEREDONLY", "CMODE_STRIPCOLOR", "CMODE_NONOTICE", "CMODE_NOINVITE", "CMODE_ALLINVITE", + "CMODE_BLOCKCAPS", "CMODE_PERM", "CMODE_NICKFLOOD", "CMODE_JOINFLOOD", "CMODE_DELAYEDJOIN", "CMODE_NOREJOIN", + "CMODE_BANDWIDTH", -ChannelStatus::ChannelStatus() : Flags<ChannelModeName, CMODE_END * 2>(ChannelModeNameStrings) -{ -} + /* b/e/I */ + "CMODE_BAN", "CMODE_EXCEPT", + "CMODE_INVITEOVERRIDE", + + /* v/h/o/a/q */ + "CMODE_VOICE", "CMODE_HALFOP", "CMODE_OP", + "CMODE_PROTECT", "CMODE_OWNER", + + "" +}; +template<> const Anope::string* Flags<ChannelModeName>::flags_strings = ChannelModeNameStrings; + +static const Anope::string EntryFlagString[] = { "ENTRYTYPE_NONE", "ENTRYTYPE_CIDR", "ENTRYTYPE_NICK_WILD", "ENTRYTYPE_NICK", "ENTRYTYPE_USER_WILD", "ENTRYTYPE_USER", "ENTRYTYPE_HOST_WILD", "ENTRYTYPE_HOST", "" }; +template<> const Anope::string* Flags<EntryType>::flags_strings = EntryFlagString; Anope::string ChannelStatus::BuildCharPrefixList() const { @@ -96,8 +78,8 @@ Anope::string ChannelStatus::BuildCharPrefixList() const { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (this->HasFlag(cm->Name)) - ret += cm->ModeChar; + if (this->HasFlag(cm->name)) + ret += cm->mchar; } return ret; @@ -111,7 +93,7 @@ Anope::string ChannelStatus::BuildModePrefixList() const { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (this->HasFlag(cm->Name)) + if (this->HasFlag(cm->name)) { ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); ret += cms->Symbol; @@ -121,139 +103,83 @@ Anope::string ChannelStatus::BuildModePrefixList() const return ret; } -/** Default constructor - * @param mClass The type of mode this is - * @param modeChar The mode char - * @param modeType The mode type - */ -Mode::Mode(ModeClass mClass, char modeChar, ModeType modeType) : Class(mClass), ModeChar(modeChar), Type(modeType) +Mode::Mode(ModeClass mcl, char mch, ModeType mt) : mclass(mcl), mchar(mch), type(mt) { } -/** Default destructor - */ Mode::~Mode() { } -/** Default constructor - * @param mName The mode name - * @param modeChar The mode char - */ -UserMode::UserMode(UserModeName mName, char modeChar) : Mode(MC_USER, modeChar, MODE_REGULAR), Name(mName) +UserMode::UserMode(UserModeName un, char mch) : Mode(MC_USER, mch, MODE_REGULAR), name(un) { } -/** Default destructor - */ UserMode::~UserMode() { } -/** Returns the mode name as a string - */ const Anope::string UserMode::NameAsString() { - if (this->Name > UMODE_END) - return this->ModeChar; - return UserModeNameStrings[this->Name]; + if (this->name >= UMODE_END) + return this->mchar; + return UserModeNameStrings[this->name]; } -/** Default constructor - * @param mName The mode name - * @param modeChar The mode char - */ -UserModeParam::UserModeParam(UserModeName mName, char modeChar) : UserMode(mName, modeChar) +UserModeParam::UserModeParam(UserModeName un, char mch) : UserMode(un, mch) { - this->Type = MODE_PARAM; + this->type = MODE_PARAM; } -/** Default constrcutor - * @param mName The mode name - * @param modeChar The mode char - */ -ChannelMode::ChannelMode(ChannelModeName mName, char modeChar) : Mode(MC_CHANNEL, modeChar, MODE_REGULAR), Name(mName) +ChannelMode::ChannelMode(ChannelModeName cm, char mch) : Mode(MC_CHANNEL, mch, MODE_REGULAR), name(cm) { } -/** Default destructor - */ ChannelMode::~ChannelMode() { } -/** Can a user set this mode, used for mlock - * NOTE: User CAN be NULL, this is for checking if it can be locked with defcon - * @param u The user, or NULL - */ bool ChannelMode::CanSet(User *u) const { - if (Config->NoMLock.find(this->ModeChar) != Anope::string::npos || Config->CSRequire.find(this->ModeChar) != Anope::string::npos) + if (Config->NoMLock.find(this->mchar) != Anope::string::npos || Config->CSRequire.find(this->mchar) != Anope::string::npos) return false; return true; } -/** Returns the mode name as a string - */ const Anope::string ChannelMode::NameAsString() { - if (this->Name > CMODE_END) - return this->ModeChar; - return ChannelModeNameStrings[this->Name]; + if (this->name >= CMODE_END) + return this->mchar; + return ChannelModeNameStrings[this->name]; } -/** Default constructor - * @param mName The mode name - * @param modeChar The mode char - */ -ChannelModeList::ChannelModeList(ChannelModeName mName, char modeChar) : ChannelMode(mName, modeChar) +ChannelModeList::ChannelModeList(ChannelModeName cm, char mch) : ChannelMode(cm, mch) { - this->Type = MODE_LIST; + this->type = MODE_LIST; } -/** Default destructor - */ ChannelModeList::~ChannelModeList() { } -/** Default constructor - * @param mName The mode name - * @param modeChar The mode char - * @param MinusArg true if the mode sends no arg when unsetting - */ -ChannelModeParam::ChannelModeParam(ChannelModeName mName, char modeChar, bool MinusArg) : ChannelMode(mName, modeChar), MinusNoArg(MinusArg) +ChannelModeParam::ChannelModeParam(ChannelModeName cm, char mch, bool ma) : ChannelMode(cm, mch), minus_no_arg(ma) { - this->Type = MODE_PARAM; + this->type = MODE_PARAM; } -/** Default destructor - */ ChannelModeParam::~ChannelModeParam() { } -/** Default constructor - * @param mName The mode name - * @param modeChar The mode char - * @param mSymbol The symbol for the mode, eg @ % + - * @param mLevel A level for the mode, which is usually determined by the PREFIX capab - */ ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol, unsigned short mLevel) : ChannelMode(mName, modeChar), Symbol(mSymbol), Level(mLevel) { - this->Type = MODE_STATUS; + this->type = MODE_STATUS; } -/** Default destructor - */ ChannelModeStatus::~ChannelModeStatus() { } -/** Is the key valid - * @param value The key - * @return true or false - */ bool ChannelModeKey::IsValid(const Anope::string &value) const { if (!value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos) @@ -262,10 +188,6 @@ bool ChannelModeKey::IsValid(const Anope::string &value) const return false; } -/** Can admin only mode be set by the user - * @param u The user - can be NULL if defcon is checking - * @return true or false - */ bool ChannelModeAdmin::CanSet(User *u) const { if (u && u->HasMode(UMODE_OPER)) @@ -274,10 +196,6 @@ bool ChannelModeAdmin::CanSet(User *u) const return false; } -/** Can oper only mode be set by the user - * @param u The user - can be NULL if defcon is checking - * @return true or false - */ bool ChannelModeOper::CanSet(User *u) const { if (u && u->HasMode(UMODE_OPER)) @@ -286,21 +204,17 @@ bool ChannelModeOper::CanSet(User *u) const return false; } -/** Can the user set the registered mode? - * No. - * @return false - */ bool ChannelModeRegistered::CanSet(User *u) const { return false; } -void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param) +void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string ¶m) { - bool IsParam = mode->Type == MODE_PARAM; + bool is_param = mode->type == MODE_PARAM; std::list<std::pair<Mode *, Anope::string> > *list, *otherlist; - if (Set) + if (set) { list = &AddModes; otherlist = &DelModes; @@ -318,7 +232,7 @@ void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param) /* The param must match too (can have multiple status or list modes), but * if it is a param mode it can match no matter what the param is */ - if (it->first == mode && (Param.equals_cs(it->second) || IsParam)) + if (it->first == mode && (is_param || param.equals_cs(it->second))) { list->erase(it); /* It can only be on this list once */ @@ -331,7 +245,7 @@ void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param) /* The param must match too (can have multiple status or list modes), but * if it is a param mode it can match no matter what the param is */ - if (it->first == mode && (Param.equals_cs(it->second) || IsParam)) + if (it->first == mode && (is_param || param.equals_cs(it->second))) { otherlist->erase(it); return; @@ -343,7 +257,7 @@ void StackerInfo::AddMode(Mode *mode, bool Set, const Anope::string &Param) } /* Add this mode and its param to our list */ - list->push_back(std::make_pair(mode, Param)); + list->push_back(std::make_pair(mode, param)); } static class ModePipe : public Pipe @@ -371,10 +285,6 @@ static StackerInfo *GetInfo(List &l, Object *o) return s; } -/** Build a list of mode strings to send to the IRCd from the mode stacker - * @param info The stacker info for a channel or user - * @return a list of strings - */ std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info) { std::list<Anope::string> ret; @@ -384,7 +294,7 @@ std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info) for (it = info->AddModes.begin(), it_end = info->AddModes.end(); it != it_end; ++it) { - if (++NModes > ircdproto->MaxModes) + if (++NModes > IRCD->MaxModes) { ret.push_back(buf + parambuf); buf = "+"; @@ -392,7 +302,7 @@ std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info) NModes = 1; } - buf += it->first->ModeChar; + buf += it->first->mchar; if (!it->second.empty()) parambuf += " " + it->second; @@ -404,7 +314,7 @@ std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info) buf += "-"; for (it = info->DelModes.begin(), it_end = info->DelModes.end(); it != it_end; ++it) { - if (++NModes > ircdproto->MaxModes) + if (++NModes > IRCD->MaxModes) { ret.push_back(buf + parambuf); buf = "-"; @@ -412,7 +322,7 @@ std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info) NModes = 1; } - buf += it->first->ModeChar; + buf += it->first->mchar; if (!it->second.empty()) parambuf += " " + it->second; @@ -427,19 +337,15 @@ std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info) return ret; } -/** Add a user mode to Anope - * @param um A UserMode or UserMode derived class - * @return true on success, false on error - */ bool ModeManager::AddUserMode(UserMode *um) { - if (ModeManager::FindUserModeByChar(um->ModeChar) != NULL) + if (ModeManager::FindUserModeByChar(um->mchar) != NULL) return false; - if (um->Name == UMODE_END) + if (um->name == UMODE_END) { - um->Name = static_cast<UserModeName>(UMODE_END + ++GenericUserModes); - Log() << "ModeManager: Added generic support for user mode " << um->ModeChar; + um->name = static_cast<UserModeName>(UMODE_END + ++GenericUserModes); + Log() << "ModeManager: Added generic support for user mode " << um->mchar; } ModeManager::UserModes.push_back(um); @@ -448,154 +354,145 @@ bool ModeManager::AddUserMode(UserMode *um) return true; } -/** Add a channel mode to Anope - * @param cm A ChannelMode or ChannelMode derived class - * @return true on success, false on error - */ bool ModeManager::AddChannelMode(ChannelMode *cm) { - if (ModeManager::FindChannelModeByChar(cm->ModeChar) != NULL) + if (ModeManager::FindChannelModeByChar(cm->mchar) != NULL) return false; - if (cm->Name == CMODE_END) + if (cm->name == CMODE_END) { - cm->Name = static_cast<ChannelModeName>(CMODE_END + ++GenericChannelModes); - Log() << "ModeManager: Added generic support for channel mode " << cm->ModeChar; + cm->name = static_cast<ChannelModeName>(CMODE_END + ++GenericChannelModes); + Log() << "ModeManager: Added generic support for channel mode " << cm->mchar; } ModeManager::ChannelModes.push_back(cm); /* Apply this mode to the new default mlock if its used */ - SetDefaultMLock(Config); + UpdateDefaultMLock(Config); FOREACH_MOD(I_OnChannelModeAdd, OnChannelModeAdd(cm)); return true; } -/** Find a channel mode - * @param Mode The mode - * @return The mode class - */ + +void ModeManager::RemoveUserMode(UserMode *um) +{ + for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i) + { + UserMode *mode = ModeManager::UserModes[i]; + if (um == mode) + { + ModeManager::UserModes.erase(ModeManager::UserModes.begin() + i); + break; + } + } + + StackerDel(um); +} + +void ModeManager::RemoveChannelMode(ChannelMode *cm) +{ + for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) + { + ChannelMode *mode = ModeManager::ChannelModes[i]; + if (cm == mode) + { + ModeManager::ChannelModes.erase(ModeManager::ChannelModes.begin() + i); + break; + } + } + + StackerDel(cm); +} + ChannelMode *ModeManager::FindChannelModeByChar(char Mode) { for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (cm->ModeChar == Mode) + if (cm->mchar == Mode) return cm; } return NULL; } -/** Find a user mode - * @param Mode The mode - * @return The mode class - */ UserMode *ModeManager::FindUserModeByChar(char Mode) { for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i) { UserMode *um = ModeManager::UserModes[i]; - if (um->ModeChar == Mode) + if (um->mchar == Mode) return um; } return NULL; } -/** Find a channel mode - * @param Mode The modename - * @return The mode class - */ ChannelMode *ModeManager::FindChannelModeByName(ChannelModeName Name) { for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (cm->Name == Name) + if (cm->name == Name) return cm; } return NULL; } -/** Find a user mode - * @param Mode The modename - * @return The mode class - */ UserMode *ModeManager::FindUserModeByName(UserModeName Name) { for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i) { UserMode *um = ModeManager::UserModes[i]; - if (um->Name == Name) + if (um->name == Name) return um; } return NULL; } -/** Find channel mode by string - * @param name The mode name - * @return The mode - */ ChannelMode *ModeManager::FindChannelModeByString(const Anope::string &name) { for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (cm->NameAsString() == name || Anope::string(cm->ModeChar) == name) + if (cm->NameAsString() == name || Anope::string(cm->mchar) == name) return cm; } return NULL; } -/** Find user mode by string - * @param name The mode name - * @return The mode - */ UserMode *ModeManager::FindUserModeByString(const Anope::string &name) { for (size_t i = UMODE_BEGIN + 1; i != UMODE_END; ++i) { UserMode *um = ModeManager::FindUserModeByName(static_cast<UserModeName>(i)); - if (um != NULL && (um->NameAsString() == name || Anope::string(um->ModeChar) == name)) + if (um != NULL && (um->NameAsString() == name || Anope::string(um->mchar) == name)) return um; } return NULL; } - -/** Gets the channel mode char for a symbol (eg + returns v) - * @param Value The symbol - * @return The char - */ char ModeManager::GetStatusChar(char Value) { for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) { ChannelMode *cm = ModeManager::ChannelModes[i]; - if (cm->Type == MODE_STATUS) + if (cm->type == MODE_STATUS) { ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); if (Value == cms->Symbol) - return cms->ModeChar; + return cms->mchar; } } return 0; } -/** Add a mode to the stacker to be set on a channel - * @param bi The client to set the modes from - * @param c The channel - * @param cm The channel mode - * @param Set true for setting, false for removing - * @param Param The param, if there is one - */ void ModeManager::StackerAdd(const BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param) { StackerInfo *s = GetInfo(ChannelStackerObjects, c); @@ -610,13 +507,6 @@ void ModeManager::StackerAdd(const BotInfo *bi, Channel *c, ChannelMode *cm, boo modePipe->Notify(); } -/** Add a mode to the stacker to be set on a user - * @param bi The client to set the modes from - * @param u The user - * @param um The user mode - * @param Set true for setting, false for removing - * @param param The param, if there is one - */ void ModeManager::StackerAdd(const BotInfo *bi, User *u, UserMode *um, bool Set, const Anope::string &Param) { StackerInfo *s = GetInfo(UserStackerObjects, u); @@ -631,8 +521,6 @@ void ModeManager::StackerAdd(const BotInfo *bi, User *u, UserMode *um, bool Set, modePipe->Notify(); } -/** Process all of the modes in the stacker and send them to the IRCd to be set on channels/users - */ void ModeManager::ProcessModes() { if (!UserStackerObjects.empty()) @@ -644,7 +532,7 @@ void ModeManager::ProcessModes() std::list<Anope::string> ModeStrings = BuildModeStrings(s); for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit) - ircdproto->SendMode(s->bi, u, lit->c_str()); + IRCD->SendMode(s->bi, u, lit->c_str()); delete it->second; } UserStackerObjects.clear(); @@ -659,15 +547,13 @@ void ModeManager::ProcessModes() std::list<Anope::string> ModeStrings = BuildModeStrings(s); for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit) - ircdproto->SendMode(s->bi, c, lit->c_str()); + IRCD->SendMode(s->bi, c, lit->c_str()); delete it->second; } ChannelStackerObjects.clear(); } } -/** Delete a user or channel from the stacker - */ void ModeManager::StackerDel(User *u) { UserStackerObjects.erase(u); @@ -678,3 +564,245 @@ void ModeManager::StackerDel(Channel *c) ChannelStackerObjects.erase(c); } +void ModeManager::StackerDel(Mode *m) +{ + for (std::map<User *, StackerInfo *>::const_iterator it = UserStackerObjects.begin(), it_end = UserStackerObjects.end(); it != it_end;) + { + StackerInfo *si = it->second; + ++it; + + for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->AddModes.begin(), it2_end = si->AddModes.end(); it2 != it2_end;) + { + Mode *mode = it2->first; + ++it2; + + if (mode == m) + si->AddModes.erase(it2); + } + + for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->DelModes.begin(), it2_end = si->DelModes.end(); it2 != it2_end;) + { + Mode *mode = it2->first; + ++it2; + + if (mode == m) + si->DelModes.erase(it2); + } + } + + for (std::map<Channel *, StackerInfo *>::const_iterator it = ChannelStackerObjects.begin(), it_end = ChannelStackerObjects.end(); it != it_end;) + { + StackerInfo *si = it->second; + ++it; + + for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->AddModes.begin(), it2_end = si->AddModes.end(); it2 != it2_end;) + { + Mode *mode = it2->first; + ++it2; + + if (mode == m) + si->AddModes.erase(it2); + } + + for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->DelModes.begin(), it2_end = si->DelModes.end(); it2 != it2_end;) + { + Mode *mode = it2->first; + ++it2; + + if (mode == m) + si->DelModes.erase(it2); + } + } +} + +void ModeManager::UpdateDefaultMLock(ServerConfig *config) +{ + for (ChannelInfo::ModeList::iterator it = DefaultModeLocks.begin(), it_end = DefaultModeLocks.end(); it != it_end; ++it) + delete it->second; + DefaultModeLocks.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 + { + ChannelInfo::ModeList::iterator it = DefaultModeLocks.find(cm->name); + if (it != DefaultModeLocks.end()) + { + delete it->second; + DefaultModeLocks.erase(it); + } + } + DefaultModeLocks.insert(std::make_pair(cm->name, new ModeLock(NULL, adding == 1, cm->name, param))); + } + } + } + + /* Set Bot Modes */ + DefaultBotModes.ClearFlags(); + for (unsigned i = 0; i < config->BotModes.length(); ++i) + { + ChannelMode *cm = ModeManager::FindChannelModeByChar(config->BotModes[i]); + + if (cm && cm->type == MODE_STATUS) + DefaultBotModes.SetFlag(cm->name); + } +} + +Entry::Entry(ChannelModeName mode, const Anope::string &_host) : modename(mode) +{ + this->SetFlag(ENTRYTYPE_NONE); + this->cidr_len = 0; + this->mask = _host; + + Anope::string _nick, _user, _realhost; + size_t at = _host.find('@'); + if (at != Anope::string::npos) + { + _realhost = _host.substr(at + 1); + Anope::string _nickident = _host.substr(0, at); + + size_t ex = _nickident.find('!'); + if (ex != Anope::string::npos) + { + _user = _nickident.substr(ex + 1); + _nick = _nickident.substr(0, ex); + } + else + _user = _nickident; + } + else + _realhost = _host; + + if (!_nick.empty() && _nick.find_first_not_of("*") != Anope::string::npos) + { + this->nick = _nick; + if (_nick.find_first_of("*?") != Anope::string::npos) + this->SetFlag(ENTRYTYPE_NICK_WILD); + else + this->SetFlag(ENTRYTYPE_NICK); + } + + if (!_user.empty() && _user.find_first_not_of("*") != Anope::string::npos) + { + this->user = _user; + if (_user.find_first_of("*?") != Anope::string::npos) + this->SetFlag(ENTRYTYPE_USER_WILD); + else + this->SetFlag(ENTRYTYPE_USER); + } + + if (!_realhost.empty() && _realhost.find_first_not_of("*") != Anope::string::npos) + { + size_t sl = _realhost.find_last_of('/'); + if (sl != Anope::string::npos) + { + try + { + sockaddrs addr(_realhost.substr(0, sl)); + /* If we got here, _realhost is a valid IP */ + + Anope::string cidr_range = _realhost.substr(sl + 1); + if (cidr_range.is_pos_number_only()) + { + _realhost = _realhost.substr(0, sl); + this->cidr_len = convertTo<unsigned int>(cidr_range); + this->SetFlag(ENTRYTYPE_CIDR); + Log(LOG_DEBUG) << "Ban " << _realhost << " has cidr " << static_cast<unsigned int>(this->cidr_len); + } + } + catch (const SocketException &) { } + } + + this->host = _realhost; + + if (!this->HasFlag(ENTRYTYPE_CIDR)) + { + if (_realhost.find_first_of("*?") != Anope::string::npos) + this->SetFlag(ENTRYTYPE_HOST_WILD); + else + this->SetFlag(ENTRYTYPE_HOST); + } + } +} + +const Anope::string Entry::GetMask() +{ + return this->mask; +} + +bool Entry::Matches(const User *u, bool full) const +{ + bool ret = true; + + if (this->HasFlag(ENTRYTYPE_CIDR)) + { + try + { + if (full) + { + cidr cidr_mask(this->host, this->cidr_len); + sockaddrs addr(u->ip); + if (!cidr_mask.match(addr)) + ret = false; + } + /* If we're not matching fully and their displayed host isnt their IP */ + else if (u->ip != u->GetDisplayedHost()) + ret = false; + } + catch (const SocketException &) + { + ret = false; + } + } + if (this->HasFlag(ENTRYTYPE_NICK) && !this->nick.equals_ci(u->nick)) + ret = false; + if (this->HasFlag(ENTRYTYPE_USER) && !this->user.equals_ci(u->GetVIdent()) && (!full || + !this->user.equals_ci(u->GetIdent()))) + ret = false; + if (this->HasFlag(ENTRYTYPE_HOST) && !this->host.equals_ci(u->GetDisplayedHost()) && (!full || + (!this->host.equals_ci(u->host) && !this->host.equals_ci(u->chost) && !this->host.equals_ci(u->vhost) && + !this->host.equals_ci(u->ip)))) + ret = false; + if (this->HasFlag(ENTRYTYPE_NICK_WILD) && !Anope::Match(u->nick, this->nick)) + ret = false; + if (this->HasFlag(ENTRYTYPE_USER_WILD) && !Anope::Match(u->GetVIdent(), this->user) && (!full || + !Anope::Match(u->GetIdent(), this->user))) + ret = false; + if (this->HasFlag(ENTRYTYPE_HOST_WILD) && !Anope::Match(u->GetDisplayedHost(), this->host) && (!full || + (!Anope::Match(u->host, this->host) && !Anope::Match(u->chost, this->host) && + !Anope::Match(u->vhost, this->host) && !Anope::Match(u->ip, this->host)))) + ret = false; + + ChannelMode *cm = ModeManager::FindChannelModeByName(this->modename); + if (cm != NULL && cm->type == MODE_LIST) + { + ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); + if (cml->Matches(u, this)) + ret = true; + } + + return ret; +} + diff --git a/src/module.cpp b/src/module.cpp index e69b7c6a3..3c3b8fdd1 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -4,13 +4,13 @@ * Contact us at team@anope.org * * Please read COPYING and README for further details. + * */ - #include "services.h" #include "modules.h" -#include "extern.h" #include "dns.h" +#include "language.h" #ifdef GETTEXT_FOUND # include <libintl.h> @@ -26,19 +26,19 @@ Module::Module(const Anope::string &modname, const Anope::string &, ModType modt if (ModuleManager::FindModule(this->name)) throw CoreException("Module already exists!"); - if (nothird && modtype == THIRD) + if (Anope::NoThird && modtype == THIRD) throw ModuleException("Third party modules may not be loaded"); - Modules.push_back(this); + ModuleManager::Modules.push_back(this); #if GETTEXT_FOUND - for (unsigned i = 0; i < languages.size(); ++i) - if (IsFile(locale_dir + "/" + languages[i] + "/LC_MESSAGES/" + modname + ".mo")) + for (unsigned i = 0; i < Language::Languages.size(); ++i) + if (Anope::IsFile(Anope::LocaleDir + "/" + Language::Languages[i] + "/LC_MESSAGES/" + modname + ".mo")) { - if (!bindtextdomain(this->name.c_str(), locale_dir.c_str())) + if (!bindtextdomain(this->name.c_str(), Anope::LocaleDir.c_str())) Log() << "Error calling bindtextdomain, " << Anope::LastError(); else - domains.push_back(modname); + Language::Domains.push_back(modname); break; } #endif @@ -46,22 +46,22 @@ Module::Module(const Anope::string &modname, const Anope::string &, ModType modt Module::~Module() { - if (DNSEngine) - DNSEngine->Cleanup(this); + if (DNS::Engine) + DNS::Engine->Cleanup(this); /* Detach all event hooks for this module */ ModuleManager::DetachAll(this); /* Clear any active callbacks this module has */ ModuleManager::ClearCallBacks(this); IdentifyRequest::ModuleUnload(this); - std::list<Module *>::iterator it = std::find(Modules.begin(), Modules.end(), this); - if (it != Modules.end()) - Modules.erase(it); + std::list<Module *>::iterator it = std::find(ModuleManager::Modules.begin(), ModuleManager::Modules.end(), this); + if (it != ModuleManager::Modules.end()) + ModuleManager::Modules.erase(it); #if GETTEXT_FOUND - std::vector<Anope::string>::iterator dit = std::find(domains.begin(), domains.end(), this->name); - if (dit != domains.end()) - domains.erase(dit); + std::vector<Anope::string>::iterator dit = std::find(Language::Domains.begin(), Language::Domains.end(), this->name); + if (dit != Language::Domains.end()) + Language::Domains.erase(dit); #endif } @@ -85,26 +85,38 @@ void Module::SetAuthor(const Anope::string &nauthor) this->author = nauthor; } -ModuleVersion::ModuleVersion(int vMajor, int vMinor, int vPatch) : Major(vMajor), Minor(vMinor), Patch(vPatch) +IRCDProto *Module::GetIRCDProto() { + return NULL; } -ModuleVersion::~ModuleVersion() +ModuleVersion::ModuleVersion(int maj, int min, int pa) : version_major(maj), version_minor(min), version_patch(pa) { } int ModuleVersion::GetMajor() const { - return this->Major; + return this->version_major; } int ModuleVersion::GetMinor() const { - return this->Minor; + return this->version_minor; } int ModuleVersion::GetPatch() const { - return this->Patch; + return this->version_patch; +} + +CallBack::CallBack(Module *mod, long time_from_now, time_t now, bool repeating) : Timer(time_from_now, now, repeating), m(mod) +{ +} + +CallBack::~CallBack() +{ + std::list<CallBack *>::iterator it = std::find(m->callbacks.begin(), m->callbacks.end(), this); + if (it != m->callbacks.end()) + m->callbacks.erase(it); } diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 360a0d34b..5e2165e30 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -4,11 +4,11 @@ * Contact us at team@anope.org * * Please read COPYING and README for further details. + * */ #include "services.h" #include "modules.h" -#include "extern.h" #include "users.h" #include "regchannel.h" @@ -20,11 +20,12 @@ #include <dlfcn.h> #endif +std::list<Module *> ModuleManager::Modules; std::vector<Module *> ModuleManager::EventHandlers[I_END]; void ModuleManager::CleanupRuntimeDirectory() { - Anope::string dirbuf = db_dir + "/runtime"; + Anope::string dirbuf = Anope::DataDir + "/runtime"; Log(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait"; @@ -59,7 +60,7 @@ void ModuleManager::CleanupRuntimeDirectory() */ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &output) { - Anope::string input = modules_dir + "/modules/" + name + ".so"; + Anope::string input = Anope::ModuleDir + "/modules/" + name + ".so"; struct stat s; if (stat(input.c_str(), &s) == -1) @@ -114,7 +115,7 @@ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &out * This function will take a pointer from either dlsym or GetProcAddress and cast it in * a way that won't cause C++ warnings/errors to come up. */ -template <class TYPE> TYPE function_cast(void *symbol) +template <class TYPE> static TYPE function_cast(void *symbol) { union { @@ -136,7 +137,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) Log(LOG_DEBUG) << "trying to load [" << modname << "]"; /* Generate the filename for the temporary copy of the module */ - Anope::string pbuf = db_dir + "/runtime/" + modname + ".so.XXXXXX"; + Anope::string pbuf = Anope::DataDir + "/runtime/" + modname + ".so.XXXXXX"; /* Don't skip return value checking! -GD */ ModuleReturn ret = moduleCopyFile(modname, pbuf); @@ -219,12 +220,6 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) else Log(LOG_DEBUG_2) << "Module " << modname << " is compiled against current version of Anope " << Anope::VersionShort(); - if (m->type == PROTOCOL && ModuleManager::FindFirstOf(PROTOCOL) != m) - { - DeleteModule(m); - Log() << "You cannot load two protocol modules"; - return MOD_ERR_UNKNOWN; - } Log(LOG_DEBUG) << "Module loaded."; FOREACH_MOD(I_OnModuleLoad, OnModuleLoad(u, m)); @@ -455,17 +450,12 @@ bool ModuleManager::SetPriority(Module *mod, Implementation i, Priority s, Modul return true; } -/** Delete all callbacks attached to a module - * @param m The module - */ void ModuleManager::ClearCallBacks(Module *m) { - while (!m->CallBacks.empty()) - delete m->CallBacks.front(); + while (!m->callbacks.empty()) + delete m->callbacks.front(); } -/** Unloading all modules except the protocol module. - */ void ModuleManager::UnloadAll() { std::vector<Anope::string> modules[MT_END]; diff --git a/src/modules.cpp b/src/modules.cpp deleted file mode 100644 index 453a89a1a..000000000 --- a/src/modules.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* Modular support - * - * (C) 2003-2012 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. - */ - - -#include "services.h" -#include "modules.h" - -std::list<Module *> Modules; - -CallBack::CallBack(Module *mod, long time_from_now, time_t now, bool repeating) : Timer(time_from_now, now, repeating), m(mod) -{ -} - -CallBack::~CallBack() -{ - std::list<CallBack *>::iterator it = std::find(m->CallBacks.begin(), m->CallBacks.end(), this); - if (it != m->CallBacks.end()) - m->CallBacks.erase(it); -} - diff --git a/src/nickalias.cpp b/src/nickalias.cpp index 0268b98be..f163c145f 100644 --- a/src/nickalias.cpp +++ b/src/nickalias.cpp @@ -7,9 +7,9 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ - #include "services.h" #include "account.h" #include "modules.h" @@ -19,17 +19,9 @@ #include "servers.h" #include "config.h" -serialize_checker<nickalias_map> NickAliasList("NickAlias"); +Serialize::Checker<nickalias_map> NickAliasList("NickAlias"); -class NickServHeld; -typedef std::map<Anope::string, NickServHeld *> nickservheld_map; -static nickservheld_map NickServHelds; - -/** Default constructor - * @param nick The nick - * @param nickcore The nickcore for this nick - */ -NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serializable("NickAlias"), Flags<NickNameFlag, NS_END>(NickNameFlagStrings) +NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serializable("NickAlias") { if (nickname.empty()) throw CoreException("Empty nick passed to NickAlias constructor"); @@ -57,8 +49,6 @@ NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serial } } -/** Default destructor - */ NickAlias::~NickAlias() { FOREACH_MOD(I_OnDelNick, OnDelNick(this)); @@ -67,19 +57,19 @@ NickAlias::~NickAlias() if (this->nc) { /* Next: see if our core is still useful. */ - std::list<serialize_obj<NickAlias> >::iterator it = std::find(this->nc->aliases.begin(), this->nc->aliases.end(), this); + std::list<Serialize::Reference<NickAlias> >::iterator it = std::find(this->nc->aliases.begin(), this->nc->aliases.end(), this); if (it != this->nc->aliases.end()) this->nc->aliases.erase(it); if (this->nc->aliases.empty()) { - this->nc->destroy(); + this->nc->Destroy(); this->nc = NULL; } else { /* Display updating stuff */ if (this->nick.equals_ci(this->nc->display)) - change_core_display(this->nc); + this->nc->SetDisplay(this->nc->aliases.front()); } } @@ -87,19 +77,15 @@ NickAlias::~NickAlias() NickAliasList->erase(this->nick); } -/** Release a nick from being held. This can be called from the core (ns_release) - * or from a timer used when forcing clients off of nicks. Note that if this is called - * from a timer, ircd->svshold is NEVER true - */ void NickAlias::Release() { if (this->HasFlag(NS_HELD)) { - if (ircdproto->CanSVSHold) - ircdproto->SendSVSHoldDel(this->nick); + if (IRCD->CanSVSHold) + IRCD->SendSVSHoldDel(this->nick); else { - User *u = finduser(this->nick); + User *u = User::Find(this->nick); if (u && u->server == Me) { delete u; @@ -114,12 +100,14 @@ void NickAlias::Release() */ class NickServHeld : public Timer { - dynamic_reference<NickAlias> na; + static std::map<Anope::string, NickServHeld *> NickServHelds; + + Reference<NickAlias> na; Anope::string nick; public: NickServHeld(NickAlias *n, long l) : Timer(l), na(n), nick(na->nick) { - nickservheld_map::iterator nit = NickServHelds.find(na->nick); + std::map<Anope::string, NickServHeld *>::iterator nit = NickServHelds.find(na->nick); if (nit != NickServHelds.end()) delete nit->second; @@ -137,6 +125,7 @@ class NickServHeld : public Timer na->UnsetFlag(NS_HELD); } }; +std::map<Anope::string, NickServHeld *> NickServHeld::NickServHelds; /** Timers for releasing nicks to be available for use */ @@ -146,27 +135,25 @@ class CoreExport NickServRelease : public User, public Timer Anope::string nick; public: - /** Default constructor + /** Constructor * @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, "", ts6_uid_retrieve()), Timer(delay), nick(na->nick) + 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) { /* Erase the current release timer and use the new one */ std::map<Anope::string, NickServRelease *>::iterator nit = NickServReleases.find(this->nick); if (nit != NickServReleases.end()) { - ircdproto->SendQuit(nit->second, ""); + IRCD->SendQuit(nit->second, ""); delete nit->second; } NickServReleases.insert(std::make_pair(this->nick, this)); - ircdproto->SendClientIntroduction(this); + IRCD->SendClientIntroduction(this); } - /** Default destructor - */ virtual ~NickServRelease() { NickServReleases.erase(this->nick); @@ -177,15 +164,11 @@ class CoreExport NickServRelease : public User, public Timer */ void Tick(time_t t) { - ircdproto->SendQuit(this, ""); + IRCD->SendQuit(this, ""); } }; std::map<Anope::string, NickServRelease *> NickServRelease::NickServReleases; -/** Called when a user gets off this nick - * See the comment in users.cpp for User::Collide() - * @param u The user - */ void NickAlias::OnCancel(User *) { if (this->HasFlag(NS_COLLIDED)) @@ -195,8 +178,8 @@ void NickAlias::OnCancel(User *) new NickServHeld(this, Config->NSReleaseTimeout); - if (ircdproto->CanSVSHold) - ircdproto->SendSVSHold(this->nick); + if (IRCD->CanSVSHold) + IRCD->SendSVSHold(this->nick); else new NickServRelease(this, Config->NSReleaseTimeout); } @@ -243,17 +226,29 @@ time_t NickAlias::GetVhostCreated() const return this->vhost_created; } -Serialize::Data NickAlias::serialize() const +NickAlias *NickAlias::Find(const Anope::string &nick) +{ + nickalias_map::const_iterator it = NickAliasList->find(nick); + if (it != NickAliasList->end()) + { + it->second->QueueUpdate(); + return it->second; + } + + return NULL; +} + +Serialize::Data NickAlias::Serialize() const { Serialize::Data data; - data["nick"].setMax(Config->NickLen) << this->nick; + data["nick"].SetMax(Config->NickLen) << this->nick; data["last_quit"] << this->last_quit; data["last_realname"] << this->last_realname; data["last_usermask"] << this->last_usermask; data["last_realhost"] << this->last_realhost; - data["time_registered"].setType(Serialize::DT_INT) << this->time_registered; - data["last_seen"].setType(Serialize::DT_INT) << this->last_seen; + data["time_registered"].SetType(Serialize::DT_INT) << this->time_registered; + data["last_seen"].SetType(Serialize::DT_INT) << this->last_seen; data["nc"] << this->nc->display; data["flags"] << this->ToString(); @@ -268,9 +263,9 @@ Serialize::Data NickAlias::serialize() const return data; } -Serializable* NickAlias::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data) { - NickCore *core = findcore(data["nc"].astr()); + NickCore *core = NickCore::Find(data["nc"].astr()); if (core == NULL) return NULL; @@ -282,14 +277,14 @@ Serializable* NickAlias::unserialize(Serializable *obj, Serialize::Data &data) if (na->nc != core) { - std::list<serialize_obj<NickAlias> >::iterator it = std::find(na->nc->aliases.begin(), na->nc->aliases.end(), na); + std::list<Serialize::Reference<NickAlias> >::iterator it = std::find(na->nc->aliases.begin(), na->nc->aliases.end(), na); if (it != na->nc->aliases.end()) na->nc->aliases.erase(it); if (na->nc->aliases.empty()) delete na->nc; else if (na->nick.equals_ci(na->nc->display)) - change_core_display(na->nc); + na->nc->SetDisplay(na->nc->aliases.front()); na->nc = core; core->aliases.push_back(na); diff --git a/src/nickcore.cpp b/src/nickcore.cpp index 0e637d0cf..f9ac3ef6c 100644 --- a/src/nickcore.cpp +++ b/src/nickcore.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -14,12 +15,21 @@ #include "account.h" #include "config.h" -serialize_checker<nickcore_map> NickCoreList("NickCore"); +Serialize::Checker<nickcore_map> NickCoreList("NickCore"); -/** Default constructor - * @param display The display nick - */ -NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"), Flags<NickCoreFlag, NI_END>(NickCoreFlagStrings) +static const Anope::string NickNameFlagStrings[] = { + "BEGIN", "NO_EXPIRE", "HELD", "COLLIDED", "" +}; +template<> const Anope::string* Flags<NickNameFlag>::flags_strings = NickNameFlagStrings; + +static const Anope::string NickCoreFlagStrings[] = { + "BEGIN", "KILLPROTECT", "SECURE", "MSG", "MEMO_HARDMAX", "MEMO_SIGNON", "MEMO_RECEIVE", + "PRIVATE", "HIDE_EMAIL", "HIDE_MASK", "HIDE_QUIT", "KILL_QUICK", "KILL_IMMED", + "MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "UNCONFIRMED", "STATS", "" +}; +template<> const Anope::string* Flags<NickCoreFlag>::flags_strings = NickCoreFlagStrings; + +NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore") { if (coredisplay.empty()) throw CoreException("Empty display passed to NickCore constructor"); @@ -43,12 +53,17 @@ NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"), Log(LOG_DEBUG) << "Duplicate account " << coredisplay << " in nickcore table?"; } -/** Default destructor - */ NickCore::~NickCore() { FOREACH_MOD(I_OnDelCore, OnDelCore(this)); + for (std::list<User *>::iterator it = this->users.begin(); it != this->users.end();) + { + User *user = *it++; + user->Logout(); + } + this->users.clear(); + /* Remove the core from the list */ NickCoreList->erase(this->display); @@ -58,16 +73,16 @@ NickCore::~NickCore() if (!this->memos.memos->empty()) { for (unsigned i = 0, end = this->memos.memos->size(); i < end; ++i) - this->memos.GetMemo(i)->destroy(); + this->memos.GetMemo(i)->Destroy(); this->memos.memos->clear(); } } -Serialize::Data NickCore::serialize() const +Serialize::Data NickCore::Serialize() const { Serialize::Data data; - data["display"].setMax(Config->NickLen) << this->display; + data["display"].SetMax(Config->NickLen) << this->display; data["pass"] << this->pass; data["email"] << this->email; data["greet"] << this->greet; @@ -84,7 +99,7 @@ Serialize::Data NickCore::serialize() const return data; } -Serializable* NickCore::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* NickCore::Unserialize(Serializable *obj, Serialize::Data &data) { NickCore *nc; @@ -127,6 +142,21 @@ Serializable* NickCore::unserialize(Serializable *obj, Serialize::Data &data) return nc; } +void NickCore::SetDisplay(const NickAlias *na) +{ + if (na->nc != this || na->nick == this->display) + return; + + FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(this, na->nick)); + + /* Remove the core from the list */ + NickCoreList->erase(this->display); + + this->display = na->nick; + + (*NickCoreList)[this->display] = this; +} + bool NickCore::IsServicesOper() const { return this->o != NULL; @@ -171,6 +201,23 @@ void NickCore::ClearAccess() this->access.clear(); } +bool NickCore::IsOnAccess(const User *u) const +{ + Anope::string buf = u->GetIdent() + "@" + u->host, buf2, buf3; + if (!u->vhost.empty()) + buf2 = u->GetIdent() + "@" + u->vhost; + if (!u->GetCloakedHost().empty()) + buf3 = u->GetIdent() + "@" + u->GetCloakedHost(); + + for (unsigned i = 0, end = this->access.size(); i < end; ++i) + { + Anope::string a = this->GetAccess(i); + if (Anope::Match(buf, a) || (!buf2.empty() && Anope::Match(buf2, a)) || (!buf3.empty() && Anope::Match(buf3, a))) + return true; + } + return false; +} + void NickCore::AddCert(const Anope::string &entry) { this->cert.push_back(entry); @@ -209,3 +256,16 @@ void NickCore::ClearCert() FOREACH_MOD(I_OnNickClearCert, OnNickClearCert(this)); this->cert.clear(); } + +NickCore* NickCore::Find(const Anope::string &nick) +{ + nickcore_map::const_iterator it = NickCoreList->find(nick); + if (it != NickCoreList->end()) + { + it->second->QueueUpdate(); + return it->second; + } + + return NULL; +} + diff --git a/src/nickserv.cpp b/src/nickserv.cpp deleted file mode 100644 index 8b5c41df9..000000000 --- a/src/nickserv.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* NickServ functions. - * - * (C) 2003-2012 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. - */ - -#include "services.h" -#include "account.h" -#include "modules.h" -#include "users.h" -#include "protocol.h" -#include "regchannel.h" - -NickAlias* findnick(const Anope::string &nick) -{ - nickalias_map::const_iterator it = NickAliasList->find(nick); - if (it != NickAliasList->end()) - { - it->second->QueueUpdate(); - return it->second; - } - - return NULL; -} - -/*************************************************************************/ - -NickCore* findcore(const Anope::string &nick) -{ - nickcore_map::const_iterator it = NickCoreList->find(nick); - if (it != NickCoreList->end()) - { - it->second->QueueUpdate(); - return it->second; - } - - return NULL; -} - -/** Is the user's address on the nickcores access list? - * @param u The user - * @param nc The nickcore - * @return true or false - */ -bool is_on_access(const User *u, const NickCore *nc) -{ - if (!u || !nc || nc->access.empty()) - return false; - - Anope::string buf = u->GetIdent() + "@" + u->host, buf2, buf3; - if (!u->vhost.empty()) - buf2 = u->GetIdent() + "@" + u->vhost; - if (!u->GetCloakedHost().empty()) - buf3 = u->GetIdent() + "@" + u->GetCloakedHost(); - - for (unsigned i = 0, end = nc->access.size(); i < end; ++i) - { - Anope::string access = nc->GetAccess(i); - if (Anope::Match(buf, access) || (!buf2.empty() && Anope::Match(buf2, access)) || (!buf3.empty() && Anope::Match(buf3, access))) - return true; - } - return false; -} - -/*************************************************************************/ - -/* Sets nc->display to newdisplay. If newdisplay is NULL, it will change - * it to the first alias in the list. - */ - -void change_core_display(NickCore *nc, const Anope::string &newdisplay) -{ - FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(nc, newdisplay)); - - /* Remove the core from the list */ - NickCoreList->erase(nc->display); - - nc->display = newdisplay; - - (*NickCoreList)[nc->display] = nc; -} - -void change_core_display(NickCore *nc) -{ - const NickAlias *na; - if (nc->aliases.empty()) - return; - na = nc->aliases.front(); - change_core_display(nc, na->nick); -} - -std::set<IdentifyRequest *> IdentifyRequest::requests; - -IdentifyRequest::IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass) : owner(o), account(acc), password(pass), dispatched(false), success(false) -{ - requests.insert(this); -} - -IdentifyRequest::~IdentifyRequest() -{ - requests.erase(this); -} - -void IdentifyRequest::Hold(Module *m) -{ - holds.insert(m); -} - -void IdentifyRequest::Release(Module *m) -{ - holds.erase(m); - if (holds.empty() && dispatched) - { - if (!success) - this->OnFail(); - delete this; - } -} - -void IdentifyRequest::Success(Module *m) -{ - if (!success) - { - this->OnSuccess(); - success = true; - } -} - -void IdentifyRequest::Dispatch() -{ - if (holds.empty()) - { - if (!success) - this->OnFail(); - delete this; - } - else - dispatched = true; -} - -void IdentifyRequest::ModuleUnload(Module *m) -{ - for (std::set<IdentifyRequest *>::iterator it = requests.begin(), it_end = requests.end(); it != it_end;) - { - IdentifyRequest *ir = *it; - ++it; - - ir->Release(m); - if (ir->owner == m) - delete ir; - } -} diff --git a/src/operserv.cpp b/src/operserv.cpp deleted file mode 100644 index f1c2edeea..000000000 --- a/src/operserv.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/* OperServ functions. - * - * (C) 2003-2012 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. - */ - - -#include "services.h" -#include "modules.h" -#include "oper.h" -#include "users.h" -#include "extern.h" -#include "sockets.h" -#include "regexpr.h" -#include "config.h" -#include "commands.h" - -/* List of XLine managers we check users against in XLineManager::CheckAll */ -std::list<XLineManager *> XLineManager::XLineManagers; -serialize_checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManager::XLinesByUID("XLine"); - -void XLine::InitRegex() -{ - if (!Config->RegexEngine.empty() && this->Mask.length() >= 2 && this->Mask[0] == '/' && this->Mask[this->Mask.length() - 1] == '/') - { - Anope::string stripped_mask = this->Mask.substr(1, this->Mask.length() - 2); - - service_reference<RegexProvider> provider("Regex", Config->RegexEngine); - if (provider) - { - try - { - this->regex = provider->Compile(stripped_mask); - } - catch (const RegexException &ex) - { - Log(LOG_DEBUG) << ex.GetReason(); - } - } - } -} - -XLine::XLine(const Anope::string &mask, const Anope::string &reason, const Anope::string &uid) : Serializable("XLine"), Mask(mask), By(Config->OperServ), Created(0), Expires(0), Reason(reason), UID(uid) -{ - regex = NULL; - manager = NULL; - - this->InitRegex(); -} - -XLine::XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid) : Serializable("XLine"), Mask(mask), By(by), Created(Anope::CurTime), Expires(expires), Reason(reason), UID(uid) -{ - regex = NULL; - manager = NULL; - - this->InitRegex(); -} - -XLine::~XLine() -{ - delete regex; -} - -Anope::string XLine::GetNick() const -{ - size_t nick_t = this->Mask.find('!'); - - if (nick_t == Anope::string::npos) - return ""; - - return this->Mask.substr(0, nick_t); -} - -Anope::string XLine::GetUser() const -{ - size_t user_t = this->Mask.find('!'), host_t = this->Mask.find('@'); - - if (host_t != Anope::string::npos) - { - if (user_t != Anope::string::npos && host_t > user_t) - return this->Mask.substr(user_t + 1, host_t - user_t - 1); - else - return this->Mask.substr(0, host_t); - } - else - return ""; -} - -Anope::string XLine::GetHost() const -{ - size_t host_t = this->Mask.find('@'), real_t = this->Mask.find('#'); - - if (host_t != Anope::string::npos) - { - if (real_t != Anope::string::npos && real_t > host_t) - return this->Mask.substr(host_t + 1, real_t - host_t - 1); - else - return this->Mask.substr(host_t + 1); - } - else - return ""; -} - -Anope::string XLine::GetReal() const -{ - size_t real_t = this->Mask.find('#'); - - if (real_t != Anope::string::npos) - return this->Mask.substr(real_t + 1); - else - return ""; -} - -Anope::string XLine::GetReason() const -{ - Anope::string r = this->Reason; - if (Config->AddAkiller && !this->By.empty()) - r = "[" + this->By + "] " + r; - if (!this->UID.empty()) - r += " (ID: " + this->UID + ")"; - return r; -} - -bool XLine::HasNickOrReal() const -{ - bool r = this->GetNick().find_first_not_of("?*") != Anope::string::npos; - r = r || this->GetReal().find_first_not_of("?*") != Anope::string::npos; - return r; -} - -bool XLine::IsRegex() const -{ - return !this->Mask.empty() && this->Mask[0] == '/' && this->Mask[this->Mask.length() - 1] == '/'; -} - -Serialize::Data XLine::serialize() const -{ - Serialize::Data data; - - data["mask"] << this->Mask; - data["by"] << this->By; - data["created"] << this->Created; - data["expires"] << this->Expires; - data["reason"] << this->Reason; - data["uid"] << this->UID; - if (this->manager) - data["manager"] << this->manager->name; - - return data; -} - -Serializable* XLine::unserialize(Serializable *obj, Serialize::Data &data) -{ - service_reference<XLineManager> xlm("XLineManager", data["manager"].astr()); - if (!xlm) - return NULL; - - XLine *xl; - if (obj) - { - xl = anope_dynamic_static_cast<XLine *>(obj); - data["mask"] >> xl->Mask; - data["by"] >> xl->By; - data["reason"] >> xl->Reason; - data["uid"] >> xl->UID; - - if (xlm != xl->manager) - { - xl->manager->DelXLine(xl); - xlm->AddXLine(xl); - } - } - else - { - time_t expires; - data["expires"] >> expires; - xl = new XLine(data["mask"].astr(), data["by"].astr(), expires, data["reason"].astr(), data["uid"].astr()); - xlm->AddXLine(xl); - } - - data["created"] >> xl->Created; - xl->manager = xlm; - - return xl; -} - -/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll - * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling - * clients and one handing them free olines, you would want the akilling one first. This way if a client - * matches an entry on both of the XLineManagers, they would be akilled. - * @param xlm THe XLineManager - */ -void XLineManager::RegisterXLineManager(XLineManager *xlm) -{ - XLineManagers.push_back(xlm); -} - -/** Unregister a XLineManager - * @param xlm The XLineManager - */ -void XLineManager::UnregisterXLineManager(XLineManager *xlm) -{ - std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm); - - if (it != XLineManagers.end()) - XLineManagers.erase(it); -} - -/* Check a user against all known XLineManagers - * @param u The user - * @return A pair of the XLineManager the user was found in and the XLine they matched, both may be NULL for no match - */ -void XLineManager::CheckAll(User *u) -{ - for (std::list<XLineManager *>::iterator it = XLineManagers.begin(), it_end = XLineManagers.end(); it != it_end; ++it) - { - XLineManager *xlm = *it; - - XLine *x = xlm->CheckAllXLines(u); - - if (x) - { - xlm->OnMatch(u, x); - break; - } - } -} - -Anope::string XLineManager::GenerateUID() -{ - Anope::string id; - int count = 0; - while (id.empty() || XLinesByUID->count(id) > 0) - { - if (++count > 10) - { - id.clear(); - Log(LOG_DEBUG) << "Unable to generate XLine UID"; - break; - } - - for (int i = 0; i < 10; ++i) - { - char c; - do - c = (rand() % 75) + 48; - while (!isupper(c) && !isdigit(c)); - id += c; - } - } - - return id; -} - -/** Constructor - */ -XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service(creator, "XLineManager", xname), type(t), XLines("XLine") -{ -} - -/** Destructor - * Clears all XLines in this XLineManager - */ -XLineManager::~XLineManager() -{ - this->Clear(); -} - -/** The type of xline provided by this service - * @return The type - */ -const char &XLineManager::Type() -{ - return this->type; -} - -/** Get the number of XLines in this XLineManager - * @return The number of XLines - */ -size_t XLineManager::GetCount() const -{ - return this->XLines->size(); -} - -/** Get the XLine vector - * @return The vecotr - */ -const std::vector<XLine *> &XLineManager::GetList() const -{ - return this->XLines; -} - -/** Add an entry to this XLineManager - * @param x The entry - */ -void XLineManager::AddXLine(XLine *x) -{ - if (!x->UID.empty()) - XLinesByUID->insert(std::make_pair(x->UID, x)); - this->XLines->push_back(x); - x->manager = this; -} - -/** Delete an entry from this XLineManager - * @param x The entry - * @return true if the entry was found and deleted, else false - */ -bool XLineManager::DelXLine(XLine *x) -{ - std::vector<XLine *>::iterator it = std::find(this->XLines->begin(), this->XLines->end(), x); - - if (!x->UID.empty()) - { - std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->find(x->UID), it3 = XLinesByUID->upper_bound(x->UID); - for (; it2 != XLinesByUID->end() && it2 != it3; ++it2) - if (it2->second == x) - { - XLinesByUID->erase(it2); - break; - } - } - - if (it != this->XLines->end()) - { - this->SendDel(x); - - x->destroy(); - this->XLines->erase(it); - - return true; - } - - return false; -} - -/** Gets an entry by index - * @param index The index - * @return The XLine, or NULL if the index is out of bounds - */ -XLine* XLineManager::GetEntry(unsigned index) -{ - if (index >= this->XLines->size()) - return NULL; - - XLine *x = this->XLines->at(index); - x->QueueUpdate(); - return x; -} - -/** Clear the XLine vector - */ -void XLineManager::Clear() -{ - for (unsigned i = 0; i < this->XLines->size(); ++i) - { - XLine *x = this->XLines->at(i); - if (!x->UID.empty()) - XLinesByUID->erase(x->UID); - x->destroy(); - } - this->XLines->clear(); -} - -/** Checks if a mask can/should be added to the XLineManager - * @param source The source adding the mask. - * @param mask The mask - * @param expires When the mask would expire - * @param reason the reason - * @return true if the mask can be added - */ -bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time_t expires, const Anope::string &reason) -{ - for (unsigned i = this->GetCount(); i > 0; --i) - { - XLine *x = this->GetEntry(i - 1); - - if (x->Mask.equals_ci(mask)) - { - if (!x->Expires || x->Expires >= expires) - { - if (x->Reason != reason) - { - x->Reason = reason; - source.Reply(_("Reason for %s updated."), x->Mask.c_str()); - } - else - source.Reply(_("%s already exists."), mask.c_str()); - } - else - { - x->Expires = expires; - if (x->Reason != reason) - { - x->Reason = reason; - source.Reply(_("Expiry and reason updated for %s."), x->Mask.c_str()); - } - else - source.Reply(_("Expiry for %s updated."), x->Mask.c_str()); - } - - return false; - } - else if (Anope::Match(mask, x->Mask) && (!x->Expires || x->Expires >= expires)) - { - source.Reply(_("%s is already covered by %s."), mask.c_str(), x->Mask.c_str()); - return false; - } - else if (Anope::Match(x->Mask, mask) && (!expires || x->Expires <= expires)) - { - source.Reply(_("Removing %s because %s covers it."), x->Mask.c_str(), mask.c_str()); - this->DelXLine(x); - } - } - - return true; -} - -/** Checks if this list has an entry - * @param mask The mask - * @return The XLine the user matches, or NULL - */ -XLine* XLineManager::HasEntry(const Anope::string &mask) -{ - std::multimap<Anope::string, XLine *, ci::less>::iterator it = XLinesByUID->find(mask); - if (it != XLinesByUID->end()) - for (std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->upper_bound(mask); it != it2; ++it) - if (it->second->manager == NULL || it->second->manager == this) - { - it->second->QueueUpdate(); - return it->second; - } - for (unsigned i = 0, end = this->XLines->size(); i < end; ++i) - { - XLine *x = this->XLines->at(i); - - if (x->Mask.equals_ci(mask)) - { - x->QueueUpdate(); - return x; - } - } - - return NULL; -} - -/** Check a user against all of the xlines in this XLineManager - * @param u The user - * @return The xline the user marches, if any. - */ -XLine *XLineManager::CheckAllXLines(User *u) -{ - for (unsigned i = this->XLines->size(); i > 0; --i) - { - XLine *x = this->XLines->at(i - 1); - - if (x->Expires && x->Expires < Anope::CurTime) - { - this->OnExpire(x); - this->DelXLine(x); - continue; - } - - if (this->Check(u, x)) - { - this->OnMatch(u, x); - return x; - } - } - - return NULL; -} - -/** Called when an XLine expires - * @param x The xline - */ -void XLineManager::OnExpire(const XLine *x) -{ -} - diff --git a/src/opertype.cpp b/src/opertype.cpp index b719b4cc7..f468e0c13 100644 --- a/src/opertype.cpp +++ b/src/opertype.cpp @@ -1,8 +1,10 @@ /* + * * Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org> * Copyright (C) 2008-2012 Anope Team <team@anope.org> * * Please read COPYING and README for further details. + * */ #include "services.h" diff --git a/src/process.cpp b/src/process.cpp index dfc4f5563..cc2b32a27 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -11,16 +11,12 @@ #include "services.h" #include "modules.h" -#include "extern.h" #include "protocol.h" #include "servers.h" #include "users.h" #include "regchannel.h" -/** Main process routine - * @param buffer A raw line from the uplink to do things with - */ -void process(const Anope::string &buffer) +void Anope::Process(const Anope::string &buffer) { /* If debugging, log the buffer */ Log(LOG_RAWIO) << "Received: " << buffer; @@ -46,12 +42,11 @@ void process(const Anope::string &buffer) } spacesepstream buf_sep(buf); - Anope::string buf_token; Anope::string command = buf; - if (buf_sep.GetToken(buf_token)) - command = buf_token; + buf_sep.GetToken(command); + Anope::string buf_token; std::vector<Anope::string> params; while (buf_sep.GetToken(buf_token)) { @@ -67,7 +62,7 @@ void process(const Anope::string &buffer) params.push_back(buf_token); } - if (protocoldebug) + if (Anope::ProtocolDebug) { Log() << "Source : " << (source.empty() ? "No source" : source); Log() << "Command: " << command; @@ -79,29 +74,26 @@ void process(const Anope::string &buffer) Log() << "params " << i << ": " << params[i]; } - const std::vector<IRCDMessage *> *messages = IRCDMessage::Find(command); + static const Anope::string proto_name = ModuleManager::FindFirstOf(PROTOCOL) ? ModuleManager::FindFirstOf(PROTOCOL)->name : ""; + + // event - if (messages && !messages->empty()) + ServiceReference<IRCDMessage> m("IRCDMessage", proto_name + "/" + command.lower()); + if (!m) { - MessageSource src(source); + Log(LOG_DEBUG) << "unknown message from server (" << buffer << ")"; + return; + } - bool retVal = true; - /* Newer messages take priority */ - for (unsigned i = messages->size(); retVal && i > 0; --i) - { - IRCDMessage *m = messages->at(i - 1); + MessageSource src(source); - if (m->HasFlag(IRCDMESSAGE_SOFT_LIMIT) ? (params.size() < m->GetParamCount()) : (params.size() != m->GetParamCount())) - Log(LOG_DEBUG) << "invalid parameters for " << command << ": " << params.size() << " != " << m->GetParamCount(); - else if (m->HasFlag(IRCDMESSAGE_REQUIRE_USER) && !src.GetUser()) - Log(LOG_DEBUG) << "unexpected non-user source " << source << " for " << command; - else if (m->HasFlag(IRCDMESSAGE_REQUIRE_SERVER) && !source.empty() && !src.GetServer()) - Log(LOG_DEBUG) << "unexpected non-server soruce " << source << " for " << command; - else - retVal = m->Run(src, params); - } - } + if (m->HasFlag(IRCDMESSAGE_SOFT_LIMIT) ? (params.size() < m->GetParamCount()) : (params.size() != m->GetParamCount())) + Log(LOG_DEBUG) << "invalid parameters for " << command << ": " << params.size() << " != " << m->GetParamCount(); + else if (m->HasFlag(IRCDMESSAGE_REQUIRE_USER) && !src.GetUser()) + Log(LOG_DEBUG) << "unexpected non-user source " << source << " for " << command; + else if (m->HasFlag(IRCDMESSAGE_REQUIRE_SERVER) && !source.empty() && !src.GetServer()) + Log(LOG_DEBUG) << "unexpected non-server soruce " << source << " for " << command; else - Log(LOG_DEBUG) << "unknown message from server (" << buffer << ")"; + m->Run(src, params); } diff --git a/src/protocol.cpp b/src/protocol.cpp index 5d836b7f4..d3372731c 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -17,10 +18,10 @@ #include "config.h" #include "uplink.h" #include "bots.h" -#include "extern.h" #include "channels.h" +#include "operserv.h" -IRCDProto *ircdproto; +IRCDProto *IRCD = NULL; IRCDProto::IRCDProto(const Anope::string &p) : proto_name(p) { @@ -29,13 +30,14 @@ IRCDProto::IRCDProto(const Anope::string &p) : proto_name(p) CanSVSO = CanCertFP = RequiresID = false; MaxModes = 3; - ircdproto = this; + if (IRCD == NULL) + IRCD = this; } IRCDProto::~IRCDProto() { - if (ircdproto == this) - ircdproto = NULL; + if (IRCD == this) + IRCD = NULL; } const Anope::string &IRCDProto::GetProtocolName() @@ -105,7 +107,7 @@ void IRCDProto::SendGlobopsInternal(const BotInfo *source, const Anope::string & void IRCDProto::SendCTCPInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf) { - Anope::string s = normalizeBuffer(buf); + Anope::string s = Anope::NormalizeBuffer(buf); this->SendNoticeInternal(bi, dest, "\1" + s + "\1"); } @@ -278,9 +280,9 @@ void IRCDProto::SendSquit(Server *s, const Anope::string &message) UplinkSocket::Message() << "SQUIT " << s->GetName() << " :" << message; } -void IRCDProto::SendChangeBotNick(const BotInfo *bi, const Anope::string &newnick) +void IRCDProto::SendNickChange(const User *u, const Anope::string &newnick) { - UplinkSocket::Message(bi) << "NICK " << newnick << " " << Anope::CurTime; + UplinkSocket::Message(u) << "NICK " << newnick << " " << Anope::CurTime; } void IRCDProto::SendForceNickChange(const User *u, const Anope::string &newnick, time_t when) @@ -308,6 +310,29 @@ void IRCDProto::SendNumeric(int numeric, const Anope::string &dest, const char * SendNumericInternal(numeric, dest, buf); } +bool IRCDProto::IsNickValid(const Anope::string &nick) +{ + /** + * RFC: defination of a valid nick + * nickname = ( letter / special ) ( letter / digit / special / "-" ) + * letter = A-Z / a-z + * digit = 0-9 + * special = [, ], \, `, _, ^, {, |, } + **/ + + if (nick.empty()) + return false; + + Anope::string special = "{}\\`_^{|}"; + + for (unsigned i = 0; i < nick.length(); ++i) + if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z') && special.find(nick[i]) == Anope::string::npos + && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-'))) + return false; + + return true; +} + bool IRCDProto::IsChannelValid(const Anope::string &chan) { if (chan.empty() || chan[0] != '#' || chan.length() > Config->ChanLen) @@ -316,20 +341,59 @@ bool IRCDProto::IsChannelValid(const Anope::string &chan) return true; } +bool IRCDProto::IsIdentValid(const Anope::string &ident) +{ + if (ident.empty() || ident.length() > Config->UserLen) + return false; + + for (unsigned i = 0; i < ident.length(); ++i) + { + const char &c = ident[i]; + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-') + ; + else + return false; + } + + return true; +} + +bool IRCDProto::IsHostValid(const Anope::string &host) +{ + if (host.empty() || host.length() > Config->HostLen) + return false; + + if (Config->VhostDisallowBE.find_first_of(host[0]) != Anope::string::npos) + return false; + else if (Config->VhostDisallowBE.find_first_of(host[host.length() - 1]) != Anope::string::npos) + return false; + + int dots = 0; + for (unsigned i = 0; i < host.length(); ++i) + { + if (host[i] == '.') + ++dots; + if (Config->VhostChars.find_first_of(host[i]) == Anope::string::npos) + return false; + } + + return Config->VhostUndotted || dots > 0; +} + void IRCDProto::SendOper(User *u) { SendNumericInternal(381, u->GetUID(), ":You are now an IRC operator (set by services)"); - u->SetMode(findbot(Config->OperServ), UMODE_OPER); + u->SetMode(OperServ, UMODE_OPER); } MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL) { if (src.empty()) this->s = !Me->GetLinks().empty() ? Me->GetLinks().front() : NULL; - else if (ircdproto->RequiresID || src.find('.') != Anope::string::npos) + else if (IRCD->RequiresID || src.find('.') != Anope::string::npos) this->s = Server::Find(src); if (this->s == NULL) - this->u = finduser(src); + this->u = User::Find(src); } MessageSource::MessageSource(User *_u) : source(_u ? _u->nick : ""), u(_u), s(NULL) @@ -365,26 +429,8 @@ Server *MessageSource::GetServer() return this->s; } -std::map<Anope::string, std::vector<IRCDMessage *> > IRCDMessage::messages; - -const std::vector<IRCDMessage *> *IRCDMessage::Find(const Anope::string &name) -{ - std::map<Anope::string, std::vector<IRCDMessage *> >::iterator it = messages.find(name); - if (it != messages.end()) - return &it->second; - return NULL; -} - -IRCDMessage::IRCDMessage(const Anope::string &n, unsigned p) : name(n), param_count(p) -{ - messages[n].insert(messages[n].begin(), this); -} - -IRCDMessage::~IRCDMessage() +IRCDMessage::IRCDMessage(Module *o, const Anope::string &n, unsigned p) : Service(o, "IRCDMessage", o->name + "/" + n.lower()), name(n), param_count(p) { - std::vector<IRCDMessage *>::iterator it = std::find(messages[this->name].begin(), messages[this->name].end(), this); - if (it != messages[this->name].end()) - messages[this->name].erase(it); } unsigned IRCDMessage::GetParamCount() const diff --git a/src/regchannel.cpp b/src/regchannel.cpp index a559d3127..3075ea301 100644 --- a/src/regchannel.cpp +++ b/src/regchannel.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -17,26 +18,36 @@ #include "channels.h" #include "config.h" #include "bots.h" -#include "extern.h" #include "language.h" #include "servers.h" +#include "chanserv.h" + +Serialize::Checker<registered_channel_map> RegisteredChannelList("ChannelInfo"); + +static const Anope::string ChannelInfoFlagStrings[] = { + "BEGIN", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED", + "PEACE", "SECURE", "NO_EXPIRE", "MEMO_HARDMAX", "SECUREFOUNDER", + "SIGNKICK", "SIGNKICK_LEVEL", "SUSPENDED", "PERSIST", "STATS", "NOAUTOOP", "" +}; +template<> const Anope::string* Flags<ChannelInfoFlag>::flags_strings = ChannelInfoFlagStrings; -serialize_checker<registered_channel_map> RegisteredChannelList("ChannelInfo"); +static const Anope::string AutoKickFlagString[] = { "AK_ISNICK", "" }; +template<> const Anope::string* Flags<AutoKickFlag>::flags_strings = AutoKickFlagString; -Serialize::Data BadWord::serialize() const +Serialize::Data BadWord::Serialize() const { Serialize::Data data; - data["ci"].setMax(64)/*XXX*/ << this->ci->name; - data["word"].setMax(512) << this->word; - data["type"].setType(Serialize::DT_INT) << this->type; + data["ci"].SetMax(64)/*XXX*/ << this->ci->name; + data["word"].SetMax(512) << this->word; + data["type"].SetType(Serialize::DT_INT) << this->type; return data; } -Serializable* BadWord::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* BadWord::Unserialize(Serializable *obj, Serialize::Data &data) { - ChannelInfo *ci = cs_findchan(data["ci"].astr()); + ChannelInfo *ci = ChannelInfo::Find(data["ci"].astr()); if (!ci) return NULL; @@ -56,42 +67,42 @@ Serializable* BadWord::unserialize(Serializable *obj, Serialize::Data &data) return bw; } -AutoKick::AutoKick() : Flags<AutoKickFlag>(AutoKickFlagString), Serializable("AutoKick") +AutoKick::AutoKick() : Serializable("AutoKick") { } -Serialize::Data AutoKick::serialize() const +Serialize::Data AutoKick::Serialize() const { Serialize::Data data; - data["ci"].setMax(64)/*XXX*/ << this->ci->name; + data["ci"].SetMax(64)/*XXX*/ << this->ci->name; if (this->HasFlag(AK_ISNICK) && this->nc) - data["nc"].setMax(Config->NickLen) << this->nc->display; + data["nc"].SetMax(Config->NickLen) << this->nc->display; else - data["mask"].setMax(Config->NickLen) << this->mask; + data["mask"].SetMax(Config->NickLen) << this->mask; data["reason"] << this->reason; data["creator"] << this->creator; - data["addtime"].setType(Serialize::DT_INT) << this->addtime; - data["last_used"].setType(Serialize::DT_INT) << this->last_used; + data["addtime"].SetType(Serialize::DT_INT) << this->addtime; + data["last_used"].SetType(Serialize::DT_INT) << this->last_used; data["flags"] << this->ToString(); return data; } -Serializable* AutoKick::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* AutoKick::Unserialize(Serializable *obj, Serialize::Data &data) { - ChannelInfo *ci = cs_findchan(data["ci"].astr()); + ChannelInfo *ci = ChannelInfo::Find(data["ci"].astr()); if (!ci) return NULL; AutoKick *ak; - NickCore *nc = findcore(data["nc"].astr()); + NickCore *nc = NickCore::Find(data["nc"].astr()); if (obj) { ak = anope_dynamic_static_cast<AutoKick *>(obj); data["creator"] >> ak->creator; data["reason"] >> ak->reason; - ak->nc = findcore(data["nc"].astr()); + ak->nc = NickCore::Find(data["nc"].astr()); data["mask"] >> ak->mask; data["addtime"] >> ak->addtime; data["last_used"] >> ak->last_used; @@ -115,31 +126,33 @@ ModeLock::ModeLock(ChannelInfo *ch, bool s, ChannelModeName n, const Anope::stri { } -Serialize::Data ModeLock::serialize() const +Serialize::Data ModeLock::Serialize() const { Serialize::Data data; if (!this->ci) return data; - data["ci"].setMax(64)/*XXX*/ << this->ci->name; - data["set"].setMax(5) << this->set; - data["name"].setMax(64) << ChannelModeNameStrings[this->name]; - data["param"].setMax(512) << this->param; + const Anope::string* ChannelModeNameStrings = Flags<ChannelModeName>::GetFlagStrings(); + data["ci"].SetMax(64)/*XXX*/ << this->ci->name; + data["set"].SetMax(5) << this->set; + data["name"].SetMax(64) << ChannelModeNameStrings[this->name]; + data["param"].SetMax(512) << this->param; data["setter"] << this->setter; - data["created"].setType(Serialize::DT_INT) << this->created; + data["created"].SetType(Serialize::DT_INT) << this->created; return data; } -Serializable* ModeLock::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* ModeLock::Unserialize(Serializable *obj, Serialize::Data &data) { - ChannelInfo *ci = cs_findchan(data["ci"].astr()); + ChannelInfo *ci = ChannelInfo::Find(data["ci"].astr()); if (!ci) return NULL; ChannelModeName name = CMODE_END; + const Anope::string* ChannelModeNameStrings = Flags<ChannelModeName>::GetFlagStrings(); for (unsigned i = 0; !ChannelModeNameStrings[i].empty(); ++i) if (ChannelModeNameStrings[i] == data["name"].astr()) { @@ -177,7 +190,7 @@ Serializable* ModeLock::unserialize(Serializable *obj, Serialize::Data &data) } } -Serialize::Data LogSetting::serialize() const +Serialize::Data LogSetting::Serialize() const { Serialize::Data data; @@ -191,14 +204,14 @@ Serialize::Data LogSetting::serialize() const data["method"] << method; data["extra"] << extra; data["creator"] << creator; - data["created"].setType(Serialize::DT_INT) << created; + data["created"].SetType(Serialize::DT_INT) << created; return data; } -Serializable* LogSetting::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* LogSetting::Unserialize(Serializable *obj, Serialize::Data &data) { - ChannelInfo *ci = cs_findchan(data["ci"].astr()); + ChannelInfo *ci = ChannelInfo::Find(data["ci"].astr()); if (ci == NULL) return NULL; @@ -223,19 +236,16 @@ Serializable* LogSetting::unserialize(Serializable *obj, Serialize::Data &data) return ls; } -/** Default constructor - * @param chname The channel name - */ -ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInfo"), Flags<ChannelInfoFlag, CI_END>(ChannelInfoFlagStrings), +ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInfo"), access("ChanAccess"), akick("AutoKick"), - badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting"), botflags(BotServFlagStrings) + badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting") { if (chname.empty()) throw CoreException("Empty channel passed to ChannelInfo constructor"); this->founder = NULL; this->successor = NULL; - this->c = findchan(chname); + this->c = Channel::Find(chname); if (this->c) this->c->ci = this; this->capsmin = this->capspercent = 0; @@ -274,12 +284,9 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInf FOREACH_MOD(I_OnCreateChan, OnCreateChan(this)); } -/** Copy constructor - * @param ci The ChannelInfo to copy settings to - */ -ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"), Flags<ChannelInfoFlag, CI_END>(ChannelInfoFlagStrings), +ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"), access("ChanAccess"), akick("AutoKick"), - badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting"), botflags(BotServFlagStrings) + badwords("BadWord"), mode_locks("ModeLock"), log_settings("LogSetting") { *this = ci; @@ -304,7 +311,7 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"), F newaccess->creator = taccess->creator; newaccess->last_seen = taccess->last_seen; newaccess->created = taccess->created; - newaccess->Unserialize(taccess->Serialize()); + newaccess->AccessUnserialize(taccess->AccessSerialize()); this->AddAccess(newaccess); } @@ -331,8 +338,6 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"), F } } -/** Default destructor, cleans up the channel complete and removes it from the internal list - */ ChannelInfo::~ChannelInfo() { FOREACH_MOD(I_OnDelChan, OnDelChan(this)); @@ -353,17 +358,17 @@ ChannelInfo::~ChannelInfo() this->ClearBadWords(); for (unsigned i = 0; i < this->log_settings->size(); ++i) - this->log_settings->at(i)->destroy(); + this->log_settings->at(i)->Destroy(); this->log_settings->clear(); for (ChannelInfo::ModeList::iterator it = this->mode_locks->begin(), it_end = this->mode_locks->end(); it != it_end; ++it) - it->second->destroy(); + it->second->Destroy(); this->mode_locks->clear(); if (!this->memos.memos->empty()) { for (unsigned i = 0, end = this->memos.memos->size(); i < end; ++i) - this->memos.GetMemo(i)->destroy(); + this->memos.GetMemo(i)->Destroy(); this->memos.memos->clear(); } @@ -371,22 +376,22 @@ ChannelInfo::~ChannelInfo() --this->founder->channelcount; } -Serialize::Data ChannelInfo::serialize() const +Serialize::Data ChannelInfo::Serialize() const { Serialize::Data data; - data["name"].setMax(255) << this->name; + data["name"].SetMax(255) << this->name; if (this->founder) data["founder"] << this->founder->display; if (this->successor) data["successor"] << this->successor->display; data["description"] << this->desc; - data["time_registered"].setType(Serialize::DT_INT) << this->time_registered; - data["last_used"].setType(Serialize::DT_INT) << this->last_used; + data["time_registered"].SetType(Serialize::DT_INT) << this->time_registered; + data["last_used"].SetType(Serialize::DT_INT) << this->last_used; data["last_topic"] << this->last_topic; data["last_topic_setter"] << this->last_topic_setter; - data["last_topic_time"].setType(Serialize::DT_INT) << this->last_topic_time; - data["bantype"].setType(Serialize::DT_INT) << this->bantype; + data["last_topic_time"].SetType(Serialize::DT_INT) << this->last_topic_time; + data["bantype"].SetType(Serialize::DT_INT) << this->bantype; data["flags"] << this->ToString(); data["botflags"] << this->botflags.ToString(); { @@ -399,11 +404,11 @@ Serialize::Data ChannelInfo::serialize() const data["bi"] << this->bi->nick; for (int i = 0; i < TTB_SIZE; ++i) data["ttb"] << this->ttb[i] << " "; - data["capsmin"].setType(Serialize::DT_INT) << this->capsmin; - data["capspercent"].setType(Serialize::DT_INT) << this->capspercent; - data["floodlines"].setType(Serialize::DT_INT) << this->floodlines; - data["floodsecs"].setType(Serialize::DT_INT) << this->floodsecs; - data["repeattimes"].setType(Serialize::DT_INT) << this->repeattimes; + data["capsmin"].SetType(Serialize::DT_INT) << this->capsmin; + data["capspercent"].SetType(Serialize::DT_INT) << this->capspercent; + data["floodlines"].SetType(Serialize::DT_INT) << this->floodlines; + data["floodsecs"].SetType(Serialize::DT_INT) << this->floodsecs; + data["repeattimes"].SetType(Serialize::DT_INT) << this->repeattimes; data["memomax"] << this->memos.memomax; for (unsigned i = 0; i < this->memos.ignores.size(); ++i) data["memoignores"] << this->memos.ignores[i] << " "; @@ -411,7 +416,7 @@ Serialize::Data ChannelInfo::serialize() const return data; } -Serializable* ChannelInfo::unserialize(Serializable *obj, Serialize::Data &data) +Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data) { ChannelInfo *ci; if (obj) @@ -423,13 +428,13 @@ Serializable* ChannelInfo::unserialize(Serializable *obj, Serialize::Data &data) { if (ci->founder) --ci->founder->channelcount; - ci->founder = findcore(data["founder"].astr()); + ci->founder = NickCore::Find(data["founder"].astr()); if (ci->founder) ++ci->founder->channelcount; } if (data.count("successor") > 0) { - ci->successor = findcore(data["successor"].astr()); + ci->successor = NickCore::Find(data["successor"].astr()); if (ci->founder && *ci->founder == *ci->successor) ci->successor = NULL; } @@ -443,11 +448,12 @@ Serializable* ChannelInfo::unserialize(Serializable *obj, Serialize::Data &data) ci->FromString(data["flags"].astr()); ci->botflags.FromString(data["botflags"].astr()); { - std::vector<Anope::string> v = BuildStringVector(data["levels"].astr()); + std::vector<Anope::string> v; + spacesepstream(data["levels"].astr()).GetTokens(v); for (unsigned i = 0; i + 1 < v.size(); i += 2) ci->levels[v[i]] = convertTo<int16_t>(v[i + 1]); } - BotInfo *bi = findbot(data["bi"].astr()); + BotInfo *bi = BotInfo::Find(data["bi"].astr()); if (*ci->bi != bi) { if (ci->bi) @@ -475,9 +481,6 @@ Serializable* ChannelInfo::unserialize(Serializable *obj, Serialize::Data &data) } -/** Change the founder of the channek - * @params nc The new founder - */ void ChannelInfo::SetFounder(NickCore *nc) { if (this->founder) @@ -489,44 +492,27 @@ void ChannelInfo::SetFounder(NickCore *nc) this->successor = NULL; } -/** Get the founder of the channel - * @return The founder - */ NickCore *ChannelInfo::GetFounder() const { return this->founder; } -/** Find which bot should send mode/topic/etc changes for this channel - * @return The bot - */ BotInfo *ChannelInfo::WhoSends() const { if (this && this->bi) return this->bi; - BotInfo *tbi = findbot(Config->ChanServ); - if (tbi) - return tbi; + else if (ChanServ) + return ChanServ; else if (!BotListByNick->empty()) return BotListByNick->begin()->second; return NULL; } -/** Add an entry to the channel access list - * @param taccess The entry - */ void ChannelInfo::AddAccess(ChanAccess *taccess) { this->access->push_back(taccess); } -/** Get an entry from the channel access list by index - * - * @param index The index in the access list vector - * @return A ChanAccess struct corresponding to the index given, or NULL if outside the bounds - * - * Retrieves an entry from the access list that matches the given index. - */ ChanAccess *ChannelInfo::GetAccess(unsigned index) const { if (this->access->empty() || index >= this->access->size()) @@ -547,13 +533,13 @@ AccessGroup ChannelInfo::AccessFor(const User *u) const NickCore *nc = u->Account(); if (nc == NULL && u->IsRecognized()) { - const NickAlias *na = findnick(u->nick); + const NickAlias *na = NickAlias::Find(u->nick); if (na != NULL) nc = na->nc; } - group.SuperAdmin = u->SuperAdmin; - group.Founder = IsFounder(u, this); + group.super_admin = u->super_admin; + group.founder = IsFounder(u, this); group.ci = this; group.nc = nc; @@ -561,9 +547,14 @@ AccessGroup ChannelInfo::AccessFor(const User *u) if (this->GetAccess(i)->Matches(u, nc)) group.push_back(this->GetAccess(i)); - if (group.Founder || !group.empty()) + if (group.founder || !group.empty()) + { this->last_used = Anope::CurTime; + for (unsigned i = 0; i < group.size(); ++i) + group[i]->last_seen = Anope::CurTime; + } + return group; } @@ -571,7 +562,7 @@ AccessGroup ChannelInfo::AccessFor(const NickCore *nc) { AccessGroup group; - group.Founder = (this->founder && this->founder == nc); + group.founder = (this->founder && this->founder == nc); group.ci = this; group.nc = nc; @@ -579,41 +570,31 @@ AccessGroup ChannelInfo::AccessFor(const NickCore *nc) if (this->GetAccess(i)->Matches(NULL, nc)) group.push_back(this->GetAccess(i)); - if (group.Founder || !group.empty()) + if (group.founder || !group.empty()) + { this->last_used = Anope::CurTime; + for (unsigned i = 0; i < group.size(); ++i) + group[i]->last_seen = Anope::CurTime; + } + return group; } -/** Get the size of the accss vector for this channel - * @return The access vector size - */ unsigned ChannelInfo::GetAccessCount() const { return this->access->size(); } -/** Erase an entry from the channel access list - * - * @param index The index in the access list vector - * - * Clears the memory used by the given access entry and removes it from the vector. - */ void ChannelInfo::EraseAccess(unsigned index) { if (this->access->empty() || index >= this->access->size()) return; - this->access->at(index)->destroy(); + this->access->at(index)->Destroy(); this->access->erase(this->access->begin() + index); } -/** Erase an entry from the channel access list - * - * @param taccess The access to remove - * - * Clears the memory used by the given access entry and removes it from the vector. - */ void ChannelInfo::EraseAccess(const ChanAccess *taccess) { for (unsigned i = 0, end = this->access->size(); i < end; ++i) @@ -626,25 +607,13 @@ void ChannelInfo::EraseAccess(const ChanAccess *taccess) } } -/** Clear the entire channel access list - * - * Clears the entire access list by deleting every item and then clearing the vector. - */ void ChannelInfo::ClearAccess() { for (unsigned i = this->access->size(); i > 0; --i) - this->GetAccess(i - 1)->destroy(); + this->GetAccess(i - 1)->Destroy(); this->access->clear(); } -/** Add an akick entry to the channel by NickCore - * @param user The user who added the akick - * @param akicknc The nickcore being akicked - * @param reason The reason for the akick - * @param t The time the akick was added, defaults to now - * @param lu The time the akick was last used, defaults to never - * @return The AutoKick structure - */ AutoKick *ChannelInfo::AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t, time_t lu) { AutoKick *autokick = new AutoKick(); @@ -661,14 +630,6 @@ AutoKick *ChannelInfo::AddAkick(const Anope::string &user, NickCore *akicknc, co return autokick; } -/** Add an akick entry to the channel by reason - * @param user The user who added the akick - * @param mask The mask of the akick - * @param reason The reason for the akick - * @param t The time the akick was added, defaults to now - * @param lu The time the akick was last used, defaults to never - * @return The AutoKick structure - */ AutoKick *ChannelInfo::AddAkick(const Anope::string &user, const Anope::string &mask, const Anope::string &reason, time_t t, time_t lu) { AutoKick *autokick = new AutoKick(); @@ -685,10 +646,6 @@ AutoKick *ChannelInfo::AddAkick(const Anope::string &user, const Anope::string & return autokick; } -/** Get an entry from the channel akick list - * @param index The index in the akick vector - * @return The akick structure, or NULL if not found - */ AutoKick *ChannelInfo::GetAkick(unsigned index) const { if (this->akick->empty() || index >= this->akick->size()) @@ -699,39 +656,26 @@ AutoKick *ChannelInfo::GetAkick(unsigned index) const return ak; } -/** Get the size of the akick vector for this channel - * @return The akick vector size - */ unsigned ChannelInfo::GetAkickCount() const { return this->akick->size(); } -/** Erase an entry from the channel akick list - * @param index The index of the akick - */ void ChannelInfo::EraseAkick(unsigned index) { if (this->akick->empty() || index >= this->akick->size()) return; - this->GetAkick(index)->destroy(); + this->GetAkick(index)->Destroy(); this->akick->erase(this->akick->begin() + index); } -/** Clear the whole akick list - */ void ChannelInfo::ClearAkick() { while (!this->akick->empty()) EraseAkick(0); } -/** Add a badword to the badword list - * @param word The badword - * @param type The type (SINGLE START END) - * @return The badword - */ BadWord* ChannelInfo::AddBadWord(const Anope::string &word, BadWordType type) { BadWord *bw = new BadWord(); @@ -746,10 +690,6 @@ BadWord* ChannelInfo::AddBadWord(const Anope::string &word, BadWordType type) return bw; } -/** Get a badword structure by index - * @param index The index - * @return The badword - */ BadWord* ChannelInfo::GetBadWord(unsigned index) const { if (this->badwords->empty() || index >= this->badwords->size()) @@ -760,17 +700,11 @@ BadWord* ChannelInfo::GetBadWord(unsigned index) const return bw; } -/** Get how many badwords are on this channel - * @return The number of badwords in the vector - */ unsigned ChannelInfo::GetBadWordCount() const { return this->badwords->size(); } -/** Remove a badword - * @param index The index of the badword - */ void ChannelInfo::EraseBadWord(unsigned index) { if (this->badwords->empty() || index >= this->badwords->size()) @@ -782,28 +716,21 @@ void ChannelInfo::EraseBadWord(unsigned index) this->badwords->erase(this->badwords->begin() + index); } -/** Clear all badwords from the channel - */ void ChannelInfo::ClearBadWords() { while (!this->badwords->empty()) EraseBadWord(0); } -/** Check if a mode is mlocked - * @param mode The mode - * @param status True to check mlock on, false for mlock off - * @return true on success, false on fail - */ bool ChannelInfo::HasMLock(ChannelMode *mode, const Anope::string ¶m, bool status) const { - std::multimap<ChannelModeName, ModeLock *>::const_iterator it = this->mode_locks->find(mode->Name); + std::multimap<ChannelModeName, ModeLock *>::const_iterator it = this->mode_locks->find(mode->name); if (it != this->mode_locks->end()) { - if (mode->Type != MODE_REGULAR) + if (mode->type != MODE_REGULAR) { - std::multimap<ChannelModeName, ModeLock *>::const_iterator it_end = this->mode_locks->upper_bound(mode->Name); + std::multimap<ChannelModeName, ModeLock *>::const_iterator it_end = this->mode_locks->upper_bound(mode->name); for (; it != it_end; ++it) { @@ -818,17 +745,11 @@ bool ChannelInfo::HasMLock(ChannelMode *mode, const Anope::string ¶m, bool s return false; } -/** Set a mlock - * @param mode The mode - * @param status True for mlock on, false for mlock off - * @param param The param to use for this mode, if required - * @return true on success, false on failure (module blocking) - */ bool ChannelInfo::SetMLock(ChannelMode *mode, bool status, const Anope::string ¶m, Anope::string setter, time_t created) { if (setter.empty()) setter = this->founder ? this->founder->display : "Unknown"; - std::pair<ChannelModeName, ModeLock *> ml = std::make_pair(mode->Name, new ModeLock(this, status, mode->Name, param, setter, created)); + std::pair<ChannelModeName, ModeLock *> ml = std::make_pair(mode->name, new ModeLock(this, status, mode->name, param, setter, created)); EventReturn MOD_RESULT; FOREACH_RESULT(I_OnMLock, OnMLock(this, ml.second)); @@ -836,30 +757,30 @@ bool ChannelInfo::SetMLock(ChannelMode *mode, bool status, const Anope::string & return false; /* First, remove this */ - if (mode->Type == MODE_REGULAR || mode->Type == MODE_PARAM) + if (mode->type == MODE_REGULAR || mode->type == MODE_PARAM) { - ChannelInfo::ModeList::const_iterator it = this->mode_locks->find(mode->Name); + ChannelInfo::ModeList::const_iterator it = this->mode_locks->find(mode->name); if (it != this->mode_locks->end()) { - ChannelInfo::ModeList::const_iterator it_end = this->mode_locks->upper_bound(mode->Name); + ChannelInfo::ModeList::const_iterator it_end = this->mode_locks->upper_bound(mode->name); for (; it != it_end; ++it) - it->second->destroy(); + it->second->Destroy(); } - this->mode_locks->erase(mode->Name); + this->mode_locks->erase(mode->name); } else { // For list or status modes, we must check the parameter - ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->Name); + ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name); if (it != this->mode_locks->end()) { - ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->Name); + ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->name); for (; it != it_end; ++it) { const ModeLock *modelock = it->second; if (modelock->param == param) { - it->second->destroy(); + it->second->Destroy(); this->mode_locks->erase(it); break; } @@ -872,17 +793,11 @@ bool ChannelInfo::SetMLock(ChannelMode *mode, bool status, const Anope::string & return true; } -/** Remove a mlock - * @param mode The mode - * @param status True for mlock on, false for mlock off - * @param param The param of the mode, required if it is a list or status mode - * @return true on success, false on failure - */ bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::string ¶m) { - if (mode->Type == MODE_REGULAR || mode->Type == MODE_PARAM) + if (mode->type == MODE_REGULAR || mode->type == MODE_PARAM) { - ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->Name), it_end = this->mode_locks->upper_bound(mode->Name), it_next = it; + ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name), it_end = this->mode_locks->upper_bound(mode->name), it_next = it; if (it != this->mode_locks->end()) for (; it != it_end; it = it_next) { @@ -896,7 +811,7 @@ bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::strin FOREACH_RESULT(I_OnUnMLock, OnUnMLock(this, it->second)); if (MOD_RESULT != EVENT_STOP) { - it->second->destroy(); + it->second->Destroy(); this->mode_locks->erase(it); return true; } @@ -906,10 +821,10 @@ bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::strin else { // For list or status modes, we must check the parameter - ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->Name); + ChannelInfo::ModeList::iterator it = this->mode_locks->find(mode->name); if (it != this->mode_locks->end()) { - ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->Name); + ChannelInfo::ModeList::iterator it_end = this->mode_locks->upper_bound(mode->name); for (; it != it_end; ++it) { const ModeLock *ml = it->second; @@ -919,7 +834,7 @@ bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::strin FOREACH_RESULT(I_OnUnMLock, OnUnMLock(this, it->second)); if (MOD_RESULT == EVENT_STOP) return false; - it->second->destroy(); + it->second->Destroy(); this->mode_locks->erase(it); return true; } @@ -930,25 +845,16 @@ bool ChannelInfo::RemoveMLock(ChannelMode *mode, bool status, const Anope::strin } } -/** Clear all mlocks on the channel - */ void ChannelInfo::ClearMLock() { this->mode_locks->clear(); } -/** Get all of the mlocks for this channel - * @return The mlocks - */ const ChannelInfo::ModeList &ChannelInfo::GetMLock() const { return this->mode_locks; } -/** Get a list of modes on a channel - * @param Name The mode name to get a list of - * @return a pair of iterators for the beginning and end of the list - */ std::pair<ChannelInfo::ModeList::iterator, ChannelInfo::ModeList::iterator> ChannelInfo::GetModeList(ChannelModeName Name) { ChannelInfo::ModeList::iterator it = this->mode_locks->find(Name), it_end = it; @@ -957,11 +863,6 @@ std::pair<ChannelInfo::ModeList::iterator, ChannelInfo::ModeList::iterator> Chan return std::make_pair(it, it_end); } -/** Get details for a specific mlock - * @param mname The mode name - * @param param An optional param to match with - * @return The MLock, if any - */ const ModeLock *ChannelInfo::GetMLock(ChannelModeName mname, const Anope::string ¶m) { ChannelInfo::ModeList::iterator it = this->mode_locks->find(mname); @@ -991,15 +892,15 @@ Anope::string ChannelInfo::GetMLockAsString(bool complete) const { const ModeLock *ml = it->second; ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name); - if (!cm || cm->Type == MODE_LIST || cm->Type == MODE_STATUS) + if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS) continue; if (ml->set) - pos += cm->ModeChar; + pos += cm->mchar; else - neg += cm->ModeChar; + neg += cm->mchar; - if (complete && !ml->param.empty() && cm->Type == MODE_PARAM) + if (complete && !ml->param.empty() && cm->type == MODE_PARAM) params += " " + ml->param; } @@ -1011,16 +912,12 @@ Anope::string ChannelInfo::GetMLockAsString(bool complete) const return pos + neg + params; } -/** Check whether a user is permitted to be on this channel - * @param u The user - * @return true if they were banned, false if they are allowed - */ bool ChannelInfo::CheckKick(User *user) { if (!user || !this->c) return false; - if (user->SuperAdmin) + if (user->super_admin) return false; /* We don't enforce services restrictions on clients on ulined services @@ -1041,13 +938,13 @@ bool ChannelInfo::CheckKick(User *user) Anope::string mask, reason; if (!user->HasMode(UMODE_OPER) && this->HasFlag(CI_SUSPENDED)) { - get_idealban(this, user, mask); - reason = translate(user, _("This channel may not be used.")); + mask = this->GetIdealBan(user); + reason = Language::Translate(user, _("This channel may not be used.")); set_modes = true; do_kick = true; } - if (!do_kick && matches_list(this->c, user, CMODE_EXCEPT)) + if (!do_kick && !this->c->MatchesList(user, CMODE_EXCEPT)) return false; const NickCore *nc = user->Account() || user->IsRecognized() ? user->Account() : NULL; @@ -1074,7 +971,7 @@ bool ChannelInfo::CheckKick(User *user) Log(LOG_DEBUG_2) << user->nick << " matched akick " << (autokick->HasFlag(AK_ISNICK) ? autokick->nc->display : autokick->mask); autokick->last_used = Anope::CurTime; if (autokick->HasFlag(AK_ISNICK)) - get_idealban(this, user, mask); + mask = this->GetIdealBan(user); else mask = autokick->mask; reason = autokick->reason.empty() ? Config->CSAutokickReason : autokick->reason; @@ -1086,8 +983,8 @@ bool ChannelInfo::CheckKick(User *user) if (!do_kick && this->HasFlag(CI_RESTRICTED) && this->AccessFor(user).empty() && (!this->founder || user->Account() != this->founder)) { do_kick = true; - get_idealban(this, user, mask); - reason = translate(user->Account(), CHAN_NOT_ALLOWED_TO_JOIN); + mask = this->GetIdealBan(user); + reason = Language::Translate(user->Account(), CHAN_NOT_ALLOWED_TO_JOIN); } if (!do_kick) @@ -1183,3 +1080,48 @@ void ChannelInfo::ClearLevels() this->levels.clear(); } +Anope::string ChannelInfo::GetIdealBan(User *u) const +{ + switch (this->bantype) + { + case 0: + return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost(); + case 1: + if (u->GetVIdent()[0] == '~') + return "*!*" + u->GetVIdent() + "@" + u->GetDisplayedHost(); + else + return "*!" + u->GetVIdent() + "@" + u->GetDisplayedHost(); + case 3: + return "*!" + u->Mask(); + case 2: + default: + return "*!*@" + u->GetDisplayedHost(); + } +} + +ChannelInfo* ChannelInfo::Find(const Anope::string &name) +{ + registered_channel_map::const_iterator it = RegisteredChannelList->find(name); + if (it != RegisteredChannelList->end()) + { + it->second->QueueUpdate(); + return it->second; + } + + return NULL; +} + +bool IsFounder(const User *user, const ChannelInfo *ci) +{ + if (!user || !ci) + return false; + + if (user->super_admin) + return true; + + if (user->Account() && user->Account() == ci->GetFounder()) + return true; + + return false; +} + diff --git a/src/serialize.cpp b/src/serialize.cpp index a84d103f5..b6da2da67 100644 --- a/src/serialize.cpp +++ b/src/serialize.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ @@ -14,10 +15,25 @@ #include "anope.h" #include "serialize.h" #include "modules.h" +#include "account.h" +#include "bots.h" +#include "regchannel.h" +#include "xline.h" +#include "access.h" + +using namespace Serialize; + +std::vector<Anope::string> Type::TypeOrder; +std::map<Anope::string, Type *> Serialize::Type::Types; +std::list<Serializable *> *Serializable::SerializableItems; -std::vector<Anope::string> SerializeType::type_order; -std::map<Anope::string, SerializeType *> SerializeType::types; -std::list<Serializable *> *Serializable::serializable_items; +void Serialize::RegisterTypes() +{ + static Type nc("NickCore", NickCore::Unserialize), na("NickAlias", NickAlias::Unserialize), bi("BotInfo", BotInfo::Unserialize), + ci("ChannelInfo", ChannelInfo::Unserialize), access("ChanAccess", ChanAccess::Unserialize), logsetting("LogSetting", LogSetting::Unserialize), + modelock("ModeLock", ModeLock::Unserialize), akick("AutoKick", AutoKick::Unserialize), badword("BadWord", BadWord::Unserialize), + memo("Memo", Memo::Unserialize), xline("XLine", XLine::Unserialize); +} stringstream::stringstream() : std::stringstream(), type(Serialize::DT_TEXT), _max(0) { @@ -48,24 +64,24 @@ bool stringstream::operator!=(const stringstream &other) const return !(*this == other); } -stringstream &stringstream::setType(Serialize::DataType t) +stringstream &stringstream::SetType(Serialize::DataType t) { this->type = t; return *this; } -Serialize::DataType stringstream::getType() const +DataType Serialize::stringstream::GetType() const { return this->type; } -stringstream &stringstream::setMax(unsigned m) +stringstream &stringstream::SetMax(unsigned m) { this->_max = m; return *this; } -unsigned stringstream::getMax() const +unsigned stringstream::GetMax() const { return this->_max; } @@ -77,13 +93,13 @@ Serializable::Serializable() : last_commit_time(0), id(0) Serializable::Serializable(const Anope::string &serialize_type) : last_commit_time(0), id(0) { - if (serializable_items == NULL) - serializable_items = new std::list<Serializable *>(); - serializable_items->push_back(this); + if (SerializableItems == NULL) + SerializableItems = new std::list<Serializable *>(); + SerializableItems->push_back(this); - this->s_type = SerializeType::Find(serialize_type); + this->s_type = Type::Find(serialize_type); - this->s_iter = serializable_items->end(); + this->s_iter = SerializableItems->end(); --this->s_iter; FOREACH_MOD(I_OnSerializableConstruct, OnSerializableConstruct(this)); @@ -91,8 +107,8 @@ Serializable::Serializable(const Anope::string &serialize_type) : last_commit_ti Serializable::Serializable(const Serializable &other) : last_commit_time(0), id(0) { - serializable_items->push_back(this); - this->s_iter = serializable_items->end(); + SerializableItems->push_back(this); + this->s_iter = SerializableItems->end(); --this->s_iter; this->s_type = other.s_type; @@ -102,7 +118,7 @@ Serializable::Serializable(const Serializable &other) : last_commit_time(0), id( Serializable::~Serializable() { - serializable_items->erase(this->s_iter); + SerializableItems->erase(this->s_iter); } Serializable &Serializable::operator=(const Serializable &) @@ -110,7 +126,7 @@ Serializable &Serializable::operator=(const Serializable &) return *this; } -void Serializable::destroy() +void Serializable::Destroy() { if (!this) return; @@ -130,12 +146,12 @@ void Serializable::QueueUpdate() bool Serializable::IsCached() { - return this->last_commit == this->serialize(); + return this->last_commit == this->Serialize(); } void Serializable::UpdateCache() { - this->last_commit = this->serialize(); + this->last_commit = this->Serialize(); } bool Serializable::IsTSCached() @@ -148,70 +164,70 @@ void Serializable::UpdateTS() this->last_commit_time = Anope::CurTime; } -SerializeType* Serializable::GetSerializableType() const +Type* Serializable::GetSerializableType() const { return this->s_type; } const std::list<Serializable *> &Serializable::GetItems() { - return *serializable_items; + return *SerializableItems; } -SerializeType::SerializeType(const Anope::string &n, unserialize_func f, Module *o) : name(n), unserialize(f), owner(o), timestamp(0) +Type::Type(const Anope::string &n, unserialize_func f, Module *o) : name(n), unserialize(f), owner(o), timestamp(0) { - type_order.push_back(this->name); - types[this->name] = this; + TypeOrder.push_back(this->name); + Types[this->name] = this; } -SerializeType::~SerializeType() +Type::~Type() { - std::vector<Anope::string>::iterator it = std::find(type_order.begin(), type_order.end(), this->name); - if (it != type_order.end()) - type_order.erase(it); - types.erase(this->name); + std::vector<Anope::string>::iterator it = std::find(TypeOrder.begin(), TypeOrder.end(), this->name); + if (it != TypeOrder.end()) + TypeOrder.erase(it); + Types.erase(this->name); } -const Anope::string &SerializeType::GetName() +const Anope::string &Type::GetName() { return this->name; } -Serializable *SerializeType::Unserialize(Serializable *obj, Serialize::Data &data) +Serializable *Type::Unserialize(Serializable *obj, Serialize::Data &data) { return this->unserialize(obj, data); } -void SerializeType::Check() +void Type::Check() { FOREACH_MOD(I_OnSerializeCheck, OnSerializeCheck(this)); } -time_t SerializeType::GetTimestamp() const +time_t Type::GetTimestamp() const { return this->timestamp; } -void SerializeType::UpdateTimestamp() +void Type::UpdateTimestamp() { this->timestamp = Anope::CurTime; } -Module* SerializeType::GetOwner() const +Module* Type::GetOwner() const { return this->owner; } -SerializeType *SerializeType::Find(const Anope::string &name) +Type *Serialize::Type::Find(const Anope::string &name) { - std::map<Anope::string, SerializeType *>::iterator it = types.find(name); - if (it != types.end()) + std::map<Anope::string, Type *>::iterator it = Types.find(name); + if (it != Types.end()) return it->second; return NULL; } -const std::vector<Anope::string> &SerializeType::GetTypeOrder() +const std::vector<Anope::string> &Type::GetTypeOrder() { - return type_order; + return TypeOrder; } diff --git a/src/servers.cpp b/src/servers.cpp index 3a44c8e65..447633298 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -7,52 +7,47 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" #include "modules.h" -#include "oper.h" +#include "xline.h" #include "servers.h" #include "bots.h" #include "regchannel.h" #include "protocol.h" #include "config.h" #include "channels.h" -#include "extern.h" + +const Anope::string ServerFlagStrings[] = { "SERVER_NONE", "SERVER_SYNCING", "SERVER_JUPED", "" }; +template<> const Anope::string* Flags<ServerFlag>::flags_strings = ServerFlagStrings; /* Anope */ Server *Me = NULL; -std::set<Anope::string> Capab; +std::set<Anope::string> Servers::Capab; -/** Constructor - * @param uplink The uplink this server is from, is only NULL when creating Me - * @param name The server name - * @param hops Hops from services server - * @param description Server rdescription - * @param sid Server sid/numeric - * @param flag An optional server flag - */ -Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const Anope::string &description, const Anope::string &sid, ServerFlag flag) : Flags<ServerFlag>(ServerFlagStrings), Name(name), Hops(hops), Description(description), SID(sid), UplinkServer(uplink) +Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Anope::string &desc, const Anope::string &ssid, ServerFlag flag) : name(sname), hops(shops), description(desc), sid(ssid), uplink(up) { this->SetFlag(SERVER_SYNCING); this->SetFlag(flag); - Log(this, "connect") << "uplinked to " << (this->UplinkServer ? this->UplinkServer->GetName() : "no uplink") << " connected to the network"; + Log(this, "connect") << "uplinked to " << (this->uplink ? this->uplink->GetName() : "no uplink") << " connected to the network"; /* Add this server to our uplinks leaf list */ - if (this->UplinkServer) + if (this->uplink) { - this->UplinkServer->AddLink(this); + this->uplink->AddLink(this); /* Check to be sure this isn't a juped server */ - if (Me == this->UplinkServer && !this->HasFlag(SERVER_JUPED)) + if (Me == this->uplink && !this->HasFlag(SERVER_JUPED)) { /* Now do mode related stuff as we know what modes exist .. */ for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) { BotInfo *bi = it->second; - Anope::string modes = !bi->botmodes.empty() ? ("+" + bi->botmodes) : ircdproto->DefaultPseudoclientModes; + Anope::string modes = !bi->botmodes.empty() ? ("+" + bi->botmodes) : IRCD->DefaultPseudoclientModes; bi->SetModesInternal(modes.c_str()); for (unsigned i = 0; i < bi->botchannels.size(); ++i) @@ -61,7 +56,7 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A if (h == Anope::string::npos) continue; Anope::string chname = bi->botchannels[i].substr(h); - Channel *c = findchan(chname); + Channel *c = Channel::Find(chname); if (c && c->FindUser(bi)) { Anope::string want_modes = bi->botchannels[i].substr(0, h); @@ -70,7 +65,7 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]); if (cm == NULL) cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j])); - if (cm && cm->Type == MODE_STATUS) + if (cm && cm->type == MODE_STATUS) { MessageSource ms = bi; c->SetModeInternal(ms, cm, bi->nick); @@ -80,14 +75,14 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A } } - ircdproto->SendBOB(); + IRCD->SendBOB(); for (unsigned i = 0; i < Me->GetLinks().size(); ++i) { Server *s = Me->GetLinks()[i]; if (s->HasFlag(SERVER_JUPED)) - ircdproto->SendServer(s); + IRCD->SendServer(s); } /* We make the bots go online */ @@ -95,14 +90,14 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A { User *u = it->second; - BotInfo *bi = findbot(u->nick); + BotInfo *bi = BotInfo::Find(u->nick); if (bi) { XLine x(bi->nick, "Reserved for services"); - ircdproto->SendSQLine(NULL, &x); + IRCD->SendSQLine(NULL, &x); } - ircdproto->SendClientIntroduction(u); + IRCD->SendClientIntroduction(u); if (bi) bi->introduced = true; } @@ -111,10 +106,10 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A { Channel *c = it->second; if (c->users.empty()) - ircdproto->SendChannel(c); + IRCD->SendChannel(c); else for (CUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit) - ircdproto->SendJoin((*cit)->user, c, (*cit)->Status); + IRCD->SendJoin((*cit)->user, c, (*cit)->status); } } } @@ -122,13 +117,11 @@ Server::Server(Server *uplink, const Anope::string &name, unsigned hops, const A FOREACH_MOD(I_OnNewServer, OnNewServer(this)); } -/** Destructor - */ Server::~Server() { - Log(this, "quit") << "quit from " << (this->UplinkServer ? this->UplinkServer->GetName() : "no uplink") << " for " << this->QReason; + Log(this, "quit") << "quit from " << (this->uplink ? this->uplink->GetName() : "no uplink") << " for " << this->quit_reason; - if (Capab.count("NOQUIT") > 0 || Capab.count("QS") > 0) + if (Servers::Capab.count("NOQUIT") > 0 || Servers::Capab.count("QS") > 0) { for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) { @@ -137,11 +130,11 @@ Server::~Server() if (u->server == this) { - NickAlias *na = findnick(u->nick); + NickAlias *na = NickAlias::Find(u->nick); if (na && !na->nc->HasFlag(NI_SUSPENDED) && (u->IsRecognized() || u->IsIdentified())) { na->last_seen = Anope::CurTime; - na->last_quit = this->QReason; + na->last_quit = this->quit_reason; } delete u; @@ -151,113 +144,80 @@ Server::~Server() Log(LOG_DEBUG) << "Finished removing all users for " << this->GetName(); } - if (this->UplinkServer) - this->UplinkServer->DelLink(this); + if (this->uplink) + this->uplink->DelLink(this); - for (unsigned i = this->Links.size(); i > 0; --i) - this->Links[i - 1]->Delete(this->QReason); + for (unsigned i = this->links.size(); i > 0; --i) + this->links[i - 1]->Delete(this->quit_reason); } -/** Delete this server with a reason - * @param reason The reason - */ void Server::Delete(const Anope::string &reason) { - this->QReason = reason; + this->quit_reason = reason; FOREACH_MOD(I_OnServerQuit, OnServerQuit(this)); delete this; } -/** Get the name for this server - * @return The name - */ const Anope::string &Server::GetName() const { - return this->Name; + return this->name; } -/** Get the number of hops this server is from services - * @return Number of hops - */ unsigned Server::GetHops() const { - return this->Hops; + return this->hops; } -/** Set the server description - * @param desc The new description - */ void Server::SetDescription(const Anope::string &desc) { - this->Description = desc; + this->description = desc; } -/** Get the server description - * @return The server description - */ const Anope::string &Server::GetDescription() const { - return this->Description; + return this->description; } -/** Change this servers SID - * @param sid The new SID - */ -void Server::SetSID(const Anope::string &sid) +void Server::SetSID(const Anope::string &nsid) { - this->SID = sid; + this->sid = nsid; } -/** Get the server numeric/SID - * @return The numeric/SID - */ const Anope::string &Server::GetSID() const { - if (!this->SID.empty() && ircdproto->RequiresID) - return this->SID; + if (!this->sid.empty() && IRCD->RequiresID) + return this->sid; else - return this->Name; + return this->name; } -/** Get the list of links this server has, or NULL if it has none - * @return A list of servers - */ const std::vector<Server *> &Server::GetLinks() const { - return this->Links; + return this->links; } -/** Get the uplink server for this server, if this is our uplink will be Me - * @return The servers uplink - */ Server *Server::GetUplink() { - return this->UplinkServer; + return this->uplink; } -/** Adds a link to this server - * @param s The linking server - */ void Server::AddLink(Server *s) { - this->Links.push_back(s); + this->links.push_back(s); Log(this, "connect") << "introduced " << s->GetName(); } -/** Delinks a server from this server - * @param s The server - */ void Server::DelLink(Server *s) { - if (this->Links.empty()) + if (this->links.empty()) throw CoreException("Server::DelLink called on " + this->GetName() + " for " + s->GetName() + " but we have no links?"); - for (unsigned i = 0, j = this->Links.size(); i < j; ++i) + for (unsigned i = 0, j = this->links.size(); i < j; ++i) { - if (this->Links[i] == s) + if (this->links[i] == s) { - this->Links.erase(this->Links.begin() + i); + this->links.erase(this->links.begin() + i); break; } } @@ -265,10 +225,7 @@ void Server::DelLink(Server *s) Log(this, "quit") << "quit " << s->GetName(); } -/** Finish syncing this server and optionally all links to it - * @param SyncLinks True to sync the links for this server too (if any) - */ -void Server::Sync(bool SyncLinks) +void Server::Sync(bool sync_links) { if (this->IsSynced()) return; @@ -279,10 +236,10 @@ void Server::Sync(bool SyncLinks) FOREACH_MOD(I_OnServerSync, OnServerSync(this)); - if (SyncLinks && !this->Links.empty()) + if (sync_links && !this->links.empty()) { - for (unsigned i = 0, j = this->Links.size(); i < j; ++i) - this->Links[i]->Sync(true); + for (unsigned i = 0, j = this->links.size(); i < j; ++i) + this->links[i]->Sync(true); } if (this->GetUplink() && this->GetUplink() == Me) @@ -302,7 +259,7 @@ void Server::Sync(bool SyncLinks) { ci->c->SetMode(NULL, CMODE_PERM); if (created) - ircdproto->SendChannel(ci->c); + IRCD->SendChannel(ci->c); } else { @@ -316,7 +273,7 @@ void Server::Sync(bool SyncLinks) FOREACH_MOD(I_OnPreUplinkSync, OnPreUplinkSync(this)); - ircdproto->SendEOB(); + IRCD->SendEOB(); Me->Sync(false); FOREACH_MOD(I_OnUplinkSync, OnUplinkSync(this)); @@ -329,25 +286,19 @@ void Server::Sync(bool SyncLinks) c->ci->RestoreTopic(); } - if (!nofork && AtTerm()) + if (!Anope::NoFork && Anope::AtTerm()) { Log(LOG_TERMINAL) << "Successfully linked, launching into background..."; - Fork(); + Anope::Fork(); } } } -/** Check if this server is synced - * @return true or false - */ bool Server::IsSynced() const { return !this->HasFlag(SERVER_SYNCING); } -/** Check if this server is ULined - * @return true or false - */ bool Server::IsULined() const { if (this == Me) @@ -359,24 +310,14 @@ bool Server::IsULined() const return false; } - -/** Send a message to alll users on this server - * @param source The source of the message - * @param message The message - */ void Server::Notice(const BotInfo *source, const Anope::string &message) { if (Config->NSDefFlags.HasFlag(NI_MSG)) - ircdproto->SendGlobalPrivmsg(source, this, message); + IRCD->SendGlobalPrivmsg(source, this, message); else - ircdproto->SendGlobalNotice(source, this, message); + IRCD->SendGlobalNotice(source, this, message); } -/** Find a server - * @param name The name or SID/numeric - * @param s The server list to search for this server on, defaults to our Uplink - * @return The server - */ Server *Server::Find(const Anope::string &name, Server *s) { Log(LOG_DEBUG_2) << "Server::Find called for " << name; @@ -417,17 +358,14 @@ static inline char& nextID(char &c) return c; } -/** Recieve the next UID in our list - * @return The UID - */ -const Anope::string ts6_uid_retrieve() +const Anope::string Servers::TS6_UID_Retrieve() { - if (!ircdproto || !ircdproto->RequiresID) + if (!IRCD || !IRCD->RequiresID) return ""; static Anope::string current_uid = "AAAAAA"; - while (finduser(Config->Numeric + current_uid) != NULL) + while (User::Find(Config->Numeric + current_uid) != NULL) { int current_len = current_uid.length() - 1; while (current_len >= 0 && nextID(current_uid[current_len--]) == 'A'); @@ -436,12 +374,9 @@ const Anope::string ts6_uid_retrieve() return Config->Numeric + current_uid; } -/** Return the next SID in our list - * @return The SID - */ -const Anope::string ts6_sid_retrieve() +const Anope::string Servers::TS6_SID_Retrieve() { - if (!ircdproto || !ircdproto->RequiresID) + if (!IRCD || !IRCD->RequiresID) return ""; static Anope::string current_sid; @@ -461,3 +396,11 @@ const Anope::string ts6_sid_retrieve() return current_sid; } +Server* Servers::GetUplink() +{ + for (unsigned i = 0; Me && i < Me->GetLinks().size(); ++i) + if (!Me->GetLinks()[i]->HasFlag(SERVER_JUPED)) + return Me->GetLinks()[i]; + return NULL; +} + diff --git a/src/socket_clients.cpp b/src/socket_clients.cpp index 44d4b873a..69700af4e 100644 --- a/src/socket_clients.cpp +++ b/src/socket_clients.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -22,7 +23,7 @@ ConnectionSocket::ConnectionSocket() : Socket() void ConnectionSocket::Connect(const Anope::string &TargetHost, int Port) { - this->IO->Connect(this, TargetHost, Port); + this->io->Connect(this, TargetHost, Port); } bool ConnectionSocket::Process() @@ -32,7 +33,7 @@ bool ConnectionSocket::Process() if (this->HasFlag(SF_CONNECTED)) return true; else if (this->HasFlag(SF_CONNECTING)) - this->SetFlag(this->IO->FinishConnect(this)); + this->SetFlag(this->io->FinishConnect(this)); else this->SetFlag(SF_DEAD); } @@ -61,7 +62,7 @@ void ConnectionSocket::OnError(const Anope::string &error) Log(LOG_DEBUG) << "Socket error: " << error; } -ClientSocket::ClientSocket(ListenSocket *ls, const sockaddrs &addr) : LS(ls), clientaddr(addr) +ClientSocket::ClientSocket(ListenSocket *l, const sockaddrs &addr) : ls(l), clientaddr(addr) { } @@ -72,7 +73,7 @@ bool ClientSocket::Process() if (this->HasFlag(SF_ACCEPTED)) return true; else if (this->HasFlag(SF_ACCEPTING)) - this->SetFlag(this->IO->FinishAccept(this)); + this->SetFlag(this->io->FinishAccept(this)); else this->SetFlag(SF_DEAD); } diff --git a/src/socket_transport.cpp b/src/socket_transport.cpp index 2297da2b2..4af3668a3 100644 --- a/src/socket_transport.cpp +++ b/src/socket_transport.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -25,28 +26,28 @@ bool BufferedSocket::ProcessRead() { char tbuffer[NET_BUFSIZE]; - this->RecvLen = 0; + this->recv_len = 0; - int len = this->IO->Recv(this, tbuffer, sizeof(tbuffer) - 1); + int len = this->io->Recv(this, tbuffer, sizeof(tbuffer) - 1); if (len <= 0) return false; tbuffer[len] = 0; - this->RecvLen = len; + this->recv_len = len; - Anope::string sbuffer = this->extrabuf; + Anope::string sbuffer = this->extra_buf; sbuffer += tbuffer; - this->extrabuf.clear(); + this->extra_buf.clear(); size_t lastnewline = sbuffer.rfind('\n'); if (lastnewline == Anope::string::npos) { - this->extrabuf = sbuffer; + this->extra_buf = sbuffer; return true; } if (lastnewline < sbuffer.length() - 1) { - this->extrabuf = sbuffer.substr(lastnewline); - this->extrabuf.trim(); + this->extra_buf = sbuffer.substr(lastnewline); + this->extra_buf.trim(); sbuffer = sbuffer.substr(0, lastnewline); } @@ -65,11 +66,11 @@ bool BufferedSocket::ProcessRead() bool BufferedSocket::ProcessWrite() { - int count = this->IO->Send(this, this->WriteBuffer); + int count = this->io->Send(this, this->write_buffer); if (count <= -1) return false; - this->WriteBuffer = this->WriteBuffer.substr(count); - if (this->WriteBuffer.empty()) + this->write_buffer = this->write_buffer.substr(count); + if (this->write_buffer.empty()) SocketEngine::Change(this, false, SF_WRITABLE); return true; @@ -82,7 +83,7 @@ bool BufferedSocket::Read(const Anope::string &buf) void BufferedSocket::Write(const char *buffer, size_t l) { - this->WriteBuffer += buffer + Anope::string("\r\n"); + this->write_buffer += buffer + Anope::string("\r\n"); SocketEngine::Change(this, true, SF_WRITABLE); } @@ -108,12 +109,12 @@ void BufferedSocket::Write(const Anope::string &message) int BufferedSocket::ReadBufferLen() const { - return RecvLen; + return recv_len; } int BufferedSocket::WriteBufferLen() const { - return this->WriteBuffer.length(); + return this->write_buffer.length(); } @@ -141,7 +142,7 @@ bool BinarySocket::ProcessRead() { char tbuffer[NET_BUFSIZE]; - int len = this->IO->Recv(this, tbuffer, sizeof(tbuffer)); + int len = this->io->Recv(this, tbuffer, sizeof(tbuffer)); if (len <= 0) return false; @@ -150,21 +151,21 @@ bool BinarySocket::ProcessRead() bool BinarySocket::ProcessWrite() { - if (this->WriteBuffer.empty()) + if (this->write_buffer.empty()) { SocketEngine::Change(this, false, SF_WRITABLE); return true; } - DataBlock *d = this->WriteBuffer.front(); + DataBlock *d = this->write_buffer.front(); - int len = this->IO->Send(this, d->buf, d->len); + int len = this->io->Send(this, d->buf, d->len); if (len <= -1) return false; else if (static_cast<size_t>(len) == d->len) { delete d; - this->WriteBuffer.pop_front(); + this->write_buffer.pop_front(); } else { @@ -172,7 +173,7 @@ bool BinarySocket::ProcessWrite() d->len -= len; } - if (this->WriteBuffer.empty()) + if (this->write_buffer.empty()) SocketEngine::Change(this, false, SF_WRITABLE); return true; @@ -180,7 +181,7 @@ bool BinarySocket::ProcessWrite() void BinarySocket::Write(const char *buffer, size_t l) { - this->WriteBuffer.push_back(new DataBlock(buffer, l)); + this->write_buffer.push_back(new DataBlock(buffer, l)); SocketEngine::Change(this, true, SF_WRITABLE); } diff --git a/src/socketengines/pipeengine_eventfd.cpp b/src/socketengines/pipeengine_eventfd.cpp index 19433d1c8..61fddd0af 100644 --- a/src/socketengines/pipeengine_eventfd.cpp +++ b/src/socketengines/pipeengine_eventfd.cpp @@ -16,7 +16,7 @@ Pipe::Pipe() : Socket(eventfd(0, EFD_NONBLOCK)) { - if (this->Sock < 0) + if (this->sock < 0) throw CoreException("Could not create pipe: " + Anope::LastError()); } diff --git a/src/sockets.cpp b/src/sockets.cpp index 861df6976..6aadb7802 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -20,15 +21,18 @@ #include <fcntl.h> #endif +static const Anope::string SocketFlagStrings[] = { + "SF_DEAD", "SF_WRITABLE", "SF_CONNECTING", "SF_CONNECTED", "SF_ACCEPTING", "SF_ACCEPTED", "" +}; +template<> const Anope::string* Flags<SocketFlag>::flags_strings = SocketFlagStrings; + std::map<int, Socket *> SocketEngine::Sockets; uint32_t TotalRead = 0; uint32_t TotalWritten = 0; -SocketIO normalSocketIO; +SocketIO NormalSocketIO; -/** Construct the object, sets everything to 0 - */ sockaddrs::sockaddrs(const Anope::string &address) { this->clear(); @@ -36,16 +40,11 @@ sockaddrs::sockaddrs(const Anope::string &address) this->pton(address.find(':') != Anope::string::npos ? AF_INET6 : AF_INET, address); } -/** Memset the object to 0 - */ void sockaddrs::clear() { memset(this, 0, sizeof(*this)); } -/** Get the size of the sockaddr we represent - * @return The size - */ size_t sockaddrs::size() const { switch (sa.sa_family) @@ -61,9 +60,6 @@ size_t sockaddrs::size() const return 0; } -/** Get the port represented by this addr - * @return The port, or -1 on fail - */ int sockaddrs::port() const { switch (sa.sa_family) @@ -79,9 +75,6 @@ int sockaddrs::port() const return -1; } -/** Get the address represented by this addr - * @return The address - */ Anope::string sockaddrs::addr() const { char address[INET6_ADDRSTRLEN + 1] = ""; @@ -103,16 +96,11 @@ Anope::string sockaddrs::addr() const return address; } -/** Check if this sockaddr has data in it - */ bool sockaddrs::operator()() const { return this->sa.sa_family != 0; } -/** Compares with sockaddr with another. Compares address type, port, and address - * @return true if they are the same - */ bool sockaddrs::operator==(const sockaddrs &other) const { if (sa.sa_family != other.sa.sa_family) @@ -130,12 +118,6 @@ bool sockaddrs::operator==(const sockaddrs &other) const return false; } -/** The equivalent of inet_pton - * @param type AF_INET or AF_INET6 - * @param address The address to place in the sockaddr structures - * @param pport An option port to include in the sockaddr structures - * @throws A socket exception if given invalid IPs - */ void sockaddrs::pton(int type, const Anope::string &address, int pport) { switch (type) @@ -169,11 +151,6 @@ void sockaddrs::pton(int type, const Anope::string &address, int pport) throw CoreException("Invalid socket type"); } -/** The equivalent of inet_ntop - * @param type AF_INET or AF_INET6 - * @param address The in_addr or in_addr6 structure - * @throws A socket exception if given an invalid structure - */ void sockaddrs::ntop(int type, const void *src) { switch (type) @@ -333,12 +310,6 @@ size_t cidr::hash::operator()(const cidr &s) const } } -/** Receive something from the buffer - * @param s The socket - * @param buf The buf to read to - * @param sz How much to read - * @return Number of bytes received - */ int SocketIO::Recv(Socket *s, char *buf, size_t sz) { size_t i = recv(s->GetFD(), buf, sz, 0); @@ -346,26 +317,18 @@ int SocketIO::Recv(Socket *s, char *buf, size_t sz) return i; } -/** Write something to the socket - * @param s The socket - * @param buf The data to write - * @param size The length of the data - */ int SocketIO::Send(Socket *s, const char *buf, size_t sz) { size_t i = send(s->GetFD(), buf, sz, 0); TotalWritten += i; return i; } + int SocketIO::Send(Socket *s, const Anope::string &buf) { return this->Send(s, buf.c_str(), buf.length()); } -/** Accept a connection from a socket - * @param s The socket - * @return The new client socket - */ ClientSocket *SocketIO::Accept(ListenSocket *s) { sockaddrs conaddr; @@ -384,20 +347,11 @@ ClientSocket *SocketIO::Accept(ListenSocket *s) throw SocketException("Unable to accept connection: " + Anope::LastError()); } -/** Finished accepting a connection from a socket - * @param s The socket - * @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error - */ SocketFlag SocketIO::FinishAccept(ClientSocket *cs) { return SF_ACCEPTED; } -/** Bind a socket - * @param s The socket - * @param ip The IP to bind to - * @param port The optional port to bind to - */ void SocketIO::Bind(Socket *s, const Anope::string &ip, int port) { s->bindaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, ip, port); @@ -405,11 +359,6 @@ void SocketIO::Bind(Socket *s, const Anope::string &ip, int port) throw SocketException("Unable to bind to address: " + Anope::LastError()); } -/** Connect the socket - * @param s THe socket - * @param target IP to connect to - * @param port to connect to - */ void SocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port) { s->UnsetFlag(SF_CONNECTING); @@ -433,10 +382,6 @@ void SocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int por } } -/** Called to potentially finish a pending connection - * @param s The socket - * @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error. - */ SocketFlag SocketIO::FinishConnect(ConnectionSocket *s) { if (s->HasFlag(SF_CONNECTED)) @@ -461,148 +406,102 @@ SocketFlag SocketIO::FinishConnect(ConnectionSocket *s) } } -/** Empty constructor, should not be called. - */ -Socket::Socket() : Flags<SocketFlag>(SocketFlagStrings) +Socket::Socket() { throw CoreException("Socket::Socket() ?"); } -/** Constructor - * @param sock The socket - * @param ipv6 IPv6? - * @param type The socket type, defaults to SOCK_STREAM - */ -Socket::Socket(int sock, bool ipv6, int type) : Flags<SocketFlag>(SocketFlagStrings) +Socket::Socket(int s, bool i, int type) { - this->IO = &normalSocketIO; - this->IPv6 = ipv6; - if (sock == -1) - this->Sock = socket(this->IPv6 ? AF_INET6 : AF_INET, type, 0); + this->io = &NormalSocketIO; + this->ipv6 = i; + if (s == -1) + this->sock = socket(this->ipv6 ? AF_INET6 : AF_INET, type, 0); else - this->Sock = sock; + this->sock = s; this->SetNonBlocking(); - SocketEngine::Sockets[this->Sock] = this; + SocketEngine::Sockets[this->sock] = this; SocketEngine::Change(this, true, SF_READABLE); } -/** Default destructor -*/ Socket::~Socket() { SocketEngine::Change(this, false, SF_READABLE); SocketEngine::Change(this, false, SF_WRITABLE); - anope_close(this->Sock); - this->IO->Destroy(); - SocketEngine::Sockets.erase(this->Sock); + anope_close(this->sock); + this->io->Destroy(); + SocketEngine::Sockets.erase(this->sock); } -/** Get the socket FD for this socket - * @return the fd - */ int Socket::GetFD() const { - return Sock; + return sock; } -/** Check if this socket is IPv6 - * @return true or false - */ bool Socket::IsIPv6() const { - return IPv6; + return ipv6; } -/** Mark a socket as blockig - * @return true if the socket is now blocking - */ bool Socket::SetBlocking() { int flags = fcntl(this->GetFD(), F_GETFL, 0); return !fcntl(this->GetFD(), F_SETFL, flags & ~O_NONBLOCK); } -/** Mark a socket as non-blocking - * @return true if the socket is now non-blocking - */ bool Socket::SetNonBlocking() { int flags = fcntl(this->GetFD(), F_GETFL, 0); return !fcntl(this->GetFD(), F_SETFL, flags | O_NONBLOCK); } -/** Bind the socket to an ip and port - * @param ip The ip - * @param port The port - */ void Socket::Bind(const Anope::string &ip, int port) { - this->IO->Bind(this, ip, port); + this->io->Bind(this, ip, port); } -/** Called when there either is a read or write event. - * @return true to continue to call ProcessRead/ProcessWrite, false to not continue - */ bool Socket::Process() { return true; } -/** Called when there is something to be received for this socket - * @return true on success, false to drop this socket - */ bool Socket::ProcessRead() { return true; } -/** Called when the socket is ready to be written to - * @return true on success, false to drop this socket - */ bool Socket::ProcessWrite() { return true; } -/** Called when there is an error for this socket - * @return true on success, false to drop this socket - */ void Socket::ProcessError() { } -/** Constructor - * @param bindip The IP to bind to - * @param port The port to listen on - * @param ipv6 true for ipv6 - */ -ListenSocket::ListenSocket(const Anope::string &bindip, int port, bool ipv6) +ListenSocket::ListenSocket(const Anope::string &bindip, int port, bool i) { this->SetNonBlocking(); const char op = 1; setsockopt(this->GetFD(), SOL_SOCKET, SO_REUSEADDR, &op, sizeof(op)); - this->bindaddr.pton(IPv6 ? AF_INET6 : AF_INET, bindip, port); - this->IO->Bind(this, bindip, port); + this->bindaddr.pton(i ? AF_INET6 : AF_INET, bindip, port); + this->io->Bind(this, bindip, port); - if (listen(Sock, SOMAXCONN) == -1) + if (listen(sock, SOMAXCONN) == -1) throw SocketException("Unable to listen: " + Anope::LastError()); } -/** Destructor - */ ListenSocket::~ListenSocket() { } -/** Accept a connection in this sockets queue - */ bool ListenSocket::ProcessRead() { try { - this->IO->Accept(this); + this->io->Accept(this); } catch (const SocketException &ex) { diff --git a/src/threadengine.cpp b/src/threadengine.cpp index c3ecdd1b5..12e14eb19 100644 --- a/src/threadengine.cpp +++ b/src/threadengine.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #include "services.h" @@ -35,9 +36,6 @@ static inline pthread_attr_t *get_engine_attr() return &attr; } -/** Entry point used for the threads - * @param parameter A Thread* cast to a void* - */ static void *entry_point(void *parameter) { Thread *thread = static_cast<Thread *>(parameter); @@ -47,129 +45,92 @@ static void *entry_point(void *parameter) return NULL; } -/** Threads constructor - */ Thread::Thread() : exit(false) { } -/** Threads destructor - */ Thread::~Thread() { } -/** Join to the thread, sets the exit state to true - */ void Thread::Join() { this->SetExitState(); - pthread_join(Handle, NULL); + pthread_join(handle, NULL); } -/** Sets the exit state as true informing the thread we want it to shut down - */ void Thread::SetExitState() { this->Notify(); exit = true; } -/** Exit the thread. Note that the thread still must be joined to free resources! - */ void Thread::Exit() { this->SetExitState(); pthread_exit(0); } -/** Launch the thread - */ void Thread::Start() { - if (pthread_create(&this->Handle, get_engine_attr(), entry_point, this)) + if (pthread_create(&this->handle, get_engine_attr(), entry_point, this)) { this->SetFlag(SF_DEAD); throw CoreException("Unable to create thread: " + Anope::LastError()); } } -/** Returns the exit state of the thread - * @return true if we want to exit - */ bool Thread::GetExitState() const { return exit; } -/** Called when this thread should be joined to - */ void Thread::OnNotify() { this->Join(); this->SetFlag(SF_DEAD); } -/** Constructor - */ Mutex::Mutex() { pthread_mutex_init(&mutex, NULL); } -/** Destructor - */ Mutex::~Mutex() { pthread_mutex_destroy(&mutex); } -/** Attempt to lock the mutex, will hang until a lock can be achieved - */ void Mutex::Lock() { pthread_mutex_lock(&mutex); } -/** Unlock the mutex, it must be locked first - */ void Mutex::Unlock() { pthread_mutex_unlock(&mutex); } -/** Attempt to lock the mutex, will return true on success and false on fail - * Does not block - * @return true or false - */ bool Mutex::TryLock() { return pthread_mutex_trylock(&mutex) == 0; } -/** Constructor - */ Condition::Condition() : Mutex() { pthread_cond_init(&cond, NULL); } -/** Destructor - */ Condition::~Condition() { pthread_cond_destroy(&cond); } -/** Called to wakeup the waiter - */ void Condition::Wakeup() { pthread_cond_signal(&cond); } -/** Called to wait for a Wakeup() call - */ void Condition::Wait() { pthread_cond_wait(&cond, &mutex); diff --git a/src/timers.cpp b/src/timers.cpp index 267629aee..bc88afb01 100644 --- a/src/timers.cpp +++ b/src/timers.cpp @@ -4,21 +4,14 @@ * 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. + * */ - #include "services.h" #include "timers.h" std::vector<Timer *> TimerManager::Timers; -/** Default constructor, initializes the triggering time - * @param time_from_now The number of seconds from now to trigger the timer - * @param now The time now - * @param repeating Repeat this timer every time_from_now if this is true - */ Timer::Timer(long time_from_now, time_t now, bool repeating) { trigger = now + time_from_now; @@ -29,48 +22,31 @@ Timer::Timer(long time_from_now, time_t now, bool repeating) TimerManager::AddTimer(this); } -/** Default destructor, removes the timer from the list - */ Timer::~Timer() { TimerManager::DelTimer(this); } -/** Set the trigger time to a new value - * @param t The new time -*/ void Timer::SetTimer(time_t t) { trigger = t; } -/** Retrieve the triggering time - * @return The trigger time - */ time_t Timer::GetTimer() const { return trigger; } -/** Returns true if the timer is set to repeat - * @return Returns true if the timer is set to repeat - */ bool Timer::GetRepeat() const { return repeat; } -/** Returns the time this timer was created -* @return The time this timer was created -*/ time_t Timer::GetSetTime() const { return settime; } -/** Sets the interval between ticks - * @param t The new interval - */ void Timer::SetSecs(time_t t) { secs = t; @@ -80,37 +56,25 @@ void Timer::SetSecs(time_t t) TimerManager::AddTimer(this); } -/** Returns the interval between ticks -* @return The interval -*/ long Timer::GetSecs() const { return secs; } -/** Add a timer to the list - * @param T A Timer derived class to add - */ -void TimerManager::AddTimer(Timer *T) +void TimerManager::AddTimer(Timer *t) { - Timers.push_back(T); + Timers.push_back(t); sort(Timers.begin(), Timers.end(), TimerManager::TimerComparison); } -/** Deletes a timer - * @param T A Timer derived class to delete - */ -void TimerManager::DelTimer(Timer *T) +void TimerManager::DelTimer(Timer *t) { - std::vector<Timer *>::iterator i = std::find(Timers.begin(), Timers.end(), T); + std::vector<Timer *>::iterator i = std::find(Timers.begin(), Timers.end(), t); if (i != Timers.end()) Timers.erase(i); } -/** Tick all pending timers - * @param ctime The current time - */ void TimerManager::TickTimers(time_t ctime) { while (Timers.size() && ctime > Timers.front()->GetTimer()) @@ -129,8 +93,6 @@ void TimerManager::TickTimers(time_t ctime) } } -/** Compares two timers - */ bool TimerManager::TimerComparison(Timer *one, Timer *two) { return one->GetTimer() < two->GetTimer(); diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 88fc37ffc..613e4ffc6 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -34,6 +34,14 @@ foreach(SRC ${TOOLS_SRCS}) endif(NOT SKIP) endforeach(SRC) +# If not on Windows, generate anoperc and install it along with mydbgen +if(NOT WIN32) + configure_file(${Anope_SOURCE_DIR}/src/tools/anoperc.in ${Anope_BINARY_DIR}/src/tools/anoperc) + install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/anoperc + DESTINATION ${BIN_DIR} + ) +endif(NOT WIN32) + # On non-Windows platforms, if RUNGROUP is set, change the permissions of the tools directory if(NOT WIN32 AND RUNGROUP) install(CODE "execute_process(COMMAND ${CHMOD} 2770 \"\${CMAKE_INSTALL_PREFIX}/bin\")") diff --git a/src/bin/anoperc.in b/src/tools/anoperc.in index 9a71a22c3..9a71a22c3 100644 --- a/src/bin/anoperc.in +++ b/src/tools/anoperc.in diff --git a/src/uplink.cpp b/src/uplink.cpp new file mode 100644 index 000000000..ac77672b2 --- /dev/null +++ b/src/uplink.cpp @@ -0,0 +1,204 @@ +/* + * + * (C) 2003-2012 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. + * + */ + +#include "uplink.h" +#include "logger.h" +#include "config.h" +#include "protocol.h" +#include "servers.h" +#include "dns.h" + +UplinkSocket *UplinkSock = NULL; + +class ReconnectTimer : public Timer +{ + public: + ReconnectTimer(int wait) : Timer(wait) { } + + void Tick(time_t) + { + try + { + Uplink::Connect(); + } + 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(); + } + } +}; + +void Uplink::Connect() +{ + if (static_cast<unsigned>(++Anope::CurrentUplink) >= Config->Uplinks.size()) + Anope::CurrentUplink = 0; + + ServerConfig::Uplink *u = Config->Uplinks[Anope::CurrentUplink]; + + new UplinkSocket(); + if (!Config->LocalHost.empty()) + UplinkSock->Bind(Config->LocalHost); + FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect()); + DNS::Query rep = DNS::Manager::BlockingQuery(u->host, u->ipv6 ? DNS::QUERY_AAAA : DNS::QUERY_A); + Anope::string reply_ip = !rep.answers.empty() ? rep.answers.front().rdata : u->host; + Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u->host << " (" << reply_ip << "), port " << u->port; + UplinkSock->Connect(reply_ip, u->port); +} + + +UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink]->ipv6), ConnectionSocket(), BufferedSocket() +{ + UplinkSock = this; +} + +UplinkSocket::~UplinkSocket() +{ + if (IRCD && Servers::GetUplink() && Servers::GetUplink()->IsSynced()) + { + FOREACH_MOD(I_OnServerDisconnect, OnServerDisconnect()); + + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) + { + User *u = it->second; + + if (u->server == Me) + { + /* Don't use quitmsg here, it may contain information you don't want people to see */ + IRCD->SendQuit(u, "Shutting down"); + BotInfo* bi = BotInfo::Find(u->nick); + if (bi != NULL) + bi->introduced = false; + } + } + + IRCD->SendSquit(Me, Anope::QuitReason); + + this->ProcessWrite(); // Write out the last bit + } + + if (Me) + for (unsigned i = Me->GetLinks().size(); i > 0; --i) + if (!Me->GetLinks()[i - 1]->HasFlag(SERVER_JUPED)) + Me->GetLinks()[i - 1]->Delete(Me->GetName() + " " + Me->GetLinks()[i - 1]->GetName()); + + UplinkSock = NULL; + + Me->SetFlag(SERVER_SYNCING); + + if (Anope::AtTerm()) + { + if (static_cast<unsigned>(Anope::CurrentUplink + 1) == Config->Uplinks.size()) + { + Anope::QuitReason = "Unable to connect to any uplink"; + Anope::Quitting = true; + Anope::ReturnValue = -1; + } + else + { + new ReconnectTimer(1); + } + } + else if (!Anope::Quitting) + { + int retry = Config->RetryWait; + if (retry <= 0) + retry = 60; + + Log() << "Disconnected, retrying in " << retry << " seconds"; + new ReconnectTimer(retry); + } +} + +bool UplinkSocket::Read(const Anope::string &buf) +{ + Anope::Process(buf); + return true; +} + +void UplinkSocket::OnConnect() +{ + 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) : ""); +} + +UplinkSocket::Message::Message() : server(NULL), user(NULL) +{ +} + +UplinkSocket::Message::Message(const Server *s) : server(s), user(NULL) +{ +} + +UplinkSocket::Message::Message(const User *u) : server(NULL), user(u) +{ + if (!u) + server = Me; +} + +UplinkSocket::Message::~Message() +{ + Anope::string message_source = ""; + + if (this->server != NULL) + { + if (this->server != Me && !this->server->HasFlag(SERVER_JUPED)) + { + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << this->server->GetName() << " who is not from me?"; + return; + } + + message_source = this->server->GetSID(); + } + else if (this->user != NULL) + { + if (this->user->server != Me && !this->user->server->HasFlag(SERVER_JUPED)) + { + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << this->user->nick << " who is not from me?"; + return; + } + + const BotInfo *bi = BotInfo::Find(this->user->nick); + if (bi != NULL && bi->introduced == false) + { + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" from " << bi->nick << " when not introduced"; + return; + } + + message_source = this->user->GetUID(); + } + + if (!UplinkSock) + { + if (!message_source.empty()) + Log(LOG_DEBUG) << "Attempted to send \"" << message_source << " " << this->buffer.str() << "\" with UplinkSock NULL"; + else + Log(LOG_DEBUG) << "Attempted to send \"" << this->buffer.str() << "\" with UplinkSock NULL"; + return; + } + + if (!message_source.empty()) + { + UplinkSock->Write(":" + message_source + " " + this->buffer.str()); + Log(LOG_RAWIO) << "Sent: :" << message_source << " " << this->buffer.str(); + } + else + { + UplinkSock->Write(this->buffer.str()); + Log(LOG_RAWIO) << "Sent: " << this->buffer.str(); + } +} diff --git a/src/users.cpp b/src/users.cpp index ea02566d4..628b0c464 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -7,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ @@ -20,16 +21,15 @@ #include "bots.h" #include "config.h" #include "opertype.h" -#include "extern.h" +#include "nickserv.h" +#include "operserv.h" +#include "language.h" user_map UserListByNick, UserListByUID; -int32_t opcnt = 0; -uint32_t usercnt = 0, maxusercnt = 0; -time_t maxusertime; - -/*************************************************************************/ -/*************************************************************************/ +int OperCount = 0; +unsigned MaxUserCount = 0; +time_t MaxUserTime = 0; User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid) { @@ -39,7 +39,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope: /* we used to do this by calloc, no more. */ server = NULL; invalid_pw_count = invalid_pw_time = lastmemosend = lastnickreg = lastmail = 0; - OnAccess = false; + on_access = false; this->nick = snick; this->ident = sident; @@ -53,7 +53,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope: this->timestamp = this->signon = ssignon; this->SetModesInternal("%s", smodes.c_str()); this->uid = suid; - this->SuperAdmin = false; + this->super_admin = false; size_t old = UserListByNick.size(); UserListByNick[snick] = this; @@ -66,22 +66,21 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope: if (sserver) // Our bots are introduced on startup with no server { - ++sserver->Users; + ++sserver->users; Log(this, "connect") << (!svhost.empty() ? Anope::string("(") + svhost + ") " : "") << "(" << srealname << ") " << sip << " connected to the network (" << sserver->GetName() << ")"; } - ++usercnt; - if (usercnt > maxusercnt) + if (UserListByNick.size() > MaxUserCount) { - maxusercnt = usercnt; - maxusertime = Anope::CurTime; - Log(this, "maxusers") << "connected - new maximum user count: " << maxusercnt; + MaxUserCount = UserListByNick.size(); + MaxUserTime = Anope::CurTime; + Log(this, "maxusers") << "connected - new maximum user count: " << UserListByNick.size(); } bool exempt = false; if (server && server->IsULined()) exempt = true; - dynamic_reference<User> user = this; + Reference<User> user = this; FOREACH_MOD(I_OnUserConnect, OnUserConnect(user, exempt)); } @@ -91,7 +90,7 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts) if (newnick.empty()) throw CoreException("User::ChangeNick() got a bad argument"); - this->SuperAdmin = false; + this->super_admin = false; Log(this, "nick") << "(" << this->realname << ") changed nick to " << newnick; Anope::string old = this->nick; @@ -101,7 +100,7 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts) this->nick = newnick; else { - NickAlias *old_na = findnick(this->nick); + NickAlias *old_na = NickAlias::Find(this->nick); if (old_na && (this->IsIdentified(true) || this->IsRecognized())) old_na->last_seen = Anope::CurTime; @@ -109,10 +108,10 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts) this->nick = newnick; UserListByNick[this->nick] = this; - OnAccess = false; - NickAlias *na = findnick(this->nick); + on_access = false; + NickAlias *na = NickAlias::Find(this->nick); if (na) - OnAccess = is_on_access(this, na->nc); + on_access = na->nc->IsOnAccess(this); if (old_na) old_na->OnCancel(this); @@ -139,9 +138,6 @@ void User::SetDisplayedHost(const Anope::string &shost) this->UpdateHost(); } -/** Get the displayed vhost of a user record. - * @return The displayed vhost of the user, where ircd-supported, or the user's real host. - */ const Anope::string &User::GetDisplayedHost() const { if (!this->vhost.empty()) @@ -152,9 +148,6 @@ const Anope::string &User::GetDisplayedHost() const return this->host; } -/** Update the cloaked host of a user - * @param host The cloaked host - */ void User::SetCloakedHost(const Anope::string &newhost) { if (newhost.empty()) @@ -167,9 +160,6 @@ void User::SetCloakedHost(const Anope::string &newhost) this->UpdateHost(); } -/** Get the cloaked host of a user - * @return The cloaked host - */ const Anope::string &User::GetCloakedHost() const { return chost; @@ -177,7 +167,7 @@ const Anope::string &User::GetCloakedHost() const const Anope::string &User::GetUID() const { - if (!this->uid.empty() && ircdproto->RequiresID) + if (!this->uid.empty() && IRCD->RequiresID) return this->uid; else return this->nick; @@ -230,7 +220,7 @@ void User::SetRealname(const Anope::string &srealname) throw CoreException("realname empty in SetRealname"); this->realname = srealname; - NickAlias *na = findnick(this->nick); + NickAlias *na = NickAlias::Find(this->nick); if (na && (this->IsIdentified(true) || this->IsRecognized())) na->last_realname = srealname; @@ -243,17 +233,15 @@ User::~User() Log(LOG_DEBUG_2) << "User::~User() called"; Log(this, "disconnect") << "(" << this->realname << ") " << "disconnected from the network (" << this->server->GetName() << ")"; - --this->server->Users; + --this->server->users; FOREACH_MOD(I_OnUserLogoff, OnUserLogoff(this)); ModeManager::StackerDel(this); this->Logout(); - --usercnt; - if (this->HasMode(UMODE_OPER)) - --opcnt; + --OperCount; while (!this->chans.empty()) this->chans.front()->chan->DeleteUser(this); @@ -262,7 +250,7 @@ User::~User() if (!this->uid.empty()) UserListByUID.erase(this->uid); - NickAlias *na = findnick(this->nick); + NickAlias *na = NickAlias::Find(this->nick); if (na) na->OnCancel(this); @@ -274,7 +262,7 @@ void User::SendMessage(const BotInfo *source, const char *fmt, ...) va_list args; char buf[BUFSIZE] = ""; - const char *translated_message = translate(this, fmt); + const char *translated_message = Language::Translate(this, fmt); va_start(args, fmt); vsnprintf(buf, BUFSIZE - 1, translated_message, args); @@ -286,7 +274,7 @@ void User::SendMessage(const BotInfo *source, const char *fmt, ...) void User::SendMessage(const BotInfo *source, const Anope::string &msg) { - const char *translated_message = translate(this, msg.c_str()); + const char *translated_message = Language::Translate(this, msg.c_str()); /* Send privmsg instead of notice if: * - UsePrivmsg is enabled @@ -298,9 +286,9 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg) while (sep.GetToken(tok)) { if (Config->UsePrivmsg && ((!this->nc && Config->NSDefFlags.HasFlag(NI_MSG)) || (this->nc && this->nc->HasFlag(NI_MSG)))) - ircdproto->SendPrivmsg(source, this->GetUID(), "%s", tok.c_str()); + IRCD->SendPrivmsg(source, this->GetUID(), "%s", tok.c_str()); else - ircdproto->SendNotice(source, this->GetUID(), "%s", tok.c_str()); + IRCD->SendNotice(source, this->GetUID(), "%s", tok.c_str()); } } @@ -362,13 +350,10 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg) */ void User::Collide(NickAlias *na) { - const BotInfo *bi = findbot(Config->NickServ); - if (!bi) - return; if (na) na->SetFlag(NS_COLLIDED); - if (ircdproto->CanSVSNick) + if (IRCD->CanSVSNick) { Anope::string guestnick; @@ -376,25 +361,21 @@ void User::Collide(NickAlias *na) do { guestnick = Config->NSGuestNickPrefix + stringify(static_cast<uint16_t>(rand())); - } while (finduser(guestnick) && i++ < 10); + } while (User::Find(guestnick) && i++ < 10); if (i == 11) this->Kill(Config->NickServ, "Services nickname-enforcer kill"); else { - this->SendMessage(bi, _("Your nickname is now being changed to \002%s\002"), guestnick.c_str()); - ircdproto->SendForceNickChange(this, guestnick, Anope::CurTime); + if (NickServ) + this->SendMessage(NickServ, _("Your nickname is now being changed to \002%s\002"), guestnick.c_str()); + IRCD->SendForceNickChange(this, guestnick, Anope::CurTime); } } else this->Kill(Config->NickServ, "Services nickname-enforcer kill"); } -/** Identify the user to the Nick - * updates last_seen, logs the user in, - * send messages, checks for mails, set vhost and more - * @param the NickAlias - */ void User::Identify(NickAlias *na) { if (!na) @@ -414,45 +395,41 @@ void User::Identify(NickAlias *na) } this->Login(na->nc); - ircdproto->SendLogin(this); + IRCD->SendLogin(this); - const NickAlias *this_na = findnick(this->nick); + const NickAlias *this_na = NickAlias::Find(this->nick); if (!Config->NoNicknameOwnership && this_na && this_na->nc == *na->nc && na->nc->HasFlag(NI_UNCONFIRMED) == false) - this->SetMode(findbot(Config->NickServ), UMODE_REGISTERED); + this->SetMode(NickServ, UMODE_REGISTERED); FOREACH_MOD(I_OnNickIdentify, OnNickIdentify(this)); if (this->IsServicesOper()) { - const BotInfo *bi = findbot(Config->OperServ); if (!this->nc->o->ot->modes.empty()) { - this->SetModes(bi, "%s", this->nc->o->ot->modes.c_str()); - if (bi != NULL) - this->SendMessage(bi, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str()); + this->SetModes(OperServ, "%s", this->nc->o->ot->modes.c_str()); + if (OperServ) + this->SendMessage(OperServ, "Changing your usermodes to \002%s\002", this->nc->o->ot->modes.c_str()); UserMode *um = ModeManager::FindUserModeByName(UMODE_OPER); - if (um && !this->HasMode(UMODE_OPER) && this->nc->o->ot->modes.find(um->ModeChar) != Anope::string::npos) - ircdproto->SendOper(this); + if (um && !this->HasMode(UMODE_OPER) && this->nc->o->ot->modes.find(um->mchar) != Anope::string::npos) + IRCD->SendOper(this); } - if (ircdproto->CanSetVHost && !this->nc->o->vhost.empty()) + if (IRCD->CanSetVHost && !this->nc->o->vhost.empty()) { - if (bi != NULL) - this->SendMessage(bi, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str()); + if (OperServ) + this->SendMessage(OperServ, "Changing your vhost to \002%s\002", this->nc->o->vhost.c_str()); this->SetDisplayedHost(this->nc->o->vhost); - ircdproto->SendVhost(this, "", this->nc->o->vhost); + IRCD->SendVhost(this, "", this->nc->o->vhost); } } } -/** Login the user to a NickCore - * @param core The account the user is useing - */ void User::Login(NickCore *core) { this->Logout(); this->nc = core; - core->Users.push_back(this); + core->users.push_back(this); this->UpdateHost(); @@ -460,8 +437,6 @@ void User::Login(NickCore *core) Log(this, "account") << "is now identified as " << this->nc->display; } -/** Logout the user - */ void User::Logout() { if (!this->nc) @@ -469,30 +444,23 @@ void User::Logout() Log(this, "account") << "is no longer identified as " << this->nc->display; - std::list<User *>::iterator it = std::find(this->nc->Users.begin(), this->nc->Users.end(), this); - if (it != this->nc->Users.end()) - this->nc->Users.erase(it); + std::list<User *>::iterator it = std::find(this->nc->users.begin(), this->nc->users.end(), this); + if (it != this->nc->users.end()) + this->nc->users.erase(it); this->nc = NULL; } -/** Get the account the user is logged in using - * @reurn The account or NULL - */ NickCore *User::Account() const { return this->nc; } -/** Check if the user is identified for their nick - * @param CheckNick True to check if the user is identified to the nickname they are on too - * @return true or false - */ bool User::IsIdentified(bool CheckNick) const { if (CheckNick && this->nc) { - NickAlias *na = findnick(this->nc->display); + NickAlias *na = NickAlias::Find(this->nc->display); if (na && *na->nc == *this->nc) return true; @@ -503,26 +471,19 @@ bool User::IsIdentified(bool CheckNick) const return this->nc ? true : false; } -/** Check if the user is recognized for their nick (on the nicks access list) - * @param CheckSecure Only returns true if the user has secure off - * @return true or false - */ bool User::IsRecognized(bool CheckSecure) const { - if (CheckSecure && OnAccess) + if (CheckSecure && on_access) { - const NickAlias *na = findnick(this->nick); + const NickAlias *na = NickAlias::Find(this->nick); if (!na || na->nc->HasFlag(NI_SECURE)) return false; } - return OnAccess; + return on_access; } -/** Check if the user is a services oper - * @return true if they are an oper - */ bool User::IsServicesOper() { if (!this->nc || !this->nc->IsServicesOper()) @@ -552,10 +513,6 @@ bool User::IsServicesOper() return true; } -/** Check whether this user has access to run the given command string. - * @param cmdstr The string to check, e.g. botserv/set/private. - * @return True if this user may run the specified command, false otherwise. - */ bool User::HasCommand(const Anope::string &command) { if (this->IsServicesOper()) @@ -563,10 +520,6 @@ bool User::HasCommand(const Anope::string &command) return false; } -/** Check whether this user has access to the given special permission. - * @param privstr The priv to check for, e.g. users/auspex. - * @return True if this user has the specified priv, false otherwise. - */ bool User::HasPriv(const Anope::string &priv) { if (this->IsServicesOper()) @@ -574,17 +527,15 @@ bool User::HasPriv(const Anope::string &priv) return false; } -/** Update the last usermask stored for a user, and check to see if they are recognized - */ void User::UpdateHost() { if (this->host.empty()) return; - NickAlias *na = findnick(this->nick); - OnAccess = false; + NickAlias *na = NickAlias::Find(this->nick); + on_access = false; if (na) - OnAccess = is_on_access(this, na->nc); + on_access = na->nc->IsOnAccess(this); if (na && (this->IsIdentified(true) || this->IsRecognized())) { @@ -595,97 +546,64 @@ void User::UpdateHost() } } -/** Check if the user has a mode - * @param Name Mode name - * @return true or false - */ bool User::HasMode(UserModeName Name) const { return this->modes.HasFlag(Name); } -/** Set a mode internally on the user, the IRCd is not informed - * @param um The user mode - * @param Param The param, if there is one - */ -void User::SetModeInternal(UserMode *um, const Anope::string &Param) +void User::SetModeInternal(UserMode *um, const Anope::string ¶m) { if (!um) return; - this->modes.SetFlag(um->Name); - if (!Param.empty()) - Params.insert(std::make_pair(um->Name, Param)); + this->modes.SetFlag(um->name); + if (!param.empty()) + this->mode_params.insert(std::make_pair(um->name, param)); - FOREACH_MOD(I_OnUserModeSet, OnUserModeSet(this, um->Name)); + FOREACH_MOD(I_OnUserModeSet, OnUserModeSet(this, um->name)); } -/** Remove a mode internally on the user, the IRCd is not informed - * @param um The user mode - */ void User::RemoveModeInternal(UserMode *um) { if (!um) return; - this->modes.UnsetFlag(um->Name); - std::map<UserModeName, Anope::string>::iterator it = Params.find(um->Name); - if (it != Params.end()) - Params.erase(it); + this->modes.UnsetFlag(um->name); + std::map<UserModeName, Anope::string>::iterator it = this->mode_params.find(um->name); + if (it != this->mode_params.end()) + this->mode_params.erase(it); - FOREACH_MOD(I_OnUserModeUnset, OnUserModeUnset(this, um->Name)); + FOREACH_MOD(I_OnUserModeUnset, OnUserModeUnset(this, um->name)); } -/** Set a mode on the user - * @param bi The client setting the mode - * @param um The user mode - * @param Param Optional param for the mode - */ void User::SetMode(const BotInfo *bi, UserMode *um, const Anope::string &Param) { - if (!um || HasMode(um->Name)) + if (!um || HasMode(um->name)) return; ModeManager::StackerAdd(bi, this, um, true, Param); SetModeInternal(um, Param); } -/** Set a mode on the user - * @param bi The client setting the mode - * @param Name The mode name - * @param param Optional param for the mode - */ void User::SetMode(const BotInfo *bi, UserModeName Name, const Anope::string &Param) { SetMode(bi, ModeManager::FindUserModeByName(Name), Param); } -/** Remove a mode on the user - * @param bi The client setting the mode - * @param um The user mode - */ void User::RemoveMode(const BotInfo *bi, UserMode *um) { - if (!um || !HasMode(um->Name)) + if (!um || !HasMode(um->name)) return; ModeManager::StackerAdd(bi, this, um, false); RemoveModeInternal(um); } -/** Remove a mode from the user - * @param bi The client setting the mode - * @param Name The mode name - */ void User::RemoveMode(const BotInfo *bi, UserModeName Name) { RemoveMode(bi, ModeManager::FindUserModeByName(Name)); } -/** Set a string of modes on a user - * @param bi The client setting the mode - * @param umodes The modes - */ void User::SetModes(const BotInfo *bi, const char *umodes, ...) { char buf[BUFSIZE] = ""; @@ -720,7 +638,7 @@ void User::SetModes(const BotInfo *bi, const char *umodes, ...) if (add) { - if (um->Type == MODE_PARAM && sep.GetToken(sbuf)) + if (um->type == MODE_PARAM && sep.GetToken(sbuf)) this->SetMode(bi, um, sbuf); else this->SetMode(bi, um); @@ -766,7 +684,7 @@ void User::SetModesInternal(const char *umodes, ...) if (add) { - if (um->Type == MODE_PARAM && sep.GetToken(sbuf)) + if (um->type == MODE_PARAM && sep.GetToken(sbuf)) this->SetModeInternal(um, sbuf); else this->SetModeInternal(um); @@ -774,13 +692,13 @@ void User::SetModesInternal(const char *umodes, ...) else this->RemoveModeInternal(um); - switch (um->Name) + switch (um->name) { case UMODE_OPER: if (add) - ++opcnt; + ++OperCount; else - --opcnt; + --OperCount; break; case UMODE_CLOAK: case UMODE_VHOST: @@ -803,18 +721,12 @@ Anope::string User::GetModes() const UserMode *um = ModeManager::FindUserModeByName(static_cast<UserModeName>(i)); if (um == NULL) continue; - ret += um->ModeChar; + ret += um->mchar; } return ret; } -/** Find the channel container for Channel c that the user is on - * This is preferred over using FindUser in Channel, as there are usually more users in a channel - * than channels a user is in - * @param c The channel - * @return The channel container, or NULL - */ ChannelContainer *User::FindChannel(const Channel *c) const { for (UChannelList::const_iterator it = this->chans.begin(), it_end = this->chans.end(); it != it_end; ++it) @@ -823,9 +735,6 @@ ChannelContainer *User::FindChannel(const Channel *c) const return NULL; } -/** Check if the user is protected from kicks and negative mode changes - * @return true or false - */ bool User::IsProtected() const { if (this->HasMode(UMODE_PROTECTED) || this->HasMode(UMODE_GOD)) @@ -839,14 +748,14 @@ 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 + ")"; - ircdproto->SendSVSKill(findbot(source), this, "%s", real_reason.c_str()); + IRCD->SendSVSKill(BotInfo::Find(source), this, "%s", real_reason.c_str()); } void User::KillInternal(const Anope::string &source, const Anope::string &reason) { Log(this, "killed") << "was killed by " << source << " (Reason: " << reason << ")"; - NickAlias *na = findnick(this->nick); + NickAlias *na = NickAlias::Find(this->nick); if (na && !na->nc->HasFlag(NI_SUSPENDED) && (this->IsRecognized() || this->IsIdentified(true))) { na->last_seen = Anope::CurTime; @@ -856,61 +765,12 @@ void User::KillInternal(const Anope::string &source, const Anope::string &reason delete this; } -User *finduser(const Anope::string &nick) -{ - if (isdigit(nick[0]) && ircdproto->RequiresID) - { - user_map::iterator it = UserListByUID.find(nick); - if (it != UserListByUID.end()) - return it->second; - } - else - { - user_map::iterator it = UserListByNick.find(nick); - if (it != UserListByNick.end()) - return it->second; - } - - return NULL; -} - -bool matches_list(Channel *c, User *user, ChannelModeName mode) -{ - if (!c || !c->HasMode(mode)) - return false; - - - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = c->GetModeList(mode); - for (; modes.first != modes.second; ++modes.first) - { - Entry e(mode, modes.first->second); - if (e.Matches(user)) - return true; - } - - return false; -} - -/*************************************************************************/ - -/* Given a user, return a mask that will most likely match any address the - * user will have from that location. For IP addresses, wildcards the - * appropriate subnet mask (e.g. 35.1.1.1 -> 35.*; 128.2.1.1 -> 128.2.*); - * for named addresses, wildcards the leftmost part of the name unless the - * name only contains two parts. If the username begins with a ~, delete - * it. - */ - -Anope::string create_mask(User *u) +Anope::string User::Mask() const { Anope::string mask; - Anope::string mident = u->GetIdent(); - Anope::string mhost = u->GetDisplayedHost(); + Anope::string mident = this->GetIdent(); + Anope::string mhost = this->GetDisplayedHost(); - /* Get us a buffer the size of the username plus hostname. The result - * will never be longer than this (and will often be shorter), thus we - * can use strcpy() and sprintf() safely. - */ if (mident[0] == '~') mask = "*" + mident + "@"; else @@ -930,6 +790,43 @@ Anope::string create_mask(User *u) else mask += mhost; } + return mask; } +bool User::BadPassword() +{ + if (!Config->BadPassLimit) + return false; + + if (Config->BadPassTimeout > 0 && this->invalid_pw_time > 0 && this->invalid_pw_time < Anope::CurTime - Config->BadPassTimeout) + this->invalid_pw_count = 0; + ++this->invalid_pw_count; + this->invalid_pw_time = Anope::CurTime; + if (this->invalid_pw_count >= Config->BadPassLimit) + { + this->Kill(Config->ServerName, "Too many invalid passwords"); + return true; + } + + return false; +} + +User* User::Find(const Anope::string &name, bool nick_only) +{ + if (!nick_only && isdigit(name[0]) && IRCD->RequiresID) + { + user_map::iterator it = UserListByUID.find(name); + if (it != UserListByUID.end()) + return it->second; + } + else + { + user_map::iterator it = UserListByNick.find(name); + if (it != UserListByNick.end()) + return it->second; + } + + return NULL; +} + diff --git a/src/win32/windows.cpp b/src/win32/windows.cpp index 785a38969..f24382f3f 100644 --- a/src/win32/windows.cpp +++ b/src/win32/windows.cpp @@ -43,7 +43,7 @@ static WSADATA wsa; void OnStartup() { if (WSAStartup(MAKEWORD(2, 0), &wsa)) - throw FatalException("Failed to initialize WinSock library"); + throw CoreException("Failed to initialize WinSock library"); } void OnShutdown() diff --git a/src/xline.cpp b/src/xline.cpp new file mode 100644 index 000000000..4ac6581a1 --- /dev/null +++ b/src/xline.cpp @@ -0,0 +1,425 @@ +/* XLine functions. + * + * (C) 2003-2012 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. + * + */ + +#include "services.h" +#include "modules.h" +#include "xline.h" +#include "users.h" +#include "sockets.h" +#include "regexpr.h" +#include "config.h" +#include "commands.h" + +/* List of XLine managers we check users against in XLineManager::CheckAll */ +std::list<XLineManager *> XLineManager::XLineManagers; +Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManager::XLinesByUID("XLine"); + +void XLine::InitRegex() +{ + if (!Config->RegexEngine.empty() && this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/') + { + Anope::string stripped_mask = this->mask.substr(1, this->mask.length() - 2); + + ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); + if (provider) + { + try + { + this->regex = provider->Compile(stripped_mask); + } + catch (const RegexException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } + } + } +} + +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) +{ + regex = NULL; + manager = NULL; + + this->InitRegex(); +} + +XLine::XLine(const Anope::string &ma, const Anope::string &b, const time_t ex, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(b), created(Anope::CurTime), expires(ex), reason(r), id(uid) +{ + regex = NULL; + manager = NULL; + + this->InitRegex(); +} + +XLine::~XLine() +{ + delete regex; +} + +Anope::string XLine::GetNick() const +{ + size_t nick_t = this->mask.find('!'); + + if (nick_t == Anope::string::npos) + return ""; + + return this->mask.substr(0, nick_t); +} + +Anope::string XLine::GetUser() const +{ + size_t user_t = this->mask.find('!'), host_t = this->mask.find('@'); + + if (host_t != Anope::string::npos) + { + if (user_t != Anope::string::npos && host_t > user_t) + return this->mask.substr(user_t + 1, host_t - user_t - 1); + else + return this->mask.substr(0, host_t); + } + else + return ""; +} + +Anope::string XLine::GetHost() const +{ + size_t host_t = this->mask.find('@'), real_t = this->mask.find('#'); + + if (host_t != Anope::string::npos) + { + if (real_t != Anope::string::npos && real_t > host_t) + return this->mask.substr(host_t + 1, real_t - host_t - 1); + else + return this->mask.substr(host_t + 1); + } + else + return ""; +} + +Anope::string XLine::GetReal() const +{ + size_t real_t = this->mask.find('#'); + + if (real_t != Anope::string::npos) + return this->mask.substr(real_t + 1); + else + return ""; +} + +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; +} + +bool XLine::HasNickOrReal() const +{ + bool r = this->GetNick().find_first_not_of("?*") != Anope::string::npos; + r = r || this->GetReal().find_first_not_of("?*") != Anope::string::npos; + return r; +} + +bool XLine::IsRegex() const +{ + return !this->mask.empty() && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/'; +} + +Serialize::Data XLine::Serialize() const +{ + Serialize::Data data; + + data["mask"] << this->mask; + data["by"] << this->by; + data["created"] << this->created; + data["expires"] << this->expires; + data["reason"] << this->reason; + data["uid"] << this->id; + if (this->manager) + data["manager"] << this->manager->name; + + return data; +} + +Serializable* XLine::Unserialize(Serializable *obj, Serialize::Data &data) +{ + ServiceReference<XLineManager> xlm("XLineManager", data["manager"].astr()); + if (!xlm) + return NULL; + + XLine *xl; + if (obj) + { + xl = anope_dynamic_static_cast<XLine *>(obj); + data["mask"] >> xl->mask; + data["by"] >> xl->by; + data["reason"] >> xl->reason; + data["uid"] >> xl->id; + + if (xlm != xl->manager) + { + xl->manager->DelXLine(xl); + xlm->AddXLine(xl); + } + } + else + { + time_t expires; + data["expires"] >> expires; + xl = new XLine(data["mask"].astr(), data["by"].astr(), expires, data["reason"].astr(), data["uid"].astr()); + xlm->AddXLine(xl); + } + + data["created"] >> xl->created; + xl->manager = xlm; + + return xl; +} + +void XLineManager::RegisterXLineManager(XLineManager *xlm) +{ + XLineManagers.push_back(xlm); +} + +void XLineManager::UnregisterXLineManager(XLineManager *xlm) +{ + std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm); + + if (it != XLineManagers.end()) + XLineManagers.erase(it); +} + +void XLineManager::CheckAll(User *u) +{ + for (std::list<XLineManager *>::iterator it = XLineManagers.begin(), it_end = XLineManagers.end(); it != it_end; ++it) + { + XLineManager *xlm = *it; + + XLine *x = xlm->CheckAllXLines(u); + + if (x) + { + xlm->OnMatch(u, x); + break; + } + } +} + +Anope::string XLineManager::GenerateUID() +{ + Anope::string id; + int count = 0; + while (id.empty() || XLinesByUID->count(id) > 0) + { + if (++count > 10) + { + id.clear(); + Log(LOG_DEBUG) << "Unable to generate XLine UID"; + break; + } + + for (int i = 0; i < 10; ++i) + { + char c; + do + c = (rand() % 75) + 48; + while (!isupper(c) && !isdigit(c)); + id += c; + } + } + + return id; +} + +XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service(creator, "XLineManager", xname), type(t), xlines("XLine") +{ +} + +XLineManager::~XLineManager() +{ + this->Clear(); +} + +const char &XLineManager::Type() +{ + return this->type; +} + +size_t XLineManager::GetCount() const +{ + return this->xlines->size(); +} + +const std::vector<XLine *> &XLineManager::GetList() const +{ + return this->xlines; +} + +void XLineManager::AddXLine(XLine *x) +{ + if (!x->id.empty()) + XLinesByUID->insert(std::make_pair(x->id, x)); + this->xlines->push_back(x); + x->manager = this; +} + +bool XLineManager::DelXLine(XLine *x) +{ + std::vector<XLine *>::iterator it = std::find(this->xlines->begin(), this->xlines->end(), x); + + if (!x->id.empty()) + { + std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->find(x->id), it3 = XLinesByUID->upper_bound(x->id); + for (; it2 != XLinesByUID->end() && it2 != it3; ++it2) + if (it2->second == x) + { + XLinesByUID->erase(it2); + break; + } + } + + if (it != this->xlines->end()) + { + this->SendDel(x); + + x->Destroy(); + this->xlines->erase(it); + + return true; + } + + return false; +} + +XLine* XLineManager::GetEntry(unsigned index) +{ + if (index >= this->xlines->size()) + return NULL; + + XLine *x = this->xlines->at(index); + x->QueueUpdate(); + return x; +} + +void XLineManager::Clear() +{ + for (unsigned i = 0; i < this->xlines->size(); ++i) + { + XLine *x = this->xlines->at(i); + if (!x->id.empty()) + XLinesByUID->erase(x->id); + x->Destroy(); + } + this->xlines->clear(); +} + +bool XLineManager::CanAdd(CommandSource &source, const Anope::string &mask, time_t expires, const Anope::string &reason) +{ + for (unsigned i = this->GetCount(); i > 0; --i) + { + XLine *x = this->GetEntry(i - 1); + + if (x->mask.equals_ci(mask)) + { + if (!x->expires || x->expires >= expires) + { + if (x->reason != reason) + { + x->reason = reason; + source.Reply(_("Reason for %s updated."), x->mask.c_str()); + } + else + source.Reply(_("%s already exists."), mask.c_str()); + } + else + { + x->expires = expires; + if (x->reason != reason) + { + x->reason = reason; + source.Reply(_("Expiry and reason updated for %s."), x->mask.c_str()); + } + else + source.Reply(_("Expiry for %s updated."), x->mask.c_str()); + } + + return false; + } + else if (Anope::Match(mask, x->mask) && (!x->expires || x->expires >= expires)) + { + source.Reply(_("%s is already covered by %s."), mask.c_str(), x->mask.c_str()); + return false; + } + else if (Anope::Match(x->mask, mask) && (!expires || x->expires <= expires)) + { + source.Reply(_("Removing %s because %s covers it."), x->mask.c_str(), mask.c_str()); + this->DelXLine(x); + } + } + + return true; +} + +XLine* XLineManager::HasEntry(const Anope::string &mask) +{ + std::multimap<Anope::string, XLine *, ci::less>::iterator it = XLinesByUID->find(mask); + if (it != XLinesByUID->end()) + for (std::multimap<Anope::string, XLine *, ci::less>::iterator it2 = XLinesByUID->upper_bound(mask); it != it2; ++it) + if (it->second->manager == NULL || it->second->manager == this) + { + it->second->QueueUpdate(); + return it->second; + } + for (unsigned i = 0, end = this->xlines->size(); i < end; ++i) + { + XLine *x = this->xlines->at(i); + + if (x->mask.equals_ci(mask)) + { + x->QueueUpdate(); + return x; + } + } + + return NULL; +} + +XLine *XLineManager::CheckAllXLines(User *u) +{ + for (unsigned i = this->xlines->size(); i > 0; --i) + { + XLine *x = this->xlines->at(i - 1); + + if (x->expires && x->expires < Anope::CurTime) + { + this->OnExpire(x); + this->DelXLine(x); + continue; + } + + if (this->Check(u, x)) + { + this->OnMatch(u, x); + return x; + } + } + + return NULL; +} + +void XLineManager::OnExpire(const XLine *x) +{ +} + |