summaryrefslogtreecommitdiffstats
path: root/src/modules/system
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
commita6d58bb6052ac8cb01805a48c4ad2f129126116f (patch)
treedd867a099fcbb263a8009a9fb22695b87855dad6 /src/modules/system
downloadkvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.tar.gz
kvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.zip
Added KDE3 version of kvirc
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/modules/system')
-rw-r--r--src/modules/system/Makefile.am18
-rw-r--r--src/modules/system/libkvisystem.cpp749
-rw-r--r--src/modules/system/plugin.cpp427
-rw-r--r--src/modules/system/plugin.h80
4 files changed, 1274 insertions, 0 deletions
diff --git a/src/modules/system/Makefile.am b/src/modules/system/Makefile.am
new file mode 100644
index 00000000..69302d13
--- /dev/null
+++ b/src/modules/system/Makefile.am
@@ -0,0 +1,18 @@
+###############################################################################
+# KVirc IRC client Makesystem - 10.03.2000 Szymon Stefanek <stefanek@tin.it>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvisystem.la
+
+libkvisystem_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvisystem_la_SOURCES = libkvisystem.cpp plugin.cpp
+libkvisystem_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS = plugin.h
+
+%.moc: %.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/system/libkvisystem.cpp b/src/modules/system/libkvisystem.cpp
new file mode 100644
index 00000000..54ada405
--- /dev/null
+++ b/src/modules/system/libkvisystem.cpp
@@ -0,0 +1,749 @@
+//=============================================================================
+//
+// File : libkvisystem.cpp
+// Creation date : Fri Nov 16 03:50:12 2001 GMT by Szymon Stefanek
+//
+// This system is part of the KVirc irc client distribution
+// Copyright (C) 2001-2005 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_module.h"
+#include "kvi_string.h"
+#include "kvi_library.h"
+#include "kvi_thread.h"
+
+#include "kvi_locale.h"
+#include "kvi_qcstring.h"
+#include "kvi_app.h"
+#include "kvi_env.h"
+#include "kvi_osinfo.h"
+#include "kvi_qcstring.h"
+
+#include <qclipboard.h>
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <sys/utsname.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+#endif
+
+#ifdef COMPILE_KDE_SUPPORT
+ #include <dcopclient.h>
+#endif
+
+#include "kvi_modulemanager.h"
+
+#include "plugin.h"
+
+KviPluginManager * g_pPluginManager;
+
+/*
+ @doc: system.ostype
+ @type:
+ function
+ @title:
+ $system.ostype
+ @short:
+ Returns the type of the operating system
+ @syntax:
+ <string> $system.ostype()
+ @description:
+ Returns the current type of operating system: unix,macosx or windows.[br]
+*/
+
+static bool system_kvs_fnc_ostype(KviKvsModuleFunctionCall * c)
+{
+ c->returnValue()->setString(KviOsInfo::type());
+ return true;
+}
+/*
+ @doc: system.osname
+ @type:
+ function
+ @title:
+ $system.osname
+ @short:
+ Returns the name of the operating system
+ @syntax:
+ <string> $system.osname()
+ @description:
+ Returns the name of the operating system. On UNIX like machines
+ this is the field sysname of the utsname structure returned by
+ the uname() syscall.
+*/
+
+static bool system_kvs_fnc_osname(KviKvsModuleFunctionCall *c)
+{
+ c->returnValue()->setString(KviOsInfo::name());
+ return true;
+}
+
+
+/*
+ @doc: system.osversion
+ @type:
+ function
+ @title:
+ $system.osversion
+ @short:
+ Returns the version of the operating system
+ @syntax:
+ <string> $system.osversion()
+ @description:
+ Returns the version of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osversion(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::version());
+ return true;
+}
+
+/*
+ @doc: system.osrelease
+ @type:
+ function
+ @title:
+ $system.osrelease
+ @short:
+ Returns the release of the operating system
+ @syntax:
+ <string> $system.osrelease()
+ @description:
+ Returns the release of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osrelease(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::release());
+ return true;
+}
+
+/*
+ @doc: system.osmachine
+ @type:
+ function
+ @title:
+ $system.osmachine
+ @short:
+ Returns the machine of the operating system
+ @syntax:
+ <string> $system.osmachine()
+ @description:
+ Returns the machine of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osmachine(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::machine());
+ return true;
+}
+
+/*
+ @doc: system.osnodename
+ @type:
+ function
+ @title:
+ $system.osnodename
+ @short:
+ Returns the nodename of the operating system
+ @syntax:
+ <string> $system.osnodename()
+ @description:
+ Returns the nodename of the operating system.[br]
+*/
+
+static bool system_kvs_fnc_osnodename(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::nodename());
+ return true;
+}
+
+/*
+ @doc: system.getenv
+ @keyterms:
+ Enviroinement variables
+ @type:
+ function
+ @title:
+ $system.getenv
+ @short:
+ Returns the value of an enviroinement variable
+ @syntax:
+ <string> $system.getenv(<variable:string>)
+ @description:
+ Returns the value of the enviroinement <variable>.[br]
+*/
+
+static bool system_kvs_fnc_getenv(KviKvsModuleFunctionCall *c)
+{
+ QString szVariable;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("variable",KVS_PT_NONEMPTYSTRING,0,szVariable)
+ KVSM_PARAMETERS_END(c)
+
+ KviQCString szVar = szVariable.local8Bit();
+#ifdef COMPILE_ON_WINDOWS
+ QString env = getenv(szVar.data());
+ QString def = __tr2qs("No environment variable found, please don't use the %% in the request");
+ c->returnValue()->setString(env.isEmpty() ? QString::fromLocal8Bit(env) : QString::fromLocal8Bit(def));
+#else
+ char * b = kvi_getenv(szVar.data());
+ c->returnValue()->setString(b ? QString::fromLocal8Bit(b) : QString::null);
+#endif
+ return true;
+}
+
+/*
+ @doc: system.clipboard
+ @keyterms:
+ Clipboard management
+ @type:
+ function
+ @title:
+ $system.clipboard
+ @short:
+ Returns the value of the system clipboard
+ @syntax:
+ <string> $system.clipboard()
+ @description:
+ Returns the current value of the system clipboard.
+ Please note that there are systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as the clipboard.
+ See [fnc]$system.selection[/fnc]().
+ @seealso:
+ [fnc]$system.selection[/fnc],
+ [cmd]system.setClipboard[/cmd],
+ [cmd]system.setSelection[/cmd]
+*/
+
+static bool system_kvs_fnc_clipboard(KviKvsModuleFunctionCall *c)
+{
+ c->returnValue()->setString(g_pApp->clipboard()->text(QClipboard::Clipboard));
+ return true;
+}
+
+
+/*
+ @doc: system.setClipboard
+ @type:
+ command
+ @title:
+ system.setClipboard
+ @keyterms:
+ Clipboard management
+ @short:
+ Sets the current system clipboard contents
+ @syntax:
+ system.setClipboard <data:string>
+ @description:
+ Sets the system clipboard contents to the string <data>.
+ Please note that there are systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as the clipboard.
+ See [fnc]$system.selection[/fnc]().
+ @seealso:
+ [fnc]$system.selection[/fnc],
+ [fnc]$system.clipboard[/fnc],
+ [cmd]system.setSelection[/cmd]
+*/
+
+static bool system_kvs_cmd_setClipboard(KviKvsModuleCommandCall * c)
+{
+ QString szValue;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+ g_pApp->clipboard()->setText(szValue,QClipboard::Clipboard);
+ return true;
+}
+
+/*
+ @doc: system.setSelection
+ @type:
+ command
+ @title:
+ system.setSelection
+ @keyterms:
+ Clipboard management
+ @short:
+ Sets the current system selection contents
+ @syntax:
+ system.setSelection <data:string>
+ @description:
+ Sets the system selection contents to the string <data>.
+ Please note that this command will work only on systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as the clipboard.
+ @seealso:
+ [fnc]$system.selection[/fnc],
+ [fnc]$system.clipboard[/fnc],
+ [cmd]system.setClipboard[/cmd]
+*/
+
+static bool system_kvs_cmd_setSelection(KviKvsModuleCommandCall * c)
+{
+ QString szValue;
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("data",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+ g_pApp->clipboard()->setText(szValue,QClipboard::Selection);
+ return true;
+}
+
+/*
+ @doc: system.selection
+ @keyterms:
+ Clipboard management
+ @type:
+ function
+ @title:
+ $system.selection
+ @short:
+ Returns the value of the system selection
+ @syntax:
+ <string> $system.selection()
+ @description:
+ Returns the current value of the system selection.
+ This function will work only on systems that have the concept
+ of "selection" (most notably X11) which is NOT the same as clipboard.
+ On other systems this function will always return an empty string.
+ See [fnc]$system.clipboard[/fnc]().
+ @seealso:
+ [fnc]$system.clipboard[/fnc],
+ [cmd]system.setClipboard[/cmd],
+ [cmd]system.setSelection[/cmd]
+*/
+
+static bool system_kvs_fnc_selection(KviKvsModuleFunctionCall *c)
+{
+ c->returnValue()->setString(g_pApp->clipboard()->text(QClipboard::Selection));
+ return true;
+}
+
+
+/*
+ @doc: system.checkModule
+ @keyterms:
+ Module checking
+ @type:
+ function
+ @title:
+ $system.checkModule
+ @short:
+ Checks if a KVIrc module is loadable
+ @syntax:
+ <boolean> $system.checkModule(<module_name:string>)
+ @description:
+ Attempts to load the specified module and returns
+ $true if succesfull and $false otherwise. This can
+ be effectively used to test if a KVIrc exension module
+ is present on the system and can be loaded by the
+ KVIrc engine.
+*/
+
+static bool system_kvs_fnc_checkModule(KviKvsModuleFunctionCall *c)
+{
+ QString szModuleName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("module_name",KVS_PT_STRING,0,szModuleName)
+ KVSM_PARAMETERS_END(c)
+
+ c->returnValue()->setBoolean(g_pModuleManager->loadModule(szModuleName.utf8().data()));
+ return true;
+}
+
+
+/*
+ @doc: system.hostname
+ @keyterms:
+ System information
+ @type:
+ function
+ @title:
+ $system.hostname
+ @short:
+ Returns the hostname of the machine that KVIrc is running on
+ @syntax:
+ <string> $system.hostname()
+ @description:
+ Returns the hostname of the machine that KVIrc is running on.[br]
+*/
+
+static bool system_kvs_fnc_hostname(KviKvsModuleFunctionCall *c)
+{
+ // no params to process
+ c->returnValue()->setString(KviOsInfo::hostname());
+ return true;
+}
+
+
+/*
+ @doc: system.dcop
+ @keyterms:
+ System information
+ @type:
+ function
+ @title:
+ $system.dcop
+ @short:
+ Performs a DCOP call
+ @syntax:
+ <variant> $system.dcop(<application:string>,<objectid:string>,<function:string>[,<parameter1:string>[,<parameter2:string>[,...]]])
+ @description:
+ This function allows performing simple DCOP calls without executing
+ an external process. This feature is available ONLY when KDE support
+ is compiled in the executable: this means that this function is absolutely
+ non portable (don't use it in scripts that you're going to distribute).
+ <application> is the name of the application being called, <objectid> is the
+ identifier of the object called, <function> is the function to be executed
+ on the remote object and <parameter1>,<parameter2>,... is the list of
+ parameters to be passed. The <function> name must contain the
+ trailing parenthesis and parameter specification (see examples).
+ The parameters MUST be in the form "type=value"
+ where "type" is the C++ type of the parameter and value
+ is the string rappresentation of the parameter data. Currently
+ KVIrc supports only QString,KviQCString,bool,int and uint data types.[br]
+ The returned value is the string rappresentation of the returned
+ data if the return type is known, otherwise it is the name of the data type returned.
+ [br]
+ If the application name is prefixed with "?" then the call is performed in "remote test"
+ mode: no "remote" errors are printed and the function returns 1 if the call executed
+ succesfully and 0 if the call failed. This can be used with the very first
+ call to programmaticaly test if the remote application is running.
+ @examples:
+ [example]
+ echo $system.dcop("kdesktop","KBackgroundIface","currentWallpaper(int)","int=0")
+ echo $system.dcop("kdesktop","KScreensaverIface","lock()")
+ # we can also ignore the return value in several ways
+ %dummy = $system.dcop("kicker","kicker","showKMenu()")
+ $system.dcop("kdesktop","KScreensaverIface","save()")
+ $system.dcop("kicker","Panel","addBrowserButton(QString)","QString=/")
+ # runtime test if a call would work (i.e. , kicker is running at all, parameters are right etc...)
+ if($system.dcop("?kicker","kicker","showKMenu()"))echo "Can't make dcop calls to kicker!"
+ [/example]
+*/
+
+static bool system_kvs_fnc_dcop(KviKvsModuleFunctionCall *c)
+{
+ bool bTestMode = false;
+
+ KviQCString szApp,szObj,szFun;
+ QStringList parms;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("application",KVS_PT_NONEMPTYCSTRING,0,szApp)
+ KVSM_PARAMETER("objectid",KVS_PT_NONEMPTYCSTRING,0,szObj)
+ KVSM_PARAMETER("function",KVS_PT_NONEMPTYCSTRING,0,szFun)
+ KVSM_PARAMETER("parameter_list",KVS_PT_STRINGLIST,KVS_PF_OPTIONAL,parms)
+ KVSM_PARAMETERS_END(c)
+
+ if((szApp.data()) && (szApp.length() > 1))
+ {
+ if(*(szApp.data()) == '?')
+ {
+ bTestMode = true;
+ szApp.remove(0,1);
+ }
+ }
+
+#ifdef COMPILE_KDE_SUPPORT
+
+ QByteArray ba;
+ QDataStream ds(ba, IO_WriteOnly);
+
+ for ( QStringList::Iterator it = parms.begin(); it != parms.end(); ++it )
+ {
+ KviStr tmp = *it;
+
+ if(tmp.isEmpty())
+ {
+ c->warning(__tr2qs("Invalid DCOP parameter syntax"));
+ return false;
+ }
+
+ KviStr szType = tmp.leftToFirst('=',false);
+ tmp.cutToFirst('=',true);
+ if(szType.isEmpty())szType = "int";
+ bool bOk;
+ if(kvi_strEqualCI("int",szType.ptr()) || kvi_strEqualCI("long",szType.ptr()))
+ {
+ int iii = tmp.toInt(&bOk);
+ if(!bOk)
+ {
+ c->warning(__tr2qs("The specified parameter is not an integer"));
+ return false;
+ }
+ ds << iii;
+ } else if(kvi_strEqualCI("QString",szType.ptr()))
+ {
+ QString ddd = tmp.ptr();
+ ds << ddd;
+ } else if(kvi_strEqualCI("KviQCString",szType.ptr()))
+ {
+ KviQCString qcs = tmp.ptr();
+ ds << qcs;
+ } else if(kvi_strEqualCI("bool",szType.ptr()))
+ {
+ bool bbb = kvi_strEqualCI(tmp.ptr(),"true");
+ ds << bbb;
+ } else if(kvi_strEqualCI("unsigned int",szType.ptr()) || kvi_strEqualCI("uint",szType.ptr()) || kvi_strEqualCI("Q_UINT32",szType.ptr()))
+ {
+ unsigned int uii = tmp.toUInt(&bOk);
+ if(!bOk)
+ {
+ c->warning(__tr2qs("The specified parameter is not an integer"));
+ return false;
+ }
+ ds << uii;
+ } else {
+ c->warning(__tr2qs("Unsupported DCOP parameter type %s"),tmp.ptr());
+ return false;
+ }
+ }
+
+ QByteArray rba;
+ KviQCString szRetType;
+
+ bool bRet = g_pApp->dcopClient()->call(szApp,szObj,szFun,ba,szRetType,rba);
+
+ if(!bRet)
+ {
+ if(!bTestMode)
+ c->warning(__tr2qs("DCOP call failed"));
+ c->returnValue()->setInteger(0);
+ } else {
+ if(bTestMode)
+ c->returnValue()->setInteger(1);
+ else {
+ QDataStream ret(rba, IO_ReadOnly);
+ if(szRetType == "bool")
+ {
+ bool bqw;
+ ret >> bqw;
+ c->returnValue()->setInteger(bqw ? 1 : 0);
+ } else if(szRetType == "QString")
+ {
+ QString szz;
+ ret >> szz;
+ c->returnValue()->setString(szz);
+ } else if(szRetType == "QCString")
+ {
+ KviQCString sss;
+ ret >> sss;
+ c->returnValue()->setString(sss.data());
+ } else if((szRetType == "uint") || (szRetType == "unsigned int") || (szRetType == "Q_UINT32"))
+ {
+ unsigned int ui3;
+ ret >> ui3;
+ c->returnValue()->setInteger(ui3);
+ } else if((szRetType == "int") || (szRetType == "long"))
+ {
+ int iii;
+ ret >> iii;
+ c->returnValue()->setInteger(iii);
+ } else if(szRetType == "QCStringList")
+ {
+#ifndef COMPILE_USE_QT4
+ QCStringList csl;
+ ret >> csl;
+ KviKvsArray * arry = new KviKvsArray();
+ int idx = 0;
+ for(QCStringList::Iterator iter = csl.begin();iter != csl.end();++iter)
+ {
+ arry->set(idx,new KviKvsVariant(QString(*iter)));
+ idx++;
+ }
+ c->returnValue()->setArray(arry);
+#endif
+ } else if(szRetType == "QStringList")
+ {
+ QStringList csl;
+ ret >> csl;
+ KviKvsArray * arry = new KviKvsArray();
+ int idx = 0;
+ for(QStringList::Iterator iter = csl.begin();iter != csl.end();++iter)
+ {
+ arry->set(idx,new KviKvsVariant(*iter));
+ idx++;
+ }
+ c->returnValue()->setArray(arry);
+ } else {
+ c->returnValue()->setString(szRetType.data());
+ }
+ }
+ }
+#else
+ if(!bTestMode)
+ c->warning(__tr2qs("DCOP calls are available only when KDE support is compiled in"));
+ c->returnValue()->setInteger(0);
+#endif
+
+ return true;
+}
+
+
+/*
+ @doc: system.setenv
+ @type:
+ command
+ @title:
+ system.setenv
+ @keyterms:
+ Enviroinement variables
+ @short:
+ Sets an enviroinement variable
+ @syntax:
+ system.setenv <variable:string> [<value:string>]
+ @description:
+ Sets the enviroinement <variable> to the <value> string.[br]
+ If <value> is not given , the <variable> is unset.[br]
+ @seealso:
+ [fnc]$system.getenv[/fnc]
+*/
+
+
+static bool system_kvs_cmd_setenv(KviKvsModuleCommandCall * c)
+{
+ QString szVariable,szValue;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("variable",KVS_PT_NONEMPTYSTRING,0,szVariable)
+ KVSM_PARAMETER("value",KVS_PT_STRING,KVS_PF_OPTIONAL,szValue)
+ KVSM_PARAMETERS_END(c)
+
+ KviQCString szVar = szVariable.local8Bit();
+ KviQCString szVal = szValue.local8Bit();
+
+ if(szVal.isEmpty())kvi_unsetenv(szVar.data());
+ else
+ {
+/*#ifdef COMPILE_ON_WINDOWS
+ QString Var,Val,VarAndVal;
+ Val = szVar.data();
+ Var = szVal.data();
+ VarAndVal = Var+"="+Val;
+ putenv(VarAndVal);
+#else*/ // <-- this stuff is implicit in kvi_setenv: that's why we have the kvi_ version.
+ kvi_setenv(szVar.data(),szVal.data());
+/*#endif*/
+ }
+ return true;
+}
+
+/*
+ @doc: system.call
+ @keyterms:
+ call plugin
+ @type:
+ function
+ @title:
+ $system.call
+ @short:
+ Allows to call functions of a plugin
+ @syntax:
+ <string> $system.call(<plugin:string>, <function:string>[,<parameters:string>,...])
+ @description:
+ This function allows you to call simple functions of "easyplugins" (dll/so) and
+ get the result of this function. The easyplugins have to be coded in a special way.
+ If you want to write your own easyplugins, have a look on the easyplugins documentation.
+ [br]
+ [br]
+ The function needs a minimum of 2 parameters. The others are optional and not limited.[br]
+ The first one is the complete name like "example.dll" or "example.so"
+ If you have a relative path or only the filename KVIrc looks for the easyplugins in the following dirs:[br]
+ In a subdir called "easyplugins" in the local and global KVIrc directory.
+ If you give an absolute path KVIrc will load it directly.
+ [br]
+ [br]
+ You are free to add more parameters, they will be given to the easyplugin.[br]
+ The easyplugin decides how much parameters you need in addition to the first 2.
+ [br]
+ [br]
+ [b]Warning: Only use easyplugins of known and trustable sources![/b]
+ @examples:
+ [example]
+ echo $system.call("my.dll","myfunction")
+ echo $system.call("my.dll","myfunction","parameter1","parameter2")
+ echo $system.call("c:/my.dll","myfunction")
+ echo $system.call("my.so","myfunction","parameter1")
+ [/example]
+*/
+
+
+static bool system_kvs_fnc_plugin_call(KviKvsModuleFunctionCall *c)
+{
+ return g_pPluginManager->pluginCall(c);
+}
+
+static bool system_module_init(KviModule * m)
+{
+ KVSM_REGISTER_FUNCTION(m,"ostype",system_kvs_fnc_ostype);
+ KVSM_REGISTER_FUNCTION(m,"osname",system_kvs_fnc_osname);
+ KVSM_REGISTER_FUNCTION(m,"osversion",system_kvs_fnc_osversion);
+ KVSM_REGISTER_FUNCTION(m,"osrelease",system_kvs_fnc_osrelease);
+ KVSM_REGISTER_FUNCTION(m,"osmachine",system_kvs_fnc_osmachine);
+ KVSM_REGISTER_FUNCTION(m,"osnodename",system_kvs_fnc_osnodename);
+ KVSM_REGISTER_FUNCTION(m,"getenv",system_kvs_fnc_getenv);
+ KVSM_REGISTER_FUNCTION(m,"hostname",system_kvs_fnc_hostname);
+ KVSM_REGISTER_FUNCTION(m,"dcop",system_kvs_fnc_dcop);
+ KVSM_REGISTER_FUNCTION(m,"clipboard",system_kvs_fnc_clipboard);
+ KVSM_REGISTER_FUNCTION(m,"selection",system_kvs_fnc_selection);
+ KVSM_REGISTER_FUNCTION(m,"checkModule",system_kvs_fnc_checkModule);
+ KVSM_REGISTER_FUNCTION(m,"call",system_kvs_fnc_plugin_call);
+
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setenv",system_kvs_cmd_setenv);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setClipboard",system_kvs_cmd_setClipboard);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"setSelection",system_kvs_cmd_setSelection);
+
+ g_pPluginManager = new(KviPluginManager);
+
+ return true;
+}
+
+static bool system_module_cleanup(KviModule *m)
+{
+ g_pPluginManager->unloadAll();
+ delete g_pPluginManager;
+ return true;
+}
+
+static bool system_module_can_unload(KviModule *m)
+{
+ if(!g_pPluginManager->checkUnload()) return false;
+ return true;
+}
+
+KVIRC_MODULE(
+ "System", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)" \
+ " (C) 2005 Tonino Imbesi (grifisx at barmes dot org)"\
+ " (C) 2005 Alessandro Carbone (noldor at barmes dot org)",// author & (C)
+ "System informations module",
+ system_module_init,
+ system_module_can_unload,
+ 0,
+ system_module_cleanup
+)
diff --git a/src/modules/system/plugin.cpp b/src/modules/system/plugin.cpp
new file mode 100644
index 00000000..b14b18c0
--- /dev/null
+++ b/src/modules/system/plugin.cpp
@@ -0,0 +1,427 @@
+//=============================================================================
+//
+// 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 "kvi_fileutils.h"
+
+#include <qdir.h>
+#include <qfileinfo.h>
+/*
+ @doc: easyplugins
+ @type:
+ generic
+ @keyterms:
+ easyplugins
+ @title:
+ Easyplugins
+ @short:
+ Small plugins which can be called in scripts
+ @body:
+ If you want to know how to call easyplugins please have a look at: $system.call()[br]
+ This part of the documentation handles only the way how to write an easyplugin. An easyplugin is simply a dll/so. You can create one like you normally make such so/dll files. The important thing is that these so/dll-files export some of the following functions.
+ [br][br]
+ [b]Exported functions by easyplugin (C/C++-Examples):[/b][br]
+ [br][b]_free function[/b] [i] (needed)[/i][br]
+ This function is important! Since KVIrc can not free directly the memory of the dll, the plugins need the _free function so that the memory can be freed by the plugin to prevent memory-leaks.[br]
+ [example]
+ int _free(void * p)[br]
+ {[br]
+ // Always free the memory here![br]
+ free(p);[br]
+ return 0;[br]
+ }[br]
+ [/example]
+
+ [br][b]_load function[/b] [i](optional)[/i][br]
+ After the plugin has be loaded, KVIrc will call the _load-function. Here you can prepare your plugin stuff.
+ [example]
+ int _load()[br]
+ {[br]
+ return 0;[br]
+ }[br]
+ [/example]
+
+ [br][b]_unload function[/b] [i]((optional)[/i][br]
+ This function will be called before the plugins is unloaded. In this function you can clean up memory or other things.
+ After this call there is no guarantee that the plugin will be kept in memory.[br]
+ [example]
+ int _unload()[br]
+ {[br]
+ return 0;[br]
+ }[br]
+ [/example]
+
+ [br][b]_canunload function[/b] [i](optional)[/i][br]
+ The _canunload-function will be called by KVIrc to check if it may unload the plugin.
+ If return value is true KVIrc will unload the plugin, false means he will try unloading it at the next check.[br]
+ Important: KVIrc will ignore this if unload of plugins will be forced! So you have to be sure that the _unload function of your plugins cleans up![br]
+ [example]
+ int _canunload()[br]
+ {[br]
+ return 0; [br]
+ }[br]
+ [/example]
+
+ [br][b]user function[/b][br]
+ This is the general structure of a user function call.[br]
+ The important thing here is the handling of return values. To return a value to KVIrc you have to allocate memory and write the pointer to it into pBuffer. Have a look at the example for more details.[br]
+ [example]
+ int about(int argc, char * argv[], char ** pBuffer)[br]
+ {[br]
+ *pBuffer = (char*)malloc(1024);[br]
+ sprintf((char*)*pBuffer, "Hello World"); [br]
+ return 1;[br]
+ }[br]
+ [/example]
+*/
+
+KviPlugin::KviPlugin(kvi_library_t pLib, const QString& name)
+{
+ m_Plugin = pLib;
+ m_szName = name;
+}
+
+KviPlugin::~KviPlugin()
+{
+}
+
+KviPlugin* KviPlugin::load(const QString& szFileName)
+{
+ kvi_library_t pLibrary = kvi_library_open(szFileName.local8Bit());
+ if (!pLibrary)
+ {
+ return 0;
+ }
+
+ KviPlugin* pPlugin = new KviPlugin(pLibrary,KviFileUtils::extractFileName(szFileName));
+
+ plugin_load function_load;
+
+ function_load = (plugin_unload)kvi_library_symbol(pLibrary,"_load");
+ if (function_load)
+ {
+ //TODO: THREAD
+ function_load();
+ }
+ return pPlugin;
+}
+
+bool KviPlugin::pfree(char * pBuffer)
+{
+ plugin_free function_free;
+
+ function_free = (plugin_free)kvi_library_symbol(m_Plugin,"_free");
+ if (function_free)
+ {
+ //TODO: THREAD
+ if(pBuffer) function_free(pBuffer);
+ return true;
+ }
+ return false;
+}
+
+bool KviPlugin::unload()
+{
+ plugin_unload function_unload;
+
+ function_unload = (plugin_unload)kvi_library_symbol(m_Plugin,"_unload");
+ if (function_unload)
+ {
+ //TODO: THREAD
+ function_unload();
+ }
+
+ if(m_Plugin)
+ {
+ kvi_library_close(m_Plugin);
+ }
+
+ return true;
+}
+
+bool KviPlugin::canunload()
+{
+ plugin_canunload function_canunload;
+
+ function_canunload = (plugin_canunload)kvi_library_symbol(m_Plugin,"_canunload");
+ if (function_canunload)
+ {
+ //TODO: THREAD
+ if(!function_canunload())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+int KviPlugin::call(const QString& pszFunctionName, int argc, char * argv[], char ** pBuffer)
+{
+ int r;
+ plugin_function function_call;
+ function_call = (plugin_function)kvi_library_symbol(m_Plugin,pszFunctionName.local8Bit());
+ if (!function_call)
+ {
+ return -1;
+ } else {
+ //TODO: THREAD
+ r = function_call(argc,argv,pBuffer);
+ }
+ if (r < 0) r = 0; // negative numbers are for error handling.
+ return r;
+}
+
+QString KviPlugin::name()
+{
+ return m_szName;
+}
+
+void KviPlugin::setName(const QString& Name)
+{
+ m_szName = Name;
+}
+
+
+KviPluginManager::KviPluginManager()
+{
+ m_pPluginDict = new KviPointerHashTable<QString,KviPlugin>(5,false);
+ m_pPluginDict->setAutoDelete(false);
+
+ m_bCanUnload = true;
+}
+
+KviPluginManager::~KviPluginManager()
+{
+ delete m_pPluginDict;
+}
+
+bool KviPluginManager::pluginCall(KviKvsModuleFunctionCall *c)
+{
+ // /echo $system.call("traffic.dll",about)
+ QString szPluginPath; //contains full path and plugin name like "c:/plugin.dll"
+ QString szFunctionName;
+
+ KVSM_PARAMETERS_BEGIN(c)
+ KVSM_PARAMETER("plugin_path",KVS_PT_NONEMPTYSTRING,0,szPluginPath)
+ KVSM_PARAMETER("function",KVS_PT_NONEMPTYSTRING,0,szFunctionName)
+ KVSM_PARAMETERS_END(c)
+
+ //Check if there is such a plugin
+ if(!findPlugin(szPluginPath))
+ {
+ c->error(__tr2qs("Plugin not found. Please check the plugin-name and path."));
+ return true;
+ }
+
+ //Load plugin or check it in cache
+ if(!loadPlugin(szPluginPath))
+ {
+ c->error(__tr2qs("Error while loading plugin."));
+ return true;
+ }
+
+ //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);
+ 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.local8Bit());
+ x += tmp.length();
+
+ *x = 0;
+ x++;
+ i++;
+ }
+
+ } else {
+ //Avoid using unfilled variables
+ ppArgv = 0;
+ pArgvBuffer = 0;
+ iArgc = 0;
+ }
+
+ //Preparing return buffer
+ char * returnBuffer;
+ KviPlugin * plugin;
+
+ plugin = getPlugin(szPluginPath);
+ 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(QString::fromLocal8Bit(returnBuffer));
+ }
+
+
+ //Clean up
+ if(pArgvBuffer) free(pArgvBuffer);
+ if(ppArgv) free(ppArgv);
+ if(returnBuffer)
+ {
+ if (!plugin->pfree(returnBuffer))
+ {
+ c->warning(__tr2qs("The plugin has no function to free memory. This can result in Memory Leaks!"));
+ }
+ }
+
+
+
+ return true;
+}
+
+bool KviPluginManager::checkUnload()
+{
+ /*
+ Always called when system module should be unloaded
+ Checking here if all small "modules" can be unloaded
+ */
+ KviPointerHashTableIterator<QString,KviPlugin> it(*m_pPluginDict);
+
+ m_bCanUnload = true;
+
+ while(it.current())
+ {
+ if(it.current()->canunload())
+ {
+ it.current()->unload();
+ m_pPluginDict->remove(it.currentKey());
+ } else {
+ m_pPluginDict++;
+ m_bCanUnload = false;
+ }
+ }
+
+ return m_bCanUnload;
+}
+
+void KviPluginManager::unloadAll()
+{
+ KviPointerHashTableIterator<QString,KviPlugin> it(*m_pPluginDict);
+
+ while(it.current())
+ {
+ it.current()->unload();
+ m_pPluginDict->remove(it.currentKey());
+ }
+}
+
+bool KviPluginManager::findPlugin(QString& szPath)
+{
+ QString szFileName(KviFileUtils::extractFileName(szPath));
+// szFileName.detach();
+ if(KviFileUtils::isAbsolutePath(szPath) && KviFileUtils::fileExists(szPath))
+ {
+ // Ok,
+ return true;
+ } else {
+ //Plugin not found in direct way. Looking in kvirc local dir
+ g_pApp->getGlobalKvircDirectory(szPath,KviApp::EasyPlugins,szFileName);
+
+ if(!KviFileUtils::fileExists(szPath))
+ {
+ //Plugin not found in kvirc local dir. Looking in kvirc global dir
+ g_pApp->getLocalKvircDirectory(szPath,KviApp::EasyPlugins,szFileName);
+
+ if(!KviFileUtils::fileExists(szPath))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool KviPluginManager::isPluginLoaded(const QString& pSingleName)
+{
+ KviPlugin * p = m_pPluginDict->find(pSingleName);
+ if (!p)
+ return false;
+ else
+ return true;
+}
+
+bool KviPluginManager::loadPlugin(const QString& szPluginPath)
+{
+ if(isPluginLoaded(szPluginPath))
+ {
+ return getPlugin(szPluginPath)!=0;
+ } else {
+ KviPlugin * plugin = KviPlugin::load(szPluginPath);
+ if(plugin)
+ {
+ m_pPluginDict->insert(szPluginPath,plugin);
+ return true;
+ }
+ }
+ return false;
+}
+
+KviPlugin * KviPluginManager::getPlugin(const QString& szPluginPath)
+{
+ KviPlugin * p = m_pPluginDict->find(szPluginPath);
+ return p;
+} \ No newline at end of file
diff --git a/src/modules/system/plugin.h b/src/modules/system/plugin.h
new file mode 100644
index 00000000..64b1723a
--- /dev/null
+++ b/src/modules/system/plugin.h
@@ -0,0 +1,80 @@
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+//=============================================================================
+//
+// File : plugin.h
+// 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "kvi_module.h"
+#include "kvi_pointerhashtable.h"
+
+typedef int (*plugin_function)(int argc, char* argv[], char ** buffer);
+typedef int (*plugin_unload)();
+typedef int (*plugin_canunload)();
+typedef int (*plugin_load)();
+typedef int (*plugin_free)(char * pBuffer);
+
+class KviPlugin
+{
+protected:
+ // You have to create plugin instance by calling KviPlugin::load()
+ KviPlugin(kvi_library_t pLib, const QString& name);
+public:
+ ~KviPlugin();
+private:
+ // shared
+ // internal
+ kvi_library_t m_Plugin;
+ QString m_szName;
+public:
+ static KviPlugin* load(const QString& szFileName);
+ bool pfree(char * pBuffer);
+ bool unload();
+ bool canunload();
+ int call(const QString& szFunctionName, int argc, char * argv[], char ** pBuffer);
+ QString name();
+ void setName(const QString& szName);
+protected:
+};
+
+class KviPluginManager
+{
+ public:
+ KviPluginManager();
+ ~KviPluginManager();
+ private:
+ // shared
+ bool m_bCanUnload;
+ // internal
+ KviPointerHashTable<QString,KviPlugin> * m_pPluginDict;
+ public:
+ bool pluginCall(KviKvsModuleFunctionCall *c);
+ bool checkUnload();
+ void unloadAll();
+ protected:
+ bool findPlugin(QString& szName);
+ bool isPluginLoaded(const QString& szFileNameOrPathToLoad);
+ bool loadPlugin(const QString& szPluginPath);
+ KviPlugin * getPlugin(const QString& szPluginPath);
+};
+
+#endif //_PLUGIN_H_ \ No newline at end of file