From 162fdbe5815bbdf187f549fefac94ff476d72e62 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 27 Oct 2015 13:21:24 -0400 Subject: Beginning of new module dependency stuff, seems to compile and link. Move some of the madness in chanserv.h to the module. --- cmake/Anope.cmake | 17 +++ include/modules.h | 72 ++++++++---- include/modules/chanserv.h | 141 +++--------------------- modules/CMakeLists.txt | 10 +- modules/commands/cs_access.cpp | 19 +++- modules/commands/cs_flags.cpp | 17 ++- modules/commands/cs_xop.cpp | 17 ++- modules/pseudoclients/chanserv/chanaccess.cpp | 127 +++++++++++++++++++++ modules/pseudoclients/chanserv/chanaccess.h | 30 +++++ modules/pseudoclients/chanserv/chanaccesstype.h | 21 ++++ modules/pseudoclients/chanserv/channel.h | 2 - modules/pseudoclients/chanserv/chanserv.cpp | 52 +-------- src/modulemanager.cpp | 54 ++++----- 13 files changed, 337 insertions(+), 242 deletions(-) create mode 100644 modules/pseudoclients/chanserv/chanaccess.cpp create mode 100644 modules/pseudoclients/chanserv/chanaccess.h create mode 100644 modules/pseudoclients/chanserv/chanaccesstype.h diff --git a/cmake/Anope.cmake b/cmake/Anope.cmake index a8624d775..48a57d213 100644 --- a/cmake/Anope.cmake +++ b/cmake/Anope.cmake @@ -89,3 +89,20 @@ macro(add_to_cpack_ignored_files ITEM) set(ENV{CPACK_IGNORED_FILES} "${REAL_ITEM}") endif(DEFINED ENV{CPACK_IGNORED_FILES}) endmacro(add_to_cpack_ignored_files) + +macro(calculate_dependencies SRC) + file(STRINGS ${SRC} REQUIRED_LIBRARIES REGEX "/\\*[ \t]*Dependencies:[ \t]*.*[ \t]*\\*/") + # Iterate through those lines + foreach(REQUIRED_LIBRARY ${REQUIRED_LIBRARIES}) + string(REGEX REPLACE "/\\*[ \t]*Dependencies:[ \t]*([^ \t]*)[ \t]*\\*/" "\\1" REQUIRED_LIBRARY ${REQUIRED_LIBRARY}) + # Replace all commas with semicolons + string(REGEX REPLACE "," ";" REQUIRED_LIBRARY ${REQUIRED_LIBRARY}) + # Iterate through the libraries given + foreach(LIBRARY ${REQUIRED_LIBRARY}) + get_filename_component(TARGNAME ${SRC} NAME_WE) + target_link_libraries(${TARGNAME} ${LIBRARY}) + add_dependencies(${TARGNAME} ${LIBRARY}) + endforeach(LIBRARY) + endforeach(REQUIRED_LIBRARY) +endmacro(calculate_dependencies) + diff --git a/include/modules.h b/include/modules.h index 5daaed613..87051704b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -19,37 +19,62 @@ #include "logger.h" #include "extensible.h" +class ModuleDef; + +struct AnopeModule +{ + ModuleDef* (*init)(); + void (*fini)(ModuleDef *); +}; + +class ModuleDef +{ + std::vector dependencies; + + public: + virtual ~ModuleDef() = default; + virtual Module *Create(const Anope::string &modname, const Anope::string &creator) anope_abstract; + virtual void Destroy(Module *) anope_abstract; + virtual void BuildModuleInfo() anope_abstract; + + void Depends(const Anope::string &modname); + const std::vector &GetDependencies(); +}; + +template void ModuleInfo(ModuleDef *moddef) { } + /** This definition is used as shorthand for the various classes * and functions needed to make a module loadable by the OS. - * It defines the class factory and external AnopeInit and AnopeFini functions. */ -#ifdef _WIN32 -# define MODULE_INIT(x) \ - extern "C" DllExport Module *AnopeInit(const Anope::string &, const Anope::string &); \ - extern "C" Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \ +#define MODULE_INIT(ModuleClass) \ + class ModuleClass ## ModuleDef : public ModuleDef \ { \ - return new x(modname, creator); \ - } \ - BOOLEAN WINAPI DllMain(HINSTANCE, DWORD, LPVOID) \ + Module *Create(const Anope::string &modname, const Anope::string &creator) override \ + { \ + return new ModuleClass(modname, creator); \ + } \ + void Destroy(Module *module) override \ + { \ + delete module; \ + } \ + void BuildModuleInfo() override \ + { \ + ModuleInfo(this); \ + } \ + }; \ + static ModuleDef *CreateModuleDef() \ { \ - return TRUE; \ + return new ModuleClass ## ModuleDef(); \ } \ - extern "C" DllExport void AnopeFini(x *); \ - extern "C" void AnopeFini(x *m) \ - { \ - delete m; \ - } -#else -# define MODULE_INIT(x) \ - extern "C" DllExport Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \ + static void DeleteModuleDef(ModuleDef *def) \ { \ - return new x(modname, creator); \ + delete def; \ } \ - extern "C" DllExport void AnopeFini(x *m) \ + extern "C" DllExport struct AnopeModule AnopeMod = \ { \ - delete m; \ - } -#endif + CreateModuleDef, \ + DeleteModuleDef \ + }; enum ModuleReturn { @@ -145,6 +170,9 @@ class CoreExport Module : public Extensible */ void *handle; + ModuleDef *def = nullptr; + AnopeModule *module = nullptr; + /** Time this module was created */ time_t created; diff --git a/include/modules/chanserv.h b/include/modules/chanserv.h index a6f741c1b..f0c396d39 100644 --- a/include/modules/chanserv.h +++ b/include/modules/chanserv.h @@ -141,11 +141,6 @@ namespace ChanServ virtual Privilege *FindPrivilege(const Anope::string &name) anope_abstract; virtual std::vector &GetPrivileges() anope_abstract; virtual void ClearPrivileges() anope_abstract; - - //XXX - typedef std::multimap Set; - typedef std::pair Path; - virtual bool Matches(ChanAccess *, const User *u, NickServ::Account *acc, Path &p) anope_abstract; }; static ServiceReference service("ChanServService", "ChanServ"); @@ -377,36 +372,33 @@ namespace ChanServ ChanAccess(Serialize::TypeBase *type) : Serialize::Object(type) { } ChanAccess(Serialize::TypeBase *type, Serialize::ID id) : Serialize::Object(type, id) { } - inline Channel *GetChannel(); - inline void SetChannel(Channel *ci); + virtual Channel *GetChannel() anope_abstract; + virtual void SetChannel(Channel *ci) anope_abstract; - inline Anope::string GetCreator(); - inline void SetCreator(const Anope::string &c); + virtual Anope::string GetCreator() anope_abstract; + virtual void SetCreator(const Anope::string &c) anope_abstract; - inline time_t GetLastSeen(); - inline void SetLastSeen(const time_t &t); + virtual time_t GetLastSeen() anope_abstract; + virtual void SetLastSeen(const time_t &t) anope_abstract; - inline time_t GetCreated(); - inline void SetCreated(const time_t &t); + virtual time_t GetCreated() anope_abstract; + virtual void SetCreated(const time_t &t) anope_abstract; - inline Anope::string GetMask(); - inline void SetMask(const Anope::string &); + virtual Anope::string GetMask() anope_abstract; + virtual void SetMask(const Anope::string &) anope_abstract; - inline Serialize::Object *GetObj(); - inline void SetObj(Serialize::Object *); + virtual Serialize::Object *GetObj() anope_abstract; + virtual void SetObj(Serialize::Object *) anope_abstract; - inline Anope::string Mask(); - inline NickServ::Account *GetAccount(); + virtual Anope::string Mask() anope_abstract; + virtual NickServ::Account *GetAccount() anope_abstract; /** Check if this access entry matches the given user or account * @param u The user - * @param nc The account + * @param acc The account * @param p The path to the access object which matches will be put here */ - virtual bool Matches(const User *u, NickServ::Account *acc, Path &p) - { - return service->Matches(this, u, acc, p); - } + virtual bool Matches(const User *u, NickServ::Account *acc, Path &p) anope_abstract; /** Check if this access entry has the given privilege. * @param name The privilege name @@ -425,7 +417,7 @@ namespace ChanServ virtual void AccessUnserialize(const Anope::string &data) anope_abstract; /* Comparison operators to other Access entries */ - virtual bool operator>(ChanAccess &other) + bool operator>(ChanAccess &other) { const std::vector &privs = service->GetPrivileges(); for (unsigned i = privs.size(); i > 0; --i) @@ -442,7 +434,7 @@ namespace ChanServ return false; } - virtual bool operator<(ChanAccess &other) + bool operator<(ChanAccess &other) { const std::vector &privs = service->GetPrivileges(); for (unsigned i = privs.size(); i > 0; --i) @@ -470,103 +462,6 @@ namespace ChanServ } }; - class ChanAccessType : public Serialize::AbstractType - { - public: - Serialize::ObjectField ci; - Serialize::Field mask; - Serialize::ObjectField obj; - Serialize::Field creator; - Serialize::Field last_seen; - Serialize::Field created; - - ChanAccessType(Module *me, const Anope::string &name) : Serialize::AbstractType(me, name) - , ci(this, "ci", true) - , mask(this, "mask") - , obj(this, "obj", true) - , creator(this, "creator") - , last_seen(this, "last_seen") - , created(this, "created") - { - } - }; - - ChanServ::Channel *ChanAccess::GetChannel() - { - return Get(&ChanAccessType::ci); - } - - void ChanAccess::SetChannel(ChanServ::Channel *ci) - { - Object::Set(&ChanAccessType::ci, ci); - } - - Anope::string ChanAccess::GetCreator() - { - return Get(&ChanAccessType::creator); - } - - void ChanAccess::SetCreator(const Anope::string &c) - { - Object::Set(&ChanAccessType::creator, c); - } - - time_t ChanAccess::GetLastSeen() - { - return Get(&ChanAccessType::last_seen); - } - - void ChanAccess::SetLastSeen(const time_t &t) - { - Object::Set(&ChanAccessType::last_seen, t); - } - - time_t ChanAccess::GetCreated() - { - return Get(&ChanAccessType::created); - } - - void ChanAccess::SetCreated(const time_t &t) - { - Object::Set(&ChanAccessType::created, t); - } - - Anope::string ChanAccess::GetMask() - { - return Get(&ChanAccessType::mask); - } - - void ChanAccess::SetMask(const Anope::string &n) - { - Object::Set(&ChanAccessType::mask, n); - } - - Serialize::Object *ChanAccess::GetObj() - { - return Get(&ChanAccessType::obj); - } - - void ChanAccess::SetObj(Serialize::Object *o) - { - Object::Set(&ChanAccessType::obj, o); - } - - Anope::string ChanAccess::Mask() - { - if (NickServ::Account *acc = GetAccount()) - return acc->GetDisplay(); - - return GetMask(); - } - - NickServ::Account *ChanAccess::GetAccount() - { - if (!GetObj() || GetObj()->GetSerializableType() != NickServ::account) - return nullptr; - - return anope_dynamic_static_cast(GetObj()); - } - static Serialize::TypeReference chanaccess("ChanAccess"); /* A group of access entries. This is used commonly, for example with ChanServ::Channel::AccessFor, diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 9078f2654..522ceb674 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -18,7 +18,7 @@ macro(build_modules SRC) file(RELATIVE_PATH FNAME ${SRC} ${MODULE_SRC}) # Convert the real source file extension to have a .so extension - string(REGEX REPLACE "\\.cpp$" ".so" SO ${FNAME}) + string(REGEX REPLACE "\\.cpp$" "" SO ${FNAME}) # Reset linker flags set(TEMP_LDFLAGS) @@ -40,7 +40,7 @@ macro(build_modules SRC) else(WIN32) set(WIN32_NO_LIBS) endif(WIN32) - set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) + set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX ".so" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) add_dependencies(${SO} ${PROGRAM_NAME}) if(GETTEXT_FOUND) add_dependencies(${SO} module_language) @@ -55,6 +55,7 @@ macro(build_modules SRC) target_link_libraries(${SO} ${PROGRAM_NAME}) endif(APPLE) endif(WIN32) + calculate_dependencies(${MODULE_SRC}) # Set the module to be installed to the module directory under the data directory install(TARGETS ${SO} DESTINATION ${LIB_DIR}/modules) endif(CPP) @@ -68,7 +69,7 @@ macro(build_subdir) list(SORT MODULES_SUBDIR_SRCS) GET_FILENAME_COMPONENT(FOLDER_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) - set(SO "${FOLDER_NAME}.so") + set(SO "${FOLDER_NAME}") # Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though) set_source_files_properties(${MODULES_SUBDIR_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}") @@ -81,6 +82,7 @@ macro(build_subdir) set(TEMP_DEPENDENCIES) # Calculate the library dependencies for the given source file calculate_libraries(${SRC} SKIP_LIBRARIES MODULE TEMP_LDFLAGS TEMP_DEPENDENCIES) + calculate_dependencies(${SRC}) # Append this source file's linker flags to the subdirectoy's linker flags, if there are any to append if(TEMP_DEPENDENCIES) @@ -107,7 +109,7 @@ macro(build_subdir) # Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS}) - set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) + set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX ".so" LINK_FLAGS "${SUBDIR_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) add_dependencies(${SO} ${PROGRAM_NAME}) if(GETTEXT_FOUND) add_dependencies(${SO} module_language) diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 6f1f0f1f0..982d5763f 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -9,15 +9,19 @@ * Based on the original code of Services by Andy Church. */ +/* Dependencies: chanserv */ + #include "module.h" #include "modules/chanserv.h" #include "modules/cs_access.h" +#include "../pseudoclients/chanserv/chanaccess.h" +#include "../pseudoclients/chanserv/chanaccesstype.h" -class AccessChanAccess : public ChanServ::ChanAccess +class AccessChanAccess : public ChanAccessImpl { public: - AccessChanAccess(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { } - AccessChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { } + AccessChanAccess(Serialize::TypeBase *type) : ChanAccessImpl(type) { } + AccessChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanAccessImpl(type, id) { } int GetLevel(); void SetLevel(const int &); @@ -43,6 +47,7 @@ class AccessChanAccess : public ChanServ::ChanAccess } } +#if 0 bool operator>(ChanServ::ChanAccess &other) override { if (this->GetSerializableType() != other.GetSerializableType()) @@ -58,9 +63,10 @@ class AccessChanAccess : public ChanServ::ChanAccess else return this->GetLevel() < anope_dynamic_static_cast(&other)->GetLevel(); } +#endif }; -class AccessChanAccessType : public Serialize::Type +class AccessChanAccessType : public Serialize::Type { public: Serialize::Field level; @@ -920,4 +926,9 @@ class CSAccess : public Module } }; +template<> void ModuleInfo(ModuleDef *def) +{ + def->Depends("chanserv"); +} + MODULE_INIT(CSAccess) diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index c8ef11796..88cc501ac 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -9,16 +9,20 @@ * Based on the original code of Services by Andy Church. */ +/* Dependencies: chanserv */ + #include "module.h" #include "modules/cs_access.h" +#include "../pseudoclients/chanserv/chanaccess.h" +#include "../pseudoclients/chanserv/chanaccesstype.h" static std::map defaultFlags; -class FlagsChanAccess : public ChanServ::ChanAccess +class FlagsChanAccess : public ChanAccessImpl { public: - FlagsChanAccess(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { } - FlagsChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { } + FlagsChanAccess(Serialize::TypeBase *type) : ChanAccessImpl(type) { } + FlagsChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanAccessImpl(type, id) { } Anope::string GetFlags(); void SetFlags(const Anope::string &); @@ -57,7 +61,7 @@ class FlagsChanAccess : public ChanServ::ChanAccess } }; -class FlagsChanAccessType : public Serialize::Type +class FlagsChanAccessType : public Serialize::Type { public: Serialize::Field flags; @@ -518,4 +522,9 @@ class CSFlags : public Module } }; +template<> void ModuleInfo(ModuleDef *def) +{ + def->Depends("chanserv"); +} + MODULE_INIT(CSFlags) diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp index 0de467f4f..891ac77e7 100644 --- a/modules/commands/cs_xop.cpp +++ b/modules/commands/cs_xop.cpp @@ -9,8 +9,12 @@ * Based on the original code of Services by Andy Church. */ +/* Dependencies: chanserv */ + #include "module.h" #include "modules/cs_access.h" +#include "../pseudoclients/chanserv/chanaccess.h" +#include "../pseudoclients/chanserv/chanaccesstype.h" namespace { @@ -18,11 +22,11 @@ namespace std::map > permissions; } -class XOPChanAccess : public ChanServ::ChanAccess +class XOPChanAccess : public ChanAccessImpl { public: - XOPChanAccess(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { } - XOPChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { } + XOPChanAccess(Serialize::TypeBase *type) : ChanAccessImpl(type) { } + XOPChanAccess(Serialize::TypeBase *type, Serialize::ID id) : ChanAccessImpl(type, id) { } Anope::string GetType(); void SetType(const Anope::string &); @@ -81,7 +85,7 @@ class XOPChanAccess : public ChanServ::ChanAccess }; -class XOPChanAccessType : public Serialize::Type +class XOPChanAccessType : public Serialize::Type { public: Serialize::Field type; @@ -648,4 +652,9 @@ class CSXOP : public Module } }; +template<> void ModuleInfo(ModuleDef *def) +{ + def->Depends("chanserv"); +} + MODULE_INIT(CSXOP) diff --git a/modules/pseudoclients/chanserv/chanaccess.cpp b/modules/pseudoclients/chanserv/chanaccess.cpp new file mode 100644 index 000000000..1601260c2 --- /dev/null +++ b/modules/pseudoclients/chanserv/chanaccess.cpp @@ -0,0 +1,127 @@ +#include "module.h" +#include "chanaccess.h" +#include "chanaccesstype.h" + +ChanServ::Channel *ChanAccessImpl::GetChannel() +{ + return Get(&ChanAccessType::ci); +} + +void ChanAccessImpl::SetChannel(ChanServ::Channel *ci) +{ + Object::Set(&ChanAccessType::ci, ci); +} + +Anope::string ChanAccessImpl::GetCreator() +{ + return Get(&ChanAccessType::creator); +} + +void ChanAccessImpl::SetCreator(const Anope::string &c) +{ + Object::Set(&ChanAccessType::creator, c); +} + +time_t ChanAccessImpl::GetLastSeen() +{ + return Get(&ChanAccessType::last_seen); +} + +void ChanAccessImpl::SetLastSeen(const time_t &t) +{ + Object::Set(&ChanAccessType::last_seen, t); +} + +time_t ChanAccessImpl::GetCreated() +{ + return Get(&ChanAccessType::created); +} + +void ChanAccessImpl::SetCreated(const time_t &t) +{ + Object::Set(&ChanAccessType::created, t); +} + +Anope::string ChanAccessImpl::GetMask() +{ + return Get(&ChanAccessType::mask); +} + +void ChanAccessImpl::SetMask(const Anope::string &n) +{ + Object::Set(&ChanAccessType::mask, n); +} + +Serialize::Object *ChanAccessImpl::GetObj() +{ + return Get(&ChanAccessType::obj); +} + +void ChanAccessImpl::SetObj(Serialize::Object *o) +{ + Object::Set(&ChanAccessType::obj, o); +} + +Anope::string ChanAccessImpl::Mask() +{ + if (NickServ::Account *acc = GetAccount()) + return acc->GetDisplay(); + + return GetMask(); +} + +NickServ::Account *ChanAccessImpl::GetAccount() +{ + if (!GetObj() || GetObj()->GetSerializableType() != NickServ::account) + return nullptr; + + return anope_dynamic_static_cast(GetObj()); +} + +bool ChanAccessImpl::Matches(const User *u, NickServ::Account *acc, Path &p) +{ + if (this->GetAccount()) + return this->GetAccount() == acc; + + if (u) + { + bool is_mask = this->Mask().find_first_of("!@?*") != Anope::string::npos; + if (is_mask && Anope::Match(u->nick, this->Mask())) + return true; + else if (Anope::Match(u->GetDisplayedMask(), this->Mask())) + return true; + } + + if (acc) + for (NickServ::Nick *na : acc->GetRefs(NickServ::nick)) + if (Anope::Match(na->GetNick(), this->Mask())) + return true; + + if (IRCD->IsChannelValid(this->Mask())) + { + ChanServ::Channel *tci = ChanServ::Find(this->Mask()); + if (tci) + { + for (unsigned i = 0; i < tci->GetAccessCount(); ++i) + { + ChanServ::ChanAccess *a = tci->GetAccess(i); + std::pair pair = std::make_pair(this, a); + + std::pair range = p.first.equal_range(this); + for (; range.first != range.second; ++range.first) + if (range.first->first == pair.first && range.first->second == pair.second) + goto cont; + + p.first.insert(pair); + if (a->Matches(u, acc, p)) + p.second.insert(pair); + + cont:; + } + + return p.second.count(this) > 0; + } + } + + return false; +} diff --git a/modules/pseudoclients/chanserv/chanaccess.h b/modules/pseudoclients/chanserv/chanaccess.h new file mode 100644 index 000000000..bb65f79c5 --- /dev/null +++ b/modules/pseudoclients/chanserv/chanaccess.h @@ -0,0 +1,30 @@ + +class ChanAccessImpl : public ChanServ::ChanAccess +{ + public: + ChanAccessImpl(Serialize::TypeBase *type) : ChanServ::ChanAccess(type) { } + ChanAccessImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::ChanAccess(type, id) { } + + ChanServ::Channel *GetChannel() override; + void SetChannel(ChanServ::Channel *ci) override; + + Anope::string GetCreator() override; + void SetCreator(const Anope::string &c) override; + + time_t GetLastSeen() override; + void SetLastSeen(const time_t &t) override; + + time_t GetCreated() override; + void SetCreated(const time_t &t) override; + + Anope::string GetMask() override; + void SetMask(const Anope::string &) override; + + Serialize::Object *GetObj() override; + void SetObj(Serialize::Object *) override; + + Anope::string Mask() override; + NickServ::Account *GetAccount() override; + + bool Matches(const User *u, NickServ::Account *acc, Path &p) override; +}; diff --git a/modules/pseudoclients/chanserv/chanaccesstype.h b/modules/pseudoclients/chanserv/chanaccesstype.h new file mode 100644 index 000000000..ca8dc1b79 --- /dev/null +++ b/modules/pseudoclients/chanserv/chanaccesstype.h @@ -0,0 +1,21 @@ + +class ChanAccessType : public Serialize::AbstractType +{ + public: + Serialize::ObjectField ci; + Serialize::Field mask; + Serialize::ObjectField obj; + Serialize::Field creator; + Serialize::Field last_seen; + Serialize::Field created; + + ChanAccessType(Module *me, const Anope::string &name) : Serialize::AbstractType(me, name) + , ci(this, "ci", true) + , mask(this, "mask") + , obj(this, "obj", true) + , creator(this, "creator") + , last_seen(this, "last_seen") + , created(this, "created") + { + } +}; diff --git a/modules/pseudoclients/chanserv/channel.h b/modules/pseudoclients/chanserv/channel.h index 995972ece..18a4be5d6 100644 --- a/modules/pseudoclients/chanserv/channel.h +++ b/modules/pseudoclients/chanserv/channel.h @@ -3,11 +3,9 @@ class ChannelImpl : public ChanServ::Channel { public: - //using ChanServ::Channel::Channel; ChannelImpl(Serialize::TypeBase *type) : ChanServ::Channel(type) { } ChannelImpl(Serialize::TypeBase *type, Serialize::ID id) : ChanServ::Channel(type, id) { } ChannelImpl(Serialize::TypeBase *type, const Anope::string &chname); - /*ChannelImpl(const ChanServ::Channel &ci);*/ ~ChannelImpl(); void Delete() override; diff --git a/modules/pseudoclients/chanserv/chanserv.cpp b/modules/pseudoclients/chanserv/chanserv.cpp index 5dd83188f..420051252 100644 --- a/modules/pseudoclients/chanserv/chanserv.cpp +++ b/modules/pseudoclients/chanserv/chanserv.cpp @@ -19,6 +19,8 @@ #include "channeltype.h" #include "leveltype.h" #include "modetype.h" +#include "chanaccesstype.h" +#include "chanaccess.h" class ChanServCore : public Module , public ChanServ::ChanServService @@ -52,7 +54,7 @@ class ChanServCore : public Module std::vector Privileges; ChanServ::registered_channel_map registered_channels; ChannelType channel_type; - ChanServ::ChanAccessType chanaccess_type; + ChanAccessType chanaccess_type; LevelType level_type; CSModeType mode_type; @@ -189,54 +191,6 @@ class ChanServCore : public Module Privileges.clear(); } - bool Matches(ChanServ::ChanAccess *access, const User *u, NickServ::Account *acc, ChanServ::ChanAccess::Path &p) override - { - if (access->GetAccount()) - return access->GetAccount() == acc; - - if (u) - { - bool is_mask = access->Mask().find_first_of("!@?*") != Anope::string::npos; - if (is_mask && Anope::Match(u->nick, access->Mask())) - return true; - else if (Anope::Match(u->GetDisplayedMask(), access->Mask())) - return true; - } - - if (acc) - for (NickServ::Nick *na : acc->GetRefs(NickServ::nick)) - if (Anope::Match(na->GetNick(), access->Mask())) - return true; - - if (IRCD->IsChannelValid(access->Mask())) - { - ChanServ::Channel *tci = Find(access->Mask()); - if (tci) - { - for (unsigned i = 0; i < tci->GetAccessCount(); ++i) - { - ChanServ::ChanAccess *a = tci->GetAccess(i); - std::pair pair = std::make_pair(access, a); - - std::pair range = p.first.equal_range(access); - for (; range.first != range.second; ++range.first) - if (range.first->first == pair.first && range.first->second == pair.second) - goto cont; - - p.first.insert(pair); - if (a->Matches(u, acc, p)) - p.second.insert(pair); - - cont:; - } - - return p.second.count(access) > 0; - } - } - - return false; - } - void OnReload(Configuration::Conf *conf) override { const Anope::string &channick = conf->GetModule(this)->Get("client"); diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index b36d8180b..9e70ab088 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -23,6 +23,16 @@ std::list ModuleManager::Modules; +void ModuleDef::Depends(const Anope::string &modname) +{ + dependencies.push_back(modname); +} + +const std::vector &ModuleDef::GetDependencies() +{ + return dependencies; +} + #ifdef _WIN32 void ModuleManager::CleanupRuntimeDirectory() { @@ -111,22 +121,6 @@ static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &out } #endif -/* This code was found online at http://www.linuxjournal.com/article/3687#comment-26593 - * - * This function will take a pointer from either dlsym or GetProcAddress and cast it in - * a way that won't cause C++ warnings/errors to come up. - */ -template static TYPE function_cast(void *symbol) -{ - union - { - void *symbol; - TYPE function; - } cast; - cast.symbol = symbol; - return cast.function; -} - ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) { if (modname.empty()) @@ -166,16 +160,18 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) } dlerror(); - Module *(*func)(const Anope::string &, const Anope::string &) = function_cast(dlsym(handle, "AnopeInit")); + AnopeModule *module = static_cast(dlsym(handle, "AnopeMod")); err = dlerror(); - if (!func) + if (!module || !module->init || !module->fini) { - Log() << "No init function found, not an Anope module"; + Log() << "No module symbols function found, not an Anope module"; if (err && *err) Log(LOG_DEBUG) << err; dlclose(handle); return MOD_ERR_NOLOAD; } + + ModuleDef *def = module->init(); /* Create module. */ Anope::string nick; @@ -187,7 +183,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) ModuleReturn moderr = MOD_ERR_OK; try { - m = func(modname, nick); + m = def->Create(modname, nick); } catch (const ModuleException &ex) { @@ -204,6 +200,8 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) m->filename = pbuf; m->handle = handle; + m->def = def; + m->module = module; ModuleVersion v = m->GetVersion(); if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor())) @@ -334,17 +332,13 @@ ModuleReturn ModuleManager::DeleteModule(Module *m) Log(LOG_DEBUG) << "Unloading module " << m->name; - dlerror(); - void (*destroy_func)(Module *m) = function_cast(dlsym(m->handle, "AnopeFini")); - const char *err = dlerror(); - if (!destroy_func || (err && *err)) - { - Log() << "No destroy function found for " << m->name << ", chancing delete..."; - delete m; /* we just have to chance they haven't overwrote the delete operator then... */ - } - else - destroy_func(m); /* Let the module delete it self, just in case */ + ModuleDef *def = m->def; + AnopeModule *module = m->module; + def->Destroy(m); + module->fini(def); + + dlerror(); if (dlclose(handle)) Log() << dlerror(); -- cgit