diff options
| author | 2007-04-12 20:37:06 +0000 | |
|---|---|---|
| committer | 2007-04-12 20:37:06 +0000 | |
| commit | f7f5ef659b7b5d1353c51239fa9a42c0481819f1 (patch) | |
| tree | d8c0a6b22ddfebb0fe2cf027821413baf6c30652 /src/modules/system/plugin.cpp | |
| parent | more QT4 fix: QSplitter (diff) | |
| download | KVIrc-f7f5ef659b7b5d1353c51239fa9a42c0481819f1.tar.gz KVIrc-f7f5ef659b7b5d1353c51239fa9a42c0481819f1.tar.bz2 KVIrc-f7f5ef659b7b5d1353c51239fa9a42c0481819f1.zip | |
added $system.call() to call functions of dll/so files
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@485 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src/modules/system/plugin.cpp')
| -rw-r--r-- | src/modules/system/plugin.cpp | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/src/modules/system/plugin.cpp b/src/modules/system/plugin.cpp new file mode 100644 index 000000000..1314c6127 --- /dev/null +++ b/src/modules/system/plugin.cpp @@ -0,0 +1,331 @@ +//============================================================================= +// +// File : plugin.cpp +// Creation date : Wed Apr 11 04 2007 00:54:00 GMT+1 by TheXception +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2007 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +//============================================================================= + +#include "plugin.h" + +#include "kvi_module.h" +#include "kvi_string.h" +#include "kvi_library.h" +#include "kvi_thread.h" +#include "kvi_locale.h" +#include "kvi_app.h" + +#include <qdir.h> +#include <qfileinfo.h> + +KviPlugin::KviPlugin() +{ +} + +KviPlugin::~KviPlugin() +{ +} + +bool KviPlugin::load(QString * pszPluginName) +{ + m_Plugin = kvi_library_open(pszPluginName->ascii()); + if (!m_Plugin) + { + return false; + } + + plugin_load function_load; + + function_load = (plugin_unload)kvi_library_symbol(m_Plugin,"_load"); + if (function_load) + { + // ADD: THREAD + function_load(); + } + return true; +} + +bool KviPlugin::unload(bool forced) +{ + plugin_unload function_unload; + + function_unload = (plugin_unload)kvi_library_symbol(m_Plugin,"_unload"); + if (function_unload) + { + // ADD: THREAD + if(!function_unload()) + { + if(!forced) return false; + } + } + + if(m_Plugin) + { + kvi_library_close(m_Plugin); + } + + return true; +} + +int KviPlugin::call(QString * pszFunctionName, int argc, char * argv[], char ** pBuffer) +{ + int r; + plugin_function function_call; + function_call = (plugin_function)kvi_library_symbol(m_Plugin,pszFunctionName->ascii()); + if (!function_call) + { + return -1; + } else { + // ADD: THREAD + r = function_call(argc,argv,pBuffer); + } + if (r < 0) r = 0; // negative numbers are for error handling. + return r; +} + +KviStr KviPlugin::name() +{ + return m_szName; +} + +void KviPlugin::setName(QString * Name) +{ + m_szName = Name->ascii(); +} + + +KviPluginManager::KviPluginManager() +{ + m_pPluginDict = new KviAsciiDict<KviPlugin>(17,false); + m_pPluginDict->setAutoDelete(false); + + m_bCanUnload = true; +} + +KviPluginManager::~KviPluginManager() +{ + delete m_pPluginDict; +} + +bool KviPluginManager::PluginCall(KviKvsModuleFunctionCall *c) +{ + QString szPluginName; //contains full path and plugin name like "c:/plugin.dll" + QString szSinglePluginName; // contains only the name of the plugin like "plugin.dll" + QString szFunctionName; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("plugin",KVS_PT_NONEMPTYSTRING,0,szPluginName) + KVSM_PARAMETER("function",KVS_PT_NONEMPTYSTRING,0,szFunctionName) + KVSM_PARAMETERS_END(c) + + //Check if there is such a plugin + if(!FindPlugin(&szPluginName, &szSinglePluginName)) + { + c->error(__tr2qs("Plugin not found. Please check the plugin-name and path.")); + return true; + } + + // Check if plugin is already loaded + if(!PluginIsLoaded(&szSinglePluginName)) + { + c->warning("Plugin not loaded yet"); //REMOVE + //If not loaded try to load now + if(!LoadPlugin(&szPluginName,&szSinglePluginName)) + { + c->error(__tr2qs("Error while loading plugin.")); + return true; + } + } else c->warning("Plugin already loaded"); //REMOVE + + c->warning(szPluginName); //REMOVE + + //Parsing more Parameters + int iArgc = 0; + char ** ppArgv; + char * pArgvBuffer; + + //Preparing argv buffer + if(c->parameterCount() > 2) + { + iArgc = c->parameterCount() - 2; + } + + + + if (iArgc > 0) + { + int i = 2; + QString tmp; + int iSize = 0; + + //Calculate buffer size + while (i < (iArgc + 2) ) + { + c->params()->at(i)->asString(tmp); + c->warning(tmp); + iSize += tmp.length()+1; //+1 for the \0 characters + i++; + } + + //Allocate buffer + ppArgv = (char**)malloc(iArgc*sizeof(char*)); + pArgvBuffer = (char*)malloc(iSize); + + i = 2; + char * x = 0; + x = pArgvBuffer; + while (i < (iArgc + 2) ) + { + ppArgv[i-2] = x; + c->params()->at(i)->asString(tmp); + strcpy(x,tmp.ascii()); + x += tmp.length(); + + *x = 0; + x++; + i++; + } + + } else { + //Avoid using unfilled variables + ppArgv = (char**)malloc(0); + pArgvBuffer = (char*)malloc(0); + } + + //Preparing return buffer + char * returnBuffer; + + KviPlugin * plugin; + + plugin = GetPlugin(&szSinglePluginName); + int r = plugin->call(&szFunctionName,iArgc,ppArgv,&returnBuffer); + + if(r == -1) + { + c->error(__tr2qs("This plugin does not export the desired function.")); + return true; + } + if (r > 0) + { + c->returnValue()->setString(returnBuffer); + } + + //Clean up + free(pArgvBuffer); + free(ppArgv); + free(returnBuffer); + return true; +} + +bool KviPluginManager::CheckUnload() +{ + /* + Always called when system module should be unloaded + Checking here if all small "modules" can be unloaded + */ + KviAsciiDictIterator<KviPlugin> it(*m_pPluginDict); + + m_bCanUnload = true; + + while(it.current()) + { + if(it.current()->unload(false)) + { + m_pPluginDict->remove(it.current()->name()); + } else { + m_bCanUnload = false; + } + } + + return m_bCanUnload; +} + +void KviPluginManager::UnloadAll(bool forced) +{ + KviAsciiDictIterator<KviPlugin> it(*m_pPluginDict); + + while(it.current()) + { + it.current()->unload(true); + m_pPluginDict->remove(it.current()->name()); + } +} + +bool KviPluginManager::FindPlugin(QString * pName, QString * pSingleName) +{ + QDir d; + QFileInfo fi; + QString szPath; + + //Trying to find the plugin directly + d.setPath(*pName); + d.convertToAbs(); // To be sure that path is completly absolute! + + fi.setFile(d.path()); + if(!fi.exists()) + { + //Plugin not found in direct way. Looking in kvirc local dir + g_pApp->getGlobalKvircDirectory(szPath,KviApp::None,"easyplugins/"+*pName); + + d.setPath(szPath); + d.convertToAbs(); // To be sure that path is completly absolute! + + fi.setFile(d.path()); + if(!fi.exists()) + { + //Plugin not found in kvirc local dir. Looking in kvirc global dir + g_pApp->getLocalKvircDirectory(szPath,KviApp::None,"easyplugins/"+*pName); + + d.setPath(szPath); + d.convertToAbs(); // To be sure that path is completly absolute! + + fi.setFile(d.path()); + if(!fi.exists()) + { + return false; + } + } + } + + *pName = d.path(); + *pSingleName = fi.fileName(); + + return true; +} + +bool KviPluginManager::PluginIsLoaded(QString * pSingleName) +{ + KviPlugin * p = m_pPluginDict->find(pSingleName->ascii()); + if (!p) return false; else return true; +} + +bool KviPluginManager::LoadPlugin(QString * pName, QString * pSingleName) +{ + KviPlugin * plugin = new KviPlugin(); + if(!plugin->load(pName)) return false; + plugin->setName(pSingleName); + m_pPluginDict->insert(pSingleName->ascii(),plugin); + return true; +} + +KviPlugin * KviPluginManager::GetPlugin(QString * pSingleName) +{ + KviPlugin * p = m_pPluginDict->find(pSingleName->ascii()); + return p; +}
\ No newline at end of file |
