diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/base64.cpp | 2 | ||||
| -rw-r--r-- | src/bots.cpp | 40 | ||||
| -rw-r--r-- | src/channels.cpp | 48 | ||||
| -rw-r--r-- | src/config.cpp | 17 | ||||
| -rw-r--r-- | src/init.cpp | 2 | ||||
| -rw-r--r-- | src/language.cpp | 7 | ||||
| -rw-r--r-- | src/logger.cpp | 62 | ||||
| -rw-r--r-- | src/messages.cpp | 19 | ||||
| -rw-r--r-- | src/modes.cpp | 194 | ||||
| -rw-r--r-- | src/modulemanager.cpp | 34 | ||||
| -rw-r--r-- | src/process.cpp | 71 | ||||
| -rw-r--r-- | src/protocol.cpp | 58 | ||||
| -rw-r--r-- | src/servers.cpp | 49 | ||||
| -rw-r--r-- | src/sockets.cpp | 15 | ||||
| -rw-r--r-- | src/uplink.cpp | 31 | ||||
| -rw-r--r-- | src/users.cpp | 25 | ||||
| -rw-r--r-- | src/win32/anope_windows.h | 2 | ||||
| -rw-r--r-- | src/win32/dl/dl.cpp | 3 | ||||
| -rw-r--r-- | src/win32/windows.cpp | 17 | ||||
| -rw-r--r-- | src/xline.cpp | 97 |
21 files changed, 503 insertions, 299 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8dadd2122..7f43fcd30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,23 +43,20 @@ if(MSVC) set_source_files_properties(win32/win32_memory.cpp PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}") add_library(win32_memory STATIC win32/win32_memory.cpp) set(WIN32_MEMORY win32_memory) + set(EXTRA_LDFLAGS "/OPT:NOREF") # https://sourceware.org/bugzilla/show_bug.cgi?id=12633 else(MSVC) set(WIN32_MEMORY) endif(MSVC) # Generate the Anope executable and set it's linker flags, also set it to export it's symbols even though it's not a module add_executable(${PROGRAM_NAME} ${SRC_SRCS}) -set_target_properties(${PROGRAM_NAME} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS}" ENABLE_EXPORTS ON INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) +set_target_properties(${PROGRAM_NAME} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS} ${EXTRA_LDFLAGS}" ENABLE_EXPORTS ON INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) # On Windows, also link Anope to the wsock32 and Ws2_32 library, as well as set the version if(WIN32) target_link_libraries(${PROGRAM_NAME} wsock32 Ws2_32 ${LINK_LIBS} ${GETTEXT_LIBRARIES} ${WIN32_MEMORY}) set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") else(WIN32) - if(GETTEXT_LIBRARIES) - target_link_libraries(${PROGRAM_NAME} ${LINK_LIBS} ${GETTEXT_LIBRARIES}) - else(GETTEXT_LIBRARIES) - target_link_libraries(${PROGRAM_NAME} ${LINK_LIBS}) - endif(GETTEXT_LIBRARIES) + target_link_libraries(${PROGRAM_NAME} ${LINK_LIBS} ${GETTEXT_LIBRARIES}) endif(WIN32) # Building the Anope executable requires the version.h header to be generated add_dependencies(${PROGRAM_NAME} headers) diff --git a/src/base64.cpp b/src/base64.cpp index d4d9ff43e..c00527d42 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -82,7 +82,7 @@ static const char Pad64 = '='; void Anope::B64Encode(const Anope::string &src, Anope::string &target) { size_t src_pos = 0, src_len = src.length(); - unsigned char input[3]; + unsigned char input[3] = { '\0', '\0', '\0' }; target.clear(); diff --git a/src/bots.cpp b/src/bots.cpp index 52773dd72..6f5c66388 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -22,7 +22,7 @@ Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo"); -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(), NULL), Serializable("BotInfo"), channels("ChanServ::Channel"), 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, "", IRCD ? IRCD->UID_Retrieve() : "", NULL), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes) { this->lastmsg = this->created = Anope::CurTime; this->introduced = false; @@ -56,6 +56,7 @@ BotInfo::~BotInfo() if (Me && Me->IsSynced()) { IRCD->SendQuit(this, ""); + Event::OnUserQuit(&Event::UserQuit::OnUserQuit, this, ""); this->introduced = false; XLine x(this->nick); IRCD->SendSQLineDel(&x); @@ -96,7 +97,7 @@ Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data) BotInfo *bi; if (obj) bi = anope_dynamic_static_cast<BotInfo *>(obj); - else if (!(bi = BotInfo::Find(nick))) + else if (!(bi = BotInfo::Find(nick, true))) bi = new BotInfo(nick, user, host, realname); data["created"] >> bi->created; @@ -118,7 +119,7 @@ void BotInfo::GenerateUID() UserListByUID.erase(this->uid); } - this->uid = Servers::TS6_UID_Retrieve(); + this->uid = IRCD->UID_Retrieve(); (*BotListByUID)[this->uid] = this; UserListByUID[this->uid] = this; } @@ -213,11 +214,16 @@ void BotInfo::Part(Channel *c, const Anope::string &reason) if (c->FindUser(this) == NULL) return; + Event::OnPrePartChannel(&Event::PrePartChannel::OnPrePartChannel, this, c); + IRCD->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : ""); - Event::OnPartChannel(&Event::PartChannel::OnPartChannel, this, c, c->name, reason); + Anope::string cname = c->name; + Reference<Channel> cref = c; c->DeleteUser(this); + + Event::OnPartChannel(&Event::PartChannel::OnPartChannel, this, cref, cname, reason); } void BotInfo::OnMessage(User *u, const Anope::string &message) @@ -262,22 +268,28 @@ CommandInfo *BotInfo::FindCommand(const Anope::string &service) BotInfo* BotInfo::Find(const Anope::string &nick, bool nick_only) { - BotInfo *bi = NULL; - if (!nick_only && isdigit(nick[0]) && IRCD->RequiresID) + if (!nick_only && IRCD != NULL && IRCD->RequiresID) { botinfo_map::iterator it = BotListByUID->find(nick); if (it != BotListByUID->end()) - bi = it->second; + { + BotInfo *bi = it->second; + bi->QueueUpdate(); + return bi; + } + + if (IRCD->AmbiguousID) + return NULL; } - else + + botinfo_map::iterator it = BotListByNick->find(nick); + if (it != BotListByNick->end()) { - botinfo_map::iterator it = BotListByNick->find(nick); - if (it != BotListByNick->end()) - bi = it->second; + BotInfo *bi = it->second; + bi->QueueUpdate(); + return bi; } - if (bi) - bi->QueueUpdate(); - return bi; + return NULL; } diff --git a/src/channels.cpp b/src/channels.cpp index aff45fcd6..2d01ad703 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -243,11 +243,14 @@ std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> Channel::Get return std::make_pair(it, it_end); } -void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) +void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) { - if (!cm) + if (!ocm) return; + Anope::string param = oparam; + ChannelMode *cm = ocm->Unwrap(param); + EventReturn MOD_RESULT; /* Setting v/h/o/a/q etc */ @@ -310,11 +313,14 @@ void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *cm, cons this->CheckModes(); } -void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) +void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *ocm, const Anope::string &oparam, bool enforce_mlock) { - if (!cm) + if (!ocm) return; + Anope::string param = oparam; + ChannelMode *cm = ocm->Unwrap(param); + EventReturn MOD_RESULT; /* Setting v/h/o/a/q etc */ @@ -388,6 +394,7 @@ void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *cm, c void Channel::SetMode(User *bi, ChannelMode *cm, const Anope::string ¶m, bool enforce_mlock) { + Anope::string wparam = param; if (!cm) return; /* Don't set modes already set */ @@ -396,11 +403,11 @@ void Channel::SetMode(User *bi, ChannelMode *cm, const Anope::string ¶m, boo else if (cm->type == MODE_PARAM) { ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); - if (!cmp->IsValid(param)) + if (!cmp->IsValid(wparam)) return; Anope::string cparam; - if (GetParam(cm->name, cparam) && cparam.equals_cs(param)) + if (GetParam(cm->name, cparam) && cparam.equals_cs(wparam)) return; } else if (cm->type == MODE_STATUS) @@ -412,7 +419,11 @@ void Channel::SetMode(User *bi, ChannelMode *cm, const Anope::string ¶m, boo else if (cm->type == MODE_LIST) { ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm); - if (this->HasMode(cm->name, param) || !cml->IsValid(param)) + + if (!cml->IsValid(wparam)) + return; + + if (this->HasMode(cm->name, wparam)) return; } @@ -427,8 +438,10 @@ void Channel::SetMode(User *bi, ChannelMode *cm, const Anope::string ¶m, boo this->chanserv_modecount++; } - ModeManager::StackerAdd(bi, this, cm, true, param); - SetModeInternal(bi, cm, param, enforce_mlock); + ChannelMode *wcm = cm->Wrap(wparam); + + ModeManager::StackerAdd(bi, this, wcm, true, wparam); + SetModeInternal(bi, wcm, wparam, enforce_mlock); } void Channel::SetMode(User *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock) @@ -477,8 +490,11 @@ void Channel::RemoveMode(User *bi, ChannelMode *cm, const Anope::string ¶m, this->chanserv_modecount++; } - ModeManager::StackerAdd(bi, this, cm, false, realparam); - RemoveModeInternal(bi, cm, realparam, enforce_mlock); + Anope::string wparam = realparam; + ChannelMode *wcm = cm->Wrap(wparam); + + ModeManager::StackerAdd(bi, this, wcm, false, wparam); + RemoveModeInternal(bi, wcm, wparam, enforce_mlock); } void Channel::RemoveMode(User *bi, const Anope::string &mname, const Anope::string ¶m, bool enforce_mlock) @@ -843,21 +859,21 @@ void Channel::SetCorrectModes(User *user, bool give_modes) } } -bool Channel::Unban(User *u, bool full) +bool Channel::Unban(User *u, const Anope::string &mode, bool full) { - if (!this->HasMode("BAN")) + if (!this->HasMode(mode)) return false; bool ret = false; - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = this->GetModeList("BAN"); + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = this->GetModeList(mode); for (; bans.first != bans.second;) { - Entry ban("BAN", bans.first->second); + Entry ban(mode, bans.first->second); ++bans.first; if (ban.Matches(u, full)) { - this->RemoveMode(NULL, "BAN", ban.GetMask()); + this->RemoveMode(NULL, mode, ban.GetMask()); ret = true; } } diff --git a/src/config.cpp b/src/config.cpp index d14f1089f..d0575a88c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -396,7 +396,7 @@ Conf::Conf() : Block("") LogInfo l(logage, rawio, debug); - l.bot = BotInfo::Find(log->Get<const Anope::string>("bot", "Global")); + l.bot = BotInfo::Find(log->Get<const Anope::string>("bot", "Global"), true); spacesepstream(log->Get<const Anope::string>("target")).GetTokens(l.targets); spacesepstream(log->Get<const Anope::string>("source")).GetTokens(l.sources); spacesepstream(log->Get<const Anope::string>("admin")).GetTokens(l.admin); @@ -638,6 +638,21 @@ BotInfo *Conf::GetClient(const Anope::string &cname) return GetClient(cname); } +Block *Conf::GetCommand(CommandSource &source) +{ + const Anope::string &block_name = source.c ? "fantasy" : "command"; + + for (std::pair<block_map::iterator, block_map::iterator> iters = blocks.equal_range(block_name); iters.first != iters.second; ++iters.first) + { + Block *b = &iters.first->second; + + if (b->Get<Anope::string>("name") == source.command) + return b; + } + + return NULL; +} + File::File(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL) { } diff --git a/src/init.cpp b/src/init.cpp index 9b6b42c86..04b02cc06 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -528,7 +528,7 @@ void Anope::Init(int ac, char **av) /* Auto assign sid if applicable */ if (IRCD->RequiresID) { - Anope::string sid = Servers::TS6_SID_Retrieve(); + Anope::string sid = IRCD->SID_Retrieve(); if (Me->GetSID() == Me->GetName()) Me->SetSID(sid); for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it) diff --git a/src/language.cpp b/src/language.cpp index feaa0b242..675605159 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -77,9 +77,6 @@ const char *Language::Translate(const NickServ::Account *nc, const char *string) #if GETTEXT_FOUND -/* 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 *Language::Translate(const char *lang, const char *string) { if (!string || !*string) @@ -88,10 +85,6 @@ const char *Language::Translate(const char *lang, const char *string) if (!lang || !*lang) lang = Config->DefLanguage.c_str(); - if (Anope::string(lang) == "en") - return string; - - ++_nl_msg_cat_cntr; #ifdef _WIN32 SetThreadLocale(MAKELCID(MAKELANGID(WindowsGetLanguage(lang), SUBLANG_DEFAULT), SORT_DEFAULT)); #else diff --git a/src/logger.cpp b/src/logger.cpp index 86141ed8a..9dad74a67 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -93,7 +93,7 @@ Log::Log(LogType t, CommandSource &src, Command *_c, ChanServ::Channel *_ci) : u size_t sl = c->name.find('/'); this->bi = NULL; if (sl != Anope::string::npos) - this->bi = BotInfo::Find(c->name.substr(0, sl)); + this->bi = BotInfo::Find(c->name.substr(0, sl), true); this->category = c->name; } @@ -140,6 +140,27 @@ Log::~Log() Config->LogInfos[i].ProcessMessage(this); } +Anope::string Log::FormatSource() const +{ + if (u) + if (nc) + return this->u->GetMask() + " (" + this->nc->display + ")"; + else + return this->u->GetMask(); + else if (nc) + return nc->display; + return ""; +} + +Anope::string Log::FormatCommand() const +{ + Anope::string buffer = FormatSource() + " used " + (source != NULL && !source->command.empty() ? source->command : this->c->name) + " "; + if (this->ci) + buffer += "on " + this->ci->name + " "; + + return buffer; +} + Anope::string Log::BuildPrefix() const { Anope::string buffer; @@ -150,44 +171,21 @@ Anope::string Log::BuildPrefix() const { if (!this->c) break; - buffer += "ADMIN: "; - Anope::string cname = source != NULL && !source->command.empty() ? source->command : this->c->name; - if (this->u) - buffer += this->u->GetMask() + " used " + cname + " "; - else if (this->nc) - buffer += this->nc->display + " used " + cname + " "; - if (this->ci) - buffer += "on " + this->ci->name + " "; + buffer += "ADMIN: " + FormatCommand(); break; } case LOG_OVERRIDE: { if (!this->c) break; - buffer += "OVERRIDE: "; - Anope::string cname = source != NULL && !source->command.empty() ? source->command : this->c->name; - if (this->u) - buffer += this->u->GetMask() + " used " + cname + " "; - else if (this->nc) - buffer += this->nc->display + " used " + cname + " "; - if (this->ci) - buffer += "on " + this->ci->name + " "; + buffer += "OVERRIDE: " + FormatCommand(); break; } case LOG_COMMAND: { if (!this->c) break; - buffer += "COMMAND: "; - Anope::string cname = source != NULL && !source->command.empty() ? source->command : this->c->name; - if (this->u) - buffer += this->u->GetMask() + " used " + cname + " "; - else if (this->source) - buffer += this->source->GetNick() + " used " + cname + " "; - else if (this->nc) - buffer += this->nc->display + " used " + cname + " "; - if (this->ci) - buffer += "on " + this->ci->name + " "; + buffer += "COMMAND: " + FormatCommand(); break; } case LOG_CHANNEL: @@ -195,16 +193,16 @@ Anope::string Log::BuildPrefix() const if (!this->chan) break; buffer += "CHANNEL: "; - if (this->u) - buffer += this->u->GetMask() + " " + this->category + " " + this->chan->name + " "; - else - buffer += this->category + " " + this->chan->name + " "; + Anope::string src = FormatSource(); + if (!src.empty()) + buffer += src + " "; + buffer += this->category + " " + this->chan->name + " "; break; } case LOG_USER: { if (this->u) - buffer += "USERS: " + this->u->GetMask() + " "; + buffer += "USERS: " + FormatSource() + " "; break; } case LOG_SERVER: diff --git a/src/messages.cpp b/src/messages.cpp index 8ba37498e..2501ac047 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -130,6 +130,9 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co User *u = it->second; keep_their_modes = ts <= c->creation_time; // OnJoinChannel can call modules which can modify this channel's ts + if (c->FindUser(u)) + continue; + /* Add the user to the channel */ c->JoinUser(u, keep_their_modes ? &status : NULL); @@ -157,8 +160,6 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co if (c->CheckDelete()) delete c; - else - c->CheckModes(); } } } @@ -209,19 +210,23 @@ void Kill::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) void Message::Mode::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { + Anope::string buf; + for (unsigned i = 1; i < params.size(); ++i) + buf += " " + params[i]; + if (IRCD->IsChannelValid(params[0])) { Channel *c = Channel::Find(params[0]); if (c) - c->SetModesInternal(source, params[1], 0); + c->SetModesInternal(source, buf.substr(1), 0); } else { User *u = User::Find(params[0]); if (u) - u->SetModesInternal(source, "%s", params[1].c_str()); + u->SetModesInternal(source, "%s", buf.substr(1).c_str()); } } @@ -314,10 +319,12 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶m * us, and strip it off. */ Anope::string botname = receiver; size_t s = receiver.find('@'); + bool nick_only = false; if (s != Anope::string::npos) { Anope::string servername(receiver.begin() + s + 1, receiver.end()); botname = botname.substr(0, s); + nick_only = true; if (!servername.equals_ci(Me->GetName())) return; } @@ -331,7 +338,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶m return; } - BotInfo *bi = BotInfo::Find(botname); + BotInfo *bi = BotInfo::Find(botname, nick_only); if (bi) { @@ -468,7 +475,7 @@ void Whois::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) if (u && u->server == Me) { - const BotInfo *bi = BotInfo::Find(u->nick); + const BotInfo *bi = BotInfo::Find(u->GetUID()); IRCD->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str()); if (bi) IRCD->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str()); diff --git a/src/modes.cpp b/src/modes.cpp index cecab9d11..c0bd79cc7 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -23,9 +23,15 @@ struct StackerInfo; static std::map<User *, StackerInfo *> UserStackerObjects; static std::map<Channel *, StackerInfo *> ChannelStackerObjects; -/* List of all modes Anope knows about */ -std::vector<ChannelMode *> ModeManager::ChannelModes; -std::vector<UserMode *> ModeManager::UserModes; +/* Array of all modes Anope knows about.*/ +static std::vector<ChannelMode *> ChannelModes; +static std::vector<UserMode *> UserModes; + +/* Modes are in this array are at position + * modechar. Additionally, status modes are in this array (again) at statuschar. + */ +static std::vector<ChannelMode *> ChannelModesIdx; +static std::vector<UserMode *> UserModesIdx; static std::map<Anope::string, ChannelMode *> ChannelModesByName; static std::map<Anope::string, UserMode *> UserModesByName; @@ -144,11 +150,40 @@ bool ChannelMode::CanSet(User *u) const return MOD_RESULT != EVENT_STOP; } +ChannelMode *ChannelMode::Wrap(Anope::string ¶m) +{ + return this; +} + +ChannelMode *ChannelMode::Unwrap(Anope::string ¶m) +{ + for (unsigned i = 0; i < listeners.size(); ++i) + { + ChannelMode *cm = listeners[i]->Unwrap(this, param); + if (cm != this) + return cm; + } + + return this; +} + +ChannelMode *ChannelMode::Unwrap(ChannelMode *, Anope::string ¶m) +{ + throw CoreException("Unwrap in channel mode"); +} + ChannelModeList::ChannelModeList(const Anope::string &cm, char mch) : ChannelMode(cm, mch) { this->type = MODE_LIST; } +bool ChannelModeList::IsValid(Anope::string &mask) const +{ + if (name == "BAN" || name == "EXCEPT" || name == "INVITEOVERRIDE") + mask = IRCD->NormalizeMask(mask); + return true; +} + ChannelModeParam::ChannelModeParam(const Anope::string &cm, char mch, bool ma) : ChannelMode(cm, mch), minus_no_arg(ma) { this->type = MODE_PARAM; @@ -159,6 +194,42 @@ ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, this->type = MODE_STATUS; } +template<typename T> +ChannelModeVirtual<T>::ChannelModeVirtual(const Anope::string &mname, const Anope::string &basename) : T(mname, 0) + , base(basename) +{ + basech = ModeManager::FindChannelModeByName(base); + if (basech) + basech->listeners.push_back(this); +} + +template<typename T> +ChannelModeVirtual<T>::~ChannelModeVirtual() +{ + if (basech) + { + std::vector<ChannelMode *>::iterator it = std::find(basech->listeners.begin(), basech->listeners.end(), this); + if (it != basech->listeners.end()) + basech->listeners.erase(it); + } +} + +template<typename T> +ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string ¶m) +{ + if (basech == NULL) + { + basech = ModeManager::FindChannelModeByName(base); + if (basech) + basech->listeners.push_back(this); + } + + return basech; +} + +template class ChannelModeVirtual<ChannelMode>; +template class ChannelModeVirtual<ChannelModeList>; + bool UserModeOperOnly::CanSet(User *u) const { return u && u->HasMode("OPER"); @@ -169,7 +240,7 @@ bool UserModeNoone::CanSet(User *u) const return false; } -bool ChannelModeKey::IsValid(const Anope::string &value) const +bool ChannelModeKey::IsValid(Anope::string &value) const { if (!value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos) return true; @@ -324,6 +395,9 @@ bool ModeManager::AddUserMode(UserMode *um) if (ModeManager::FindUserModeByChar(um->mchar) != NULL) return false; + if (ModeManager::FindUserModeByName(um->name) != NULL) + return false; + if (um->name.empty()) { um->name = stringify(++GenericUserModes); @@ -331,12 +405,14 @@ bool ModeManager::AddUserMode(UserMode *um) } unsigned want = um->mchar; - if (want >= ModeManager::UserModes.size()) - ModeManager::UserModes.resize(want + 1); - ModeManager::UserModes[want] = um; + if (want >= UserModesIdx.size()) + UserModesIdx.resize(want + 1); + UserModesIdx[want] = um; UserModesByName[um->name] = um; + UserModes.push_back(um); + Event::OnUserModeAdd(&Event::UserModeAdd::OnUserModeAdd, um); return true; @@ -344,7 +420,9 @@ bool ModeManager::AddUserMode(UserMode *um) bool ModeManager::AddChannelMode(ChannelMode *cm) { - if (ModeManager::FindChannelModeByChar(cm->mchar) != NULL) + if (cm->mchar && ModeManager::FindChannelModeByChar(cm->mchar) != NULL) + return false; + if (ModeManager::FindChannelModeByName(cm->name) != NULL) return false; if (cm->name.empty()) @@ -353,24 +431,29 @@ bool ModeManager::AddChannelMode(ChannelMode *cm) Log() << "ModeManager: Added generic support for channel mode " << cm->mchar; } - unsigned want = cm->mchar; - if (want >= ModeManager::ChannelModes.size()) - ModeManager::ChannelModes.resize(want + 1); - ModeManager::ChannelModes[want] = cm; + if (cm->mchar) + { + unsigned want = cm->mchar; + if (want >= ChannelModesIdx.size()) + ChannelModesIdx.resize(want + 1); + ChannelModesIdx[want] = cm; + } if (cm->type == MODE_STATUS) { ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); - want = cms->symbol; - if (want >= ModeManager::ChannelModes.size()) - ModeManager::ChannelModes.resize(want + 1); - ModeManager::ChannelModes[want] = cms; + unsigned want = cms->symbol; + if (want >= ChannelModesIdx.size()) + ChannelModesIdx.resize(want + 1); + ChannelModesIdx[want] = cms; RebuildStatusModes(); } ChannelModesByName[cm->name] = cm; + ChannelModes.push_back(cm); + Event::OnChannelModeAdd(&Event::ChannelModeAdd::OnChannelModeAdd, cm); return true; @@ -382,16 +465,20 @@ void ModeManager::RemoveUserMode(UserMode *um) return; unsigned want = um->mchar; - if (want >= ModeManager::UserModes.size()) + if (want >= UserModesIdx.size()) return; - - if (ModeManager::UserModes[want] != um) + + if (UserModesIdx[want] != um) return; - - ModeManager::UserModes[want] = NULL; + + UserModesIdx[want] = NULL; UserModesByName.erase(um->name); + std::vector<UserMode *>::iterator it = std::find(UserModes.begin(), UserModes.end(), um); + if (it != UserModes.end()) + UserModes.erase(it); + StackerDel(um); } @@ -400,52 +487,59 @@ void ModeManager::RemoveChannelMode(ChannelMode *cm) if (!cm) return; - unsigned want = cm->mchar; - if (want >= ModeManager::ChannelModes.size()) - return; - - if (ModeManager::ChannelModes[want] != cm) - return; - - ModeManager::ChannelModes[want] = NULL; + if (cm->mchar) + { + unsigned want = cm->mchar; + if (want >= ChannelModesIdx.size()) + return; + + if (ChannelModesIdx[want] != cm) + return; + + ChannelModesIdx[want] = NULL; + } if (cm->type == MODE_STATUS) { ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); - want = cms->symbol; + unsigned want = cms->symbol; - if (want >= ModeManager::ChannelModes.size()) + if (want >= ChannelModesIdx.size()) return; - if (ModeManager::ChannelModes[want] != cm) + if (ChannelModesIdx[want] != cm) return; - ModeManager::ChannelModes[want] = NULL; + ChannelModesIdx[want] = NULL; RebuildStatusModes(); } ChannelModesByName.erase(cm->name); + std::vector<ChannelMode *>::iterator it = std::find(ChannelModes.begin(), ChannelModes.end(), cm); + if (it != ChannelModes.end()) + ChannelModes.erase(it); + StackerDel(cm); } ChannelMode *ModeManager::FindChannelModeByChar(char mode) { unsigned want = mode; - if (want >= ModeManager::ChannelModes.size()) + if (want >= ChannelModesIdx.size()) return NULL; - - return ModeManager::ChannelModes[want]; + + return ChannelModesIdx[want]; } UserMode *ModeManager::FindUserModeByChar(char mode) { unsigned want = mode; - if (want >= ModeManager::UserModes.size()) + if (want >= UserModesIdx.size()) return NULL; - - return ModeManager::UserModes[want]; + + return UserModesIdx[want]; } ChannelMode *ModeManager::FindChannelModeByName(const Anope::string &name) @@ -467,10 +561,10 @@ UserMode *ModeManager::FindUserModeByName(const Anope::string &name) char ModeManager::GetStatusChar(char value) { unsigned want = value; - if (want >= ModeManager::ChannelModes.size()) + if (want >= ChannelModesIdx.size()) return 0; - - ChannelMode *cm = ModeManager::ChannelModes[want]; + + ChannelMode *cm = ChannelModesIdx[want]; if (cm == NULL || cm->type != MODE_STATUS || cm->mchar == value) return 0; @@ -503,9 +597,9 @@ static struct StatusSort void ModeManager::RebuildStatusModes() { ChannelModesByStatus.clear(); - for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j) + for (unsigned j = 0; j < ChannelModesIdx.size(); ++j) { - ChannelMode *cm = ModeManager::GetChannelModes()[j]; + ChannelMode *cm = ChannelModesIdx[j]; if (cm && cm->type == MODE_STATUS && std::find(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), cm) == ChannelModesByStatus.end()) ChannelModesByStatus.push_back(anope_dynamic_static_cast<ChannelModeStatus *>(cm)); @@ -712,7 +806,7 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh this->host = cidr_ip; - Log(LOG_DEBUG) << "Ban " << this->mask << " has cidr " << this->cidr_len; + Log(LOG_DEBUG) << "Ban " << m << " has cidr " << this->cidr_len; } } catch (const ConvertException &) { } @@ -728,6 +822,14 @@ const Anope::string Entry::GetMask() const return this->mask; } +const Anope::string Entry::GetNUHMask() const +{ + Anope::string n = nick.empty() ? "*" : nick, + u = user.empty() ? "*" : user, + h = host.empty() ? "*" : host; + return n + "!" + u + "@" + h; +} + bool Entry::Matches(User *u, bool full) const { /* First check if this mode has defined any matches (usually for extbans). */ @@ -768,7 +870,7 @@ bool Entry::Matches(User *u, bool full) const } } else if (!this->host.empty() && !Anope::Match(u->GetDisplayedHost(), this->host) && !Anope::Match(u->GetCloakedHost(), this->host) && - (!full || (!Anope::Match(u->host, this->host) && !Anope::Match(u->ip, this->host)))) + (!full || (!Anope::Match(u->host, this->host) && !Anope::Match(u->ip.addr(), this->host)))) ret = false; if (!this->real.empty() && !Anope::Match(u->realname, this->real)) diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 9e27eec26..d11585791 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -158,25 +158,25 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) dlerror(); void *handle = dlopen(pbuf.c_str(), RTLD_NOW); const char *err = dlerror(); - if (!handle && err && *err) + if (!handle) { - Log() << err; + if (err && *err) + Log() << err; return MOD_ERR_NOLOAD; } dlerror(); Module *(*func)(const Anope::string &, const Anope::string &) = function_cast<Module *(*)(const Anope::string &, const Anope::string &)>(dlsym(handle, "AnopeInit")); err = dlerror(); - if (!func && err && *err) + if (!func |
