diff options
author | Adam <Adam@anope.org> | 2015-10-27 13:21:24 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2015-10-27 13:21:24 -0400 |
commit | 162fdbe5815bbdf187f549fefac94ff476d72e62 (patch) | |
tree | 1c58968fd29dd90ef8ab6dc0f3013d88b313ce4e | |
parent | c6a92296d4175a2d2276c2d5a46894af3d9085f4 (diff) |
Beginning of new module dependency stuff, seems to compile and link. Move some of the madness in chanserv.h to the module.
-rw-r--r-- | cmake/Anope.cmake | 17 | ||||
-rw-r--r-- | include/modules.h | 72 | ||||
-rw-r--r-- | include/modules/chanserv.h | 141 | ||||
-rw-r--r-- | modules/CMakeLists.txt | 10 | ||||
-rw-r--r-- | modules/commands/cs_access.cpp | 19 | ||||
-rw-r--r-- | modules/commands/cs_flags.cpp | 17 | ||||
-rw-r--r-- | modules/commands/cs_xop.cpp | 17 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv/chanaccess.cpp | 127 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv/chanaccess.h | 30 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv/chanaccesstype.h | 21 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv/channel.h | 2 | ||||
-rw-r--r-- | modules/pseudoclients/chanserv/chanserv.cpp | 52 | ||||
-rw-r--r-- | src/modulemanager.cpp | 54 |
13 files changed, 337 insertions, 242 deletions
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<Anope::string> 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<Anope::string> &GetDependencies(); +}; + +template<class ModuleClass> 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<ModuleClass>(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<Privilege> &GetPrivileges() anope_abstract; virtual void ClearPrivileges() anope_abstract; - - //XXX - typedef std::multimap<ChanAccess *, ChanAccess *> Set; - typedef std::pair<Set, Set> Path; - virtual bool Matches(ChanAccess *, const User *u, NickServ::Account *acc, Path &p) anope_abstract; }; static ServiceReference<ChanServService> 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<Privilege> &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<Privilege> &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<ChanServ::ChanAccess, ChanServ::Channel *> ci; - Serialize::Field<ChanServ::ChanAccess, Anope::string> mask; - Serialize::ObjectField<ChanServ::ChanAccess, Serialize::Object *> obj; - Serialize::Field<ChanServ::ChanAccess, Anope::string> creator; - Serialize::Field<ChanServ::ChanAccess, time_t> last_seen; - Serialize::Field<ChanServ::ChanAccess, time_t> 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<NickServ::Account *>(GetObj()); - } - static Serialize::TypeReference<ChanAccess> 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<AccessChanAccess *>(&other)->GetLevel(); } +#endif }; -class AccessChanAccessType : public Serialize::Type<AccessChanAccess, ChanServ::ChanAccessType> +class AccessChanAccessType : public Serialize::Type<AccessChanAccess, ChanAccessType> { public: Serialize::Field<AccessChanAccess, int> level; @@ -920,4 +926,9 @@ class CSAccess : public Module } }; +template<> void ModuleInfo<CSAccess>(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<Anope::string, char> 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<FlagsChanAccess, ChanServ::ChanAccessType> +class FlagsChanAccessType : public Serialize::Type<FlagsChanAccess, ChanAccessType> { public: Serialize::Field<FlagsChanAccess, Anope::string> flags; @@ -518,4 +522,9 @@ class CSFlags : public Module } }; +template<> void ModuleInfo<CSFlags>(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<Anope::string, std::vector<Anope::string> > 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<XOPChanAccess, ChanServ::ChanAccessType> +class XOPChanAccessType : public Serialize::Type<XOPChanAccess, ChanAccessType> { public: Serialize::Field<XOPChanAccess, Anope::string> type; @@ -648,4 +652,9 @@ class CSXOP : public Module } }; +template<> void ModuleInfo<CSXOP>(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<NickServ::Account *>(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 *>(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<ChanServ::ChanAccess *, ChanServ::ChanAccess *> pair = std::make_pair(this, a); + + std::pair<Set::iterator, Set::iterator> 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<ChanServ::ChanAccess, ChanServ::Channel *> ci; + Serialize::Field<ChanServ::ChanAccess, Anope::string> mask; + Serialize::ObjectField<ChanServ::ChanAccess, Serialize::Object *> obj; + Serialize::Field<ChanServ::ChanAccess, Anope::string> creator; + Serialize::Field<ChanServ::ChanAccess, time_t> last_seen; + Serialize::Field<ChanServ::ChanAccess, time_t> 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<ChanServ::Privilege> 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 *>(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<ChanServ::ChanAccess *, ChanServ::ChanAccess *> pair = std::make_pair(access, a); - - std::pair<Set::iterator, Set::iterator> 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<Anope::string>("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<Module *> ModuleManager::Modules; +void ModuleDef::Depends(const Anope::string &modname) +{ + dependencies.push_back(modname); +} + +const std::vector<Anope::string> &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 <class TYPE> 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<Module *(*)(const Anope::string &, const Anope::string &)>(dlsym(handle, "AnopeInit")); + AnopeModule *module = static_cast<AnopeModule *>(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<void (*)(Module *)>(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(); |