diff --git a/Modules.cpp b/Modules.cpp index 8a89b5c8..f67cf565 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -201,13 +201,14 @@ CModule* CSocket::GetModule() const { return m_pModule; } const CString& CSocket::GetLabel() const { return m_sLabel; } /////////////////// !Socket /////////////////// -CModule::CModule(void* pDLL, CUser* pUser, const CString& sModName) { +CModule::CModule(void* pDLL, CUser* pUser, const CString& sModName, const CString& sDataDir) { m_bFake = false; m_pDLL = pDLL; m_pManager = &(CZNC::Get().GetManager());; m_pUser = pUser; m_pClient = NULL; m_sModName = sModName; + m_sDataDir = sDataDir; if (m_pUser) { m_sSavePath = m_pUser->GetUserPath() + "/moddata/" + m_sModName; @@ -215,13 +216,14 @@ CModule::CModule(void* pDLL, CUser* pUser, const CString& sModName) { } } -CModule::CModule(void* pDLL, const CString& sModName) { +CModule::CModule(void* pDLL, const CString& sModName, const CString& sDataDir) { m_bFake = false; m_pDLL = pDLL; m_pManager = &(CZNC::Get().GetManager()); m_pUser = NULL; m_pClient = NULL; m_sModName = sModName; + m_sDataDir = sDataDir; m_sSavePath = CZNC::Get().GetZNCPath() + "/moddata/" + m_sModName; LoadRegistry(); @@ -472,7 +474,6 @@ void CModule::ListSockets() { } } -const CString& CModule::GetModName() const { return m_sModName; } CString CModule::GetModNick() const { return ((m_pUser) ? m_pUser->GetStatusPrefix() : "*") + m_sModName; } bool CModule::OnLoad(const CString& sArgs, CString& sMessage) { sMessage = ""; return true; } @@ -678,15 +679,15 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p return false; } - CString sModPath = FindModPath(sModule); + CString sModPath, sDataPath; - if (sModPath.empty()) { + if (!CZNC::Get().FindModPath(sModule, sModPath, sDataPath)) { sRetMsg = "Unable to find module [" + sModule + "]"; return false; } if (bFake) { - CModule* pModule = new CModule(NULL, sModule); + CModule* pModule = new CModule(NULL, sModule, sDataPath); pModule->SetArgs(sArgs); pModule->SetDescription("<>"); pModule->SetFake(true); @@ -751,7 +752,8 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p CModule* pModule = NULL; if (pUser) { - typedef CModule* (*fp)(void*, CUser* pUser, const CString& sModName); + typedef CModule* (*fp)(void*, CUser* pUser, + const CString& sModName, const CString& sDataPath); fp Load = (fp) dlsym(p, "Load"); if (!Load) { @@ -760,9 +762,10 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p return false; } - pModule = Load(p, pUser, sModule); + pModule = Load(p, pUser, sModule, sDataPath); } else { - typedef CModule* (*fp)(void*, const CString& sModName); + typedef CModule* (*fp)(void*, const CString& sModName, + const CString& sDataPath); fp Load = (fp) dlsym(p, "Load"); if (!Load) { @@ -771,7 +774,7 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p return false; } - pModule = Load(p, sModule); + pModule = Load(p, sModule, sDataPath); } pModule->SetDescription(GetDesc()); @@ -879,10 +882,6 @@ bool CModules::ReloadModule(const CString& sModule, const CString& sArgs, CUser* return true; } -CString CModules::FindModPath(const CString& sModule) { - return CZNC::Get().FindModPath(sModule); -} - bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule) { for (unsigned int a = 0; a < sModule.length(); a++) { const char& c = sModule[a]; @@ -892,9 +891,9 @@ bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule) { } } - CString sModPath = FindModPath(sModule); - - if (sModPath.empty()) { + CString sModPath, sTmp; + + if (!CZNC::Get().FindModPath(sModule, sModPath, sTmp)) { return false; } diff --git a/Modules.h b/Modules.h index ad1108fc..2db40a8f 100644 --- a/Modules.h +++ b/Modules.h @@ -37,30 +37,39 @@ using std::set; #endif #define MODCONSTRUCTOR(CLASS) \ - CLASS(void *pDLL, CUser* pUser, const CString& sModName) : CModule(pDLL, pUser, sModName) + CLASS(void *pDLL, CUser* pUser, const CString& sModName, \ + const CString& sModPath) \ + : CModule(pDLL, pUser, sModName, sModPath) #define MODULEDEFS(CLASS, DESCRIPTION) \ extern "C" { \ CString GetDescription() { return DESCRIPTION; } \ bool IsGlobal() { return false; } \ - CModule* Load(void* p, CUser* pUser, const CString& sModName); \ + CModule* Load(void* p, CUser* pUser, const CString& sModName, \ + const CString& sModPath); \ void Unload(CModule* pMod); double GetVersion(); } \ double GetVersion() { return VERSION; } \ - CModule* Load(void* p, CUser* pUser, const CString& sModName) { return new CLASS(p, pUser, sModName); } \ + CModule* Load(void* p, CUser* pUser, const CString& sModName, \ + const CString& sModPath) \ + { return new CLASS(p, pUser, sModName, sModPath); } \ void Unload(CModule* pMod) { if (pMod) { delete pMod; } \ } // !User Module Macros // Global Module Macros #define GLOBALMODCONSTRUCTOR(CLASS) \ - CLASS(void *pDLL, const CString& sModName) : CGlobalModule(pDLL, sModName) + CLASS(void *pDLL, const CString& sModName, const CString& sModPath) \ + : CGlobalModule(pDLL, sModName, sModPath) #define GLOBALMODULEDEFS(CLASS, DESCRIPTION) \ extern "C" { \ CString GetDescription() { return DESCRIPTION; } \ bool IsGlobal() { return true; } \ - CGlobalModule* Load(void* p, const CString& sModName); \ + CGlobalModule* Load(void* p, const CString& sModName, \ + const CString& sModPath); \ void Unload(CGlobalModule* pMod); double GetVersion(); } \ double GetVersion() { return VERSION; } \ - CGlobalModule* Load(void* p, const CString& sModName) { return new CLASS(p, sModName); } \ + CGlobalModule* Load(void* p, const CString& sModName, \ + const CString& sModPath) \ + { return new CLASS(p, sModName, sModPath); } \ void Unload(CGlobalModule* pMod) { if (pMod) { delete pMod; } \ } // !Global Module Macros @@ -195,8 +204,9 @@ protected: class CModule { public: - CModule(void* pDLL, CUser* pUser, const CString& sModName); - CModule(void* pDLL, const CString& sModName); + CModule(void* pDLL, CUser* pUser, const CString& sModName, + const CString& sDataDir); + CModule(void* pDLL, const CString& sModName, const CString& sDataDir); virtual ~CModule(); typedef enum { @@ -272,7 +282,9 @@ public: virtual bool PutModule(const CString& sLine, const CString& sIdent = "znc", const CString& sHost = "znc.com"); virtual bool PutModNotice(const CString& sLine, const CString& sIdent = "znc", const CString& sHost = "znc.com"); - const CString& GetModName() const; + const CString& GetModName() const { return m_sModName; } + // This is where constant module data (e.g. webadmin skins) are saved + const CString& GetModDataDir() const { return m_sDataDir; } CString GetModNick() const; // Timer stuff @@ -321,19 +333,20 @@ public: // !Getters protected: - bool m_bFake; - CString m_sDescription; - vector m_vTimers; - vector m_vSockets; - void* m_pDLL; - CSockManager* m_pManager; - CUser* m_pUser; - CClient* m_pClient; - CString m_sModName; - CString m_sSavePath; - CString m_sArgs; + bool m_bFake; + CString m_sDescription; + vector m_vTimers; + vector m_vSockets; + void* m_pDLL; + CSockManager* m_pManager; + CUser* m_pUser; + CClient* m_pClient; + CString m_sModName; + CString m_sDataDir; + CString m_sSavePath; + CString m_sArgs; private: - MCString m_mssRegistry; //!< way to save name/value pairs. Note there is no encryption involved in this + MCString m_mssRegistry; //!< way to save name/value pairs. Note there is no encryption involved in this }; class CModules : public vector { @@ -399,7 +412,6 @@ public: bool UnloadModule(const CString& sModule); bool UnloadModule(const CString& sModule, CString& sRetMsg); bool ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg); - CString FindModPath(const CString& sModule); bool GetModInfo(CModInfo& ModInfo, const CString& sModule); void GetAvailableMods(set& ssMods, bool bGlobal = false); @@ -410,7 +422,8 @@ protected: class CGlobalModule : public CModule { public: - CGlobalModule(void* pDLL, const CString& sModName) : CModule(pDLL, sModName) {} + CGlobalModule(void* pDLL, const CString& sModName, + const CString &sDataDir) : CModule(pDLL, sModName, sDataDir) {} virtual ~CGlobalModule() {} virtual EModRet OnConfigLine(const CString& sName, const CString& sValue, CUser* pUser, CChan* pChan); diff --git a/configure b/configure index 4a070fc7..35fe825f 100755 --- a/configure +++ b/configure @@ -641,6 +641,7 @@ NOSSL PERL SASL MODDIR +DATADIR LIBOBJS LTLIBOBJS' ac_subst_files='' @@ -1243,6 +1244,8 @@ Optional Packages: --with-module-prefix=/path/to/moduledir + --with-module-data-prefix=/path/to/moduledir + Some influential environment variables: CXX C++ compiler command @@ -3633,10 +3636,20 @@ fi if test "${with_module_prefix+set}" = set; then withval=$with_module_prefix; MODDIR=$withval else - MODDIR="${prefix}/libexec/znc" + MODDIR="${libdir}/znc" fi + +# Check whether --with-module-data-prefix was given. +if test "${with_module_data_prefix+set}" = set; then + withval=$with_module_data_prefix; DATADIR=$withval +else + DATADIR="${datadir}/znc" +fi + + + if test "$MODULES" = "yes"; then if test -z "$NOCHECK_DL"; then @@ -3734,6 +3747,7 @@ fi fi appendCXX "-D_MODDIR_=\\\"${MODDIR}\\\"" + appendCXX "-D_DATADIR_=\\\"${DATADIR}\\\"" if test -z "$NOPERL"; then echo -n "checking for perl... " @@ -3915,6 +3929,7 @@ VERSION=0.053 + ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files znc-config" @@ -4618,11 +4633,12 @@ NOSSL!$NOSSL$ac_delim PERL!$PERL$ac_delim SASL!$SASL$ac_delim MODDIR!$MODDIR$ac_delim +DATADIR!$DATADIR$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 67; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 68; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/main.h b/main.h index c268cf8f..7b02bd7e 100644 --- a/main.h +++ b/main.h @@ -13,7 +13,11 @@ #define VERSION 0.053 #ifndef _MODDIR_ -#define _MODDIR_ "/usr/libexec/znc" +#define _MODDIR_ "/usr/lib/znc" +#endif + +#ifndef _DATADIR_ +#define _DATADIR_ "/usr/share/znc" #endif #ifdef _MODULES diff --git a/modules/modperl.cpp b/modules/modperl.cpp index ca179323..4a1cd702 100644 --- a/modules/modperl.cpp +++ b/modules/modperl.cpp @@ -238,8 +238,9 @@ public: void SetupZNCScript() { - CString sModule = CZNC::Get().FindModPath( "modperl.pm" ); - if ( !sModule.empty() ) + CString sModule, sTmp; + + if ( CZNC::Get().FindModPath( "modperl.pm", sModule, sTmp) ) { CString sBuffer, sScript; CFile cFile( sModule ); @@ -1035,8 +1036,9 @@ void CModPerl::LoadPerlMod( const CString & sModule ) return; } - CString sModPath = CZNC::Get().FindModPath( sModule ); - if ( sModPath.empty() ) + CString sModPath, sTmp; + + if ( !CZNC::Get().FindModPath(sModule, sModPath, sTmp)) PutStatus( "No such module " + sModule ); else { diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index c1b0cdb6..b7c8e001 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -221,23 +221,14 @@ private: }; CString CWebAdminSock::GetSkinDir() { - CString sModPath = CZNC::Get().FindModPath(m_pModule->GetModName()); // @todo store the path to the module at load time and store it in a member var which can be used here - - // Remove the file.so portion from the path - while (!sModPath.empty() && sModPath.Right(1) != "/") { - sModPath.RightChomp(); - } - - // Remove the last / - sModPath.RightChomp(); - - CString sSkinDir = sModPath + "/" + m_pModule->GetModName() + "/skins/" + m_pModule->GetSkinName() + "/"; + CString sSkinDir = m_pModule->GetModDataDir() + "/skins/" + + m_pModule->GetSkinName() + "/"; if (CDir::Exists(sSkinDir)) { return sSkinDir; } - return sModPath + "/" + m_pModule->GetModName() + "/skins/default/"; + return m_pModule->GetModDataDir() + "/skins/default/"; } void CWebAdminSock::PrintPage(CString& sPageRet, const CString& sTmplName) { diff --git a/znc.cpp b/znc.cpp index 40727f98..248f0a31 100644 --- a/znc.cpp +++ b/znc.cpp @@ -1261,28 +1261,33 @@ void CZNC::Broadcast(const CString& sMessage, CUser* pUser) { } } -CString CZNC::FindModPath(const CString& sModule) const { - CString sModPath = GetCurPath() + "/modules/" + sModule; - sModPath += (sModule.find(".") == CString::npos) ? ".so" : ""; +bool CZNC::FindModPath(const CString& sModule, CString& sModPath, + CString& sDataPath) const { + CString sMod = sModule; + CString sDir = sMod; + if (sModule.find(".") == CString::npos) + sMod += ".so"; + + sDataPath = GetCurPath() + "/modules/"; + sModPath = sDataPath + sMod; if (!CFile::Exists(sModPath)) { - //DEBUG_ONLY(cout << "[" << sModPath << "] Not found..." << endl); - sModPath = GetModPath() + "/" + sModule; - sModPath += (sModule.find(".") == CString::npos) ? ".so" : ""; + sDataPath = GetModPath() + "/"; + sModPath = sDataPath + sMod; if (!CFile::Exists(sModPath)) { - //DEBUG_ONLY(cout << "[" << sModPath << "] Not found..." << endl); - sModPath = _MODDIR_ + CString("/") + sModule; - sModPath += (sModule.find(".") == CString::npos) ? ".so" : ""; + sDataPath = _DATADIR_ + CString("/"); + sModPath = _MODDIR_ + CString("/") + sMod; if (!CFile::Exists(sModPath)) { - //DEBUG_ONLY(cout << "[" << sModPath << "] Not found... giving up!" << endl); - return ""; + return false; } } } - return sModPath; + sDataPath += sDir; + + return true; } CUser* CZNC::FindUser(const CString& sUsername) { diff --git a/znc.h b/znc.h index f201c313..8b5dbe6f 100644 --- a/znc.h +++ b/znc.h @@ -109,7 +109,10 @@ public: bool WriteNewConfig(const CString& sConfig); bool WriteConfig(); static CString GetTag(bool bIncludeVersion = true); - CString FindModPath(const CString& sModule) const; + // This returns the path to the .so and to the data dir + // which is where static data (webadmin skins) are saved + bool FindModPath(const CString& sModule, CString& sModPath, + CString& sDataPath) const; void ClearVHosts(); bool AddVHost(const CString& sHost); bool RemVHost(const CString& sHost);