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) { 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> ¶ms) +{ + 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 |