From d33a0f75a5c0c584fbb7cc0076da36d494f39494 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 22 Nov 2012 00:50:33 -0500 Subject: Pretty large coding style cleanup, in source doc cleanup, and allow protocol mods to depend on each other --- src/modes.cpp | 594 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 361 insertions(+), 233 deletions(-) (limited to 'src/modes.cpp') 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 * * 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 ModeManager::ChannelModes; std::vector 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::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(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::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::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(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 > *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 ModeManager::BuildModeStrings(StackerInfo *info) { std::list ret; @@ -384,7 +294,7 @@ std::list 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 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 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 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 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(UMODE_END + ++GenericUserModes); - Log() << "ModeManager: Added generic support for user mode " << um->ModeChar; + um->name = static_cast(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(CMODE_END + ++GenericChannelModes); - Log() << "ModeManager: Added generic support for channel mode " << cm->ModeChar; + cm->name = static_cast(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(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(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 ModeStrings = BuildModeStrings(s); for (std::list::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 ModeStrings = BuildModeStrings(s); for (std::list::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::const_iterator it = UserStackerObjects.begin(), it_end = UserStackerObjects.end(); it != it_end;) + { + StackerInfo *si = it->second; + ++it; + + for (std::list >::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 >::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::const_iterator it = ChannelStackerObjects.begin(), it_end = ChannelStackerObjects.end(); it != it_end;) + { + StackerInfo *si = it->second; + ++it; + + for (std::list >::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 >::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(cidr_range); + this->SetFlag(ENTRYTYPE_CIDR); + Log(LOG_DEBUG) << "Ban " << _realhost << " has cidr " << static_cast(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(cm); + if (cml->Matches(u, this)) + ret = true; + } + + return ret; +} + -- cgit