From 98d0faa2eeddfe260bd337c69b00734b7cff2375 Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Sat, 26 Nov 2011 15:54:11 +0000 Subject: added mBot git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@217 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- mBot/src/libphp/internals.h | 97 ++ mBot/src/libphp/libphp.cpp | 573 +++++++++++ mBot/src/libphp/libphp.h | 95 ++ mBot/src/libphp/libphp.rc | 115 +++ mBot/src/libphp/libphp.vcproj | 213 ++++ mBot/src/libphp/phpenv.cpp | 1502 +++++++++++++++++++++++++++ mBot/src/libphp/phpenv.h | 114 +++ mBot/src/libphp/resource.h | 34 + mBot/src/libphp/svar.cpp | 124 +++ mBot/src/libphp/svar.h | 60 ++ mBot/src/mbot/config.cpp | 217 ++++ mBot/src/mbot/config.h | 47 + mBot/src/mbot/cron.cpp | 590 +++++++++++ mBot/src/mbot/cron.h | 87 ++ mBot/src/mbot/dialogs.cpp | 295 ++++++ mBot/src/mbot/dialogs.h | 77 ++ mBot/src/mbot/functions.cpp | 327 ++++++ mBot/src/mbot/functions.h | 251 +++++ mBot/src/mbot/functions/mb_auth.cpp | 115 +++ mBot/src/mbot/functions/mb_contact.cpp | 518 ++++++++++ mBot/src/mbot/functions/mb_dlg.cpp | 899 ++++++++++++++++ mBot/src/mbot/functions/mb_event.cpp | 202 ++++ mBot/src/mbot/functions/mb_ft.cpp | 260 +++++ mBot/src/mbot/functions/mb_icons.cpp | 79 ++ mBot/src/mbot/functions/mb_irc.cpp | 357 +++++++ mBot/src/mbot/functions/mb_menu.cpp | 167 +++ mBot/src/mbot/functions/mb_misc.cpp | 185 ++++ mBot/src/mbot/functions/mb_msg.cpp | 152 +++ mBot/src/mbot/functions/mb_proto.cpp | 80 ++ mBot/src/mbot/functions/mb_pu.cpp | 198 ++++ mBot/src/mbot/functions/mb_reg.cpp | 432 ++++++++ mBot/src/mbot/functions/mb_search.cpp | 154 +++ mBot/src/mbot/functions/mb_snd.cpp | 73 ++ mBot/src/mbot/functions/mb_sys.cpp | 786 ++++++++++++++ mBot/src/mbot/helpers.cpp | 662 ++++++++++++ mBot/src/mbot/helpers.h | 220 ++++ mBot/src/mbot/m_script.h | 143 +++ mBot/src/mbot/mbot.cpp | 1750 ++++++++++++++++++++++++++++++++ mBot/src/mbot/mbot.def | 6 + mBot/src/mbot/mbot.h | 229 +++++ mBot/src/mbot/mbot.rc | 298 ++++++ mBot/src/mbot/mbot.vcproj | 376 +++++++ mBot/src/mbot/res/icon1.ico | Bin 0 -> 2550 bytes mBot/src/mbot/res/php5-power-micro.bmp | Bin 0 -> 2278 bytes mBot/src/mbot/res/tbar.bmp | Bin 0 -> 12344 bytes mBot/src/mbot/resource.h | 67 ++ mBot/src/mbot/server.cpp | 1383 +++++++++++++++++++++++++ mBot/src/mbot/smanager.cpp | 434 ++++++++ mBot/src/mbot/smanager.h | 74 ++ mBot/src/mbot/sync.cpp | 157 +++ mBot/src/mbot/sync.h | 63 ++ mBot/src/mbot/window.cpp | 1255 +++++++++++++++++++++++ mBot/src/mbot/window.h | 31 + mBot/src/msp.sln | 39 + mBot/src/utils/cBase64.cpp | 204 ++++ mBot/src/utils/cBase64.h | 57 ++ mBot/src/utils/cUtils.cpp | 334 ++++++ mBot/src/utils/cUtils.h | 137 +++ mBot/src/utils/cXmldoc.cpp | 899 ++++++++++++++++ mBot/src/utils/cXmldoc.h | 153 +++ mBot/src/utils/includes.h | 33 + mBot/src/utils/utils.vcproj | 194 ++++ 62 files changed, 18673 insertions(+) create mode 100644 mBot/src/libphp/internals.h create mode 100644 mBot/src/libphp/libphp.cpp create mode 100644 mBot/src/libphp/libphp.h create mode 100644 mBot/src/libphp/libphp.rc create mode 100644 mBot/src/libphp/libphp.vcproj create mode 100644 mBot/src/libphp/phpenv.cpp create mode 100644 mBot/src/libphp/phpenv.h create mode 100644 mBot/src/libphp/resource.h create mode 100644 mBot/src/libphp/svar.cpp create mode 100644 mBot/src/libphp/svar.h create mode 100644 mBot/src/mbot/config.cpp create mode 100644 mBot/src/mbot/config.h create mode 100644 mBot/src/mbot/cron.cpp create mode 100644 mBot/src/mbot/cron.h create mode 100644 mBot/src/mbot/dialogs.cpp create mode 100644 mBot/src/mbot/dialogs.h create mode 100644 mBot/src/mbot/functions.cpp create mode 100644 mBot/src/mbot/functions.h create mode 100644 mBot/src/mbot/functions/mb_auth.cpp create mode 100644 mBot/src/mbot/functions/mb_contact.cpp create mode 100644 mBot/src/mbot/functions/mb_dlg.cpp create mode 100644 mBot/src/mbot/functions/mb_event.cpp create mode 100644 mBot/src/mbot/functions/mb_ft.cpp create mode 100644 mBot/src/mbot/functions/mb_icons.cpp create mode 100644 mBot/src/mbot/functions/mb_irc.cpp create mode 100644 mBot/src/mbot/functions/mb_menu.cpp create mode 100644 mBot/src/mbot/functions/mb_misc.cpp create mode 100644 mBot/src/mbot/functions/mb_msg.cpp create mode 100644 mBot/src/mbot/functions/mb_proto.cpp create mode 100644 mBot/src/mbot/functions/mb_pu.cpp create mode 100644 mBot/src/mbot/functions/mb_reg.cpp create mode 100644 mBot/src/mbot/functions/mb_search.cpp create mode 100644 mBot/src/mbot/functions/mb_snd.cpp create mode 100644 mBot/src/mbot/functions/mb_sys.cpp create mode 100644 mBot/src/mbot/helpers.cpp create mode 100644 mBot/src/mbot/helpers.h create mode 100644 mBot/src/mbot/m_script.h create mode 100644 mBot/src/mbot/mbot.cpp create mode 100644 mBot/src/mbot/mbot.def create mode 100644 mBot/src/mbot/mbot.h create mode 100644 mBot/src/mbot/mbot.rc create mode 100644 mBot/src/mbot/mbot.vcproj create mode 100644 mBot/src/mbot/res/icon1.ico create mode 100644 mBot/src/mbot/res/php5-power-micro.bmp create mode 100644 mBot/src/mbot/res/tbar.bmp create mode 100644 mBot/src/mbot/resource.h create mode 100644 mBot/src/mbot/server.cpp create mode 100644 mBot/src/mbot/smanager.cpp create mode 100644 mBot/src/mbot/smanager.h create mode 100644 mBot/src/mbot/sync.cpp create mode 100644 mBot/src/mbot/sync.h create mode 100644 mBot/src/mbot/window.cpp create mode 100644 mBot/src/mbot/window.h create mode 100644 mBot/src/msp.sln create mode 100644 mBot/src/utils/cBase64.cpp create mode 100644 mBot/src/utils/cBase64.h create mode 100644 mBot/src/utils/cUtils.cpp create mode 100644 mBot/src/utils/cUtils.h create mode 100644 mBot/src/utils/cXmldoc.cpp create mode 100644 mBot/src/utils/cXmldoc.h create mode 100644 mBot/src/utils/includes.h create mode 100644 mBot/src/utils/utils.vcproj (limited to 'mBot/src') diff --git a/mBot/src/libphp/internals.h b/mBot/src/libphp/internals.h new file mode 100644 index 0000000..851245f --- /dev/null +++ b/mBot/src/libphp/internals.h @@ -0,0 +1,97 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _LIBPHP_I_H_ +#define _LIBPHP_I_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "libphp.h" + +struct lphp_funct +{ + char name[64]; + void* ptr; + long lp; + long pinfo; +public: + lphp_funct(){} + lphp_funct(const char* n,void* p,long l,long pi){ + strncpy(name,n,63); + ptr = p; + lp = l; + pinfo = pi; + } +}; + +struct STR{ + char* val; + unsigned long len; +}; + +class ccLock +{ +public: + ccLock(CRITICAL_SECTION& cs) : m_cs(cs){lock();} + ~ccLock(){unlock();} +public: + void unlock(){LeaveCriticalSection(&m_cs);} + void lock(){EnterCriticalSection(&m_cs);} +protected: + CRITICAL_SECTION& m_cs; +}; +#define cLock(c) ccLock _lockObj(c) +#define cULock() _lockObj.unlock(); +#define cLLock() _lockObj.lock(); + +typedef enum { + MT_LOG_INFO = 0, + MT_LOG_ERROR = 1, + MT_LOG_FATAL_ERROR = 2, + MT_LOG_WARNING = 3, + MT_LOG_DATA_ERROR = 4, + MT_LOG_EXCEPTION = 5, + MT_LOG_DATABASE = 6 +}MTLOG_ENUM; + +void lphp_error(MTLOG_ENUM log_class,void* _ep,const char* info,...); +const char* g_pref(const char* name); +const char* g_pref_def(const char* name,const char* def); +unsigned long g_pref_ul(const char* name, long base = 0, unsigned long def=0); + +typedef void* (*LPHP_GEN0)(void* cp); +typedef void* (*LPHP_GEN1)(void* cp,void* p1); +typedef void* (*LPHP_GEN2)(void* cp,void* p1,void* p2); +typedef void* (*LPHP_GEN3)(void* cp,void* p1,void* p2,void* p3); +typedef void* (*LPHP_GEN4)(void* cp,void* p1,void* p2,void* p3,void* p4); + +extern void* g_php_module; + +#endif \ No newline at end of file diff --git a/mBot/src/libphp/libphp.cpp b/mBot/src/libphp/libphp.cpp new file mode 100644 index 0000000..f78ff52 --- /dev/null +++ b/mBot/src/libphp/libphp.cpp @@ -0,0 +1,573 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "internals.h" +#include "phpenv.h" +#include "svar.h" + +HINSTANCE hInstance = NULL; +LPHP_OUTPUT g_std_out = NULL; +LPHP_OUTPUT g_std_err = NULL; +CRITICAL_SECTION g_csection = {0}; + +LPHP_MALLOC g_malloc = NULL; +LPHP_FREE g_free = NULL; +HANDLE g_event = NULL; +HANDLE g_initth = NULL; +HANDLE g_heap = NULL; +int g_initialized = FALSE; +int g_preinitialized = FALSE; +void* g_php_module = NULL; + +sVARmap g_vars; +sFCNmap g_fcns; +sVARmap* pg_vars = &g_vars; +sFCNmap* pg_fcns = &g_fcns; + + +int my_compare(long* l1,long * l2,void* param){ + if(*l1 == *l2){ + return 0; + }else if(*l1 > *l2){ + return 1; + }else{ + return -1; + } +} + +int lphp_funct_compare(lphp_funct* f1,lphp_funct * f2,void* param){ + return strcmp(f1->name,f2->name); +} + +unsigned int lphp_funct_hash(lphp_funct* v) +{ + int index = 0; + char* c = v->name; + + if(!*c){ + return 0; + } + + while(*c){ + index = 31 * index + *c++; + } + + return (index & 0x7EffFFff) + 1; +} + +void my_std_out(const char* data,long length = 0) +{ + if(!length){ + length = strlen(data); + } + fwrite(data,1,length,stdout); +} + +void lphp_error(MTLOG_ENUM log_class,void* _ep,const char* info,...) +{ + va_list args; + char ss[2048]; + + va_start(args,info); + _vsnprintf(ss,sizeof(ss),info,args); + va_end(args); + g_std_err(ss,strlen(ss)); + return; +} +#ifndef _LPHP_STATIC_ +int WINAPI DllMain(HINSTANCE hInst,unsigned long dwReason,VOID* data) +{ + if(dwReason == DLL_PROCESS_ATTACH) + { + g_std_out = my_std_out; + g_std_err = my_std_out; + }else if(dwReason == DLL_THREAD_DETACH && g_initialized){ + try{ + ts_free_thread(); + }catch(...){ + return TRUE; + } + } + hInstance = hInst; + return TRUE; +} +#endif //_LPHP_STATIC_ + +const char* g_pref(const char* name) +{ + return g_pref_def(name, NULL); +} + +const char* g_pref_def(const char* name,const char* def) +{ + cLock(g_csection); + + sVARmap::const_iterator it = g_vars.find(name); + if(it == g_vars.end()){ + return NULL; + }else{ + if((it->second).type == SV_STRING && (it->second).locked){ + return (it->second).str.val; + }else{ + return def; + } + } +} +unsigned long g_pref_ul(const char* name, long base,unsigned long def) +{ + cLock(g_csection); + + sVARmap::const_iterator it = g_vars.find(name); + if(it == g_vars.end()){ + return NULL; + }else{ + if((it->second).type == SV_STRING){ + return strtoul((it->second).str.val,NULL,base); + }else{ + return (it->second).lval; + } + } +} + +LPHPAPI int LPHP_PreInit(unsigned long vt_size,unsigned long ft_size,LPHP_MALLOC fp_malloc,LPHP_FREE fp_free) +{ + if(vt_size < 256){ + vt_size = 256; + }else if(vt_size > 65530){ + vt_size = 65530; + } + + g_std_out = my_std_out; + g_std_err = my_std_out; + + if(ft_size < 256){ + ft_size = 256; + }else if(ft_size > 65530){ + ft_size = 65530; + } + + g_free = fp_free; + g_malloc = fp_malloc; + InitializeCriticalSection(&g_csection); + return g_preinitialized = TRUE; +} + +unsigned long WINAPI InitTh(void* dummy) +{ + printf("initializing...\n"); + g_initialized = GO_PhpGlobalInit(); + printf("retval: %u\n",g_initialized); + SetEvent(g_event); + printf("suspending\n"); + SuspendThread(GetCurrentThread()); + if(g_initialized){ + g_initialized = 0; + printf("shutting down\n"); + GO_PhpGlobalDeInit(); + } + printf("done!\n"); + return 0; +} + +LPHPAPI int LPHP_Init(LPHP_OUTPUT fp_output,LPHP_OUTPUT fp_error,void* php_module) +{ + unsigned long tmp; + if(g_initialized!=FALSE || !g_preinitialized){ + return 0; + } + + g_php_module = php_module; + + g_event = CreateEvent(0,0,0,0); + //add checking + g_initth = CreateThread(0,64*1024,(LPTHREAD_START_ROUTINE)InitTh,NULL,0,&tmp); + WaitForSingleObject(g_event,INFINITE); + + if(g_initialized) + { + if(fp_output)g_std_out = fp_output; + if(fp_error)g_std_err = fp_error; + g_initialized = TRUE; + return TRUE; + } + else + { + TerminateThread(g_initth,NULL); + CloseHandle(g_initth); + g_php_module = NULL; + return FALSE; + } +} +LPHPAPI int LPHP_DeInit() +{ + if(g_initialized == FALSE && g_preinitialized == FALSE){ + return FALSE; + } + + ResumeThread(g_initth); + WaitForSingleObject(g_initth,INFINITE); + CloseHandle(g_initth); + CloseHandle(g_event); + + g_std_out = my_std_out; + g_std_err = my_std_out; + g_php_module = NULL; + g_initialized = FALSE; + g_preinitialized = FALSE; + DeleteCriticalSection(&g_csection); + return TRUE; +} + +LPHPAPI int LPHP_Initialized() +{ + return g_initialized; +} + +LPHPAPI int LPHP_Free(void* ptr) +{ + try{ + g_free(ptr); + return TRUE; + }catch(...){ + return FALSE; + } +} + +LPHPAPI int LPHP_RegisterFunction(const char* name,void* fptr,long lp,LPHP_TYPE rval, + LPHP_TYPE p1,LPHP_TYPE p2,LPHP_TYPE p3,LPHP_TYPE p4) +{ + cLock(g_csection); + + lphp_funct nf(name, fptr, lp, + (rval & 0x03) | ((p1 & 0x03) << 2) | ((p2 & 0x03) << 4) | + ((p3 & 0x03) << 6) | ((p4 & 0x03) << 8)); + + if(g_fcns.find(name) != g_fcns.end()){ + return FALSE; + }else{ + g_fcns[name] = nf; + return TRUE; + } +} +LPHPAPI int LPHP_UnregisterFunction(const char* name) +{ + cLock(g_csection); + + sFCNmap::const_iterator it = g_fcns.find(name); + if(it != g_fcns.end()){ + + } + return TRUE; +} + +LPHPAPI int LPHP_ExecutePage(const char* path, const char* querystring, const char** output, void* cparam, LPHP_ENVCB cb, long flags) +{ + cutMemf mf; + cutMemf* of = &mf; + std::string ss; + + if(flags & 0x01){ + of = (cutMemf*)output; + }else if(output && !mf.create(8*1024)){ + return 0; + } + + if(GO_PhpExecute(path,(output)?(&ss):(NULL),(output)?(of):(NULL),PHPENV_MODE_FILE,querystring,cparam,(PHPENV_CB)cb)) + { + if(output && !(flags & 0x01)){ + mf.putc('\0'); + mf.write((void*)ss.data(), ss.length()); + mf.putc(0); + *output = (const char*)mf.leave(); + } + return TRUE; + }else{ + return FALSE; + } +} + +LPHPAPI int LPHP_ExecuteDirect(const char* body,const char** output,void* cparam) +{ + cutMemf mf; + sEPHP ephp={0}; + long result = 0; + char tmp[32]; + + if(output && !mf.create(8*1024)){ + return 0; + } + + ephp.pszBody = body; + ephp.pszFile = "[direct source]"; + ephp.c_param = (void*)cparam; + ephp.pOut = (output)?(&mf):(NULL); + ephp.cFlags = (output)?(0x01):(0); + + result = GO_PhpExecute2(&ephp); + + if(result){ + if(output){ + mf.putc(0); + if(ephp.cResType == 0x01){ + mf.writestring(ephp.res.str.val); + free(ephp.res.str.val); + }else{ + _snprintf(tmp, sizeof(tmp) - 1, "%d", ephp.res.lval); + mf.writestring(tmp); + } + mf.putc(0); + *output = (const char*)mf.leave(); + } + return TRUE; + }else{ + return FALSE; + } +} + +long LPHP_ExecuteThread(exe_helper* hh) +{ + return (hh->result = GO_PhpExecute2(hh->php)); +} + +LPHPAPI int LPHP_ExecuteFile(const char* path,const char* funct,const char** output,void* cparam,const char* ptypes,...) +{ + va_list args; + int result; + + va_start(args,ptypes); + result = LPHP_ExecuteFileVA(path,funct,output,cparam,ptypes,args); + va_end(args); + return result; +} + +LPHPAPI int LPHP_ExecuteFileVA(const char* path,const char* funct,const char** output, + void* cparam,const char* ptypes,va_list args) +{ + cutMemf mf; + int result = 0; + char code[MAX_PATH + 64]; + sEPHP ephp={0}; + + if(output && !mf.create(1024)){ + return 0; + } + + _snprintf(code, sizeof(code) - 1, "require_once('%s');\r\n", path); + + ephp.pszFile = path; + ephp.pszFunction = funct; + ephp.pszPT = ptypes; + ephp.pszBody = code; + ephp.c_param = (void*)cparam; + ephp.pOut = (output)?(&mf):(NULL); + ephp.cFlags = (output)?(0x01):(0); + ephp.pArguments = args; + + result = GO_PhpExecute2(&ephp); + + if(result) + { + if(output) + { + mf.putc('\0'); + if(ephp.cResType == 0x01){ + mf.writestring(ephp.res.str.val); + free(ephp.res.str.val); + }else{ + _snprintf(code, sizeof(code) - 1,"%d",ephp.res.lval); + mf.writestring(code); + } + mf.putc(0); + *output = (const char*)mf.leave(); + } + return TRUE; + }else{ + if(mf.size()){ + g_std_err((const char*)mf.getdata(),mf.size()); + } + return FALSE; + } +} + +LPHPAPI int LPHP_ExecuteScript(const char* body,const char* funct,const char** output,void* cparam,const char* ptypes,...) +{ + va_list args; + int result; + + va_start(args,ptypes); + result = LPHP_ExecuteScriptVA(body,funct,output,cparam,ptypes,args); + va_end(args); + return result; +} + +LPHPAPI int LPHP_ExecuteScriptVA(const char* body,const char* funct,const char** output,void* cparam, + const char* ptypes,va_list args) +{ + cutMemf mf; + int result = 0; + sEPHP ephp={0}; + char tmp[32]; + + if(output && !mf.create(1024)){ + return 0; + } + + ephp.pszFile = (funct)?(funct):("[direct source]"); + ephp.pszFunction = funct; + ephp.pszPT = ptypes; + ephp.pszBody = body; + ephp.pOut = (output)?(&mf):(NULL); + ephp.cFlags = (output)?(0x01):(0); + ephp.c_param = (void*)cparam; + ephp.pArguments = args; + + result = GO_PhpExecute2(&ephp); + + if(result) + { + if(output) + { + mf.putc('\0'); + if(ephp.cResType == 0x01){ + mf.writestring(ephp.res.str.val); + free(ephp.res.str.val); + }else{ + + _snprintf(tmp,sizeof(tmp)-1,"%d",ephp.res.lval); + mf.writestring(tmp); + } + mf.putc(0); + *output = (const char*)mf.leave(); + } + return TRUE; + }else{ + if(mf.size()){ + g_std_err((const char*)mf.getdata(),mf.size()); + } + return FALSE; + } +} + +LPHPAPI int LPHP_GetVar(const char* name,void** value,SVAR_TYPE* cType) +{ + cLock(g_csection); + + if(!name || !value || !cType){ + return FALSE; + } + + sVARmap::const_iterator it; + sVar &sv = *((sVar*)NULL); + + if((it = g_vars.find(name)) == g_vars.end()){ + return FALSE; + } + + sv = it->second; + + *cType = (SVAR_TYPE)sv.type; + + if(sv.type == SV_STRING){ + *value = (void*)sv.str.val; + }else if(sv.type == SV_DOUBLE){ + *value = (void*)&sv.dval; + }else if(sv.type == SV_LONG || sv.type == SV_NULL){ + *value = (void*)sv.lval; + }else if(sv.type >= 11){ + *value = (void*)&sv.dval; + }else{ + *value = NULL; + } + return TRUE; +} + +LPHPAPI int LPHP_DelVar(const char* name) +{ + cLock(g_csection); + + sVARmap::iterator it = g_vars.find(name); + if(it == g_vars.end() || it->second.locked){ + return FALSE; + } + return TRUE; +} + +LPHPAPI int LPHP_IsVar(const char* name) +{ + cLock(g_csection); + + return (g_vars.find(name) != g_vars.end()); +} + +LPHPAPI int LPHP_SetVar(const char* name,void* value,SVAR_TYPE cType) +{ + cLock(g_csection); + + sVar sv; + void* tmp; + STR* ss = (STR*)value; + sVARmap::iterator it = g_vars.find(name); + + if(it == g_vars.end()){ + return FALSE; + } + + sv.type = cType; + + if(cType == SV_DOUBLE){ + sVariable(&sv,*(double*)value,2); + }else if((int)cType >= 11){ + tmp = svar_malloc(ss->len); + if(!tmp){ + return 0; + } + memcpy(tmp,ss->val,ss->len); + sVariable(&sv,cType,tmp,ss->len,2); + }else{ + sVariable(&sv,cType,value,0,2); + } + it->second = sv; + + return TRUE; +} +LPHPAPI int LPHP_NewVar(const char* name,void* value,SVAR_TYPE cType,char locked) +{ + cLock(g_csection); + + sVar sv; + void* tmp; + STR* ss = (STR*)value; + + if(cType == SV_DOUBLE){ + sVariable(&sv,*(double*)value,locked); + }else if((int)cType >= 11){ + tmp = svar_malloc(ss->len); + if(!tmp){ + return 0; + } + memcpy(tmp,ss->val,ss->len); + sVariable(&sv,cType,tmp,ss->len,(char)locked); + }else{ + sVariable(&sv,cType,value,0,(char)locked); + } + + g_vars[name] = sv; + return TRUE; +} \ No newline at end of file diff --git a/mBot/src/libphp/libphp.h b/mBot/src/libphp/libphp.h new file mode 100644 index 0000000..802a557 --- /dev/null +++ b/mBot/src/libphp/libphp.h @@ -0,0 +1,95 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ + +#ifndef _LIBPHP_H__ +#define _LIBPHP_H__ + +#ifndef _LPHP_STATIC_ + #ifdef LIBPHP_EXPORTS + #define LPHPAPI __declspec(dllexport) + #else + #define LPHPAPI __declspec(dllimport) + #endif +#else //_LPHP_STATIC_ + #define LPHPAPI +#endif //_LPHP_STATIC_ + +#include + + +enum LPHP_TYPE{LPHP_NUMBER=0,LPHP_STRING=1,LPHP_VOID=2}; + +enum SVAR_TYPE{ + SV_NULL,SV_LONG=1,SV_WORD=2,SV_DOUBLE=3, + SV_STRING=4,SV_LPOINTER=5,SV_ARRAY=11}; + +enum LPHP_CB{ + LPHP_CB_SETHDR=0, //const char* "header: value", int replace + LPHP_CB_OUTSTARTED=1, //NULL NULL + LPHP_CB_GETMETHOD=2, //NULL NULL, must return "GET" or "POST" + LPHP_CB_GETCOOKIE=3, //NULL NULL, must return "string" or NULL + LPHP_CB_POST_LENGTH=5, //NULL NULL, must return length + LPHP_CB_POST_DATA=6, //NULL NULL, must return pointer or NULL + LPHP_CB_GETENV=7,//const char* name NULL, must return pointer or "" if empty! + LPHP_CB_GETCL=8,//NULL NULL + LPHP_CB_GETCT=9,//NULL NULL + LPHP_CB_GETVARS=10//NULL NULL must return pointer to a "\0\0" terminated var array; +}; + +struct lphp_vparam{ + void* data; + long length; + long type; +}; + +typedef void (*LPHP_OUTPUT)(const char* data,long length); +typedef int (*LPHP_ENVCB)(LPHP_CB code,void* p1,void* p2,void* cparam); +typedef void* (*LPHP_MALLOC)(unsigned long amount); +typedef void (*LPHP_FREE)(void* ptr); + +LPHPAPI int LPHP_PreInit(unsigned long vt_size,unsigned long ft_size, LPHP_MALLOC fp_malloc, LPHP_FREE fp_free); +LPHPAPI int LPHP_Init(LPHP_OUTPUT fp_output, LPHP_OUTPUT fp_error, void* php_module = 0); + +LPHPAPI int LPHP_DeInit(); +LPHPAPI int LPHP_Initialized(); + +LPHPAPI int LPHP_RegisterFunction(const char* name,void* fptr,long lp, + LPHP_TYPE rval,LPHP_TYPE p1 = LPHP_VOID,LPHP_TYPE p2 = LPHP_VOID,LPHP_TYPE p3 = LPHP_VOID,LPHP_TYPE p4 = LPHP_VOID); +LPHPAPI int LPHP_UnregisterFunction(const char* name); + +LPHPAPI int LPHP_Free(void* ptr); + +LPHPAPI int LPHP_ExecutePage(const char* filepath,const char* querystring,const char** output,void* cparam,LPHP_ENVCB cb,long flags=0); +LPHPAPI int LPHP_ExecuteFile(const char* path,const char* funct,const char** output,void* cparam,const char* ptypes, ...); +LPHPAPI int LPHP_ExecuteFileVA(const char* path,const char* funct,const char** output,void* cparam,const char* ptypes, va_list args); + +LPHPAPI int LPHP_ExecuteScript(const char* body,const char* funct,const char** output,void* cparam,const char* ptypes, ...); +LPHPAPI int LPHP_ExecuteScriptVA(const char* body,const char* funct,const char** output,void* cparam,const char* ptypes, va_list args); + +LPHPAPI int LPHP_ExecuteDirect(const char* body,const char** output,void* cparam); + +LPHPAPI int LPHP_GetVar(const char* name,void** value,SVAR_TYPE* cType); +LPHPAPI int LPHP_DelVar(const char* name); +LPHPAPI int LPHP_SetVar(const char* name,void* value,SVAR_TYPE cType); +LPHPAPI int LPHP_NewVar(const char* name,void* value,SVAR_TYPE cType,char locked=0); +LPHPAPI int LPHP_IsVar(const char* name); + +#endif \ No newline at end of file diff --git a/mBot/src/libphp/libphp.rc b/mBot/src/libphp/libphp.rc new file mode 100644 index 0000000..07e57b3 --- /dev/null +++ b/mBot/src/libphp/libphp.rc @@ -0,0 +1,115 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Polish resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK) +#ifdef _WIN32 +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,5 + PRODUCTVERSION 1,0,0,5 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041504b0" + BEGIN + VALUE "Comments", "www.piopawlu.net" + VALUE "CompanyName", "Piotr Pawluczuk (www.piopawlu.net)" + VALUE "FileDescription", "php library" + VALUE "FileVersion", "1, 0, 0, 8" + VALUE "InternalName", "LIBPHP" + VALUE "LegalCopyright", "Copyright © 2000-2004 Piotr Pawluczuk (www.piopawlu.net)" + VALUE "OriginalFilename", "libphp.dll" + VALUE "ProductName", "LIBPHP" + VALUE "ProductVersion", "1, 0, 0, 8" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x415, 1200 + END +END + +#endif // Polish resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/mBot/src/libphp/libphp.vcproj b/mBot/src/libphp/libphp.vcproj new file mode 100644 index 0000000..4dee41a --- /dev/null +++ b/mBot/src/libphp/libphp.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mBot/src/libphp/phpenv.cpp b/mBot/src/libphp/phpenv.cpp new file mode 100644 index 0000000..cf82192 --- /dev/null +++ b/mBot/src/libphp/phpenv.cpp @@ -0,0 +1,1502 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "libphp.h" +#include "internals.h" +#include "svar.h" +#include "phpenv.h" + +#define UH(s) (unsigned char*)(s) +#define PHPWS php_error_docref(NULL TSRMLS_CC,E_WARNING, +#define PHPWE );return +#define PHPWSE(s) php_error_docref(NULL TSRMLS_CC,E_WARNING,s);return + +void php_phpenv_sapi_error(int type, const char *fmt, ...); +int php_phpenv_ub_write(const char *str, unsigned int str_length TSRMLS_DC); +void php_phpenv_log_message(char *message); +int php_phpenv_startup(sapi_module_struct *sapi_module); +char* php_phpenv_read_cookies(TSRMLS_D); +void php_phpenv_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC); +void php_phpenv_flush(void *server_context); +int php_phpenv_read_post(char *buffer, uint count_bytes TSRMLS_DC); +int php_phpenv_deactivate(TSRMLS_D); +char* php_phpenv_getenv(char *name, size_t name_len TSRMLS_DC); +void php_phpenv_register_variables(zval *track_vars_array TSRMLS_DC); +int php_set_ini_entry(char *entry, char *value, int stage); +int php_update_ini_file(TSRMLS_D); + +///////////////////////////////////// +//GLOBALS +///////////////////////////////////// +extern LPHP_FREE g_free; +extern LPHP_MALLOC g_malloc; +extern LPHP_OUTPUT g_std_out; +extern LPHP_OUTPUT g_std_err; +extern CRITICAL_SECTION g_csection; + +extern sVARmap g_vars; +extern sFCNmap g_fcns; +sTHRlst g_php_threads; + +unsigned long g_stat_num_executions = 0; +unsigned long g_stat_num_errors = 0; +unsigned long g_stat_num_threads = 0; + +unsigned long g_tls_key = 0; + +zend_function_entry* g_zend_functions = NULL; + +/* declaration of functions to be exported */ +ZEND_FUNCTION(mt_echo); +ZEND_FUNCTION(mt_clock); +ZEND_FUNCTION(mt_getvar); +ZEND_FUNCTION(mt_delvar); +ZEND_FUNCTION(mt_setvar); +ZEND_FUNCTION(mt_isvar); +ZEND_FUNCTION(mt_call); +PHP_MINIT_FUNCTION(mt_module_entry); + +/* compiled function list so Zend knows what's in this module */ +zend_function_entry mt_functions[] = +{ + PHP_FE(mt_echo,NULL)// UH("s")) //ok + PHP_FE(mt_clock,NULL)// UH(""))//ok + PHP_FE(mt_getvar,NULL)// UH("s")) + PHP_FE(mt_delvar,NULL)// UH("s")) + PHP_FE(mt_setvar,NULL)// UH("ssl")) + PHP_FE(mt_isvar,NULL) + PHP_FE(mt_call,NULL)// UH("s|ssss")) + //////////////////////////////// + {NULL, NULL, NULL} +}; + +/* compiled module information */ +static zend_module_entry mt_module_entry = +{ + STANDARD_MODULE_HEADER, + "libphp (www.piopawlu.net)", + mt_functions, + PHP_MINIT(mt_module_entry), + NULL, + NULL, + NULL, + NULL, + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES +}; + +PHP_MINIT_FUNCTION(mt_module_entry) +{ + if(g_php_module && ((zend_module_entry*)g_php_module)->module_startup_func) + { + ((zend_module_entry*)g_php_module)->module_startup_func(INIT_FUNC_ARGS_PASSTHRU); + } + return SUCCESS; +} + +static sapi_module_struct phpenv_sapi_module = { + "libphp 1.0.0.8", /* name */ + "libPHP", /* pretty name */ + + php_phpenv_startup, /* startup */ + php_module_shutdown_wrapper, /* shutdown */ + + NULL, /* activate */ + php_phpenv_deactivate, /* deactivate */ + + php_phpenv_ub_write, /* unbuffered write */ + php_phpenv_flush, /* flush */ + NULL, /* get uid */ + php_phpenv_getenv, /* getenv */ + + php_phpenv_sapi_error, /* error handler */ + + NULL, /* header handler */ + NULL, /* send headers handler */ + php_phpenv_send_header, /* send header handler */ + + php_phpenv_read_post, /* read POST data */ + php_phpenv_read_cookies, /* read Cookies */ + + php_phpenv_register_variables, /* register server variables */ + php_phpenv_log_message, /* Log message */ + + NULL, /* Block interruptions */ + NULL, /* Unblock interruptions */ + + STANDARD_SAPI_MODULE_PROPERTIES +}; + +ZEND_FUNCTION(mt_echo) +{ + char* str; + long strl; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str,&strl) == FAILURE){ + PHPWSE("mt_echo takes exactly one string parameter!"); + } + + g_std_out(str,strl); + RETURN_LONG(1); +} + +ZEND_FUNCTION(mt_clock) +{ + RETURN_LONG(clock()); +} + +ZEND_FUNCTION(mt_call) +{ + char *cmd=NULL, *par1=NULL, *par2=NULL, *par3=NULL, *par4=NULL, *tmp=NULL; + long cmd_l=0, par1_l=0, par2_l=0, par3_l=0, par4_l=0; + long np = 0; + long rt = 0; + void* rv = NULL; + const lphp_funct* f; + sFCNmap::const_iterator it; + + #define xtol(a) strtol(a,NULL,0) + + sPHPENV* ctx = (sPHPENV*)SG(server_context); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ssss", + &cmd,&cmd_l,&par1,&par1_l,&par2,&par2_l,&par3,&par3_l,&par4,&par4_l) == FAILURE || !cmd_l || strlen(cmd)<1) + { + PHPWSE("Not enough parameters given!"); + return; + } + + it = g_fcns.find(cmd); + if(it == g_fcns.end() || !it->second.ptr){ + PHPWS "Function %s is not defined!", cmd PHPWE; + return; + } + f = &it->second; + + rt = f->pinfo & 0x03; + + try + { + switch(f->lp) + { + case 0: + { + LPHP_GEN0 g0 = (LPHP_GEN0)f->ptr; + rv = g0(ctx->c_param); + break; + } + case 1: + { + LPHP_GEN1 g1 = (LPHP_GEN1)f->ptr; + rv = g1(ctx->c_param,(f->pinfo & 0x0C)?((void*)par1):((void*)xtol(par1))); + break; + } + case 2: + { + LPHP_GEN2 g2 = (LPHP_GEN2)f->ptr; + rv = g2(ctx->c_param,(f->pinfo & 0x0C)?((void*)par1):((void*)xtol(par1)), + (f->pinfo & 0x30)?((void*)par2):((void*)xtol(par2))); + break; + } + case 3: + { + LPHP_GEN3 g3 = (LPHP_GEN3)f->ptr; + rv = g3(ctx->c_param,(f->pinfo & 0x0C)?((void*)par1):((void*)xtol(par1)), + (f->pinfo & 0x30)?((void*)par2):((void*)xtol(par2)), + (f->pinfo & 0xC0)?((void*)par3):((void*)xtol(par3))); + break; + } + case 4: + { + LPHP_GEN4 g4 = (LPHP_GEN4)f->ptr; + rv = g4(ctx->c_param,(f->pinfo & 0x000C)?((void*)par1):((void*)atol(par1)), + (f->pinfo & 0x0030)?((void*)par2):((void*)xtol(par2)), + (f->pinfo & 0x00C0)?((void*)par3):((void*)xtol(par3)), + (f->pinfo & 0x0300)?((void*)par4):((void*)xtol(par4))); + break; + } + default: + PHPWS "You can't call a function taking %u parameters!", f->lp PHPWE; + return; + } + + if(rt == 0){ + RETURN_LONG((long)rv); + }else if(rt == 1){ + if(rv){ + tmp = estrdup((const char*)rv); + g_free((void*)rv); + RETURN_STRING(tmp,FALSE); + }else{ + RETURN_FALSE; + } + }else{ + RETURN_LONG(1); + } + } + catch(...) + { + PHPWS "An exception occured while executing the %s function!", cmd PHPWE; + return; + } +} + + +int return_var(zval* out,unsigned char* data) +{ + int kt; + char* key; + char* str; + double* dbl; + ulong nk=0; + ulong* tmp; + zval* val; + int toff = 0; + unsigned char* od = data; + + while(*data != 'X') + { + val = NULL; + if(*data == '%'){ + kt = 0; + data++; + }else if(*data == '>'){ + kt = HASH_KEY_IS_STRING; + tmp = (ulong*)(++data); + key = (char*)data + 4; + data += *tmp + 4; + }else{ + kt = HASH_KEY_IS_LONG; + tmp = (ulong*)(++data); + nk = *tmp; + data += 4; + } + + val = NULL; + MAKE_STD_ZVAL(val); + + switch(*data++) + { + case 'S': + tmp = (ulong*)(data); + data += 4; + str = (char*)data; + ZVAL_STRINGL(val,str,*tmp,1); + data += *tmp; + break; + case 'L': + tmp = (ulong*)(data); + data += 4; + ZVAL_LONG(val,*tmp); + break; + case 'D': + dbl = (double*)(data); + data += 8; + ZVAL_DOUBLE(val,*dbl); + break; + case 'B': + ZVAL_BOOL(val,*data++); + break; + case 'N': + ZVAL_NULL(val); + break; + case 'A': + if(array_init(val)==FAILURE || !(toff = return_var(val,data))){ + return 0; + }else{ + data += toff; + } + break; + default: + return 0; + }//switch + if(kt == HASH_KEY_IS_STRING){ + add_assoc_zval(out,key,val); + }else if(kt == HASH_KEY_IS_LONG){ + add_index_zval(out,nk,val); + }else{ + add_next_index_zval(out,val); + } + }data++; + + return (data - od); +} + +ZEND_FUNCTION(mt_getvar) +{ + cLock(g_csection); + + char* vname = NULL; + long vnl = 0; + const sVar* sv = NULL; + sVARmap::const_iterator it; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&vname,&vnl) == FAILURE){ + PHPWSE("You've not provided the numeber of parameters the function needs!"); + return; + } + + it = g_vars.find(vname); + + if(it == g_vars.end()){ + PHPWS "Variable %s is not defined!", vname PHPWE; + } + + sv = &it->second; + + if(sv->type == SV_LONG || sv->type == SV_WORD){ + RETVAL_LONG(sv->lval); + }else if(sv->type == SV_LPOINTER){ + RETVAL_LONG(*((long*)sv->lval)); + }else if(sv->type == SV_DOUBLE){ + RETVAL_DOUBLE(sv->dval); + }else if(sv->type == SV_STRING){ + RETVAL_STRING(sv->str.val,1); + }else if(sv->type == SV_ARRAY){ + if(array_init(return_value)==FAILURE){ + PHPWSE("Could not initialize array!"); + } + return_var(return_value,(unsigned char*)(sv->str.val + 1)); + }else if(sv->type == SV_NULL){ + RETVAL_NULL(); + return; + }else{ + PHPWS "Unknown variable type %u!", sv->type PHPWE; + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mt_delvar) +{ + char* vname = NULL; + long vnl = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&vname,&vnl) == FAILURE || !vnl){ + PHPWSE("No parameters given!"); + } + + if(LPHP_DelVar(vname)){ + RETURN_LONG(1); + }else{ + PHPWS "Variable %s wasn't defined!", vname PHPWE; + } +} + +ZEND_FUNCTION(mt_isvar) +{ + char* vname = NULL; + long vnl = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&vname,&vnl) == FAILURE || !vnl){ + PHPWSE("No parameters given!"); + } + + RETURN_LONG(LPHP_IsVar(vname)); +} + +int make_var(zval* v,cutMemf* mf,bool keep_idx) +{ + unsigned long t1; + unsigned long t2; + + if(v->type == IS_STRING){ + t1 = v->value.str.len; + mf->putc('S'); + mf->write(&t1,4); + mf->write(v->value.str.val,t1); + }else if(v->type == IS_LONG){ + mf->putc('L'); + mf->write(&v->value.lval,4); + }else if(v->type == IS_DOUBLE){ + mf->putc('D'); + mf->write(&v->value.dval,8); + }else if(v->type == IS_BOOL){ + mf->putc('B'); + mf->write(&v->value.lval,1); + }else if(v->type == IS_NULL){ + mf->putc('N'); + }else if(v->type == IS_ARRAY){ + HashPosition pos; + zval** aitem; + zval* aval; + uint str_len; + char *str; + ulong num_key = 0; + + mf->putc('A'); + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(v),&pos); + while(zend_hash_get_current_data_ex(Z_ARRVAL_P(v),(void**)&aitem,&pos) == SUCCESS) + { + aval = *aitem; + if(!aval)return 0; + + if(!keep_idx){ + mf->putc('%'); + }else{ + t2 = zend_hash_get_current_key_ex(Z_ARRVAL_P(v),&str,&str_len,&num_key,0,&pos); + if(t2 == HASH_KEY_IS_STRING){ + mf->putc('>'); + str_len++; + mf->write(&str_len,4); + mf->write(str,str_len-1); + mf->putc('\0'); + }else{ + mf->putc('@'); + mf->write(&num_key,4); + } + } + + make_var(aval,mf,keep_idx); + zend_hash_move_forward_ex(Z_ARRVAL_P(v), &pos); + } + mf->putc('X'); + }else{ + return 1; + } + return 1; +} + +ZEND_FUNCTION(mt_setvar) +{ + char* vname = NULL; + long vnl = 0; + zval* val; + void* mem; + zend_bool create = 1; + zend_bool keep_idx = 0; + cutMemf mf; + sVar sv; + sVARmap::iterator it; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|bb",&vname,&vnl,&val,&create,&keep_idx) == FAILURE){ + PHPWSE("Not enough parameters given!"); + return; + } + + if(!create && (it = g_vars.find(vname)) == g_vars.end()){ + RETURN_LONG(0); + } + + if(val->type == IS_STRING){ + sVariable(&sv,SV_STRING,(char*)val->value.str.val,0,0); + }else if(val->type == IS_DOUBLE){ + sVariable(&sv,val->value.dval,0); + }else if(val->type == IS_LONG || val->type == IS_BOOL){ + sVariable(&sv,SV_LONG,(void*)(val->value.lval),0,0); + }else if(val->type == IS_ARRAY){ + if(!mf.create(512) || !make_var(val,&mf,keep_idx!=0)){ + PHPWSE("Could not create variable!"); + } + mf.putc(0); + mem = svar_malloc(vnl = mf.size()); + if(!mem){ + mf.close(); + PHPWSE("Could not allocate memory!"); + }else{ + memcpy(mem,mf.getdata(),vnl); + mf.close(); + sVariable(&sv,SV_ARRAY,mem,vnl,0); + } + }else if(val->type == IS_NULL){ + sVariable(&sv,SV_NULL,0,0,0); + }else{ + PHPWSE("Unsupported variable type!"); + } + + if(!create){ + it->second = sv; + }else{ + g_vars[vname] = sv; + vnl = 1; + } + + if(vnl){ + RETURN_LONG(1); + }else{ + svar_freevar(&sv); + } + PHPWSE("Could not put the variable into the bucket!"); +} +//////////////////////////////// +//GO_PHPSCRIPT +//////////////////////////////// + +int GO_EvalString(sEPHP* ephp TSRMLS_DC) +{ + zval pv; + zval fn; + zval *rv = NULL; + zval **args[16] = {NULL}; + zval *argv[16] = {0}; + zval *local_retval_ptr = NULL; + zend_op_array *new_op_array; + int retval = FAILURE; + const char* pt = ephp->pszPT; + long pc = (!pt)?(0):(strlen(pt)); + + zend_op_array *original_active_op_array = EG(active_op_array); + zend_function_state *original_function_state_ptr = EG(function_state_ptr); + zend_uchar original_handle_op_arrays; + zval **original_return_value_ptr_ptr = NULL; + zend_op **original_opline_ptr = NULL; + + if(pc > 16){ + return FAILURE; + }else if(pt){ + for(int i=0;ipArguments,char*); + if(tmp){ + ZVAL_STRING(argv[i],tmp,0); + }else{ + ZVAL_NULL(argv[i]); + } + } + break; + case 'S': + { + char** tmp = va_arg(ephp->pArguments,char**); + if(tmp && *tmp){ + ZVAL_STRING(argv[i],*tmp,1); + }else{ + ZVAL_NULL(argv[i]); + } + } + break; + case 'd': + case 'l': + case 'u': + case 'c': + case 'x': + { + long tmp = va_arg(ephp->pArguments,long); + ZVAL_LONG(argv[i],tmp); + } + break; + case 'U': + case 'D': + case 'X': + case 'C': + case 'L': + { + long* tmp = va_arg(ephp->pArguments,long*); + ZVAL_LONG(argv[i],*tmp); + } + break; + case 'f': + { + float tmp = va_arg(ephp->pArguments,float); + ZVAL_DOUBLE(argv[i],tmp); + } + break; + case 'q': + { + double tmp = va_arg(ephp->pArguments,double); + ZVAL_DOUBLE(argv[i],tmp); + } + break; + case 'b': + { + int tmp = va_arg(ephp->pArguments,int); + ZVAL_BOOL(argv[i],tmp); + } + break; + case 'm'://string array + { + char** tmp = va_arg(ephp->pArguments,char**); + long n = 0; + + if(!tmp){ + ZVAL_LONG(argv[i],0); + }else{ + if(array_init(argv[i])==FAILURE){ + goto CleanUp; + } + while(*tmp){ + add_index_string(argv[i],n++,*tmp,0); + tmp++; + } + } + } + break; + case 'v': + { + lphp_vparam* tmp = va_arg(ephp->pArguments,lphp_vparam*); + if(!tmp){ + ZVAL_LONG(argv[i],0); + }else{ + if(tmp->type == LPHP_STRING){ + ZVAL_STRINGL(argv[i],(char*)tmp->data,tmp->length,0); + }else{ + ZVAL_LONG(argv[i],(long)tmp->data); + } + } + } + break; + default: + pc = i+1; + goto CleanUp; + }//switch(*pt) + args[i] = &argv[i]; + } + } + + if(ephp->pszFunction){ + fn.value.str.len = strlen(ephp->pszFunction); + fn.value.str.val = (char*)ephp->pszFunction; + fn.type = IS_STRING; + } + + pv.value.str.len = strlen(ephp->pszBody); + pv.value.str.val = (char*)ephp->pszBody; + pv.type = IS_STRING; + + original_handle_op_arrays = CG(handle_op_arrays); + CG(handle_op_arrays) = 0; + try{ + new_op_array = compile_string(&pv,(ephp->pszFile)?((char*)ephp->pszFile):((char*)ephp->pszFunction) TSRMLS_CC); + }catch(...){ + CG(handle_op_arrays) = original_handle_op_arrays; + return FAILURE; + } + CG(handle_op_arrays) = original_handle_op_arrays; + + if (new_op_array) + { + original_return_value_ptr_ptr = EG(return_value_ptr_ptr); + original_opline_ptr = EG(opline_ptr); + + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + + try{ + zend_execute(new_op_array TSRMLS_CC); + }catch(...){ + goto Skip; + } + + if(ephp->pszFunction){ + retval = call_user_function_ex(CG(function_table),NULL,&fn,&rv,pc,(pc)?args:NULL,0,NULL TSRMLS_CC); + }else{ + retval = SUCCESS; + } + + if(rv){ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + if(rv->type == IS_LONG || rv->type == IS_BOOL){ + ctx->m_flags |= PHPENV_FLAG_NUMERIC_RESULT; + ctx->r_value = (const char*)rv->value.lval; + }else if(rv->type == IS_DOUBLE){ + ctx->m_flags |= PHPENV_FLAG_NUMERIC_RESULT; + ctx->r_value = (const char*)((long)rv->value.dval); + }else if(rv->type == IS_STRING){ + ctx->r_value = (const char*)g_malloc(rv->value.str.len+1); + if(ctx->r_value){ + memcpy((void*)ctx->r_value,rv->value.str.val,rv->value.str.len); + ((char*)ctx->r_value)[rv->value.str.len]='\0'; + } + }else{ + ctx->m_flags |= PHPENV_FLAG_NUMERIC_RESULT; + ctx->r_value = NULL; + } + zval_ptr_dtor(&rv); + } + + EG(return_value_ptr_ptr) = &local_retval_ptr; + + if(local_retval_ptr){ + zval_ptr_dtor(&local_retval_ptr); + } +Skip: + EG(no_extensions)=0; + EG(opline_ptr) = original_opline_ptr; + EG(active_op_array) = original_active_op_array; + EG(function_state_ptr) = original_function_state_ptr; + EG(return_value_ptr_ptr) = original_return_value_ptr_ptr; + destroy_op_array(new_op_array TSRMLS_CC); + efree(new_op_array); + } else { + retval = FAILURE; + } +CleanUp: + for(int i=0;itype = IS_LONG; + argv[i]->value.lval = 0; + FREE_ZVAL(argv[i]); + } + return retval; +} + +int GO_PhpExecute2(sEPHP* ephp) +{ + ephp->th_id = GetCurrentThreadId(); + if(!GO_PhpExecute2Locked(ephp)){ + g_stat_num_errors++; + return FALSE; + }else{ + return TRUE; + } + return 0; +} + +/* frees all resources allocated for the current thread */ + +struct TSRMENTRY{ + void **storage; + int count; + unsigned long thread_id; + TSRMENTRY *next; +}; + +TSRMENTRY* GetParentEntry(unsigned long tid) +{ + cLock(g_csection); + + TSRMENTRY* tmp = NULL; + tmp = (TSRMENTRY*)TlsGetValue(g_tls_key); + + g_stat_num_executions++; + + while(tmp) + { + if(tmp->thread_id == tid){ + break; + } + tmp = tmp->next; + } + return tmp; +} + +int exceptionhandler(LPEXCEPTION_POINTERS *e, LPEXCEPTION_POINTERS ep) +{ + *e=ep; + return TRUE; +} + +int GO_LockThread(unsigned long thID) +{ + cLock(g_csection); + + sTHRlst::iterator it; + it = g_php_threads.find(thID); + + if(it != g_php_threads.end()){ + return FALSE; + } + g_php_threads[thID] = 1; + return TRUE; +} + +int GO_UnlockThread(unsigned long thID) +{ + extern int g_initialized; + + if(!g_initialized){ + //we do not want it, cause another thread is cleaning up... + return TRUE; + } + + cLock(g_csection); + + sTHRlst::iterator it; + it = g_php_threads.find(thID); + + if(it == g_php_threads.end()){ + return FALSE; + } + + g_php_threads.erase(it); + return TRUE; +} + +int GO_PhpExecute2Locked(sEPHP* ephp) +{ + long rv = 0xff00ff00; + long result = 0; + long started = 0; + void ***tsrm_ls = NULL; + sPHPENV php_ctx; + LPEXCEPTION_POINTERS e; + int parent_to = 0; + int branch = 0; + TSRMENTRY* parent = GetParentEntry(ephp->th_id); + TSRMENTRY* tht; + TSRMENTRY op; + ///////////////////////////// + //check if this is not a php call + ///////////////////////////// + if(!GO_LockThread(ephp->th_id)){ + branch = 1; + g_stat_num_threads++; + } + + if(branch && parent){ + tsrm_ls = (void ***) ts_resource_ex(0,NULL); + parent_to = EG(timeout_seconds); + EG(timeout_seconds) = 0; + + memcpy(&op,parent,sizeof(op)); + memset(parent,0,sizeof(op)); + TlsSetValue(g_tls_key,NULL); + } + + __try + { + tsrm_ls = (void ***) ts_resource_ex(0,NULL); + } + __except(exceptionhandler(&e, GetExceptionInformation())){ + if(branch && parent){ + memcpy(parent,&op,sizeof(op)); + TlsSetValue(g_tls_key,parent); + tsrm_ls = (void ***) ts_resource_ex(0,NULL); + EG(timeout_seconds) = parent_to; + }else{ + GO_UnlockThread(ephp->th_id); + } + lphp_error(MT_LOG_EXCEPTION,e,"[%s],ts_resource_ex(0,NULL);\r\n",ephp->pszFile); + } + + tht = GetParentEntry(ephp->th_id); + ////////////////// + SG(server_context) = &php_ctx; + + ////////////////// + php_ctx.r_out = ephp->pOut; + php_ctx.m_flags = (ephp->pOut)?(1):(0); + php_ctx.c_param = (void*)ephp->c_param; + php_ctx.script_path = ephp->pszFile; + ////////////////// + if(!ephp->pszBody || tsrm_ls == NULL){ + goto End; + } + ////////////////// + php_update_ini_file(TSRMLS_C); + SG(options) |= SAPI_OPTION_NO_CHDIR; + ////////////////// + zend_first_try + ////////////////// + { + __try + { + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + + php_request_startup(TSRMLS_C);started = 1; + rv = GO_EvalString(ephp TSRMLS_CC); + result = (rv == SUCCESS); + } + __except(exceptionhandler(&e, GetExceptionInformation())){ + lphp_error(MT_LOG_EXCEPTION,e,"[%s],php_execute_script();\r\n",ephp->pszFile); + } + } + ////////////////// + zend_catch + { + result = 0xffffffff; + } + zend_end_try(); + ////////////////// + + if(result != 1){ + lphp_error(MT_LOG_ERROR,NULL,"[%s],php_execute_script [%.8x][%.8x]\r\n",ephp->pszFile,rv,result); + }else{ + if(ephp->cFlags & 0x01) + { + if(php_ctx.m_flags & PHPENV_FLAG_NUMERIC_RESULT) + { + ephp->cResType = 0x00; + ephp->res.lval = (long)php_ctx.r_value; + } + else if(php_ctx.r_value) + { + ephp->cResType = 0x01; + if(ephp->res.str.val && ephp->res.str.len){ + strncpy(ephp->res.str.val,(const char*)php_ctx.r_value,ephp->res.str.len); + }else{ + ephp->res.str.val = _strdup((const char*)php_ctx.r_value); + ephp->res.str.len = strlen((const char*)php_ctx.r_value); + g_free((void*)php_ctx.r_value); + } + } + else + { + ephp->cResType = 0x00; + ephp->res.str.val = NULL; + ephp->res.str.len = 0; + } + } + } + + if(started == 1){ + __try + { + php_request_shutdown(NULL); + } + __except(exceptionhandler(&e, GetExceptionInformation())){ + lphp_error(MT_LOG_EXCEPTION,e,"[%s],php_request_shutdown(NULL);\r\n",ephp->pszFile); + } + } + + if(branch && parent) + { + __try{ + ts_free_thread(); + }__except(exceptionhandler(&e, GetExceptionInformation())){ + lphp_error(MT_LOG_EXCEPTION,e,"[%s],ts_free_thread();\r\n",ephp->pszFile); + } + if(parent){ + memcpy(parent,&op,sizeof(op)); + TlsSetValue(g_tls_key,parent); + tsrm_ls = (void ***) ts_resource_ex(0,NULL); + EG(timeout_seconds) = parent_to; + } + }else{ + GO_UnlockThread(ephp->th_id); + } +End: + return (result == 1); +} + +int GO_PhpExecute(const char* script,std::string* out,cutFile* redir_out,long mode, + const char* querystring,void* cparam,PHPENV_CB fpCb) +{ + long rv = 0xff00ff00; + long result = 0; + long started = 0; + void ***tsrm_ls = NULL; + unsigned long thread_id = GetCurrentThreadId(); + sPHPENV php_ctx; + zend_file_handle file_handle = {0}; + zval* ret_val = NULL; + char full_path[260] = {0}; + ///////////////////////////// + //check if this is not a php call + ///////////////////////////// + + if(!GO_LockThread(thread_id)){ + lphp_error(MT_LOG_ERROR,NULL,"You must not call php from another php script!"); + return 0; + } + + try + { + tsrm_ls = (void ***) ts_resource_ex(0, NULL); + } + catch(LPEXCEPTION_POINTERS e) + { + lphp_error(MT_LOG_EXCEPTION,e,"ts_resource_ex(0,NULL);"); + goto End; + } + + + ////////////////// + SG(server_context) = &php_ctx; + ////////////////// + php_ctx.r_out = redir_out; + php_ctx.m_flags = (redir_out)?(1):(0); + php_ctx.c_param = cparam; + php_ctx.fp_callback = fpCb; + php_ctx.query_string = querystring; + php_ctx.script_path = (mode == PHPENV_MODE_SCRIPT)?"":script; + ////////////////// + if(!script || !strlen(script) || tsrm_ls == NULL){ + goto End; + } + ////////////////// + php_update_ini_file(TSRMLS_C); + ////////////////// + if(mode & PHPENV_MODE_FILE) + { + if(!fpCb){ + goto End; + } + + strncpy(full_path,script,sizeof(full_path)); + } + ////////////////// + SG(options) |= SAPI_OPTION_NO_CHDIR; + ////////////////// + zend_first_try + ////////////////// + { + try + { + if(mode & PHPENV_MODE_SCRIPT) + { + if(!(mode & PHPENV_MODE_ALLOWHDR)) + { + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } + else + { + if(!fpCb){ + goto End; + } + } + + php_request_startup(TSRMLS_C);started = 1; + rv = zend_eval_string((char*)script,NULL,"libphp (www.piopawlu.net)" TSRMLS_CC); + result = (rv == SUCCESS); + } + else + { + file_handle.filename = full_path; + file_handle.free_filename = 0; + file_handle.type = ZEND_HANDLE_FILENAME; + file_handle.opened_path = NULL; + + php_ctx.post_len = (long)fpCb(LPHP_CB_POST_LENGTH,0,0,cparam); + php_ctx.post_data = (unsigned char*)fpCb(LPHP_CB_POST_DATA,0,0,cparam); + php_ctx.content_length = (long)fpCb(LPHP_CB_GETCL,0,0,cparam); + php_ctx.content_type = (const char*)fpCb(LPHP_CB_GETCT,0,0,cparam); + + SG(request_info).cookie_data = (char*)fpCb(LPHP_CB_GETCOOKIE,0,0,cparam); + SG(request_info).request_method = (const char*)fpCb(LPHP_CB_GETMETHOD,0,0,cparam); + SG(request_info).content_type = php_ctx.content_type; + SG(request_info).content_length = php_ctx.post_len; + SG(request_info).path_translated = full_path; + SG(request_info).query_string = (querystring)?((char*)querystring):((char*)""); + ////////// + php_request_startup(TSRMLS_C);started = 1; + php_execute_simple_script(&file_handle, &ret_val TSRMLS_CC); + result = 1; + } + + if(out && php_ctx.r_value){ + *out = php_ctx.r_value; + } + } + catch(LPEXCEPTION_POINTERS e) + { + lphp_error(MT_LOG_EXCEPTION,e,"php_execute_script();"); + } + } + ////////////////// + zend_catch + ////////////////// + { + result = 0xffffffff; + } + ////////////////// + zend_end_try(); + ////////////////// + + if(result != 1){ + lphp_error(MT_LOG_ERROR,NULL,"php_execute_script [%.8x][%.8x]",rv,result); + } + + if(started == 1) + { + try{ + php_request_shutdown(NULL); + } + catch(LPEXCEPTION_POINTERS e) + { + lphp_error(MT_LOG_EXCEPTION,e,"php_request_shutdown(NULL);"); + } + } + +End: + GO_UnlockThread(thread_id); + return (result == 1); +} + +int GO_PhpGlobalInit() +{ + const char* php_ini = NULL; + void*** key = NULL; + TSRMENTRY* te; + unsigned long php_tc = g_pref_ul("/cfg/php/tc",10,1); + sVar sv; + + php_ini = g_pref("/cfg/php/ini"); + phpenv_sapi_module.php_ini_path_override = (php_ini)?(php_ini):"php.ini"; + + if(!tsrm_startup(64,1,NULL,NULL)){ + return FALSE; + } + + //g_tls_key + key = (void ***) ts_resource_ex(0,NULL); + if(key){ + for(int i=0;i<512;i++){ + te = (TSRMENTRY*)TlsGetValue(i); + if(te && ((void***)te) == key){ + g_tls_key = i; + break; + } + } + if(!g_tls_key){ + tsrm_shutdown(); + return FALSE; + } + }else{ + tsrm_shutdown(); + return FALSE; + } + + + sapi_startup(&phpenv_sapi_module); + + if(phpenv_sapi_module.startup){ + phpenv_sapi_module.startup(&phpenv_sapi_module); + } + + sVariable(&sv,SV_LPOINTER,&g_stat_num_executions, 0, 1); + g_vars["/stat/php/num_execs"] = sv; + + sVariable(&sv,SV_LPOINTER,&g_stat_num_errors, 0, 1); + g_vars["/stat/php/num_errors"] = sv; + + sVariable(&sv,SV_LPOINTER,&g_stat_num_threads, 0, 1); + g_vars["/stat/php/num_threads"] = sv; + + return TRUE; +} +int GO_PhpGlobalDeInit() +{ + HANDLE hThread; + + //lock further execution and wait for all the threads remaining + cLock(g_csection); + sTHRlst::iterator it = g_php_threads.begin(); + + while(it != g_php_threads.end()) + { + cULock(); + hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, it->first); + if(hThread != NULL){ + if(WaitForSingleObject(hThread, 2000) != WAIT_OBJECT_0){ + TerminateThread(hThread, -1); + } + CloseHandle(hThread); + } + cLLock(); + it++; + } + + if(phpenv_sapi_module.shutdown) + { + try{ + phpenv_sapi_module.shutdown(&sapi_module); + }catch(...){} + } + + try{ + tsrm_shutdown(); + }catch(...){} + + mt_module_entry.functions = mt_functions; + if(g_zend_functions){ + free(g_zend_functions); + g_zend_functions = NULL; + } + return TRUE; +} + +int php_phpenv_ub_write(const char *str, unsigned int str_length TSRMLS_DC) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + + SG(headers_sent) = 1; + + if(ctx->fp_callback){ + ctx->fp_callback(1,0,0,ctx->c_param); + } + + if(ctx->r_out){ + ctx->r_out->write((void*)str,str_length); + return SUCCESS; + } + +#ifdef _DEBUG + g_std_out(str, strlen(str)); + return SUCCESS; +#else + if((ctx->m_flags & PHPENV_FLAG_DISABLE_OUTPUT)){ + return SUCCESS; + }else{ + g_std_out(str,strlen(str)); + return SUCCESS; + } +#endif +} +void php_phpenv_sapi_error(int type, const char *fmt, ...) +{ + char error[1024]; + + va_list ap; + va_start(ap, fmt); + _vsnprintf(error,sizeof(error)-1,fmt,ap); + php_phpenv_ub_write(error,strlen(error),0); + va_end(ap); +} +void php_phpenv_log_message(char *message) +{ + g_std_err(message,strlen(message)); +} + +int php_set_ini_entry(char *entry, char *value, int stage) +{ + return (SUCCESS == zend_alter_ini_entry(entry, strlen(entry) + 1, value, strlen(value) + 1,PHP_INI_SYSTEM, stage)); +} +int php_phpenv_startup(sapi_module_struct *sapi_module) +{ + if(g_php_module == NULL) + { + mt_module_entry.functions = mt_functions; + if(php_module_startup(sapi_module,&mt_module_entry,1)==FAILURE){ + return FAILURE; + } + return SUCCESS; + } + else //new functions + { + long c1 = 0; + long c2 = 0; + long c = 0; + long x = 0; + zend_function_entry* cfe = mt_functions; + //count our own functions + while(cfe->fname){ + c1++; + cfe++; + } + //count given functions + cfe = ((zend_module_entry*)g_php_module)->functions; + while(cfe->fname){ + c2++; + cfe++; + } + c = c1 + c2; + + g_zend_functions = (zend_function_entry*)malloc((c + 1)*sizeof(zend_module_entry)); + if(!g_zend_functions){ + return FAILURE; + } + memset(g_zend_functions,0,(c + 1)*sizeof(zend_module_entry)); + //copy our own functions + cfe = mt_functions; + for(int i=0;ifunctions; + for(int i=0;ifp_callback) + { + return (char*)ctx->fp_callback(LPHP_CB_GETCOOKIE,0,0,ctx->c_param); + } + else{ + return NULL; + } + return 0; +} + +void php_phpenv_flush(void *server_context) +{ + return; +} + +void php_phpenv_register_variables(zval *track_vars_array TSRMLS_DC) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + const char* rm = "GET"; + const char* rv = NULL; + char temp[64]; + + if(ctx->fp_callback) + { + rm = (const char*)ctx->fp_callback(LPHP_CB_GETMETHOD,0,0,ctx->c_param); + + php_register_variable("REQUEST_METHOD",(char*)rm,track_vars_array TSRMLS_CC); + + if(ctx->content_type){ + php_register_variable("CONTENT_TYPE",(char*)ctx->content_type,track_vars_array TSRMLS_CC); + } + + _snprintf(temp,sizeof(temp)-1,"%u",ctx->content_length); + php_register_variable("CONTENT_LENGTH",temp,track_vars_array TSRMLS_CC); + + if(ctx->script_path){ + php_register_variable("PATH_TRANSLATED",(char*)ctx->script_path,track_vars_array TSRMLS_CC); + } + if(ctx->query_string){ + php_register_variable("QUERY_STRING",(char*)ctx->query_string,track_vars_array TSRMLS_CC); + } + + rm = (const char*)ctx->fp_callback(LPHP_CB_GETVARS,0,0,ctx->c_param); + if(rm){ + while(*rm){ + rv = rm + strlen(rm) + 1; + php_register_variable((char*)rm,(char*)rv,track_vars_array TSRMLS_CC); + rm = rv + strlen(rv) + 1; + } + } + } + php_import_environment_variables(track_vars_array TSRMLS_CC); +} + +int php_phpenv_read_post(char *buffer, uint count_bytes TSRMLS_DC) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + unsigned long to_read = 0; + unsigned long rd_left = 0; + + if(!ctx || !ctx->post_data){ + return 0; + } + + rd_left = ctx->post_len - ctx->post_read; + to_read = (rd_left >= count_bytes)?count_bytes:rd_left; + if(to_read <= 0){ + return 0; + } + + memcpy(buffer,(ctx->post_data + ctx->post_read),to_read); + ctx->post_read += to_read; + *(buffer + to_read) = '\0'; + return to_read; + return 0; +} + +void php_phpenv_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC) +{ + if(!sapi_header)return; + sPHPENV* ctx = (sPHPENV*)SG(server_context); + if(ctx && ctx->fp_callback){ + ctx->fp_callback(LPHP_CB_SETHDR,(void*)sapi_header->header,(void*)sapi_header->replace,ctx->c_param); + } +} +int php_phpenv_deactivate(TSRMLS_D){ + return SUCCESS; +} + +char* php_phpenv_getenv(char *name, size_t name_len TSRMLS_DC) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + + if(ctx->fp_callback){ + return (char*)ctx->fp_callback(LPHP_CB_GETENV,(void*)name,NULL,ctx->c_param); + }else{ + return getenv(name); + } + return NULL; +} + +int php_update_ini_file(TSRMLS_D) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + + if(!ctx->fp_callback && g_pref_ul("/cfg/php/noupd",10)){ + return 1; + } + + char inc_path_full[512]; + char* tmp = (char*)g_pref("/cfg/php/root"); + const char* root_dir = (tmp)?(tmp):(""); + + try + { + tmp = (char*)g_pref("/cfg/php/sessions"); + if(tmp && !php_set_ini_entry("session.save_path", (char*)tmp, PHP_INI_STAGE_ACTIVATE)){ + return 0; + } + + tmp = (char*)g_pref("/cfg/php/includes"); + if(tmp && !php_set_ini_entry("include_path", (char*)tmp, PHP_INI_STAGE_ACTIVATE)){ + return 0; + } + + if(ctx->fp_callback && ctx->script_path) + { + strncpy(inc_path_full+1,ctx->script_path,sizeof(inc_path_full)-2); + *inc_path_full = 0; + tmp = inc_path_full + strlen(ctx->script_path); + while(*tmp) + { + if(*tmp == '\\' || *tmp == '/'){ + *tmp='\0'; + break; + }else{ + tmp--; + if(!(*tmp)){ + *tmp = (char)(0xff); + } + } + } + + if(*tmp!=0xFF){ + if(!php_set_ini_entry("doc_root", (char*)(inc_path_full+1), PHP_INI_STAGE_ACTIVATE))return 0; + } + } + else + { + tmp = (char*)g_pref("/cfg/php/doc_root"); + if(tmp && !php_set_ini_entry("doc_root", (char*)tmp, PHP_INI_STAGE_ACTIVATE)){ + return 0; + } + } + + tmp = (char*)g_pref("/cfg/php/uploads"); + if(tmp && !php_set_ini_entry("upload_tmp_dir", (char*)tmp, PHP_INI_STAGE_ACTIVATE)){ + return 0; + } + + tmp = (char*)g_pref("/cfg/php/extensions"); + if(tmp && !php_set_ini_entry("extension_dir",(char*)tmp, PHP_INI_STAGE_ACTIVATE)){ + return 0; + } + return 1; + } + catch(...) + { + return 0; + } + return 1; +} \ No newline at end of file diff --git a/mBot/src/libphp/phpenv.h b/mBot/src/libphp/phpenv.h new file mode 100644 index 0000000..e398bdb --- /dev/null +++ b/mBot/src/libphp/phpenv.h @@ -0,0 +1,114 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#pragma once + +#ifndef _PHP_ENV_H_ +#define _PHP_ENV_H_ + +extern "C"{ + #include
+ #include
+ #include
+ #include
+ #include
+ #include +} +#include +#include + +const static long PHPENV_FLAG_DISABLE_OUTPUT = 0x01; +const static long PHPENV_MODE_SCRIPT = 0x01; +const static long PHPENV_MODE_FILE = 0x02; +const static long PHPENV_MODE_ALLOWHDR = 0x02; +const static long PHPENV_FLAG_NUMERIC_RESULT = 0x04; + +#ifdef _DEBUG +#define DBGS(s) OutputDebugString(s) +#else +#define DBGS(s) +#endif + +typedef std::map sTHRlst; + +typedef int (*PHPENV_CB)(long code,void* param1,void* param2,void* cparam); + +struct sPHPENV +{ + void* c_param; + PHPENV_CB fp_callback; + long m_flags; + //////////////////////////// + cutFile* r_out; + const char* r_value; + //////////////////////////// + const char* script_path; + const char* query_string; + const char* content_type; + long content_length; + //////////////////////////// + unsigned char* post_data; + long post_len; + long post_read; + //////////////////////////// +public: + sPHPENV(){memset(this,0,sizeof(sPHPENV));} +}; + +typedef struct sPHPExeParam +{ + const char* pszBody; + const char* pszFile; + const char* pszFunction; + const char* pszPT; + va_list pArguments; + cutFile* pOut; + const void* c_param; + //////////// + short dummy; + //////////// + char cFlags; + char cResType; + //////////// + union{ + struct{ + char* val; + long len; + }str; + long lval; + double dval; + }res; + unsigned long th_id; +}sEPHP; + +struct exe_helper{ + sEPHP* php; + int result; +}; + +int GO_PhpExecute(const char* script,std::string* out,cutFile* redir_out,long mode = PHPENV_MODE_SCRIPT, + const char* querystring = NULL,void* cparam = NULL,PHPENV_CB fpCb = NULL); +int GO_PhpExecute2Locked(sEPHP* ephp); +int GO_PhpExecute2(sEPHP* ephp); + +int GO_PhpGlobalInit(); +int GO_PhpGlobalDeInit(); + +#endif //_PHP_ENV_H_ \ No newline at end of file diff --git a/mBot/src/libphp/resource.h b/mBot/src/libphp/resource.h new file mode 100644 index 0000000..a2dd62d --- /dev/null +++ b/mBot/src/libphp/resource.h @@ -0,0 +1,34 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by libphp.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/mBot/src/libphp/svar.cpp b/mBot/src/libphp/svar.cpp new file mode 100644 index 0000000..c249859 --- /dev/null +++ b/mBot/src/libphp/svar.cpp @@ -0,0 +1,124 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "libphp.h" +#include "internals.h" +#include "svar.h" + +extern LPHP_MALLOC g_malloc; +extern LPHP_FREE g_free; + +void* svar_malloc(unsigned long amount) +{ + return g_malloc(amount); +} +char* svar_strdup(const char* str) +{ + unsigned long len = strlen(str)+1; + char* tmp = (char*)g_malloc(len); + if(tmp){ + memcpy(tmp,str,len); + } + return tmp; +} +void svar_free(void* ptr) +{ + try{//g_heap,0, + (ptr)?(g_free(ptr)):(0); + }catch(...){ + return; + } +} + +void svar_freevar(sVar* ptr) +{ + try{ + if(ptr) + { + if(ptr->type == SV_STRING || ptr->type > 10){ + svar_free(ptr->str.val); + ptr->str.val = 0; + } + } + }catch(...){ + return; + } +} + +int svar_set(sVar* v1, sVar* v2, void* param){ + + if(!v2) + {//release + if(v1->locked && param!=(void*)1)return 0; + svar_freevar(v1); + v1->type = SV_NULL; + } + else + { + if(v1->locked){ + return 1; + } + if(v1->type == SV_STRING || v1->type > 10){ + svar_free(v1->str.val); + v1->str = v2->str; + }else{ + v1->dval = v2->dval; + } + v1->type = v2->type; + } + return 1; +} + +void sVariable(sVar* out,char cType,void* pValue,unsigned long pLen,char cLocked) +{ + out->type = cType; + out->locked = cLocked; + + switch(cType){ + case SV_STRING: + out->str.val = (pLen)?((char*)pValue):(svar_strdup((const char*)pValue)); + out->str.len = (pLen)?(pLen):(strlen(out->str.val)); + break; + case SV_LONG: + case SV_WORD: + out->lval = (long)pValue; + break; + case SV_DOUBLE: + out->dval = *((double*)pValue); + break; + case SV_ARRAY: + out->str.val = (char*)pValue; + out->str.len = pLen; + break; + case SV_LPOINTER: + out->lval = (long)pValue; + break; + default: + out->type = SV_NULL; + out->lval = 0; + } +}; + +void sVariable(sVar* out,double val,char cLocked) +{ + out->type = SV_DOUBLE; + out->dval = val; + out->locked = cLocked; +} \ No newline at end of file diff --git a/mBot/src/libphp/svar.h b/mBot/src/libphp/svar.h new file mode 100644 index 0000000..05f63b6 --- /dev/null +++ b/mBot/src/libphp/svar.h @@ -0,0 +1,60 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _SVAR_H_ +#define _SVAR_H_ + +#include "internals.h" + +struct sVar +{ + char type; + char locked; + union{ + struct { + char* val; + unsigned long len; + }str; + long lval; + unsigned long ulval; + short sval; + double dval; + }; + + /*sVar(){ + this->type = 0; + this->lval = 0; + this->locked = 0; + }*/ +}; + +typedef stdext::hash_map sVARmap; +typedef stdext::hash_map sFCNmap; + +void sVariable(sVar* out,char cType,void* pValue,unsigned long pLen,char cLocked); +void sVariable(sVar* out,double val,char cLocked); + +void* svar_malloc(unsigned long amount); +char* svar_strdup(const char* str); +void svar_free(void* ptr); +void svar_freevar(sVar* ptr); +int svar_set(sVar* v1,sVar* v2,void* param); + +#endif //_SVAR_H_ diff --git a/mBot/src/mbot/config.cpp b/mBot/src/mbot/config.cpp new file mode 100644 index 0000000..1f64bab --- /dev/null +++ b/mBot/src/mbot/config.cpp @@ -0,0 +1,217 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "config.h" + +char pszCmdTag[8] = "m>"; +char pszPhpTag[8] = "?>"; +const char* pszMonospacedFont = "Courier"; +long lCmdTagLen = 2; +long lPhpTagLen = 2; +long lDebugOut = 0; +long lConTopMost = 0; +long lErrorLog = 0; +long lConFontSize = 13; +long lConToFile = 0; +cXmlDoc cSettings; + +static php_entry php_ini[] = +{ + {"memory_limit","8M",0}, + {"max_execution_time","45",0}, + {"display_startup_errors","On",0}, + {"precision","14",0}, + {"display_errors","On",0}, + {"asp_tags","Off",0}, + {"error_reporting","E_ALL",0}, + {"cgi.force_redirect","0",0}, + {"safe_mode","Off",0}, + {"implicit_flush","On",0}, + {"html_errors","Off",0}, + {"register_argc_argv","On",0}, + {"register_globals","On",0}, + {"variables_order","GPCES",1}, + {"magic_quotes_gpc","Off",0}, + {"file_uploads","On",0}, + {"upload_tmp_dir","$(mroot)\\mbot\\temp",1}, + {"upload_max_filesize","2M",0}, + {"session.use_cookies","1",1}, + {"session.cookie_path","/",1}, + {"session.name","phpsessid",1}, + {"session.save_path","$(mroot)\\mbot\\temp",1}, + {"include_path","$(mroot)\\mbot;$(mroot)\\mbot\\scripts;$(mroot)\\mbot\\scripts\\autoload",1}, + {"doc_root","$(mroot)\\mbot\\scripts\\autoload\\",1}, + {"extension_dir","$(mroot)\\mbot\\extensions",1}, + {NULL,NULL,0} +}; + +int php_generate_ini() +{ + char path[MAX_PATH + 2]={0}; + string ss; + sXmlNode* xn; + php_entry* ce; + long res = 0; + FILE* pini = NULL; + + _snprintf(path,sizeof(path)-1,"%s\\mbot\\config\\php.ini",g_root); + LPHP_NewVar("/cfg/php/ini",path,SV_STRING,1); + LPHP_NewVar("/cfg/php/noupd",(void*)1,SV_LONG,1); + LPHP_NewVar("/cfg/php/debug",(void*)1,SV_LONG,1); + LPHP_NewVar("/cfg/php/root",g_root,SV_STRING,1); + + _snprintf(path,sizeof(path)-1,"%s\\mbot\\config\\mbot.xml",g_root); + try{ + res = cSettings.ParseFile(path,cXmlDoc::PARSE_IGNORE_WHITESPACES | cXmlDoc::PARSE_COMMENTS); + }catch(...){ + res = 0; + } + + if(!res) + { + MessageBox(0,"Could not parse 'mbot/mbot.xml' configuration file!","MBot",MB_ICONERROR); + return 1; + } + //generate php.ini + _snprintf(path,sizeof(path)-1,"%s\\mbot\\config\\php.ini",g_root); + pini = fopen(path,"wb"); + fprintf(pini,";(auto-generated) Please don't ever modify this file! Modify mbot.xml instead!\r\n"); + for(ce = php_ini;(ce->name);ce++) + { + _snprintf(path,sizeof(path)-1,"mbot/php/%s",ce->name); + sXmlNode* xn = cSettings.GetNode(path,NULL); + ss = (xn && xn->value)?(xn->value):(ce->def_val); + ut_str_replace("$(default)", ce->def_val, ss); + ut_str_replace("$(mroot)", g_root, ss); + + if(xn){ + fprintf(pini,"%s=%c%s%c\r\n",ce->name,(ce->str)?('\"'):(' '),ss.data(),(ce->str)?('\"'):(' ')); + }else{ + fprintf(pini,"%s=%c%s%c\r\n",ce->name,(ce->str)?('\"'):(' '),ss.data(),(ce->str)?('\"'):(' ')); + } + } + xn = cSettings.GetNode("mbot/add_php",NULL); + if(xn && xn->f_child) + { + xn = xn->f_child; + while(xn) + { + if(xn->value && xn->name) + { + fprintf(pini, "%s=%s\r\n", xn->name, (xn && xn->value)?(xn->value):(ce->def_val)); + } + xn = xn->next; + } + } + fclose(pini); + + xn = cSettings.GetNode("mbot/thread_switch",NULL); + if(!xn || !xn->value){ + LPHP_NewVar("/cfg/php/thread_fork",(void*)0,SV_LONG,1); + }else{ + LPHP_NewVar("/cfg/php/thread_fork",(void*)strtoul(xn->value,0,0),SV_LONG,1); + } + + _snprintf(path,sizeof(path)-1,"%s\\mbot\\extensions",g_root); + if(!help_direxists(path)){ + CreateDirectory(path,NULL); + } + + xn = cSettings.GetNode("mbot/debug"); + if(xn && xn->value && *xn->value == '1'){ + lDebugOut = 1; + } + + xn = cSettings.GetNode("mbot/error_log"); + if(xn && xn->value && *xn->value == '1'){ + lErrorLog = 1; + } + + xn = cSettings.GetNode("mbot/console/font"); + if(xn && xn->value){ + pszMonospacedFont = xn->value; + } + xn = cSettings.GetNode("mbot/console/topmost"); + if(xn && xn->value && *xn->value == '1'){ + lConTopMost = 1; + } + xn = cSettings.GetNode("mbot/console/tofile"); + if(xn && xn->value && *xn->value == '1'){ + lConToFile = 1; + } + xn = cSettings.GetNode("mbot/console/fsize"); + if(xn && xn->value){ + lConFontSize = strtoul(xn->value,NULL,0); + } + +#ifndef _NOHTTPD_ + xn = cSettings.GetNode("mbot/httpd/port",NULL); + if(xn && xn->value && (res = strtoul(xn->value,NULL,10))){ + DBWriteContactSettingWord(NULL,MBOT,"WWWPort",(WORD)(res&0xffff)); + } + + xn = cSettings.GetNode("mbot/httpd/ip_mask",NULL); + if(xn && xn->value && *xn->value){ + DBWriteContactSettingString(NULL,MBOT,"WWWIPMask",xn->value); + } + + xn = cSettings.GetNode("mbot/httpd/auth_req",NULL); + if(xn && xn->value && (res = strtoul(xn->value,NULL,10))){ + DBWriteContactSettingByte(NULL,MBOT,"WWWAuthR",1); + }else{ + DBWriteContactSettingByte(NULL,MBOT,"WWWAuthR",0); + } + + if(res) + { + xn = cSettings.GetNode("mbot/httpd/auth_usr",NULL); + if(xn && xn->value && *xn->value){ + DBWriteContactSettingString(NULL,MBOT,"WWWUser",xn->value); + } + xn = cSettings.GetNode("mbot/httpd/auth_pwd",NULL); + if(xn && xn->value && *xn->value){ + DBWriteContactSettingString(NULL,MBOT,"WWWPass",xn->value); + } + } + + xn = cSettings.GetNode("mbot/httpd/wwwroot",NULL); + if(xn && xn->value && *xn->value) + { + ss = xn->value; + ut_str_replace("$(mroot)", g_root, ss); + DBWriteContactSettingString(NULL,MBOT,"WWWRoot",ss.data()); + } +#endif + return 0; +} + +int mbot_our_own(const char* s){ + for(const char** x=config_table;*x;x++){ + if(s == *x){return 1;} + }return 0; +} + +const char* mbot_replace_with_our_own(const char* s) +{ + for(const char** x=config_table;*x;x++){ + if(strcmp(*x,s)==0){return *x;} + }return s; +} diff --git a/mBot/src/mbot/config.h b/mBot/src/mbot/config.h new file mode 100644 index 0000000..b7cdb12 --- /dev/null +++ b/mBot/src/mbot/config.h @@ -0,0 +1,47 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#include + +#define MBOT_CFG_STATUS "Status" +static const char* config_table[]={MBOT_CFG_STATUS,NULL}; +int mbot_our_own(const char* s); +const char* mbot_replace_with_our_own(const char* s); + +struct php_entry +{ + const char* name; + const char* def_val; + unsigned long str; +}; + +extern char pszCmdTag[8]; +extern char pszPhpTag[8]; +extern long lCmdTagLen; +extern long lPhpTagLen; +extern long lErrorLog; +extern cXmlDoc cSettings; + +int php_generate_ini(); + +#endif //_CONFIG_H_ \ No newline at end of file diff --git a/mBot/src/mbot/cron.cpp b/mBot/src/mbot/cron.cpp new file mode 100644 index 0000000..7ccf3d3 --- /dev/null +++ b/mBot/src/mbot/cron.cpp @@ -0,0 +1,590 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "functions.h" +#include "config.h" +#include "m_script.h" +#include "helpers.h" +#include "sync.h" +#include "cron.h" + +CSyncList g_cron; +HANDLE g_cron_event = NULL; +HANDLE g_cron_thread = NULL; +long g_cron_tid = 0; +volatile long g_cron_status = 0; +volatile long g_cron_signal = 0; +CRITICAL_SECTION g_cron_cts; + +const char* g_cron_days[]={"mon","tue","wed","thu","fri","sat","sun",NULL}; + +unsigned long cron_day2num(const char* s) +{ + unsigned long i=0; + for(const char** g = g_cron_days;*g;g++,i++) + { + if((*(long*)s & 0x00ffffff) == *(long*)(*g)){ + return i; + } + } + return (-1); +} + +unsigned long cron_strtoul(const char* s,const char** out) +{ + char c = *s; + unsigned long res; + + if(isalpha(c) && (res = cron_day2num(s))!=(unsigned long)(-1)) + { + *out = s + 3; + return res; + } + + if(c < '0' || c > '9')return (-1); + s++; + + if(*s < '0' || *s > '9'){ + *out = s; + return (c - '0'); + } + + res = (c - '0') * 10; + c = *s; + s++; + + *out = s; + if(*s >= '0' && *s <= '9'){ + return (-1); + } + return res + (c - '0'); +} + +const char* cron_sub_parse(const char* s,cron_field* out,unsigned long max) +{ + unsigned int tmp; + unsigned int last; + const char* stop; + char ss = 0; + + out->s64 = 0; + + if(*s == '*'){ + s++; + if(*s == ' ' || !(*s)) + { + out->s64 = 0x7fffffffFFFFFFFF; + return s; + } + else if(*s == '/') + { + s++; + tmp = cron_strtoul(s,&stop); + if((*stop!=' ' && *stop) || !tmp || tmp > max){ + return NULL; + } + + for(unsigned int i=0;is64 |= (((__int64)1) << i); + } + } + return stop; + } + else{ + return NULL; + } + }else{ + + do + { + tmp = cron_strtoul(s,&stop); + if(tmp > max){ + return NULL; + } + + if(ss == '-') + { + if(last >= tmp){ + return NULL; + } + + for(unsigned int i=last;i<=tmp;i++){ + out->s64 |= ((__int64)1 << i); + } + ss = 0; + s = stop + 1; + } + else if(*stop == '-') + { + last = tmp; + ss = *stop; + s = stop + 1; + } + else + { + out->s64 |= ((__int64)1 << tmp); + s = stop + 1; + } + }while(*stop == ',' || *stop == '-'); + + return stop; + } + return NULL; +} + +unsigned long cron_fbit64(int n,__int64 x) +{ + for(register int i=n;i<64;i++){ + if(x & ((__int64)1 << i)){ + return i; + } + } + for(register int i=0;imin = cs[0].s64; + out->hour = cs[1].dw.l32; + out->wday = cs[2].dw.l32; + return 1; +} + +int cron_calcnext(sCronEvent* ce) +{ + int i = 0; + struct tm lt; + struct tm *tlt; + time_t ct; + + ct = time(0); + ct += (CRON_MINUTE - (ct % CRON_MINUTE)); + + while(1){ + tlt = localtime(&ct); + if(!tlt)return 0; + lt = *tlt; + //wday + i = cron_fbit32(lt.tm_wday,ce->wday); + if(i < lt.tm_wday){ + //round to full day + ct -= (lt.tm_min * CRON_MINUTE) + (lt.tm_hour * CRON_HOUR); + ct += (CRON_DAY) * ((7 - lt.tm_wday) + i); + continue; + }else if(i > lt.tm_wday){ + ct -= (lt.tm_min * CRON_MINUTE) + (lt.tm_hour * CRON_HOUR); + ct += (CRON_DAY) * (i - lt.tm_wday); + continue; + } + //hour + i = cron_fbit32(lt.tm_hour,ce->hour); + if(i < lt.tm_hour){ + //round to full hour + ct -= (lt.tm_min * CRON_MINUTE); + ct += (CRON_HOUR) * ((24 - lt.tm_hour) + i); + continue; + }else if(i > lt.tm_hour){ + ct -= (lt.tm_min * CRON_MINUTE); + ct += (CRON_HOUR) * (i - lt.tm_hour); + continue; + } + //minute + i = cron_fbit64(lt.tm_min,ce->min); + if(i < lt.tm_min){ + ct += (CRON_MINUTE) * ((60 - lt.tm_min) + i); + continue; + }else if(i > lt.tm_min){ + ct += (CRON_MINUTE) * (i - lt.tm_min); + continue; + } + break; + } + return ct; +} + +int cron_register(sCronSync* ce) +{ + sCronSync* e; + g_cron.Lock(); + e = (sCronSync*)g_cron.m_head; + while(e) + { + if(strcmp(e->name,ce->name)==0){ + g_cron.Unlock(); + return 0; + } + e = (sCronSync*)e->next; + } + ce->lSpent = ce->lSpent = 0; + g_cron.AddLocked((sSync*)ce); + g_cron.Unlock(); + return 1; +} + +int cron_unregister(const char* name) +{ + g_cron.Lock(); + sCronSync* e = (sCronSync*)g_cron.m_head; + + while(e) + { + if(strcmp(e->name,name)==0){ + e->lFlags |= MBOT_FLAG_DELETE | MBOT_FLAG_INACTIVE; + cron_signal_change(); + g_cron.Unlock(); + return 1; + } + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + return 0; +} + +int cron_enable_param(void* data,bool enable) +{ + g_cron.Lock(); + sCronSync* e = (sCronSync*)g_cron.m_head; + + while(e) + { + if((void*)e->data == data){ + if(enable == false){ + e->lFlags |= MBOT_FLAG_DELETE | MBOT_FLAG_INACTIVE; + }else{ + e->lFlags &= ~(MBOT_FLAG_INACTIVE | MBOT_FLAG_DELETE); + } + cron_signal_change(); + } + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + return 0; +} + +int cron_unregister_param(void* data) +{ + g_cron.Lock(); + sCronSync* e = (sCronSync*)g_cron.m_head; + + while(e) + { + if((void*)e->data == data){ + e->lFlags |= MBOT_FLAG_DELETE | MBOT_FLAG_INACTIVE; + cron_signal_change(); + } + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + return 0; +} + +int cron_enable(const char* name,long enable) +{ + g_cron.Lock(); + sCronSync* e = (sCronSync*)g_cron.m_head; + + while(e) + { + if(strcmp(e->name,name)==0){ + if(enable){ + e->lFlags &= ~(MBOT_FLAG_INACTIVE | MBOT_FLAG_DELETE); + }else{ + e->lFlags |= MBOT_FLAG_INACTIVE; + } + cron_signal_change(); + g_cron.Unlock(); + return 1; + } + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + return 0; +} + +int cron_modify(const char* name,const sCronEvent& ce) +{ + g_cron.Lock(); + sCronSync* e = (sCronSync*)g_cron.m_head; + + while(e) + { + if(strcmp(e->name,name)==0) + { + e->ce = ce; + cron_signal_change(); + g_cron.Unlock(); + return 1; + } + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + return 0; +} + +int WINAPI cron_execute(sCronSync* event) +{ + time_t st; + time_t en; + int result; + mb_event mbe = {MBT_TIMER,0,0}; + mbe.php = event->data; + + st = clock(); + sman_inc(mbe.php); + if(mbe.php->szBuffered) + { + result = LPHP_ExecuteScript(mbe.php->szBuffered,event->fcn,NULL,&mbe,NULL); + } + else + { + result = LPHP_ExecuteFile(mbe.php->szFilePath,event->fcn,NULL,&mbe,NULL); + } + sman_dec(mbe.php); + en = clock(); + + event->lLastSpent = en - st; + event->lSpent += event->lLastSpent; + event->lFlags &= ~(MBOT_FLAG_WORKING); + + result = cron_calcnext(&event->ce); + if(!result){ + event->lTime = 0x7fFFffFF; + }else{ + event->lTime = result; + } + return 0; +} + +int WINAPI cron_thread(void* dummy) +{ + static sCronSync* e; + static sCronSync* te; + static HANDLE hThread; + static long tid; + static long ct; + static time_t st; + + WaitForSingleObject(g_cron_event,INFINITE); + + if(g_cron_status != CRON_WORKING){ + return 0; + } + + e = (sCronSync*)g_cron.m_head; + while(e) + { + if(!(tid = cron_calcnext(&e->ce))){ + e->lTime = 0x7fFFffFF; + }else{ + e->lTime = tid; + } + e = (sCronSync*)e->next; + } + + while(g_cron_status == CRON_WORKING) + { + ct = time(0); + //do stuff + g_cron.Lock(); + e = (sCronSync*)g_cron.m_head; + while(e) + { + if(e->lTime <= ct && !(e->lFlags & (MBOT_FLAG_INACTIVE|MBOT_FLAG_DELETE)) && !(e->lFlags & MBOT_FLAG_WORKING)) + {//execute + if(e->lFlags & MBOT_FLAG_ASYNC) + { + e->lFlags |= (MBOT_FLAG_WORKING); + if(!(hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)cron_execute,(LPVOID)e,NULL,(LPDWORD)&tid))) + { + e->lFlags &= ~(MBOT_FLAG_WORKING); + } + CloseHandle(hThread); + } + else + { + e->lFlags |= (MBOT_FLAG_WORKING); + g_cron.Unlock(); + cron_execute(e); + g_cron.Lock(); + } + } + e = (sCronSync*)e->next; + } + //now remove events which want to be removed... + if(g_cron_signal) + { + InterlockedExchange(&g_cron_signal,0); + e = (sCronSync*)g_cron.m_head; + while(e) + { + if((e->lFlags & MBOT_FLAG_DELETE)) + { + te = (sCronSync*)e->next; + g_cron.DelLocked(e); + cron_free(e); + e = te; + }else{ + e = (sCronSync*)e->next; + } + } + } + g_cron.Unlock(); + + + st = time(0); + ct = (60 - (st % 60)); + WaitForSingleObject(g_cron_event,ct * 1000); + } + + return 0; +} + +int cron_shutdown() +{ + if(g_cron_thread) + { + InterlockedExchange(&g_cron_status,CRON_SHUTDOWN); + SetEvent(g_cron_event); + WaitForSingleObject(g_cron_thread,10000); + + CloseHandle(g_cron_event); + CloseHandle(g_cron_thread); + + g_cron_event = NULL; + g_cron_thread = NULL; + return 1; + }else{ + return 0; + } +} + +int cron_startup() +{ + sCronSync* e; + + if(!g_cron_thread){ + return 0; + } + + g_cron.Lock(); + + e = (sCronSync*)g_cron.m_head; + while(e){ + cron_calcnext(&e->ce); + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + + InterlockedExchange(&g_cron_status,CRON_WORKING); + SetEvent(g_cron_event); + return 1; +} + +int cron_initialize() +{ + InitializeCriticalSectionAndSpinCount(&g_cron_cts,0x80000100); + + g_cron_event = CreateEvent(0,0,0,0); + + if(g_cron_event == INVALID_HANDLE_VALUE){ + DeleteCriticalSection(&g_cron_cts); + return 0; + } + + if(g_cron_thread = CreateThread(NULL,(512*1024),(LPTHREAD_START_ROUTINE)cron_thread, + (LPVOID)NULL,NULL,(LPDWORD)&g_cron_tid)) + { + return 1; + } + else + { + return 0; + } +} + +int cron_signal_change() +{ + InterlockedExchange(&g_cron_signal,1); + return 1; +} + +void cron_free(sCronSync* e) +{ + my_memfree((void*)e); +} + +int cron_release() +{ + sCronSync* e; + sCronSync* tmp; + g_cron.Lock(); + e = (sCronSync*)g_cron.m_head; + while(e) + { + tmp = (sCronSync*)e->next; + cron_free(e); + e = tmp; + } + g_cron.m_head = g_cron.m_tail = NULL; + g_cron.Unlock(); + return 1; +} \ No newline at end of file diff --git a/mBot/src/mbot/cron.h b/mBot/src/mbot/cron.h new file mode 100644 index 0000000..096f07d --- /dev/null +++ b/mBot/src/mbot/cron.h @@ -0,0 +1,87 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _CRON_H_ +#define _CRON_H_ + +#include "sync.h" +#include "mbot.h" +#include "smanager.h" +#pragma once + +#define CRON_SECOND 1 +#define CRON_MINUTE 60*CRON_SECOND +#define CRON_HOUR 60*CRON_MINUTE +#define CRON_DAY 24*CRON_HOUR + +#define CRON_WORKING 1 +#define CRON_SHUTDOWN 2 +#define CRON_IDLE 3 + +//define this one! +#define CRON_PARAM PPHP + +union cron_field{ + __int64 s64; + struct{ + unsigned long l32; + unsigned long h32; + }dw; +}; + +struct sCronEvent{ + __int64 min; + unsigned long hour; + unsigned long wday; +}; + +struct sCronSync : public sSync +{ + sCronEvent ce; + char fcn[24]; + char name[24]; + long lTime; + long lSpent; + long lLastSpent; + volatile long lFlags; + CRON_PARAM data; +public: + sCronSync(){ + memset(this,0,sizeof(sCronSync)); + } +}; + +int cron_parse(const char* q,sCronEvent* out); +int cron_calcnext(sCronEvent* ce); +int cron_register(sCronSync* ce); +int cron_unregister(const char* name); +int cron_unregister_param(void* data); +int cron_enable_param(void* data,bool enable); +int cron_enable(const char* name,long enable); +int cron_modify(const char* name,const sCronEvent& ce); +int WINAPI cron_thread(void* dummy); +int cron_initialize(); +int cron_shutdown(); +int cron_startup(); +int cron_release(); +int cron_signal_change(); +void cron_free(sCronSync* e); + +#endif //_CRON_H_ \ No newline at end of file diff --git a/mBot/src/mbot/dialogs.cpp b/mBot/src/mbot/dialogs.cpp new file mode 100644 index 0000000..9d4574b --- /dev/null +++ b/mBot/src/mbot/dialogs.cpp @@ -0,0 +1,295 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "helpers.h" +#include "functions.h" +#include "dialogs.h" + +extern CSyncList g_dlist; + + +LPCSTR DlgGetCtrlClass(long type) +{ + const static char* classes[]={ + WC_STATIC,//1 + WC_BUTTON,//2 + WC_EDIT,//3 + WC_COMBOBOX,//4 + WC_IPADDRESS,//5 + WC_LISTVIEW,//6 + PROGRESS_CLASS,//7 + WC_TREEVIEW,//8 + }; + + type &= 0x7FffFFff; + + if(type > (sizeof(classes) / sizeof(char*))){ + return "STATIC"; + }else{ + return classes[type-1]; + } +} + +VOID DlgFree(sDialog* dlg) +{ + if(dlg){ + while(dlg->lNum) + { + //DestroyWindow(dlg->table[dlg->lNum-1]->hWnd); + my_memfree(dlg->table[dlg->lNum-1]); + dlg->table[dlg->lNum-1] = NULL; + dlg->lNum--; + } + my_memfree(dlg); + //memset(dlg,0xAA,sizeof(sDialog)); + } +} + +BOOL CALLBACK DlgStdInProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: + { + SetWindowLong(hDlg,GWL_USERDATA,(LONG)lParam); + sStdInDlg* sin = (sStdInDlg*)lParam; + if(!sin){ + EndDialog(hDlg,IDCANCEL); + return (TRUE); + } + + SetWindowText(hDlg,(sin->title)?(sin->title):("Enter some data")); + SetDlgItemText(hDlg,IDC_GS_INFO,(sin->info)?(sin->info):("Please enter some data:")); + + if(sin->flags & sStdInDlg::NUMBER_ONLY){ + SetWindowLong(GetDlgItem(hDlg,IDC_GS_EDIT),GWL_STYLE,ES_NUMBER); + } + + if(sin->flags & sStdInDlg::NO_CANCEL){ + ShowWindow(GetDlgItem(hDlg,IDCANCEL),SW_HIDE); + } + + if(sin->def){ + SetDlgItemText(hDlg,IDC_GS_EDIT,sin->def); + } + return (TRUE); + } + case WM_COMMAND: + { + UINT uid = LOWORD(wParam); + UINT ncode = HIWORD(wParam); + sStdInDlg* sin = (sStdInDlg*)GetWindowLong(hDlg,GWL_USERDATA); + if(uid == IDOK) + { + //do checking + ncode = GetDlgItemText(hDlg,IDC_GS_EDIT,sin->buffer,sizeof(sin->buffer)-1); + if(!ncode && (sin->flags & sStdInDlg::MUST_FILL)){ + MessageBox(hDlg,"You must type in some data!",sin->title,MB_ICONWARNING); + break; + } + EndDialog(hDlg,IDOK); + }else if(uid == IDCANCEL){ + if(sin->flags & sStdInDlg::MUST_FILL){ + MessageBox(hDlg,"You must type in some data!",sin->title,MB_ICONWARNING); + break; + }else{ + EndDialog(hDlg,IDCANCEL); + } + } + } + break; + default: + return (FALSE); + } + return (TRUE); +} + +BOOL CALLBACK DlgProcedure(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + sDialog* dlg = (sDialog*)GetWindowLong(hDlg,GWL_USERDATA); + PHPR res; + + if((uMsg != WM_INITDIALOG && uMsg != (WM_USER + 2)) && (!dlg || (dlg->hDlg != hDlg) || (dlg->lDepth > 0) || !(dlg->lFlags))){ + return (FALSE); + } + + if(dlg){dlg->lDepth++;} + + switch(uMsg) + { + case WM_INITDIALOG: + SetWindowLong(hDlg,GWL_USERDATA,lParam); + dlg = (sDialog*)lParam; + sman_inc(dlg->php); + return (TRUE); + case (WM_USER + 2): + { + RECT rc; + RECT drc; + HWND hButton; + //move the OK & CANCEL buttons + GetClientRect(hDlg,&drc); + + hButton = GetDlgItem(hDlg,IDCANCEL); + GetClientRect(hButton,&rc); + SetWindowPos(hButton,NULL,drc.right - 10 - 2*(rc.right - rc.left),drc.bottom - 5 - (rc.bottom - rc.top), + 0,0,SWP_NOZORDER | SWP_NOSIZE); + + hButton = GetDlgItem(hDlg,IDOK); + GetClientRect(hButton,&rc); + SetWindowPos(hButton,NULL,drc.right - 5 - (rc.right - rc.left), + drc.bottom - 5 - (rc.bottom - rc.top),0,0,SWP_NOZORDER | SWP_NOSIZE); + } + break; + case (WM_USER + 3): + DestroyWindow(hDlg); + sman_dec(dlg->php); + DlgFree(dlg); + SetWindowLong(hDlg,GWL_USERDATA,0); + return (TRUE); + case WM_CLOSE: + wParam = IDCANCEL; + lParam = (LPARAM)GetDlgItem(dlg->hDlg,IDCANCEL); + case WM_COMMAND: + { + UINT uid = LOWORD(wParam); + UINT ncode = HIWORD(wParam); + if((uid == IDOK || uid == IDCANCEL) && ncode == BN_CLICKED) + { + mb_event mbe={MBT_DIALOG,wParam,lParam,0}; + mbe.php = dlg->php; + mbe.t3 = MBE_DIALOGCB; + mbe.p3 = (void*)dlg; + + res = (PHPR)MBMultiParam(mbe.php,dlg->pszCallback,&mbe,"lll",(uid==IDOK),dlg->param,0); + if(res == PHPR_BREAK || res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + break; + } + else if(uid >= 1000 && uid < (dlg->lNum + 1000)) + { + sDlgControl* dc = dlg->table[uid - 1000]; + ULONG tmp = GetTickCount(); + if(((uid == dlg->lid) && (tmp - dlg->ltc < 250)) || dc->pszCallback[0]=='\0'){ + break; + } + + mb_event mbe={MBT_DIALOG,wParam,lParam,0}; + mbe.php = dlg->php; + mbe.t3 = MBE_DIALOGCB; + mbe.p3 = (void*)dlg; + mbe.lFlags = MBOT_FLAG_NOOUTPUT; + + if(dc->type == 2 && ncode==BN_CLICKED){//button + res = (PHPR)MBMultiParam(dlg->php,dc->pszCallback,&mbe,"ll",uid,dc->param); + if(res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + } + else if(dc->type == 4 && ncode == CBN_SELENDOK) + { + res = (PHPR)MBMultiParam(dlg->php,dc->pszCallback,&mbe,"ll",uid,dc->param); + if(res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + } + else if(*dlg->pszWmCommand) + { + res = (PHPR)MBMultiParam(dlg->php,dlg->pszWmCommand,&mbe,"llll",uid,dc->param,wParam,lParam); + if(res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + } + dlg->lid = uid; + dlg->ltc = GetTickCount(); + } + break; + } + break; + case WM_NOTIFY: + if(wParam >= 1000 && (wParam < (dlg->lNum + 1000)) && + (((LPNMHDR)lParam)->code == NM_RCLICK || ((LPNMHDR)lParam)->code == NM_CLICK)) + { + LVITEM lvi = {0}; + sDlgControl* dc = dlg->table[wParam - 1000]; + + if(!dc || dc->type != 6 || !(*dc->pszCallback))break; + + mb_event mbe={MBT_DIALOG,wParam,lParam,0}; + mbe.php = dlg->php; + mbe.t3 = MBE_DIALOGCB; + mbe.p3 = (void*)dlg; + mbe.lFlags = MBOT_FLAG_NOOUTPUT; + + res = (PHPR)MBMultiParam(dlg->php,dc->pszCallback,&mbe,"llll",wParam,dc->param, + ((LPNMLISTVIEW)lParam)->iItem, + ((LPNMHDR)lParam)->code == NM_RCLICK); + + if(res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + } + else if(*dlg->pszWmNotify && ((LPNMHDR)lParam)->idFrom >= 1000) + { + mb_event mbe={MBT_DIALOG,wParam,lParam,0}; + mbe.php = dlg->php; + mbe.t3 = MBE_DIALOGCB; + mbe.p3 = (void*)dlg; + mbe.lFlags = MBOT_FLAG_NOOUTPUT; + + res = (PHPR)MBMultiParam(dlg->php,dlg->pszWmNotify,&mbe,"llll",((LPNMHDR)lParam)->idFrom, + dlg->param,wParam,lParam); + + if(res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + } + break; + case WM_TIMER: + { + if(*dlg->pszWmTimer){ + mb_event mbe={MBT_DIALOG,wParam,lParam,0}; + mbe.php = dlg->php; + mbe.t3 = MBE_DIALOGCB; + mbe.p3 = (void*)dlg; + mbe.lFlags = MBOT_FLAG_NOOUTPUT; + + res = (PHPR)MBMultiParam(dlg->php,dlg->pszWmTimer,&mbe,"llll",wParam, + dlg->param,wParam,lParam); + + if(res == PHPR_END){ + PostMessage(hDlg,WM_USER + 3,0,0); + } + } + }break; + case WM_DESTROY: + sman_dec(dlg->php); + DlgFree(dlg); + SetWindowLong(hDlg,GWL_USERDATA,0); + return (TRUE); + default: + dlg->lDepth--; + return (FALSE); + }; + dlg->lDepth--; + return (TRUE); +} \ No newline at end of file diff --git a/mBot/src/mbot/dialogs.h b/mBot/src/mbot/dialogs.h new file mode 100644 index 0000000..0bfa4bc --- /dev/null +++ b/mBot/src/mbot/dialogs.h @@ -0,0 +1,77 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _DIALOGS_H__ +#define _DIALOGS_H__ + +#include "mbot.h" +#include "helpers.h" +#include "sync.h" +#include "smanager.h" +#pragma once + +#define DLG_NUM_CONTROLS 32 + + +struct sDlgControl +{ + char pszCallback[24]; + char type;/*0-button*/; + char dummy; + HWND hWnd; + long param; + unsigned long cs1; + unsigned long cs2; +}; + +struct sDialog +{ + char pszCallback[24]; + char pszWmCommand[24]; + char pszWmNotify[24]; + char pszWmTimer[24]; + HWND hDlg; + unsigned long lFlags; + unsigned long lDepth; + unsigned long lNum; + long param; + unsigned long ltc; + unsigned long lid; + PPHP php; + sDlgControl* table[DLG_NUM_CONTROLS]; + //callbacks +}; + +struct sStdInDlg{ + enum FLAGS{NONE=0,NO_CANCEL=0x02,MUST_FILL=0x04,NUMBER_ONLY=0x80}; + char* title; + char* info; + char* def; + char buffer[2048]; + long x,y; + long flags; +}; + +BOOL CALLBACK DlgProcedure(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam); +BOOL CALLBACK DlgStdInProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam); +VOID DlgFree(sDialog* dlg); +LPCSTR DlgGetCtrlClass(long type); + +#endif //_DIALOGS_H__ \ No newline at end of file diff --git a/mBot/src/mbot/functions.cpp b/mBot/src/mbot/functions.cpp new file mode 100644 index 0000000..fbfa0ea --- /dev/null +++ b/mBot/src/mbot/functions.cpp @@ -0,0 +1,327 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "functions.h" +#include "config.h" + +const char* PHP_ERROR_MSG = "The number of parameters, or their values are incorrect! It's also possible that you called a function which isn't allowed in current stage!"; +const char* PHP_ERROR_EXECUTION = "An error occured while executing your PHP statement/script!\nThere might be some error info in /mbot/(profile)_dbg.txt"; +const char* PHP_ERROR_TITLE = "ERROR"; +const char* PHP_WARN_INVALID_PARAMS = "Invalid parameters given!"; + +/****************************************** + * Load/Unload * + ******************************************/ +PHP_MINIT_FUNCTION(mb_module_entry); + +/* function table */ +zend_function_entry mb_functions[] = +{ + PHP_FE(mb_SelfRegister,NULL) + PHP_FE(mb_SelfEnable,NULL) + PHP_FE(mb_SelfSetInfo,NULL) + //scheduler + PHP_FE(mb_SchReg,NULL) + PHP_FE(mb_SchModify,NULL) + PHP_FE(mb_SchUnreg,NULL) + PHP_FE(mb_SchEnable,NULL) + PHP_FE(mb_SchList,NULL) + //misc + PHP_FE(mb_MsgBox,NULL) + PHP_FE(mb_Echo,NULL) + //msgs + PHP_FE(mb_MsgSend,NULL) + PHP_FE(mb_MsgSetBody,NULL) + //menu + PHP_FE(mb_MenuAdd,NULL) + PHP_FE(mb_MenuModify,NULL) + //clist + PHP_FE(mb_CListEventAdd,NULL) + //system + PHP_FE(mb_SysEnumModules,NULL) + PHP_FE(mb_SysEnumProtocols,NULL) + PHP_FE(mb_SysEnumHandlers,NULL) + PHP_FE(mb_SysGetMirandaDir,NULL) + PHP_FE(mb_SysGetProfileName,NULL) + PHP_FE(mb_SysTranslate,NULL) + PHP_FE(mb_SysQuit,NULL) + PHP_FE(mb_SysCallService,NULL) + PHP_FE(mb_SysCallProtoService,NULL) + PHP_FE(mb_SysCallContactService,NULL) + PHP_FE(mb_SysGetString,NULL) + PHP_FE(mb_SysGetNumber,NULL) + PHP_FE(mb_SysGetPointer,NULL) + PHP_FE(mb_SysPutString,NULL) + PHP_FE(mb_SysPutNumber,NULL) + PHP_FE(mb_SysMalloc,NULL) + PHP_FE(mb_SysFree,NULL) + PHP_FE(mb_SysGlobalAlloc,NULL) + PHP_FE(mb_SysGlobalFree,NULL) + PHP_FE(mb_SysMemCpy,NULL) + PHP_FE(mb_SysBeginThread,NULL) + PHP_FE(mb_SysLoadModule,NULL) + PHP_FE(mb_SysUnLoadModule,NULL) + PHP_FE(mb_SysManageScript,NULL) + PHP_FE(mb_SysShallDie,NULL) + PHP_FE(mb_SysCreateService,NULL) + PHP_FE(mb_SysHookEvent,NULL) + PHP_FE(mb_SysGetProcAddr,NULL) + PHP_FE(mb_SysCallProc,NULL) + //console + PHP_FE(mb_ConsoleShow,NULL) + PHP_FE(mb_ConsoleClear,NULL) + //protocols + PHP_FE(mb_PGetMyStatus,NULL) + PHP_FE(mb_PSetMyStatus,NULL) + PHP_FE(mb_PSetMyAwayMsg,NULL) + PHP_FE(mb_PGetCaps,NULL) + //contact/settings + PHP_FE(mb_CSettingGet,NULL) + PHP_FE(mb_CSettingSet,NULL) + PHP_FE(mb_CGetAwayMsg,NULL) + PHP_FE(mb_CSettingAdd,NULL) + PHP_FE(mb_CSettingDel,NULL) + PHP_FE(mb_CSettingEnum,NULL) + PHP_FE(mb_CGetStatus,NULL) + PHP_FE(mb_CGetUIN,NULL) + PHP_FE(mb_CGetProto,NULL) + PHP_FE(mb_CDelete,NULL) + PHP_FE(mb_CGetDisplayName,NULL) + PHP_FE(mb_CIsOnList,NULL) + PHP_FE(mb_CFindFirst,NULL) + PHP_FE(mb_CFindNext,NULL) + PHP_FE(mb_CFindByUIN,NULL) + PHP_FE(mb_CSetApparentMode,NULL) + PHP_FE(mb_CAddNew,NULL) + PHP_FE(mb_CGetInfo,NULL) + PHP_FE(mb_CAddAuth,NULL) + PHP_FE(mb_CAddSearch,NULL) + PHP_FE(mb_CSendTypingInfo,NULL) + //auth + PHP_FE(mb_AuthGetInfo,NULL) + PHP_FE(mb_AuthDeny,NULL) + PHP_FE(mb_AuthAccept,NULL) + PHP_FE(mb_AuthStore,NULL) + //events + PHP_FE(mb_EventGetCount,NULL) + PHP_FE(mb_EventFindFirst,NULL) + PHP_FE(mb_EventFindFirstUnread,NULL) + PHP_FE(mb_EventFindNext,NULL) + PHP_FE(mb_EventFindPrev,NULL) + PHP_FE(mb_EventFindLast,NULL) + PHP_FE(mb_EventGetData,NULL) + PHP_FE(mb_EventDel,NULL) + PHP_FE(mb_EventMarkRead,NULL) + PHP_FE(mb_EventAdd,NULL) + //sounds + PHP_FE(mb_SoundPlay,NULL) + PHP_FE(mb_SoundAdd,NULL) + PHP_FE(mb_SoundAddEx,NULL) + PHP_FE(mb_SoundDel,NULL) + PHP_FE(mb_SoundSet,NULL) + //popups + PHP_FE(mb_PUMsg,NULL) + PHP_FE(mb_PUAdd,NULL) + PHP_FE(mb_PUAddEx,NULL) + PHP_FE(mb_PUSystem,NULL) + //icons + PHP_FE(mb_IconLoadSys,NULL) + PHP_FE(mb_IconLoadSkin,NULL) + PHP_FE(mb_IconLoadProto,NULL) + PHP_FE(mb_IconLoadSkinnedProto,NULL) + PHP_FE(mb_IconDestroy,NULL) + //search + PHP_FE(mb_SearchBasic,NULL) + PHP_FE(mb_SearchByEmail,NULL) + PHP_FE(mb_SearchByName,NULL) + //dialogs + PHP_FE(mb_DlgGetFile,NULL) + PHP_FE(mb_DlgGetFileMultiple,NULL) + //irc + PHP_FE(mb_IrcGetGuiDataIn,NULL) + PHP_FE(mb_IrcSetGuiDataIn,NULL) + PHP_FE(mb_IrcSetGuiDataOut,NULL) + PHP_FE(mb_IrcInsertRawIn,NULL) + PHP_FE(mb_IrcInsertRawOut,NULL) + PHP_FE(mb_IrcInsertGuiIn,NULL) + PHP_FE(mb_IrcInsertGuiOut,NULL) + PHP_FE(mb_IrcGetData,NULL) + PHP_FE(mb_IrcPostMessage,NULL) + + PHP_FE(mb_DlgCreate,NULL) + PHP_FE(mb_DlgRun,NULL) + PHP_FE(mb_DlgGet,NULL) + PHP_FE(mb_DlgAddControl,NULL) + PHP_FE(mb_DlgGetText,NULL) + PHP_FE(mb_DlgSetText,NULL) + PHP_FE(mb_DlgGetInt,NULL) + PHP_FE(mb_DlgGetIdByParam,NULL) + PHP_FE(mb_DlgSendMsg,NULL) + PHP_FE(mb_DlgSetCallbacks,NULL) + PHP_FE(mb_DlgSetTimer,NULL) + PHP_FE(mb_DlgKillTimer,NULL) + + PHP_FE(mb_DlgListAddItem,NULL) + PHP_FE(mb_DlgListDelItem,NULL) + PHP_FE(mb_DlgListSetItem,NULL) + PHP_FE(mb_DlgListGetItem,NULL) + PHP_FE(mb_DlgListGetSel,NULL) + PHP_FE(mb_DlgListAddCol,NULL) + + PHP_FE(mb_DlgComboAddItem,NULL) + PHP_FE(mb_DlgComboDelItem,NULL) + PHP_FE(mb_DlgComboGetItem,NULL) + PHP_FE(mb_DlgComboGetItemData,NULL) + PHP_FE(mb_DlgComboGetSel,NULL) + + PHP_FE(mb_DlgGetHWND,NULL) + PHP_FE(mb_DlgMove,NULL) + PHP_FE(mb_DlgGetString,NULL) + + //files + PHP_FE(mb_FileInitSend,NULL) + PHP_FE(mb_FileAccept,NULL) + PHP_FE(mb_FileDeny,NULL) + PHP_FE(mb_FileStore,NULL) + PHP_FE(mb_FileCancel,NULL) + PHP_FE(mb_FileGetInfo,NULL) + //asus + PHP_FE(mb_AsusExt,NULL) + + ZEND_FALIAS(mbox,mb_MsgBox,NULL) + {NULL, NULL, NULL} +}; +/* compiled module information */ +zend_module_entry mb_module_entry = +{ + STANDARD_MODULE_HEADER, + "Miranda Scripting Plugin", + mb_functions, + PHP_MINIT(mb_module_entry), + NULL,NULL,NULL,NULL, + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES +}; + +void* mv_module_entry = (void*)&mb_module_entry; + +/* init_function */ +PHP_MINIT_FUNCTION(mb_module_entry) +{ + extern DWORD g_mbot_version; + extern int g_res_dlg_id; + extern char* g_res_dlg_name; + + g_res_dlg_id = zend_register_list_destructors_ex(help_dlg_destruction_handler,NULL,(char*)g_res_dlg_name,module_number); + + try + { + //events + REGISTER_LONG_CONSTANT("MB_EVENT_MSG_IN",MB_EVENT_MSG_IN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_MSG_OUT",MB_EVENT_MSG_OUT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_URL_IN",MB_EVENT_URL_IN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_AUTH_IN",MB_EVENT_AUTH_IN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_AWAY_MSG_OUT",MB_EVENT_AWAY_MSG_OUT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_AWAY_MSG_REQ",MB_EVENT_AWAY_MSG_REQ,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_NEW_CSTATUS",MB_EVENT_NEW_CSTATUS,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_NEW_MYSTATUS",MB_EVENT_NEW_MYSTATUS,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_COMMAND",MB_EVENT_COMMAND,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_STARTUP",MB_EVENT_STARTUP,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_SHUTDOWN",MB_EVENT_SHUTDOWN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_USER_TYPING",MB_EVENT_USER_TYPING,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_AWAY_MSG_ICQ",MB_EVENT_AWAY_MSG_ICQ,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_MENU_COMMAND",MB_EVENT_MENU_COMMAND,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_DUMMY",MB_EVENT_MENU_COMMAND,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_EXTERNAL",MB_EVENT_EXTERNAL,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_FILE_IN",MB_EVENT_FILE_IN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IRC_EVENT_GUI_IN",IRC_EVENT_GUI_IN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IRC_EVENT_GUI_OUT",IRC_EVENT_GUI_OUT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IRC_EVENT_RAW_IN",IRC_EVENT_RAW_IN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IRC_EVENT_RAW_OUT",IRC_EVENT_RAW_OUT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MB_EVENT_CONFIG",MB_EVENT_CONFIG,CONST_CS|CONST_PERSISTENT); + //mbot version + REGISTER_LONG_CONSTANT("MBOT_VERSION",g_mbot_version,CONST_CS|CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("MBOT_TIMESTAMP",__TIMESTAMP__,CONST_CS|CONST_PERSISTENT); + //event types + REGISTER_LONG_CONSTANT("EVENTTYPE_MESSAGE",EVENTTYPE_MESSAGE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EVENTTYPE_URL",EVENTTYPE_URL,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EVENTTYPE_CONTACTS",EVENTTYPE_CONTACTS,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EVENTTYPE_ADDED",EVENTTYPE_ADDED,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EVENTTYPE_AUTHREQUEST",EVENTTYPE_AUTHREQUEST,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EVENTTYPE_FILE",EVENTTYPE_FILE,CONST_CS|CONST_PERSISTENT); + //database types + REGISTER_LONG_CONSTANT("DBVT_BYTE",DBVT_BYTE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVT_WORD",DBVT_WORD,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVT_DWORD",DBVT_DWORD,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVT_ASCIIZ",DBVT_ASCIIZ,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVT_BLOB",DBVT_BLOB,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVT_UTF8",DBVT_UTF8,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVT_WCHAR",DBVT_WCHAR,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DBVTF_VARIABLELENGTH",DBVTF_VARIABLELENGTH,CONST_CS|CONST_PERSISTENT); + //status ids + REGISTER_LONG_CONSTANT("ID_STATUS_OFFLINE",40071,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_ONLINE",40072,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_AWAY",40073,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_DND",40074,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_NA",40075,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_OCCUPIED",40076,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_FREECHAT",40077,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_INVISIBLE",40078,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_ONTHEPHONE",40079,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_OUTTOLUNCH",40080,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ID_STATUS_IDLE",40081,CONST_CS|CONST_PERSISTENT); + //icons + REGISTER_LONG_CONSTANT("IDI_APPLICATION",1,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_ASTERISK",2,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_ERROR",3,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_EXCLAMATION",4,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_HAND",5,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_INFORMATION",6,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_QUESTION",7,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_WARNING",8,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IDI_WINLOGO",9,CONST_CS|CONST_PERSISTENT); + //skin icons + REGISTER_LONG_CONSTANT("SKINICON_EVENT_MESSAGE",SKINICON_EVENT_MESSAGE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_EVENT_URL",SKINICON_EVENT_URL,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_EVENT_FILE",SKINICON_EVENT_FILE,CONST_CS|CONST_PERSISTENT); + //other icons + REGISTER_LONG_CONSTANT("SKINICON_OTHER_MIRANDA",SKINICON_OTHER_MIRANDA,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_OTHER_EXIT",SKINICON_OTHER_EXIT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_OTHER_SHOWHIDE",SKINICON_OTHER_SHOWHIDE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_OTHER_GROUPOPEN",SKINICON_OTHER_GROUPOPEN,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_OTHER_GROUPSHUT",SKINICON_OTHER_GROUPSHUT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_OTHER_USERONLINE",SKINICON_OTHER_USERONLINE,CONST_CS|CONST_PERSISTENT); + //status mode icons + REGISTER_LONG_CONSTANT("SKINICON_STATUS_OFFLINE",SKINICON_STATUS_OFFLINE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_ONLINE",SKINICON_STATUS_ONLINE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_AWAY",SKINICON_STATUS_AWAY,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_NA",SKINICON_STATUS_NA,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_OCCUPIED",SKINICON_STATUS_OCCUPIED,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_DND",SKINICON_STATUS_DND,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_FREE4CHAT",SKINICON_STATUS_FREE4CHAT,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_INVISIBLE",SKINICON_STATUS_INVISIBLE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_ONTHEPHONE",SKINICON_STATUS_ONTHEPHONE,CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SKINICON_STATUS_OUTTOLUNCH",SKINICON_STATUS_OUTTOLUNCH,CONST_CS|CONST_PERSISTENT); + return SUCCESS; + }catch(...){ + return FAILURE; + } +} \ No newline at end of file diff --git a/mBot/src/mbot/functions.h b/mBot/src/mbot/functions.h new file mode 100644 index 0000000..5fc4170 --- /dev/null +++ b/mBot/src/mbot/functions.h @@ -0,0 +1,251 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _FUNCTIONS_H_ +#define _FUNCTIONS_H_ + +#include "mbot.h" +#pragma once + +extern void* mv_module_entry; + +#define MB_EVENT_MSG_IN 0x01 +#define MB_EVENT_MSG_OUT 0x02 +#define MB_EVENT_URL_IN 0x04 +#define MB_EVENT_AUTH_IN 0x08 +#define MB_EVENT_AWAY_MSG_OUT 0x10 +#define MB_EVENT_AWAY_MSG_REQ 0x20 +#define MB_EVENT_NEW_CSTATUS 0x40 +#define MB_EVENT_NEW_MYSTATUS 0x80 +#define MB_EVENT_COMMAND 0x0100 +#define MB_EVENT_STARTUP 0x0200 +#define MB_EVENT_SHUTDOWN 0x0400 +#define MB_EVENT_USER_TYPING 0x0800 +#define MB_EVENT_AWAY_MSG_ICQ 0x1000 +#define MB_EVENT_MENU_COMMAND 0x2000 +#define MB_EVENT_EXTERNAL 0x4000 +#define MB_EVENT_FILE_IN 0x8000 +#define IRC_EVENT_GUI_IN 0x010000 +#define IRC_EVENT_GUI_OUT 0x020000 +#define IRC_EVENT_RAW_IN 0x040000 +#define IRC_EVENT_RAW_OUT 0x080000 +#define MB_EVENT_CONFIG 0x100000 + +extern const char* PHP_ERROR_MSG; +extern const char* PHP_ERROR_EXECUTION; +extern const char* PHP_ERROR_TITLE; +extern const char* PHP_WARN_INVALID_PARAMS; + +#define PHP_FALSE_AND_ERROR php_error_docref(NULL TSRMLS_CC,E_ERROR,PHP_ERROR_MSG);return +#define PHP_FALSE_AND_ERRORS(s) php_error_docref(NULL TSRMLS_CC,E_ERROR,s);return +#define PHP_FALSE_AND_WARNS(s) php_error_docref(NULL TSRMLS_CC,E_WARNING,s);return +#define PHP_WARN php_error_docref(NULL TSRMLS_CC,E_WARNING, + +#define PHPWS php_error_docref(NULL TSRMLS_CC,E_WARNING, +#define PHPWE );return +#define PHPWSE(s) php_error_docref(NULL TSRMLS_CC,E_WARNING,s);return + +extern HICON hMBotIcon; +extern CSyncList g_mlist; +extern CSyncList g_elist; +extern long lm_flags; +extern MM_INTERFACE mmi; + +void MB_Popup(const char* title,const char* error,unsigned long flags = NIIF_ERROR,unsigned long timeout=15000); + +/* function definition */ +ZEND_FUNCTION(mb_SelfRegister); +ZEND_FUNCTION(mb_SelfEnable); +ZEND_FUNCTION(mb_SelfSetInfo); + +ZEND_FUNCTION(mb_SchReg); +ZEND_FUNCTION(mb_SchModify); +ZEND_FUNCTION(mb_SchUnreg); +ZEND_FUNCTION(mb_SchEnable); +ZEND_FUNCTION(mb_SchList); +//messages +ZEND_FUNCTION(mb_MsgSend); +ZEND_FUNCTION(mb_MsgSetBody); +//stdin/out +ZEND_FUNCTION(mb_MsgBox); +ZEND_FUNCTION(mb_Echo); +//menu +ZEND_FUNCTION(mb_MenuAdd); +ZEND_FUNCTION(mb_MenuModify); +//clist +ZEND_FUNCTION(mb_CListEventAdd); +//system +ZEND_FUNCTION(mb_SysTranslate); +ZEND_FUNCTION(mb_SysGetMirandaDir); +ZEND_FUNCTION(mb_SysGetProfileName); +ZEND_FUNCTION(mb_SysQuit); +ZEND_FUNCTION(mb_SysEnumModules); +ZEND_FUNCTION(mb_SysEnumHandlers); +ZEND_FUNCTION(mb_SysEnumProtocols); +ZEND_FUNCTION(mb_SysCallService); +ZEND_FUNCTION(mb_SysCallProtoService); +ZEND_FUNCTION(mb_SysCallContactService); +ZEND_FUNCTION(mb_SysManageScript); +ZEND_FUNCTION(mb_SysShallDie); + +ZEND_FUNCTION(mb_SysGetNumber); +ZEND_FUNCTION(mb_SysGetString); +ZEND_FUNCTION(mb_SysGetPointer); +ZEND_FUNCTION(mb_SysPutString); +ZEND_FUNCTION(mb_SysPutNumber); +ZEND_FUNCTION(mb_SysMemCpy); +ZEND_FUNCTION(mb_SysMalloc); +ZEND_FUNCTION(mb_SysFree); +ZEND_FUNCTION(mb_SysGlobalAlloc); +ZEND_FUNCTION(mb_SysGlobalFree); +ZEND_FUNCTION(mb_SysBeginThread); +ZEND_FUNCTION(mb_SysLoadModule); +ZEND_FUNCTION(mb_SysUnLoadModule); + +ZEND_FUNCTION(mb_SysCreateService); +ZEND_FUNCTION(mb_SysHookEvent); +ZEND_FUNCTION(mb_SysGetProcAddr); +ZEND_FUNCTION(mb_SysCallProc); +//console +ZEND_FUNCTION(mb_ConsoleShow); +ZEND_FUNCTION(mb_ConsoleClear); +//protocols +ZEND_FUNCTION(mb_PGetMyStatus); +ZEND_FUNCTION(mb_PSetMyStatus); +ZEND_FUNCTION(mb_PSetMyAwayMsg); +ZEND_FUNCTION(mb_PGetCaps); +//contacts/settings +ZEND_FUNCTION(mb_CSettingGet); +ZEND_FUNCTION(mb_CSettingSet); +ZEND_FUNCTION(mb_CSettingAdd); +ZEND_FUNCTION(mb_CSettingDel); +ZEND_FUNCTION(mb_CSettingEnum); +ZEND_FUNCTION(mb_CGetDisplayName); +ZEND_FUNCTION(mb_CGetUIN); +ZEND_FUNCTION(mb_CGetProto); +ZEND_FUNCTION(mb_CDelete); +ZEND_FUNCTION(mb_CGetAwayMsg); +ZEND_FUNCTION(mb_CGetStatus); +ZEND_FUNCTION(mb_CIsOnList); +ZEND_FUNCTION(mb_CFindFirst); +ZEND_FUNCTION(mb_CFindNext); +ZEND_FUNCTION(mb_CFindByUIN); +ZEND_FUNCTION(mb_CSetApparentMode); +ZEND_FUNCTION(mb_CAddNew); +ZEND_FUNCTION(mb_CAddAuth); +ZEND_FUNCTION(mb_CAddSearch); +ZEND_FUNCTION(mb_CGetInfo); +ZEND_FUNCTION(mb_CSendTypingInfo); +//auth in +ZEND_FUNCTION(mb_AuthGetInfo); +ZEND_FUNCTION(mb_AuthDeny); +ZEND_FUNCTION(mb_AuthAccept); +ZEND_FUNCTION(mb_AuthStore); +//history +ZEND_FUNCTION(mb_EventFindFirst); +ZEND_FUNCTION(mb_EventFindFirstUnread); +ZEND_FUNCTION(mb_EventFindNext); +ZEND_FUNCTION(mb_EventFindPrev); +ZEND_FUNCTION(mb_EventFindLast); +ZEND_FUNCTION(mb_EventGetCount); +ZEND_FUNCTION(mb_EventGetData); +ZEND_FUNCTION(mb_EventDel); +ZEND_FUNCTION(mb_EventAdd); +ZEND_FUNCTION(mb_EventMarkRead); +//skin/sounds +ZEND_FUNCTION(mb_SoundPlay); +ZEND_FUNCTION(mb_SoundAdd); +ZEND_FUNCTION(mb_SoundAddEx); +ZEND_FUNCTION(mb_SoundDel); +ZEND_FUNCTION(mb_SoundSet); +//popups +ZEND_FUNCTION(mb_PUMsg); +ZEND_FUNCTION(mb_PUAdd); +ZEND_FUNCTION(mb_PUAddEx); +ZEND_FUNCTION(mb_PUSystem); +//icons +ZEND_FUNCTION(mb_IconLoadSys); +ZEND_FUNCTION(mb_IconLoadSkin); +ZEND_FUNCTION(mb_IconLoadProto); +ZEND_FUNCTION(mb_IconLoadSkinnedProto); +ZEND_FUNCTION(mb_IconDestroy); +//search +ZEND_FUNCTION(mb_SearchBasic); +ZEND_FUNCTION(mb_SearchByEmail); +ZEND_FUNCTION(mb_SearchByName); + +//dialogs +void help_dlg_destruction_handler(zend_rsrc_list_entry *rsrc TSRMLS_DC); + +ZEND_FUNCTION(mb_DlgGetFile); +ZEND_FUNCTION(mb_DlgGetFileMultiple); +ZEND_FUNCTION(mb_DlgCreate); +ZEND_FUNCTION(mb_DlgRun); +ZEND_FUNCTION(mb_DlgAddControl); +ZEND_FUNCTION(mb_DlgGet); +ZEND_FUNCTION(mb_DlgGetText); +ZEND_FUNCTION(mb_DlgSetText); +ZEND_FUNCTION(mb_DlgGetInt); +ZEND_FUNCTION(mb_DlgGetIdByParam); +ZEND_FUNCTION(mb_DlgSendMsg); +ZEND_FUNCTION(mb_DlgSetCallbacks); +ZEND_FUNCTION(mb_DlgSetTimer); +ZEND_FUNCTION(mb_DlgKillTimer); +//list view +ZEND_FUNCTION(mb_DlgListAddItem); +ZEND_FUNCTION(mb_DlgListDelItem); +ZEND_FUNCTION(mb_DlgListSetItem); +ZEND_FUNCTION(mb_DlgListGetItem); +ZEND_FUNCTION(mb_DlgListGetSel); +ZEND_FUNCTION(mb_DlgListAddCol); +//combo box +ZEND_FUNCTION(mb_DlgComboAddItem); +ZEND_FUNCTION(mb_DlgComboDelItem); +ZEND_FUNCTION(mb_DlgComboGetItem); +ZEND_FUNCTION(mb_DlgComboGetItemData); +ZEND_FUNCTION(mb_DlgComboGetSel); + +//general +ZEND_FUNCTION(mb_DlgGetHWND); +ZEND_FUNCTION(mb_DlgMove); +ZEND_FUNCTION(mb_DlgGetString); + +//file transfers +ZEND_FUNCTION(mb_FileInitSend); +ZEND_FUNCTION(mb_FileAccept); +ZEND_FUNCTION(mb_FileCancel); +ZEND_FUNCTION(mb_FileDeny); +ZEND_FUNCTION(mb_FileStore); +ZEND_FUNCTION(mb_FileGetInfo); + +ZEND_FUNCTION(mb_IrcGetGuiDataIn);//ok +ZEND_FUNCTION(mb_IrcSetGuiDataIn);//ok +ZEND_FUNCTION(mb_IrcSetGuiDataOut); +ZEND_FUNCTION(mb_IrcInsertRawIn); +ZEND_FUNCTION(mb_IrcInsertRawOut); +ZEND_FUNCTION(mb_IrcInsertGuiIn); +ZEND_FUNCTION(mb_IrcInsertGuiOut); +ZEND_FUNCTION(mb_IrcGetData); +ZEND_FUNCTION(mb_IrcPostMessage); + +//asus +ZEND_FUNCTION(mb_AsusExt); + +#endif //_FUNCTIONS_H_ \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_auth.cpp b/mBot/src/mbot/functions/mb_auth.cpp new file mode 100644 index 0000000..5fdae44 --- /dev/null +++ b/mBot/src/mbot/functions/mb_auth.cpp @@ -0,0 +1,115 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +/////////////////////////////// +//authorize +/////////////////////////////// +ZEND_FUNCTION(mb_AuthGetInfo) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + char* inf = (char*)mbe->p3; + + if(mbe->t2 != MBE_EVENTID || (mbe->p2 != (void*)MB_EVENT_AUTH_IN) || mbe->t3!=MBE_CUSTOM){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(array_init(return_value)==FAILURE){ + RETURN_FALSE; + } + + //blob is: uin(DWORD),hcontact(HANDLE),nick(ASCIIZ),first(ASCIIZ),last(ASCIIZ),email(ASCIIZ),reason(ASCIIZ) + + //nick + inf += sizeof(DWORD) + sizeof(HANDLE); + add_index_string(return_value,0,inf,1); + //first + inf += strlen(inf) + 1; + add_index_string(return_value,1,inf,1); + //last + inf += strlen(inf) + 1; + add_index_string(return_value,2,inf,1); + //email + inf += strlen(inf) + 1; + add_index_string(return_value,3,inf,1); + return; +} + +ZEND_FUNCTION(mb_AuthDeny) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + char* reason=NULL; + long rl=0,hid=0,cid=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll",&reason,&rl,&cid,&hid) == FAILURE || + !reason || !hid || !cid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG((CallService(PS_AUTHDENY,(WPARAM)hid,(LPARAM)reason) == 0)); +} + +ZEND_FUNCTION(mb_AuthAccept) +{ + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + long hid=0,cid=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll",&cid,&hid) == FAILURE || !hid || !cid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG((CallContactService((HANDLE)cid,PS_AUTHALLOW,(WPARAM)hid,NULL) == 0)); +} + +ZEND_FUNCTION(mb_AuthStore) +{ + DBEVENTINFO dbei = {sizeof(dbei),0}; + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + CCSDATA* css = (CCSDATA*)mbe->lParam; + PROTORECVEVENT* prr; + long result = 0; + char* proto = NULL; + + if(mbe->event != MBT_AUTHRECV || !css || !css->lParam){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(mbe->lFlags & MBOT_FLAG_STORED){ + RETURN_FALSE; + } + + prr = (PROTORECVEVENT*)css->lParam; + proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)css->hContact,0); + + dbei.cbBlob = prr->lParam; + dbei.pBlob = (PBYTE)prr->szMessage; + dbei.eventType = (unsigned short)EVENTTYPE_AUTHREQUEST; + dbei.timestamp = time(0); + dbei.szModule = proto; + dbei.flags = DBEF_READ; + + result = CallService(MS_DB_EVENT_ADD,(WPARAM)css->hContact,(LPARAM)&dbei); + if(result){ + mbe->lFlags |= MBOT_FLAG_STORED; + } + + RETURN_LONG(result); +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_contact.cpp b/mBot/src/mbot/functions/mb_contact.cpp new file mode 100644 index 0000000..6156936 --- /dev/null +++ b/mBot/src/mbot/functions/mb_contact.cpp @@ -0,0 +1,518 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +ZEND_FUNCTION(mb_CIsOnList) +{ + long cid=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || cid==0){ + PHP_FALSE_AND_ERROR; + } + RETURN_LONG(DBGetContactSettingByte((HANDLE)cid,"CList","NotOnList",0)==FALSE); +} + +ZEND_FUNCTION(mb_CSendTypingInfo) +{ + long cid=0; + char on=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb",&cid,&on) == FAILURE || cid==0){ + PHP_FALSE_AND_ERROR; + } + + RETURN_LONG(CallContactService((HANDLE)cid,PSS_USERISTYPING,(WPARAM)cid,on)==0); +} + +ZEND_FUNCTION(mb_CGetStatus) +{ + long cid = 0; + char* proto = NULL; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || !cid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)cid,0); + if(!proto){ + RETURN_FALSE; + } + + cid = DBGetContactSettingWord((HANDLE)cid,proto,"Status",0); + RETURN_LONG(cid); +} + +ZEND_FUNCTION(mb_CGetProto) +{ + long cid = 0; + char* proto = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || !cid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)cid,0); + if(proto){ + RETURN_STRING(proto,1); + }else{ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_CDelete) +{ + long cid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || !cid) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallService(MS_DB_CONTACT_DELETE,(WPARAM)cid,0)==0); +} + +ZEND_FUNCTION(mb_CGetDisplayName) +{ + long cid=0; + char* tmp=NULL; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || !cid) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + tmp = (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)cid,0); + if(tmp){ + RETURN_STRING(tmp,1); + }else{ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_CGetAwayMsg) +{ + long cid=0; + zval *cb; + char *proto; + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + sACKSync* ack; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz",&cid,&cb)==FAILURE || cid==0 || cb->type != IS_STRING){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!(proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,cid,0))){ + RETURN_FALSE; + } + + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + memset(ack,0,sizeof(sACKSync)); + + if(!(ack->php = mbe->php))goto Error; + sman_incref(ack->php); + + ack->lType = ACKTYPE_AWAYMSG; + ack->hContact = (HANDLE)cid; + + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + strncpy(ack->pszProtocol,proto,15); + + if(!g_slist.Add(ack)){goto Error;} + + ack->hProcess = (HANDLE)CallContactService((HANDLE)cid,PSS_GETAWAYMSG,0,0); + if(!ack->hProcess){ + g_slist.Del(ack); + goto Error; + } + RETURN_LONG(1); +Error: + if(ack->php)sman_decref(ack->php); + if(ack)my_memfree(ack); + RETURN_FALSE; +} + +int xx_enumcsettings(const char *szSetting,LPARAM lParam) +{ + cutMemf* mf = (cutMemf*)lParam; + if(*szSetting){ + mf->write((void*)szSetting, strlen(szSetting)+1); + } + return 0; +} + +ZEND_FUNCTION(mb_CSettingEnum) +{ + DBCONTACTENUMSETTINGS ecs = {0}; + cutMemf mf; + long cid=0,ml=0; + char* mod=NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls",&cid,&mod,&ml) == FAILURE || !mod || !ml){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!mf.create(2048)){ + RETURN_FALSE; + } + + ecs.pfnEnumProc = xx_enumcsettings; + ecs.szModule = mod; + ecs.lParam = (LPARAM)&mf; + + if(CallService(MS_DB_CONTACT_ENUMSETTINGS,cid,(LPARAM)&ecs)!=0){ + RETURN_FALSE; + } + mf.putc(0); + if(array_init(return_value)==FAILURE){ + RETURN_FALSE; + } + + mod = (char*)mf.getdata(); + ml = 0; + while(*mod) + { + add_index_string(return_value,ml,mod,1); + mod = mod + strlen(mod) + 1; + ml++; + } + mf.close(); + return; +} + +ZEND_FUNCTION(mb_CSetApparentMode) +{ + long cid=0,mode=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll",&cid,&mode) == FAILURE || !cid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallContactService((HANDLE)cid,PSS_SETAPPARENTMODE,mode,0)==0); +} +ZEND_FUNCTION(mb_CAddNew) +{ + RETURN_LONG(CallService(MS_DB_CONTACT_ADD,0,0)); +} +ZEND_FUNCTION(mb_CAddAuth) +{ + long aid=0; + DBEVENTINFO dbei={0}; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&aid) == FAILURE || !aid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + dbei.cbSize = sizeof(dbei); + + if(CallService(MS_DB_EVENT_GET,(WPARAM)aid,(LPARAM)&dbei)!=0){ + RETURN_FALSE; + } + RETURN_LONG(CallProtoService(dbei.szModule,PS_ADDTOLISTBYEVENT,0,(LPARAM)aid)); +} +ZEND_FUNCTION(mb_CAddSearch) +{ + //MBT_SRESULT + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + if(mbe->event != MBT_CALLBACK || mbe->t3 != MBE_SRESULT) + { + //PHPWARN(); + RETURN_FALSE; + } + else + { + PROTOSEARCHRESULT* sr = (PROTOSEARCHRESULT*)mbe->p3; + ACKDATA* ack = (ACKDATA*)mbe->p2; + + RETURN_LONG(CallProtoService(ack->szModule,PS_ADDTOLIST,0,(LPARAM)sr)); + } +} +ZEND_FUNCTION(mb_CGetInfo) +{ + long cid=0,cf=0; + CONTACTINFO ci={0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll",&cid,&cf) == FAILURE || !cid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(cf < 1 || cf > 17){ + RETURN_FALSE; + } + + ci.cbSize = sizeof(ci); + ci.dwFlag = (BYTE)((0xFF)& cf); + ci.hContact = (HANDLE)cid; + ci.szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)cid,0); + + cid = CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&ci); + + if(cid == 0) + { + if(ci.type == CNFT_ASCIIZ){ + RETURN_STRING(ci.pszVal,1); + }else if(ci.type == CNFT_BYTE){ + RETURN_LONG(ci.bVal); + }else if(ci.type == CNFT_WORD){ + RETURN_LONG(ci.wVal); + }else{ + RETURN_LONG(ci.dVal); + } + + if(cf >= 16) + { + MM_INTERFACE mmi={0}; + mmi.cbSize = sizeof(mmi); + CallService(MS_SYSTEM_GET_MMI,0,(LPARAM)&mmi); + mmi.mmi_free((void*)ci.pszVal); + } + return; + }else{ + RETURN_FALSE; + } +} +ZEND_FUNCTION(mb_CGetUIN) +{ + long cid = 0; + char* proto = NULL; + char* uin = NULL; + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || cid==0){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)cid,0); + if(!proto){ + RETURN_FALSE; + } + uin = (char*)CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); + if(!uin){ + RETURN_FALSE; + } + + cgs.szModule=proto; + cgs.szSetting=uin; + cgs.pValue=&dbv; + if(CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)cid,(LPARAM)&cgs)){ + RETURN_FALSE; + } + + if(dbv.type==DBVT_BYTE){ + RETVAL_LONG(dbv.bVal); + }else if(dbv.type==DBVT_WORD){ + RETVAL_LONG(dbv.wVal); + }else if(dbv.type==DBVT_DWORD){ + RETVAL_LONG(dbv.dVal); + }else if(dbv.type==DBVT_ASCIIZ){ + RETVAL_STRING(dbv.pszVal,1); + }else if(dbv.type==DBVT_BLOB){ + RETVAL_STRINGL((char*)dbv.pbVal,dbv.cpbVal,1) + }else{ + RETVAL_FALSE; + } + DBFreeVariant(&dbv); + return; +} + +ZEND_FUNCTION(mb_CSettingGet) +{ + char* setting = NULL; + char* module = NULL; + long cid=0,sl=0,ml=0; + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss",&cid,&module,&ml,&setting,&sl) == FAILURE || !sl || !ml){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + cgs.szModule=module; + cgs.szSetting=setting; + cgs.pValue=&dbv; + + if(CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)cid,(LPARAM)&cgs)){ + RETURN_FALSE; + } + + if(dbv.type==DBVT_BYTE){ + RETVAL_LONG(dbv.bVal); + }else if(dbv.type==DBVT_WORD){ + RETVAL_LONG(dbv.wVal); + }else if(dbv.type==DBVT_DWORD){ + RETVAL_LONG(dbv.dVal); + }else if(dbv.type==DBVT_ASCIIZ){ + RETVAL_STRING(dbv.pszVal,1); + }else if(dbv.type==DBVT_BLOB){ + RETVAL_STRINGL((char*)dbv.pbVal,dbv.cpbVal,1) + }else{ + RETVAL_FALSE; + } + DBFreeVariant(&dbv); +} +ZEND_FUNCTION(mb_CSettingDel) +{ + char* setting = NULL; + char* module = NULL; + long cid=0,sl=0,ml=0; + DBVARIANT dbv={0}; + DBCONTACTGETSETTING cgs; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss",&cid,&module,&ml,&setting,&sl) == FAILURE || !sl || !ml){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else{ + //MBT_CSCHANGED + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + if(mbe->event == MBT_CSCHANGED && strcmp(setting,"Status")==0){ + RETURN_FALSE; + } + } + + cgs.szModule=module; + cgs.szSetting=setting; + cgs.pValue=&dbv; + + RETURN_LONG(DBDeleteContactSetting((HANDLE)cid,module,setting)==0); +} + + +ZEND_FUNCTION(mb_CSettingSet) +{ + char* setting = NULL; + char* module = NULL; + char* value = NULL; + char buf[32]={0}; + long cid=0,sl=0,ml=0,vl=0; + DBVARIANT dbv ={0}; + DBCONTACTGETSETTING cgs; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsss",&cid,&module,&ml,&setting,&sl,&value,&vl) == FAILURE || + !sl || !ml || !value){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else{ + //MBT_CSCHANGED + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + if(mbe->event == MBT_CSCHANGED && strcmp(setting,"Status")==0){ + RETURN_FALSE; + } + } + + + cgs.szModule = module; + cgs.szSetting = setting; + cgs.pValue = &dbv; + + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = (char*)buf; + dbv.cchVal = sizeof(buf); + + if(CallService(MS_DB_CONTACT_GETSETTINGSTATIC,(WPARAM)cid,(LPARAM)&cgs)){ + RETURN_FALSE; + } + + if(dbv.type==DBVT_BYTE){ + RETVAL_LONG(DBWriteContactSettingByte((HANDLE)cid,module,setting,(BYTE)(strtoul(value,NULL,0)&0xff))==FALSE); + }else if(dbv.type==DBVT_WORD){ + RETVAL_LONG(DBWriteContactSettingWord((HANDLE)cid,module,setting,(WORD)(strtoul(value,NULL,0)&0xffff))==FALSE); + }else if(dbv.type==DBVT_DWORD){ + RETVAL_LONG(DBWriteContactSettingDword((HANDLE)cid,module,setting,(DWORD)(strtoul(value,NULL,0)))==FALSE); + }else if(dbv.type==DBVT_ASCIIZ){ + RETVAL_LONG(DBWriteContactSettingString((HANDLE)cid,module,setting,value)==FALSE) + }else if(dbv.type==DBVT_BLOB){ + DBCONTACTWRITESETTING cws; + cws.szModule=module; + cws.szSetting = mbot_replace_with_our_own(setting); + cws.value.type=DBVT_BLOB; + cws.value.pbVal=(BYTE*)value; + cws.value.cpbVal = (WORD)(vl&0x00ffff); + RETVAL_LONG(CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)cid,(LPARAM)&cws)==FALSE); + }else{ + RETVAL_FALSE; + } +} + +ZEND_FUNCTION(mb_CSettingAdd) +{ + char* setting = NULL; + char* module = NULL; + char* value = NULL; + char buf[32]={0}; + long cid=0,sl=0,ml=0,vl=0,type=0; + DBVARIANT dbv ={0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lslss",&cid,&module,&ml,&type,&setting,&sl,&value,&vl) == FAILURE || + !sl || !ml || !value){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else{ + //MBT_CSCHANGED + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + if(mbe->event == MBT_CSCHANGED && strcmp(setting,"Status")==0){ + RETURN_FALSE; + } + } + + if(type==DBVT_BYTE){ + RETVAL_LONG(DBWriteContactSettingByte((HANDLE)cid,module,setting,(BYTE)(strtoul(value,NULL,0)&0xff))==FALSE); + }else if(type==DBVT_WORD){ + RETVAL_LONG(DBWriteContactSettingWord((HANDLE)cid,module,setting,(WORD)(strtoul(value,NULL,0)&0xffff))==FALSE); + }else if(type==DBVT_DWORD){ + RETVAL_LONG(DBWriteContactSettingDword((HANDLE)cid,module,setting,(DWORD)(strtoul(value,NULL,0)))==FALSE); + }else if(type==DBVT_ASCIIZ){ + RETVAL_LONG(DBWriteContactSettingString((HANDLE)cid,module,setting,value)==FALSE) + }else if(type==DBVT_BLOB){ + DBCONTACTWRITESETTING cws; + cws.szModule=module; + cws.szSetting = mbot_replace_with_our_own(setting); + cws.value.type=DBVT_BLOB; + cws.value.pbVal=(BYTE*)value; + cws.value.cpbVal = (WORD)(vl&0x00ffff); + RETVAL_LONG(CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)cid,(LPARAM)&cws)==FALSE); + }else{ + RETVAL_FALSE; + } +} + +ZEND_FUNCTION(mb_CFindFirst) +{ + long cid = CallService(MS_DB_CONTACT_FINDFIRST,0,0); + RETURN_LONG(cid); +} +ZEND_FUNCTION(mb_CFindNext) +{ + long cid = 0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE || cid==NULL){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + cid = CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)cid,0); + RETURN_LONG(cid); +} +ZEND_FUNCTION(mb_CFindByUIN) +{ + char* proto=NULL; + long pl=0; + zval* uin; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz",&proto,&pl,&uin) == FAILURE || !pl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(uin->type == IS_STRING){ + RETURN_LONG((long)help_find_by_uin(proto,uin->value.str.val,0)); + }else if(uin->type == IS_LONG){ + RETURN_LONG((long)help_find_by_uin(proto,(const char*)uin->value.lval,1)); + }else{ + RETURN_FALSE; + } +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_dlg.cpp b/mBot/src/mbot/functions/mb_dlg.cpp new file mode 100644 index 0000000..9ff635b --- /dev/null +++ b/mBot/src/mbot/functions/mb_dlg.cpp @@ -0,0 +1,899 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" +#include "../dialogs.h" + +int g_res_dlg_id = 0; +char* g_res_dlg_name = "mb_rsc_dlg"; + +void help_dlg_destruction_handler(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + sDialog* dlg = (sDialog*)rsrc->ptr; + if(dlg && (dlg->lFlags & 0x01)==0) + { + if(dlg->hDlg){ + DestroyWindow(dlg->hDlg); + dlg->hDlg = NULL; + } + DlgFree(dlg); + } +} + +ZEND_FUNCTION(mb_DlgGetFile) +{ + char open = 0; + char *ext = NULL; + char *std = NULL; + char *e; + long el = 0; + long sl = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb|s",&ext,&el,&open,&std,&sl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(el < 2 || ext[el-1]!='|'){ + RETURN_FALSE; + } + + e = ext; + while(*e){ + if(*e == '|'){ + *e = '\0'; + }e++; + }; + + e = help_getfilename(open,ext,std); + if(e && *e){ + RETURN_STRING(e,1); + }else{ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_DlgGetFileMultiple) +{ + char *ext = NULL; + char *fn; + char *e; + char out[2048]; + char path[MAX_PATH]; + long el = 0; + long n = 0; + long offset = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&ext,&el) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(el < 2 || ext[el-1]!='|'){ + RETURN_FALSE; + } + + e = ext; + while(*e){ + if(*e == '|'){ + *e = '\0'; + }e++; + }; + + *out = 0; + + fn = help_getfilenamemultiple(ext,out,sizeof(out)-1,&offset); + + if(!fn || array_init(return_value)==FAILURE) + { + RETURN_FALSE; + } + else + { + //add_index_string(return_value,i,proto[i]->szName,1); + if(offset>0){ + out[offset-1]='\0'; + } + + fn = out + offset; + while(*fn) + { + _snprintf(path,sizeof(path)-1,"%s\\%s",out,fn); + add_index_string(return_value,n++,path,1); + fn += strlen(fn) + 1; + } + return; + } +} + +ZEND_FUNCTION(mb_DlgCreate) +{ + char* title=NULL; + unsigned long tl=0; + unsigned long cx=CW_USEDEFAULT; + unsigned long cy=CW_USEDEFAULT; + long rs_id = 0; + long param = 0; + long flags = 0; + zval* cb; + sDialog* dlg = NULL; + + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szll|ll",&title,&tl,&cb,&cx,&cy,¶m,&flags) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(mbe->php == NULL){ + RETURN_FALSE; + }else if(!zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb is expected to be a valid callback function!"); + } + + if(!tl){title="MBot";} + if(cx < 100 || cx > 1024){ + cx = 256; + } + if(cy < 100 || cy > 1024){ + cy = 256; + } + + dlg = (sDialog*)my_malloc(sizeof(sDialog)); + if(!dlg){ + RETURN_NULL(); + } + memset(dlg,0,sizeof(sDialog)); + dlg->php = mbe->php; + dlg->param = param; + + if(!(dlg->hDlg = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DlgProcedure,(LPARAM)dlg))){ + goto Error; + } + + if(flags & 0x01){ + ShowWindow(GetDlgItem(dlg->hDlg,IDCANCEL),SW_HIDE); + } + + SetWindowPos(dlg->hDlg,NULL,0,0,cx,cy,SWP_NOMOVE | SWP_NOZORDER); + SetWindowText(dlg->hDlg,title); + SendMessage(dlg->hDlg,WM_USER + 2,0,0); + strncpy(dlg->pszCallback,cb->value.str.val,sizeof(dlg->pszCallback)-1); + + rs_id = zend_list_insert(dlg,g_res_dlg_id); + if(rs_id){ + RETURN_RESOURCE(rs_id); + } +Error: + if(dlg){ + if(dlg->hDlg)DestroyWindow(dlg->hDlg); + my_memfree(dlg); + } + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgRun) +{ + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r",&res) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + if(!res)goto Error; + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || (dlg->lFlags & 0x01))goto Error; + + ShowWindow(dlg->hDlg,SW_SHOWNORMAL); + dlg->lFlags |= 1; + + RETURN_TRUE; +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_DlgSetCallbacks) +{ + zval* res = 0; + zval* wmc=NULL; + zval* wmn=NULL; + zval* wmt=NULL; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!z!z!",&res,&wmc,&wmn,&wmt) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + if(!res)goto Error; + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + + if(wmc && zend_is_callable(wmc,0,NULL)){ + strncpy(dlg->pszWmCommand,wmc->value.str.val,sizeof(dlg->pszWmCommand)); + }else{ + *dlg->pszWmCommand = 0; + } + + if(wmn && zend_is_callable(wmn,0,NULL)){ + strncpy(dlg->pszWmNotify,wmn->value.str.val,sizeof(dlg->pszWmNotify)); + }else{ + *dlg->pszWmNotify = 0; + } + + if(wmt && zend_is_callable(wmt,0,NULL)){ + strncpy(dlg->pszWmTimer,wmt->value.str.val,sizeof(dlg->pszWmTimer)); + }else{ + *dlg->pszWmTimer = 0; + } + + RETURN_TRUE; +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_DlgSetTimer) +{ + unsigned long id,ts; + zval* res = 0; + zval* cb = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllz",&res,&id,&ts,&cb) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb must be a valid callback!"); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)RETURN_FALSE; + + strncpy(dlg->pszWmTimer,cb->value.str.val,sizeof(dlg->pszWmTimer)); + + RETURN_LONG(SetTimer(dlg->hDlg,id,ts,NULL)); +} + +ZEND_FUNCTION(mb_DlgKillTimer) +{ + unsigned long id; + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl",&res,&id) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)RETURN_FALSE; + RETURN_LONG(KillTimer(dlg->hDlg,id)); +} + +ZEND_FUNCTION(mb_DlgGet) +{ + sDialog* dlg = NULL; + long rs_id = 0; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(mbe->event != MBT_DIALOG){ + RETURN_NULL(); + } + + if(mbe->p1 != NULL){ + RETURN_RESOURCE((long)mbe->p1); + } + + dlg = (sDialog*)mbe->p3; + rs_id = zend_list_insert(dlg,g_res_dlg_id); + if(rs_id){ + mbe->p1 = (void*)(rs_id); + RETURN_RESOURCE(rs_id); + } + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgGetText) +{ + unsigned long id=0; + char text[2048]; + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl",&res,&id) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + + + if(id > (dlg->lNum + 1000)){ + goto Error; + }else{ + *text = 0; + GetDlgItemText(dlg->hDlg,id,text,sizeof(text)-1); + RETURN_STRING(text,1); + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgSetText) +{ + char* text=""; + unsigned long id=0,tl=0; + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls",&res,&id,&text,&tl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + + + if(id > (dlg->lNum + 1000)){ + goto Error; + }else{ + SetDlgItemText(dlg->hDlg,id,text); + } + RETURN_TRUE; +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_DlgGetInt) +{ + unsigned long id=0; + char isss=0; + int ok = 0; + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|b",&res,&id,&isss) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + + + if(id > (dlg->lNum + 1000)){ + goto Error; + }else{ + id = GetDlgItemInt(dlg->hDlg,id,&ok,isss); + if(ok){ + RETURN_LONG(id); + }else{ + RETURN_FALSE; + } + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgSendMsg) +{ + zval* res=0; + zval* lparam=0; + zval* wparam=0; + unsigned long id=0; + unsigned long msg=0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll|z!z!",&res,&id,&msg,&wparam,&lparam) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || !msg || msg == WM_DESTROY)goto Error; + + if(id > (dlg->lNum + 1000)){ + goto Error; + }else{ + try{ + void* lp = (lparam->type==IS_STRING)?((void*)lparam->value.str.val):((void*)lparam->value.lval); + void* wp = (lparam->type==IS_STRING)?((void*)wparam->value.str.val):((void*)wparam->value.lval); + RETURN_LONG(SendDlgItemMessage(dlg->hDlg,id,msg,(WPARAM)wp,(LPARAM)lp)); + }catch(...){ + RETURN_FALSE; + } + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgGetIdByParam) +{ + long param=0; + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl",&res,¶m) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + + for(unsigned long i=0;ilNum;i++) + { + if(dlg->table[i]->param == param){ + RETURN_LONG(1000 + i); + } + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgGetHWND) +{ + long id=0; + zval* res = 0; + sDialog* dlg = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl",&res,&id) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + if(id == NULL){ + RETURN_LONG((long)dlg->hDlg); + }else{ + RETURN_LONG((long)GetDlgItem(dlg->hDlg,id)); + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgMove) +{ + sDialog* dlg = NULL; + long id,x,y,cx=-1,cy=-1; + HWND hWnd; + zval* res = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll|ll",&res,&id,&x,&y,&cx,&cy) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg)goto Error; + + hWnd = (id == NULL)?(dlg->hDlg):GetDlgItem(dlg->hDlg,id); + RETURN_LONG(SetWindowPos(hWnd,NULL,x,y,cx,cy,SWP_NOZORDER | ((cx == -1)?(SWP_NOSIZE):0))); +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgGetString) +{ + sStdInDlg di = {0}; + zval* tmp = NULL; + long ilen; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sllls",&di.info,&ilen,&di.title,&ilen,&di.flags,&di.x,&di.y,&di.def,&ilen) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + + //zend_alter_ini_entry("max_execution_time",sizeof("max_execution_time"),"600",3,PHP_INI_USER,PHP_INI_STAGE_RUNTIME); + + if(DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG2),NULL,(DLGPROC)DlgStdInProc,(LPARAM)&di)==IDOK) + { + RETURN_STRING(di.buffer,1); + }else{ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_DlgListAddItem) +{ + unsigned long id=0; + unsigned long nl=0; + unsigned long cx=0; + unsigned long i=0; + zval* res = 0; + char* values[5]={0}; + sDialog* dlg = NULL; + sDlgControl* ct; + LVITEM li={0}; + HWND hList; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls|ssss",&res,&id,&values[0],&nl, + &values[1],&nl,&values[2],&nl,&values[3],&nl,&values[4],&nl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)) || *values[0]=='\0')goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 6)goto Error; + + li.pszText = values[0]; + li.lParam = (LPARAM)ct->cs2; + li.iSubItem = 0; + li.iItem = ct->cs2; + li.mask = LVIF_PARAM | LVIF_TEXT; + + hList = GetDlgItem(dlg->hDlg,id); + nl = ListView_InsertItem(hList,&li); + if(nl != -1) + { + for(char** v=(values + 1);*v;v++) + { + li.mask = LVIF_TEXT; + li.pszText = *v; + li.iItem = nl; + li.iSubItem = ++i; + ListView_SetItem(hList,&li); + } + ct->cs2++; + RETURN_LONG(nl); + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgListDelItem) +{ + unsigned long item=0; + unsigned long id=0; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll",&res,&id,&item) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 6)goto Error; + + RETURN_LONG(ListView_DeleteItem(ct->hWnd,item)); +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgListSetItem) +{ + unsigned long id=0,it=0,si=0,tl=0; + zval* res = 0; + char* txt = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + LVITEM li={0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllls",&res,&id,&it,&si,&txt,&tl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 6 || it > ct->cs2 || si > ct->cs1)goto Error; + + li.mask = LVIF_TEXT; + li.pszText = txt; + li.iItem = it; + li.iSubItem = si; + ListView_SetItem(ct->hWnd,&li); + RETURN_TRUE; +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgListGetItem) +{ + unsigned long id=0,it=0,si=0; + char buffer[1024]; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + LVITEM li={0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll",&res,&id,&it,&si) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 6 || it > ct->cs2 || si > ct->cs1)goto Error; + + *buffer = 0; + + li.mask = LVIF_TEXT; + li.iItem = it; + li.iSubItem = si; + li.pszText = buffer; + li.cchTextMax = sizeof(buffer)-1; + + if(ListView_GetItem(ct->hWnd,&li) == FALSE)goto Error; + RETURN_STRING(buffer,1); +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgListGetSel) +{ + unsigned long id=0; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl",&res,&id) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 6)goto Error; + + id = ListView_GetSelectionMark(ct->hWnd); + if(id !=-1){ + RETURN_LONG(id); + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgListAddCol) +{ + unsigned long id=0; + unsigned long nl=0; + unsigned long cx=0; + zval* res = 0; + char* name; + sDialog* dlg = NULL; + sDlgControl* ct; + LVCOLUMN lvc={0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlsl",&res,&id,&name,&nl,&cx) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 6 || ct->cs1 > 5)goto Error; + + lvc.cx = cx; + lvc.fmt = LVCFMT_CENTER; + lvc.pszText = name; + lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT; + + nl = ListView_InsertColumn(GetDlgItem(dlg->hDlg,id),ct->cs1,&lvc) != -1; + ct->cs1 += nl; + if(nl != -1){ + RETURN_LONG(nl); + } +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgComboAddItem) +{ + unsigned long id; + unsigned long il; + unsigned long param = -1; + char* item; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls|l",&res,&id,&item,&il,¶m) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 4)goto Error; + + id = SendMessage(ct->hWnd,CB_ADDSTRING,NULL,(LPARAM)item); + if(id >= 0){ + if(param != -1){ + SendMessage(ct->hWnd,CB_SETITEMDATA,id,param); + } + RETURN_LONG(id); + } +Error: + RETURN_NULL(); +} +ZEND_FUNCTION(mb_DlgComboDelItem) +{ + unsigned long id; + unsigned long iid; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll",&res,&id,&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 4)goto Error; + + RETURN_LONG(SendMessage(ct->hWnd,CB_DELETESTRING,iid,0)>=0); +Error: + RETURN_NULL(); +} + +ZEND_FUNCTION(mb_DlgComboGetItem) +{ + unsigned long id; + unsigned long iid; + zval* res = 0; + char* str = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll",&res,&id,&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 4)goto Error; + + id = SendMessage(ct->hWnd,CB_GETLBTEXTLEN,iid,0); + if(id < 0)goto Error; + + str = (char*)emalloc(id + 1); + if(!str)goto Error; + str[id] = 0; + + id = SendMessage(ct->hWnd,CB_GETLBTEXT,iid,(LPARAM)str); + if(id<=0){ + efree(str); + goto Error; + } + RETURN_STRING(str,0); +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_DlgComboGetSel) +{ + unsigned long id; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl",&res,&id) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 4)goto Error; + + id = SendMessage(ct->hWnd,CB_GETCURSEL,0,0); + if(id != CB_ERR){ + RETURN_LONG(id); + } +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_DlgComboGetItemData) +{ + unsigned long id; + unsigned long iid; + zval* res = 0; + sDialog* dlg = NULL; + sDlgControl* ct; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll",&res,&id,&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || id < 1000 || (id > (dlg->lNum + 1000)))goto Error; + + ct = dlg->table[id - 1000]; + if(ct->type != 4)goto Error; + + id = SendMessage(ct->hWnd,CB_GETITEMDATA,iid,0); + if(id == CB_ERR)goto Error; + RETURN_LONG(id); +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_DlgAddControl) +{ + extern HFONT hVerdanaFont; + + zval* res = 0; + zval* cb = 0; + long type=0; + long param=0; + long style=0; + long x,y,cx,cy; + char* name; + long nl=0; + sDialog* dlg = NULL; + sDlgControl* ctrl = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlsllllz!|ll",&res,&type,&name,&nl, + &x,&y,&cx,&cy,&cb,&style,¶m) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!res){ + goto Error; + } + + if(cb){ + if(cb->type!=IS_STRING || !zend_is_callable(cb,0,NULL)){ + goto Error; + } + } + + ZEND_FETCH_RESOURCE(dlg,sDialog*,&res,-1,g_res_dlg_name,g_res_dlg_id); + if(!dlg || dlg->lNum >= DLG_NUM_CONTROLS)goto Error; + + ctrl = (sDlgControl*)my_malloc(sizeof(sDlgControl)); + if(!ctrl)goto Error; + memset(ctrl,0,sizeof(sDlgControl)); + + if(type != 1){ + style |= WS_TABSTOP; + } + + ctrl->hWnd = CreateWindow(DlgGetCtrlClass(type),name,(WS_CHILD|WS_VISIBLE|style),x,y,cx,cy, + dlg->hDlg,(HMENU)(1000 + dlg->lNum),hInst,NULL); + + if(!ctrl->hWnd)goto Error; + + if(type == 6){ + ListView_SetExtendedListViewStyle(ctrl->hWnd,LVS_EX_FULLROWSELECT); + } + + SendMessage(ctrl->hWnd,WM_SETFONT,(WPARAM)hVerdanaFont,0); + + if(cb){ + strncpy(ctrl->pszCallback,cb->value.str.val,sizeof(ctrl->pszCallback)-1); + } + + ctrl->type = (char)(0xFF & type); + ctrl->param = param; + dlg->table[dlg->lNum] = ctrl; + + RETURN_LONG(1000 + dlg->lNum++); +Error: + if(ctrl){ + my_memfree((void*)ctrl); + } + RETURN_FALSE; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_event.cpp b/mBot/src/mbot/functions/mb_event.cpp new file mode 100644 index 0000000..e7602b7 --- /dev/null +++ b/mBot/src/mbot/functions/mb_event.cpp @@ -0,0 +1,202 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +/*********************************** + * history + **********************************/ +ZEND_FUNCTION(mb_EventFindFirst) +{ + long cid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)cid,0)); +} +ZEND_FUNCTION(mb_EventFindFirstUnread) +{ + long cid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)cid,0)); +} +ZEND_FUNCTION(mb_EventFindLast) +{ + long cid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallService(MS_DB_EVENT_FINDLAST,(WPARAM)cid,0)); +} +ZEND_FUNCTION(mb_EventFindNext) +{ + long hid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&hid) == FAILURE || !hid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hid,0)); +} +ZEND_FUNCTION(mb_EventFindPrev) +{ + long hid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&hid) == FAILURE || !hid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(CallService(MS_DB_EVENT_FINDPREV,(WPARAM)hid,0)); +} +ZEND_FUNCTION(mb_EventGetCount) +{ + long cid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&cid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + cid = CallService(MS_DB_EVENT_GETCOUNT,(WPARAM)cid,0); + if(cid == -1){ + RETURN_FALSE; + }else{ + RETURN_LONG(cid); + } +} +ZEND_FUNCTION(mb_EventDel) +{ + long hid=0,cid=-1; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",&hid,&cid) == FAILURE || !hid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(cid == -1){ + cid = CallService(MS_DB_EVENT_GETCONTACT,hid,0); + if(cid == -1){ + RETURN_NULL(); + } + } + RETURN_LONG(CallService(MS_DB_EVENT_DELETE,cid,hid)!=-1); +} +ZEND_FUNCTION(mb_EventAdd) +{ + DBEVENTINFO dbei = {sizeof(dbei),0}; + char* proto=NULL,*body=NULL; + long hid=0,cid=0,pl=0,bl=0,type=EVENTTYPE_MESSAGE,ts=0; + long flags=DBEF_SENT; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls|lll",&proto,&pl,&cid,&body,&bl,&type,&flags,&ts) == FAILURE || !proto){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + flags &= ~(0x00000001); + + dbei.cbBlob = bl + 1; + dbei.pBlob = (PBYTE)body; + dbei.eventType = (unsigned short)type; + dbei.timestamp = (ts)?(ts):(time(0)); + dbei.szModule = proto; + dbei.flags = flags; + + RETURN_LONG(CallService(MS_DB_EVENT_ADD,(WPARAM)cid,(LPARAM)&dbei)); +} +ZEND_FUNCTION(mb_EventGetData) +{ + long hid=0; + unsigned long mbLen = 0; + char* buffer = NULL; + wchar_t *wbuff = NULL; + long req_buff = NULL; + zend_bool unicode = 0; + + DBEVENTINFO dbei = {0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b",&hid,&unicode) == FAILURE || !hid){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + req_buff = CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)hid,0); + if(req_buff < 0){ + RETURN_FALSE; + } + + buffer = (char*)emalloc(req_buff + 1); + if(!buffer){ + RETURN_FALSE; + } + buffer[req_buff]='\0'; + + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = req_buff; + dbei.pBlob = (PBYTE)buffer; + + if(CallService(MS_DB_EVENT_GET, (WPARAM)hid, (LPARAM)&dbei)!=0){ + efree(buffer); + RETURN_FALSE; + } + + //module,type,timestamp,flags,value + if(array_init(return_value)==FAILURE){ + efree(buffer); + RETURN_FALSE; + } + + add_index_string(return_value, 0, dbei.szModule, 1); + add_index_long(return_value, 1, dbei.eventType); + add_index_long(return_value, 2, dbei.timestamp); + add_index_long(return_value, 3, dbei.flags); + + mbLen = strlen(buffer); + + if(unicode){ + //add the ascii body + add_index_stringl(return_value, 4, buffer, mbLen, 1); + //if possible add the UNICODE body + if(((mbLen + 1) * 3) <= dbei.cbBlob){ + add_index_stringl(return_value, 5, (buffer + mbLen + 1), mbLen * 2 , 1); + }else{//if not add empty string + wbuff = (wchar_t*)emalloc((mbLen + 1) * sizeof(wchar_t)); + if(wbuff){ + for(unsigned i=0;ic_param; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsszl",&cid,&desc,&dl,&file,&fl,&cb,¶m) == FAILURE || !cid || !dl || !fl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(!mbe->php){ + PHPWSE("You can't use this function here!"); + }else if(!zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb is expected to be a valid callback function!"); + } + + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + memset(ack,0,sizeof(sACKSync)); + + ack->lType = ACKTYPE_FILE; + ack->hContact = (HANDLE)cid; + ack->php = mbe->php; + ack->lParam = param; + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + + files[0] = file; + ack->hProcess = (HANDLE)CallContactService((HANDLE)cid,PSS_FILE,(WPARAM)desc,(LPARAM)files); + if(!ack->hProcess)goto Error; + g_slist.Add(ack); + + RETURN_LONG((long)ack); +Error: + free(ack); + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_FileGetInfo) +{ + long fth; + sACKSync* as; + sFileInfo* fi; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll",&fth) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!fth){ + goto Error; + } + + try{ + g_slist.Lock(); + as = (sACKSync*)g_slist.m_head; + while(as) + { + if((long)as == fth) + { + fi = (sFileInfo*)as->pszProtocol; + if(array_init(return_value)==FAILURE){ + as = NULL; + break; + } + //array($num_files,$cur_file,$tot_bytes,$tot_sent,$cur_size,$cur_sent,$cur_time); + add_index_long(return_value,0,fi->numFiles); + add_index_long(return_value,1,fi->curFile); + add_index_long(return_value,2,fi->bytesTotal); + add_index_long(return_value,3,fi->bytesDone); + add_index_long(return_value,4,fi->curSize); + add_index_long(return_value,5,fi->curDone); + add_index_long(return_value,6,fi->curTime); + break; + } + as = (sACKSync*)as->next; + } + }catch(...){ + as = NULL; + } + + g_slist.Unlock(); + + if(as){ + return; + } +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_FileCancel) +{ + long fth,hp; + sACKSync* as; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&fth) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!fth){ + goto Error; + } + + try{ + g_slist.Lock(); + as = (sACKSync*)g_slist.m_head; + while(as){ + if((long)as == fth){ + hp = (long)as->hProcess; + break; + } + as = (sACKSync*)as->next; + } + }catch(...){ + as = NULL; + } + + g_slist.Unlock(); + + + if(as){ + CallContactService((HANDLE)as->hContact,PSS_FILECANCEL,(WPARAM)hp,0); + RETURN_TRUE; + } +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_FileDeny) +{ + char *desc=NULL; + long fid=0,dl=0,cid=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lls",&cid,&fid,&desc,&dl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + if(!fid || !cid){ + RETURN_FALSE; + } + RETURN_LONG(CallContactService((HANDLE)cid,PSS_FILEDENY,(WPARAM)fid,(LPARAM)desc)); +} + +ZEND_FUNCTION(mb_FileAccept) +{ + char *dst=NULL; + long dl; + long cid; + long fth; + long param=0; + char resume=0; + zval* cb; + sACKSync* ack = NULL; + PROTOFILERESUME pfr; + + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llsz|cl",&fth,&cid,&dst,&dl,&cb,&resume,¶m) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(!mbe->php){ + PHPWSE("You can't use this function here!"); + }else if(!zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb is expected to be a valid callback function!"); + } + + if(!fth){RETURN_FALSE} + + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + memset(ack,0,sizeof(sACKSync)); + + ack->lType = ACKTYPE_FILE; + ack->hContact = (HANDLE)cid; + ack->php = mbe->php; + ack->lParam = param; + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + + try{ + if(resume == 0){ + ack->hProcess = (HANDLE)CallContactService((HANDLE)cid,PSS_FILEALLOW,(WPARAM)fth,(LPARAM)dst); + }else{ + pfr.action = resume; + pfr.szFilename = dst; + ack->hProcess = (HANDLE)CallContactService((HANDLE)cid,PS_FILERESUME,(WPARAM)fth,(LPARAM)&pfr); + } + }catch(...){ + ack->hProcess = NULL; + } + + if(ack->hProcess){ + g_slist.Add(ack); + RETURN_LONG((long)ack); + } + + if(ack)my_memfree(ack); + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_FileStore) +{ + CCSDATA* css; + PROTORECVEVENT* prr; + long result = 0; + char* proto=NULL; + char* szDesc=NULL; + char* szFile=NULL; + DBEVENTINFO dbei={0}; + + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + css = (CCSDATA*)mbe->lParam; + + if(mbe->event != MBT_FILEIN || !css || !css->lParam){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(mbe->lFlags & MBOT_FLAG_STORED){ + RETURN_FALSE; + } + + + prr = (PROTORECVEVENT*)css->lParam; + proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)css->hContact,0); + + szFile = prr->szMessage + sizeof(DWORD); + szDesc = szFile + strlen(szFile) + 1; + + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = sizeof(DWORD) + strlen(szFile) + strlen(szDesc) + 2; + dbei.pBlob = (PBYTE)prr->szMessage; + dbei.eventType = (unsigned short)EVENTTYPE_FILE; + dbei.timestamp = time(0); + dbei.szModule = proto; + dbei.flags = DBEF_READ; + + result = CallService(MS_DB_EVENT_ADD,(WPARAM)css->hContact,(LPARAM)&dbei); + if(result){ + mbe->lFlags |= MBOT_FLAG_STORED; + } + + RETURN_LONG(*((long*)dbei.pBlob)); +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_icons.cpp b/mBot/src/mbot/functions/mb_icons.cpp new file mode 100644 index 0000000..a5bbf55 --- /dev/null +++ b/mBot/src/mbot/functions/mb_icons.cpp @@ -0,0 +1,79 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +/////////////////////////////// +//icons +/////////////////////////////// +const static char* mb_lsi_def_icons[]={0,IDI_APPLICATION,IDI_ASTERISK, + IDI_ERROR,IDI_EXCLAMATION,IDI_HAND,IDI_INFORMATION,IDI_QUESTION,IDI_WARNING,IDI_WINLOGO,0}; + +ZEND_FUNCTION(mb_IconLoadSys) +{ + HANDLE hIcon = NULL; + long iid=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&iid) == FAILURE || iid<1 || iid>9){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG((long)LoadIcon(NULL,mb_lsi_def_icons[iid])); +} +ZEND_FUNCTION(mb_IconLoadSkin) +{ + long iid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG((long)LoadSkinnedIcon((int)iid)); +} +ZEND_FUNCTION(mb_IconLoadSkinnedProto) +{ + char* proto=NULL; + long iid=0,pl=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl",&proto,&pl,&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG((long)LoadSkinnedProtoIcon((const char*)(*proto)?(proto):(NULL),(int)iid)); +} +ZEND_FUNCTION(mb_IconLoadProto) +{ + char* proto=NULL; + long iid=0,pl=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl",&proto,&pl,&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + // + RETURN_LONG((long)CallProtoService((const char*)proto,PS_LOADICON,(int)iid | PLIF_SMALL,0)); +} + +ZEND_FUNCTION(mb_IconDestroy) +{ + long iid=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&iid) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + try{ + DestroyIcon((HICON)iid); + }catch(...){ + RETURN_FALSE; + } + RETURN_TRUE; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_irc.cpp b/mBot/src/mbot/functions/mb_irc.cpp new file mode 100644 index 0000000..6b6ea43 --- /dev/null +++ b/mBot/src/mbot/functions/mb_irc.cpp @@ -0,0 +1,357 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +ZEND_FUNCTION(mb_IrcGetGuiDataIn) +{ + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + if(mbe->event == MBT_IRC_IN) + { + GCEVENT* gce = (GCEVENT*)mbe->p4; + if(array_init(return_value)==FAILURE)RETURN_FALSE; + add_index_long(return_value,0,gce->pDest->iType); + if(gce->pDest->pszID){add_index_string(return_value,1,(char*)gce->pDest->pszID,1);}else{add_index_unset(return_value,1);} + if(gce->pszText){add_index_string(return_value,2,(char*)gce->pszText,1);}else{add_index_unset(return_value,2);} + if(gce->pszNick){add_index_string(return_value,3,(char*)gce->pszNick,1);}else{add_index_unset(return_value,3);} + if(gce->pszUID){add_index_string(return_value,4,(char*)gce->pszUID,1);}else{add_index_unset(return_value,4);} + if(gce->pszStatus){add_index_string(return_value,5,(char*)gce->pszStatus,1);}else{add_index_unset(return_value,5);} + if(gce->pszUserInfo){add_index_string(return_value,6,(char*)gce->pszUserInfo,1);}else{add_index_unset(return_value,6);} + add_index_long(return_value,7,gce->bIsMe); + add_index_long(return_value,8,(gce->dwFlags & GCEF_ADDTOLOG) != 0); + add_index_long(return_value,9,gce->time); + add_index_long(return_value,10,((WPARAM_GUI_IN*)mbe->wParam)->wParam); + return; + } + else + { + PHPWSE("You cannot call this function here!"); + } +} + +void help_strrealloc(zval* v,const char** out) +{ + if(v){ + mmi.mmi_free((void*)*out); + if((v->type == IS_BOOL && !v->value.lval) || (v->type == IS_LONG && !v->value.lval)){ + *out = NULL; + }else{ + convert_to_string(v); + *out = (const char*)mmi.mmi_malloc(v->value.str.len+1); + memcpy((void*)*out,v->value.str.val,v->value.str.len+1); + } + } +} + +ZEND_FUNCTION(mb_IrcSetGuiDataIn) +{ + zval* itype = NULL; + zval* pszID = NULL; + zval* pszText = NULL; + zval* pszNick = NULL; + zval* pszUID = NULL; + zval* pszStatus = NULL; + zval* pszUserInfo = NULL; + zval* bIsMe = NULL; + zval* bAddToLog = NULL; + zval* timestamp = NULL; + long wParam = 0xfaaaffaa; + + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(mbe->event != MBT_IRC_IN){ + PHPWSE("You cannot call this function here!"); + } + //mb_IrcSetGuiDataIn($iType,$pszID,$pszText,$pszNick,$pszUID,$pszStatus,$pszUserInfo,$bIsMe,$bAddToLog,$timestamp,$wParam); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!|z!z!z!z!z!z!z!z!z!l", + &itype,&pszID,&pszText,&pszNick,&pszUID,&pszStatus,&pszUserInfo,&bIsMe,&bAddToLog,×tamp,&wParam) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + GCEVENT* gce = (GCEVENT*)mbe->p4; + if(itype && itype->type == IS_LONG){ + gce->pDest->iType = itype->value.lval; + } + + try{ + help_strrealloc(pszID,(const char**)&gce->pDest->pszID); + help_strrealloc(pszText,&gce->pszText); + help_strrealloc(pszNick,&gce->pszNick); + help_strrealloc(pszUID,&gce->pszUID); + help_strrealloc(pszStatus,&gce->pszStatus); + help_strrealloc(pszUserInfo,&gce->pszUserInfo); + help_strrealloc(pszNick,&gce->pszNick); + }catch(...){ + PHPWSE("Oops... some data might have got corrupted!"); + } + + if(bIsMe && bIsMe->type == IS_LONG){ + gce->bIsMe = bIsMe->value.lval; + } + if(bAddToLog && bAddToLog->type == IS_LONG){ + gce->dwFlags = (bAddToLog->value.lval)?GCEF_ADDTOLOG:0; + } + if(timestamp && timestamp->type == IS_LONG){ + gce->time = timestamp->value.lval; + } + if(wParam != 0xfaaaffaa){ + ((WPARAM_GUI_IN*)mbe->wParam)->wParam = wParam; + } + RETURN_TRUE; +} + +ZEND_FUNCTION(mb_IrcSetGuiDataOut) +{ + //$iType,$pszID,$pszUID,$text + zval* itype; + zval* pszID; + zval* pszUID; + zval* text; + + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(mbe->event != MBT_IRC_OUT){ + PHPWSE("You cannot call this function here!"); + } + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!|z!z!z!",&itype,&pszID,&pszUID,&text) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + GCHOOK* gch = (GCHOOK*)mbe->p4; + + if(itype && itype->type == IS_LONG){ + gch->pDest->iType = itype->value.lval; + } + + try{ + help_strrealloc(text,(const char**)&gch->pszText); + help_strrealloc(pszUID,(const char**)&gch->pszUID); + help_strrealloc(pszID,(const char**)&gch->pDest->pszID); + }catch(...){ + PHPWSE("Oops... some data might have got corrupted!"); + } + RETURN_TRUE; +} +ZEND_FUNCTION(mb_IrcInsertRawIn) +{ + char msg[256]; + char raw[530]; + char* module,*body; + long ml,bl; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&module,&ml,&body,&bl) == FAILURE || !*module){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(bl > 512){ + PHPWSE("You must not provide more than 512 bytes including CRLF for this function!"); + } + + memcpy(raw,body,bl); + raw[bl]=0; + + _snprintf(msg,sizeof(msg)-1,"%s/InsertRawIn",module); + RETURN_LONG(CallService(msg,NULL,(LPARAM)raw)); +} +ZEND_FUNCTION(mb_IrcInsertRawOut) +{ + char msg[256]; + char raw[530]; + char* module,*body; + long ml,bl; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&module,&ml,&body,&bl) == FAILURE || !*module){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + }else if(bl > 512){ + PHPWSE("You must not provide more than 512 bytes including CRLF for this function!"); + } + + memcpy(raw,body,bl); + if(raw[bl-2]!='\r'){ + if(raw[bl-1]=='\n'){ + raw[bl-1]='\r'; + raw[bl]='\n'; + raw[bl+1]=0; + }else{ + raw[bl]='\r'; + raw[bl+1]='\n'; + raw[bl+2]=0; + } + }else{ + raw[bl]=0; + } + + _snprintf(msg,sizeof(msg)-1,"%s/InsertRawOut",module); + RETURN_LONG(CallService(msg,NULL,(LPARAM)raw)); +} +ZEND_FUNCTION(mb_IrcInsertGuiIn) +{ + char* module; + long ml; + long itype = NULL; + zval* pszID = NULL; + zval* pszText = NULL; + zval* pszNick = NULL; + zval* pszUID = NULL; + zval* pszStatus = NULL; + zval* pszUserInfo = NULL; + char bIsMe = 0; + char bAddToLog = 0; + long timestamp = 0; + long wParam = 0; + + char msg[256]; + GCEVENT gce = {0}; + GCDEST gcd = {0}; + WPARAM_GUI_IN wpi = {0}; + + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + //mb_IrcInsertGuiIn($module,$iType,$pszID,$pszText,$pszNick,$pszUID,$pszStatus,$pszUserInfo,$bIsMe,$bAddToLog,$timestamp,$wParam); + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz!|z!z!z!z!z!bbll",&module,&ml,&itype,&pszID, + &pszText,&pszNick,&pszUID,&pszStatus,&pszUserInfo,&bIsMe,&bAddToLog,×tamp,&wParam) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + gce.pDest = &gcd; + gcd.iType = itype; + gcd.pszModule = module; + if(pszID){ + convert_to_string(pszID); + gcd.pszID = pszID->value.str.val; + } + gce.cbSize = sizeof(gce); + gce.dwItemData = 0x80000000; + gce.time = (timestamp)?timestamp:time(0); + gce.bIsMe = bIsMe; + gce.dwFlags = (bAddToLog)?GCEF_ADDTOLOG:0; + + if(pszUID){ + convert_to_string(pszUID); + gce.pszUID = pszUID->value.str.val; + } + if(pszText){ + convert_to_string(pszText); + gce.pszText = pszText->value.str.val; + } + if(pszNick){ + convert_to_string(pszNick); + gce.pszNick = pszNick->value.str.val; + } + if(pszStatus){ + convert_to_string(pszStatus); + gce.pszStatus = pszStatus->value.str.val; + } + if(pszUserInfo){ + convert_to_string(pszUserInfo); + gce.pszUserInfo = pszUserInfo->value.str.val; + } + wpi.wParam = wParam; + wpi.pszModule = module; + + _snprintf(msg,sizeof(msg)-1,"%s/InsertGuiIn",module); + RETURN_LONG(CallService(msg,(WPARAM)&wpi,(LPARAM)&gce)); +} + +ZEND_FUNCTION(mb_IrcInsertGuiOut) +{ + //?> mb_IrcInsertGuiOut('IRC',0x0080,'#miranda',NULL,NULL); + char* module; + long iType = 0; + long ml = 0; + zval* pszText = NULL; + zval* pszUID = NULL; + zval* pszID = NULL; + + char msg[256]; + GCHOOK gch = {0}; + GCDEST gcd = {0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz!|z!z!",&module,&ml,&iType,&pszID,&pszUID,&pszText) == FAILURE || !*module){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + + gch.pDest = &gcd; + gcd.iType = iType; + gcd.pszModule = module; + gch.dwData = 0x80000000; + if(pszID){ + convert_to_string(pszID); + gch.pDest->pszID = pszID->value.str.val; + } + if(pszUID){ + convert_to_string(pszUID); + gch.pszUID = pszUID->value.str.val; + } + if(pszText){ + convert_to_string(pszText); + gch.pszText = pszText->value.str.val; + } + _snprintf(msg,sizeof(msg)-1,"%s/InsertGuiOut",module); + RETURN_LONG(CallService(msg,(WPARAM)module,(LPARAM)&gch)); +} + +ZEND_FUNCTION(mb_IrcGetData) +{ + char* module; + char* setting; + char* channel = 0; + long ml,sl,cl; + char msg[256]; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s",&module,&ml,&setting,&sl,&channel,&cl) == FAILURE || !*module){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + _snprintf(msg,sizeof(msg)-1,"%s/GetIrcData",module); + setting = (char*)CallService(msg,(WPARAM)channel,(LPARAM)setting); + if(setting){ + try{ + RETVAL_STRING(setting,1); + mmi.mmi_free(setting); + return; + }catch(...){ + RETURN_FALSE; + } + }else{ + RETURN_FALSE; + } +} +ZEND_FUNCTION(mb_IrcPostMessage) +{ + char* module; + char* text; + long ml,tl; + + char msg[256]; + GCHOOK gch = {0}; + GCDEST gcd = {0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&module,&ml,&text,&tl) == FAILURE || !*module){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + gch.pDest = &gcd; + gcd.iType = 1; + gcd.pszModule = module; + gcd.pszID = "Network Log"; + gch.dwData = 0x80000000; + gch.pszText = text; + _snprintf(msg,sizeof(msg)-1,"%s/InsertGuiOut",module); + RETURN_LONG(CallService(msg,(WPARAM)module,(LPARAM)&gch)); +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_menu.cpp b/mBot/src/mbot/functions/mb_menu.cpp new file mode 100644 index 0000000..0942081 --- /dev/null +++ b/mBot/src/mbot/functions/mb_menu.cpp @@ -0,0 +1,167 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +ZEND_FUNCTION(mb_MenuAdd) +{ + zval* cb = NULL; + zval* pb = NULL; + char* name = NULL; + char* proto = NULL; + char fname[24]; + char root = 0; + void* temp = NULL; + long nl = 0; + long pl = 0; + long param = 0; + long icon = 0; + long flags = 0; + long position = 0x7ffffff; + char cm = 0; + CLISTMENUITEM mi={0}; + sMFSync* mfs; + + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz|llbslz!b",&name,&nl,¶m,&cb,&icon, + &flags,&cm,&proto,&pl,&position,&pb,&root)==FAILURE + || !nl || cb->type != IS_STRING){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(pb && (!cm || !zend_is_callable(pb,0,NULL))){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(mbe->event == MBT_AUTOLOAD){ + mbe->php = sman_getbyfile((const char*)mbe->p3); + } + if(!mbe->php){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + mfs = (sMFSync*)my_malloc(sizeof(sMFSync)); + if(!mfs){RETURN_FALSE;} + memset(mfs,0,sizeof(sMFSync)); + + mfs->php = mbe->php; + + strncpy(mfs->pszFunction,cb->value.str.val,sizeof(mfs->pszFunction)); + _snprintf(fname,sizeof(fname),"MBot/Menu/%.8x",mfs); + + temp = help_makefunct(mfs,(void*)help_callmenu); + if(!temp){ + goto Error; + } + if(!CreateServiceFunction(fname,(MIRANDASERVICE)temp)){ + goto Error; + } + mi.cbSize = sizeof(mi); + mi.position = position; + mi.hIcon = (icon)?((HICON)icon):(hMBotIcon); + mi.pszName = name; + mi.pszService = fname; + mi.flags = flags; + + if(cm){ + if(pl){ + mi.pszContactOwner = proto; + } + if(pb){ + strncpy(mfs->pszPrebuild,pb->value.str.val,sizeof(mfs->pszPrebuild)); + lm_flags |= MBOT_FLAG_WANTPREBUILD; + } + }else{ + mi.pszPopupName = (!root)?"MBot":NULL; + } + + mfs->hMenu = CallService((cm)?(MS_CLIST_ADDCONTACTMENUITEM):(MS_CLIST_ADDMAINMENUITEM),0,(LPARAM)&mi); + if(mfs->hMenu==NULL){ + DestroyServiceFunction(fname); + goto Error; + } + g_mlist.Add(mfs); + RETURN_LONG(mfs->hMenu); +Error: + if(mbe->php){sman_decref(mbe->php);} + my_memfree(mfs); + if(temp){my_memfree(temp);} + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_MenuModify) +{ + long mid = 0; + long flags = 0xffffffff; + char* name = 0; + long nl = 0; + long ico = 0; + zval* cb = NULL; + CLISTMENUITEM mi = {0}; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|sllz",&mid,&name,&nl,&ico,&flags,&cb)==FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!mid){ + RETURN_NULL(); + } + + if(cb) + { + sMFSync* mfs; + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_ERRORS("$cb is expected to be a valid callback function!"); + } + + g_mlist.Lock(); + mfs = (sMFSync*)g_mlist.m_head; + while(mfs) + { + if(mfs->hMenu == mid){ + strncpy(mfs->pszFunction,cb->value.str.val,sizeof(mfs->pszFunction)-1); + break; + } + mfs = (sMFSync*)mfs->next; + } + g_mlist.Unlock(); + } + + mi.cbSize = sizeof(mi); + + if(ico){ + mi.hIcon = (HICON)ico; + mi.flags |= CMIM_ICON; + } + if(nl){ + mi.pszName = name; + mi.flags |= CMIM_NAME; + } + if(flags != 0xffffffff){ + mi.flags |= flags | CMIM_FLAGS; + } + + RETURN_LONG(CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)mid,(LPARAM)&mi)); +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_misc.cpp b/mBot/src/mbot/functions/mb_misc.cpp new file mode 100644 index 0000000..de689ce --- /dev/null +++ b/mBot/src/mbot/functions/mb_misc.cpp @@ -0,0 +1,185 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" +#include "../window.h" + +int CtrlACPI(HANDLE hATKACPI,int code, int hasArg, int arg) +{ + unsigned long bytes = 0; + long inbuf[5]; + struct cmbuf { + short cmds[2]; + long cm2; + } cbuf; + long outbuf[192]; + int ret; + + cbuf.cmds[0] = 0; + cbuf.cmds[1] = 4; + cbuf.cm2 = arg; + inbuf[0] = 2; + inbuf[1] = code; + inbuf[2] = hasArg; + inbuf[3] = 8 * hasArg; + inbuf[4] = (long)&cbuf; + + ret = DeviceIoControl(hATKACPI, 0x222404, inbuf, sizeof(inbuf), + outbuf, sizeof(outbuf), &bytes, NULL); + return ret; +} + +ZEND_FUNCTION(mb_AsusExt) +{ + int code,arg,harg; + HANDLE hATKACPI; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll",&code,&harg,&arg) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + hATKACPI = CreateFile("\\\\.\\ATKACPI",GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,0, NULL); + + if(!hATKACPI){ + PHPWSE("This computer does not support this extension!"); + } + + code = CtrlACPI(hATKACPI,code,harg,arg); + CloseHandle(hATKACPI); + RETURN_LONG(code); +} + +ZEND_FUNCTION(mb_ConsoleShow) +{ + extern long lConTopMost; + zend_bool show = 1; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b",&show) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(hDialog){ + ShowWindow(hDialog,(show)?(SW_SHOW):(SW_HIDE)); + if(show){ + SetWindowPos(hDialog,lConTopMost?HWND_TOPMOST:0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + } + } +} + +ZEND_FUNCTION(mb_ConsoleClear) +{ + if(hConsole){ + MBotConsoleClear(); + } +} + +void __stdcall mbb_echo(void* txt) +{ + MBotConsoleAppendText(((char*)txt)+1,*((char*)txt)); + my_memfree((void*)txt); +} + +ZEND_FUNCTION(mb_Echo) +{ + char* txt=NULL; + char* tmp=NULL; + long tl=0; + zend_bool rtf = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",&txt,&tl,&rtf) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + tmp = (char*)my_malloc(tl + 2); + if(tmp){ + memcpy(tmp+1,txt,tl+1); + *tmp = rtf; + if(CallFunctionAsync(mbb_echo,tmp)==FALSE){ + my_memfree(tmp); + RETURN_FALSE; + } + RETURN_TRUE; + }else{ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_MsgBox) +{ + char* body=NULL; + char* caption=NULL; + long bl=0,cl=0,type=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sl",&body,&bl,&caption,&cl,&type) == FAILURE || !bl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(MessageBox(NULL,body,(cl)?(caption):(NULL),type | MB_TOPMOST)); +} + +ZEND_FUNCTION(mb_CListEventAdd) +{ + long cid = 0; + long ico = 0; + zval *cb = NULL; + char *info = NULL; + long il = 0; + long param = 0; + CLISTEVENT cle = {0}; + sCLESync* mfs; + + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz|ll",&cid,&info,&il,&cb,¶m,&ico)==FAILURE || cb->type != IS_STRING){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + mfs = (sCLESync*)my_malloc(sizeof(sCLESync)); + if(!mfs){ + RETURN_FALSE; + } + memset(mfs,0,sizeof(sCLESync)); + + if(!mbe->php){goto Error;} + mfs->php = mbe->php; + + mfs->pParam = (void*)param; + strncpy(mfs->pszFunction,cb->value.str.val,sizeof(mfs->pszFunction)); + + cle.cbSize = sizeof(cle); + cle.hIcon = (ico)?((HICON)ico):hMBotIcon; + cle.pszTooltip = info; + cle.hContact = (HANDLE)cid; + cle.pszService = MS_MBOT_CLISTEVENT; + cle.hDbEvent = (HANDLE)mfs; + cle.lParam = (LPARAM)mfs; + + CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); + RETURN_TRUE; +Error: + if(mfs){ + my_memfree(mfs); + } + RETURN_FALSE; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_msg.cpp b/mBot/src/mbot/functions/mb_msg.cpp new file mode 100644 index 0000000..8acffcf --- /dev/null +++ b/mBot/src/mbot/functions/mb_msg.cpp @@ -0,0 +1,152 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +ZEND_FUNCTION(mb_MsgSetBody) +{ + char* body = NULL; + char* tmp; + long bl = 0; + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + + if((mbe->event!=MBT_PRERECV && mbe->event!=MBT_SEND && mbe->event != MBT_COMMAND && mbe->event != MBT_IRC_RAW) || + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&body,&bl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(mbe->event == MBT_IRC_RAW) + { + mmi.mmi_free(*((char**)mbe->p4)); + if(mbe->p3 == NULL && (bl < 2 || body[bl-2]!='\r'))bl += 2; + + tmp = (char*)mmi.mmi_malloc(bl + 1); + + *((char**)mbe->p4) = tmp; + + if(tmp){ + memcpy(tmp,body,bl); + if(mbe->p3 == NULL){ + *(short*)&tmp[bl-2]='\n\r'; + } + tmp[bl]=0; + RETURN_LONG(1); + }else{ + RETURN_FALSE; + } + } + else if(mbe->t1 = MBE_SSTRING) + { + string* cs = (string*)mbe->p1; + *cs = body; + mbe->lFlags |= MBOT_FLAG_BODY_CHANGED; + } + + RETURN_LONG(1); +} + +ZEND_FUNCTION(mb_MsgSend) +{ + char* body = NULL,*proto = NULL; + long bl = 0,cid = 0,hp = 0,result = 0,param = 0; + zval* cb = NULL; + zend_bool log = 0; + zend_bool unicode = 0; + sACKSync* ack = NULL; + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|bz!lb",&cid,&body,&bl,&log,&cb,¶m,&unicode) == FAILURE + || cid==NULL || bl==0){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(cb && !zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_ERRORS("$cb is expected to be a valid callback function!"); + } + + proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)cid,0); + if(!proto) + { + RETURN_FALSE; + } + + if(cb) + { + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + + memset(ack,0,sizeof(sACKSync)); + + if(!(ack->php = mbe->php)){ + goto Error; + } + + ack->lType = ACKTYPE_MESSAGE; + ack->hContact = (HANDLE)cid; + ack->lParam = param; + + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + strncpy(ack->pszProtocol,proto,15); + + if(!g_slist.Add(ack)){ + goto Error; + } + + ack->hProcess = (HANDLE)CallContactService((HANDLE)cid,(unicode)?(PSS_MESSAGE "W"):(PSS_MESSAGE),(WPARAM)0x800000,(LPARAM)body); + if(!ack->hProcess || ack->hProcess == (HANDLE)(-1)) + { + g_slist.Del(ack); + goto Error; + } + } + else + { + if(!CallContactService((HANDLE)cid,(unicode)?(PSS_MESSAGE "W"):(PSS_MESSAGE),(WPARAM)0x800000,(LPARAM)body)) + { + goto Error; + } + } + + if(log) + { + DBEVENTINFO dbei = {sizeof(dbei),0}; + dbei.cbBlob = bl + 1; + dbei.pBlob = (PBYTE)body; + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.timestamp = time(0); + dbei.szModule = proto; + dbei.flags = DBEF_SENT; + bl = CallService(MS_DB_EVENT_ADD,(WPARAM)cid,(LPARAM)&dbei); + + if(ack && !param){ + ack->lParam = bl; + } + }else{ + bl = 1; + } + + RETURN_LONG(bl); +Error: + if(ack){ + my_memfree(ack); + } + RETURN_FALSE; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_proto.cpp b/mBot/src/mbot/functions/mb_proto.cpp new file mode 100644 index 0000000..50a8b5f --- /dev/null +++ b/mBot/src/mbot/functions/mb_proto.cpp @@ -0,0 +1,80 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +//protocols +ZEND_FUNCTION(mb_PGetMyStatus) +{ + char* proto=NULL; + long pl=0; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&proto,&pl) == FAILURE || !pl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + pl = CallProtoService(proto,PS_GETSTATUS,0,0); + RETURN_LONG(pl); +} + +ZEND_FUNCTION(mb_PSetMyStatus) +{ + long status=0,pl=0; + char* proto=NULL; + + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + if(mbe->event == MBT_NEWMYSTATUS){ + RETURN_FALSE; + } + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl",&proto,&pl,&status) == FAILURE || !status || !proto){ + PHP_FALSE_AND_ERROR; + } + RETURN_LONG(CallProtoService(proto,PS_SETSTATUS,status,0)==0); +} +ZEND_FUNCTION(mb_PSetMyAwayMsg) +{ + long ml=0,pl=0,status=0; + char* proto=NULL,*msg=NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l",&proto,&pl,&msg,&ml,&status) == FAILURE || !proto || !pl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!status){ + status = CallProtoService(proto,PS_GETSTATUS,0,0); + } + RETVAL_LONG(CallProtoService(proto,PS_SETAWAYMSG,status,(ml)?((LPARAM)msg):(NULL))==0); + return; +} + +ZEND_FUNCTION(mb_PGetCaps) +{ + long pl=0; + long flag=0; + char* proto=NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl",&proto,&pl,&flag) == FAILURE || !pl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + RETVAL_LONG(CallProtoService(proto,PS_GETCAPS,flag,0)); + return; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_pu.cpp b/mBot/src/mbot/functions/mb_pu.cpp new file mode 100644 index 0000000..3cafe34 --- /dev/null +++ b/mBot/src/mbot/functions/mb_pu.cpp @@ -0,0 +1,198 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +/****************************************** + * popups * + ******************************************/ + +void MB_Popup(const char* title,const char* error,unsigned long flags,unsigned long timeout) +{ + MIRANDASYSTRAYNOTIFY mbp={0}; + mbp.cbSize = sizeof(MIRANDASYSTRAYNOTIFY); + mbp.szProto = "MBot"; + mbp.szInfoTitle = (char*)title; + mbp.szInfo = (char*)error; + mbp.dwInfoFlags = flags; + mbp.uTimeout = timeout; + + if(flags == NIIF_ERROR && (DBGetContactSettingByte(NULL,MBOT,"SWOnError",0))){ + ShowWindow(hDialog,SW_SHOW); + SetWindowPos(hDialog,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + } + + CallService(MS_CLIST_SYSTRAY_NOTIFY, (WPARAM)NULL,(LPARAM) &mbp); +} + +void WINAPI MBotPUHelperThread(void* a) +{ + POPUPDATAEX* pde = (POPUPDATAEX*)a; + + if(pde) + { + try{ + PUAddPopUpEx(pde); + }catch(...){ + pde->lchIcon = NULL; + } + my_memfree(pde); + } +} + +ZEND_FUNCTION(mb_PUMsg) +{ + char* txt=NULL; + long tl=0,type=0; + POPUPDATAEX *pd; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l",&txt,&tl,&type) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!(pd = (POPUPDATAEX*)my_malloc(sizeof(POPUPDATAEX)))){ + RETURN_FALSE; + } + + memset(pd,0,sizeof(POPUPDATAEX)); + pd->iSeconds = 0; + + if(type == 2){ + pd->lchIcon = (HICON)hMBotIcon; + }else{ + pd->lchIcon = (type == 2)?LoadIcon(NULL,IDI_ASTERISK):LoadIcon(NULL,IDI_INFORMATION); + } + + strncpy(pd->lpzText,txt,sizeof(pd->lpzText)); + strcpy(pd->lpzContactName,"MBot"); + if(CallFunctionAsync(MBotPUHelperThread,pd)==FALSE){ + my_memfree(pd); + RETURN_FALSE; + } + RETURN_TRUE; +} +ZEND_FUNCTION(mb_PUAdd) +{ + char *cname,*txt; + long cid=0,cl=0,tl=0,bgc=0,txc=0,hico=NULL; + POPUPDATAEX *pd; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss|lll", + &cid,&cname,&cl,&txt,&tl,&bgc,&txc,&hico) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!(pd = (POPUPDATAEX*)my_malloc(sizeof(POPUPDATAEX)))){ + PHP_FALSE_AND_WARNS("Could not allocate memory!"); + } + + memset(pd,0,sizeof(POPUPDATAEX)); + pd->iSeconds = 0; + + pd->lchContact = (HANDLE)cid; + pd->colorText = txc; + pd->colorBack = bgc; + pd->lchIcon = (hico)?((HICON)hico):((HICON)hMBotIcon); + strncpy(pd->lpzContactName,cname,sizeof(pd->lpzContactName)-1); + strncpy(pd->lpzText,txt,sizeof(pd->lpzText)-1); + + if(CallFunctionAsync(MBotPUHelperThread,pd)==FALSE){ + my_memfree(pd); + RETURN_FALSE; + } + RETURN_TRUE; +} + +ZEND_FUNCTION(mb_PUAddEx) +{ + long cid=0,cl=0,tl=0,bgc=0,txc=0,delay=0,param=0,hico=0; + char* cname=NULL,*txt=NULL; + zval* cb = NULL; + sMFSync* mfs = NULL; + POPUPDATAEX *pd; + + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lss|llllzl", + &cid,&cname,&cl,&txt,&tl,&bgc,&txc,&hico,&delay,&cb,¶m) == FAILURE || (cb && cb->type != IS_STRING)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(cb && !zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!(pd = (POPUPDATAEX*)my_malloc(sizeof(POPUPDATAEX)))){ + RETURN_FALSE; + } + + memset(pd,0,sizeof(POPUPDATAEX)); + + if(cb) + { + mfs = (sMFSync*)my_malloc(sizeof(sMFSync)); + if(!mfs)goto Error; + memset(mfs,0,sizeof(sMFSync)); + + if(!mbe->php){goto Error;} + mfs->php = mbe->php; + + strncpy(mfs->pszFunction,cb->value.str.val,sizeof(mfs->pszFunction)); + mfs->pParam = (void*)param; + + pd->PluginWindowProc = (WNDPROC)help_popup_wndproc; + pd->PluginData = mfs; + } + + pd->iSeconds = delay; + pd->lchContact = (HANDLE)cid; + pd->colorText = txc; + pd->colorBack = bgc; + pd->lchIcon = (hico)?((HICON)hico):((HICON)hMBotIcon); + strncpy(pd->lpzContactName,cname,sizeof(pd->lpzContactName)-1); + strncpy(pd->lpzText,txt,sizeof(pd->lpzText)-1); + + if(CallFunctionAsync(MBotPUHelperThread,pd)==FALSE){ + goto Error; + } + RETURN_TRUE; +Error: + my_memfree(pd); + if(mfs)my_memfree(mfs); + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_PUSystem) +{ + char* body; + char* title; + unsigned long tl=0,bl=0,flags=0,timeout=5; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll",&title,&tl,&body,&bl,&flags,&timeout) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!bl || !tl){ + RETURN_FALSE; + } + + MB_Popup(title,body,flags,timeout * 1000); + RETURN_TRUE; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_reg.cpp b/mBot/src/mbot/functions/mb_reg.cpp new file mode 100644 index 0000000..bb2c752 --- /dev/null +++ b/mBot/src/mbot/functions/mb_reg.cpp @@ -0,0 +1,432 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" +#include "../smanager.h" +#include "../cron.h" + +ZEND_FUNCTION(mb_SelfRegister) +{ + long sl=0,event=0,id=0,priority=0x7fffffff; + char cache = 0; + PPHP php; + PHANDLER ph; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(mbe->event != MBT_AUTOLOAD || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|bl",&event,&cache,&priority) == FAILURE){ + PHP_FALSE_AND_WARNS("Invalid parameters given or this function is not allowed now!"); + } + + if(DBGetContactSettingByte(NULL,MBOT,"NoCache",0)){ + cache = 0; + } + + if(php = sman_getbyfile((const char*)mbe->p3)) + { + if(mbe->p2 != NULL){ + sman_recache(php); + } + }else{ + php = sman_register((const char*)mbe->p3,cache); + if(!php){ + RETURN_FALSE; + } + } + + //count bytes + for(sl=0;sl<32;sl++) + { + if(event & (1 << sl)) + { + ph = sman_handler_add(php,event & (1 << sl),priority & 0x7fffffff,(cache)?(MBOT_FLAG_CACHE):(0)); + if(ph){ + id++; + } + } + } + + if(!id){ + sman_unregister(php); + }else{ + lh_flags |= event; + mbe->php = php; + } + RETURN_LONG(id); +} + +ZEND_FUNCTION(mb_SelfSetInfo) +{ + char* desc = NULL; + long dl = 0; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(!mbe->php || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&desc,&dl) == FAILURE){ + PHP_FALSE_AND_WARNS("Script is not registered yet, or wrong parameters given!"); + } + + if(mbe->php->szDescription){ + my_memfree(mbe->php->szDescription); + } + mbe->php->szDescription = my_strdup(desc); + RETURN_LONG(mbe->php->szDescription != NULL); +} + +ZEND_FUNCTION(mb_SelfEnable) +{ + long event; + char enable = 0; + PHANDLER ph; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(!mbe->php || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb",&event,&enable) == FAILURE){ + PHP_FALSE_AND_WARNS("Invalid parameters given or this function is not allowed now!"); + } + + ph = sman_handler_find(mbe->php,event); + if(!ph){ + PHPWSE("Event isn't registered!"); + }else{ + if(enable){ + sman_handler_enable(ph); + }else{ + sman_handler_disable(ph); + } + RETURN_TRUE; + } +} + +ZEND_FUNCTION(mb_SchReg) +{ + extern CSyncList g_cron; + char *cron=NULL,*funct=NULL,*name=NULL; + long cl=0,sl=0,fl=0,nl=0; + char async=0; + char cache=0; + sCronSync* csn = 0; + sCronSync cs; + + sPHPENV* ctx = (sPHPENV*)SG(server_context); + mb_event* mbe = (mb_event*)(ctx->c_param); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|sbb",&name,&nl,&cron,&cl,&funct, + &fl,&cache,&async) == FAILURE || !cl || !fl || !nl) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + //parse cron + if(!cron_parse(cron,&cs.ce)){ + PHP_FALSE_AND_WARNS("You have an error in scheduler syntax!"); + } + strncpy(cs.name,name,sizeof(cs.name)-1); + strncpy(cs.fcn,funct,sizeof(cs.fcn)-1); + + if(mbe->event == MBT_AUTOLOAD){ + mbe->php = sman_register((const char*)mbe->p3,(cache!=0)); + if(!mbe->php){RETURN_FALSE;} + }else if(mbe->php == NULL){ + RETURN_FALSE; + }else{ + sman_incref(mbe->php); + } + + if(async){ + cs.lFlags |= MBOT_FLAG_ASYNC; + } + + csn = (sCronSync*)my_malloc(sizeof(sCronSync)); + if(!csn){ + goto Error; + } + + *csn = cs; + csn->data = mbe->php; + + if(!cron_register(csn)){ + goto Error; + } + cron_calcnext(&csn->ce); + + RETURN_LONG(1); + //error +Error: + sman_decref(mbe->php); + if(csn)my_memfree((void*)csn); + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_SchUnreg) +{ + char* name = NULL; + long nl = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name,&nl) == FAILURE || !nl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + RETURN_LONG(cron_unregister(name)); +} + +ZEND_FUNCTION(mb_SchEnable) +{ + char* name = NULL; + long nl = 0; + zend_bool enable = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb",&name,&nl,&enable) == FAILURE || !nl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(cron_enable(name,enable)); +} + +ZEND_FUNCTION(mb_SchModify) +{ + char* name = NULL; + char* csl = NULL; + long nl = 0; + zend_bool enable = 0; + sCronSync cs; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&name,&nl,&csl,&nl) == FAILURE || !nl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + RETURN_LONG(cron_modify(name,cs.ce)); +} + +ZEND_FUNCTION(mb_SchList) +{ + extern CSyncList g_cron; + + zval *fname; + char *name; + zval *argv[4] = {0}; + zval **args[4] = {0}; + zval *rv = NULL; + long result = 1; + sCronSync *e; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&fname) == FAILURE || fname->type != IS_STRING){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(fname, 0, &name)) + { + php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argument is expected to be a valid callback"); + efree(name); + RETURN_FALSE; + } + + MAKE_STD_ZVAL(argv[0]); + MAKE_STD_ZVAL(argv[1]); + MAKE_STD_ZVAL(argv[2]); + MAKE_STD_ZVAL(argv[3]); + + args[0] = &argv[0]; + args[1] = &argv[1]; + args[2] = &argv[2]; + args[3] = &argv[3]; + + g_cron.Lock(); + e = (sCronSync*)g_cron.m_head; + while(e) + { + if(!(e->lFlags & MBOT_FLAG_DELETE)) + { + ZVAL_STRING(argv[0],(char*)e->name,0); + + if(e->lFlags & MBOT_FLAG_INACTIVE){ + ZVAL_LONG(argv[1],0); + }else{ + ZVAL_LONG(argv[1],e->lTime); + } + ZVAL_LONG(argv[2],e->lLastSpent); + ZVAL_LONG(argv[3],e->lSpent); + + if(call_user_function_ex(CG(function_table),NULL,fname,&rv,4,args,0, NULL TSRMLS_CC) != SUCCESS){ + result = 0; + break; + } + } + e = (sCronSync*)e->next; + } + g_cron.Unlock(); + + efree(name); + FREE_ZVAL(argv[0]); + FREE_ZVAL(argv[1]); + FREE_ZVAL(argv[2]); + FREE_ZVAL(argv[3]); + RETURN_LONG(result); +} + +ZEND_FUNCTION(mb_SysShallDie) +{ + extern CRITICAL_SECTION sm_sync; + + char* script = NULL; + long sl = 0; + PPHP php; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",&script,&sl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!sl){ + php = sman_getbyfile(script); + }else{ + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + php = mbe->php; + } + + if(!php){ + RETURN_FALSE; + }else{ + sman_lock(); + sl = (php->lFlags & MBOT_FLAG_SHALLDIE | MBOT_FLAG_INACTIVE)==0; + sman_unlock(); + } + RETURN_LONG(sl); +} + +ZEND_FUNCTION(mb_SysManageScript) +{ + extern CRITICAL_SECTION sm_sync; + + char* path=NULL; + long action,pl; + long events = 0x0FffFFff; + PPHP php; + PHANDLER ph; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l",&path,&pl,&action,&events) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + php = sman_getbyfile(path); + + if(!php && action<7)goto Error; + switch(action) + { + case 0://disable + for(int i=0;i<32;i++){ + if(events & (1 << i)){ + ph = sman_handler_find(php,1 << i); + if(ph)sman_handler_disable(ph); + } + } + events = TRUE; + break; + case 1://enable + for(int i=0;i<32;i++){ + if(events & (1 << i)){ + ph = sman_handler_find(php,1 << i); + if(ph)sman_handler_enable(ph); + } + } + events = TRUE; + break; + case 2://cache/recache + events = sman_recache(php); + break; + case 3://uncache + events = sman_uncache(php); + break; + case 4://uninstall/unload + events = sman_uninstall(php,events == 1); + break; + case 5://enable file + events = help_enable_script(php,true); + break; + case 6://disable file + events = help_enable_script(php,false); + break; + case 7://install script + events = help_loadscript(path,0); + break; + case 8://is registered + events = php != NULL; + break; + default: + goto Error; + } + RETURN_TRUE; +Error: + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_SysEnumHandlers) +{ + zval *fname; + char *name; + zval *argv[4] = {0}; + zval **args[4] = {0}; + zval *rv = NULL; + long result = 1; + long count = 0; + PHANDLER ph; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&fname) == FAILURE || fname->type != IS_STRING){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(fname, 0, &name)) + { + php_error_docref1(NULL TSRMLS_CC, name, E_WARNING, "First argument is expected to be a valid callback"); + efree(name); + RETURN_FALSE; + } + + MAKE_STD_ZVAL(argv[0]); + MAKE_STD_ZVAL(argv[1]); + MAKE_STD_ZVAL(argv[2]); + MAKE_STD_ZVAL(argv[3]); + + args[0] = &argv[0]; + args[1] = &argv[1]; + args[2] = &argv[2]; + args[3] = &argv[3]; + + for(int i=0;i<32;i++) + { + ph = sman_handler_get(1 << i); + + while(ph) + { + ZVAL_LONG(argv[0],(long)ph); + ZVAL_STRING(argv[1],(char*)ph->php->szFilePath,0); + ZVAL_LONG(argv[2],(1 << i)); + ZVAL_LONG(argv[3],ph->lFlags); + + if(call_user_function_ex(CG(function_table),NULL,fname,&rv,4,args,0, NULL TSRMLS_CC) != SUCCESS){ + result = 0; + goto End; + } + ph = ph->next; + } + } +End: + efree(name); + FREE_ZVAL(argv[0]); + FREE_ZVAL(argv[1]); + FREE_ZVAL(argv[2]); + FREE_ZVAL(argv[3]); + RETURN_LONG(result); +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_search.cpp b/mBot/src/mbot/functions/mb_search.cpp new file mode 100644 index 0000000..3f2fbcf --- /dev/null +++ b/mBot/src/mbot/functions/mb_search.cpp @@ -0,0 +1,154 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +ZEND_FUNCTION(mb_SearchBasic) +{ + zval *cb = NULL; + char *uin = NULL; + char *proto = NULL; + long pl = 0; + long ul = 0; + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + sACKSync* ack; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz",&proto,&pl,&uin,&ul,&cb)==FAILURE || + cb->type != IS_STRING || !pl || !ul){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + memset(ack,0,sizeof(sACKSync)); + + if(!(ack->php = mbe->php))goto Error; + + ack->lType = ACKTYPE_SEARCH; + ack->hContact = NULL; + + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + strncpy(ack->pszProtocol,proto,15); + + if(!g_slist.Add(ack)){goto Error;} + + ack->hProcess = (HANDLE)CallProtoService(proto,PS_BASICSEARCH,0,(LPARAM)uin); + if(!ack->hProcess){ + g_slist.Del(ack); + goto Error; + } + RETURN_LONG(1); +Error: + if(ack)my_memfree(ack); + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_SearchByEmail) +{ + zval *cb=NULL; + char *email=NULL; + char *proto=NULL; + long el = 0; + long pl = 0; + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + sACKSync* ack; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz",&proto,&pl,&email,&el,&cb)==FAILURE || + cb->type != IS_STRING || !pl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + memset(ack,0,sizeof(sACKSync)); + + if(!(ack->php = mbe->php))goto Error; + + ack->lType = ACKTYPE_SEARCH; + ack->hContact = NULL; + + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + strncpy(ack->pszProtocol,proto,15); + + if(!g_slist.Add(ack)){goto Error;} + + ack->hProcess = (HANDLE)CallProtoService(proto,PS_SEARCHBYEMAIL,0,(LPARAM)email); + if(!ack->hProcess){ + g_slist.Del(ack); + goto Error; + } + RETURN_LONG(1); +Error: + if(ack)my_memfree(ack); + RETURN_FALSE; +} + +ZEND_FUNCTION(mb_SearchByName) +{ + zval *cb=NULL; + char *proto=NULL; + long pl = 0; + long tl = 0; + PROTOSEARCHBYNAME psbn={0}; + sACKSync* ack; + + mb_event* mbe = (mb_event*)(((sPHPENV*)SG(server_context))->c_param); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szsss",&proto,&pl,&cb, + &psbn.pszNick,&tl,&psbn.pszFirstName,&tl,&psbn.pszLastName,&tl)==FAILURE || cb->type != IS_STRING || !pl){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + ack = (sACKSync*)my_malloc(sizeof(sACKSync)); + if(!ack){RETURN_FALSE} + memset(ack,0,sizeof(sACKSync)); + + if(!(ack->php = mbe->php))goto Error; + + ack->lType = ACKTYPE_SEARCH; + ack->hContact = NULL; + + strncpy(ack->pszFunction,cb->value.str.val,sizeof(ack->pszFunction)-1); + strncpy(ack->pszProtocol,proto,15); + + if(!g_slist.Add(ack)){goto Error;} + + ack->hProcess = (HANDLE)CallProtoService(proto,PS_SEARCHBYNAME,0,(LPARAM)&psbn); + if(!ack->hProcess){ + g_slist.Del(ack); + goto Error; + } + RETURN_LONG(1); +Error: + if(ack)my_memfree(ack); + RETURN_FALSE; +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_snd.cpp b/mBot/src/mbot/functions/mb_snd.cpp new file mode 100644 index 0000000..d4ea6f0 --- /dev/null +++ b/mBot/src/mbot/functions/mb_snd.cpp @@ -0,0 +1,73 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +/****************************************** + * sounds * + ******************************************/ +ZEND_FUNCTION(mb_SoundPlay) +{ + char* snd = NULL; + long sl = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&snd,&sl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(SkinPlaySound(snd)==0); +} + +ZEND_FUNCTION(mb_SoundAdd) +{ + char *s1=NULL,*s2=NULL,*s3=NULL; + long l1=0,l2=0,l3=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss",&s1,&l1,&s2,&l2,&s3,&l3) == FAILURE)return; + RETURN_LONG(SkinAddNewSound(s1,(const char*)s2,(const char*)s3)==0); +} + +ZEND_FUNCTION(mb_SoundAddEx) +{ + char *s1=NULL,*s2=NULL,*s3=NULL; + long l1=0,l2=0,l3=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss",&s1,&l1,&s2,&l2,&s3,&l3) == FAILURE)return; + RETURN_LONG(SkinAddNewSoundEx(s1,(const char*)s2,(const char*)s3)==0); +} + +ZEND_FUNCTION(mb_SoundSet) +{ + char *s1=NULL,*s2=NULL; + long l1=0,l2=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&s1,&l1,&s2,&l2) == FAILURE)return; + + RETURN_LONG(DBWriteContactSettingString(NULL,"SkinSounds",s1,s2)==0); +} + +ZEND_FUNCTION(mb_SoundDel) +{ + char *s1=NULL; + long l1=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&s1,&l1) == FAILURE)return; + + RETURN_LONG(DBDeleteContactSetting(NULL,"SkinSounds",s1)==0); +} \ No newline at end of file diff --git a/mBot/src/mbot/functions/mb_sys.cpp b/mBot/src/mbot/functions/mb_sys.cpp new file mode 100644 index 0000000..08fef2a --- /dev/null +++ b/mBot/src/mbot/functions/mb_sys.cpp @@ -0,0 +1,786 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "../functions.h" + +/*name: mb_SysLoadModule +params: $name{S:dll path}; +desc: Tries to load a dynamicly linked library (DLL), and returns its handle or 0; +example: +*/ +ZEND_FUNCTION(mb_SysLoadModule) +{ + char* name; + long nl=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&name,&nl) == FAILURE) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + RETURN_LONG((long)LoadLibrary(name)); +} + +/*name: mb_SysUnLoadModule +params: $handle{L:dll handle}; +desc: Releases a module loaded with %mb_SysLoadModule; +example: +*/ +ZEND_FUNCTION(mb_SysUnLoadModule) +{ + HMODULE hm; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&hm) == FAILURE) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + RETURN_LONG(FreeLibrary(hm)); +} + + +/*name: mb_SysCallService +params: $name{S:service name}|$wparam{M:WPARAM},$lparam{M:LPARAM}; +desc: Calls a miranda service specified by $name, passing up to two parameters. mb_SysCallService accepts up to two parameters (0, 1 or 3) and returns the numeric result; +example: +*/ +ZEND_FUNCTION(mb_SysCallService) +{ + zval* lparam=0; + zval* wparam=0; + char* name=0; + void *lp=NULL,*wp=NULL; + long nl=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z!z!",&name,&nl,&wparam,&lparam) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!nl){ + PHPWSE("You can't call an empty service!"); + } + + if(lparam){ + lp = (lparam->type==IS_STRING)?((void*)lparam->value.str.val):((void*)lparam->value.lval); + } + if(wparam){ + wp = (wparam->type==IS_STRING)?((void*)wparam->value.str.val):((void*)wparam->value.lval); + } + + try{ + nl = CallService(name,(WPARAM)wp,(LPARAM)lp); + }catch(...){ + RETURN_FALSE; + } + RETURN_LONG(nl); +} + +ZEND_FUNCTION(mb_SysCallProtoService) +{ + zval* lparam=0; + zval* wparam=0; + char* name=0; + char* proto=0; + long nl=0; + long pl=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z!z!",&proto,&pl,&name,&nl,&wparam,&lparam) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!nl || !pl){ + PHPWSE("Specified $serivce or $protocol name is empty!"); + } + + void* lp = (lparam->type==IS_STRING)?((void*)lparam->value.str.val):((void*)lparam->value.lval); + void* wp = (lparam->type==IS_STRING)?((void*)wparam->value.str.val):((void*)wparam->value.lval); + + try{ + nl = CallProtoService(proto,name,(WPARAM)wp,(LPARAM)lp); + }catch(...){ + RETURN_FALSE; + } + RETURN_LONG(nl); +} + + +ZEND_FUNCTION(mb_SysQuit) +{ + PostQuitMessage(0); +} + +ZEND_FUNCTION(mb_SysCallContactService) +{ + zval* lparam=0; + zval* wparam=0; + char* name=0; + long nl=0; + long cid=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz!z!",&cid,&name,&nl,&wparam,&lparam) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!nl || !cid){ + PHPWSE("Specified $cid or $service name is empty!"); + } + + void* lp = (lparam->type==IS_STRING)?((void*)lparam->value.str.val):((void*)lparam->value.lval); + void* wp = (lparam->type==IS_STRING)?((void*)wparam->value.str.val):((void*)wparam->value.lval); + + try{ + nl = CallContactService((HANDLE)cid,name,(WPARAM)wp,(LPARAM)lp); + }catch(...){ + RETURN_FALSE; + } + RETURN_LONG(nl); +} + +ZEND_FUNCTION(mb_SysGetString) +{ + long str; + char* n=0; + long len = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",&str,&len) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!str){ + PHPWSE("Null pointer given!"); + } + try{ + if(!len){ + len = strlen((const char*)str); + } + n = (char*)emalloc(len+1); + if(!n){ + RETURN_FALSE; + } + memcpy(n,(void*)str,len); + n[len]='\0'; + }catch(...){ + RETURN_FALSE; + } + RETURN_STRINGL(n,len,0); +} + +ZEND_FUNCTION(mb_SysGetNumber) +{ + long ptr; + long type = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l",&ptr,&type) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!ptr){ + PHPWSE("Null pointer given!"); + } + + try + { + if(type == 0 || type == 4){ + RETURN_LONG(*((long*)ptr)); + }else if(type == 2){ + RETURN_LONG(*((short*)ptr)); + }else if(type == 1){ + RETURN_LONG(*((char*)ptr)); + }else{ + RETURN_FALSE; + } + }catch(...){ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysGetPointer) +{ + zval* ptr; + long type = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&ptr) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!ptr){ + PHPWSE("Null pointer given!"); + } + + if(ptr->type == IS_STRING){ + RETURN_LONG(((long)ptr->value.str.val)); + }else{ + RETURN_LONG(((long)&ptr->value.lval)); + } +} + +ZEND_FUNCTION(mb_SysPutString) +{ + long ptr=0; + long len=0; + zval* val=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|l",&ptr,&val,&len) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!ptr){ + PHPWSE("Null pointer given!"); + }else if(val->type != IS_STRING){ + PHPWSE("$str must be a valid string!"); + }else if(len > val->value.str.len){ + PHPWSE("$str is shorter than you think it is!"); + } + + try{ + if(!len){ + strcpy((char*)ptr,val->value.str.val); + }else{ + memcpy((void*)ptr,val->value.str.val,len); + } + RETURN_TRUE; + }catch(...){ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysPutNumber) +{ + long ptr; + long num; + long type = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|l",&ptr,&num,&type) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!ptr){ + PHPWSE("Null pointer given!"); + } + + try + { + if(type == 0 || type == 4){ + *((long*)ptr) = num; + }else if(type == 2){ + *((short*)ptr) = *((short*)&num); + }else if(type == 1){ + *((char*)ptr) = *((char*)&num); + }else{ + RETURN_FALSE; + } + RETURN_LONG(num); + }catch(...){ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysMemCpy) +{ + long p1,p2,amount; + zval* vp2 = NULL; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lzl",&p1,&vp2,&amount) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!p1 || !vp2){ + PHPWSE("Null pointer given!"); + }else if(amount < 0){ + PHPWSE("You can't copy negative number of bytes!"); + } + + if(vp2->type == IS_STRING){ + p2 = (long)vp2->value.str.val; + if(!amount){amount = vp2->value.str.len;} + }else if(vp2->type == IS_LONG){ + p2 = vp2->value.lval; + }else{ + PHPWSE("Wrong parameter type!"); + } + + try{ + memcpy((void*)p1,(void*)p2,(amount)?(amount):(strlen((const char*)p2)+1)); + RETURN_TRUE; + } + catch(...) + { + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysMalloc) +{ + long amount=0; + void* ptr; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&amount) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(amount <= 0){ + PHPWSE("You can't allocate nothing or even less than nothing!"); + } + + try{ + ptr = my_malloc(amount); + if(ptr){memset(ptr,0,amount);} + RETURN_LONG((long)ptr); + }catch(...){ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysGlobalAlloc) +{ + long amount=0; + void* ptr; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&amount) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(amount <= 0){ + PHPWSE("You can't allocate nothing or even less than nothing!"); + } + + try{ + ptr = my_malloc(amount); + if(ptr){memset(ptr,0,amount);} + RETURN_LONG((long)ptr); + }catch(...){ + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysGlobalFree) +{ + long ptr; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&ptr) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!ptr){ + PHPWSE("Null pointer given!"); + } + try{ + my_memfree((void*)ptr); + RETURN_TRUE; + } + catch(...) + { + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysFree) +{ + long ptr; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",&ptr) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!ptr){ + PHPWSE("Null pointer given!"); + } + try{ + efree((void*)ptr); + RETURN_TRUE; + } + catch(...) + { + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysGetProcAddr) +{ + char* module=0; + char* function=0; + long ml=0; + long fl=0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",&module,&ml,&function,&fl) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + RETURN_LONG(help_getprocaddr(module,function)); +} +struct sSysThreadHelper{ + PPHP php; + char* cb; + lphp_vparam vp; + HANDLE hEvent; +}; + + +long WINAPI SysThread(sSysThreadHelper* p) +{ + lphp_vparam vp; + mb_event mbe = {MBT_CALLBACK,0}; + char cb[32]; + + mbe.php = p->php; + strncpy(cb,p->cb,sizeof(cb)-1); + + //make a copy of vp + vp = p->vp; + + if(vp.type == LPHP_STRING){ + vp.data = strdup((const char*)vp.data); + } + + sman_incref(mbe.php); + SetEvent(p->hEvent); + + MBMultiParam(mbe.php,cb,&mbe,"v",&vp); + sman_decref(mbe.php); + + if(vp.type == LPHP_STRING){ + my_memfree(vp.data); + } + return 0; +} + +ZEND_FUNCTION(mb_SysBeginThread) +{ + zval* cb = NULL; + zval* param = NULL; + HANDLE hThread; + DWORD dwID; + sSysThreadHelper shp; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz",&cb,¶m) == FAILURE) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!mbe->php){ + PHPWSE("You can't register a service function here!"); + } + + if(cb->type != IS_STRING || !zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb is expected to be a valid callback function!"); + } + + if(param->type == IS_STRING) + { + shp.vp.type = LPHP_STRING; + shp.vp.data = (void*)param->value.str.val; + shp.vp.length = param->value.str.len; + }else{ + shp.vp.type = LPHP_NUMBER; + shp.vp.data = (void*)param->value.lval; + shp.vp.length = 4; + } + + shp.php = mbe->php; + shp.cb = cb->value.str.val; + shp.hEvent = CreateEvent(0,0,0,0); + if(shp.hEvent == INVALID_HANDLE_VALUE){ + RETURN_FALSE; + } + + hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)SysThread,(void*)&shp,0,&dwID); + if(hThread){ + CloseHandle(hThread); + WaitForSingleObject(shp.hEvent,INFINITE); + CloseHandle(shp.hEvent); + RETURN_LONG(dwID); + }else{ + CloseHandle(shp.hEvent); + RETURN_FALSE; + } +} + +ZEND_FUNCTION(mb_SysCallProc) +{ + extern FILE* dbgout; + void* p_ebp; + void* p_esp; + void* p_res = NULL; + + long fcn=0; + long argc; + zval* params[10]={0}; + void* vp[10]={0}; + + argc = ZEND_NUM_ARGS(); + + if(argc < 2){ + WRONG_PARAM_COUNT; + } + + if(zend_parse_parameters(argc TSRMLS_CC, "l|z!z!z!z!z!z!z!z!z!z!",&fcn, + ¶ms[0],¶ms[1],¶ms[2],¶ms[3],¶ms[4],¶ms[5],¶ms[6],¶ms[7],¶ms[8],¶ms[9]) == FAILURE) + { + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!fcn){ + PHPWSE("Null function pointer given!"); + } + + __asm{ + mov p_ebp, ebp; + mov p_esp, esp; + } + + argc --; + + //fprintf(dbgout,"0x%.8x(",fcn); + for(int i=0;itype == IS_STRING){ + vp[i] = (void*)params[i]->value.str.val; + }else{ + vp[i] = (void*)params[i]->value.lval; + } + + //fprintf(dbgout,"%d,",vp[i]); + } + //fprintf(dbgout,");\r\n"); + //fflush(dbgout); + + try{ + //put the params + p_res = (void*)vp; + __asm{ + mov ecx, argc + mov ebx, ecx + shl ebx, 2d + sub ebx, 4d + add ebx, p_res +PETLA: + push DWORD PTR [ebx] + sub ebx, 4d + dec ecx + jnz PETLA + //call the function + mov ebx, fcn + xor eax, eax + call ebx + mov p_res, eax + //cleanup + mov ebp, p_ebp; + mov esp, p_esp; + } + }catch(...){ + __asm{ + mov ebp, p_ebp; + mov esp, p_esp; + } + PHP_WARN "Execution failed :!"); + + RETURN_FALSE; + } + + RETURN_LONG((long)p_res); +} + +ZEND_FUNCTION(mb_SysCreateService) +{ + extern CSyncList g_svlist; + + zval* name = NULL; + zval* cb = NULL; + sHESync* hfs = NULL; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz",&name,&cb) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!mbe->php){ + PHPWSE("You can't register a service function here!"); + } + + if(name->type != IS_STRING || name->value.str.len < 5){ + PHPWSE("$name must be a valid string of 5-47 characters!"); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb is expected to be a valid callback function!"); + } + + hfs = (sHESync*)my_malloc(sizeof(sHESync)); + if(!hfs){ + PHPWSE("Could not allocate memory!"); + } + memset(hfs,0,sizeof(sHESync)); + + hfs->pCode = help_makefunct((void*)hfs,(void*)help_callsvc); + if(!hfs->pCode){ + my_memfree((void*)hfs); + PHPWSE("Could not create the machine code!"); + } + + sman_incref(mbe->php); + hfs->php = mbe->php; + + strncpy(hfs->pszFunction,cb->value.str.val,sizeof(hfs->pszFunction)-1); + strncpy(hfs->pszSvcName,name->value.str.val,sizeof(hfs->pszSvcName)-1); + hfs->hFunction = (long)CreateServiceFunction(hfs->pszSvcName,(MIRANDASERVICE)hfs->pCode); + if(!hfs->hFunction){ + my_memfree((void*)hfs->pCode); + my_memfree((void*)hfs); + sman_decref(mbe->php); + PHPWSE("Could not create service function!"); + } + g_svlist.Add(hfs); + + RETURN_LONG(hfs->hFunction); +} + +ZEND_FUNCTION(mb_SysHookEvent) +{ + extern CSyncList g_svlist; + + zval* name = NULL; + zval* cb = NULL; + sHESync* hfs = NULL; + mb_event* mbe = (mb_event*)((sPHPENV*)SG(server_context))->c_param; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz",&name,&cb) == FAILURE){ + PHP_FALSE_AND_WARNS(PHP_WARN_INVALID_PARAMS); + } + + if(!mbe->php){ + PHPWSE("You can't register a service function here!"); + } + + if(name->type != IS_STRING || name->value.str.len < 1){ + PHPWSE("$name must be a valid string of 1-47 characters!"); + } + + if(!zend_is_callable(cb,0,NULL)){ + PHPWSE("$cb is expected to be a valid callback function!"); + } + + hfs = (sHESync*)my_malloc(sizeof(sHESync)); + if(!hfs){ + PHPWSE("Could not allocate memory!"); + } + memset(hfs,0,sizeof(sHESync)); + + hfs->pCode = help_makefunct((void*)hfs,(void*)help_callsvc); + if(!hfs->pCode){ + my_memfree((void*)hfs); + PHPWSE("Could not create the machine code!"); + } + + sman_incref(mbe->php); + hfs->php = mbe->php; + + strncpy(hfs->pszFunction,cb->value.str.val,sizeof(hfs->pszFunction)-1); + hfs->hHook = (long)HookEvent(name->value.str.val,(MIRANDAHOOK)hfs->pCode); + + if(!hfs->hHook){ + my_memfree((void*)hfs->pCode); + my_memfree((void*)hfs); + sman_decref(mbe->php); + PHPWSE("Could not create service function!"); + } + g_svlist.Add(hfs); + + RETURN_LONG(hfs->hFunction); +} + +ZEND_FUNCTION(mb_SysEnumProtocols) +{ + PROTOCOLDESCRIPTOR **proto; + int protoCount; + + CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&proto); + if(!protoCount || array_init(return_value)==FAILURE){ + RETURN_FALSE; + } + + for(int i=0;itype != PROTOTYPE_PROTOCOL) continue; + add_index_string(return_value,i,proto[i]->szName,1); + } + return; +} +int xx_enummodules(const char *szModuleName,DWORD ofsModuleName,LPARAM lParam) +{ + cutMemf* mf = (cutMemf*)lParam; + if(*szModuleName){ + mf->write((void*)szModuleName, strlen(szModuleName) + 1); + } + return 0; +} +ZEND_FUNCTION(mb_SysEnumModules) +{ + cutMemf mf; + long ml=0; + char* mod=NULL; + + if(!mf.create(2048)){ + RETURN_FALSE; + } + + if(CallService(MS_DB_MODULES_ENUM,(WPARAM)&mf,(LPARAM)xx_enummodules)!=0){ + RETURN_FALSE; + } + + mf.putc(0); + if(array_init(return_value)==FAILURE){ + RETURN_FALSE; + } + + mod = (char*)mf.getdata(); + ml = 0; + while(*mod) + { + add_index_string(return_value,ml,mod,1); + mod = mod + strlen(mod) + 1; + ml++; + } + mf.close(); +} + +ZEND_FUNCTION(mb_SysGetProfileName) +{ + RETURN_STRING(g_profile,1); +} + +ZEND_FUNCTION(mb_SysTranslate) +{ + char* str = NULL; + long sl = 0; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&str,&sl) == FAILURE){ + PHP_FALSE_AND_ERROR; + } + + str = (char*)CallService(MS_LANGPACK_TRANSLATESTRING,0,(LPARAM)str); + RETURN_STRING((str)?(str):(""),1); +} + +ZEND_FUNCTION(mb_SysGetMirandaDir) +{ + RETURN_STRING(g_root,1); +} \ No newline at end of file diff --git a/mBot/src/mbot/helpers.cpp b/mBot/src/mbot/helpers.cpp new file mode 100644 index 0000000..d5866f4 --- /dev/null +++ b/mBot/src/mbot/helpers.cpp @@ -0,0 +1,662 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "functions.h" +#include "config.h" +#include "m_script.h" +#include "helpers.h" +#include "window.h" + +MBT help_get_event_type(long event_id) +{ + static const MBT ftable[] = + {MBT_PRERECV,MBT_SEND,MBT_PRERECV,MBT_AUTHRECV, + MBT_CALLBACK,MBT_CALLBACK,MBT_CALLBACK, + MBT_NEWMYSTATUS,MBT_COMMAND,MBT_STARTUP,MBT_SHUTDOWN, + MBT_CALLBACK,MBT_CALLBACK,MBT_CALLBACK, + MBT_NOTHING,MBT_FILEIN}; + + static const long ftsize = (sizeof(ftable)/sizeof(MBT)) - 1; + + event_id = fcn_log2(event_id); + + if(event_id < ftsize){ + return ftable[event_id]; + }else{ + return MBT_NOTHING; + } +} + +const char* help_get_funct_name(long event_id) +{ + static const char* ftable[] = + {"mbe_MsgIn","mbe_MsgOut","mbe_UrlIn","mbe_AuthIn", + "mbe_AwayMsgOut","mbe_AwayMsgReq","mbe_CStatus", + "mbe_MyStatus","mbe_Command","mbe_StartUp","mbe_ShutDown", + "mbe_CTyping","mbe_AwayMsgICQ","mbe_Dummy", + "mbe_External","mbe_FileIn", + "irc_GuiIn","irc_GuiOut","irc_RawIn","irc_RawOut","mbe_config",NULL}; + + static const long ftsize = (sizeof(ftable) / sizeof(char*)) - 1; + + event_id = fcn_log2(event_id); + + if(event_id < ftsize){ + return ftable[event_id]; + }else{ + return NULL; + } +} + +void help_callmenu(sMFSync* mfs,WPARAM wParam,LPARAM lParam) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + + if(!mfs)return; + mbe.php = mfs->php; + + sman_inc(mfs->php); + if(mfs->php->szBuffered){ + LPHP_ExecuteScript(mfs->php->szBuffered,mfs->pszFunction,NULL,&mbe, + (mfs->hMenu)?("lll"):("ll"),mfs->pParam,wParam,mfs->hMenu); + }else{ + LPHP_ExecuteFile(mfs->php->szFilePath,mfs->pszFunction,NULL,&mbe, + (mfs->hMenu)?("lll"):("ll"),mfs->pParam,wParam,mfs->hMenu); + } + sman_dec(mfs->php); +} + +/////////////////////////////////////////////////////////// +long help_callsvc(sHESync* hfs,WPARAM wParam,LPARAM lParam) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + const char* output = NULL; + long result = 0; + + if(!hfs)return 0; + mbe.php = hfs->php; + + sman_inc(hfs->php); + if(hfs->php->szBuffered){ + LPHP_ExecuteScript(hfs->php->szBuffered,hfs->pszFunction,&output,&mbe,"ll",wParam,lParam); + }else{ + LPHP_ExecuteFile(hfs->php->szFilePath,hfs->pszFunction,&output,&mbe,"ll",wParam,lParam); + } + sman_dec(hfs->php); + + if(!output){ + return 0; + }else{ + result = strtol(output + 1,NULL,0); + LPHP_Free((void*)output); + return result; + } +} +void* help_makefunct(void* param,void* fcn) +{ + typedef long (*HFFX2)(void* hfs,WPARAM wParam,LPARAM lParam); + struct s_dummy{ + HFFX2 fcn; + }; + + unsigned char* buff = (unsigned char*)my_malloc(32); + unsigned char* bb = buff; + if(!buff){return NULL;} + + *bb++ = 0x55;//push ebp + *bb++ = 0x8B;//mov ebp + *bb++ = 0xEC;//esp + + *bb++ = 0xff;//push + *bb++ = 0x75; + *bb++ = 0x0C;//ebp + 12 + + *bb++ = 0xff;//push + *bb++ = 0x75; + *bb++ = 0x08;//ebp + 8 + + *bb++ = 0x68;//push + *(unsigned long*)(bb) = *(unsigned long*)¶m; bb+=4;//src + *bb++ = 0xBB;//mov ebx, + ((s_dummy*)bb)->fcn = (HFFX2)fcn; bb+=4; + *bb++ = 0xFF; + *bb++ = 0xD3; + *bb++ = 0x83;//add + *bb++ = 0xC4;//esp + *bb++ = 0x0C;//12d + *bb++ = 0x5D;//pop ebp + *bb++ = 0xC3;//ret + return (void*)(buff);//buff; +}; + +__declspec(naked) unsigned long __fastcall fcn_log2(long event_id) +{ + _asm + { + ;function + mov edx, ecx; + or edx, 0 + jz LEND; + xor eax, eax; + jmp ENTRY; +MLOOP: + inc eax; +ENTRY: + shr edx,1 + jnc MLOOP; +LEND: + ret + } +} + +PHPR help_parseoutput(const char* output) +{ + PHPR result = PHPR_UNKNOWN; + const char* tmp; + + if(output){ + tmp = output + strlen(output) + 1; + + if(*tmp == '0' && *(tmp+1)=='\0'){ + result = PHPR_CONTINUE; + }else if(*tmp == '1' && *(tmp+1)=='\0'){ + result = PHPR_BREAK; + }else if(strcmp(tmp,"end")==0){ + result = PHPR_END; + }else if(strcmp(tmp,"drop")==0){ + result = PHPR_DROP; + }else if(strcmp(tmp,"send")==0){ + result = PHPR_SEND; + }else if(strcmp(tmp,"hide")==0){ + result = PHPR_HIDE; + }else if(strcmp(tmp,"store")==0){ + result = PHPR_STORE; + }else if(strcmp(tmp,"failed")==0){ + result = PHPR_FAILED; + } + LPHP_Free((void*)output); + } + return result; +} + +int help_loadscript(const char* script,long recache) +{ + mb_event mbe = {MBT_AUTOLOAD,0}; + mbe.p3 = (void*)script; + mbe.t3 = MBE_LPCSTR; + mbe.t2 = MBE_LPARAM; + mbe.p2 = (void*)recache; + if(sman_getbyfile(script))return FALSE; + return (LPHP_ExecuteFile(script,"mbot_load",NULL,&mbe,NULL)==TRUE); +} + +int help_enable_script(PPHP php,bool enable) +{ + extern CSyncList sm_list; + sm_list.Lock(); + PHANDLER ph; + + for(int i=0;i<32;i++){ + ph = sman_handler_find(php,1 << i); + if(ph){ + if(enable){ + sman_handler_enable(ph); + }else{ + sman_handler_disable(ph); + } + } + } + cron_enable_param(php,enable); + if(enable){ + php->lFlags &= ~(MBOT_FLAG_INACTIVE | MBOT_FLAG_DELETE); + }else{ + php->lFlags |= MBOT_FLAG_INACTIVE; + } + sm_list.Unlock(); + return 0; +} + +long help_autoload(const char* path) +{ + intptr_t fptr = NULL; + _finddata_t fdt = {0}; + long count = 0; + long left = 0; + int result = 0; + char fpath[MAX_PATH + 32]; + char* fname = NULL; + + + + + strncpy(fpath,path,sizeof(fpath)-1); + fname = fpath + (left = strlen(fpath)); + left = (sizeof(fpath)-1) - left; + + strcpy(fname,"*.php"); + + fptr = _findfirst(fpath,&fdt); + if(fptr!=-1) + { + do + { + strncpy(fname,fdt.name,left); + + if(help_loadscript(fpath,0)) + { + count ++; + }else{ + MBotConsoleAppendText("Error loading script: ",0); + MBotConsoleAppendText(fpath); + MBotConsoleAppendText("!\r\nThere might be some error information in the debug file!\r\n",0); + if(DBGetContactSettingByte(NULL,MBOT,"SWOnError",0)){ + MBotShowConsole(0,0); + } + } + + }while(_findnext(fptr,&fdt)!=-1); + _findclose(fptr); + } + + MBHookEvents(); + return count; +} + +long help_getprocaddr(const char* module,const char* name) +{ + HMODULE hModule = NULL; + + if(!(*module) || strcmp(module,"miranda")==0) + { + if(!strcmp(name,"CallService")){ + return ((long)pluginLink->CallService); + }else if(!strcmp(name,"CallProtoService")){ + return ((long)CallProtoService); + }else if(!strcmp(name,"CallContactService")){ + return ((long)CallContactService); + }else if(!strcmp(name,"ServiceExists")){ + return ((long)pluginLink->ServiceExists); + }else{ + return 0; + } + } + else + { + hModule = (HMODULE)GetModuleHandle(module); + return ((hModule)?((long)GetProcAddress(hModule,name)):(0)); + } +} + +int help_fileexists(const char* path,long* fs) +{ + intptr_t fptr = NULL; + _finddata_t fdt = {0}; + + fptr = _findfirst(path,&fdt); + if(fptr!=-1){ + _findclose(fptr); + if((fdt.attrib & _A_SUBDIR)==0){ + *fs = fdt.size; + return 1; + }else{ + return 0; + } + }else{ + return 0; + } +} + +int help_fileexists(const char* path) +{ + intptr_t fptr = NULL; + _finddata_t fdt = {0}; + + fptr = _findfirst(path,&fdt); + if(fptr!=-1){ + _findclose(fptr); + return (fdt.attrib & _A_SUBDIR)==0; + }else{ + return 0; + } +} +int help_filemtime(const char* path,unsigned long* out) +{ + intptr_t fptr = NULL; + _finddata_t fdt = {0}; + + fptr = _findfirst(path,&fdt); + if(fptr!=-1){ + _findclose(fptr); + if((fdt.attrib & _A_SUBDIR)==0){ + *out = fdt.time_write; + return 1; + }else{ + return 0; + } + }else{ + return 0; + } +} + +int help_direxists(const char* path) +{ + intptr_t fptr = NULL; + _finddata_t fdt = {0}; + + fptr = _findfirst(path,&fdt); + if(fptr!=-1){ + _findclose(fptr); + return (fdt.attrib & _A_SUBDIR)!=0; + }else{ + return 0; + } +} + +int help_iswin2k() +{ + static OSVERSIONINFO vi = {sizeof(vi),0}; + GetVersionEx(&vi); + if((vi.dwPlatformId != VER_PLATFORM_WIN32_NT) && (vi.dwMajorVersion < 5)){ + return 0; + }else{ + return 1; + } +} + +const char* help_static_time() +{ + static char buffer[256]; + static SYSTEMTIME st; + + GetLocalTime(&st); + _snprintf(buffer,sizeof(buffer)-1,"%.2d:%.2d:%.2d-%.3d",st.wHour,st.wMinute,st.wSecond,st.wMilliseconds); + return buffer; +} + +LRESULT WINAPI help_popup_wndproc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) + { + case WM_COMMAND: + if(HIWORD(wParam) == STN_CLICKED) + { + sMFSync* mfs = NULL; + mfs = (sMFSync*)CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hWnd,(LPARAM)mfs); + if(mfs){ + help_callmenu(mfs,(WPARAM)PUGetContact(hWnd),0); + } + PUDeletePopUp(hWnd); + return TRUE; + } + break; + case UM_FREEPLUGINDATA: + { + sMFSync* mfs = NULL; + mfs = (sMFSync*)CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hWnd,(LPARAM)mfs); + my_memfree(mfs); + return TRUE; + } + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +HANDLE help_find_by_uin(const char* proto,const char* uin,int numeric) +{ + HANDLE hCid = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + long bKnown = FALSE; + const char *szProto; + const char *szUIN; + const char* szPTR; + wchar_t* wc; + char szBuff[256]; + DBCONTACTGETSETTING dbgcs={0}; + DBVARIANT dbv = {0}; + + if(!hCid){ + return NULL; + } + + do + { + szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hCid,0); + if(!szProto || *szProto != *proto || strcmp(proto,szProto)!=0)continue; + + if(!bKnown){ + szUIN = (char*)CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); + if(!szUIN)return NULL; + bKnown = TRUE; + dbgcs.szModule = proto; + dbgcs.szSetting = szUIN; + dbgcs.pValue = &dbv; + + dbv.cchVal = sizeof(szBuff) - 1; + dbv.pszVal = (char*)szBuff; + dbv.type = DBVT_ASCIIZ; + } + + if(CallService(MS_DB_CONTACT_GETSETTINGSTATIC,(WPARAM)hCid,(LPARAM)&dbgcs)){ + continue; + } + + if(dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR) + { + if(dbv.type == DBVT_WCHAR){ + szPTR = uin; + + for(wc = dbv.pwszVal; *wc && *szPTR; wc++, szPTR++){ + if(*wc != *szPTR)break; + } + + if(!*wc && !*szPTR){ + return hCid; + } + }else if(strcmp(uin, dbv.pszVal) == 0){ + return hCid; + } + + }else if(dbv.type && dbv.type <= 4){ + if(numeric){ + if(dbv.dVal == (DWORD)uin){ + return hCid; + } + }else{ + if(dbv.dVal == strtoul(uin,NULL,0)){ + return hCid; + } + } + } + }while(hCid = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hCid,0)); + + return NULL; +} + +const char* help_cache_php_file(const char* path) +{ + cutMemf in; + cutMemf out; + char ss[MAX_PATH]; + + char* c = NULL; + char* tmp = 0; + long status = 0;//normal + long skipped = 0; + long level = 0;//body + + if(!in.load(mb2u(path),0)) + { + snprintf(ss, sizeof(ss), "%s\\mbot\\scripts\\%s", g_root, path); + if(in.load(mb2u(ss),0))goto OK; + + snprintf(ss, sizeof(ss), "%s\\mbot\\%s", g_root, path); + if(in.load(mb2u(ss),0))goto OK; + + return NULL; + } +OK: + if(!out.create(in.size() + 1)){ + return NULL; + } + + //in.SetEOF(in.size() + 16); + in.setpos(in.size() - 1); + in.putc(0); + + c = (char*)in.getdata(); + c = strstr(c,"') + { + c = strstr(c+2," + pResult - if set, you'll get the struct filled with the result; + NOTE! Remember to release the struct with "fp_freeresult"!; + pCParam - custom parameter, for your own use; use MBOT_GETCPARAM(cparam) to get the pointer; + nCPType - its type {MBOT_NUMBER,MBOT_STRING,MBOT_VOID} if str or num, php will be able to get it too + + *EXAMPLE: + fpExecuteFile("mbot/scripts/my.php","fct1",&mbr,"parameter", + MBOT_STRING,"suf","hello",100,25.6); + *******************************************************************/ +typedef int (*MBOT_ExecuteScript)(const char* pszScript,MBOT_RESULT* pResult, + void* pCParam,MBOT_TYPE nCPType); + +/******************************************************************* + * PARAMETERS: + pszPathname - relative or absolute path of the php file; + pszFcnName - function name can be NULL (whole file will be executed then); + pResult - if set, you'll get the struct filled with the result; + NOTE! Remember to release the struct with "fp_freeresult"!; + pCParam - custom parameter, for your own use; use MBOT_GETCPARAM(cparam) to get the pointer; + nCPType - its type {MBOT_NUMBER,MBOT_STRING,MBOT_VOID} if str or num, php will be able to get it too + pszPTypes - a string containing pformats s-string,u-long,l-long,d-long,q-double,f-float,x-hex long, v - MBOT_VPARAM* + ... - values; + + *EXAMPLE: + fpExecuteScript("mbot/scripts/my.php","fct1",&mbr,"parameter", + MBOT_STRING,"suf","hello",100,25.6); + *******************************************************************/ +typedef int (*MBOT_ExecuteFile)(const char* pszPathname,const char* pszFcnName,MBOT_RESULT* pResult, + void* pCParam,MBOT_TYPE nCPType,const char* pszPTypes,...); + +typedef struct{ + int cbSize; //sizeof(MBOT_LPHP); + const char* pszMBotVersion; + //execution + MBOT_ExecuteScript fpExecuteScript; + MBOT_ExecuteFile fpExecuteFile; + //functions + MBOT_RegisterFunction fpRegister; + MBOT_UnregisterFunction fpUnregister; + //variables + MBOT_NewVar fpNewVar; + MBOT_SetVar fpSetVar; + MBOT_GetVar fpGetVar; + MBOT_DelVar fpDelVar; + //memory + MBOT_Strdup fp_strdup; + MBOT_Malloc fp_malloc; + MBOT_Free fp_free; + MBOT_FreeResult fp_freeresult; +}MBOT_FUNCTIONS; + +/*MS_MBOT_GET_FUNCTIONS +lParam = wParam = 0; +returns a pointer to const MBOT_FUNCTIONS structure; +*/ +#define MS_MBOT_GET_FCN_TABLE "MBot/GetFcnTable" +#endif //M_SCRIPT_H__ \ No newline at end of file diff --git a/mBot/src/mbot/mbot.cpp b/mBot/src/mbot/mbot.cpp new file mode 100644 index 0000000..3580b52 --- /dev/null +++ b/mBot/src/mbot/mbot.cpp @@ -0,0 +1,1750 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "m_script.h" +#include "functions.h" +#include "helpers.h" +#include "window.h" +#include "config.h" +#include "cron.h" + +#pragma comment(lib,"comctl32.lib") +#pragma comment(lib,"/data/src/lib/php5ts") + +/****************************************** + * Imports/Exports * + ******************************************/ +PLUGINLINK* pluginLink; +MBOT_FUNCTIONS mbot_functions; +HINSTANCE hInst = NULL; +/*************** + * HANDLERSs * + ***************/ +CSyncList g_slist; //ack callbacks +CSyncList g_mlist; //menu callbacks +CSyncList g_svlist; //service list; +CSyncList g_msglist; //msg body list; +long lh_count=0; //num of handlers +long lh_flags=0; //reg handlers flags +long lm_flags=0; //reg menus flags +long lMsgSeq=1; //msg sequence id +long lFinished=0; //execution finished +MM_INTERFACE mmi = {0}; +/*********** + * PATHs * + ***********/ +char g_root[MAX_PATH+1]={0}; +char g_profile[MAX_PATH+1]={0}; +/*********** + * HWNDs * + ***********/ +HWND hDialog = NULL; +HWND hConsole = NULL; +HWND hCommandBox = NULL; +HWND hToolbar = NULL; +CRITICAL_SECTION csConsole; +/*********** + * hooks * + ***********/ +HANDLE hHookNE = NULL; +HANDLE hHookNU = NULL; +HANDLE hHookDU = NULL; +HANDLE hHookTY = NULL; +HANDLE hHookACK = NULL; +HANDLE hHookSC = NULL; +HANDLE hHookNMS = NULL; +HANDLE hHookOPT = NULL; +HANDLE hHookSHUT = NULL; +HANDLE hHookICQ = NULL; +HANDLE hHookPBCM = NULL; +HANDLE hHookOKToExit = NULL; +HANDLE hHookPreDB = NULL; +HANDLE hHookNewDB = NULL; +/*********** + * svces * + ***********/ +HANDLE hFunctPSR_MESSAGE = NULL; +HANDLE hFunctPSR_URL = NULL; +HANDLE hFunctPSR_AUTH = NULL; +HANDLE hFunctPSS_AWAYMSG = NULL; +HANDLE hFunctPSR_FILE = NULL; +HANDLE hFunctPSS_MESSAGE = NULL; +HANDLE hFunctGET_FUNCTIONS = NULL; +HANDLE hFunctEXT_TRIGGER = NULL; +HANDLE hFunctCLIST_EVENT = NULL; + +HANDLE hFunctIRCRawIn = NULL; +HANDLE hFunctIRCRawOut = NULL; +HANDLE hFunctIRCGuiIn = NULL; +HANDLE hFunctIRCGuiOut = NULL; +/*********** + * debug * + ***********/ +FILE* dbgout = NULL; +/************ + * MISC * + ************/ +HMODULE hRichModule = NULL; +HICON hMBotIcon = NULL; +DWORD g_mbot_version = PLUGIN_MAKE_VERSION(0,0,3,5); +PCHAR g_mbot_version_s = "0.0.3.5"; + +const static PLUGININFO pluginInfo = +{ + sizeof(PLUGININFO), + "MSP - Miranda Scripting Plugin", + g_mbot_version, + "Miranda Scripting Plugin (MSP), known as mBot, is a multi-purpose plugin providing\ + PHP scripting in Miranda-IM. It lets you write your own very customized scripts as well\ + as use the ones which have been written by others; MSP has many built in Miranda specific\ + functions like sending/receiving messages, file transferring, contacts management, etc;\ + of which all can be used by you. In addition to that there is a task scheduler (with cron\ + syntax) and a simple web server embedded in the application; All that makes MSP a very\ + powerful tool with many applications; MBot is basing on my libphp library which lets you\ + include PHP scripting in your applications with minimal effort! This program uses PHP,\ + freely available from http://www.php.net", + + "Piotr Pawluczuk", + "piotrek@piopawlu.net", + "© 2004-2006 Piotr Pawluczuk", + "http://www.pawluczuk.info", + 0, //not transient + 0 //doesn't replace anything built-in +}; + +//definitions +#ifndef _NOHTTPD_ + long httpd_startup(); + long httpd_shutdown(); +#endif + +int WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + if(fdwReason == DLL_PROCESS_ATTACH) + { + hInst = hinstDLL; + } + else if(fdwReason == DLL_THREAD_DETACH && LPHP_Initialized()) + { + try{ + ts_free_thread(); + }catch(...){ + return TRUE; + } + } + return TRUE; +} + +__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + if(mirandaVersion < PLUGIN_MAKE_VERSION(0,4,0,0)) + { + MessageBox(0,"MBot requires at least Miranda 0.4.0.0!","MBot",MB_ICONINFORMATION); + return NULL; + } + return (PLUGININFO*)&pluginInfo; +} +/****************************************** + * LPHP must have functions * + ******************************************/ +void my_memfree(void* ptr){ + try{ + if(ptr){ + free(ptr); + }else{ + return; + } + }catch(...){ + return; + } +} +void* my_malloc(long amount){ + return malloc(amount); +} +char* my_strdup(const char* str) +{ + char* tmp; + unsigned long lt = strlen(str) + 1; + tmp = (char*)malloc(lt); + if(tmp){ + memcpy(tmp,str,lt); + } + return tmp; +} +void my_freeresult(MBOT_RESULT* mbr){ + if(mbr) + { + my_memfree(mbr->pszOutput); + my_memfree(mbr->pszResult); + } +} + +void my_stdout(const char* str,long length) +{ + extern long lConToFile; + if(hConsole){ + MBotConsoleAppendText(str,0); + } + + if(lConToFile){my_stderr(str,-length-1);} +} + +void my_stderr(const char* str,long length) +{ + extern long lDebugOut; + + if(lDebugOut && hConsole && length>=0){ + MBotConsoleAppendText(str,0); + } + + if(dbgout){ + if(length < 0){ + length = (-length) - 1; + } + fprintf(dbgout,"%s [",help_static_time()); + fwrite(str,1,length,dbgout); + fputc(']',dbgout); + fputc('\n',dbgout); + fflush(dbgout); + } +} + +///////////////////////////////////// +void WINAPI MBBroadcastACKT(void* p) +{ + if(p) + { + mb_ack* ack = (mb_ack*)p; + + SleepEx(50,FALSE); + ack->proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)ack->hContact,0); + + ProtoBroadcastAck( + ack->proto, + ack->hContact, + ACKTYPE_MESSAGE, (ack->result?ACKRESULT_SUCCESS:ACKRESULT_FAILED), + (HANDLE)ack->seq, 0); + + my_memfree((void*)ack); + } +} + +int MBBroadcastACK(HANDLE hContact, bool result) +{ + mb_ack* ack = (mb_ack*)my_malloc(sizeof(mb_ack)); + + if(!lMsgSeq){ + lMsgSeq = 1; + } + + if(ack){ + ack->seq = (lMsgSeq & 0x0FffFFff); + ack->hContact = hContact; + ack->result = result; + CallFunctionAsync(MBBroadcastACKT,ack); + return lMsgSeq++; + }else{ + return NULL; + } +} + +int MB_ExecuteScript(const char* script,MBOT_RESULT* mbr,void* cpv,MBOT_TYPE cpt) +{ + mb_event mbe = {MBT_EXECUTE,0,0,0}; + char* output = NULL; + char* tmp = NULL; + + mbe.p4 = cpv; + mbe.t4 = (MBE)cpt; + + try{ + if(!script || LPHP_ExecuteDirect(script,(mbr)?((const char**)&output):(NULL),&mbe) == FALSE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + return 1; + } + }catch(...){ + return -1; + } + + if(output){ + mbr->pszOutput = strdup(output); + mbr->pszResult = strdup((char*)(output + strlen(output) + 1)); + LPHP_Free(output); + output = NULL; + } + return 0; +} +int MB_ExecuteFile(const char* script,const char* function,MBOT_RESULT* mbr,void* cpv,MBOT_TYPE cpt,const char* ptypes,...) +{ + mb_event mbe = {MBT_EXECUTE,0,0,0}; + const char* output = NULL; + const char* tmp = NULL; + int result = 0; + + if(!script || (mbr && mbr->cbSize!=sizeof(MBOT_RESULT))){ + return 1; + } + + mbe.p4 = cpv; + mbe.t4 = (MBE)cpt; + + try + { + if(function){ + va_list args = NULL; + va_start(args,ptypes); + result = LPHP_ExecuteFileVA(script,function,&output,(void*)&mbe,(function)?(ptypes):(NULL),args); + }else{ + result = LPHP_ExecuteFileVA(script,function,&output,(void*)&mbe,NULL,NULL); + } + }catch(...){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + return -1; + } + + if(output) + { + mbr->pszOutput = strdup(output); + mbr->pszResult = strdup((char*)(output + strlen(output) + 1)); + LPHP_Free((void*)output); + output = NULL; + } + return 0; +} +int MB_GetFunctions(WPARAM wParam, LPARAM lParam) +{ + return (int)&mbot_functions; +} + +int MBExternalTrigger(WPARAM wParam, LPARAM lParam) +{ + MBMultiParamExecute(MB_EVENT_EXTERNAL,NULL,"sl",(wParam!=0)?((void*)wParam):((void*)""),(void*)lParam); + return 0; +} + +int MBCListEventHandle(WPARAM wParam, LPARAM lParam) +{ + CLISTEVENT* cle = (CLISTEVENT*)lParam; + if(cle && cle->lParam && cle->lParam == (LPARAM)cle->hDbEvent) + { + sCLESync* ev = (sCLESync*)cle->lParam; + mb_event mbe = {MBT_CALLBACK,0,0}; + mbe.php = ev->php; + + sman_inc(ev->php); + if(ev->php->szBuffered){ + LPHP_ExecuteScript(ev->php->szBuffered,ev->pszFunction,NULL,&mbe,"ll",cle->hContact,ev->pParam); + }else{ + LPHP_ExecuteFile(ev->php->szFilePath,ev->pszFunction,NULL,&mbe,"ll",cle->hContact,ev->pParam); + } + sman_dec(ev->php); + my_memfree(ev); + } + return 0; +} + +/****************************************** + * Load/Unload * + ******************************************/ +int __declspec(dllexport) Load(PLUGINLINK *link) +{ + PROTOCOLDESCRIPTOR pd = {sizeof(PROTOCOLDESCRIPTOR),0}; + CLISTMENUITEM mi = {0}; + char path[MAX_PATH + 2] = {0}; + char* tmp; + + pd.szName = MBOT; + pd.type = /*PROTOTYPE_FILTER*/ PROTOTYPE_IGNORE; + pluginLink = link; + + if(!DBGetContactSettingByte(NULL,MBOT,"Enable",1)){ + hHookOPT = HookEvent(ME_OPT_INITIALISE,event_opt_initialise); + return 0; + } + + if(AllocConsole()) + { + ShowWindow(GetConsoleWindow(),SW_HIDE); + } + + /////////////////////////////////////////////// + mbot_functions.cbSize = sizeof(mbot_functions); + //memory + mbot_functions.fp_free = my_memfree; + mbot_functions.fp_malloc = my_malloc; + mbot_functions.fp_strdup = my_strdup; + mbot_functions.fp_freeresult = my_freeresult; + //variables + mbot_functions.fpGetVar = LPHP_GetVar; + mbot_functions.fpSetVar = LPHP_SetVar; + mbot_functions.fpDelVar = LPHP_DelVar; + mbot_functions.fpNewVar = LPHP_NewVar; + //execution + mbot_functions.fpExecuteFile = MB_ExecuteFile; + mbot_functions.fpExecuteScript = MB_ExecuteScript; + //register/unregister + mbot_functions.fpRegister = (MBOT_RegisterFunction)LPHP_RegisterFunction; + mbot_functions.fpUnregister = LPHP_UnregisterFunction; + + //profile_name + if(CallService(MS_DB_GETPROFILENAME,(WPARAM)(MAX_PATH-1),(LPARAM)g_profile)){ + MessageBox(NULL,"Could not retrive profile name!",NULL,MB_ICONERROR); + return 1; + } + + //include_path + if(!GetModuleFileName(NULL,path,MAX_PATH)){ + MessageBox(NULL,"Could not retrive application path!",NULL,MB_ICONERROR); + return 1; + } + + for(tmp=path;*tmp;tmp++){ + if(*tmp == '\\')*tmp = '/'; + } + if(!(tmp = strrchr(path,'/'))){ + MessageBox(NULL,"Could not found application path!",NULL,MB_ICONERROR); + return 1; + } + *tmp = 0; + strcpy(g_root,path); + strlwr(g_root); + + //create the window + if(!(hRichModule = LoadLibrary("riched20.dll"))){ + MessageBox(NULL,"Could not init richedit control!",NULL,MB_ICONERROR); + return 1; + } + + if(!LPHP_PreInit(600,256,(LPHP_MALLOC)my_malloc,(LPHP_FREE)my_memfree)){ + MessageBox(0,"Could generate pre-initialize libphp!","MBot",MB_ICONERROR); + return 1; + } + + + if(php_generate_ini()){ + MessageBox(0,"Could generate php.ini!","MBot",MB_ICONERROR); + goto Error; + } + + _snprintf(path,MAX_PATH-4,"%s/mbot/%s",g_root,g_profile); + tmp = strrchr(path,'.'); + if(tmp){ + strcpy(tmp,"_dbg.txt"); + } + dbgout = fopen(path,"a+t"); + + if(LPHP_Init((LPHP_OUTPUT)my_stdout,(LPHP_OUTPUT)my_stderr,(void*)mv_module_entry)!=TRUE){ + MessageBox(0,"Could not initialize php environment!","MBot",MB_ICONERROR); + goto Error; + } + + ////////////////////////////////////// + hMBotIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1)); + ////////////////////////////////////// + CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); + ////////////////////////////////////// + sman_startup(); + _snprintf(path,MAX_PATH-4,"%s/mbot/scripts/autoload/",g_root); + help_autoload(path); + ////////////////////////////////////// + hFunctGET_FUNCTIONS = CreateServiceFunction(MS_MBOT_GET_FCN_TABLE,MB_GetFunctions); + hFunctCLIST_EVENT = CreateServiceFunction(MS_MBOT_CLISTEVENT,MBCListEventHandle); + hFunctEXT_TRIGGER = CreateServiceFunction(MS_MBOT_TRIGGER,MBExternalTrigger); + hFunctPSS_MESSAGE = CreateServiceFunction(MBOT PSS_MESSAGE,MBSendMsg); + ////////////////////////////////////// + hHookOPT = HookEvent(ME_OPT_INITIALISE,event_opt_initialise); + hHookNU = HookEvent(ME_SYSTEM_MODULESLOADED,event_modules_loaded); + hHookOKToExit = HookEvent(ME_SYSTEM_OKTOEXIT,event_oktoexit); + hHookPreDB = HookEvent(ME_DB_EVENT_FILTER_ADD,event_pre_db_event); + hHookNewDB = HookEvent(ME_DB_EVENT_ADDED,event_new_db_event); + CreateServiceFunction(MS_MBOT_SHOWCONSOLE,MBotShowConsole); + CreateServiceFunction(MS_MBOT_REGISTERIRC,MBIRCRegister); + ////////////////////////////////////// + mi.cbSize=sizeof(mi); + mi.position = - 0x7FFFFFFF; + mi.flags = 0; + mi.hIcon = hMBotIcon; + mi.pszPopupName = "MBot"; + mi.pszName="Show MBot Console"; + mi.pszService= MS_MBOT_SHOWCONSOLE; + CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); + ////////////////////////////////////// + hDialog = CreateDialog(hInst,MAKEINTRESOURCE(IDD_MBOTCONSOLE),NULL,(DLGPROC)MBotDlgProc); + ////////////////////////////////////// + if(!hDialog){ + MessageBox(0,"Could not create MBot Console!","MBot",MB_ICONERROR); + goto Error; + } + + if(DBGetContactSettingByte(NULL,MBOT,"SWOnStartup",0)){ + ShowWindow(hDialog,SW_SHOW); + } + return 0; +Error: + LPHP_DeInit(); + + if(hMBotIcon){ + DeleteObject((HGDIOBJ)hMBotIcon); + hMBotIcon = NULL; + } + if(hConsole){ + DestroyWindow(hConsole); + hConsole = NULL; + } + if(hRichModule){ + FreeModule(hRichModule); + hRichModule = NULL; + } + return 1; +} + +void sync_g_mlist(sMFSync* mi) +{ + my_memfree(mi->fpFunction); + my_memfree(mi); +} + +int __declspec(dllexport) Unload(void) +{ + MBLOGEX("Shutdown sequence started!"); + + MBLOGEX("Shutting down crond..."); + cron_shutdown(); + +#ifndef _NOHTTPD_ + MBLOGEX("Shutting down HTTPD..."); + httpd_shutdown(); +#endif + + MBLOGEX("Stopping libphp..."); + LPHP_DeInit(); + + MBLOGEX("Destroying console window..."); + DestroyWindow(hDialog); + hDialog = NULL; + hConsole = NULL; + + MBLOGEX("Releasing g_mlist..."); + g_mlist.Release((SYNC_RELEASE)sync_g_mlist); + MBLOGEX("Releasing g_slist..."); + g_slist.Release((SYNC_RELEASE)my_memfree); + + + MBLOGEX("Releasing crond tasks..."); + cron_release(); + MBLOGEX("Releasing config tree..."); + cSettings.Free(); + if(hRichModule){ + MBLOGEX("Releasing riched20.dll..."); + FreeModule(hRichModule); + } + MBLOGEX("Destroying global functions..."); + DestroyServiceFunction(MBOT PSS_MESSAGE); + DestroyServiceFunction(MS_MBOT_GET_FCN_TABLE); + MBLOGEX("Shutting down script manager..."); + sman_shutdown(); + MBLOGEX("Releasing console critical section..."); + DeleteCriticalSection(&csConsole); + + MBLOGEX("Shutdown sequence finished!"); + + if(dbgout){ + fclose(dbgout); + } + + FreeConsole(); + + return 0; +} +/****************************************** + * events * + ******************************************/ +int event_contact_new(WPARAM wParam, LPARAM lParam) +{ + CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)wParam,(LPARAM)(char*)MBOT); + return 0; +} + +int event_oktoexit(WPARAM wParam,LPARAM lParam) +{ + UNHOOK(hHookOKToExit); + + if(!lFinished) + { + MBUnHookEvents(); + if(lh_flags & MB_EVENT_SHUTDOWN){ + MBNoParamExecute(MB_EVENT_SHUTDOWN); + } + + lFinished = 1; + } + return 0; +} + +int event_contact_del(WPARAM wParam, LPARAM lParam) +{ + CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)wParam,(LPARAM)(char*)MBOT); + return 0; +} + +int MBUnHookEvents() +{ + if(lh_flags & MB_EVENT_MSG_IN){DestroyServiceFunction(MBOT PSR_MESSAGE);} + if(lh_flags & MB_EVENT_URL_IN){DestroyServiceFunction(MBOT PSR_URL);} + if(lh_flags & MB_EVENT_AUTH_IN){DestroyServiceFunction(MBOT PSR_AUTH);} + if(lh_flags & MB_EVENT_AWAY_MSG_OUT){DestroyServiceFunction(MBOT PSS_AWAYMSG);} + if(lh_flags & MB_EVENT_FILE_IN){DestroyServiceFunction(MBOT PSR_FILE);} + UNHOOK(hHookNMS) + UNHOOK(hHookSC) + UNHOOK(hHookTY) + UNHOOK(hHookSHUT) + UNHOOK(hHookICQ) + + UNHOOK(hHookACK) + UNHOOK(hHookNU) + UNHOOK(hHookDU) + UNHOOK(hHookPBCM) + return 0; +} + +int MBHookEvents() +{ + if((lh_flags & MB_EVENT_MSG_IN) && !(hFunctPSR_MESSAGE)){ + hFunctPSR_MESSAGE = CreateServiceFunction(MBOT PSR_MESSAGE,MBRecvMsg); + } + if((lh_flags & MB_EVENT_URL_IN) && !(hFunctPSR_URL)){ + hFunctPSR_URL = CreateServiceFunction(MBOT PSR_URL,MBRecvUrl); + } + if((lh_flags & MB_EVENT_AUTH_IN) && !(hFunctPSR_AUTH)){ + hFunctPSR_AUTH = CreateServiceFunction(MBOT PSR_AUTH,MBRecvAuth); + } + if((lh_flags & MB_EVENT_AWAY_MSG_OUT) && !(hFunctPSS_AWAYMSG)){ + hFunctPSS_AWAYMSG = CreateServiceFunction(MBOT PSS_AWAYMSG,MBSendAwayMsg); + } + if((lh_flags & MB_EVENT_FILE_IN) && !(hFunctPSR_FILE)){ + hFunctPSR_FILE = CreateServiceFunction(MBOT PSR_FILE,MBRecvFile); + } + if((lh_flags & MB_EVENT_USER_TYPING) && !(hHookTY)){ + hHookTY = HookEvent(ME_PROTO_CONTACTISTYPING,event_typing); + } + if((lh_flags & MB_EVENT_NEW_CSTATUS) && !(hHookSC)){ + hHookSC = HookEvent(ME_DB_CONTACT_SETTINGCHANGED,event_contact_changed); + } + if((lh_flags & MB_EVENT_NEW_MYSTATUS) && !(hHookNMS)){ + hHookNMS = HookEvent(ME_CLIST_STATUSMODECHANGE,event_new_mystatus); + } + if((lh_flags & MB_EVENT_AWAY_MSG_ICQ) && !(hHookICQ)){ + hHookICQ = HookEvent("ICQ/StatusMsgReq",event_icq_awayreq); + } + if(!hHookPBCM){ + hHookPBCM = HookEvent(ME_CLIST_PREBUILDCONTACTMENU,event_contact_menu_prebuild); + } + + //hook irc stuff + if(!hFunctIRCGuiIn) + { + hFunctIRCGuiIn = CreateServiceFunction(MS_MBOT_IRC_GUI_IN,MBIRCGuiIn); + hFunctIRCGuiOut = CreateServiceFunction(MS_MBOT_IRC_GUI_OUT,MBIRCGuiOut); + hFunctIRCRawIn = CreateServiceFunction(MS_MBOT_IRC_RAW_IN,MBIRCRawIn); + hFunctIRCRawOut = CreateServiceFunction(MS_MBOT_IRC_RAW_OUT,MBIRCRawOut); + } + + return 0; +} + +int event_modules_loaded(WPARAM wParam, LPARAM lParam) +{ + RegisterContacts(); + UnhookEvent(hHookNU);//unhook mod-loaded + hHookNU = HookEvent(ME_DB_CONTACT_ADDED,event_contact_new); + hHookDU = HookEvent(ME_DB_CONTACT_DELETED,event_contact_del); + hHookACK = HookEvent(ME_PROTO_ACK,event_msg_ack); + + MBotGetPrefString("CmdTag",pszCmdTag,2,"m>"); + MBotGetPrefString("ScriptTag",pszPhpTag,2,"?>"); + + lCmdTagLen = strlen(pszCmdTag); + lPhpTagLen = strlen(pszPhpTag); + + if(lh_flags & MB_EVENT_STARTUP){ + MBNoParamExecute(MB_EVENT_STARTUP); + } + MBHookEvents(); + + if(!DBGetContactSettingByte(NULL,MBOT,"NoScheduler",0) && cron_initialize()){ + cron_startup(); + } + + CallService(MS_SYSTEM_GET_MMI,0,(LPARAM)&mmi); + + //launch server +#ifndef _NOHTTPD_ + if(DBGetContactSettingByte(NULL,MBOT,"WWWEnabled",1)){ + httpd_startup(); + } +#endif + return 0; +} + +int event_contact_menu_prebuild(WPARAM wParam,LPARAM lParam) +{ + if(lm_flags & MBOT_FLAG_WANTPREBUILD) + { + sMFSync* mfs = (sMFSync*)g_mlist.m_head; + mb_event mbe = {MBT_CALLBACK,0,0}; + mbe.php = mfs->php; + + while(mfs) + { + if(*(mfs->pszPrebuild)) + { + sman_inc(mfs->php); + if(mfs->php->szBuffered){ + LPHP_ExecuteScript(mfs->php->szBuffered,mfs->pszPrebuild,NULL,&mbe,"ll",wParam,mfs->hMenu); + }else{ + LPHP_ExecuteFile(mfs->php->szFilePath,mfs->pszPrebuild,NULL,&mbe,"ll",wParam,mfs->hMenu); + } + sman_dec(mfs->php); + } + mfs = (sMFSync*)mfs->next; + } + } + return 0; +} + +int event_contact_changed(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING* dbws = (DBCONTACTWRITESETTING*)lParam; + if(dbws && dbws->value.type && !mbot_our_own(dbws->szSetting)) + { + if(*dbws->szSetting == 'S' && strcmp(dbws->szSetting,MBOT_CFG_STATUS)==0) + { + MBGenericSettChanged((HANDLE)wParam,dbws,MB_EVENT_NEW_CSTATUS); + } + } + return 0; +} + +int event_icq_awayreq(WPARAM mode,LPARAM uin) +{ + HANDLE hContact = help_find_by_uin("ICQ",(const char*)uin,1); + MBMultiParamExecute(MB_EVENT_AWAY_MSG_ICQ,NULL,"uuuu",(void*)hContact, + (void*)(DBGetContactSettingByte(hContact,"CList","NotOnList",1)==0),(void*)mode,(void*)uin); + return 0; +} + +int handle_ack_awaymsg(ACKDATA* ack,sACKSync* cs) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + mbe.php = cs->php; + + sman_inc(cs->php); + if(cs->php->szBuffered){ + LPHP_ExecuteScript(cs->php->szBuffered,cs->pszFunction,NULL,&mbe,"lls", + ack->hContact,ack->result == ACKRESULT_SUCCESS,ack->lParam); + }else{ + LPHP_ExecuteFile(cs->php->szFilePath,cs->pszFunction,NULL,&mbe,"lls", + ack->hContact,ack->result == ACKRESULT_SUCCESS,ack->lParam); + } + sman_dec(cs->php); + return 1; +} + +int handle_ack_message(ACKDATA* ack,sACKSync* cs) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + mbe.php = cs->php; + + sman_inc(cs->php); + if(cs->php->szBuffered){ + LPHP_ExecuteScript(cs->php->szBuffered,cs->pszFunction,NULL,&mbe,"lll", + ack->hContact,ack->result == ACKRESULT_SUCCESS,cs->lParam); + }else{ + LPHP_ExecuteFile(cs->php->szFilePath,cs->pszFunction,NULL,&mbe,"lll", + ack->hContact,ack->result == ACKRESULT_SUCCESS,cs->lParam); + } + sman_dec(cs->php); + return 1; +} + +int handle_ack_file(ACKDATA* ack,sACKSync* cs) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + mbe.php = cs->php; + sman_inc(cs->php); + //file_cb($fth,$ack,$param,$pack) + + if(ack->result == ACKRESULT_DATA){ + PROTOFILETRANSFERSTATUS *fts=(PROTOFILETRANSFERSTATUS*)ack->lParam; + sFileInfo* fi = (sFileInfo*)cs->pszProtocol; + bool first = fi->numFiles == 0; + + fi->numFiles = fts->totalFiles; + fi->curFile = fts->currentFileNumber; + fi->bytesTotal = fts->totalBytes; + fi->bytesDone = fts->totalProgress; + fi->curDone = fts->currentFileProgress; + fi->curSize = fts->currentFileSize; + fi->curTime = fts->currentFileTime; + if(!first){ + return 0; + }else{ + ack->result = 101; + } + }; + + if(cs->php->szBuffered){ + LPHP_ExecuteScript(cs->php->szBuffered,cs->pszFunction,NULL,&mbe,"llll", + cs->hProcess,ack->hContact,ack->result,cs->lParam); + }else{ + LPHP_ExecuteFile(cs->php->szFilePath,cs->pszFunction,NULL,&mbe,"llll", + cs->hProcess,ack->hContact,ack->result,cs->lParam); + } + sman_dec(cs->php); + return (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED); +} + +int handle_ack_search(ACKDATA* ack,sACKSync* cs) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + PROTOSEARCHRESULT* sr = (PROTOSEARCHRESULT*)ack->lParam; + mbe.php = cs->php; + + sman_inc(cs->php); + + mbe.p3 = (void*)sr; + mbe.t3 = MBE_SRESULT; + mbe.p2 = (void*)ack; + mbe.t2 = MBE_ACK; + + if(ack->result == ACKRESULT_DATA) + { + if(cs->php->szBuffered){ + LPHP_ExecuteScript(cs->php->szBuffered,cs->pszFunction,NULL,&mbe,"lssss", + 2,sr->nick,sr->firstName,sr->lastName,sr->email); + }else{ + LPHP_ExecuteFile(cs->php->szFilePath,cs->pszFunction,NULL,&mbe,"lssss", + 2,sr->nick,sr->firstName,sr->lastName,sr->email); + } + + sman_dec(cs->php); + return 0; + }else{ + if(cs->php->szBuffered){ + LPHP_ExecuteScript(cs->php->szBuffered,cs->pszFunction,NULL,&mbe,"lllll", + (ack->result == ACKRESULT_SUCCESS),0,0,0,0); + }else{ + LPHP_ExecuteFile(cs->php->szFilePath,cs->pszFunction,NULL,&mbe,"lllll", + (ack->result == ACKRESULT_SUCCESS),0,0,0,0); + } + sman_dec(cs->php); + return 1; + } +} + +int event_msg_ack(WPARAM wParam, LPARAM lParam) +{ + ACKDATA* ack = (ACKDATA*)lParam; + sACKSync* s; + sMsgSync* ms; + int result = 0; + + if(!ack){ + return 0; + } + + if(ack->type == ACKTYPE_AWAYMSG && ack->result == ACKRESULT_SENTREQUEST + && (lh_flags & MB_EVENT_AWAY_MSG_REQ)) + { + MBMultiParamExecute(MB_EVENT_AWAY_MSG_REQ,NULL,"uu", + (void*)ack->hContact,(void*)(DBGetContactSettingByte(ack->hContact,"CList","NotOnList",1)==0)); + } + else if(g_slist.m_count || g_msglist.m_count) + { + if(ack->result != ACKRESULT_SUCCESS && g_msglist.m_count) + { + g_msglist.Lock(); + ms = (sMsgSync*)g_msglist.m_head; + while(ms) + { + if(ms->hContact == ack->hContact && ms->hProcess == ack->hProcess) + { + g_msglist.DelLocked(ms); + my_memfree(ms->new_body); + my_memfree(ms->old_body); + my_memfree(ms); + break; + } + ms = (sMsgSync*)ms->next; + } + g_msglist.Unlock(); + } + + g_slist.Lock(); + s = (sACKSync*)g_slist.m_head; + while(s) + { + if(s->lType == ack->type && s->hProcess == ack->hProcess && + s->hContact == ack->hContact) + { + g_slist.Unlock(); + switch(ack->type) + { + case ACKTYPE_AWAYMSG: result = handle_ack_awaymsg(ack,s);break; + case ACKTYPE_SEARCH: result = handle_ack_search(ack,s);break; + case ACKTYPE_MESSAGE: result = handle_ack_message(ack,s);break; + case ACKTYPE_FILE: result = handle_ack_file(ack,s);break; + default: + break; + } + + if(result == 1){ + g_slist.Del(s); + my_memfree(s); + } + + return 0; + } + s = (sACKSync*)s->next; + } + g_slist.Unlock(); + } + return 0; +} + +int MBNoParamExecute(long ev_id) +{ + int result = 0; + const char* output = NULL; + mb_event mbe={MBT_SHUTDOWN,0,0,0}; + + PHANDLER ph = sman_handler_get(ev_id); + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + } + + mbe.php = ph->php; + + sman_inc(ph->php); + if(ph->php->szBuffered){ + result = LPHP_ExecuteScript(ph->php->szBuffered,ph->szFcnName,&output,&mbe,NULL); + }else{ + result = LPHP_ExecuteFile(ph->php->szFilePath,ph->szFcnName,&output,&mbe,NULL); + } + sman_dec(ph->php); + + if(result!=TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + if(help_parseoutput(output)!=PHPR_CONTINUE){ + break; + } +Next: + ph = ph->next; + } + return 0; +} + +int MBMultiParam(PPHP php,const char* fcn,mb_event* mbe,const char* params,...) +{ + int result = 0; + const char* output = NULL; + va_list args; + + va_start(args,params); + + sman_inc(php); + if(php->szBuffered){ + result = LPHP_ExecuteScriptVA(php->szBuffered,fcn,(mbe->lFlags&MBOT_FLAG_NOOUTPUT)?(NULL):(&output),mbe,params,args); + }else{ + result = LPHP_ExecuteFileVA(php->szFilePath,fcn,(mbe->lFlags&MBOT_FLAG_NOOUTPUT)?(NULL):(&output),mbe,params,args); + } + sman_dec(php); + + if(result!=TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + return 0; + } + + if(mbe->lFlags&MBOT_FLAG_NOOUTPUT){ + return 1; + }else{ + result = (int)help_parseoutput(output); + return result; + } +} + +int MBMultiParamExecute(long ev_id,mb_event* me,const char* params,...) +{ + int result = 0; + const char* output = NULL; + va_list args; + + mb_event mbe={MBT_NOTHING,0}; + + va_start(args,params); + + if(!me){ + mbe.event = help_get_event_type(ev_id); + me = &mbe; + } + + PHANDLER ph = sman_handler_get(ev_id); + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + } + me->php = ph->php; + + sman_inc(ph->php); + if(ph->php->szBuffered){ + result = LPHP_ExecuteScriptVA(ph->php->szBuffered,ph->szFcnName,&output,me,params,args); + }else{ + result = LPHP_ExecuteFileVA(ph->php->szFilePath,ph->szFcnName,&output,me,params,args); + } + sman_dec(ph->php); + + if(result!=TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + if((result = (int)help_parseoutput(output)) != (int)PHPR_CONTINUE){ + break; + } +Next: + ph = ph->next; + } + return result; +} + +int event_new_mystatus(WPARAM wParam, LPARAM lParam) +{ + MBMultiParamExecute(MB_EVENT_NEW_MYSTATUS,NULL,"su",(void*)lParam,(void*)wParam); + return 0; +} + +int event_typing(WPARAM wParam, LPARAM lParam) +{ + MBMultiParamExecute(MB_EVENT_USER_TYPING,NULL,"ll",(void*)wParam,(void*)lParam); + return 0; +} + +int event_new_db_event(WPARAM wParam, LPARAM lParam) +{ + HANDLE hc = (HANDLE)wParam; + DBEVENTINFO dbei={0}; + CLISTEVENT cle={0}; + sMsgSync* ms; + + if(!g_msglist.m_count)return 0; + + dbei.cbSize=sizeof(dbei); + dbei.cbBlob=0; + CallService(MS_DB_EVENT_GET,lParam,(LPARAM)&dbei); + if(!(dbei.flags&DBEF_SENT) || dbei.eventType)return 0; + + g_msglist.Lock(); + ms = (sMsgSync*)g_msglist.m_head; + while(ms) + { + if(ms->hContact == hc && ms->timestamp == dbei.timestamp) + { + g_msglist.DelLocked(ms); + my_memfree(ms->new_body); + my_memfree(ms); + break; + } + ms = (sMsgSync*)ms->next; + } + g_msglist.Unlock(); + return 0; +} + +int event_pre_db_event(WPARAM wParam, LPARAM lParam) +{ + HANDLE hc = (HANDLE)wParam; + DBEVENTINFO *dbev = (DBEVENTINFO*)lParam; + sMsgSync* ms; + if(!g_msglist.m_count)return 0; + else{ + g_msglist.Lock(); + ms = (sMsgSync*)g_msglist.m_head; + while(ms) + { + if(ms->old_body && ms->hContact == hc && (*ms->old_body == *dbev->pBlob) && !strcmp(ms->old_body,(const char*)dbev->pBlob)) + { + if(!ms->new_body){ + my_memfree(ms->old_body); + g_msglist.DelLocked(ms); + my_memfree(ms); + g_msglist.Unlock(); + return 1; + }else{ + dbev->pBlob = (unsigned char*)ms->new_body; + dbev->cbBlob = strlen(ms->new_body) + 1; + my_memfree(ms->old_body); + ms->old_body = NULL; + ms->timestamp = dbev->timestamp; + } + break; + } + ms = (sMsgSync*)ms->next; + } + g_msglist.Unlock(); + } + return 0; +} + +int event_opt_initialise(WPARAM wParam, LPARAM lParam) +{ + static unsigned int adv_options[] = {IDC_ADV1,IDC_ADVCMDTAG,IDC_ADVLABEL1,IDC_ADVLABEL2,IDC_ADVSCRIPTTAG}; + + OPTIONSDIALOGPAGE odp = { 0 }; + + odp.cbSize = sizeof(odp); + odp.position = 2000; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = Translate("MBot"); + odp.pszGroup = Translate("Plugins"); + odp.pfnDlgProc = MBotDlgProcOption; + odp.hIcon = hMBotIcon; + odp.expertOnlyControls = adv_options; + odp.nExpertOnlyControls = sizeof(adv_options) / sizeof(unsigned int); + odp.flags = ODPF_BOLDGROUPS; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp); + + return 0; +} + +/****************************************** + * generic handlers * + ******************************************/ +int MBGenericSettChanged(HANDLE hContact, DBCONTACTWRITESETTING* dbws, long ev_id) +{ + int bNotOnList = 0; + int first = 0; + int result = 0; + const char* output = NULL; + lphp_vparam vp; + DBVARIANT* dbv; + + if(!hContact){ + return 0; + } + + mb_event mbe={MBT_CSCHANGED,(WPARAM)hContact,(LPARAM)dbws,0,0}; + PHANDLER ph = sman_handler_get(ev_id); + + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + }else{ + if(!(first++)) + { + bNotOnList = DBGetContactSettingByte(hContact,"CList","NotOnList",0); + dbv = (DBVARIANT*)&dbws->value; + mbe.t3 = MBE_DBVARIANT; + mbe.p3 = (void*)dbv; + + if(dbv->type == DBVT_BLOB){ + vp.type = LPHP_STRING; + vp.data = dbv->pbVal; + vp.length = dbv->cpbVal; + }else if(dbv->type == DBVT_ASCIIZ){ + vp.type = LPHP_STRING; + vp.data = dbv->pszVal; + vp.length = strlen((const char*)dbv->pszVal); + }else{ + vp.type = LPHP_NUMBER; + vp.length = 4; + if(dbv->type == DBVT_BYTE){ + vp.data = ((void*)((long)dbv->bVal)); + }else if(dbv->type == DBVT_WORD){ + vp.data = ((void*)((long)dbv->wVal)); + }else{ + vp.data = ((void*)((long)dbv->lVal)); + } + } + } + } + + mbe.php = ph->php; + + sman_inc(ph->php); + if(ph->php->szBuffered){ + result = LPHP_ExecuteScript(ph->php->szBuffered,ph->szFcnName,&output,&mbe,"llsslv", + hContact,bNotOnList==0,dbws->szModule,dbws->szSetting,dbws->value.type,&vp); + }else{ + result = LPHP_ExecuteFile(ph->php->szFilePath,ph->szFcnName,&output,&mbe,"llsslv", + hContact,bNotOnList==0,dbws->szModule,dbws->szSetting,dbws->value.type,&vp); + } + sman_dec(ph->php); + + if(result!=TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + + if(help_parseoutput(output)!=PHPR_CONTINUE){ + break; + } +Next: + ph = ph->next; + } + return 0; +} + +int MBGenericRecv(WPARAM wParam, LPARAM lParam,long ev_id,mb_event* ce) +{ + const char* output = NULL; + int first = 0; + int result = 0; + int bNotOnList = 0; + PHPR ret_val = PHPR_UNKNOWN; + string ss; + CCSDATA *pccsd = (CCSDATA *)lParam; + PROTORECVEVENT *ppre = (PROTORECVEVENT*)pccsd->lParam; + + mb_event mbe = {MBT_PRERECV,wParam,lParam,0}; + + PHANDLER ph = sman_handler_get(ev_id); + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + }else{ + if(!(first++)){ + bNotOnList = DBGetContactSettingByte(pccsd->hContact,"CList","NotOnList",0); + mbe.t1 = MBE_SSTRING; + mbe.p1 = (void*)&ss; + if(!ce){ + ce = &mbe; + } + } + } + + ce->php = ph->php; + + sman_inc(ph->php); + if(ph->php->szBuffered) + { + result = LPHP_ExecuteScript(ph->php->szBuffered,ph->szFcnName,&output,(void*)ce,"usuu", + pccsd->hContact,ppre->szMessage,ppre->timestamp,(bNotOnList==0)); + }else{ + result = LPHP_ExecuteFile(ph->php->szFilePath,ph->szFcnName,&output,(void*)ce,"usuu", + pccsd->hContact,ppre->szMessage,ppre->timestamp,(bNotOnList==0)); + } + sman_dec(ph->php); + + if(result != TRUE) + { + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + + ret_val = help_parseoutput(output); + + if(ret_val == PHPR_DROP || ret_val == PHPR_HIDE){ + return 1; + }else if(ret_val != PHPR_CONTINUE){ + break; + } + + if((mbe.lFlags & MBOT_FLAG_BODY_CHANGED) && ss.size()){ + ppre->szMessage = (char*)ss.data(); + } +Next: + ph = ph->next; + } + + if(ret_val == PHPR_STORE) + { + ppre->flags |= PREF_CREATEREAD; + } + + return CallService(MS_PROTO_CHAINRECV, wParam,(LPARAM)pccsd); +} +/****************************************** + * service functions * + ******************************************/ +int MBRecvMsg(WPARAM wParam, LPARAM lParam){ + return MBGenericRecv(wParam,lParam,MB_EVENT_MSG_IN); +} +int MBRecvUrl(WPARAM wParam, LPARAM lParam){ + return MBGenericRecv(wParam,lParam,MB_EVENT_URL_IN); +} +int MBRecvFile(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *pccsd = (CCSDATA *)lParam; + PROTORECVEVENT* pre = (PROTORECVEVENT*)pccsd->lParam; + PHPR result = PHPR_UNKNOWN; + char* desc; + char* file; + + mb_event mbe={MBT_FILEIN,wParam,lParam,0}; + + file = (char*)(pre->szMessage + sizeof(DWORD)); + desc = file + strlen(file)+1; + + result = (PHPR)MBMultiParamExecute(MB_EVENT_FILE_IN,&mbe,"lssl",pccsd->hContact, + (void*)desc,(void*)file,(void*)pre->timestamp); + + if(result == PHPR_DROP || result == PHPR_HIDE){ + return 1; + }else{ + return CallService(MS_PROTO_CHAINRECV,wParam,lParam); + } +} +int MBRecvAuth(WPARAM wParam, LPARAM lParam){ + CCSDATA* css = (CCSDATA*)lParam; + PROTORECVEVENT pqr; + PROTORECVEVENT* o_pre; + int result = 0; + mb_event mbe = {MBT_AUTHRECV,wParam,lParam,0}; + + if(!css || !css->lParam){ + return 1; + } + o_pre = (PROTORECVEVENT*)css->lParam; + pqr = *o_pre; + css->lParam = (LPARAM)&pqr; + + pqr.szMessage = (char*)o_pre->szMessage + sizeof(DWORD) + sizeof(HANDLE); + pqr.szMessage += strlen(pqr.szMessage) + 1;//first + pqr.szMessage += strlen(pqr.szMessage) + 1;//last + pqr.szMessage += strlen(pqr.szMessage) + 1;//email + pqr.szMessage += strlen(pqr.szMessage) + 1;//reason + + mbe.t2 = MBE_EVENTID; + mbe.p2 = (void*)MB_EVENT_AUTH_IN; + mbe.t3 = MBE_CUSTOM; + mbe.p3 = (void*)o_pre->szMessage; + mbe.t4 = MBE_HCONTACT; + mbe.p4 = (void*)css->hContact; + result = MBGenericRecv(wParam,lParam,MB_EVENT_AUTH_IN,&mbe); + css->lParam = (LPARAM)o_pre; + return result; +} + +PHPR MBCommandExecute(const char* msg, HANDLE hContact, string* ss) +{ + if(!(*msg)){ + return PHPR_UNKNOWN; + } + while(*msg && isspace(*msg)){msg++;} + if(!(*msg)){ + MBotConsoleAppendText("Command is empty!\r\n",1); + return PHPR_UNKNOWN; + } + + const char* output = NULL; + int result = 0; + PHPR retval = PHPR_UNKNOWN; + PHANDLER ph = sman_handler_get(MB_EVENT_COMMAND); + mb_event mbe = {MBT_COMMAND,0,0,0}; + + if(!hContact || !ss){ + mbe.event = MBT_CONSOLE_CMD; + }else{ + mbe.t1 = MBE_SSTRING; + mbe.p1 = (void*)ss; + } + + + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + } + + mbe.php = ph->php; + + sman_inc(ph->php); + if(ph->php->szBuffered){ + result = LPHP_ExecuteScript(ph->php->szBuffered,ph->szFcnName,&output,&mbe,"su",msg,hContact); + }else{ + result = LPHP_ExecuteFile(ph->php->szFilePath,ph->szFcnName,&output,&mbe,"su",msg,hContact); + } + sman_dec(ph->php); + + if(result != TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + + retval = help_parseoutput(output); + + if((mbe.lFlags & MBOT_FLAG_BODY_CHANGED) && ss->size()){ + msg = ss->data(); + mbe.lFlags &= ~(MBOT_FLAG_BODY_CHANGED); + } + + if(retval != PHPR_CONTINUE && retval != PHPR_UNKNOWN){ + break; + } +Next: + ph = ph->next; + } + return retval; +} + +int MBSendAwayMsg(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *pccsd = (CCSDATA *)lParam; + const char* msg = (const char*)pccsd->lParam; + const char* output = NULL; + int result = 0; + + mb_event mbe = {MBT_SEND,lParam,wParam,0}; + PHPR retval = PHPR_UNKNOWN; + string ss; + + mbe.t1 = MBE_SSTRING; + mbe.p1 = (void*)&ss; + + PHANDLER ph = sman_handler_get(MB_EVENT_AWAY_MSG_REQ); + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + } + + mbe.php = ph->php; + + sman_inc(ph->php); + if(ph->php->szBuffered){ + result = LPHP_ExecuteScript(ph->php->szBuffered,ph->szFcnName,&output,&mbe,"us", + pccsd->hContact,msg); + }else{ + result = LPHP_ExecuteFile(ph->php->szFilePath,ph->szFcnName,&output,&mbe,"us", + pccsd->hContact,msg); + } + sman_dec(ph->php); + + if(result != TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + + retval = help_parseoutput(output); + + if((mbe.lFlags & MBOT_FLAG_BODY_CHANGED)){ + msg = (const char*)ss.data(); + pccsd->lParam = (LPARAM)msg; + mbe.lFlags &= ~(MBOT_FLAG_BODY_CHANGED); + } + + if(retval == PHPR_SEND){ + break; + }else if(retval == PHPR_DROP){ + return 1; + } +Next: + ph = ph->next; + } + return CallService( MS_PROTO_CHAINSEND, wParam, lParam); +} + + +int MBSendMsg(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *pccsd = (CCSDATA *)lParam; + const char* msg = (const char*)pccsd->lParam; + const char* output = NULL; + char num_buff[64]; + int result = 0; + PHPR retval = PHPR_UNKNOWN; + string ss; + sMsgSync mgs; + sMsgSync* pmgs = NULL; + + if(pccsd->wParam & 0x800000){ + pccsd->wParam &= ~(0x800000); + return CallService( MS_PROTO_CHAINSEND, wParam, lParam); + } + + mb_event mbe = {MBT_COMMAND,lParam,wParam,0}; + + mbe.t1 = MBE_SSTRING; + mbe.p1 = (void*)&ss; + + mgs.old_body = (char*)msg; + mgs.hContact = pccsd->hContact; + mgs.new_body = NULL; + + if((lh_flags & MB_EVENT_COMMAND) && strncmp(pszCmdTag,msg,lCmdTagLen)==0) + { + retval = MBCommandExecute(msg + lCmdTagLen,pccsd->hContact,&ss); + if(retval != PHPR_SEND){ + return MBBroadcastACK(pccsd->hContact, retval != PHPR_FAILED); + } + } + else if(strncmp(pszPhpTag,msg,lPhpTagLen)==0) + { + string body; + sprintf(num_buff, "$cid=%u;\r\n", pccsd->hContact); + body = num_buff; + body.append(msg + lPhpTagLen); + + mbe.event = MBT_SSCRIPT; + + if(LPHP_ExecuteDirect((const char*)body.data(), &output, (void*)&mbe) == FALSE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + return MBBroadcastACK(pccsd->hContact, false); + }else{ + return MBBroadcastACK(pccsd->hContact, true); + } + } + //////// + //normal message, or command said to send the message :-) + //////// + if(lh_flags & MB_EVENT_MSG_OUT) + { + mbe.event = MBT_SEND; + + PHANDLER ph = sman_handler_get(MB_EVENT_MSG_OUT); + while(ph) + { + if(ph->lFlags & MBOT_FLAG_INACTIVE){ + goto Next; + } + + mbe.php = ph->php; + sman_inc(ph->php); + if(ph->php->szBuffered){ + result = LPHP_ExecuteScript(ph->php->szBuffered,ph->szFcnName,&output,&mbe,"us", + pccsd->hContact,pccsd->lParam); + }else{ + result = LPHP_ExecuteFile(ph->php->szFilePath,ph->szFcnName,&output,&mbe,"us", + pccsd->hContact,pccsd->lParam); + } + sman_dec(ph->php); + + if(result != TRUE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + goto Next; + } + + retval = help_parseoutput(output); + + if(((retval == PHPR_DROP) && !pmgs) || (mbe.lFlags & MBOT_FLAG_BODY_CHANGED)) + { + if(retval != PHPR_DROP){ + pccsd->lParam = (LPARAM)ss.data(); + mbe.lFlags &= ~(MBOT_FLAG_BODY_CHANGED); + } + + if(!pmgs){ + pmgs = (sMsgSync*)my_malloc(sizeof(sMsgSync)); + if(!pmgs){ + MB_Popup("MSP Error!","Could not allocate memory!"); + return NULL; + } + *pmgs = mgs; + g_msglist.Add(pmgs); + } + + pmgs->new_body = (char*)msg; + } + + if(retval == PHPR_SEND || retval == PHPR_STORE || retval == PHPR_DROP) + { + break; + } + else if(retval == PHPR_HIDE || retval == PHPR_FAILED) + { + CallService( MS_PROTO_CHAINSEND, wParam, lParam); + MBBroadcastACK(pccsd->hContact, retval != PHPR_FAILED); + } +Next: + ph = ph->next; + } + } + result = ((retval==PHPR_STORE) || (retval==PHPR_DROP)) ? + (MBBroadcastACK(mgs.hContact, retval != PHPR_FAILED)) : //else + (CallService( MS_PROTO_CHAINSEND, wParam, lParam)); + + + if(!result && pmgs) + { + g_msglist.Del(pmgs); + my_memfree(pmgs); + } + else if(pmgs) + { + pmgs->hProcess = (HANDLE)result; + pmgs->old_body = my_strdup(msg); + if(!pmgs->old_body){ + g_msglist.Del(pmgs); + my_memfree(pmgs); + return NULL; + } + pmgs->new_body = (retval == PHPR_DROP)?(NULL):((char*)my_strdup(ss.data())); + } + return result; +} +/****************************************** + * queue and other stuff * + ******************************************/ +int RegisterContacts() +{ + HANDLE hContact = NULL; + + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact){ + CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)hContact,(LPARAM)(char*)MBOT); + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } + return 0; +} + +int MBotShowConsole(WPARAM wParam, LPARAM lParam) +{ + extern long lConTopMost; + + if(hDialog){ + ShowWindow(hDialog,SW_SHOW); + SetWindowPos(hDialog,lConTopMost?HWND_TOPMOST:0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + UpdateWindow(hDialog); + } + return 1; +} + +/****************************************** + * IRC functions * + ******************************************/ +int MBIRCGuiIn(WPARAM wParam, LPARAM lParam) +{ + GCEVENT* gce = (GCEVENT*)lParam; + WPARAM_GUI_IN* wpi = (WPARAM_GUI_IN*)wParam; + mb_event mbe = {MBT_IRC_IN,0}; + + if(gce->dwItemData & 0x80000000)return 0; + + mbe.lParam = lParam; + mbe.wParam = wParam; + mbe.p4 = (void*)lParam; + mbe.t4 = MBE_CUSTOM; + + return (MBMultiParamExecute(IRC_EVENT_GUI_IN,&mbe,"slsSS",wpi->pszModule,gce->pDest->iType, + gce->pDest->pszID,&gce->pszNick,&gce->pszText) == PHPR_DROP); +} +int MBIRCGuiOut(WPARAM wParam, LPARAM lParam) +{ + GCHOOK * gch = (GCHOOK*)lParam; + mb_event mbe = {MBT_IRC_OUT,0}; + + if(gch->dwData & 0x80000000)return 0; + + mbe.lParam = lParam; + mbe.wParam = wParam; + mbe.p4 = (void*)lParam; + mbe.t4 = MBE_CUSTOM; + + return (MBMultiParamExecute(IRC_EVENT_GUI_OUT,&mbe,"sLSSS",wParam,&gch->pDest->iType,&gch->pDest->pszID,&gch->pszUID,&gch->pszText)==PHPR_DROP); +} + +int MBIRCRawIn(WPARAM wParam, LPARAM lParam) +{ + mb_event mbe = {MBT_IRC_RAW,0}; + mbe.lParam = lParam; + mbe.wParam = wParam; + mbe.p4 = (void*)lParam; + mbe.t4 = MBE_CUSTOM; + mbe.t3 = MBE_CUSTOM; + mbe.p3 = (void*)TRUE; + return (MBMultiParamExecute(IRC_EVENT_RAW_IN,&mbe,"sS",wParam,lParam) == PHPR_DROP); +} +int MBIRCRawOut(WPARAM wParam, LPARAM lParam) +{ + mb_event mbe = {MBT_IRC_RAW,0}; + mbe.lParam = lParam; + mbe.wParam = wParam; + mbe.p4 = (void*)lParam; + mbe.t4 = MBE_CUSTOM; + mbe.t3 = MBE_CUSTOM; + mbe.p3 = (void*)FALSE; + return (MBMultiParamExecute(IRC_EVENT_RAW_OUT,&mbe,"sS",wParam,lParam) == PHPR_DROP); +} + +int MBIRCRegister(WPARAM wParam, LPARAM lParam) +{ + struct STR{ + char* val; + unsigned long len; + }; + + char* array = 0; + char* narr = 0; + char* module = (char*)lParam; + unsigned long temp=0,temp2=0; + + STR tmp = {0}; + STR pptmp = {0}; + STR* ptmp; + SVAR_TYPE svt = SV_NULL; + + if(LPHP_GetVar("/irc/modules",(void**)&ptmp,&svt)) + { + temp = strlen(module);//@ 0000 4 + pptmp = *ptmp; + ptmp = &pptmp; + tmp.len = temp + 6 + ptmp->len; + narr = array = (char*)my_malloc(tmp.len);// + if(!array)return 1; + memcpy(array,ptmp->val,ptmp->len); + array += ptmp->len - 1; + //count + *array++ = '%'; + *array++ = 'S'; + *((long*)array) = temp; + array += 4; + memcpy(array,module,temp); + array += temp; + *array++ = 'X'; + tmp.val = narr; + LPHP_SetVar("/irc/modules",(void*)&tmp,SV_ARRAY); + my_memfree(narr); + }else{ //A@0000S0000[...]X + temp = strlen(module); + tmp.len = temp + 6 + 2; + narr = array = (char*)my_malloc(tmp.len); + if(!array)return 1; + tmp.val = array; + *array++ = 'A'; + *array++ = '%'; + *array++ = 'S'; + *((long*)array) = temp; + array += 4; + memcpy(array,module,temp); + array += temp; + *array++ = 'X'; + LPHP_NewVar("/irc/modules",&tmp,SV_ARRAY,0); + my_memfree(narr); + } + return 0; +} \ No newline at end of file diff --git a/mBot/src/mbot/mbot.def b/mBot/src/mbot/mbot.def new file mode 100644 index 0000000..5e773de --- /dev/null +++ b/mBot/src/mbot/mbot.def @@ -0,0 +1,6 @@ +LIBRARY "mbot" + +EXPORTS + MirandaPluginInfo + Load + Unload \ No newline at end of file diff --git a/mBot/src/mbot/mbot.h b/mBot/src/mbot/mbot.h new file mode 100644 index 0000000..9a4fdbe --- /dev/null +++ b/mBot/src/mbot/mbot.h @@ -0,0 +1,229 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _MBOT_H_ +#define _MBOT_H_ + +#pragma once + +#pragma warning(disable: 4996) +#pragma warning(disable: 4005) + +#define WINVER 0x0500 +#define _WIN32_WINNT 0x0500 +#define _WIN32_IE 0x0501 +#define _WIN32_WINDOWS 0x0500 + +#define MBOT "MBot" +#define MS_MBOT_TRIGGER MBOT "/Trigger" +#define MS_MBOT_CLISTEVENT MBOT "/CLEHandler" +#define MS_MBOT_SHOWCONSOLE MBOT "/ShowConsole" + +#define UNHOOK(e) if(e){UnhookEvent(e);e=NULL;} + +#ifndef _DEBUG +#define MBLOG(s) +#define MBLOGEX(s) +#else +#define MBLOG(s) fprintf(dbgout,s) +#define MBLOGEX(s) if(lErrorLog && dbgout)fprintf(dbgout,"[ERROR_LOG@%s]: %s\r\n",help_static_time(),s);fflush(dbgout) +#endif + +#include +#include +#include +#include +#include +#include +//#include +#pragma optimize("gsy12",on) + +void EnterCriticalSectionR(LPCRITICAL_SECTION cs,const char* file,long line); +void LeaveCriticalSectionR(LPCRITICAL_SECTION cs,const char* file,long line); + +#define EnterCriticalSectionX(cs) EnterCriticalSection(cs) +#define LeaveCriticalSectionX(cs) LeaveCriticalSection(cs) + + //LeaveCriticalSectionR(cs,__FUNCTION__ "@" __FILE__,__LINE__); + //EnterCriticalSectionR(cs,__FUNCTION__ "@" __FILE__,__LINE__); + +#include +#include + +using namespace std; + +#include "resource.h" +#include "helpers.h" +#include "sync.h" +#include "cron.h" +#include "config.h" +/****************************************** + * To download libphp visit my website * + ******************************************/ +#include +#include +#include + +extern "C" { + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include
+ #include
+ #include
+ #include +} + +#include "m_script.h" + +#define MBOT_FLAG_BODY_CHANGED 0x0010 +#define MBOT_FLAG_HANDLERS_CHANGED 0x0020 +#define MBOT_FLAG_CACHE 0x01 +#define MBOT_FLAG_SHARE 0x02 +#define MBOT_FLAG_INACTIVE 0x04 +#define MBOT_FLAG_DELETE 0x08 +#define MBOT_FLAG_ASYNC 0x10 +#define MBOT_FLAG_WORKING 0x20 +#define MBOT_FLAG_SHARE_NAME 0x40 +#define MBOT_FLAG_STORED 0x80 +#define MBOT_FLAG_NOOUTPUT 0x0100 +#define MBOT_FLAG_CONTACTM 0x0200 +#define MBOT_FLAG_WANTPREBUILD 0x0400 +#define MBOT_FLAG_SHALLDIE 0x0800 + +typedef int (*PHPENV_CB)(long code,void* param1,void* param2,void* cparam); +struct sPHPENV +{ + void* c_param; + PHPENV_CB fp_callback; + long m_flags; + //////////////////////////// + cutFile* r_out; + const char* r_value; + //////////////////////////// + const char* script_path; + const char* query_string; + const char* content_type; + long content_length; + //////////////////////////// + unsigned char* post_data; + long post_len; + long post_read; +public: + sPHPENV(){ + memset(this,0,sizeof(sPHPENV)); + } +}; + + +void my_memfree(void* ptr); +char* my_strdup(const char* str); +void* my_malloc(long amount); +/****************************************** + * events * + ******************************************/ +int event_contact_new(WPARAM wParam, LPARAM lParam); +int event_contact_del(WPARAM wParam, LPARAM lParam); +int event_contact_changed(WPARAM wParam, LPARAM lParam); +int event_new_db_event(WPARAM wParam, LPARAM lParam); +int event_pre_db_event(WPARAM wParam, LPARAM lParam); +int event_msg_ack(WPARAM wParam, LPARAM lParam); +int event_modules_loaded(WPARAM wParam, LPARAM lParam); +int event_typing(WPARAM wParam, LPARAM lParam); +int event_new_mystatus(WPARAM wParam, LPARAM lParam); +int event_opt_initialise(WPARAM wParam, LPARAM lParam); +int event_icq_awayreq(WPARAM wParam,LPARAM lParam); +int event_contact_menu_prebuild(WPARAM wParam,LPARAM lParam); +int event_oktoexit(WPARAM wParam,LPARAM lParam); +/****************************************** + * IRC functions * + ******************************************/ +int MBIRCGuiIn(WPARAM wParam, LPARAM lParam); +int MBIRCGuiOut(WPARAM wParam, LPARAM lParam); +int MBIRCRawIn(WPARAM wParam, LPARAM lParam); +int MBIRCRawOut(WPARAM wParam, LPARAM lParam); +int MBIRCRegister(WPARAM wParam, LPARAM lParam); + +/****************************************** + * svc functions * + ******************************************/ +int MBRecvMsg(WPARAM wParam, LPARAM lParam); +int MBRecvUrl(WPARAM wParam, LPARAM lParam); +int MBSendMsg(WPARAM wParam, LPARAM lParam); +int MBSendAwayMsg(WPARAM wParam, LPARAM lParam); +int MBRecvAuth(WPARAM wParam, LPARAM lParam); +int MBRecvFile(WPARAM wParam, LPARAM lParam); +int MBTyping(WPARAM wParam, LPARAM lParam); +int MBotShowConsole(WPARAM wParam, LPARAM lParam); +int MBCListEventHandle(WPARAM wParam, LPARAM lParam); +int MBExternalTrigger(WPARAM wParam, LPARAM lParam); +/****************************************** + * generic handlers * + ******************************************/ +int MBGenericSettChanged(HANDLE hContact, DBCONTACTWRITESETTING* dbws, long ev_id); +int MBGenericDBEvent(HANDLE hDBEvent,long ev_id,const char* pszFcn, HANDLE hContact,const char* pszData,long timestamp,void* p3); +int MBGenericRecv(WPARAM wParam, LPARAM lParam,long ev_id,mb_event* ce = NULL); +int MBNoParamExecute(long ev_id); +int MBMultiParamExecute(long ev_id,mb_event* mbe,const char* params,...); +int MBMultiParam(PPHP php,const char* fcn,mb_event* mbe,const char* params,...); +int MBBroadcastACK(HANDLE hContact); +/****************************************** + * other functions * + ******************************************/ +PHPR MBCommandExecute(const char* msg,HANDLE hContact,string* ss); +int MBUnHookEvents(); +int MBHookEvents(); +void my_stdout(const char* str,long length); +void my_stderr(const char* str,long length); + +int RegisterContacts(); +int GenericThreadProc(void* p); + +extern char g_root[MAX_PATH+1]; +extern char g_profile[MAX_PATH+1]; + +extern CSyncList g_slist; + +extern long lh_flags; +extern DWORD g_mbot_version; +extern PCHAR g_mbot_version_s; +extern FILE* dbgout; + +extern HWND hDialog; +extern HWND hConsole; +extern HWND hCommandBox; +extern HWND hToolbar; +extern HINSTANCE hInst; +#endif //_MBOT_H_ \ No newline at end of file diff --git a/mBot/src/mbot/mbot.rc b/mBot/src/mbot/mbot.rc new file mode 100644 index 0000000..2295a18 --- /dev/null +++ b/mBot/src/mbot/mbot.rc @@ -0,0 +1,298 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Polish resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK) +#ifdef _WIN32 +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,3,5 + PRODUCTVERSION 0,0,3,5 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041504b0" + BEGIN + VALUE "Comments", "MSP - Miranda Scripting Plugin (mBot)" + VALUE "CompanyName", "Piotr Pawluczuk" + VALUE "FileDescription", "MSP - Miranda Scripting Plugin (mBot)" + VALUE "FileVersion", "0, 0, 3, 5" + VALUE "InternalName", "MBot" + VALUE "LegalCopyright", "Copyright (C) 2004-2006 Piotr Pawluczuk" + VALUE "OriginalFilename", "mbot.dll" + VALUE "ProductName", "MSP - Miranda Scripting Plugin (mBot)" + VALUE "ProductVersion", "0, 0, 3, 5" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x415, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MBOTCONSOLE DIALOGEX 0, 0, 200, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "MBot Console" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_MBCONSOLE,"RichEdit20A",ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL,0,0,199,101 + EDITTEXT IDC_MBCOMMANDBOX,0,117,199,35,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER | WS_VSCROLL | NOT WS_TABSTOP,WS_EX_ACCEPTFILES +END + +IDD_DIALOG1 DIALOGEX 0, 0, 186, 132 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,136,112,43,13 + PUSHBUTTON "Cancel",IDCANCEL,91,112,43,13 +END + +IDD_DIALOG2 DIALOGEX 0, 0, 169, 65 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,112,44,50,14 + PUSHBUTTON "Cancel",IDCANCEL,60,44,50,14 + EDITTEXT IDC_GS_EDIT,7,23,155,13,ES_AUTOHSCROLL + LTEXT "Static",IDC_GS_INFO,7,7,155,15 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_MBOTCONSOLE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 193 + TOPMARGIN, 7 + BOTTOMMARGIN, 145 + END + + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 125 + END + + IDD_DIALOG2, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 162 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_BITMAP1 BITMAP "res\\tbar.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "res\\icon1.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "Re|cache", ID_POPUP_RECACHE + MENUITEM "Uncache", ID_POPUP_UNCACHE + MENUITEM SEPARATOR + POPUP "Activate" + BEGIN + MENUITEM "File", ID_ACTIVATE_FILE + MENUITEM "Event", ID_ACTIVATE_EVENT + END + POPUP "Deactivate" + BEGIN + MENUITEM "File", ID_DEACTIVATE_FILE + MENUITEM "Event", ID_DEACTIVATE_EVENT + END + MENUITEM SEPARATOR + MENUITEM "Unload", ID_POPUP_UNLOAD + MENUITEM "Uninstall", ID_POPUP_UNINSTALL + END + POPUP "popup2" + BEGIN + MENUITEM "Install Script", ID_POPUP2_INSTALLSCRIPT + MENUITEM "Install Extension", ID_POPUP2_INSTALLEXTENSION + END + POPUP "popup3" + BEGIN + MENUITEM "Configure", ID_POPUP3_CONFIGURE + MENUITEM SEPARATOR + MENUITEM "Disable", ID_POPUP3_DISABLE + MENUITEM "Enable", ID_POPUP3_ENABLE + MENUITEM SEPARATOR + MENUITEM "Uninstall", ID_POPUP3_UNINSTALL + END +END + +#endif // Polish resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 314, 254 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "General Settings",IDC_STATIC,7,3,300,126 + CONTROL "Disable all events",IDC_MBDISABLEEVENTS,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,15,26,283,10 + CONTROL "Disable file caching (overwrites script settings)",IDC_MBDISABLECACHE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,37,283,10 + CONTROL "Enable MBot",IDC_MBENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,15,283,10 + CONTROL "Show MBot console on startup",IDC_MBSHOWCONSOLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,59,283,10 + GROUPBOX "Command Tags",IDC_ADV1,7,129,300,41 + CONTROL "Show MBot console on error",IDC_MBSHOWCONSOLEERROR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,70,283,10 + CONTROL "Wrap console output",IDC_WRAPCONSOLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,81,283,10 + CONTROL "Disable scheduler",IDC_DISABLESCHEDULER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,48,283,10 + EDITTEXT IDC_ADVSCRIPTTAG,15,140,20,12,ES_AUTOHSCROLL + EDITTEXT IDC_ADVCMDTAG,15,154,20,12,ES_AUTOHSCROLL + LTEXT "Script tag (default: ""?>"")",IDC_ADVLABEL1,81,144,217,9 + LTEXT "Command tag (default: ""m>"")",IDC_ADVLABEL2,81,157,217,9 + CONTROL "Enable WWW Server",IDC_ENABLEWWW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,92,283,10 + GROUPBOX "Registered Handlers",IDC_ADV2,7,171,300,76 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,15,184,283,57 + CONTROL "Enable WWW Log",IDC_ENABLEWWW2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,103,283,10 + CONTROL "Show advanced script configuration (requires options restart);",IDC_ENABLEADVOPT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,113,283,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 307 + VERTGUIDE, 15 + VERTGUIDE, 298 + TOPMARGIN, 7 + BOTTOMMARGIN, 247 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/mBot/src/mbot/mbot.vcproj b/mBot/src/mbot/mbot.vcproj new file mode 100644 index 0000000..11c2bc8 --- /dev/null +++ b/mBot/src/mbot/mbot.vcproj @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mBot/src/mbot/res/icon1.ico b/mBot/src/mbot/res/icon1.ico new file mode 100644 index 0000000..432c382 Binary files /dev/null and b/mBot/src/mbot/res/icon1.ico differ diff --git a/mBot/src/mbot/res/php5-power-micro.bmp b/mBot/src/mbot/res/php5-power-micro.bmp new file mode 100644 index 0000000..0b7a5c4 Binary files /dev/null and b/mBot/src/mbot/res/php5-power-micro.bmp differ diff --git a/mBot/src/mbot/res/tbar.bmp b/mBot/src/mbot/res/tbar.bmp new file mode 100644 index 0000000..b8a4be1 Binary files /dev/null and b/mBot/src/mbot/res/tbar.bmp differ diff --git a/mBot/src/mbot/resource.h b/mBot/src/mbot/resource.h new file mode 100644 index 0000000..71fc9f9 --- /dev/null +++ b/mBot/src/mbot/resource.h @@ -0,0 +1,67 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by mbot.rc +// +#define IDD_MBOTCONSOLE 9 +#define IDR_RT_MANIFEST1 100 +#define IDB_BITMAP1 102 +#define IDI_ICON1 104 +#define IDD_OPTIONS 106 +#define IDD_DIALOG1 107 +#define IDR_MENU1 108 +#define IDD_DIALOG2 109 +#define IDC_MBCONSOLE 1002 +#define IDC_MBCOMMANDBOX 1003 +#define IDC_TOOLBAR 1004 +#define IDC_GS_INFO 1004 +#define ID_EXECUTE 1005 +#define ID_LINEWRAP 1006 +#define ID_CLEAR 1007 +#define ID_MBHELP 1008 +#define ID_MBINSTALL 1009 +#define IDC_MBDISABLEEVENTS 1010 +#define IDC_MBDISABLECACHE 1011 +#define IDC_MBENABLE 1012 +#define IDC_MBSHOWCONSOLE 1013 +#define IDC_MBSHOWCONSOLEERROR 1015 +#define IDC_WRAPCONSOLE 1016 +#define IDC_DISABLESCHEDULER 1017 +#define IDC_ADV1 1018 +#define IDC_ADVSCRIPTTAG 1019 +#define IDC_ADVCMDTAG 1020 +#define IDC_ADVLABEL1 1021 +#define IDC_ADVLABEL2 1022 +#define IDC_ENABLEWWW 1023 +#define IDC_ADV2 1024 +#define IDC_LIST1 1025 +#define IDC_ENABLEWWW2 1026 +#define IDC_EDIT1 1026 +#define IDC_GS_EDIT 1026 +#define IDC_ENABLEADVOPT 1027 +#define ID_POPUP_RECACHE 40001 +#define ID_POPUP_ACTIVATE 40002 +#define ID_POPUP_DEACTIVATE 40003 +#define ID_POPUP_UNCACHE 40004 +#define ID_POPUP_UNINSTALL 40005 +#define ID_POPUP2_INSTALLSCRIPT 40006 +#define ID_POPUP2_INSTALLEXTENSION 40007 +#define ID_ACTIVATE_FILE 40008 +#define ID_ACTIVATE_EVENT 40009 +#define ID_DEACTIVATE_FILE 40010 +#define ID_DEACTIVATE_EVENT 40011 +#define ID_POPUP_UNLOAD 40012 +#define ID_POPUP3_CONFIGURE 40013 +#define ID_POPUP3_UNINSTALL 40014 +#define ID_POPUP3_ENABLE 40015 +#define ID_POPUP3_DISABLE 40016 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40017 +#define _APS_NEXT_CONTROL_VALUE 1027 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/mBot/src/mbot/server.cpp b/mBot/src/mbot/server.cpp new file mode 100644 index 0000000..2495e01 --- /dev/null +++ b/mBot/src/mbot/server.cpp @@ -0,0 +1,1383 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "window.h" +#include "functions.h" +#include + +#ifndef _NOHTTPD_ + +#pragma comment (lib,"ws2_32") + +typedef volatile unsigned long VDWORD; + +struct sHTTPDEnv +{ + cutSockf* sf; + cutMemf* mf; + cutMemf* req; + map hdr; + + char* post_data; + long post_length; + + enum eMethod{GET, POST} method; + char out_started; + short error_code; + long var_offset; +public: + sHTTPDEnv(){ + sf = NULL; + mf = NULL; + req = NULL; + post_data = NULL; + post_length = 0; + method = GET; + out_started = 0; + error_code = 200; + var_offset = 0; + } +}; + +struct sFDS +{ + u_int fd_count; + SOCKET fd_array[2]; +}; + +struct sHTTPSync : public sSync +{ + SOCKET s; + unsigned long to; +}; + +struct sMIME +{ + char* ext; + char* type; +}; + +struct sVS +{ + char auth_req; + char* path; + char* ip; + char* user; + char* pass; + + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } +}; + +/////////////////////////// +SOCKET svr_ls = NULL; +HANDLE svr_hTh = NULL; +HANDLE svr_q_hTh = NULL; +HANDLE svr_q_event = NULL; +VDWORD svr_q_tc = 0; +VDWORD svr_cur_clients = 0; +HANDLE svr_w_hTh = NULL; +CSyncList svr_q_queue; + +map svr_mimes; +map svr_vs; + +////////////////////////// +DWORD svr_max_clients = 15; +DWORD svr_timeout = 60000; +FILE* svr_log = NULL; +CSECTION svr_log_cs; +short svr_listen_port = 8081; +long svr_auth_required = 0; +char svr_allowed_ip[32] = "*"; +char svr_wwwroot[260]; +long svr_wwwroot_len = 0; +long svr_maxrequest = 4*1024*1024; + +extern cXmlDoc cSettings; + +const static char* error503 = "HTTP/1.0 503 Too many connections\r\nConnection: close\r\nRetry-After: 30\r\nContent-Type: text/html\r\n\r\n

503 Too many connections

"; + +static const char* svr_months[]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""}; +static const char* svr_days[]={0,"Mon","Tue","Wed","Thu","Fri","Sat","Sun",""}; + +unsigned int httpd_mime_hash(sMIME* v) +{ + unsigned int index = 0; + char* c = v->ext; + while(*c){index = 31 * index + *c++;} + return (index & 0x7EffFFff) + 1; +} + +int httpd_mime_cmp(sMIME* v1,sMIME* v2,void* param){ + return strcmp(v1->ext,v2->ext); +} + +int httpd_mime_set(sMIME* v1,sMIME* v2,void* param){ + *v1 = *v2; + return 1; +} + +unsigned int httpd_vs_hash(sVS* v) +{ + unsigned int index = 0; + char* c = v->path; + while(*c){index = 31 * index + *c++;} + return (index & 0x7EffFFff) + 1; +} +int httpd_vs_cmp(sVS* v1,sVS* v2,void* param){ + return strcmp(v1->path,v2->path); +} +int httpd_vs_set(sVS* v1,sVS* v2,void* param){ + if(v2 != NULL){ + *v1 = *v2; + } + return 1; +} + +int httpd_logaccess(const char* request,long code,long length,DWORD ip) +{ + + static const char* tmp = NULL; + static SYSTEMTIME st; + + if(!svr_log)return 1; + //218.4.232.179 - - [11/Dec/2004:14:43:45 +0100] "GET / HTTP/1.1" 403 319 + EnterCriticalSectionX(&svr_log_cs); + GetSystemTime(&st); + + if(request){ + tmp = strchr(request,'\r'); + if(!tmp && !(tmp = strchr(request,'\n'))){ + tmp = request + strlen(request) + 1; + } + } + if(st.wMonth > 12){st.wMonth = 1;} + + fprintf(svr_log,"%s - - [%.2u/%s/%.4u:%.2u:%.2u:%.2u GMT] \"", + inet_ntoa(*(in_addr*)&ip), + st.wDay, + svr_months[st.wMonth], + st.wYear, + st.wHour, + st.wMinute, + st.wSecond); + + if(request && tmp > request){ + fwrite(request,1,(tmp - request - 1),svr_log); + } + + fprintf(svr_log,"\" %u %u\r\n",code,length); + fflush(svr_log); + LeaveCriticalSectionX(&svr_log_cs); + return 1; +} + +char* httpd_mime_reg(const char* extension) +{ + char sPath[MAX_PATH]; + unsigned long dwSize = MAX_PATH; + unsigned long dwType = REG_SZ; + HKEY hItem; + + if(RegOpenKeyEx(HKEY_CLASSES_ROOT,extension,0,KEY_READ,&hItem) == SUCCESS) + { + if(RegQueryValueEx(hItem,"Content Type",NULL,&dwType,(LPBYTE)sPath,&dwSize)==ERROR_SUCCESS) + { + svr_mimes[extension] = sPath; + return (char*)svr_mimes[extension].data(); + + /*/sMIME m = {my_strdup(extension + 1),my_strdup(sPath)}; + + RegCloseKey(hItem); + + /*if(!(m.ext) || !(m.type)) + { + if(m.ext)my_memfree(m.ext); + if(m.type)my_memfree(m.type); + return NULL; + } + + if(svr_mimes.Insert(&m)){ + return m.type; + }else{ + my_memfree(m.ext); + my_memfree(m.type); + return NULL; + }*/ + } + else{ + RegCloseKey(hItem); + return NULL; + } + }else{ + return NULL; + } +} + +int httpd_mime_init() +{ + /*if(svr_mimes.InitArray(911,sizeof(sMIME),(SA_COMPARE)httpd_mime_cmp, + (SA_HASH)httpd_mime_hash,(SA_COMPARE)httpd_mime_set)==FALSE) + { + return 0; + }*/ + return 1; +} + +int httpd_vs_init() +{ + sVS vs={0}; + sXmlNode* n; + const char *tmp; + + /*if(svr_vs.InitArray(253,sizeof(sVS),(SA_COMPARE)httpd_vs_cmp, + (SA_HASH)httpd_vs_hash,(SA_COMPARE)httpd_vs_set)==FALSE) + { + return 0; + }*/ + + n = cSettings.GetNode("mbot/httpd/dirs/dir"); + while(n) + { + vs.path = (char*)cSettings.GetProperty(n,"path"); + if(vs.path && *vs.path) + { + tmp = cSettings.GetProperty(n,"auth_req"); + vs.auth_req = tmp?(*tmp!='0'):0; + if(vs.auth_req){ + tmp = cSettings.GetProperty(n,"user"); + vs.user = tmp?tmp:":::"; + tmp = cSettings.GetProperty(n,"pass"); + vs.pass = tmp?tmp:":::"; + } + + tmp = cSettings.GetProperty(n,"ip_mask"); + vs.ip = tmp?tmp:"*"; + svr_vs[vs.path] = vs; + } + n = n->next; + } + return 1; +} + +char* httpd_getmime(char* ext) +{ + std::map::iterator loc; + sMIME m = {(ext+1),NULL}; + + if(!ext){ + return "application/octet-stream"; + } + + loc = svr_mimes.find(ext); + if(loc != svr_mimes.end()){ + return (char*)loc->second.data(); + }else{ + char* tmp = httpd_mime_reg(ext); + return (tmp)?(tmp):("application/octet-stream"); + } +} + +char* httpd_getextension(char* filename) +{ + long l = strlen(filename); + char* c = NULL; + + strlwr((char*)filename); + + if(l<2){ + return NULL; + } + + c = filename + l - 1; + while(c != filename) + { + if(*c == '.'){ + goto Okay; + }else{ + c--; + } + } + return NULL; +Okay: + return c; +} +void httpd_make_spaces(char* str){ + while(*str){ + if(*str=='+')*str=' '; + str++; + } +} +long httpd_rrecv(SOCKET sock,void *buffer,long length,long timeout = 3000) +{ + if(!length || !timeout){ + return 0; + } + int read = 0; + + for(;timeout>0;) + { + read = recv(sock,(char*)buffer,length,0); + if(read > 0) + { + return read; + } + else if(read < 0 && (WSAGetLastError() == 10035)) + { + Sleep(50); + timeout -= 50; + } + else + { + return 0; + } + } + return 0; +} + +char *httpd_strnws(const char* str) +{ + while(*str){ + if(!isspace(*str)){ + return (char*)str; + }else{ + str++; + } + } + return (NULL); +} + +long httpd_count(const char* str,char c) +{ + long count = 0; + + while(*str){ + if(*str == c){ + count ++; + } + str++; + } + return count; +} +long httpd_writestring(cutSockf* gf, const char* str) +{ + return gf->write((void*)str, strlen(str)); +} + +long httpd_writeformatted(cutFile* gf, const char* format, ...) +{ + if(!gf){ + return 0; + } + char temp[1024]; + + va_list args; + va_start(args,format); + _vsnprintf(temp, sizeof(temp), format, args); + va_end(args); + + return gf->writestring(temp); +} + +inline long httpd_unify(register char* str) +{ + register long len = 0; + while(*str){ + if(*str == '\\'){ + *str = '/'; + } + str++; + len++; + } + return len; +} + +char* httpd_hdr_get(const char* table,const char* name) +{ + const char* n = table; + const char* v; + while(*n) + { + v = n + strlen(n) + 1; + if(stricmp(name,n)==0){ + return (char*)v; + } + n = v + strlen(v) + 1; + } + return NULL; +} + +long httpd_queue(SOCKET sock) +{ + sHTTPSync* hs = (sHTTPSync*)my_malloc(sizeof(sHTTPSync)); + if(!hs){ + return 0; + }else{ + hs->prev = hs->next = NULL; + hs->s = sock; + hs->to = GetTickCount() + svr_timeout; + svr_q_queue.Add(hs); + SetEvent(svr_q_event); + return 1; + } +} +void httpd_sname(SOCKET sock,cutMemf* out,DWORD* ip) +{ + SOCKADDR_IN sin = {0}; + int ssize = sizeof(sin); + char* tmp = NULL; + char val[10]; + + if(getsockname(sock,(sockaddr*)&sin,&ssize)!=-1) + { + if(out) + { + tmp = inet_ntoa(sin.sin_addr); + if(!tmp)tmp = "0.0.0.0"; + + out->write("REMOTE_ADDR",12); + out->write(tmp,strlen(tmp)+1); + + out->write("REMOTE_PORT",12); + _snprintf(val,sizeof(val)-1,"%u",ntohs(sin.sin_port)); + out->write(val,strlen(val)+1); + out->putc(0); + } + if(ip){ + *ip = *(DWORD*)&sin.sin_addr; + } + } +} + +char *httpd_fix(char* str,char* sub) +{ + if(!str)return NULL; + char* max = (char*) str + strlen(str); + + str += strlen(sub); + while(str < max) + { + if(!isspace(*str)){ + return (char*)str; + }else{ + str++; + } + } + return NULL; +} + +long httpd_init_hdr(cutMemf* out) +{ + if(!out->create(512)){ + return 0; + } + out->write("content-type\0text/html",23); + out->write("connection\0close",17); + out->write("pragma\0no-cache",16); + out->putc(0); + return 1; +} + +void httpd_send_headers(sHTTPDEnv* env) +{ + const char* v = NULL; + map::iterator it = env->hdr.begin(); + + httpd_writeformatted(env->sf,"HTTP/1.0 %u %s\r\n", env->error_code, + (env->error_code==200) ? "OK": "ERROR"); + + for(;it != env->hdr.end(); it++) + { + httpd_writeformatted(env->sf, "%s: %s\r\n", it->first.data(), it->second.data()); + } + env->sf->write("\r\n",2); +} + +long httpd_sendfile(const char* file, sHTTPDEnv* env, char* buffer) +{ + cutDiskf gf; + cutSockf* sf = env->sf; + DWORD size = 0; + DWORD sent = 0; + DWORD read = 0; + tm* ft = NULL; + tm sft; + + if(!gf.open(file,"rb")){ + return 0; + } + + size = gf.size(); + + sf->writestring("HTTP/1.0 200 OK\r\n"); + httpd_writeformatted(sf,"Content-Type: %s\r\n",httpd_getmime((char*)strrchr(file,'.'))); + httpd_writeformatted(sf,"Content-Length: %u\r\n",size); + httpd_writeformatted(sf,"X-Powered-By: MBot/%s\r\n",g_mbot_version_s); + help_filemtime(file,&sent); + + ft = gmtime((const time_t*)&sent); + if(ft){sft = *ft;} + sft.tm_wday = min((unsigned int)sft.tm_wday,6); + sft.tm_mon = min((unsigned int)sft.tm_mon,11); + + httpd_writeformatted(sf,"Last-Modified: %s, %.2u %s %.4u %.2u:%.2u:%.2u GMT\r\n\r\n", + svr_days[sft.tm_wday+1], + sft.tm_mday, + svr_months[sft.tm_mon+1], + sft.tm_year + 1900, + sft.tm_hour, + sft.tm_min, + sft.tm_sec); + + sent = 0; + + while(sent < size) + { + read = gf.read(buffer,1024); + if(!read)goto Error; + if(sf->write(buffer,read)!=read)goto Error; + sent += read; + } + gf.close(); + return 1; +Error: + gf.close(); + return 0; +} + +long httpd_php_cb(long code, void* param1, void* param2, mb_event* mbe) +{ + sHTTPDEnv* env; + + if(!mbe){ + return 0; + } + env = (sHTTPDEnv*)mbe->p1; + + if(code == LPHP_CB_SETHDR) + { + char* hdr = (char*)param1; + char* cp = NULL; + char* sn; + char* sv; + char* cx; + + if(env->out_started || !hdr || !(cp = strchr(hdr,':'))){ + return 0; + }else{ + *cp = 0; + sn = hdr; + sv = cp + 1; + cp = strchr(sv,'\r'); + if(cp){ + *cp = '\0'; + cx = cp - 1; + while(isspace(*cx) && cx!=sn){ + *(cx--)=0; + } + } + while(isspace(*sv)){sv++;} + while(isspace(*sn)){sn++;} + env->hdr[sn] = sv; + + if(stricmp(sn,"location") == 0){ + env->error_code = 301; + } + return 1; + } + return 0; + }else if(code == LPHP_CB_OUTSTARTED){//start output + if(env->out_started == 0){ + httpd_send_headers(env); + env->out_started = 1; + } + return 1; + }else if(code == LPHP_CB_GETMETHOD){//get method + return (int)((env->method == 1)?"POST":"GET"); + }else if(code == LPHP_CB_GETCOOKIE){//get cookie + return (int)httpd_hdr_get((const char*)env->req->getdata(),"HTTP_COOKIE"); + }else if(code == 4){// n/a + return (int)NULL; + }else if(code == LPHP_CB_POST_LENGTH){//get post data length + return (int)env->post_length; + }else if(code == LPHP_CB_POST_DATA){//get post data pointer + return (int)env->post_data; + }else if(code == LPHP_CB_GETENV){ + param2 = (void*)httpd_hdr_get((const char*)env->req->getdata(),(const char*)param1); + return (long)((param2)?(param2):getenv((const char*)param1)); + }else if(code == LPHP_CB_GETCT){ + return (long)httpd_hdr_get((const char*)env->req->getdata(),"CONTENT_TYPE"); + }else if(code == LPHP_CB_GETCL){ + char* tmp = httpd_hdr_get((const char*)env->req->getdata(),"CONTENT_LENGTH"); + return (tmp)?(strtoul(tmp,NULL,10)):(0); + }else if(code == LPHP_CB_GETVARS){ + return ((long)env->req->getdata() + env->var_offset); + }else{ + return NULL; + } +} + +long httpd_parse_headers(cutMemf* mf, sHTTPDEnv* env) +{ + long pos = mf->tellpos(); + long rcv = 0; + char buffer[2052]; + char* line = NULL; + + mf->setpos(0); + while(mf->gets(buffer, sizeof(buffer) - 1)) + { + rcv ++; + if(rcv == 1){ + strlwr(buffer); + if(strncmp(buffer,"get ",4) == 0){ + env->method = sHTTPDEnv::GET; + }else if(strncmp(buffer,"post ",5) == 0){ + env->method = sHTTPDEnv::POST; + }else{ + mf->setpos(pos); + return 0; + } + } + else + { + char* ne = strchr(buffer,':'); + char* ns = NULL; + char* vs = ne + 1; + + if(!ne){ + continue; + } + if(!(ns = httpd_fix(buffer,""))){ + continue; + } + *ne = '\0'; + + if(!(vs = httpd_fix(vs,""))){ + continue; + } + strupr(ns); + for(ne=ns;*ne;ne++){ + if(*ne == ' ' || *ne == '-'){ + *ne = '_'; + } + } + + if(strncmp(ns,"CONTENT_",8)){ + env->req->write("HTTP_",5); + } + env->req->write(ns, strlen(ns) + 1); + env->req->write(vs, strlen(vs) + 1); + } + } + + mf->setpos(pos); + return (rcv != 0); +} + +long httpd_authorize(const char* b64pass,char* user=0,char* pass=0) +{ + cBase64 b64; + char* str_tmp = NULL; + char* str_tmp2 = NULL; + char str_buff[128]; + extern FILE* dbgout; + + if(!b64pass){ + /*@*///fprintf(dbgout,"%d - Base64 not given\r\n",__LINE__); + return FALSE; + } + + str_tmp = (char*)b64pass; + if(!(str_tmp = strchr(str_tmp,' '))){ + /*@*///fprintf(dbgout,"%d - Could not find ' '\r\n",__LINE__); + goto Error; + } + str_tmp++; + if(!b64.Decode(str_tmp)){ + /*@*///fprintf(dbgout,"%d - Error decoding Base64\r\n",__LINE__); + goto Error; + } + + str_tmp = (char*)b64.GetBuffer(); + if(!str_tmp || httpd_count(str_tmp,':')!=1 || strlen(str_tmp)<3){ + /*@*///fprintf(dbgout,"%d - Could not find ':'\r\n",__LINE__); + goto Error; + } + str_tmp2 = strchr(str_tmp,':'); + if(!str_tmp2){ + /*@*///fprintf(dbgout,"%d - Could not find ':'\r\n",__LINE__); + goto Error; + } + + *str_tmp2='\0'; + str_tmp2++; + + if(!user){ + /*@*///fprintf(dbgout,"%d - No username given\r\n",__LINE__); + MBotGetPrefString("WWWUser",str_buff,sizeof(str_buff)-1,"::::"); + user = str_buff; + } + if(strcmp(str_tmp,user)!=0)goto Error; + /*@*///fprintf(dbgout,"%d - strcmp(%s,%s)\r\n",__LINE__,str_tmp,user); + + if(!pass){ + /*@*///fprintf(dbgout,"%d - No password given\r\n",__LINE__); + MBotGetPrefString("WWWPass",str_buff,sizeof(str_buff)-1,"::::"); + pass = str_buff; + } + + /*@*///fprintf(dbgout,"%d - strcmp(%s,%s)\r\n",__LINE__,str_tmp2,pass); + if(strcmp(str_tmp2,pass)!=0)goto Error; + + /*@*///fprintf(dbgout,"%d - Authorization SUCCESS\r\n",__LINE__); + return TRUE; +Error: + /*@*///fprintf(dbgout,"%d - Authorization failed\r\n",__LINE__); + return FALSE; +} + +// +long httpd_authorize_host(char* path,char* ip,char* b64pass) +{ + sVS vs = {0}; + char* tmp = strrchr(path,'/'); + char* ntmp; + char rw = '/'; + int root = 0; + int result = 0; + map::iterator loc; + + if(!tmp)return FALSE; + + if(tmp != path){ + *tmp = '\0'; + }else{ + rw = *(tmp + 1); + *(tmp + 1) = '\0'; + root = 1; + } + + vs.path = path; + while(tmp) + { + loc = svr_vs.find(vs.path); + if(svr_vs.end() == loc) + { + if(path == tmp){ + goto Okay; + } + ntmp = strrchr(path,'/'); + *tmp = (tmp==path)?rw:'/'; + if(!ntmp){ + goto Okay; + } + tmp = ntmp; + if(tmp == path){ + rw = *(tmp + 1); + root = 1; + *(tmp+1) = '\0'; + }else{ + rw = '/'; + *tmp = '\0'; + } + }else{ + vs = loc->second; + break; + } + } + + if(!vs.ip){ + goto Okay; + } + + if( *vs.ip && false == ut_str_match(vs.ip, ip)){ + result = -1; + goto Error; + } + + if(vs.auth_req) + { + if(!httpd_authorize(b64pass,vs.user?vs.user:"::::",vs.pass?vs.pass:"::::")){ + goto Error; + } + } + + *(tmp+root) = (root)?rw:'/'; +Okay: + return TRUE; +Error: + *(tmp+root) = (root)?rw:'/'; + return result; +} + +long httpd_client_thread(SOCKET sock) +{ + static timeval tv = {30,30}; + + long rcv = 0; + long post = 0; + long post_len = 0; + long post_got = 0; + long ip = 0; + long ok = 0; + long fs = 0; + char* request = NULL; + char* str_tmp = NULL; + char* str_tmp2 = NULL; + char* cgi_params = NULL; + char* query_str = NULL; + char* req_page; + char buffer[1028]; + + sHTTPDEnv httpd_env; + cutSockf sf; + cutMemf mf; + cutMemf hdr; + cutMemf req; + sFDS fd; + mb_event mbe = {MBT_WEBPAGE, 0}; + + httpd_sname(sock,NULL,(DWORD*)&ip); + + if(!mf.create(4*1024) || !(req.create(1024))){ + //malloc error + goto Error500; + } + //////////////////////////////////////// + sf.open(sock); + //////////////////////////////////////// + *fd.fd_array = sock; + fd.fd_count = 1; + //////////////////////////////////////// + httpd_env.sf = &sf; + httpd_env.mf = &mf; + httpd_env.req = &req; + //////////////////////////////////////// + + while(select(0,(fd_set*)&fd,0,0,&tv) >= 1 && mf.tellpos() < svr_maxrequest) + { + if(!(rcv = httpd_rrecv(sock,buffer,1024,3000))){ + //recv error + httpd_logaccess((const char*)mf.getdata(),500,sf.size(),ip); + goto End; + } + if(!mf.write(buffer,rcv)){ + goto Error500; + } + mf.putc(0); + + if(post == FALSE) + { + if((rcv = mf.size()) > 4 && (request = (char*)strstr((const char*)mf.getdata(),"\r\n\r\n"))) + { + httpd_env.var_offset = req.written(); + if(httpd_parse_headers(&mf, &httpd_env) != 1){ + goto Error; + } + req.setpos(0); + + if(httpd_env.method == 1) + { + post = TRUE; + str_tmp = httpd_hdr_get((const char*)req.getdata(),"CONTENT_LENGTH"); + post_len = (str_tmp)?(strtoul(str_tmp,NULL,10)):(0); + post_got = rcv - (request - ((const char*)mf.getdata()) + 4); + if(!post_len || post_got >= post_len){ + ok = TRUE; + break; + } + } + else + { + ok = TRUE; + break; + } + } + } + else + { + post_got += rcv; + if(post_got >= post_len){ + ok = TRUE; + break; + } + } + } + //////////////////////////////////////// + if(!ok || mf.size() < 10 || !(request = (char*)mf.getdata())){ + goto Error; + } + //////////////////////////////////////// + if(request[4 + post] != '/')goto Error; + + { + str_tmp = strchr(request + 5,' '); + if(!str_tmp)goto Error; + *str_tmp = '\0'; + query_str = strchr(request + 5,'?'); + *str_tmp = ' '; + } + + if(post == TRUE) + { + cgi_params = strstr(request,"\r\n\r\n"); + if(!cgi_params)goto Error; + httpd_env.post_data = cgi_params + 4; + httpd_env.post_length = post_len; + + if(post_got > post_len){ + *(httpd_env.post_data + post_len) = '\0'; + } + cgi_params = NULL; + } + + if(httpd_env.error_code != 200) + { + httpd_writeformatted(&sf,"HTTP/1.0 %u ERROR\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

%u ERROR

",httpd_env.error_code,httpd_env.error_code); + goto End; + } + //////////////////////////////////////// + if(query_str) + { + *query_str = '\0'; + req_page = request + 4 + post; + //*cgi_params = '?'; + } + else + { + str_tmp = strchr(request + 4 + post,' '); + if(!str_tmp)goto Error; + *str_tmp = '\0'; + req_page = request + 4 + post; + //*str_tmp = ' '; + } + + /////////////////////////// + if(svr_auth_required && !httpd_authorize( + httpd_hdr_get((const char*)req.getdata(),"HTTP_AUTHORIZATION") + )) + { + goto Error401; + } + /////////////////////////// + strlwr(req_page); + httpd_unify(req_page); + rcv = strlen(req_page); + + str_tmp = httpd_hdr_get((const char*)req.getdata(),"HTTP_AUTHORIZATION"); + str_tmp2 = inet_ntoa(*(in_addr*)&ip); + + + strncpy(buffer,req_page,sizeof(buffer)-1); + ok = httpd_unify(buffer); + if(ok && buffer[ok-1]!='/'){buffer[ok]='/'; buffer[ok+1]='\0';} + + if((ok = httpd_authorize_host(buffer,str_tmp2?str_tmp2:"0.0.0.0",str_tmp?str_tmp:"")) < 1){ + if(ok < 0){ + goto Error403; + }else{ + goto Error401; + } + } + + /////////////////////////// + if(!(*req_page)){ + _snprintf(buffer,MAX_PATH,"%s/index.php",svr_wwwroot); + req_page = "/index.php"; + }else if(req_page[rcv-1]=='/'){ + _snprintf(buffer,MAX_PATH,"%s%sindex.php",svr_wwwroot,req_page); + req_page = buffer + strlen(svr_wwwroot); + }else{ + _snprintf(buffer,MAX_PATH,"%s%s",svr_wwwroot,req_page); + } + httpd_unify(buffer); + + ok = help_fileexists(buffer,&fs); + + if(!ok){ + ok = help_direxists(buffer); + if(!ok){ + goto Error404; + }else{ + httpd_writeformatted(&sf,"HTTP/1.0 301 Moved Permanently\r\nConnection: close\r\nLocation: %s/\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

301 Document moved permanently!

",req_page); + goto End; + } + }else{ + //do the authorization for vhosts + str_tmp = httpd_getextension(buffer); + + if(str_tmp && true == ut_str_match(".php*", str_tmp)) + { + if(query_str){ + *query_str = '?'; + if((str_tmp2 = strchr(query_str+1,' ')) || (str_tmp2 = strchr(query_str,'\r'))){ + *str_tmp2 = '\0'; + } + } + + mbe.t1 = MBE_HTTPDENV; + mbe.p1 = (void*)&httpd_env; + + if(!httpd_init_hdr(&hdr)){ + goto Error500; + } + + httpd_sname(sock,&req,NULL); + req.write("SERVER_SOFTWARE\0MBot (c) Piotr Pawluczuk (www.piopawlu.net)",60); + //SCRIPT_NAME + req.write("SCRIPT_NAME",12); + req.write(req_page,strlen(req_page)+1); + //PHP_SELF + req_page = strrchr(req_page,'/'); + if(!req_page){goto Error404;} + req_page++; + req.write("PHP_SELF",9); + req.write(req_page,strlen(req_page)+1); + //END OF VARIABLES + req.putc(0); + + if(!LPHP_ExecutePage(buffer,(query_str)?(query_str+1):NULL, + (const char**)&sf,(void*)&mbe,(LPHP_ENVCB)httpd_php_cb,1)){ + goto Error500; + } + + if(httpd_env.out_started == 0){ + httpd_send_headers(&httpd_env); + } + httpd_logaccess((const char*)mf.getdata(),200,sf.size(),ip); + goto End; + } + else + { + if(httpd_sendfile(buffer,&httpd_env,buffer)){ + httpd_logaccess((const char*)mf.getdata(),200,sf.size(),ip); + }else{ + httpd_logaccess((const char*)mf.getdata(),404,sf.size(),ip); + } + goto End; + } + } + + /////////////////////////// +Error: + /////////////////////////// + httpd_logaccess((const char*)mf.getdata(),400,sf.size(),ip); + httpd_writestring(&sf,"HTTP/1.0 400 Bad Request\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

400 Bad Request

"); + goto End; + /////////////////////////// +Error500: + /////////////////////////// + httpd_logaccess((const char*)mf.getdata(),500,sf.size(),ip); + if(httpd_env.out_started == 0) + { + httpd_writestring(&sf,"HTTP/1.0 500 Internal Server Error\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

500 Internal Server Error

"); + } + goto End; + /////////////////////////// +Error401: + /////////////////////////// + httpd_logaccess((const char*)mf.getdata(),401,sf.size(),ip); + httpd_writestring(&sf,"HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"MSP Server HTTPD\"\r\nstatus: 401 Unauthorized\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

401 Authorization Required

"); + goto End; + /////////////////////////// +Error403: + /////////////////////////// + httpd_logaccess((const char*)mf.getdata(),401,sf.size(),ip); + httpd_writestring(&sf,"HTTP/1.0 403 Access DENIED\r\nWWW-Authenticate: Basic realm=\"MSP Server HTTPD\"\r\nstatus: 403 Access DENIED\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

403 Access DENIED

"); + goto End; + /////////////////////////// +Error404: + /////////////////////////// + httpd_logaccess((const char*)mf.getdata(),404,sf.size(),ip); + httpd_writestring(&sf,"HTTP/1.0 404 Not Found\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n

404 Not Found

"); + /////////////////////////// +End: + /////////////////////////// + sf.close(); + mf.close(); + svr_cur_clients --; + return 0; +} + +long WINAPI httpd_launch_client(void* st) +{ + httpd_client_thread((SOCKET)st); + svr_q_tc--; + SetEvent(svr_q_event); + return 0; +} +long WINAPI httpd_server_queue(void* param) +{ + static sHTTPSync* task; + static HANDLE hThread; + static DWORD result; + + while(1) + { + if((result = WaitForSingleObject(svr_q_event,INFINITE)) == WAIT_OBJECT_0) + { + while(svr_q_tc < svr_max_clients) + { + svr_q_queue.Lock(); + task = (sHTTPSync*)svr_q_queue.m_head; + + if(!task) + { + svr_q_queue.Unlock(); + break; + } + else + { + svr_q_queue.DelLocked(task); + svr_q_queue.Unlock(); + } + + if((DWORD)task->to < GetTickCount()) + { + closesocket((SOCKET)task->s); + my_memfree(task); + } + else + { + svr_q_tc++; + hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)httpd_launch_client,(LPVOID)task->s,NULL,&result); + + my_memfree(task); + + if(!hThread) + { + svr_q_tc--; + } + else + { + CloseHandle(hThread); + } + }//else + }//while + }//if + else + { + return 0; + } + }//while(1) + return 1; +} + +long WINAPI httpd_server_thread(void* param) +{ + static WSADATA wsad = {0}; + static SOCKADDR_IN server = {0}; + static SOCKADDR_IN client = {0}; + static SOCKET as = INVALID_SOCKET; + static int client_size = sizeof(client); + + server.sin_family = AF_INET; + server.sin_port = htons(DBGetContactSettingWord(NULL,MBOT,"WWWPort",8081)); + server.sin_addr.s_addr = htonl(INADDR_ANY); + + MBotGetPrefString("WWWIPMask",svr_allowed_ip,sizeof(svr_allowed_ip)-1,"*"); + if(!MBotGetPrefString("WWWRoot",svr_wwwroot,sizeof(svr_wwwroot)-1,"")) +{ + _snprintf(svr_wwwroot,sizeof(svr_wwwroot)-1,"%s/mbot/www",g_root); + } + + svr_wwwroot_len = strlen(svr_wwwroot); + + svr_auth_required = DBGetContactSettingByte(NULL,MBOT,"WWWAuthR",0); + svr_max_clients = DBGetContactSettingWord(NULL,MBOT,"WWWMaxC",5); + svr_timeout = DBGetContactSettingWord(NULL,MBOT,"WWWTimeout",60); + + if(svr_max_clients == 0 || svr_max_clients > 20){ + svr_max_clients = 5; + } + if(svr_timeout < 10 || svr_timeout > 120){ + svr_timeout = 30; + } + svr_timeout *= 1000; + + if(WSAStartup(MAKEWORD(2,2),&wsad) == SOCKET_ERROR) + { + MB_Popup("HTTPDeamon","Could not initialize sockets!"); + httpd_logaccess("ERROR: Could not initialize sockets!",GetLastError(),0,0); + goto Error; + } + + if(!httpd_mime_init()){ + MB_Popup("HTTPDeamon","Could not initialize MIME table!"); + httpd_logaccess("ERROR: Could not initialize MIME table!",GetLastError(),0,0); + goto Error; + } + + if(!httpd_vs_init()){ + MB_Popup("HTTPDeamon","Could not initialize VS table!"); + goto Error; + } + + + svr_ls = socket(AF_INET,SOCK_STREAM,0); + + if(svr_ls == INVALID_SOCKET) + { + MB_Popup("HTTPDeamon","Could not create socket!"); + httpd_logaccess("ERROR: Could not create socket!",GetLastError(),0,0); + goto Error; + } + + if(bind(svr_ls,(sockaddr*)&server,sizeof(server))==-1) + { + MB_Popup("HTTPDeamon","Could not bind the server socket!"); + httpd_logaccess("ERROR: Could not bind the server socket!",GetLastError(),0,0); + closesocket(svr_ls); + goto Error; + } + + httpd_logaccess("SYSTEM: Server started!",0,0,0); + + while(1) + { + if(listen(svr_ls,5)==-1){ + closesocket(svr_ls); + MB_Popup("HTTPDeamon","An error occured while listening!"); + httpd_logaccess("ERROR: An error occured while listening!",GetLastError(),0,0); + goto Error; + } + + if((as = accept(svr_ls,(sockaddr*)&client,(int*)&client_size))!=INVALID_SOCKET) + { + char* client_ip = inet_ntoa(client.sin_addr); + + if(false == ut_str_match(svr_allowed_ip, client_ip)){ + closesocket(as); + } + else + { + if(svr_q_queue.m_count < 100){ + httpd_queue(as); + }else{ + httpd_logaccess("SYSTEM: Queue FULL!",svr_q_queue.m_count,0,0); + closesocket(as); + } + } + } + } +Error: + svr_mimes.clear(); + svr_vs.clear(); + + if(svr_ls != INVALID_SOCKET){ + closesocket(svr_ls); + svr_ls = INVALID_SOCKET; + } + CloseHandle(svr_hTh); + return 0; +} + +long httpd_startup() +{ + static unsigned long tmpid; + char tmp[MAX_PATH]; + + //////////// + tzset(); + //////////// + + svr_q_event = CreateEvent(0,0,0,0); + if(!svr_q_event){ + MB_Popup("HTTPDeamon","Could not create queue sync event!"); + httpd_logaccess("ERROR: Could not create queue sync event!",GetLastError(),0,0); + return 0; + } + if(!(svr_q_hTh = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)httpd_server_queue,NULL,0,&tmpid))) + { + MB_Popup("HTTPDeamon","Could not create queue thread!"); + httpd_logaccess("ERROR: Could not create queue thread!",GetLastError(),0,0); + CloseHandle(svr_q_event); + svr_q_event = NULL; + return 0; + } + + if(DBGetContactSettingByte(NULL,MBOT,"WWWLog",1)==1){ + InitializeCriticalSectionAndSpinCount(&svr_log_cs,0x80000100); + _snprintf(tmp,sizeof(tmp)-1,"%s\\mbot\\httpd.log",g_root); + svr_log = fopen(tmp,"a+b"); + if(!svr_log){ + MB_Popup("HTTPDeamon","Could not create log file!"); + httpd_logaccess("ERROR: Could not create log file!",GetLastError(),0,0); + DeleteCriticalSection(&svr_log_cs); + } + } + + if(!(svr_hTh = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)httpd_server_thread,NULL,0,&tmpid))) + { + MB_Popup("HTTPDeamon","Could not create server thread!"); + httpd_logaccess("ERROR: Could not create server thread!",GetLastError(),0,0); + + CloseHandle(svr_q_event); + TerminateThread(svr_q_hTh,0); + CloseHandle(svr_q_hTh); + + svr_q_event = NULL; + svr_q_hTh = NULL; + return 0; + } + return 1; +} + +long httpd_shutdown() +{ + if(svr_hTh) + { + TerminateThread(svr_hTh,0); + CloseHandle(svr_hTh); + svr_hTh = NULL; + } + if(svr_q_hTh) + { + TerminateThread(svr_q_hTh,0); + CloseHandle(svr_q_hTh); + svr_q_hTh = NULL; + } + if(svr_q_event){ + CloseHandle(svr_q_event); + svr_q_event = NULL; + } + if(svr_ls && svr_ls!=INVALID_SOCKET){ + closesocket(svr_ls); + svr_ls = 0; + } + + httpd_logaccess("SYSTEM: Server stopped!",0,0,0); + if(svr_log){ + DeleteCriticalSection(&svr_log_cs); + fclose(svr_log); + svr_log = NULL; + } + + svr_mimes.clear(); + svr_vs.clear(); + return 1; +} + +#endif //_NOHTTPD_ \ No newline at end of file diff --git a/mBot/src/mbot/smanager.cpp b/mBot/src/mbot/smanager.cpp new file mode 100644 index 0000000..66318db --- /dev/null +++ b/mBot/src/mbot/smanager.cpp @@ -0,0 +1,434 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "helpers.h" +#include "functions.h" +#include "smanager.h" + +CSyncList sm_list; +PHANDLER sm_handlers[32]={0}; +CSECTION sm_sync = {0}; +int sm_maxe = fcn_log2(MB_EVENT_FILE_IN) + 1; + +void sman_startup() +{ + InitializeCriticalSectionAndSpinCount(&sm_sync,0x80000100); +} +void sman_shutdown() +{ + if(!hConsole)return; + + sman_lock(); + for(int i=0;inext; + my_memfree(ph); + ph = tmp; + } + } + sman_unlock(); + + while(1) + { + PPHP php; + PPHP tmp; + + sm_list.Lock(); + php = (PPHP)sm_list.m_head; + while(php) + { + tmp = (PPHP)php->next; + if(php->szBuffered){ + my_memfree(php->szBuffered); + } + if(php->szFilePath){ + my_memfree(php->szFilePath); + } + my_memfree(php); + php = tmp; + } + sm_list.Unlock(); + break; + } + DeleteCriticalSection(&sm_sync); +} + +void sman_insertafter(PHANDLER a,PHANDLER b) +{ + if(a->next){ + a->next->prev = b; + b->next = a->next; + } + b->prev = a; + a->next = b; +} + +void sman_inserthead(PHANDLER a,PHANDLER b) +{ + a->prev = b; + b->next = a; + b->prev = NULL; +} + +PHANDLER sman_handler_add(PPHP s,long event_id,long priority,long flags) +{ + sman_lock(); + + PHANDLER* head; + PHANDLER f; + PHANDLER nhandler; + char* szFunction = (char*)help_get_funct_name(event_id); + + head = &sm_handlers[fcn_log2(event_id)]; + + if(*head){ + f = *head; + while(f) + { + if(f->php == s){ + f->lFlags &= ~(MBOT_FLAG_INACTIVE); + sman_unlock(); + return f; + } + f = (PHANDLER)f->next; + } + } + + if(!szFunction || !(nhandler=(PHANDLER)my_malloc(sizeof(SHANDLER)))){ + goto Error; + } + memset(nhandler,0,sizeof(SHANDLER)); + + nhandler->php = s; + nhandler->lPriority = priority; + nhandler->szFcnName = szFunction; + + head = &sm_handlers[fcn_log2(event_id)]; + + if(*head == NULL){ + *head = nhandler; + }else{ + f = *head; + + if(f->lPriority < priority){ + sman_inserthead(f,nhandler); + *head = nhandler; + }else{ + while(1){ + if(f->next == NULL || f->next->lPriority < priority){ + sman_insertafter(f,nhandler); + break; + } + f = f->next; + } + } + } + sman_unlock(); + return nhandler; +Error: + sman_unlock(); + return NULL; +} + +PHANDLER sman_handler_get(long event_id) +{ + return sm_handlers[fcn_log2(event_id)]; +} + +PHANDLER sman_handler_find(PPHP s,long event_id) +{ + PHANDLER first; + + sman_lock(); + first = sm_handlers[fcn_log2(event_id)]; + + if(!first) + { + sman_unlock(); + return NULL; + } + + while(first) + { + if(first->php == s)break; + first = first->next; + } + sman_unlock(); + return first; +} + +void sman_handler_disable(PHANDLER h) +{ + sman_lock(); + h->lFlags |= MBOT_FLAG_INACTIVE; + sman_unlock(); +} + +void sman_handler_enable(PHANDLER h) +{ + sman_lock(); + h->lFlags &= ~(MBOT_FLAG_INACTIVE); + sman_unlock(); +} + +PPHP sman_register(const char* szPathname,long cache) +{ + static char* body; + static char* path; + PPHP php; + + for(char* a = (char*)strchr(szPathname,'\\');a;a=strchr(a,'\\'))*a = '/'; + + sm_list.Lock(); + php = (PPHP)sm_list.m_head; + while(php){ + if(strcmp(php->szFilePath,szPathname)==0){ + php->lRefCount++; + goto End; + } + php = (PPHP)php->next; + } + //cache if necessary + if(cache){ + if(!(body = (char*)help_cache_php_file(szPathname))){ + goto End; + } + }else{ + body = NULL; + } + path = my_strdup(szPathname); + if(!path){ + goto Error; + } + php = (PPHP)my_malloc(sizeof(SPHP)); + if(!php){ + goto Error; + } + memset(php,0,sizeof(SPHP)); + php->lRefCount = 1; + php->szBuffered = body; + php->szFilePath = path; + sm_list.AddLocked(php); + goto End; +Error: + if(cache && body)my_memfree((void*)body); + if(path)my_memfree((void*)path); +End: + sm_list.Unlock(); + return php; +} + +PPHP sman_getbyfile(const char* szPathname) +{ + PPHP php; + + strlwr((char*)szPathname); + for(char* a = (char*)strchr(szPathname,'\\');a;a=strchr(a,'\\'))*a = '/'; + + sm_list.Lock(); + php = (PPHP)sm_list.m_head; + while(php) + { + if(!stricmp(php->szFilePath,szPathname)){ + php->lRefCount++; + goto End; + } + php = (PPHP)php->next; + } + End: + sm_list.Unlock(); + return php; +} + +long sman_uninstall(PPHP s,long del) +{ + extern CSyncList g_mlist; + extern CSyncList g_svlist; + + PHANDLER ph; + sMFSync *mfs; + sHESync *hfs; + + sm_list.Lock(); + if(s->lUsgCount != 0){ + s->lFlags |= MBOT_FLAG_SHALLDIE | (del==1?MBOT_FLAG_DELETE:0); + sm_list.Unlock(); + return 0; + } + sman_lock(); + + for(int i=0;i<32 && s->lRefCount;i++) + { + ph = sm_handlers[i]; + while(ph && s->lRefCount) + { + if(ph->php == s){ + ph->lFlags |= MBOT_FLAG_INACTIVE | MBOT_FLAG_DELETE; + s->lRefCount--; + break; + } + ph = ph->next; + } + } + + //check if not using menu stuff + g_mlist.Lock(); + mfs = (sMFSync*)g_mlist.m_head; + while(mfs) + { + if(mfs->php == s){ + CLISTMENUITEM mi={0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIF_GRAYED | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM,(LPARAM)mfs->hMenu,(LPARAM)&mi); + } + mfs = (sMFSync*)mfs->next; + } + g_mlist.Unlock(); + //check if not using service stuff + g_svlist.Lock(); + hfs = (sHESync*)g_svlist.m_head; + while(hfs) + { + if(hfs->php == s) + { + sHESync* tmp = (sHESync*)hfs->next; + if(hfs->hFunction){ + DestroyServiceFunction((HANDLE)hfs->hFunction); + }else if(hfs->hHook){ + UnhookEvent((HANDLE)hfs->hHook); + } + my_memfree(hfs->pCode); + g_svlist.DelLocked(tmp); + my_memfree(tmp); + hfs = tmp; + }else{ + hfs = (sHESync*)hfs->next; + } + } + g_svlist.Unlock(); + + //check if not using cron stuff + cron_unregister_param(s); + + if(s->szBuffered){ + my_memfree(s->szBuffered); + s->szBuffered = NULL; + } + sm_list.Unlock(); + sman_unlock(); + return (!del)?1:DeleteFile(s->szFilePath); +} + +void sman_unregister(PPHP s) +{ + sm_list.Lock(); + s->lRefCount--; + if(s->lRefCount == 0) + { + if(s->szBuffered){ + my_memfree((void*)s->szBuffered); + } + if(s->szFilePath){ + my_memfree((void*)s->szFilePath); + } + sm_list.DelLocked(s); + } + sm_list.Unlock(); +} + +void sman_inc(PPHP s) +{ + sm_list.Lock(); + s->lUsgCount++; + sm_list.Unlock(); +} +void sman_dec(PPHP s) +{ + sm_list.Lock(); + s->lUsgCount--; + if((s->lFlags & MBOT_FLAG_SHALLDIE) && s->lUsgCount == 0){ + sm_list.Unlock(); + sman_uninstall(s,(s->lFlags & MBOT_FLAG_DELETE)!=0); + }else{ + sm_list.Unlock(); + } +} + +void sman_incref(PPHP s) +{ + sm_list.Lock(); + s->lRefCount++; + sm_list.Unlock(); +} +void sman_decref(PPHP s) +{ + sm_list.Lock(); + s->lRefCount--; + if(s->lRefCount <= 0) + { + if(s->szBuffered){ + my_memfree((void*)s->szBuffered); + } + if(s->szFilePath){ + my_memfree((void*)s->szFilePath); + } + sm_list.DelLocked(s); + } + sm_list.Unlock(); +} + +long sman_recache(PPHP s) +{ + long result=0; + sm_list.Lock(); + if(s->lFlags)s->lFlags = 0; + if(s->lUsgCount == 0) + { + if(s->szBuffered){ + my_memfree(s->szBuffered); + } + s->szBuffered = (char*)help_cache_php_file(s->szFilePath); + result = (s->szBuffered != NULL); + } + sm_list.Unlock(); + return result; +} +long sman_uncache(PPHP s) +{ + long result=0; + sm_list.Lock(); + if(s->lFlags)s->lFlags = 0; + if(s->lUsgCount == 0) + { + if(s->szBuffered){ + my_memfree((void*)s->szBuffered); + s->szBuffered = NULL; + } + result = 1; + } + sm_list.Unlock(); + return result; +} \ No newline at end of file diff --git a/mBot/src/mbot/smanager.h b/mBot/src/mbot/smanager.h new file mode 100644 index 0000000..e8349ce --- /dev/null +++ b/mBot/src/mbot/smanager.h @@ -0,0 +1,74 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _SMANAGER_H__ +#define _SMANAGER_H__ + +#include "helpers.h" +#include "sync.h" +#pragma once + +typedef struct sScript : public sSync +{ + char* szFilePath; + char* szBuffered; + char* szDescription; + long lRefCount; + long lUsgCount; + long lFlags; +}SPHP,*PPHP; + +typedef struct sHandler +{ + char* szFcnName; + long lPriority; + long lFlags; + PPHP php; + + sHandler* next; + sHandler* prev; +}SHANDLER,*PHANDLER; + +typedef CRITICAL_SECTION CSECTION; + +void sman_unregister(PPHP s); +void sman_inc(PPHP s); +void sman_dec(PPHP s); +void sman_incref(PPHP s); +void sman_decref(PPHP s); +long sman_recache(PPHP s); +long sman_uncache(PPHP s); +long sman_uninstall(PPHP s,long del); +PPHP sman_register(const char* szPathname,long cache); +PPHP sman_getbyfile(const char* szPathname); + +void sman_startup(); +void sman_shutdown(); + +PHANDLER sman_handler_add(PPHP s,long event_id,long priority,long flags); +PHANDLER sman_handler_get(long event_id); +PHANDLER sman_handler_find(PPHP s,long event_id); +void sman_handler_enable(PHANDLER h); +void sman_handler_disable(PHANDLER h); + +#define sman_lock() EnterCriticalSectionX(&sm_sync) +#define sman_unlock() LeaveCriticalSectionX(&sm_sync) + +#endif //_SMANAGER_H__ \ No newline at end of file diff --git a/mBot/src/mbot/sync.cpp b/mBot/src/mbot/sync.cpp new file mode 100644 index 0000000..ede1c65 --- /dev/null +++ b/mBot/src/mbot/sync.cpp @@ -0,0 +1,157 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "sync.h" + +CSyncList::CSyncList() +{ + m_count = 0; + m_head = m_tail = NULL; + InitializeCriticalSectionAndSpinCount(&m_cts,0x80000100); +} + +CSyncList::~CSyncList() +{ + m_count = 0; + m_head = m_tail = NULL; + DeleteCriticalSection(&m_cts); +} + +int CSyncList::Add(sSync* s) +{ + Lock(); + if(!m_head){ + m_head = m_tail = s; + }else{ + m_tail->next = s; + s->prev = m_tail; + m_tail = s; + } + m_count++; + Unlock(); + return 1; +} + +int CSyncList::AddLocked(sSync* s) +{ + if(!m_head){ + m_head = m_tail = s; + }else{ + m_tail->next = s; + s->prev = m_tail; + m_tail = s; + } + m_count++; + return 1; +} +int CSyncList::Del(sSync* s) +{ + Lock(); + if(m_count == 1) + { + m_tail = m_head = NULL; + }else{ + if(!s->next && !s->prev)goto Skip; + + if(m_head == s){ + m_head = s->next; + }else if(m_tail == s){ + m_tail = s->prev; + } + + if(s->prev){ + s->prev->next = s->next; + } + if(s->next){ + s->next->prev = s->prev; + } + } + s->next = s->prev = NULL; + m_count--; +Skip: + Unlock(); + return 1; +} +int CSyncList::DelLocked(sSync* s) +{ + if(m_count == 1) + { + if(m_head != s)return 1; + m_tail = m_head = NULL; + }else{ + if(!s->next && !s->prev)return 1; + + if(m_head == s){ + m_head = s->next; + }else if(m_tail == s){ + m_tail = s->prev; + } + + if(s->prev){ + s->prev->next = s->next; + } + if(s->next){ + s->next->prev = s->prev; + } + } + + s->next = s->prev = NULL; + m_count--; + return 1; +} + +int CSyncList::Release(SYNC_RELEASE fp) +{ + Lock(); + sSync* tmp; + sSync* cur = m_head; + while(cur) + { + tmp = cur->next; + fp(cur); + cur = tmp; + } + m_head = m_tail = NULL; + Unlock(); + return TRUE; +} + +int CSyncList::Lock() +{ + try{ + EnterCriticalSectionX(&m_cts); + }catch(...){ + MBLOGEX("Error entering critical section!"); + return FALSE; + } + return TRUE; +} +int CSyncList::Unlock() +{ + try{ + LeaveCriticalSectionX(&m_cts); + }catch(...){ + MBLOGEX("Error leaving critical section!"); + return FALSE; + } + return TRUE; +} \ No newline at end of file diff --git a/mBot/src/mbot/sync.h b/mBot/src/mbot/sync.h new file mode 100644 index 0000000..3fd7a82 --- /dev/null +++ b/mBot/src/mbot/sync.h @@ -0,0 +1,63 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ + +#ifndef _SYNC_H_ +#define _SYNC_H_ + +#define WINVER 0x0500 +#define _WIN32_WINNT 0x0500 +#define _WIN32_IE 0x0501 +#define _WIN32_WINDOWS 0x0500 +#include +#pragma once + +typedef void (*SYNC_RELEASE)(void* data); + +struct sSync +{ + sSync* next; + sSync* prev; +public: + sSync(){ + next = prev = NULL; + } +}; + +class CSyncList +{ +public: + CSyncList(); + ~CSyncList(); +public: + int Add(sSync* hs); + int AddLocked(sSync* hs); + int Del(sSync* hs); + int DelLocked(sSync* s); + int Lock(); + int Unlock(); + int Release(SYNC_RELEASE fp); +public: + sSync* m_head; + sSync* m_tail; + unsigned long m_count; + CRITICAL_SECTION m_cts; +}; +#endif //_SYNC_H_ \ No newline at end of file diff --git a/mBot/src/mbot/window.cpp b/mBot/src/mbot/window.cpp new file mode 100644 index 0000000..52bb41d --- /dev/null +++ b/mBot/src/mbot/window.cpp @@ -0,0 +1,1255 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "mbot.h" +#include "functions.h" +#include "window.h" +#include "config.h" + +extern CRITICAL_SECTION csConsole; +extern cXmlDoc cSettings; +extern CSyncList sm_list; +extern HICON hMBotIcon; +extern FILE* dbgout; +extern const char* pszMonospacedFont; +extern long lConFontSize; + +HIMAGELIST hImagelist = NULL; +HBITMAP hBitmap = NULL; +WNDPROC fpOldWndProc = NULL; +HFONT hVerdanaFont = NULL; +HFONT hMonospacedFont = NULL; +HMENU hMenu = NULL; +BOOL bLocked = FALSE; + +const char* rtf_start = "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fmodern Lucida Console;}}\n\ +{\\colortbl;\\red255\\green0\\blue0;\\red63\\green172\\blue51;\\red47\\green86\\blue176;}\\fs21 "; +const char* rtf_stop = "}"; + +struct mbot_es +{ + const char* ptr; + long left; + long cb; + const char* buff[3]; + unsigned short length[3]; +}; + +void MBotDragAccept(HDROP wParam); + +static DWORD CALLBACK MBotESCallback(mbot_es* es,LPBYTE pbBuff,long cb,long *pcb) +{ + if(!es->ptr && es->cb == 0){ + es->ptr = es->buff[0]; + es->left = es->length[0]; + } + + if(!es->left){ + *pcb = 0; + return 0; + } + + if(es->left > cb){ + memcpy(pbBuff,es->ptr,cb); + es->left -= cb; + es->ptr += cb; + *pcb = cb; + }else{ + memcpy(pbBuff,es->ptr,es->left); + *pcb = es->left; + es->ptr += es->left; + es->left = 0; + } + + if(!es->left && es->cb < 3){ + es->ptr = es->buff[es->cb]; + es->left = es->length[es->cb++]; + } + + return 0; +} + +void MBotConsoleAppendText(const char* txt,long formatted) +{ + GETTEXTLENGTHEX stGTL = {GTL_NUMCHARS,CP_ACP}; + EDITSTREAM es = {0}; + SCROLLINFO si = {0}; + CHARRANGE sel; + mbot_es mbes = {0,0,0,{rtf_start,txt,rtf_stop},{strlen(rtf_start),strlen(txt),1}}; + long stTxtLength = 0; + + if(!(formatted=0)){ + mbes.cb = 3; + mbes.ptr = mbes.buff[1]; + mbes.left = mbes.length[1]; + } + + if(!hConsole){ + return; + } + + try{ + EnterCriticalSectionX(&csConsole); + }catch(...){ + return; + } + + stGTL.codepage = CP_ACP; + stGTL.flags = GTL_PRECISE; + + SendMessage(hConsole,EM_HIDESELECTION, TRUE, 0); + stTxtLength = SendMessage(hConsole,EM_GETTEXTLENGTHEX,(WPARAM)&stGTL,0); + sel.cpMin = sel.cpMax = stTxtLength; + SendMessage(hConsole,EM_EXSETSEL,0,(LPARAM) &sel); + + es.dwCookie = (DWORD)&mbes; + es.pfnCallback = (EDITSTREAMCALLBACK)MBotESCallback; + SendMessage(hConsole,EM_STREAMIN,(WPARAM)formatted?(SF_RTF | SFF_SELECTION):(SF_TEXT | SFF_SELECTION),(LPARAM)&es); + + + SendMessage(hConsole,EM_HIDESELECTION, TRUE, 0); + SendMessage(hConsole,EM_SETSEL,-1,0); + SendMessage(hConsole,WM_KILLFOCUS,0,0); + + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hConsole,SB_VERT, &si); + si.fMask = SIF_POS; + si.nPos = si.nMax - si.nPage + 1; + SetScrollInfo(hConsole,SB_VERT, &si, TRUE); + + PostMessage(hConsole,WM_VSCROLL,SB_BOTTOM,0); + LeaveCriticalSectionX(&csConsole); +} + +void MBotConsoleClear() +{ + static mbot_es mbes = {0,0,0,{rtf_start,rtf_stop,0},{strlen(rtf_start),1,0}}; + EDITSTREAM es = {0}; + + if(!hConsole){ + return; + } + + try{ + EnterCriticalSectionX(&csConsole); + }catch(...){ + return; + } + es.dwCookie = (DWORD)&mbes; + es.pfnCallback = (EDITSTREAMCALLBACK)MBotESCallback; + SendMessage(hConsole,EM_STREAMIN,(WPARAM)SF_RTF,(LPARAM)&es); + LeaveCriticalSectionX(&csConsole); +} + +void MBotDlgOnSize(HWND hWnd) +{ + RECT rc; + long h; + long tbh; + + GetClientRect(hToolbar,&rc); + tbh = rc.bottom - rc.top; + GetClientRect(hWnd,&rc); + h = ((rc.bottom - rc.top)*72)/100 - tbh; + + SetWindowPos(hConsole,NULL,0,0,(rc.right - rc.left),h,SWP_NOZORDER); + SetWindowPos(hToolbar,NULL,0,h+1,(rc.right - rc.left),tbh,SWP_NOZORDER); + SetWindowPos(hCommandBox,NULL,0,h+tbh+1,(rc.right - rc.left),(rc.bottom - rc.top) - h - tbh - 1,SWP_NOZORDER); +} + +static TBBUTTON tbb[]= +{ + {2,NULL,TBSTATE_ENABLED,TBSTYLE_SEP,NULL,NULL}, + {0,ID_EXECUTE,TBSTATE_ENABLED,TBSTYLE_BUTTON, NULL,NULL}, + {1,ID_CLEAR,TBSTATE_ENABLED,TBSTYLE_BUTTON, NULL,NULL}, + {2,ID_LINEWRAP,TBSTATE_ENABLED,TBSTYLE_BUTTON|TBSTYLE_CHECK, NULL,NULL}, + //{3,ID_MBHELP,TBSTATE_ENABLED,TBSTYLE_BUTTON, NULL,NULL}, + {4,ID_MBINSTALL,TBSTATE_ENABLED,TBSTYLE_DROPDOWN|BTNS_WHOLEDROPDOWN, NULL,NULL}, +}; + +static char pszCommand[4096]; + +void WINAPI MBotDlgExecute(void* cut) +{ + static PHPR retval = PHPR_UNKNOWN; + static char* cmd; + static SYSTEMTIME st; + static LONG len=0; + + string body; + + if(GetWindowTextLength(hCommandBox) >= sizeof(pszCommand)){ + MBotConsoleAppendText("Command too long!\r\n",1); + SendDlgItemMessage(hDialog,IDC_TOOLBAR,TB_ENABLEBUTTON,ID_EXECUTE,TRUE); + EnableWindow(hCommandBox,TRUE); + bLocked = FALSE; + return; + } + + len = GetWindowText(hCommandBox,pszCommand,sizeof(pszCommand)-1); + + if(cut && len > 4){ + pszCommand[len - 4]='\0'; + } + + if(strncmp(pszCmdTag, pszCommand, lCmdTagLen)==0) + { + if(!(lh_flags & MB_EVENT_COMMAND)) + { + MBotConsoleAppendText("No command handler registered!\r\n",1); + } + else + { + cmd = pszCommand + lCmdTagLen; + while(*cmd && isspace(*cmd))cmd++; + if(!(*cmd)){ + MBotConsoleAppendText("Command is empty!\r\n",1); + goto End; + } + + retval = MBCommandExecute(cmd,0,NULL); + if(retval != PHPR_DROP && retval != PHPR_BREAK){ + MBotConsoleAppendText("Command not found!\r\n",1); + } + else + { + GetSystemTime(&st); + + /*body.Format("%.2d:%.2d:%.2d \'%s%s\'\r\n", + st.wHour,st.wMinute,st.wSecond,pszCmdTag,cmd); + + MBotConsoleAppendText(body,1);*/ + SetWindowText(hCommandBox, pszCmdTag); + } + } + } + else if(strncmp(pszPhpTag,pszCommand,lPhpTagLen)==0) + { + mb_event mbe = {MBT_CCSCRIPT,0,0}; + + cmd = pszCommand + lPhpTagLen; + while(*cmd && isspace(*cmd))cmd++; + if(!(*cmd))goto End; + + body = "$cid=0;\r\n"; + body.append(cmd); + + if(LPHP_ExecuteDirect(body.data(), NULL, (void*)&mbe) == FALSE){ + MB_Popup(PHP_ERROR_TITLE,PHP_ERROR_EXECUTION); + }else{ + SetWindowText(hCommandBox,""); + } + }else{ + MBotConsoleAppendText("Remember to use command/script tags!\r\n",1); + } + +End: + SendDlgItemMessage(hDialog,IDC_TOOLBAR,TB_ENABLEBUTTON,ID_EXECUTE,TRUE); + EnableWindow(hCommandBox,TRUE); + bLocked = FALSE; + return; +} + +void MBotDlgSetWrap(long set) +{ + SendMessage(hConsole,EM_SETTARGETDEVICE,NULL,(set)?(0):(1)); +} + +LRESULT WINAPI MBotNewWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + static DWORD lr = 0; + + switch(uMsg) + { + case WM_KEYUP: + if(wParam == VK_RETURN) + { + if(GetTickCount() - lr < 600){ + SendMessage(hDialog,WM_USER + 3,0,0); + }else{ + lr = GetTickCount(); + } + }else{ + if(wParam == VK_DOWN){ + PostMessage(hDialog,WM_USER + 5,0,0); + } + lr = 0; + } + break; + case WM_DROPFILES: + MBotDragAccept((HDROP)wParam); + break; + } + return CallWindowProc(fpOldWndProc,hWnd, uMsg, wParam, lParam); +} + +long MBotInstallScript(char* path) +{ + char* ff; + char tmpp[MAX_PATH + 1]; + int length; + + length = strlen(path); + ff = path + length - 4; + + while(ff != path && *ff!='\\' && *ff!='/'){ + ff--; + } + if(ff!=path)ff++; + + if(_snprintf(tmpp,MAX_PATH,"%s\\mbot\\scripts\\autoload\\%s",g_root,ff) < 0){ + MBotConsoleAppendText("File path is too long!\r\n",1); + return 0; + } + + if(help_fileexists(tmpp)) + { + char msg[MAX_PATH + 64]; + _snprintf(msg,MAX_PATH + 63,"Following file already exists:\n'%s'\nOverwrite?",tmpp); + if(MessageBox(NULL,msg,"MBot",MB_ICONQUESTION | MB_YESNO) == IDNO){ + return -1; + } + } + + if(!CopyFile(path,tmpp,FALSE)) + { + MBotConsoleAppendText("Could not copy the file!\r\n",0); + return 0; + } + else + { + if(DBGetContactSettingByte(NULL,MBOT,"LoadOnDrop",1)==1) + { + if(!help_loadscript(tmpp)){ + DeleteFile(tmpp); + _snprintf(tmpp,MAX_PATH,"Could not load the script: %s\r\n",ff); + + }else{ + _snprintf(tmpp,MAX_PATH,"New script installed: %s\r\n",ff); + MBHookEvents(); + } + MBotConsoleAppendText(tmpp,1); + } + return 1; + } +} + +long MBotInstallExtension(char* path) +{ + char* ff; + char tmpp[MAX_PATH + 1]; + int length; + sXmlNode* node; + + length = strlen(path); + ff = path + length - 4; + + while(ff != path && *ff!='\\' && *ff!='/'){ + ff--; + } + if(ff != path)ff++; + + if(*(DWORD*)ff != '_php'){ + MBotConsoleAppendText("This is not a valid php module!\r\n",1); + return 0; + } + + if(_snprintf(tmpp,MAX_PATH,"%s\\mbot\\extensions\\%s",g_root,ff) < 0){ + MBotConsoleAppendText("File path is too long!\r\n",1); + return 0; + } + + if(help_fileexists(tmpp)) + { + char msg[MAX_PATH + 64]; + _snprintf(msg,MAX_PATH + 63,"Following file already exists:\n'%s'\nOverwrite?",tmpp); + if(MessageBox(NULL,msg,"MBot",MB_ICONQUESTION | MB_YESNO) == IDNO){ + return -1; + } + } + + if(!CopyFile(path,tmpp,FALSE)) + { + MBotConsoleAppendText("Could not copy the file!\r\n",0); + return 0; + } + else + { + node = cSettings.GetNode("mbot/add_php",NULL); + if(!node){ + MBotConsoleAppendText("Could not found appropriate node!\r\n",1); + return 0; + } + + strlwr(ff); + node = cSettings.AddNewNode("extension",ff,node); + if(!node){ + MBotConsoleAppendText("Could add a new node to the config file!\r\n",1); + return 0; + } + + _snprintf(tmpp,MAX_PATH,"New extension installed: %s\r\n",ff); + MBotConsoleAppendText(tmpp,1); + return 1; + } +} + +void MBotUpdateConfigFile() +{ + char path[MAX_PATH + 1]={0}; + _snprintf(path,MAX_PATH,"%s\\mbot\\config\\mbot.xml",g_root); + cSettings.SaveToFile(path); + _snprintf(path,MAX_PATH,"Extensions will be loaded next time you restart miranda\r\n"); + MBotConsoleAppendText(path,1); +} + +void MBotDragAccept(HDROP wParam) +{ + static int count; + static int ok1; + static int ok2; + static int length; + char path[MAX_PATH + 1]={0}; + + count = DragQueryFile((HDROP)wParam,0xFFFFFFFF,NULL,NULL); + ok1 = 0; + ok2 = 0; + + for(int i=0;i 4 && *(DWORD*)(path + length - 4) == 'php.'){//script + if(MBotInstallScript(path)==1)ok1++; + } + else if(length > 8 && *(DWORD*)(path + length - 4) == 'lld.'){//extension + if(MBotInstallExtension(path)==1)ok2++; + } + if(ok2 > 0){ + MBotUpdateConfigFile(); + } + } +} + +INT_PTR WINAPI MBotDlgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + static POINT pt; + + switch(uMsg) + { + case WM_INITDIALOG: + { + TBADDBITMAP tbab; + RECT rc; + unsigned long tmp = 0; + + InitializeCriticalSectionAndSpinCount(&csConsole,0x80000100); + hConsole = GetDlgItem(hWnd,IDC_MBCONSOLE); + hCommandBox = GetDlgItem(hWnd,IDC_MBCOMMANDBOX); + hImagelist = ImageList_Create(21,16,ILC_COLOR24|ILC_MASK,10,0); + + SendMessage(hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hMBotIcon); + + hBitmap = (HBITMAP)LoadImage(hInst, MAKEINTRESOURCE(IDB_BITMAP1), + IMAGE_BITMAP, 0, 0, LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS); + + ImageList_AddMasked(hImagelist,hBitmap,RGB(255,255,255)); + + hToolbar = CreateWindowEx(0,TOOLBARCLASSNAME,NULL,WS_CHILD | WS_VISIBLE | + TBSTYLE_TOOLTIPS | CCS_NOPARENTALIGN | CCS_NODIVIDER | CCS_NORESIZE, + 0,0,100,26,hWnd,(HMENU)IDC_TOOLBAR,hInst,NULL); + + if(!hConsole || !hCommandBox || !hToolbar){ + return -1; + } + + hVerdanaFont = CreateFont(13,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET, + OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,0,"Verdana"); + + hMonospacedFont = CreateFont(lConFontSize,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET, + OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,FIXED_PITCH,pszMonospacedFont); + + hMenu = LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1)); + + SendMessage(hConsole,EM_SETBKGNDCOLOR,FALSE,(LPARAM)(RGB(240,240,240))); + + SendMessage(hConsole,WM_SETFONT,(WPARAM)hMonospacedFont,0); + SendMessage(hCommandBox,WM_SETFONT,(WPARAM)hMonospacedFont,0); + + tbab.hInst = NULL; + tbab.nID = (INT_PTR)hBitmap; + + SendMessage(hToolbar,TB_SETIMAGELIST,(WPARAM)0,(LPARAM)hImagelist); + SendMessage(hToolbar,TB_BUTTONSTRUCTSIZE,(WPARAM) sizeof(TBBUTTON), 0); + + SendMessage(hToolbar,TB_ADDBUTTONS,sizeof(tbb)/sizeof(TBBUTTON),(LPARAM)tbb); + SendMessage(hToolbar,TB_SETEXTENDEDSTYLE,0,TBSTYLE_EX_DRAWDDARROWS); + + MBotConsoleClear(); + MBotConsoleAppendText("Miranda Scripting Plugin 0.0.3.2" "\r\nhttp://www.piopawlu.net\r\nBuilt on: "__TIMESTAMP__"\r\n",0); + + SendMessage(hConsole,EM_SETWORDWRAPMODE,WBF_WORDBREAK,0); + + fpOldWndProc = (WNDPROC)SetWindowLong(hCommandBox,GWL_WNDPROC,(LONG)MBotNewWndProc); + DragAcceptFiles(hCommandBox,TRUE); + + if(DBGetContactSettingByte(NULL,MBOT,"Wrap",0)){ + SendMessage(hToolbar,TB_CHECKBUTTON,ID_LINEWRAP,TRUE); + MBotDlgSetWrap(1); + } + + tmp = DBGetContactSettingWord(NULL,MBOT,"wX",10); + if(tmp >= (ULONG)GetSystemMetrics(SM_CXSCREEN))tmp = 0; + rc.left = rc.right = tmp; + + tmp = DBGetContactSettingWord(NULL,MBOT,"wY",10); + if(tmp >= (ULONG)GetSystemMetrics(SM_CYSCREEN))tmp = 0; + rc.top = rc.bottom = tmp; + + tmp = DBGetContactSettingWord(NULL,MBOT,"wCx",400); + if(tmp >= (ULONG)GetSystemMetrics(SM_CXSCREEN))tmp = 200; + rc.right += tmp; + + tmp = DBGetContactSettingWord(NULL,MBOT,"wCy",300); + if(tmp >= (ULONG)GetSystemMetrics(SM_CYSCREEN))tmp = 300; + rc.bottom += tmp; + + MoveWindow(hWnd,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,FALSE); + MBotDlgOnSize(hWnd); + } + return 1; + case WM_CLOSE: + ShowWindow(hWnd,SW_HIDE); + return 1; + case WM_GETMINMAXINFO: + { + MINMAXINFO* mmi = (MINMAXINFO*)lParam; + mmi->ptMinTrackSize.x = 300; + mmi->ptMinTrackSize.y = 200; + return TRUE; + } + break; + case WM_SIZE: + MBotDlgOnSize(hWnd); + return 1; + case (WM_USER + 2): + SendMessage(hToolbar,TB_CHECKBUTTON,ID_LINEWRAP,wParam); + MBotDlgSetWrap(wParam); + return 1; + case (WM_USER + 3): + { + if(!bLocked){ + SendDlgItemMessage(hDialog,IDC_TOOLBAR,TB_ENABLEBUTTON,ID_EXECUTE,FALSE); + EnableWindow(hCommandBox,FALSE); + bLocked = TRUE; + CallFunctionAsync(MBotDlgExecute,(void*)1); + } + return 1; + } + case (WM_USER + 5): + { + if(!bLocked && *pszCommand && GetWindowTextLength(hCommandBox) <= 1){ + SetWindowText(hCommandBox,pszCommand); + } + return 1; + } + break; + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case ID_CLEAR: + MBotConsoleClear(); + break; + case ID_EXECUTE: + { + if(!bLocked) + { + SendDlgItemMessage(hDialog,IDC_TOOLBAR,TB_ENABLEBUTTON,ID_EXECUTE,FALSE); + EnableWindow(hCommandBox,FALSE); + bLocked = TRUE; + CallFunctionAsync(MBotDlgExecute,NULL); + } + } + break; + case ID_MBHELP: + { + _snprintf(pszCommand,sizeof(pszCommand)-1,"%s\\mbot\\help\\mbot.chm",g_root); + ShellExecute(NULL,"open","hh.exe",pszCommand,0,SW_SHOWNORMAL); + } + break; + case ID_LINEWRAP: + if(SendMessage(hToolbar,TB_ISBUTTONCHECKED,(ID_LINEWRAP),0)) + { + DBWriteContactSettingByte(NULL,MBOT,"Wrap",1); + MBotDlgSetWrap(1); + }else{ + DBWriteContactSettingByte(NULL,MBOT,"Wrap",0); + MBotDlgSetWrap(0); + } + break; + case ID_POPUP2_INSTALLSCRIPT: + { + char* fn = (char*)help_getfilename(1,"PHP Files (*.php)\0*.php\0\0",NULL); + if(!fn)break; + MBotInstallScript(fn); + } + break; + case ID_POPUP2_INSTALLEXTENSION: + { + char* fn = (char*)help_getfilename(1,"PHP Extensions (php_*.dll)\0php_*.dll\0\0",NULL); + if(!fn)break; + if(MBotInstallExtension(fn)){ + MBotUpdateConfigFile(); + } + } + break; + } + } + break; + case WM_DESTROY: + { + MBLOGEX("WM_DESTROY START"); + RECT rc; + + if(help_iswin2k()) + { + MBLOGEX("GetWindowRect..."); + GetWindowRect(hWnd,&rc); + MBLOGEX("DBWriteContactSettingWord (wCx)"); + DBWriteContactSettingWord(NULL,MBOT,"wCx",(WORD)(rc.right - rc.left)); + MBLOGEX("DBWriteContactSettingWord (wCy)"); + DBWriteContactSettingWord(NULL,MBOT,"wCy",(WORD)(rc.bottom - rc.top)); + MBLOGEX("DBWriteContactSettingWord (wX)"); + DBWriteContactSettingWord(NULL,MBOT,"wX",(WORD)rc.left); + MBLOGEX("DBWriteContactSettingWord (wY)"); + DBWriteContactSettingWord(NULL,MBOT,"wY",(WORD)rc.top); + } + + MBLOGEX("Destroying toolbar..."); + DestroyWindow(hToolbar); + MBLOGEX("Destroying toolbar icons..."); + DeleteObject((HGDIOBJ)hBitmap); + MBLOGEX("Destroying toolbar images..."); + DeleteObject((HGDIOBJ)hImagelist); + MBLOGEX("Destroying fonts..."); + DeleteObject((HGDIOBJ)hVerdanaFont); + DeleteObject((HGDIOBJ)hMonospacedFont); + MBLOGEX("WM_DESTROY END"); + } + return 1; + case WM_NOTIFY: + { + #define lpnm ((LPNMHDR)lParam) + + if(wParam == IDC_MBCOMMANDBOX) + { + LPNMHDR nmhdr = (LPNMHDR)lParam; + if(nmhdr->code == EN_DROPFILES){ + return 1; + } + } + else if(lpnm->code == TTN_GETDISPINFO) + { + NMTTDISPINFO* tt = (NMTTDISPINFO*)lParam; + switch(tt->hdr.idFrom) + { + case ID_CLEAR: tt->lpszText = "Clear the console window"; break; + case ID_MBHELP: tt->lpszText = "Opens the help file"; break; + case ID_EXECUTE: tt->lpszText = "Executes the command or a piece of script entered in the box below"; break; + case ID_LINEWRAP: tt->lpszText = "Changes the output wrap mode (on/off)"; break; + case ID_MBINSTALL: tt->lpszText = "Install new script or php extension"; break; + default: + return FALSE; + } + return TRUE; + }else if(lpnm->code == TBN_DROPDOWN){ + + GetCursorPos(&pt); + TrackPopupMenu(GetSubMenu(hMenu,1), + TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL, + pt.x,pt.y,0,hWnd,NULL); + + return FALSE; + } + } + break; + default: + break; + } + return(FALSE); +} + +int MBotGetPrefString(const char *szSetting, char* out, int len, char* def) +{ + DBVARIANT dbv; + if((DBGetContactSetting(NULL, MBOT,szSetting, &dbv) == FALSE) && dbv.type==DBVT_ASCIIZ) + { + strncpy(out,dbv.pszVal,len); + DBFreeVariant(&dbv); + return 1; + } + else + { + strncpy(out,def,len); + return FALSE; + } +} + +int MBotDlgFillHandlers(HWND hList,int* sch) +{ + extern CSECTION sm_sync; + extern CSyncList g_cron; + PHANDLER ph; + PPHP php; + sCronSync* cs; + LVITEM li={0}; + char temp[MAX_PATH]; + long n = 1; + long it = 0; + long adv = DBGetContactSettingByte(NULL,MBOT,"AdvConfig",0); + + if(!hConsole)return 0; + + ListView_DeleteAllItems(hList); + + if(!adv) + { + sm_list.Lock(); + php = (PPHP)sm_list.m_head; + while(php) + { + li.pszText = strrchr(php->szFilePath,'/'); + if(!li.pszText)li.pszText = php->szFilePath; + + li.lParam = (LPARAM)php; + li.iSubItem = 0; + li.iItem = n; + li.mask = LVIF_PARAM | LVIF_TEXT; + it = ListView_InsertItem(hList,&li); + + li.pszText = php->szDescription?php->szDescription:"no description"; + li.mask = LVIF_TEXT; + li.iItem = it; + li.iSubItem = 1; + ListView_SetItem(hList,&li); + + php = (PPHP)php->next; + } + sm_list.Unlock(); + return 0; + } + + EnterCriticalSectionX(&sm_sync); + + for(int i=0;i<32;i++) + { + ph = sman_handler_get(1 << i); + while(ph) + { + if(!(ph->lFlags & MBOT_FLAG_DELETE)) + { + _snprintf(temp,sizeof(temp)-1,"%.2u",n++); + li.pszText = temp; + li.lParam = (LPARAM)ph; + li.iSubItem = 0; + li.iItem = n; + li.mask = LVIF_PARAM | LVIF_TEXT; + it = ListView_InsertItem(hList,&li); + if(it!=-1) + { + li.mask = LVIF_TEXT; + li.pszText = ph->szFcnName + 4; + li.iItem = it; + li.iSubItem = 1; + ListView_SetItem(hList,&li); + + li.pszText = (ph->lFlags & MBOT_FLAG_INACTIVE)?("no"):("yes"); + if(ph->php->lFlags & MBOT_FLAG_SHALLDIE)li.pszText = "DEL"; + + li.iSubItem = 2; + ListView_SetItem(hList,&li); + + li.pszText = (ph->php->szBuffered)?("yes"):("no"); + li.iSubItem = 3; + ListView_SetItem(hList,&li); + + li.pszText = strrchr(ph->php->szFilePath,'/'); + if(!li.pszText)li.pszText = ph->php->szFilePath; + + li.iSubItem = 4; + ListView_SetItem(hList,&li); + + } + } + ph = ph->next; + } + } + /////////////////////////////// + *sch = n; + /////////////////////////////// + li.iSubItem = 0; + li.iItem = n; + li.lParam = NULL; + li.pszText = "---"; + it = ListView_InsertItem(hList,&li); + if(it != -1){ + li.mask = LVIF_TEXT; + li.pszText = "#scheduler#"; + li.iItem = it; + li.iSubItem = 1; + ListView_SetItem(hList,&li); + + li.pszText = "---"; + li.iSubItem = 2; + ListView_SetItem(hList,&li); + li.iSubItem = 3; + ListView_SetItem(hList,&li); + li.iSubItem = 4; + ListView_SetItem(hList,&li); + } + /////////////////////////////// + g_cron.Lock(); + cs = (sCronSync*)g_cron.m_head; + while(cs) + { + if(!(cs->lFlags & MBOT_FLAG_DELETE)) + { + _snprintf(temp,sizeof(temp)-1,"%.2u",n++); + li.pszText = temp; + li.lParam = (LPARAM)cs; + li.iSubItem = 0; + li.iItem = n; + li.mask = LVIF_PARAM | LVIF_TEXT; + it = ListView_InsertItem(hList,&li); + if(it!=-1) + { + li.mask = LVIF_TEXT; + li.pszText = cs->name; + li.iItem = it; + li.iSubItem = 1; + ListView_SetItem(hList,&li); + + li.pszText = (cs->lFlags & MBOT_FLAG_INACTIVE)?("no"):("yes"); + li.iSubItem = 2; + ListView_SetItem(hList,&li); + + li.pszText = (cs->data->szBuffered)?("yes"):("no"); + if(cs->data->lFlags & MBOT_FLAG_SHALLDIE)li.pszText = "DEL"; + li.iSubItem = 3; + ListView_SetItem(hList,&li); + + _snprintf(temp,sizeof(temp)-1,"%s\\mbot\\scripts\\autoload",g_root); + if(strncmp(cs->data->szFilePath,temp,strlen(temp))==0){ + _snprintf(temp,sizeof(temp)-1,"%s",cs->data->szFilePath + strlen(temp)); + li.pszText = temp; + }else{ + li.pszText = (cs->data->szFilePath); + } + li.iSubItem = 4; + ListView_SetItem(hList,&li); + } + } + cs = (sCronSync*)cs->next; + } + g_cron.Unlock(); + LeaveCriticalSectionX(&sm_sync); + return 0; +} + +void xx_configure_script(PPHP php) +{ + mb_event mbe={MBT_CALLBACK,0,0}; + mbe.php = php; + mbe.event = MBT_CALLBACK; + MBMultiParam(php,"mbe_config",&mbe,NULL); +} + +INT_PTR WINAPI MBotDlgProcOption(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + static int tmp = 0; + static char stmp[64]; + static int initialized = 0; + static HWND hList; + static PHANDLER phc; + static sCronSync* cs; + static int sch_id; + static int adv = 0; + static int type; + + static PPHP xphp = NULL; + + switch(uMsg) + { + case WM_INITDIALOG: + { + LVCOLUMN lvc = {0}; + + phc = NULL; + initialized = 0; + type = 0; + TranslateDialogDefault(hWnd); + + tmp = DBGetContactSettingByte(NULL,MBOT,"Enable",1); + SendDlgItemMessage(hWnd,IDC_MBENABLE,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"NoCache",0); + SendDlgItemMessage(hWnd,IDC_MBDISABLECACHE,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"NoEvents",0); + SendDlgItemMessage(hWnd,IDC_MBDISABLEEVENTS,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"SWOnStartup",0); + SendDlgItemMessage(hWnd,IDC_MBSHOWCONSOLE,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"SWOnError",0); + SendDlgItemMessage(hWnd,IDC_MBSHOWCONSOLEERROR,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"Wrap",0); + SendDlgItemMessage(hWnd,IDC_WRAPCONSOLE,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"NoScheduler",0); + SendDlgItemMessage(hWnd,IDC_DISABLESCHEDULER,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),0); + tmp = DBGetContactSettingByte(NULL,MBOT,"WWWEnabled",1); + SendDlgItemMessage(hWnd,IDC_ENABLEWWW,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),1); + tmp = DBGetContactSettingByte(NULL,MBOT,"WWWLog",1); + SendDlgItemMessage(hWnd,IDC_ENABLEADVOPT,BM_SETCHECK,(tmp)?(BST_CHECKED):(BST_UNCHECKED),1); + adv = DBGetContactSettingByte(NULL,MBOT,"AdvConfig",0); + SendDlgItemMessage(hWnd,IDC_ENABLEADVOPT,BM_SETCHECK,(adv)?(BST_CHECKED):(BST_UNCHECKED),1); + + + MBotGetPrefString("CmdTag",stmp,2,"m>"); + SetDlgItemText(hWnd,IDC_ADVCMDTAG,stmp); + + MBotGetPrefString("ScriptTag",stmp,2,"?>"); + SetDlgItemText(hWnd,IDC_ADVSCRIPTTAG,stmp); + + hList = GetDlgItem(hWnd,IDC_LIST1); + if(!hList)return 0; + + sm_list.Lock(); + xphp = (PPHP)sm_list.m_head; + while(xphp){ + sman_inc(xphp); + xphp = (PPHP)xphp->next; + } + sm_list.Unlock(); + + if(adv) + { + lvc.cx = 25; + lvc.fmt = LVCFMT_CENTER; + lvc.pszText = "#"; + lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT; + ListView_InsertColumn(hList,0,&lvc); + + lvc.cx = 100; + lvc.pszText = "Event"; + lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT; + ListView_InsertColumn(hList,1,&lvc); + + lvc.cx = 60; + lvc.pszText = "Active"; + ListView_InsertColumn(hList,2,&lvc); + + lvc.cx = 60; + lvc.pszText = "Cached"; + ListView_InsertColumn(hList,3,&lvc); + + lvc.cx = 150; + lvc.pszText = "File"; + lvc.fmt = LVCFMT_LEFT; + ListView_InsertColumn(hList,4,&lvc); + + ListView_SetExtendedListViewStyle(hList,LVS_EX_FULLROWSELECT); + MBotDlgFillHandlers(hList,&sch_id); + SetDlgItemText(hWnd,IDC_ADV2,Translate("Registered handlers")); + }else{ + lvc.cx = 100; + lvc.pszText = "File"; + lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT; + lvc.fmt = LVCFMT_LEFT; + ListView_InsertColumn(hList,0,&lvc); + + lvc.cx = 300; + lvc.pszText = "Description"; + ListView_InsertColumn(hList,1,&lvc); + + ListView_SetExtendedListViewStyle(hList,LVS_EX_FULLROWSELECT); + MBotDlgFillHandlers(hList,&sch_id); + SetDlgItemText(hWnd,IDC_ADV2,Translate("Installed scripts (double click to configure)")); + } + SendDlgItemMessage(hWnd,IDC_ADVSCRIPTTAG,EM_LIMITTEXT,2,0); + SendDlgItemMessage(hWnd,IDC_ADVCMDTAG,EM_LIMITTEXT,2,0); + initialized = 1; + } + return TRUE; + case WM_NOTIFY: + if(((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) + { + tmp = IsDlgButtonChecked(hWnd,IDC_MBENABLE); + DBWriteContactSettingByte(NULL,MBOT,"Enable",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_MBDISABLECACHE); + DBWriteContactSettingByte(NULL,MBOT,"NoCache",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_MBDISABLEEVENTS); + DBWriteContactSettingByte(NULL,MBOT,"NoEvents",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_MBSHOWCONSOLE); + DBWriteContactSettingByte(NULL,MBOT,"SWOnStartup",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_MBSHOWCONSOLEERROR); + DBWriteContactSettingByte(NULL,MBOT,"SWOnError",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_DISABLESCHEDULER); + DBWriteContactSettingByte(NULL,MBOT,"NoScheduler",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_ENABLEWWW); + DBWriteContactSettingByte(NULL,MBOT,"WWWEnabled",(tmp)?(1):(0)); + tmp = IsDlgButtonChecked(hWnd,IDC_ENABLEWWW2); + DBWriteContactSettingByte(NULL,MBOT,"WWWLog",(tmp)?(1):(0)); + + tmp = IsDlgButtonChecked(hWnd,IDC_WRAPCONSOLE); + DBWriteContactSettingByte(NULL,MBOT,"Wrap",(tmp)?(1):(0)); + PostMessage(hDialog,WM_USER + 2,tmp,0); + + tmp = GetDlgItemText(hWnd,IDC_ADVCMDTAG,stmp,64); + if(!tmp || tmp>2){ + SetDlgItemText(hWnd,IDC_ADVCMDTAG,"m>"); + }else{ + strncpy(pszCmdTag,stmp,tmp+1); + lCmdTagLen = tmp; + DBWriteContactSettingString(NULL,MBOT,"CmdTag",pszCmdTag); + } + + tmp = GetDlgItemText(hWnd,IDC_ADVSCRIPTTAG,stmp,64); + if(!tmp || tmp>2){ + SetDlgItemText(hWnd,IDC_ADVSCRIPTTAG,"?>"); + }else{ + strncpy(pszPhpTag,stmp,tmp+1); + lPhpTagLen = tmp; + DBWriteContactSettingString(NULL,MBOT,"ScriptTag",pszPhpTag); + } + return (TRUE); + } + else if(((LPNMHDR)lParam)->code == NM_DBLCLK && wParam == IDC_LIST1) + { + LVITEM lvi = {0}; + + lvi.mask = LVIF_PARAM; + lvi.iItem = ((LPNMLISTVIEW)lParam)->iItem; + if(!ListView_GetItem(GetDlgItem(hWnd,IDC_LIST1),&lvi) || !lvi.lParam)break; + xphp = (PPHP)lvi.lParam; + + if(xphp && sman_handler_find(xphp,MB_EVENT_CONFIG)){ + xx_configure_script(xphp); + }else{ + MessageBox(hList,"No configuration available","MSP",MB_ICONINFORMATION); + } + } + else if(((LPNMHDR)lParam)->code == NM_RCLICK && wParam == IDC_LIST1) + { + LVITEM lvi = {0}; + POINT pt; + LONG lFlags; + PPHP php; + lvi.mask = LVIF_PARAM; + lvi.iItem = ((LPNMLISTVIEW)lParam)->iItem; + + if(!ListView_GetItem(GetDlgItem(hWnd,IDC_LIST1),&lvi) || !lvi.lParam)break; + GetCursorPos(&pt); + + if(!adv){ + phc = NULL; + cs = NULL; + xphp = (PPHP)lvi.lParam; + lFlags = xphp->lFlags; + + if(lFlags & (MBOT_FLAG_INACTIVE|MBOT_FLAG_SHALLDIE|MBOT_FLAG_DELETE)){ + EnableMenuItem(hMenu,ID_POPUP3_ENABLE,MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(hMenu,ID_POPUP3_DISABLE,MF_BYCOMMAND | MF_GRAYED); + }else{ + EnableMenuItem(hMenu,ID_POPUP3_DISABLE,MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(hMenu,ID_POPUP3_ENABLE,MF_BYCOMMAND | MF_GRAYED); + } + + if(sman_handler_find(xphp,MB_EVENT_CONFIG)){ + EnableMenuItem(hMenu,ID_POPUP3_CONFIGURE,MF_BYCOMMAND | MF_ENABLED); + }else{ + EnableMenuItem(hMenu,ID_POPUP3_CONFIGURE,MF_BYCOMMAND | MF_GRAYED); + } + + }else{ + xphp = NULL; + if(lvi.iItem < sch_id){ + phc = (PHANDLER)lvi.lParam; + lFlags = phc->lFlags; + php = phc->php; + cs = NULL; + }else{ + cs = (sCronSync*)lvi.lParam; + lFlags = cs->lFlags; + php = cs->data; + phc = NULL; + } + + if(lFlags & MBOT_FLAG_INACTIVE){ + EnableMenuItem(hMenu,ID_POPUP_ACTIVATE,MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(hMenu,ID_POPUP_DEACTIVATE,MF_BYCOMMAND | MF_GRAYED); + }else{ + EnableMenuItem(hMenu,ID_POPUP_DEACTIVATE,MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(hMenu,ID_POPUP_ACTIVATE,MF_BYCOMMAND | MF_GRAYED); + } + + if(!(php->szBuffered)){ + EnableMenuItem(hMenu,ID_POPUP_UNCACHE,MF_BYCOMMAND | MF_GRAYED); + }else{ + EnableMenuItem(hMenu,ID_POPUP_UNCACHE,MF_BYCOMMAND | MF_ENABLED); + } + } + + TrackPopupMenu(GetSubMenu(hMenu,adv?0:2),0,pt.x,pt.y,0,hWnd,NULL); + } + break; + case WM_COMMAND: + { + tmp = 0; + switch(LOWORD(wParam)) + { + case IDC_MBENABLE: + case IDC_MBDISABLECACHE: + case IDC_ENABLEWWW: + case IDC_ENABLEWWW2: + MessageBox(NULL,"This option requires Miranda restart!","MBot",MB_ICONINFORMATION); + case IDC_MBDISABLEEVENTS: + case IDC_MBSHOWCONSOLE: + case IDC_MBSHOWCONSOLEERROR: + case IDC_WRAPCONSOLE: + SendMessage(GetParent(hWnd),PSM_CHANGED,0,0); + break; + case IDC_ADVCMDTAG: + case IDC_ADVSCRIPTTAG: + if(HIWORD(wParam) == EN_CHANGE && initialized==1){ + SendMessage(GetParent(hWnd),PSM_CHANGED,0,0); + } + break; + case ID_ACTIVATE_EVENT: + if(phc){ + sman_handler_enable(phc); + }else if(cs){ + cron_enable(cs->name,1); + } + MBotDlgFillHandlers(hList,&sch_id); + break; + case ID_DEACTIVATE_EVENT: + if(phc){ + sman_handler_disable(phc); + }else if(cs){ + cron_enable(cs->name,0); + } + MBotDlgFillHandlers(hList,&sch_id); + break; + case ID_POPUP3_ENABLE: + case ID_ACTIVATE_FILE: + tmp = 1; + case ID_POPUP3_DISABLE: + case ID_DEACTIVATE_FILE: + xphp = (!adv)?(xphp):((phc)?(phc->php):(cs->data)); + sman_dec(xphp); + help_enable_script(xphp,tmp==1); + sman_inc(xphp); + MBotDlgFillHandlers(hList,&sch_id); + break; + case ID_POPUP_UNCACHE: + { + PPHP php = (phc)?(phc->php):(cs->data); + sman_dec(php); + if(!sman_uncache(php)){ + sman_inc(php); + MessageBox(hWnd,"File is in use!",MBOT,MB_ICONINFORMATION); + }else{ + sman_inc(php); + MBotDlgFillHandlers(hList,&sch_id); + } + } + break; + case ID_POPUP_RECACHE: + { + PPHP php = (phc)?(phc->php):(cs->data); + sman_dec(php); + if(!sman_recache(php)){ + sman_inc(php); + MessageBox(hWnd,"File is in use or could not cache the file!",MBOT,MB_ICONINFORMATION); + }else{ + sman_inc(php); + } + MBotDlgFillHandlers(hList,&sch_id); + } + break; + case ID_POPUP_UNLOAD: + { + PPHP php = (phc)?(phc->php):(cs->data); + sman_dec(php); + if(!sman_uninstall(php,0)){ + sman_inc(php); + MessageBox(hWnd,"File is in use or could not find the file!",MBOT,MB_ICONINFORMATION); + }else{ + MBotDlgFillHandlers(hList,&sch_id); + } + } + break; + case ID_POPUP3_CONFIGURE: + if(xphp){ + xx_configure_script(xphp); + } + break; + case ID_POPUP3_UNINSTALL: + case ID_POPUP_UNINSTALL: + { + PPHP php = (!adv)?(xphp):((phc)?(phc->php):(cs->data)); + + if(MessageBox(hWnd,"Are you sure you want to unload selected script?", + MBOT,MB_ICONQUESTION | MB_YESNO)==IDYES) + { + if(!sman_uninstall(php,1)){ + MessageBox(hWnd,"File is in use or could not find the file!",MBOT,MB_ICONINFORMATION); + }else{ + MBotDlgFillHandlers(hList,&sch_id); + } + } + } + break; + default: + break; + } + } + break; + case WM_DESTROY: + tmp = IsDlgButtonChecked(hWnd,IDC_ENABLEADVOPT); + DBWriteContactSettingByte(NULL,MBOT,"AdvConfig",(tmp)?(1):(0)); + + sm_list.Lock(); + xphp = (PPHP)sm_list.m_head; + while(xphp){ + sman_dec(xphp); + xphp = (PPHP)xphp->next; + } + sm_list.Unlock(); + hList = NULL; + break; + default: + break; + } + return(FALSE); +} \ No newline at end of file diff --git a/mBot/src/mbot/window.h b/mBot/src/mbot/window.h new file mode 100644 index 0000000..581454f --- /dev/null +++ b/mBot/src/mbot/window.h @@ -0,0 +1,31 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + +INT_PTR WINAPI MBotDlgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); +INT_PTR WINAPI MBotDlgProcOption(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); + +void MBotConsoleAppendText(const char* txt,long formatted = 0); +int MBotGetPrefString(const char *szSetting, char* out, int len, char* def); +void MBotConsoleClear(); + +#endif //_WINDOW_H_ \ No newline at end of file diff --git a/mBot/src/msp.sln b/mBot/src/msp.sln new file mode 100644 index 0000000..9eb1230 --- /dev/null +++ b/mBot/src/msp.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utils", "utils\utils.vcproj", "{A45C2C2E-2662-48DE-A18D-5F52C9A86253}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libphp", "libphp\libphp.vcproj", "{E6589813-69E7-4F2D-A6DB-342D41C85698}" + ProjectSection(ProjectDependencies) = postProject + {A45C2C2E-2662-48DE-A18D-5F52C9A86253} = {A45C2C2E-2662-48DE-A18D-5F52C9A86253} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbot", "mbot\mbot.vcproj", "{E7893C5B-D58D-40ED-98C1-A6C29015401E}" + ProjectSection(ProjectDependencies) = postProject + {E6589813-69E7-4F2D-A6DB-342D41C85698} = {E6589813-69E7-4F2D-A6DB-342D41C85698} + {A45C2C2E-2662-48DE-A18D-5F52C9A86253} = {A45C2C2E-2662-48DE-A18D-5F52C9A86253} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A45C2C2E-2662-48DE-A18D-5F52C9A86253}.Debug|Win32.ActiveCfg = Debug|Win32 + {A45C2C2E-2662-48DE-A18D-5F52C9A86253}.Debug|Win32.Build.0 = Debug|Win32 + {A45C2C2E-2662-48DE-A18D-5F52C9A86253}.Release|Win32.ActiveCfg = Release|Win32 + {A45C2C2E-2662-48DE-A18D-5F52C9A86253}.Release|Win32.Build.0 = Release|Win32 + {E6589813-69E7-4F2D-A6DB-342D41C85698}.Debug|Win32.ActiveCfg = DebugSt|Win32 + {E6589813-69E7-4F2D-A6DB-342D41C85698}.Debug|Win32.Build.0 = DebugSt|Win32 + {E6589813-69E7-4F2D-A6DB-342D41C85698}.Release|Win32.ActiveCfg = ReleaseSt|Win32 + {E6589813-69E7-4F2D-A6DB-342D41C85698}.Release|Win32.Build.0 = ReleaseSt|Win32 + {E7893C5B-D58D-40ED-98C1-A6C29015401E}.Debug|Win32.ActiveCfg = Debug|Win32 + {E7893C5B-D58D-40ED-98C1-A6C29015401E}.Debug|Win32.Build.0 = Debug|Win32 + {E7893C5B-D58D-40ED-98C1-A6C29015401E}.Release|Win32.ActiveCfg = Release|Win32 + {E7893C5B-D58D-40ED-98C1-A6C29015401E}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/mBot/src/utils/cBase64.cpp b/mBot/src/utils/cBase64.cpp new file mode 100644 index 0000000..294e68e --- /dev/null +++ b/mBot/src/utils/cBase64.cpp @@ -0,0 +1,204 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "includes.h" +#include "cBase64.h" + +#define BASE64_BM 0x000000FC + +static const char* base64_etable; +static unsigned char base64_dtable[256]; +static bool base64_dtable_ok = false; + +cBase64::cBase64() +{ + if(base64_dtable_ok == false) + { + int i = 0; + memset(base64_dtable,0xAAAAAAAA,sizeof(base64_dtable)); + for(const char* c = base64_etable; i<67; i++, c++){ + base64_dtable[*c] = i; + } + base64_etable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\0"; + base64_dtable_ok = true; + } +} + +cBase64::~cBase64() +{ + +} + +inline bool cBase64::IsValidB64(register char c) +{ + return (base64_dtable[c] != 0xAA); +} + +int cBase64::EncodeRAW(unsigned char* pszIn, int length) +{ + m_data.close(); + + if(!m_data.create((length * 3) / 2)){ + return 0; + } + + int tocopy = 0; + int encoded = 0; + + while(encoded < length) + { + QUAD q = {0}; + tocopy = min(3, length - encoded); + q.size = tocopy; + + memcpy(&q, pszIn + encoded, tocopy); + + EncodeQuad(q); + + if(!m_data.write(&q,4)){ + goto Error; + } + encoded += tocopy; + } + m_data.putc(0); + return encoded; +Error: + m_data.close(); + return 0; +} + +int cBase64::Encode(const char* pszData) +{ + return this->EncodeRAW((unsigned char*)pszData, strlen(pszData)); +} + +int cBase64::Decode(const char* pszIn) +{ + int len = strlen(pszIn); + int done = 0; + unsigned long *quads = (unsigned long*)pszIn; + + if(!len || len % 4)return 0; + + for(const char* c=pszIn;*c;c++){ + if(!IsValidB64(*c)){ + return 0; + } + } + + m_data.close(); + if(!m_data.create(len / 3 + 5)){ + return 0; + } + + while(done < len) + { + QUAD q ={0}; + q.size = 4; + q.d.bDword = *quads++; + + DecodeQuad(q); + if(!m_data.write(&q.d.bDword,q.size)){ + goto Error; + } + done += 4; + } + m_data.putc(0); + return 1; +Error: + m_data.close(); + return 0; +} + +int cBase64::GetString(char* pszOut) +{ + strcpy(pszOut, (const char*)m_data.getdata()); + return m_data.size(); +} + +int cBase64::DecodedMessageSize() +{ + return m_data.size(); +} + +const char* cBase64::GetBuffer() +{ + return (const char*)m_data.getdata(); +} + +void cBase64::EncodeQuad(QUAD &quad) +{ + QUAD out = {0}; + unsigned char tmp_2 = 0; + + tmp_2 = ((quad.d.bData[0] & BASE64_BM) >> 2); + out.d.bData[0] = base64_etable[tmp_2]; + + tmp_2 = ((quad.d.bData[0] & 0x03) << 4) | ((quad.d.bData[1] & 0xF0) >> 4); + out.d.bData[1] = base64_etable[tmp_2]; + + tmp_2 = ((quad.d.bData[1] & 0x0F) << 2) | ((quad.d.bData[2] & 0xC0) >> 6); + out.d.bData[2] = base64_etable[tmp_2]; + + out.d.bData[3] = base64_etable[quad.d.bData[2] & 0x3F]; + + if(quad.size == 1) + { + out.d.bData[2] = '='; + out.d.bData[3] = '='; + } + else if(quad.size == 2) + out.d.bData[3] = '='; + + out.size = 4; + quad = out; +} + +void cBase64::DecodeQuad(QUAD &quad) +{ + QUAD out = {0}; + unsigned char tmp_0 = 0; + unsigned char tmp_1 = 0; + + quad.d.bData[0] = base64_dtable[quad.d.bData[0]]; + quad.d.bData[1] = base64_dtable[quad.d.bData[1]]; + quad.d.bData[2] = base64_dtable[quad.d.bData[2]]; + quad.d.bData[3] = base64_dtable[quad.d.bData[3]]; + + if(quad.d.bData[2]==0xff && quad.d.bData[3]==0xff) + out.size = 1; + else if(quad.d.bData[3] == 0xff) + out.size = 2; + else + out.size = 3; + + tmp_0 = (quad.d.bData[0]) << 2; + tmp_1 = (quad.d.bData[1] & 0x30) >> 4; + out.d.bData[0] = tmp_0 | tmp_1; + + if(out.size>1) + out.d.bData[1] = ((quad.d.bData[1] & 0x0f) <<4) | ((quad.d.bData[2] & 0x3C) >> 2); + + if(out.size>2) + out.d.bData[2] = ((quad.d.bData[2] & 0x03) << 6) | (quad.d.bData[3] & 0x3f); + + out.d.bData[out.size] = '\0'; + quad = out; +} diff --git a/mBot/src/utils/cBase64.h b/mBot/src/utils/cBase64.h new file mode 100644 index 0000000..4b5b0de --- /dev/null +++ b/mBot/src/utils/cBase64.h @@ -0,0 +1,57 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef __cBASE64_H__ +#define __cBASE64_H__ + +#include "cUtils.h" + +typedef struct tagQuad +{ + union{ + unsigned char bData[4]; + unsigned long bDword; + }d; + char null; + char size; +}QUAD; + +class cBase64 +{ + +public: + cBase64(); + ~cBase64(); + +public: + int Encode(const char* pszIn); + int EncodeRAW(unsigned char* pszIn, int length); + int Decode(const char* pszIn); + int DecodedMessageSize(); + int GetString(char* pszOut); + const char* GetBuffer(); +protected: + static void EncodeQuad(QUAD &q); + static void DecodeQuad(QUAD &q); + static bool IsValidB64(register char c); +public: + cutMemf m_data; +}; +#endif //__BASE64_CODER_PIOPAWLU_H__ \ No newline at end of file diff --git a/mBot/src/utils/cUtils.cpp b/mBot/src/utils/cUtils.cpp new file mode 100644 index 0000000..8caf341 --- /dev/null +++ b/mBot/src/utils/cUtils.cpp @@ -0,0 +1,334 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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 "includes.h" +#include "cUtils.h" + +cutMemf::cutMemf(void* data,unsigned long length) +{ + m_ptr = (unsigned char*)data; + m_end = m_ptr + length; + m_data = m_ptr; + m_flags = 0; + m_maxptr = m_ptr; +} + +cutMemf::cutMemf() +{ + m_data = m_ptr = m_end = m_maxptr = 0; + m_flags = 0; +} + +cutMemf::~cutMemf() +{ + close(); +} + +int cutMemf::close() +{ + if(m_data && (m_flags & 0x01)){ + free(m_data); + } + m_data = NULL; + m_end = NULL; + m_ptr = NULL; + m_maxptr = NULL; + m_flags = 0; + return 1; +} + +int cutMemf::create(unsigned long len) +{ + close(); + m_data = (unsigned char*)malloc(len); + if(!m_data)return 0; + m_ptr = m_data; + m_end = m_data + len; + m_maxptr = m_data; + m_flags = 0x01; + return 1; +} + +void cutMemf::assign(void* data, unsigned long size) +{ + close(); + m_data = (unsigned char*)data; + m_ptr = m_data; + m_end = m_data + size; + m_maxptr = m_end - 1; + m_flags = 0x01; +} + +int cutMemf::load(const char* f,int off) +{ + cutDiskf df; + long fs; + + close(); + if(!df.open(f,"rb")){ + goto Error; + } + fs = df.size(); + if(fs <= off){ + goto Error; + } + fs -= off; + df.setpos(off); + if(!create(fs + 1)){ + goto Error; + } + if(!df.read(m_data,fs)){ + goto Error; + } + df.close(); + m_maxptr = m_data + fs; + m_data[fs] = 0; + return 1; +Error: + return 0; +} + +int cutMemf::resize(unsigned long ns) +{ + //safe + void* tmp = malloc(ns); + if(!tmp){ + return 0; + } + memcpy(tmp,m_data,m_end - m_data); + m_ptr = (unsigned char*)tmp + (m_ptr - m_data); + m_maxptr = (unsigned char*)tmp + (m_maxptr - m_data); + m_end = (unsigned char*)tmp + ns; + free(m_data); + m_data = (unsigned char*)tmp; + return 1; +} + +int cutMemf::removeblock(unsigned long off, unsigned long length) +{ + if (m_data + off + length > m_maxptr){ + return 0; + } + memcpy(m_data + off, m_data + off + length, (m_maxptr - m_data) - off - length); + m_end -= length; + return 1; +} + +int cutMemf::read(void* out,unsigned long n) +{ + n = min(m_end - m_ptr,n); + if(!n)return 0; + memcpy(out,m_ptr,n); + m_ptr += n; + return n; +} + +int cutMemf::gets(char* out, unsigned long n) +{ + int c = 0, l = 0; + + while((c = getc()) > 0x10 && n > 0){ + *out++ = c; + n--; + l++; + } + if(c == '\r'){ + c = getc(); + } + if(c == '\n'){ + getc(); + } + out[l] = 0; + return l; +} + +int cutMemf::write(void* in,unsigned long n) +{ + if(!m_flags){ + n = min(m_end - m_ptr,n); + if(!n){ + return 0; + } + }else{ + if(m_ptr + n > m_end){ + if(!resize(round((m_end - m_data) + n,2048))){ + return 0; + } + } + } + memcpy(m_ptr,in,n); + m_ptr += n; + if(m_ptr > m_maxptr){ + m_maxptr = m_ptr; + } + return n; +} + +int cutMemf::setpos(unsigned long pos) +{ + if(m_data + pos >= m_end)return 0; + m_ptr = m_data + pos; + return 1; +} + + +cutDiskf::cutDiskf() +{ + m_fp = NULL; +} +cutDiskf::~cutDiskf() +{ + this->close(); +} + +int cutDiskf::open(const char* f,const char* mode) +{ + close(); + return (m_fp = (void*)fopen(f,mode))!= NULL; +} + +int cutDiskf::read(void* out,unsigned long n) +{ + return (m_fp)?(fread(out,1,n,(FILE*)m_fp)):0; +} +int cutDiskf::write(void* in,unsigned long n) +{ + return (m_fp)?(fwrite(in,1,n,(FILE*)m_fp)):0; +} +int cutDiskf::size() +{ + int tp = tellpos(); + int fs; + fseek((FILE*)m_fp,0,SEEK_END); + fs = tellpos(); + fseek((FILE*)m_fp,tp,SEEK_SET); + return fs; +} +int cutDiskf::tellpos() +{ + return (m_fp)?(ftell((FILE*)m_fp)):0; +} +int cutDiskf::setpos(unsigned long pos) +{ + return (m_fp)?(!fseek((FILE*)m_fp,pos,SEEK_SET)):0; +} + +int cutDiskf::seek(int pos,int method) +{ + return (m_fp)?(!fseek((FILE*)m_fp,pos,method)):0; +} +int cutDiskf::close() +{ + if(m_fp){ + return fclose((FILE*)m_fp); + }else{ + return 0; + } +} +int cutDiskf::getc() +{ + return (m_fp)?(fgetc((FILE*)m_fp)):0; +} + +cutDiskf::FTYPE cutDiskf::checkFile(const char* path) +{ + _finddata_t fd = {0}; + intptr_t sh = _findfirst(path, &fd); + + if(sh == -1){ + return FT_NONE; + }else{ + _findclose(sh); + if(fd.attrib & _A_SUBDIR){ + return FT_DIRECTORY; + }else{ + return FT_FILE; + } + } +} + +int ut_split(char* str, char chr, char** out, int max) +{ + int n = 0; + char *lchr = str; + + while(*str && max > 0) + { + if(*str == chr){ + *str = 0; + out[n++] = lchr; + lchr = str + 1; + } + str++; + } + return n; +} + +void ut_str_replace(const char* from, const char* to, std::string& src) +{ + std::string::size_type loc = 0; + + if(!strcmp(from, to))return; + + while(std::string::npos != (loc = src.find(from, 0))) + { + src.replace(loc, strlen(from), to); + } +} + +bool ut_str_match(const char* tmpl, const char* str) +{ + const char* c1 = tmpl; + const char* c2 = str; + unsigned l1 = strlen(tmpl); + unsigned l2 = strlen(str); + + while(*c1 && *c2) + { + if(*c1 == '?'){ + c1++; + c2++; + }else if(*c1 == '*'){ + c1++; + if(*c1 == '\0'){ + return true; + }else if(*c1 == '?'){ + c2 = c2 + (strlen(c2) - strlen(c1)); + }else{ + c2 = strchr(c2,*c1); + if(!c2){ + return false; + } + } + }else{ + if(*c1 != *c2){ + return false; + } + c1++; + c2++; + } + } + + if((!(*c1) || (*c1) == '*') && !(*c2)){ + return true; + }else{ + return false; + } +} \ No newline at end of file diff --git a/mBot/src/utils/cUtils.h b/mBot/src/utils/cUtils.h new file mode 100644 index 0000000..72f2858 --- /dev/null +++ b/mBot/src/utils/cUtils.h @@ -0,0 +1,137 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _cUTILS_H__ +#define _cUTILS_H__ + +#include +#include + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + + +class cutFile +{ +#ifdef getc +#undef getc +#undef putc +#endif +public: + virtual int read(void* out,unsigned long n)=0; + virtual int write(void* out,unsigned long n)=0; + virtual int writestring(const char* str){return write((void*)str, strlen(str));} + virtual int size()=0; + virtual int tellpos()=0; + virtual int setpos(unsigned long pos)=0; + virtual int close()=0; + virtual int getc()=0; + virtual int putc(int c)=0; +}; + +class cutSockf : public cutFile +{ +public: + int open(SOCKET s){m_written = 0; m_sock = s; return 1;} + int read(void* out,unsigned long n){return recv(m_sock, (char*)out, n, 0);} + int write(void* out,unsigned long n){m_written += n; return send(m_sock, (const char*)out, n, 0);} + int writestring(const char* str){return write((void*)str, strlen(str));} + int size(){return m_written;} + int tellpos(){return 0;} + int setpos(unsigned long pos){return 0;}; + int close(){closesocket(m_sock); return 1;} + int getc(){int c=0; read(&c,1); return c;} + int putc(int c){return write(&c, 1);} +protected: + SOCKET m_sock; + int m_written; +}; + +class cutDiskf : public cutFile +{ +public: + enum FTYPE{FT_NONE, FT_DIRECTORY, FT_FILE}; +public: + cutDiskf(); + ~cutDiskf(); +public: + int open(const char* f,const char* mode); + //int open(const wchar_t* f, const wchar_t* mode); + int read(void* out,unsigned long n); + int write(void* in,unsigned long n); + int size(); + int tellpos(); + int seek(int pos,int method); + int setpos(unsigned long pos); + int close(); + int getc(); + int putc(int c){return fputc(c, (FILE*)m_fp);} + void* getfp(){return m_fp;} + + static FTYPE checkFile(const char* path); + + operator FILE* (){return (FILE*)m_fp;} +protected: + void* m_fp; +}; + +class cutMemf : public cutFile +{ +public: + cutMemf(); + cutMemf(void* data,unsigned long length); + ~cutMemf(); +public: + int create(unsigned long len); + int read(void* out,unsigned long n); + int write(void* in,unsigned long n); + int size(){return (m_end - m_data);} + unsigned long written(){return m_maxptr - m_data;} + int tellpos(){return (m_ptr - m_data);} + int setpos(unsigned long pos); + int getc(){return (m_ptr 0){ + fputc('\t',out); + level--; + } +} + +void xml_write_value(FILE* out,const char* val,long length) +{ + if(!length){ + length = strlen(val); + } + + for(int i=0;i' || *val=='<' || *val=='&'){ + fprintf(out,"&#%.2x;",*val); + }else{ + fputc(*val,out); + } + } +} + +cXmlDoc::cXmlDoc() +{ + memset(&m_root,0,sizeof(m_root)); + m_parse_flags = m_flags = m_level = 0; +} + +cXmlDoc::~cXmlDoc() +{ + m_root.Free(); + m_parse_flags = m_flags = m_level = 0; +} + +long cXmlDoc::ParseProperties(char* start,sXmlNode* node) +{ + char* s = start; + char* ids = NULL; + char* ide = NULL; + char* vs = NULL; + char* ve = NULL; + char et = '\0'; + sXmlProperty prop; + + while((s = xml_strnws(s)) && *s!='\0' && *s!='/') // id = [',"] .... [',"] + { + ids = s; + if(!isalpha(*s)) + { + return (m_parse_flags & cXmlDoc::PARSE_IGNORE_BAD_PROPERTIES)!=0; + } + s++; + while(isalnum(*s) || *s=='_' || *s=='.' || *s=='-' || *s == ':') + { + s++; + } + if(*s == '\0') + { + return (m_parse_flags & cXmlDoc::PARSE_IGNORE_BAD_PROPERTIES)!=0; + } + ide = s; + + s = xml_strnws(s); + if(!s || *s != '=') + { + return (m_parse_flags & cXmlDoc::PARSE_IGNORE_BAD_PROPERTIES)!=0; + } + s++; + + s = xml_strnws(s); + if(!s || (*s!='\'' && *s != '\"')) + { + return (m_parse_flags & cXmlDoc::PARSE_IGNORE_BAD_PROPERTIES)!=0; + } + et = *s; + vs = ++s; + ve = strchr(vs,et); + if(!ve) + { + return (m_parse_flags & cXmlDoc::PARSE_IGNORE_BAD_PROPERTIES)!=0; + } + + prop.name = xml_strndup(ids,ide - ids); + prop.value = xml_parsendup(vs,ve - vs,0);//xml_strndup(vs,ve - vs); + if(!AddProperty(&prop,node))return 0; + memset(&prop,0,sizeof(prop)); + + s = ve + 1; + } + return 1; +} + +long cXmlDoc::AddProperty(sXmlProperty* prop,sXmlNode* node) +{ + sXmlProperty* tmp = (sXmlProperty*)malloc(sizeof(sXmlProperty)); + + if(!tmp){ + return 0; + } + memcpy(tmp,prop,sizeof(sXmlProperty)); + + if(node->f_prop == NULL) + { + node->f_prop = node->l_prop = tmp; + } + else + { + node->l_prop->next = tmp; + node->l_prop = tmp; + } + return 1; +} + +long cXmlDoc::AddBinProperty(sXmlBinProperty* prop,sXmlNode* node) +{ + sXmlBinProperty* tmp = (sXmlBinProperty*)malloc(sizeof(sXmlBinProperty)); + if(!tmp)return 0; + memcpy(tmp,prop,sizeof(sXmlBinProperty)); + + if(node->f_prop == NULL) + { + node->f_prop = node->l_prop = tmp; + } + else + { + node->l_prop->next = tmp; + node->l_prop = tmp; + } + return 1; +} + +long cXmlDoc::AddNewBinProperty(sXmlNode* node,const char* name,void* value) +{ + sXmlBinProperty* tmp = (sXmlBinProperty*)malloc(sizeof(sXmlBinProperty)); + if(!tmp)return 0; + + tmp->name = _strdup(name); + tmp->value = (const char*)value; + + if(node->f_prop == NULL) + { + node->f_prop = node->l_prop = tmp; + } + else + { + node->l_prop->next = tmp; + node->l_prop = tmp; + } + return 1; +} + +long cXmlDoc::SetBinPropertyValue(sXmlNode* node,const char* name,void* value) +{ + sXmlProperty* p = node->f_prop; + while(p) + { + if(p->type() == 1 && strcmp(p->name,name)==0){ + p->value = (const char*)value; + return 1; + } + p = p->next; + } + return 0; +} + +void* cXmlDoc::GetBinPropertyValue(sXmlNode* node,const char* name,long* success) +{ + sXmlProperty* p = node->f_prop; + while(p) + { + if(p->type() == 1 && strcmp(p->name,name)==0){ + *success = TRUE; + return (void*)p->value; + } + p = p->next; + } + *success = FALSE; + return NULL; +} + +long cXmlDoc::JoinParent(sXmlNode* parent,sXmlNode* tmp) +{ + tmp->parent = parent; + parent->num_children ++; + + if(parent->value){ + free((void*)parent->value); + parent->value = NULL; + } + parent->type = NODE_PARENT; + + if(parent->f_child == NULL) + { + parent->f_child = parent->l_child = tmp; + return 1; + } + else + { + parent->l_child->next = tmp; + parent->l_child = tmp; + return 1; + } +} +char* cXmlDoc::ParseNode(char* start,sXmlNode* parent) +{ + char* c = xml_strnws(start); + char* t = NULL; + char* e = NULL; + char* x = NULL; + sXmlNode* node = (sXmlNode*)malloc(sizeof(sXmlNode)); + if(!node)return NULL; + memset(node,0,sizeof(sXmlNode)); + + // comment + // + //< ... > v /> + if(!c || *c != '<') + { + goto Error; + } + c++; + //node type.. + if(*c == '!' && strncmp(c,"!--",3)==0)/*comment*/ + { + c += 3; + e = strstr(c,"-->"); + if(!e) + { + goto Error; + } + else + { + if(m_parse_flags & cXmlDoc::PARSE_COMMENTS) + { + node->type = cXmlDoc::NODE_COMMENT; + node->value = xml_strndup(c,e - c); + JoinParent(parent,node); + } + else + { + free(node); + } + return e + 3; + } + } + else if(*c == '!')/*special command */ + { + c ++; + e = xml_strstrx(c,">"); + if(!e) + { + goto Error; + } + + if(m_parse_flags & cXmlDoc::PARSE_SPECIAL) + { + node->type = cXmlDoc::NODE_SPECIAL; + node->value = xml_strndup(c,e - c); + JoinParent(parent,node); + } + else + { + free(node); + } + return e + 1; + } + else if(*c == '?')/**/ + { + c++; + e = xml_strstrx(c,"?>"); + if(!e) + { + goto Error; + } + if(m_parse_flags & cXmlDoc::PARSE_COMMANDS) + { + node->type = cXmlDoc::NODE_COMMAND; + node->value = xml_strndup(c,e - c); + JoinParent(parent,node); + } + else + { + free(node); + } + return c + 2; + } + else/*normal node*/ + { + if(!isalnum(*c)) + { + goto Error;//improper.. too bad :-) + } + t = xml_strfnalnum(c); + if(!t || (*t != ' ' && *t != '>' && *t != '/' && !isspace(*t))) + { + goto Error; + } + + node->name = xml_strndup(c,t - c); + + e = xml_strstrx(c,">"); + if(!e) + { + goto Error; + } + *e = '\0';//terminate ;-) cool, isn't it? + if(!ParseProperties(t,node)) + { + goto Error; + } + *e = '>';// + x = e + 1; + + if(*(e - 1) == '/') + { + node->type = cXmlDoc::NODE_DATA; + JoinParent(parent,node); + return e + 1;/**/ + } + c = e + 1; +Next: + e = strchr(c,'<'); + if(!e) + { + goto Error;//error? + } + else + { + //end tag, or child + if(*(e + 1) == '/')//end tag.. possibly + { + if(strncmp(e + 2,node->name,strlen(node->name))!=0) + { + goto Error; // too bad :-) + } + c = xml_strnws(e + 2 + strlen(node->name)); + if(!c || *c != '>') + { + goto Error; + } + t = strchr(t,'>'); + if(!t) + { + goto Error; + } + /*append as a child, etc...*/ + + if(node->f_child == NULL)//no children.. then data is interesting ;-) + { + t = xml_strnws(x); + if(!t) + { + goto Error; + } + *e = '\0'; // '<'; + x = xml_strrnws(t); + if(!x) + { + goto Error; + } + x++; + node->type = cXmlDoc::NODE_DATA; + node->value = xml_parsendup(t,x - t,0);//xml_strndup(t,x - t); + } + else + { + node->type = node->type = cXmlDoc::NODE_PARENT; + } + JoinParent(parent,node); + return c + 1; + } + else + { + c = ParseNode(e,node); + if(!c) + { + goto Error; + } + else + { + goto Next; + } + } + } + } +Error: + if(node) + { + node->Free(); + free(node); + } + return NULL; +} + +long cXmlDoc::SaveNode(FILE* f,sXmlNode* node) +{ + while(node) + { + switch(node->type) + { + case cXmlDoc::NODE_COMMAND: + xml_put_tabs(f,m_level); + fprintf(f,"\r\n",node->value); + break; + case cXmlDoc::NODE_SPECIAL: + xml_put_tabs(f,m_level); + fprintf(f,"\r\n",node->value); + break; + case cXmlDoc::NODE_COMMENT: + xml_put_tabs(f,m_level); + fprintf(f,"\r\n",node->value); + break; + case cXmlDoc::NODE_PARENT: + xml_put_tabs(f,m_level); + + if(node->f_prop) + { + fprintf(f,"<%s",node->name); + sXmlProperty* p = node->f_prop; + while(p) + { + fprintf(f," %s=\"%s\"",p->name,p->value); + p = p->next; + } + fprintf(f,">\r\n"); + } + else + { + fprintf(f,"<%s>\r\n",node->name); + } + + m_level ++; + SaveNode(f,node->f_child); + m_level --; + xml_put_tabs(f,m_level); + fprintf(f,"\r\n",node->name); + break; + case cXmlDoc::NODE_DATA: + xml_put_tabs(f,m_level); + + if(node->f_prop) + { + fprintf(f,"<%s",node->name); + sXmlProperty* p = node->f_prop; + while(p) + { + fprintf(f," %s=\"",p->name); + xml_write_value(f,p->value,0); + fputc('\"',f); + p = p->next; + } + } + else + { + fprintf(f,"<%s",node->name); + } + + if(node->value) + { + fputc('>',f); + xml_write_value(f,node->value,0); + fprintf(f,"\r\n",node->name); + } + else + { + fprintf(f,"/>\r\n"); + } + break; + } + node = node->next; + } + return 1; +} + +long cXmlDoc::SaveToFile(const char* file) +{ + FILE* f = fopen(file,"wb"); + m_level = 0; + if(f) + { + fprintf(f,"\r\n"); + SaveNode(f,m_root.f_child); + fclose(f); + return 1; + } + else + { + return 0; + } +} +void cXmlDoc::Free() +{ + m_root.Free(); +} + +const char* cXmlDoc::GetProperty(sXmlNode* node,const char* name) +{ + sXmlProperty* prop; + if(!node || !name)return NULL; + + prop = node->f_prop; + while(prop){ + if(strcmp(prop->name,name)==0){ + return (const char*)prop->value; + } + prop = prop->next; + } + return NULL; +} + +long cXmlDoc::SetValue(sXmlNode* node,const char* value) +{ + if(!node || !node->value || !value)return 0; + + char* tmp = _strdup(value); + if(!tmp)return 0; + free((void*)node->value); + node->value = tmp; + return 1; +} + +sXmlNode* cXmlDoc::GetNode(const char* path,sXmlNode* parent) +{ + sXmlNode* n = NULL; + char* c = NULL; + char* sc = (char*)path; + + if(!path || !strlen(path)) + { + return NULL; + } + if(!parent) + { + parent = &m_root; + } +Next: + c = strchr(sc,'/'); + if(!c) + { + c = sc + strlen(sc); + } + if(c == sc) + { + return NULL; + } + + n = parent->f_child; + while(n) + { + if(n->name && strncmp(n->name,sc,c - sc) == 0) + { + if(*c == '\0') + { + return n; + } + else + { + sc = c + 1; + parent = n; + goto Next; + } + } + n = n->next; + } + return NULL; +} + +sXmlNode* cXmlDoc::AddNewNode(const char* name,const char* value,sXmlNode* parent) +{ + sXmlNode* tmp; + + if(!parent){parent = &m_root;} + + if(!parent || !name || !value){ + return NULL; + } + + if((tmp = GetNode(name,parent)) && tmp->value && strcmp(tmp->value,value)==0){ + return tmp; + }else{ + tmp = NULL; + } + + tmp = (sXmlNode*)malloc(sizeof(sXmlNode)); + if(!tmp){ + return NULL; + } + memset(tmp,0,sizeof(sXmlNode)); + + tmp->name = _strdup(name); + tmp->value = _strdup(value); + tmp->parent = parent; + tmp->type = NODE_DATA; + JoinParent(parent,tmp); + return tmp; +} + +long cXmlDoc::ParseString(char* buffer, long flags) +{ + char* c = NULL; + char* s = NULL; + long level = 0; + + m_root.Free(); + + /*initializing processor*/ + s = c = buffer; + /*processing*/ + c = xml_strnws(c); + if(!c){ + goto End;//empty? + } + + if(strncmp(c,""); + if(!c) + { + goto Error; + } + c += 2; + } + m_parse_flags = flags; +GoOn: + c = ParseNode(c,&m_root); + if(!c) + { + goto Error; + } + else if(*c != '\0' && ((m_parse_flags & cXmlDoc::PARSE_MULTIPLE_ROOTS) || m_root.l_child == NULL + || (m_root.l_child->type != cXmlDoc::NODE_PARENT && m_root.l_child->type != cXmlDoc::NODE_DATA))) + { + goto GoOn; + } + +End: + return 1; +Error: + m_root.Free(); + return 0; +} + +long cXmlDoc::ParseFile(const char* file,long flags) +{ + cutMemf mf; + + if(!mf.load(mb2u(file), 0)){ + return 0; + } + + if(ParseString((char*)mf.getdata(),flags)){ + mf.close(); + return 1; + }else{ + mf.close(); + return 0; + } +} \ No newline at end of file diff --git a/mBot/src/utils/cXmldoc.h b/mBot/src/utils/cXmldoc.h new file mode 100644 index 0000000..71c2cd0 --- /dev/null +++ b/mBot/src/utils/cXmldoc.h @@ -0,0 +1,153 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _XML_DOC_H_ +#define _XML_DOC_H_ + +#include + +/*///////////////////// +//CXmlDoc::Structures +/////////////////////*/ + +#define xmlmin(a,b) (((a) < (b)) ? (a) : (b)) + +struct sXmlProperty +{ + const char* name; + const char* value; + sXmlProperty* next; +public: + sXmlProperty(){ + name = value = NULL; + next = NULL; + } + void Free() + { + if(name){ + free((void*)name); + } + if(value){ + free((void*)value); + } + } + int type(){ + return 0; + } +}; + +struct sXmlBinProperty : public sXmlProperty +{ +public: + void Free(){ + value = NULL; + sXmlProperty::Free(); + } + int type(){return 1;} +}; + +struct sXmlNode +{ + const char* name; + const char* value; + long type; + long num_children; + sXmlProperty* f_prop; + sXmlProperty* l_prop; + + sXmlNode* parent; + sXmlNode* f_child;/*first child*/ + sXmlNode* l_child;/*last child*/ + sXmlNode* next; +public: + sXmlNode(){memset(this,0,sizeof(sXmlNode));} + void Free() + { + sXmlNode* f = this->f_child; + sXmlProperty* p = this->f_prop; + while(f) + { + sXmlNode* tmp = f->next; + f->Free(); + free((void*)f); + f = tmp; + } + while(p) + { + sXmlProperty* tmp = p->next; + p->Free(); + free((void*)p); + p = tmp; + } + if(this->name)free((void*)this->name); + if(this->value)free((void*)this->value); + memset(this,0,sizeof(sXmlNode)); + } +}; + + + + +class cXmlDoc +{ +public: + + enum {NODE_NONE = 0,NODE_DOC_TYPE,NODE_SPECIAL,NODE_COMMAND,NODE_ROOT,NODE_PARENT,NODE_DATA,NODE_COMMENT}; + + const static long PARSE_NOT_REQUIRE_DEF = 0x01; + const static long PARSE_COMMENTS = 0x02; + const static long PARSE_IGNORE_WHITESPACES = 0x04; + const static long PARSE_MULTIPLE_ROOTS = 0x08; + const static long PARSE_SPECIAL = 0x10; + const static long PARSE_COMMANDS = 0x20; + const static long PARSE_IGNORE_BAD_PROPERTIES = 0x40; + +public: + cXmlDoc(); + ~cXmlDoc(); +public: + long ParseFile(const char* file,long flags); + long ParseString(char* string, long flags); + long SaveToFile(const char* file); + void Free(); +public: + const char* GetProperty(sXmlNode* node,const char* name); + sXmlNode* GetRootNode(){return &m_root;} + sXmlNode* GetNode(const char* path,sXmlNode* parent = NULL); + sXmlNode* AddNewNode(const char* name,const char* value,sXmlNode* parent = NULL); + long SetValue(sXmlNode* node,const char* value); +protected: + long SaveNode(FILE* f,sXmlNode* node); + char* ParseNode(char* start,sXmlNode* parent); + long ParseProperties(char* start,sXmlNode* node); + long JoinParent(sXmlNode* parent,sXmlNode* child); + long AddProperty(sXmlProperty* prop,sXmlNode* node); + long AddBinProperty(sXmlBinProperty* prop,sXmlNode* node); + long AddNewBinProperty(sXmlNode* node,const char* name,void* value); + long SetBinPropertyValue(sXmlNode* node,const char* name,void* value); + void* GetBinPropertyValue(sXmlNode* node,const char* name,long* success); +protected: + sXmlNode m_root; + long m_flags; + long m_parse_flags; + long m_level; +}; + +#endif //_XML_DOC_H_ \ No newline at end of file diff --git a/mBot/src/utils/includes.h b/mBot/src/utils/includes.h new file mode 100644 index 0000000..6555294 --- /dev/null +++ b/mBot/src/utils/includes.h @@ -0,0 +1,33 @@ +/* + +Miranda Scripting Plugin for Miranda-IM +Copyright 2004-2006 Piotr Pawluczuk (www.pawluczuk.info) + +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 option) 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. + +*/ +#ifndef _INCLUDES_H__ +#define _INCLUDES_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif //_INCLUDES_H__ \ No newline at end of file diff --git a/mBot/src/utils/utils.vcproj b/mBot/src/utils/utils.vcproj new file mode 100644 index 0000000..2a673db --- /dev/null +++ b/mBot/src/utils/utils.vcproj @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3