aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/system/plugin.cpp
diff options
context:
space:
mode:
authorGravatar TheXception2007-04-12 20:37:06 +0000
committerGravatar TheXception2007-04-12 20:37:06 +0000
commitf7f5ef659b7b5d1353c51239fa9a42c0481819f1 (patch)
treed8c0a6b22ddfebb0fe2cf027821413baf6c30652 /src/modules/system/plugin.cpp
parentmore QT4 fix: QSplitter (diff)
downloadKVIrc-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.cpp331
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