From 7b6fb82d857584f93a1d4b7e9b3a7db0bc9c80f9 Mon Sep 17 00:00:00 2001 From: imaginos Date: Wed, 11 May 2005 08:24:49 +0000 Subject: [PATCH] initial import of modperl into znc git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@264 726aef4b-f618-498e-8847-2d620e286838 --- modules/Makefile.in | 9 ++- modules/modperl.cpp | 155 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 modules/modperl.cpp diff --git a/modules/Makefile.in b/modules/Makefile.in index 627ed32a..ea300c3a 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -20,7 +20,7 @@ endif all: $(OBJS) $(TARGETS) depend:: - g++ -M $(CXXFLAGS) $(SRCS) $(INCLUDES) >.depend + g++ -M $(CXXFLAGS) $(SRCS) $(INCLUDES) `perl -MExtUtils::Embed -e ccopts` >.depend install: all create_install_dir $(INSTALL_TARGS) @echo -n "" @@ -41,3 +41,10 @@ clean: %.o: %.cpp $(CXX) $(CXXFLAGS) $(INCLUDES) -c -o $@ $< + +########### modperl special TODO this is just so i don't forget, need to make configureable yet +modperl.so: modperl.o + $(CXX) $(CXXFLAGS) -shared -o $@ $< $(INCLUDES) $(LIBS) `perl -MExtUtils::Embed -e ccopts -e ldopts` + +modperl.o: modperl.cpp + $(CXX) $(CXXFLAGS) $(INCLUDES) -c -o $@ modperl.cpp `perl -MExtUtils::Embed -e ccopts` diff --git a/modules/modperl.cpp b/modules/modperl.cpp new file mode 100644 index 00000000..6ae273c2 --- /dev/null +++ b/modules/modperl.cpp @@ -0,0 +1,155 @@ +#include "main.h" +#include "User.h" +#include "Nick.h" +#include "Modules.h" +#include "Chan.h" + +// perl stuff +#include +#include +#include + +class CModPerl; + +static CModPerl *g_ModPerl = NULL; + +class CModPerl : public CModule +{ +public: + MODCONSTRUCTOR( CModPerl ) + { + g_ModPerl = this; + m_pPerl = perl_alloc(); + perl_construct( m_pPerl ); + AddZNCHook( "Init" ); + AddZNCHook( "Shutdown" ); + } + + virtual ~CModPerl() + { + ModPerlDestroy(); + perl_destruct( m_pPerl ); + perl_free( m_pPerl ); + g_ModPerl = NULL; + } + + virtual bool OnLoad( const CString & sArgs ); + + virtual bool OnChanMsg( const CNick& Nick, const CChan & Channel, CString & sMessage ) + { + int iRet = CallBack( "OnChanMsg", Nick.GetNickMask().c_str(), Channel.GetName().c_str(), sMessage.c_str(), NULL ); + if ( iRet > 0 ) + return( true ); + + return( false ); + } + + void AddZNCHook( const string & sHookName ) + { + m_mssHookNames.insert( sHookName ); + } + + +private: + PerlInterpreter *m_pPerl; + set< string > m_mssHookNames; + + void ModPerlInit() + { + CallBack( "Init", NULL ); + } + + void ModPerlDestroy() + { + CallBack( "Shutdown", NULL ); + } + + int CallBack( const char *pszHookName, ... ) + { + set< string >::iterator it = m_mssHookNames.find( pszHookName ); + + if ( it == m_mssHookNames.end() ) + return( -1 ); + + va_list ap; + va_start( ap, pszHookName ); + + char *pTmp; + + dSP; + ENTER; + SAVETMPS; + + PUSHMARK( SP ); + while( ( pTmp = va_arg( ap, char * ) ) ) + { + XPUSHs( sv_2mortal( newSVpv( pTmp, strlen( pTmp ) ) ) ); + } + PUTBACK; + + int iCount = call_pv( it->c_str(), G_SCALAR ); + + SPAGAIN; + int iRet = 0; + + if ( iCount == 1 ) + iRet = POPi; + + PUTBACK; + FREETMPS; + LEAVE; + + va_end( ap ); + return( iRet ); + } +}; + +MODULEDEFS( CModPerl ) + + + +//////////////////////////////// PERL GUTS ////////////////////////////// + +XS(XS_AddZNCHook) +{ + dXSARGS; + if ( items != 1 ) + Perl_croak(aTHX_ "Usage: AddZNCHook( HookName )"); + + SP -= items; + ax = (SP - PL_stack_base) + 1 ; + { + if ( g_ModPerl ) + g_ModPerl->AddZNCHook( (char *)SvPV(ST(0),PL_na) ); + + PUTBACK; + return; + } +} + + +EXTERN_C void +xs_init(pTHX) +{ + char *file = __FILE__; + newXS( "AddZNCHook", XS_AddZNCHook, file ); +} + + +/////////// supporting functions from within module +bool CModPerl::OnLoad( const CString & sArgs ) +{ + const char *pArgv[] = + { + "ZNCPerl", + sArgs.c_str(), + NULL + }; + + perl_parse( m_pPerl, xs_init, 2, (char **)pArgv, (char **)NULL ); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + + ModPerlInit(); + return( true ); +} +