summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt9
-rw-r--r--src/base64.cpp2
-rw-r--r--src/bots.cpp40
-rw-r--r--src/channels.cpp48
-rw-r--r--src/config.cpp17
-rw-r--r--src/init.cpp2
-rw-r--r--src/language.cpp7
-rw-r--r--src/logger.cpp62
-rw-r--r--src/messages.cpp19
-rw-r--r--src/modes.cpp194
-rw-r--r--src/modulemanager.cpp34
-rw-r--r--src/process.cpp71
-rw-r--r--src/protocol.cpp58
-rw-r--r--src/servers.cpp49
-rw-r--r--src/sockets.cpp15
-rw-r--r--src/uplink.cpp31
-rw-r--r--src/users.cpp25
-rw-r--r--src/win32/anope_windows.h2
-rw-r--r--src/win32/dl/dl.cpp3
-rw-r--r--src/win32/windows.cpp17
-rw-r--r--src/xline.cpp97
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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, bool enforce_mlock)
@@ -477,8 +490,11 @@ void Channel::RemoveMode(User *bi, ChannelMode *cm, const Anope::string &param,
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 &param, 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> &params)
void Message::Mode::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
+ 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> &param
* 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> &param
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> &params)
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 &param)
+{
+ return this;
+}
+
+ChannelMode *ChannelMode::Unwrap(Anope::string &param)
+{
+ 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 &param)
+{
+ 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 &param)
+{
+ 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