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)
{
Log() << "No init function found, not an Anope module";
+ if (err && *err)
+ Log(LOG_DEBUG) << err;
dlclose(handle);
return MOD_ERR_NOLOAD;
}
-
- if (!func)
- throw CoreException("Couldn't find constructor, yet moderror wasn't set?");
-
+
/* Create module. */
Anope::string nick;
if (u)
@@ -184,6 +184,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
Module *m;
+ ModuleReturn moderr = MOD_ERR_OK;
try
{
m = func(modname, nick);
@@ -191,7 +192,14 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
catch (const ModuleException &ex)
{
Log() << "Error while loading " << modname << ": " << ex.GetReason();
- return MOD_ERR_EXCEPTION;
+ moderr = MOD_ERR_EXCEPTION;
+ }
+
+ if (moderr != MOD_ERR_OK)
+ {
+ if (dlclose(handle))
+ Log() << dlerror();
+ return moderr;
}
m->filename = pbuf;
@@ -233,14 +241,18 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
catch (const ModuleException &ex)
{
Log() << "Module " << modname << " couldn't load:" << ex.GetReason();
- DeleteModule(m);
- return MOD_ERR_EXCEPTION;
+ moderr = MOD_ERR_EXCEPTION;
}
catch (const ConfigException &ex)
{
Log() << "Module " << modname << " couldn't load due to configuration problems: " << ex.GetReason();
+ moderr = MOD_ERR_EXCEPTION;
+ }
+
+ if (moderr != MOD_ERR_OK)
+ {
DeleteModule(m);
- return MOD_ERR_EXCEPTION;
+ return moderr;
}
Log(LOG_DEBUG) << "Module " << modname << " loaded.";
diff --git a/src/process.cpp b/src/process.cpp
index 70849243b..d14d8d589 100644
--- a/src/process.cpp
+++ b/src/process.cpp
@@ -24,34 +24,10 @@ void Anope::Process(const Anope::string &buffer)
if (buffer.empty())
return;
- spacesepstream buf_sep(buffer);
-
- Anope::string source;
- if (buffer[0] == ':')
- {
- buf_sep.GetToken(source);
- source.erase(0, 1);
- }
-
- Anope::string command;
- if (!buf_sep.GetToken(command))
- return;
-
- Anope::string buf_token;
+ Anope::string source, command;
std::vector<Anope::string> params;
- while (buf_sep.GetToken(buf_token))
- {
- if (buf_token[0] == ':')
- {
- if (!buf_sep.StreamEnd())
- params.push_back(buf_token.substr(1) + " " + buf_sep.GetRemaining());
- else
- params.push_back(buf_token.substr(1));
- break;
- }
- else
- params.push_back(buf_token);
- }
+
+ IRCD->Parse(buffer, source, command, params);
if (Anope::ProtocolDebug)
{
@@ -65,6 +41,12 @@ void Anope::Process(const Anope::string &buffer)
Log() << "params " << i << ": " << params[i];
}
+ if (command.empty())
+ {
+ Log(LOG_DEBUG) << "No command? " << buffer;
+ return;
+ }
+
static const Anope::string proto_name = ModuleManager::FindFirstOf(PROTOCOL) ? ModuleManager::FindFirstOf(PROTOCOL)->name : "";
MessageSource src(source);
@@ -91,3 +73,38 @@ void Anope::Process(const Anope::string &buffer)
m->Run(src, params);
}
+void IRCDProto::Parse(const Anope::string &buffer, Anope::string &source, Anope::string &command, std::vector<Anope::string> &params)
+{
+ spacesepstream sep(buffer);
+
+ if (buffer[0] == ':')
+ {
+ sep.GetToken(source);
+ source.erase(0, 1);
+ }
+
+ sep.GetToken(command);
+
+ for (Anope::string token; sep.GetToken(token);)
+ {
+ if (token[0] == ':')
+ {
+ if (!sep.StreamEnd())
+ params.push_back(token.substr(1) + " " + sep.GetRemaining());
+ else
+ params.push_back(token.substr(1));
+ break;
+ }
+ else
+ params.push_back(token);
+ }
+}
+
+Anope::string IRCDProto::Format(const Anope::string &source, const Anope::string &message)
+{
+ if (!source.empty())
+ return ":" + source + " " + message;
+ else
+ return message;
+}
+
diff --git a/src/protocol.cpp b/src/protocol.cpp
index d8fd9dc79..ade936594 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -26,7 +26,7 @@ IRCDProto::IRCDProto(Module *creator, const Anope::string &p) : Service(creator,
{
DefaultPseudoclientModes = "+io";
CanSVSNick = CanSVSJoin = CanSetVHost = CanSetVIdent = CanSNLine = CanSQLine = CanSQLineChannel
- = CanSZLine = CanSVSHold = CanSVSO = CanCertFP = RequiresID = false;
+ = CanSZLine = CanSVSHold = CanSVSO = CanCertFP = RequiresID = AmbiguousID = false;
MaxModes = 3;
MaxLine = 512;
@@ -45,6 +45,53 @@ const Anope::string &IRCDProto::GetProtocolName()
return this->proto_name;
}
+static inline char& nextID(char &c)
+{
+ if (c == 'Z')
+ c = '0';
+ else if (c != '9')
+ ++c;
+ else
+ c = 'A';
+ return c;
+}
+
+Anope::string IRCDProto::UID_Retrieve()
+{
+ if (!IRCD || !IRCD->RequiresID)
+ return "";
+
+ static Anope::string current_uid = "AAAAAA";
+
+ do
+ {
+ int current_len = current_uid.length() - 1;
+ while (current_len >= 0 && nextID(current_uid[current_len--]) == 'A');
+ }
+ while (User::Find(Me->GetSID() + current_uid) != NULL);
+
+ return Me->GetSID() + current_uid;
+}
+
+Anope::string IRCDProto::SID_Retrieve()
+{
+ if (!IRCD || !IRCD->RequiresID)
+ return "";
+
+ static Anope::string current_sid = Config->GetBlock("serverinfo")->Get<const Anope::string>("id");
+ if (current_sid.empty())
+ current_sid = "00A";
+
+ do
+ {
+ int current_len = current_sid.length() - 1;
+ while (current_len >= 0 && nextID(current_sid[current_len--]) == 'A');
+ }
+ while (Server::Find(current_sid) != NULL);
+
+ return current_sid;
+}
+
void IRCDProto::SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason)
{
UplinkSocket::Message(source) << "KILL " << target << " :" << reason;
@@ -276,7 +323,7 @@ void IRCDProto::SendNickChange(User *u, const Anope::string &newnick)
void IRCDProto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when)
{
- UplinkSocket::Message() << "SVSNICK " << u->nick << " " << newnick << " " << when;
+ UplinkSocket::Message() << "SVSNICK " << u->GetUID() << " " << newnick << " " << when;
}
void IRCDProto::SendCTCP(const MessageSource &source, const Anope::string &dest, const char *fmt, ...)
@@ -387,6 +434,13 @@ unsigned IRCDProto::GetMaxListFor(Channel *c)
return c->HasMode("LBAN") ? 0 : Config->GetBlock("networkinfo")->Get<int>("modelistsize");
}
+Anope::string IRCDProto::NormalizeMask(const Anope::string &mask)
+{
+ if (IsExtbanValid(mask))
+ return mask;
+ return Entry("", mask).GetNUHMask();
+}
+
MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL)
{
/* no source for incoming message is our uplink */
diff --git a/src/servers.cpp b/src/servers.cpp
index c4cb3665e..a6998b200 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -96,7 +96,7 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
{
User *u = it->second;
- BotInfo *bi = BotInfo::Find(u->nick);
+ BotInfo *bi = BotInfo::Find(u->GetUID());
if (bi)
{
XLine x(bi->nick, "Reserved for services");
@@ -353,53 +353,6 @@ Server *Server::Find(const Anope::string &name, bool name_only)
return NULL;
}
-static inline char& nextID(char &c)
-{
- if (c == 'Z')
- c = '0';
- else if (c != '9')
- ++c;
- else
- c = 'A';
- return c;
-}
-
-const Anope::string Servers::TS6_UID_Retrieve()
-{
- if (!IRCD || !IRCD->RequiresID)
- return "";
-
- static Anope::string current_uid = "AAAAAA";
-
- do
- {
- int current_len = current_uid.length() - 1;
- while (current_len >= 0 && nextID(current_uid[current_len--]) == 'A');
- }
- while (User::Find(Me->GetSID() + current_uid) != NULL);
-
- return Me->GetSID() + current_uid;
-}
-
-const Anope::string Servers::TS6_SID_Retrieve()
-{
- if (!IRCD || !IRCD->RequiresID)
- return "";
-
- static Anope::string current_sid = Config->GetBlock("options")->Get<const Anope::string>("id");
- if (current_sid.empty())
- current_sid = "00A";
-
- do
- {
- int current_len = current_sid.length() - 1;
- while (current_len >= 0 && nextID(current_sid[current_len--]) == 'A');
- }
- while (Server::Find(current_sid) != NULL);
-
- return current_sid;
-}
-
Server* Servers::GetUplink()
{
for (unsigned i = 0; Me && i < Me->GetLinks().size(); ++i)
diff --git a/src/sockets.cpp b/src/sockets.cpp
index 5d84d1a3f..aea80ee4a 100644
--- a/src/sockets.cpp
+++ b/src/sockets.cpp
@@ -96,9 +96,9 @@ bool sockaddrs::ipv6() const
return sa.sa_family == AF_INET6;
}
-bool sockaddrs::operator()() const
+bool sockaddrs::valid() const
{
- return valid();
+ return size() != 0;
}
bool sockaddrs::operator==(const sockaddrs &other) const
@@ -180,11 +180,6 @@ void sockaddrs::ntop(int type, const void *src)
this->clear();
}
-bool sockaddrs::valid() const
-{
- return size() != 0;
-}
-
cidr::cidr(const Anope::string &ip)
{
bool ipv6 = ip.find(':') != Anope::string::npos;
@@ -221,6 +216,12 @@ cidr::cidr(const Anope::string &ip, unsigned char len)
this->cidr_len = len;
}
+cidr::cidr(const sockaddrs &a, unsigned char len) : addr(a)
+{
+ this->cidr_ip = a.addr();
+ this->cidr_len = len;
+}
+
Anope::string cidr::mask() const
{
if ((this->addr.ipv6() && this->cidr_len == 128) || (!this->addr.ipv6() && this->cidr_len == 32))
diff --git a/src/uplink.cpp b/src/uplink.cpp
index 2f7a03ebd..9337692bb 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -62,11 +62,22 @@ void Uplink::Connect()
UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].ipv6), ConnectionSocket(), BufferedSocket()
{
+ error = false;
UplinkSock = this;
}
UplinkSocket::~UplinkSocket()
{
+ if (!error)
+ {
+ this->OnError("");
+ Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
+ if (protocol && !protocol->name.find("inspircd"))
+ Log(LOG_TERMINAL) << "Check that you have loaded m_spanningtree.so on InspIRCd, and are not connecting Anope to an SSL enabled port without configuring SSL in Anope (or vice versa)";
+ else
+ Log(LOG_TERMINAL) << "Check that you are not connecting Anope to an SSL enabled port without configuring SSL in Anope (or vice versa)";
+ }
+
if (IRCD && Servers::GetUplink() && Servers::GetUplink()->IsSynced())
{
Event::OnServerDisconnect(&Event::ServerDisconnect::OnServerDisconnect);
@@ -79,7 +90,7 @@ UplinkSocket::~UplinkSocket()
{
/* 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);
+ BotInfo* bi = BotInfo::Find(u->GetUID());
if (bi != NULL)
bi->introduced = false;
}
@@ -138,10 +149,11 @@ void UplinkSocket::OnConnect()
Event::OnServerConnect(&Event::ServerConnect::OnServerConnect);
}
-void UplinkSocket::OnError(const Anope::string &error)
+void UplinkSocket::OnError(const Anope::string &err)
{
Anope::string what = !this->flags[SF_CONNECTED] ? "Unable to connect to" : "Lost connection from";
- Log(LOG_TERMINAL) << what << " uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << ")" << (!error.empty() ? (": " + error) : "");
+ Log(LOG_TERMINAL) << what << " uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << ")" << (!err.empty() ? (": " + err) : "");
+ error |= !err.empty();
}
UplinkSocket::Message::Message() : source(Me)
@@ -197,14 +209,7 @@ UplinkSocket::Message::~Message()
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();
- }
+ Anope::string sent = IRCD->Format(message_source, this->buffer.str());
+ UplinkSock->Write(sent);
+ Log(LOG_RAWIO) << "Sent: " << sent;
}
diff --git a/src/users.cpp b/src/users.cpp
index 47923a350..f6d72383e 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -34,7 +34,7 @@ time_t MaxUserTime = 0;
std::list<User *> User::quitting_users;
-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 ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *account)
+User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &uip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickServ::Account *account) : ip(uip)
{
if (snick.empty() || sident.empty() || shost.empty())
throw CoreException("Bad args passed to User::User");
@@ -50,7 +50,6 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->host = shost;
this->vhost = svhost;
this->chost = svhost;
- this->ip = sip;
this->server = sserver;
this->realname = srealname;
this->timestamp = this->signon = ts;
@@ -69,10 +68,11 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->Login(account);
this->UpdateHost();
- if (sserver && sserver->IsSynced()) // Our bots are introduced on startup with no server
+ if (sserver) // Our bots are introduced on startup with no server
{
++sserver->users;
- Log(this, "connect") << (!vhost.empty() && vhost != host ? "(" + vhost + ") " : "") << "(" << srealname << ") " << (!sip.empty() && sip != host ? "[" + sip + "] " : "") << "connected to the network (" << sserver->GetName() << ")";
+ if (server->IsSynced())
+ Log(this, "connect") << (!vhost.empty() && vhost != host ? "(" + vhost + ") " : "") << "(" << srealname << ") " << (!uip.empty() && uip != host ? "[" + uip + "] " : "") << "connected to the network (" << sserver->GetName() << ")";
}
if (UserListByNick.size() > MaxUserCount)
@@ -119,7 +119,7 @@ User* User::OnIntroduce(const Anope::string &snick, const Anope::string &sident,
// How IRCds handle collisions varies a lot, for safety well just always kill both sides
// With properly set qlines, this can almost never happen anyway
- User *u = User::Find(snick);
+ User *u = User::Find(snick, true);
if (u)
{
Collide(u, !suid.empty() ? suid : snick, "Nick collision");
@@ -837,18 +837,19 @@ bool User::BadPassword()
User* User::Find(const Anope::string &name, bool nick_only)
{
- if (!nick_only && isdigit(name[0]) && IRCD->RequiresID)
+ if (!nick_only && IRCD->RequiresID)
{
user_map::iterator it = UserListByUID.find(name);
if (it != UserListByUID.end())
return it->second;
+
+ if (IRCD->AmbiguousID)
+ return NULL;
}
- else
- {
- user_map::iterator it = UserListByNick.find(name);
- if (it != UserListByNick.end())
- return it->second;
- }
+
+ user_map::iterator it = UserListByNick.find(name);
+ if (it != UserListByNick.end())
+ return it->second;
return NULL;
}
diff --git a/src/win32/anope_windows.h b/src/win32/anope_windows.h
index f2a496c33..061934752 100644
--- a/src/win32/anope_windows.h
+++ b/src/win32/anope_windows.h
@@ -74,7 +74,7 @@ namespace Anope
extern CoreExport void OnStartup();
extern CoreExport void OnShutdown();
-extern CoreExport USHORT WindowsGetLanguage(const char *lang);
+extern CoreExport USHORT WindowsGetLanguage(const Anope::string &lang);
extern CoreExport int gettimeofday(timeval *tv, void *);
extern CoreExport Anope::string GetWindowsVersion();
extern CoreExport bool SupportedWindowsVersion();
diff --git a/src/win32/dl/dl.cpp b/src/win32/dl/dl.cpp
index b7ffddaa3..5b19d7441 100644
--- a/src/win32/dl/dl.cpp
+++ b/src/win32/dl/dl.cpp
@@ -15,7 +15,8 @@ void *dlopen(const char *filename, int)
char *dlerror(void)
{
- static Anope::string err = Anope::LastError();
+ static Anope::string err;
+ err = Anope::LastError();
SetLastError(0);
return err.empty() ? NULL : const_cast<char *>(err.c_str());
}
diff --git a/src/win32/windows.cpp b/src/win32/windows.cpp
index 319bebf58..a70ff53c3 100644
--- a/src/win32/windows.cpp
+++ b/src/win32/windows.cpp
@@ -20,12 +20,13 @@
static struct WindowsLanguage
{
- const char *languageName;
+ Anope::string languageName;
USHORT windowsLanguageName;
} WindowsLanguages[] = {
{"ca_ES", LANG_CATALAN},
{"de_DE", LANG_GERMAN},
{"el_GR", LANG_GREEK},
+ {"en_US", LANG_ENGLISH},
{"es_ES", LANG_SPANISH},
{"fr_FR", LANG_FRENCH},
{"hu_HU", LANG_HUNGARIAN},
@@ -35,7 +36,6 @@ static struct WindowsLanguage
{"pt_PT", LANG_PORTUGUESE},
{"ru_RU", LANG_RUSSIAN},
{"tr_TR", LANG_TURKISH},
- {NULL, 0}
};
static WSADATA wsa;
@@ -51,11 +51,16 @@ void OnShutdown()
WSACleanup();
}
-USHORT WindowsGetLanguage(const char *lang)
+USHORT WindowsGetLanguage(const Anope::string &lang)
{
- for (int i = 0; WindowsLanguages[i].languageName; ++i)
- if (!strcmp(lang, WindowsLanguages[i].languageName))
- return WindowsLanguages[i].windowsLanguageName;
+ for (int i = 0; i < sizeof(WindowsLanguages) / sizeof(WindowsLanguage); ++i)
+ {
+ WindowsLanguage &l = WindowsLanguages[i];
+
+ if (lang == l.languageName || !lang.find(l.languageName + "."))
+ return l.windowsLanguageName;
+ }
+
return LANG_NEUTRAL;
}
diff --git a/src/xline.cpp b/src/xline.cpp
index 8c8f6034c..a39d655be 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -23,7 +23,7 @@
std::list<XLineManager *> XLineManager::XLineManagers;
Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManager::XLinesByUID("XLine");
-void XLine::InitRegex()
+void XLine::Init()
{
if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && Config->regex_flags)
{
@@ -38,77 +38,92 @@ void XLine::InitRegex()
Log(LOG_DEBUG) << ex.what();
}
}
+
+ size_t nick_t = this->mask.find('!');
+ if (nick_t != Anope::string::npos)
+ nick = this->mask.substr(0, nick_t);
+
+ 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)
+ user = this->mask.substr(user_t + 1, host_t - user_t - 1);
+ else
+ user = this->mask.substr(0, host_t);
+ }
+
+ size_t real_t = this->mask.find('#');
+ if (host_t != Anope::string::npos)
+ {
+ if (real_t != Anope::string::npos && real_t > host_t)
+ host = this->mask.substr(host_t + 1, real_t - host_t - 1);
+ else
+ host = this->mask.substr(host_t + 1);
+ }
+ else
+ {
+ if (real_t != Anope::string::npos)
+ host = this->mask.substr(0, real_t);
+ else
+ host = this->mask;
+ }
+
+ if (real_t != Anope::string::npos)
+ real = this->mask.substr(real_t + 1);
+
+ if (host.find('/') != Anope::string::npos)
+ {
+ c = new cidr(host);
+ if (!c->valid())
+ {
+ delete c;
+ c = NULL;
+ }
+ }
}
XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(Me->GetName()), created(0), expires(0), reason(r), id(uid)
{
regex = NULL;
manager = NULL;
+ c = NULL;
- this->InitRegex();
+ this->Init();
}
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;
+ c = NULL;
- this->InitRegex();
+ this->Init();
}
XLine::~XLine()
{
delete regex;
+ delete c;
}
-Anope::string XLine::GetNick() const
+const 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);
+ return nick;
}
-Anope::string XLine::GetUser() const
+const 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 "";
+ return user;
}
-Anope::string XLine::GetHost() const
+const 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 "";
+ return host;
}
-Anope::string XLine::GetReal() const
+const 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 "";
+ return real;
}
Anope::string XLine::GetReason() const