diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/CMakeLists.txt | 8 | ||||
-rw-r--r-- | modules/core/cs_xop.cpp | 2 | ||||
-rw-r--r-- | modules/core/db_plain.cpp | 6 | ||||
-rw-r--r-- | modules/core/ns_register.cpp | 2 | ||||
-rw-r--r-- | modules/extra/db_mysql.cpp | 4 | ||||
-rw-r--r-- | modules/extra/m_alias.cpp | 2 | ||||
-rw-r--r-- | modules/socketengines/m_socketengine_epoll.cpp | 6 | ||||
-rw-r--r-- | modules/socketengines/m_socketengine_poll.cpp | 192 |
8 files changed, 204 insertions, 18 deletions
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 9e094b40c..a9a73e775 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -76,9 +76,9 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS}) endif(WIN32) set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}") add_dependencies(${SO} ${PROGRAM_NAME}) - # For Windows only, have the module link to the export library of Anope as well as the wsock32 library (most of the modules probably don't need this, but this is to be on the safe side), also set it's version + # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version if(WIN32) - target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES}) + target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES}) set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") endif(WIN32) # Set the module to be installed to the module directory under the data directory @@ -170,9 +170,9 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS}) add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS}) set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}") add_dependencies(${SO} ${PROGRAM_NAME}) - # For Windows only, have the module link to the export library of Anope as well as the wsock32 library (most of the modules probably don't need this, but this is to be on the safe side), also set it's version + # For Windows only, have the module link to the export library of Anope as well as wsock32 and Ws2_32 libraries (most of the modules probably don't need this, but this is to be on the safe side), also set it's version if(WIN32) - target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS}) + target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${SUBDIR_EXTRA_DEPENDS}) set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") endif(WIN32) # Set the module to be installed to the module directory under the data directory diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp index 1d1ec7c84..6ab6edff8 100644 --- a/modules/core/cs_xop.cpp +++ b/modules/core/cs_xop.cpp @@ -316,7 +316,7 @@ class XOPBase : public Command XOPDelCallback list(source, this, messages, override, mask); list.Process(); } - else if (!access) + else if (!access || access->level != level) { source.Reply(messages[XOP_NOT_FOUND], mask.c_str(), ci->name.c_str()); return MOD_CONT; diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp index 44058d5e5..97ac75bde 100644 --- a/modules/core/db_plain.cpp +++ b/modules/core/db_plain.cpp @@ -980,7 +980,7 @@ class DBPlain : public Module db << " " << oldmodes; else { - for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) + for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { const ModeLock &ml = it->second; if (ml.set) @@ -1003,7 +1003,7 @@ class DBPlain : public Module } else { - for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) + for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { const ModeLock &ml = it->second; if (!ml.set) @@ -1028,7 +1028,7 @@ class DBPlain : public Module } else { - for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) + for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { const ModeLock &ml = it->second; ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name); diff --git a/modules/core/ns_register.cpp b/modules/core/ns_register.cpp index edf8181e5..31f99540a 100644 --- a/modules/core/ns_register.cpp +++ b/modules/core/ns_register.cpp @@ -213,7 +213,7 @@ class CommandNSRegister : public CommandNSConfirm /* Guest nick can now have a series of between 1 and 7 digits. * --lara */ - if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && !u->nick.find_ci(Config->NSGuestNickPrefix) && !u->nick.substr(prefixlen).find_first_not_of("1234567890")) + if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && !u->nick.find_ci(Config->NSGuestNickPrefix) && u->nick.substr(prefixlen).find_first_not_of("1234567890") == Anope::string::npos) { source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); return MOD_CONT; diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp index 07135757c..3cc0ceacb 100644 --- a/modules/extra/db_mysql.cpp +++ b/modules/extra/db_mysql.cpp @@ -206,7 +206,7 @@ static Anope::string MakeMLock(ChannelInfo *ci, bool status) ; else { - for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) + for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { const ModeLock &ml = it->second; if (ml.set == status) @@ -249,7 +249,7 @@ static Anope::string GetMLockParams(ChannelInfo *ci, bool onoff) } else { - for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) + for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { const ModeLock &ml = it->second; diff --git a/modules/extra/m_alias.cpp b/modules/extra/m_alias.cpp index f1b6c3959..8e73bacd9 100644 --- a/modules/extra/m_alias.cpp +++ b/modules/extra/m_alias.cpp @@ -62,7 +62,7 @@ class ModuleAlias : public Module EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci) { bool fantasy = ci != NULL; - std::map<Anope::string, CommandAlias, std::less<ci::string> >::const_iterator it = aliases.find(command), it_end = it; + std::multimap<Anope::string, CommandAlias, std::less<ci::string> >::const_iterator it = aliases.find(command), it_end = it; if (it_end != aliases.end()) it_end = aliases.upper_bound(command); for (; it != it_end; ++it) diff --git a/modules/socketengines/m_socketengine_epoll.cpp b/modules/socketengines/m_socketengine_epoll.cpp index 7ec380109..4a228a694 100644 --- a/modules/socketengines/m_socketengine_epoll.cpp +++ b/modules/socketengines/m_socketengine_epoll.cpp @@ -10,12 +10,10 @@ class SocketEngineEPoll : public SocketEngineBase long max; int EngineHandle; epoll_event *events; - unsigned SocketCount; public: SocketEngineEPoll() { - SocketCount = 0; max = ulimit(4, 0); if (max <= 0) @@ -57,8 +55,6 @@ class SocketEngineEPoll : public SocketEngineBase } Sockets.insert(std::make_pair(ev.data.fd, s)); - - ++SocketCount; } void DelSocket(Socket *s) @@ -76,8 +72,6 @@ class SocketEngineEPoll : public SocketEngineBase } Sockets.erase(ev.data.fd); - - --SocketCount; } void MarkWritable(Socket *s) diff --git a/modules/socketengines/m_socketengine_poll.cpp b/modules/socketengines/m_socketengine_poll.cpp new file mode 100644 index 000000000..044a79c4f --- /dev/null +++ b/modules/socketengines/m_socketengine_poll.cpp @@ -0,0 +1,192 @@ +#include "module.h" + +#ifndef _WIN32 +# include <ulimit.h> +# include <sys/poll.h> +# include <poll.h> +# ifndef POLLRDHUP +# define POLLRDHUP 0 +# endif +#else +# define poll WSAPoll +# define POLLRDHUP POLLHUP +#endif + +class SocketEnginePoll : public SocketEngineBase +{ + private: + long max; + pollfd *events; + int SocketCount; + std::map<int, int> socket_positions; + + public: + SocketEnginePoll() + { + SocketCount = 0; +#ifndef _WIN32 + max = ulimit(4, 0); +#else + max = 1024; +#endif + + if (max <= 0) + { + Log() << "Can't determine maximum number of open sockets"; + throw ModuleException("Can't determine maximum number of open sockets"); + } + + events = new pollfd[max]; + } + + ~SocketEnginePoll() + { + delete [] events; + } + + void AddSocket(Socket *s) + { + if (SocketCount == max) + { + Log() << "Unable to add fd " << s->GetFD() << " to socketengine poll, engine is full"; + return; + } + + pollfd *ev = &this->events[SocketCount]; + ev->fd = s->GetFD(); + ev->events = POLLIN; + ev->revents = 0; + + Sockets.insert(std::make_pair(ev->fd, s)); + socket_positions.insert(std::make_pair(ev->fd, SocketCount)); + + ++SocketCount; + } + + void DelSocket(Socket *s) + { + std::map<int, int>::iterator pos = socket_positions.find(s->GetFD()); + if (pos == socket_positions.end()) + { + Log() << "Unable to delete unknown fd " << s->GetFD() << " from socketengine poll"; + return; + } + + if (pos->second != SocketCount) + { + pollfd *ev = &this->events[pos->second], + *last_ev = &this->events[SocketCount - 1]; + + ev->fd = last_ev->fd; + ev->events = last_ev->events; + ev->revents = last_ev->revents; + + socket_positions[ev->fd] = pos->second; + } + + Sockets.erase(s->GetFD()); + this->socket_positions.erase(pos); + + --SocketCount; + } + + void MarkWritable(Socket *s) + { + if (s->HasFlag(SF_WRITABLE)) + return; + + std::map<int, int>::iterator pos = socket_positions.find(s->GetFD()); + if (pos == socket_positions.end()) + { + Log() << "Unable to mark unknown fd " << s->GetFD() << " as writable"; + return; + } + + pollfd *ev = &this->events[pos->second]; + ev->events |= POLLOUT; + + s->SetFlag(SF_WRITABLE); + } + + void ClearWritable(Socket *s) + { + if (!s->HasFlag(SF_WRITABLE)) + return; + + std::map<int, int>::iterator pos = socket_positions.find(s->GetFD()); + if (pos == socket_positions.end()) + { + Log() << "Unable to mark unknown fd " << s->GetFD() << " as writable"; + return; + } + + pollfd *ev = &this->events[pos->second]; + ev->events &= ~POLLOUT; + + s->UnsetFlag(SF_WRITABLE); + } + + void Process() + { + int total = poll(this->events, this->SocketCount, Config->ReadTimeout * 1000); + Anope::CurTime = time(NULL); + + if (total == -1) + { + Log() << "SockEngine::Process(): error: " << Anope::LastError(); + return; + } + + for (int i = 0; i < total; ++i) + { + pollfd *ev = &this->events[i]; + Socket *s = Sockets[ev->fd]; + + if (s->HasFlag(SF_DEAD)) + continue; + if (ev->revents & (POLLERR | POLLRDHUP)) + { + s->ProcessError(); + s->SetFlag(SF_DEAD); + continue; + } + + if ((ev->revents & POLLIN) && !s->ProcessRead()) + s->SetFlag(SF_DEAD); + + if ((ev->revents & POLLOUT) && !s->ProcessWrite()) + s->SetFlag(SF_DEAD); + } + + for (int i = 0; i < total; ++i) + { + pollfd *ev = &this->events[i]; + Socket *s = Sockets[ev->fd]; + + if (s->HasFlag(SF_DEAD)) + delete s; + } + } +}; + +class ModuleSocketEnginePoll : public Module +{ + SocketEnginePoll engine; + + public: + ModuleSocketEnginePoll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetPermanent(true); + this->SetType(SOCKETENGINE); + + SocketEngine = &engine; + } + + ~ModuleSocketEnginePoll() + { + SocketEngine = NULL; + } +}; + +MODULE_INIT(ModuleSocketEnginePoll) |