Big update of modperl module.

Old modperl had several flaws and was very outdated.
New modperl makes the whole ZNC API accessible from inside perl.
Modperl API was changed, so old perl modules are not supported,
but they weren't used much anyway.

Modperl needs --enable-perl option to ./configure.

This introduces new dependence on SWIG, which is needed only while
compiling ZNC. So to use modperl, you need to install SWIG or
to download several files and use --disable-swig option of configure.

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@2120 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
darthgandalf
2010-09-07 11:13:47 +00:00
parent ffcd42232f
commit a44e6eaada
13 changed files with 2524 additions and 1648 deletions
Vendored
+81 -3
View File
@@ -568,6 +568,7 @@ MODLINK
LIBZNCDIR
LIBZNC
MODFLAGS
SWIG_BINARY
PERL_BINARY
openssl_LIBS
openssl_CFLAGS
@@ -642,6 +643,7 @@ enable_debug
enable_ipv6
enable_openssl
enable_perl
enable_swig
enable_sasl
enable_optimization
enable_c_ares
@@ -1288,7 +1290,13 @@ Optional Features:
--enable-debug enable debugging
--disable-ipv6 disable ipv6 support
--disable-openssl disable openssl
--disable-perl disable perl
--enable-perl enable perl
--disable-swig Disable automatic generation of source files needed
for modperl. This value is ignored if perl is
disabled or not found. If you disable swig, but
still want to use modperl, please download the
necessary files to modules/modperl. Check
http://en.znc.in/wiki/Modperl for details.
--enable-sasl enable sasl
--disable-optimization Disable some compiler optimizations to decrease
memory usage while compiling
@@ -2913,7 +2921,14 @@ fi
if test "${enable_perl+set}" = set; then :
enableval=$enable_perl; PERL="$enableval"
else
PERL="auto"
PERL="no"
fi
# Check whether --enable-swig was given.
if test "${enable_swig+set}" = set; then :
enableval=$enable_swig; SWIG="$enableval"
else
SWIG="auto"
fi
# Check whether --enable-sasl was given.
@@ -3649,6 +3664,7 @@ fi
if test "x$PERL" != "xno"; then
old_PERL="$PERL"
old_SWIG="$SWIG"
# Extract the first word of "perl", so it can be a program name with args.
set dummy perl; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -3734,6 +3750,53 @@ else
PERL="no"
fi
if test "x$PERL" != "xno"; then
if test "x$SWIG" != "xno"; then
# Extract the first word of "swig", so it can be a program name with args.
set dummy swig; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if test "${ac_cv_path_SWIG_BINARY+set}" = set; then :
$as_echo_n "(cached) " >&6
else
case $SWIG_BINARY in
[\\/]* | ?:[\\/]*)
ac_cv_path_SWIG_BINARY="$SWIG_BINARY" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_path_SWIG_BINARY="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
SWIG_BINARY=$ac_cv_path_SWIG_BINARY
if test -n "$SWIG_BINARY"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG_BINARY" >&5
$as_echo "$SWIG_BINARY" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test -z "$SWIG_BINARY"; then
SWIG="no"
fi
fi
fi
LDFLAGS="$my_saved_LDFLAGS"
else
PERL="no"
@@ -3751,7 +3814,22 @@ $as_echo "$as_me: WARNING: perl was not found and thus disabled" >&2;}
PERL_BINARY=""
else
PERL=yes
if test "x$SWIG" = "xno"; then
SWIG_BINARY=""
if test "x$old_SWIG" = "xno"; then
PERL="yes, but with manual download"
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: swig was disabled, so you should put needed sources for modperl to modules/modperl.
Please check http://en.znc.in/wiki/Modperl for details." >&5
$as_echo "$as_me: WARNING: swig was disabled, so you should put needed sources for modperl to modules/modperl.
Please check http://en.znc.in/wiki/Modperl for details." >&2;}
else
as_fn_error $? "swig was not found. Try --disable-perl, or download the necessary sources and use --disable-swig.
Please check http://en.znc.in/wiki/Modperl for details." "$LINENO" 5
fi
else
PERL="yes"
SWIG="yes"
fi
fi
fi
+32 -3
View File
@@ -93,9 +93,16 @@ AC_ARG_ENABLE( [openssl],
[SSL="$enableval"],
[SSL="auto"])
AC_ARG_ENABLE( [perl],
AS_HELP_STRING([--disable-perl], [disable perl]),
AS_HELP_STRING([--enable-perl], [enable perl]),
[PERL="$enableval"],
[PERL="auto"])
[PERL="no"])
AC_ARG_ENABLE( [swig],
AS_HELP_STRING([--disable-swig], [Disable automatic generation of source files needed for modperl.
This value is ignored if perl is disabled or not found. If you disable swig,
but still want to use modperl, please download the necessary files to modules/modperl.
Check http://en.znc.in/wiki/Modperl for details.]),
[SWIG="$enableval"],
[SWIG="auto"])
AC_ARG_ENABLE( [sasl],
AS_HELP_STRING([--enable-sasl], [enable sasl]),
[if test "$enableval" = "yes" ; then SASL=1; fi],)
@@ -257,6 +264,7 @@ fi
if test "x$PERL" != "xno"; then
old_PERL="$PERL"
old_SWIG="$SWIG"
AC_PATH_PROG([PERL_BINARY], [perl], [])
if test -n "$PERL_BINARY"; then
my_saved_LDFLAGS="$LDFLAGS"
@@ -264,6 +272,14 @@ if test "x$PERL" != "xno"; then
AC_CHECK_LIB(perl, perl_alloc,
[: No, we do not want autoconf to do sth automatically],
PERL="no")
if test "x$PERL" != "xno"; then
if test "x$SWIG" != "xno"; then
AC_PATH_PROG([SWIG_BINARY], [swig], [])
if test -z "$SWIG_BINARY"; then
SWIG="no"
fi
fi
fi
LDFLAGS="$my_saved_LDFLAGS"
else
PERL="no"
@@ -274,7 +290,20 @@ if test "x$PERL" != "xno"; then
[perl was not found and thus disabled])
PERL_BINARY=""
else
PERL=yes
if test "x$SWIG" = "xno"; then
SWIG_BINARY=""
if test "x$old_SWIG" = "xno"; then
PERL="yes, but with manual download"
AC_MSG_WARN([swig was disabled, so you should put needed sources for modperl to modules/modperl.
Please check http://en.znc.in/wiki/Modperl for details.])
else
AC_MSG_ERROR([swig was not found. Try --disable-perl, or download the necessary sources and use --disable-swig.
Please check http://en.znc.in/wiki/Modperl for details.])
fi
else
PERL="yes"
SWIG="yes"
fi
fi
fi
+31 -2
View File
@@ -22,6 +22,7 @@ LDFLAGS := @LDFLAGS@
# The znc binary links already against those.
# LIBS := @LIBS@
PERL := @PERL_BINARY@
SWIG := @SWIG_BINARY@
MODDIR := @MODDIR@
DATADIR := @DATADIR@
LIBZNC := @LIBZNC@
@@ -69,6 +70,10 @@ ifneq "$(PERL)" ""
modperlFLAGS := $(shell $(PERL) -MExtUtils::Embed -e perl_inc -e ldopts)
# Perl API is ugly, casting string literals to char* and redeclaring functions :(
modperlFLAGS += -Wno-write-strings -Wno-redundant-decls -Wno-missing-declarations
# This is for SWIG
modperlFLAGS += -DSWIG_TYPE_TABLE=znc
# Find additional headers for out-of-tree build
modperlFLAGS += -I.
PERLHOOK := modperl_install
else
FILES := $(shell echo $(FILES) | sed -e "s/modperl//")
@@ -94,7 +99,7 @@ modtclFLAGS := $(TCL_FLAGS)
TARGETS := $(addsuffix .so, $(FILES))
CLEAN := *.so extra/*.so
CLEAN := *.so extra/*.so modperl/ZNC.so modperl/modperl_wrap.cxx modperl/ZNC.pm
.PHONY: all clean install modperl_install
@@ -125,10 +130,34 @@ clean:
$(E) Building $(if $(filter %extra/,$(dir $<)),extra )module $(notdir $(basename $@))...
$(Q)$(CXX) $(MODFLAGS) $(LDFLAGS) $(MODLINK) -o $@ $< $($(notdir $(basename $@))FLAGS) -MMD -MF .depend/$(notdir $@).dep
modperl_install: create_install_dir
modperl.so: modperl/ZNC.so
modperl/ZNC.so: modperl/modperl_wrap.cxx Makefile
$(E) Building ZNC perl bindings library...
$(Q)$(CXX) $(MODFLAGS) $(LDFLAGS) $(MODLINK) -I$(srcdir) -DSWIG_TYPE_TABLE=znc $(shell $(PERL) -MExtUtils::Embed -e perl_inc -e ldopts) -o $@ $<
ifneq "$(SWIG)" ""
modperl/modperl_wrap.cxx: modperl/modperl.i Makefile modperl/module.h modperl/CString.i
$(E) Generating ZNC API for perl...
@mkdir -p modperl
$(Q)$(SWIG) -perl5 -c++ -shadow -outdir modperl -I$(srcdir) -w362,315,401,402 -o $@.warn $<
$(Q)$(PERL) -pe '$$x==2 and print "items+=0;" and $$x=3;/^XS\(SWIG_init\)/ and $$x=1;$$x==1 and /dXSARGS/ and $$x=2' $@.warn > $@
$(Q)rm -rf $@.warn
$(Q)$(SWIG) -perl5 -c++ -shadow -external-runtime modperl/swigperlrun.h
endif
modperl_install: create_install_dir install_metadirs
for i in $(srcdir)/*.pm; do \
$(INSTALL_DATA) $$i $(DESTDIR)$(MODDIR); \
done
for a in $(srcdir)/*; do \
if [ -d $$a ] && [ -f $${a}.pm ]; then \
cp -Rp $$a $(DESTDIR)$(DATADIR); \
fi \
done
rm -rf $(DESTDIR)$(DATADIR)/modperl
mkdir -p $(DESTDIR)$(MODDIR)/modperl
$(INSTALL_PROGRAM) $(srcdir)/modperl/ZNC.so $(DESTDIR)$(MODDIR)/modperl
$(INSTALL_DATA) $(srcdir)/modperl/ZNC.pm $(DESTDIR)$(MODDIR)/modperl
$(INSTALL_DATA) $(srcdir)/modperl/startup.pl $(DESTDIR)$(MODDIR)/modperl
modtcl_install:
mkdir -p $(DESTDIR)$(DATADIR)/modtcl/
+253 -1193
View File
File diff suppressed because it is too large Load Diff
-447
View File
@@ -1,447 +0,0 @@
# TODO need Close()
package ZNC;
use strict;
my @MODS = ();
sub COREEval
{
my $arg = shift;
eval $arg;
}
sub CORECallFunc
{
my ( $Username, $Func, @args ) = @_;
my $FinalRet = CONTINUE();
foreach( @MODS )
{
next if ( $_->{ZNC_Username} ne $Username );
if ( $_->can( $Func ) )
{
my $Ret = $_->$Func( @args );
if ( $Ret == HALT() )
{
return( $Ret );
}
if ( $Ret == HALTMODS() )
{
return( $Ret );
}
if ( $Ret == HALTCORE() )
{
$FinalRet = $Ret;
}
}
}
return( $FinalRet );
}
sub CORELoadMod
{
my ( $Username, $ModPath ) = @_;
my $Module;
if ( $ModPath =~ /\/([^\/.]+)\.pm/ )
{
$Module = $1;
}
if ( !$Module )
{
ZNC::PutModule( "Invalid Module requested!" );
return( HALTMODS() );
}
my $DPath = GetString( "SavePath" );
my $FileName = $DPath . "/." . $Username . $Module . ".pm";
if ( !open( INMOD, $ModPath ) )
{
ZNC::PutModule( "Unable to open module $ModPath!" );
return( HALTMODS() );
}
if ( !open( OUTMOD, ">$FileName" ) )
{
ZNC::PutModule( "Unable to write to Module cache $FileName!" );
close( INMOD );
return( HALTMODS() );
}
foreach( @MODS )
{
if ( ( $_->{ZNC_Username} eq $Username ) && ( $_->{ZNC_Name} eq $Module ) )
{
ZNC::PutModule( "$Module Already Loaded" );
return( HALTMODS() );
}
}
my $bFoundPackage = 0;
while( <INMOD> )
{
if ( $_ =~ /^\s*package\s*$Module\s*;/ )
{
print OUTMOD "package $Username$Module;\n";
$bFoundPackage = 1;
}
else
{
print OUTMOD $_;
}
}
close( INMOD );
close( OUTMOD );
if( !$bFoundPackage )
{
ZNC::PutModule( "Warning, did not find 'package $Module;' in $FileName" );
}
if ( $INC{$FileName} )
{ # force a delete on this guy
delete $INC{$FileName};
}
require $FileName;
my $NewMod = $Username . $Module;
my $obj = new $NewMod();
if ( !$obj )
{
ZNC::PutModule( "$Module Failed to load" );
return( HALTMODS() );
}
$obj->{ZNC_Username} = $Username;
$obj->{ZNC_Name} = $Module;
$obj->{ZNC_ModPath} = $FileName;
@{$obj->{socks}} = ();
push( @MODS, $obj );
ZNC::PutModule( "Loaded $Module" );
}
sub COREUnloadMod
{
my ( $Username, $Module ) = @_;
$Module =~ s/(.+?)\.pm/$1/;
if ( !$Module )
{
ZNC::PutModule( "Invalid Module requested!" );
return( HALTMODS() );
}
for( my $i = 0; $i < @MODS; $i++ )
{
if ( ( $MODS[$i]->{ZNC_Username} eq $Username ) && ( $MODS[$i]->{ZNC_Name} eq $Module ) )
{
my $filename = $MODS[$i]->{ZNC_ModPath};
undef $MODS[$i];
splice( @MODS, $i, 1 );
if ( $INC{$filename} )
{ # remove the $INC instantiation
delete $INC{$filename};
}
ZNC::PutModule( "Unloaded $Module" );
return( CONTINUE() );
}
}
ZNC::PutModule( "$Module Isn't Loaded" );
}
# the timer is inserted, it just calls this guy and expects it to be here
sub CORECallTimer
{
my ( $Username, $Func, $ModName ) = @_;
for( my $i = 0; $i < @MODS; $i++ )
{
if ( ( $MODS[$i]->{ZNC_Username} eq $Username ) && ( $MODS[$i]->{ZNC_Name} eq $ModName ) )
{
return( $MODS[$i]->$Func() );
}
}
return( HALTMODS() );
}
sub CORECallSock
{
my ( $Username, $Func, $ModName, $fd, @args ) = @_;
for( my $i = 0; $i < @MODS; $i++ )
{
if ( ( $MODS[$i]->{ZNC_Username} eq $Username ) && ( $MODS[$i]->{ZNC_Name} eq $ModName ) )
{
######### Sock methods are in the module directly
if ( @{$MODS[$i]->{socks}} == 0 )
{ # ok, try simple manner, overloads in this here class
if ( $MODS[$i]->can( $Func ) )
{
my $ret = $MODS[$i]->$Func( $fd, @args );
if ( $Func eq "OnConnectionFrom" )
{ # special case this for now, requires a return value
return( $ret );
}
}
return( CONTINUE() );
}
########## they sent us a socket to look at, we'll use it
for( my $a = 0; $a < @{$MODS[$i]->{socks}}; $a++ )
{
my $obj = ${$MODS[$i]->{socks}}[$a];
if ( $obj->{fd} == $fd )
{
if ( $obj->can( $Func ) )
{
my $ret = $obj->$Func( @args );
if ( $Func eq "OnConnectionFrom" )
{ # special case this for now, requires a return value
return( $ret );
}
elsif ( $Func eq "OnSockDestroy" )
{
splice( @{$MODS[$i]->{socks}}, $a, 1 );
}
}
return( CONTINUE() );
}
}
last; #no point in checking further
}
}
return( HALTMODS() );
}
######################
# Ease Of use USER functions
sub AddTimer
{
my ( $mod, $funcname, $description, $interval, $cycles ) = @_;
COREAddTimer( $mod->{ZNC_Name}, $funcname, $description, $interval, $cycles );
}
sub RemTimer
{
my ( $mod, $funcname ) = @_;
CORERemTimer( $mod->{ZNC_Name}, $funcname );
}
sub PutModule
{
my ( $line, $ident, $host ) = @_;
if ( !$ident )
{
$ident = "znc";
}
if ( !$host )
{
$host = "znc.in";
}
COREPutModule( "Module", $line, $ident, $host );
}
sub PutModNotice
{
my ( $line, $ident, $host ) = @_;
if ( !$ident )
{
$ident = "znc";
}
if ( !$host )
{
$host = "znc.in";
}
COREPutModule( "ModNotice", $line, $ident, $host );
}
sub PutIRC
{
my ( $line ) = @_;
COREPuts( "IRC", $line );
}
sub PutStatus
{
my ( $line ) = @_;
COREPuts( "Status", $line );
}
sub PutUser
{
my ( $line ) = @_;
COREPuts( "User", $line );
}
sub PutTarget
{
my ( $target, $line ) = @_;
PutIRC( "PRIVMSG $target :$line" );
}
sub Connect
{
my ( $obj, $host, $port, $timeout, $bEnableReadline, $bUseSSL ) = @_;
if ( ( !$host ) || ( !$port ) )
{
return( -1 );
}
if ( !$timeout )
{
$timeout = 60;
}
if ( !$bEnableReadline )
{
$bEnableReadline = 0;
}
if ( !$bUseSSL )
{
$bUseSSL = 0;
}
return( COREConnect( $obj->{ZNC_Name}, $host, $port, $timeout, $bEnableReadline, $bUseSSL ) );
}
sub ConnectSSL
{
my ( $obj, $host, $port, $timeout, $bEnableReadline, $bUseSSL ) = @_;
return( Connect( $obj, $host, $port, $timeout, $bEnableReadline, $bUseSSL, 1 ) );
}
sub Listen
{
my ( $obj, $port, $bindhost, $bEnableReadline, $bUseSSL ) = @_;
if ( !$port )
{
return( -1 );
}
if ( !$bindhost )
{
$bindhost = "";
}
if ( !$bEnableReadline )
{
$bEnableReadline = 0;
}
if ( !$bUseSSL )
{
$bUseSSL = 0;
}
return( COREListen( $obj->{ZNC_Name}, $port, $bindhost, $bEnableReadline, $bUseSSL ) );
}
sub ListenSSL
{
my ( $obj, $port, $bindhost, $bEnableReadline ) = @_;
return( Listen( $obj, $port, $bindhost, $bEnableReadline, 1 ) );
}
1;
######################
## use this if you really want to have fun. be sure you don't leave a reference to the
## handle laying around! ZNC will deal with that inside your module, so its properly closed
package ZNCSocket;
sub new
{
my ( $classname, $modobj, $fd ) = @_;
if ( !defined( $fd ) )
{
$fd = -1;
}
my $self =
{
modobj => $modobj,
fd => $fd
};
bless( $self, $classname );
return( $self );
}
sub AddSock
{
my ( $me ) = @_;
push( @{$me->{modobj}->{socks}}, $me );
}
sub Connect
{
my ( $me, $host, $port, $timeout, $bEnableReadline, $bUseSSL ) = @_;
$me->{fd} = ZNC::Connect( $me->{modobj}, $host, $port, $timeout, $bEnableReadline, $bUseSSL );
return( ( $me->{fd} >= 0 ) );
}
sub ConnectSSL
{
my ( $me, $host, $port, $timeout, $bEnableReadline ) = @_;
$me->{fd} = ZNC::ConnectSSL( $me->{modobj}, $host, $port, $timeout, $bEnableReadline );
return( ( $me->{fd} >= 0 ) );
}
sub Write
{
my ( $me, $data ) = @_;
return( ZNC::WriteSock( $me->{fd}, $data, length( $data ) ) );
}
sub Close
{
my ( $me ) = @_;
ZNC::CloseSock( $me->{fd} );
}
sub SetTimeout
{
my ( $me, $timeout ) = @_;
ZNC::SetSockValue( $me->{fd}, "timeout", $timeout );
}
sub Listen
{
my ( $me, $port, $bindhost, $bEnableReadline, $bUseSSL ) = @_;
$me->{fd} = ZNC::Listen( $me->{modobj}, $port, $bindhost, $bEnableReadline, $bUseSSL );
return( ( $me->{fd} >= 0 ) );
}
sub ListenSSL
{
my ( $me, $port, $bindhost, $bEnableReadline ) = @_;
$me->{fd} = ZNC::ListenSSL( $me->{modobj}, $port, $bindhost, $bEnableReadline );
return( ( $me->{fd} >= 0 ) );
}
1;
+260
View File
@@ -0,0 +1,260 @@
%{
#include <string>
%}
%feature("naturalvar") CString;
class CString;
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,74,%typemaps_std_string@*/
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,4,%std_string_asptr@*/
%fragment("SWIG_" "AsPtr" "_" {CString},"header",fragment="SWIG_AsCharPtrAndSize") {
SWIGINTERN int
SWIG_AsPtr_std_string SWIG_PERL_DECL_ARGS_2(SV * obj, CString **val)
{
char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ;
if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) {
if (buf) {
if (val) *val = new CString(buf, size - 1);
if (alloc == SWIG_NEWOBJ) free((char*)buf);
return SWIG_NEWOBJ;
} else {
if (val) *val = 0;
return SWIG_OLDOBJ;
}
} else {
static int init = 0;
static swig_type_info* descriptor = 0;
if (!init) {
descriptor = SWIG_TypeQuery("CString" " *");
init = 1;
}
if (descriptor) {
CString *vptr;
int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
if (SWIG_IsOK(res) && val) *val = vptr;
return res;
}
}
return SWIG_ERROR;
}
}
/*@SWIG@*/
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,52,%std_string_asval@*/
%fragment("SWIG_" "AsVal" "_" {CString},"header", fragment="SWIG_" "AsPtr" "_" {CString}) {
SWIGINTERN int
SWIG_AsVal_std_string SWIG_PERL_DECL_ARGS_2(SV * obj, CString *val)
{
CString* v = (CString *) 0;
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2(obj, &v);
if (!SWIG_IsOK(res)) return res;
if (v) {
if (val) *val = *v;
if (SWIG_IsNewObj(res)) {
free((char*)v);
res = SWIG_DelNewMask(res);
}
return res;
}
return SWIG_ERROR;
}
}
/*@SWIG@*/
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,38,%std_string_from@*/
%fragment("SWIG_" "From" "_" {CString},"header",fragment="SWIG_FromCharPtrAndSize") {
SWIGINTERNINLINE SV *
SWIG_From_std_string SWIG_PERL_DECL_ARGS_1(const CString& s)
{
if (s.size()) {
return SWIG_FromCharPtrAndSize(s.data(), s.size());
} else {
return SWIG_FromCharPtrAndSize(s.c_str(), 0);
}
}
}
/*@SWIG@*/
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,201,%typemaps_asptrfromn@*/
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,190,%typemaps_asptrfrom@*/
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,160,%typemaps_asptr@*/
%fragment("SWIG_" "AsVal" "_" {CString},"header",fragment="SWIG_" "AsPtr" "_" {CString}) {
SWIGINTERNINLINE int
SWIG_AsVal_std_string SWIG_PERL_CALL_ARGS_2(SV * obj, CString *val)
{
CString *v = (CString *)0;
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2(obj, &v);
if (!SWIG_IsOK(res)) return res;
if (v) {
if (val) *val = *v;
if (SWIG_IsNewObj(res)) {
free((char*)v);
res = SWIG_DelNewMask(res);
}
return res;
}
return SWIG_ERROR;
}
}
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,28,%ptr_in_typemap@*/
%typemap(in,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
CString *ptr = (CString *)0;
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, &ptr);
if (!SWIG_IsOK(res) || !ptr) {
SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
}
$1 = *ptr;
if (SWIG_IsNewObj(res)) free((char*)ptr);
}
%typemap(freearg) CString "";
%typemap(in,fragment="SWIG_" "AsPtr" "_" {CString}) const CString & (int res = SWIG_OLDOBJ) {
CString *ptr = (CString *)0;
res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, &ptr);
if (!SWIG_IsOK(res)) { SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); }
if (!ptr) { SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); }
$1 = ptr;
}
%typemap(freearg,noblock=1) const CString & {
if (SWIG_IsNewObj(res$argnum)) free((char*)$1);
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,53,%ptr_varin_typemap@*/
%typemap(varin,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
CString *ptr = (CString *)0;
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, &ptr);
if (!SWIG_IsOK(res) || !ptr) {
SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in variable '""$name""' of type '""$type""'");
}
$1 = *ptr;
if (SWIG_IsNewObj(res)) free((char*)ptr);
}
/*@SWIG@*/;
;
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,143,%ptr_typecheck_typemap@*/
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString * {
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, (CString**)(0));
$1 = SWIG_CheckState(res);
}
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString, const CString& {
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, (CString**)(0));
$1 = SWIG_CheckState(res);
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,254,%ptr_input_typemap@*/
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,117,%_ptr_input_typemap@*/
%typemap(in,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString *INPUT(int res = 0) {
res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, &$1);
if (!SWIG_IsOK(res)) {
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
}
res = SWIG_AddTmpMask(res);
}
%typemap(in,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString &INPUT(int res = 0) {
res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, &$1);
if (!SWIG_IsOK(res)) {
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
}
if (!$1) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
}
res = SWIG_AddTmpMask(res);
}
%typemap(freearg,noblock=1,match="in") CString *INPUT, CString &INPUT {
if (SWIG_IsNewObj(res$argnum)) free((char*)$1);
}
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString *INPUT, CString &INPUT {
int res = SWIG_AsPtr_std_string SWIG_PERL_CALL_ARGS_2($input, (CString**)0);
$1 = SWIG_CheckState(res);
}
/*@SWIG@*/
/*@SWIG@*/;
/*@SWIG@*/
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,184,%typemaps_from@*/
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,55,%value_out_typemap@*/
%typemap(out,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString {
$result = SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((CString)($1)); argvi++ ;
}
%typemap(out,noblock=1,fragment="SWIG_" "From" "_" {CString}) const CString& {
$result = SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((CString)(*$1)); argvi++ ;
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,79,%value_varout_typemap@*/
%typemap(varout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString& {
sv_setsv($result,SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((CString)($1))) ;
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,87,%value_constcode_typemap@*/
%typemap(constcode,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString {
/*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
SV *sv = get_sv((char*) SWIG_prefix "$symname", TRUE | 0x2 | GV_ADDMULTI);
sv_setsv(sv, SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((CString)($value)));
SvREADONLY_on(sv);
} while(0) /*@SWIG@*/;
}
/*@SWIG@*/;
;
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,154,%value_throws_typemap@*/
%typemap(throws,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString {
sv_setsv(GvSV(PL_errgv), SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((CString)($1))); SWIG_fail ;
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,258,%value_output_typemap@*/
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,175,%_value_output_typemap@*/
%typemap(in,numinputs=0,noblock=1)
CString *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ),
CString &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) {
$1 = &temp;
}
%typemap(argout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString *OUTPUT, CString &OUTPUT {
if (SWIG_IsTmpObj(res$argnum)) {
if (argvi >= items) EXTEND(sp,1); $result = SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((*$1)); argvi++ ;
} else {
int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | $shadow) : $shadow;
if (argvi >= items) EXTEND(sp,1); $result = SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags); argvi++ ;
}
}
/*@SWIG@*/
/*@SWIG@*/;
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,258,%value_output_typemap@*/
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,175,%_value_output_typemap@*/
%typemap(in,numinputs=0,noblock=1)
CString *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ),
CString &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) {
$1 = &temp;
}
%typemap(argout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString *OUTPUT, CString &OUTPUT {
if (SWIG_IsTmpObj(res$argnum)) {
if (argvi >= items) EXTEND(sp,1); $result = SWIG_From_std_string SWIG_PERL_CALL_ARGS_1((*$1)); argvi++ ;
} else {
int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | $shadow) : $shadow;
if (argvi >= items) EXTEND(sp,1); $result = SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags); argvi++ ;
}
}
/*@SWIG@*/
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,240,%_ptr_inout_typemap@*/
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,230,%_value_inout_typemap@*/
%typemap(in) CString *INOUT = CString *INPUT;
%typemap(in) CString &INOUT = CString &INPUT;
%typemap(typecheck) CString *INOUT = CString *INPUT;
%typemap(typecheck) CString &INOUT = CString &INPUT;
%typemap(argout) CString *INOUT = CString *OUTPUT;
%typemap(argout) CString &INOUT = CString &OUTPUT;
/*@SWIG@*/
%typemap(typecheck) CString *INOUT = CString *INPUT;
%typemap(typecheck) CString &INOUT = CString &INPUT;
%typemap(freearg) CString *INOUT = CString *INPUT;
%typemap(freearg) CString &INOUT = CString &INPUT;
/*@SWIG@*/;
/*@SWIG@*/;
/*@SWIG@*/;
/*@SWIG@*/;
+136
View File
@@ -0,0 +1,136 @@
#!/usr/bin/env perl
#
# Copyright (C) 2004-2010 See the AUTHORS file for details.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
#
use strict;
use warnings;
use IO::File;
use feature 'switch', 'say';
open my $in, "functions.in" or die;
open my $out, "> functions.cpp" or die;
print $out <<'EOF';
/*
* Copyright (C) 2004-2010 See the AUTHORS file for details.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
/***************************************************************************
* This file is generated automatically using codegen.pl from functions.in *
* Don't change it manually. *
***************************************************************************/
/*#include "module.h"
#include "swigperlrun.h"
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include "pstring.h"*/
namespace {
template<class T>
struct SvToPtr {
CString m_sType;
SvToPtr(const CString& sType) {
m_sType = sType;
}
T* operator()(SV* sv) {
T* result;
int res = SWIG_ConvertPtr(sv, (void**)&result, SWIG_TypeQuery(m_sType.c_str()), 0);
if (SWIG_IsOK(res)) {
return result;
}
return NULL;
}
};
CModule::EModRet SvToEModRet(SV* sv) {
return static_cast<CModule::EModRet>(SvUV(sv));
}
}
/*
#define PSTART dSP; I32 ax; int ret = 0; ENTER; SAVETMPS; PUSHMARK(SP)
#define PCALL(name) PUTBACK; ret = call_pv(name, G_EVAL|G_ARRAY); SPAGAIN; SP -= ret; ax = (SP - PL_stack_base) + 1
#define PEND PUTBACK; FREETMPS; LEAVE
#define PUSH_STR(s) XPUSHs(PString(s).GetSV())
#define PUSH_PTR(type, p) XPUSHs(SWIG_NewInstanceObj(const_cast<type>(p), SWIG_TypeQuery(#type), SWIG_SHADOW))
*/
#define PSTART_IDF(Func) PSTART; PUSH_STR(GetPerlID()); PUSH_STR(#Func)
#define PCALLMOD(Error, Success) PCALL("ZNC::Core::CallModFunc"); if (SvTRUE(ERRSV)) { DEBUG("Perl hook died with: " + PString(ERRSV)); Error; } else { Success; } PEND
EOF
while (<$in>) {
my ($type, $name, $args, $default) = /(\S+)\s+(\w+)\((.*)\)(?:=(\w+))?/ or next;
$type =~ s/(EModRet)/CModule::$1/;
$type =~ s/^\s*(.*?)\s*$/$1/;
unless (defined $default) {
given ($type) {
when ('bool') { $default = 'true' }
when ('CModule::EModRet') { $default = 'CONTINUE' }
when ('CString') { $default = '""' }
when (/\*$/) { $default = "($type)NULL" }
}
}
my @arg = map {
my ($t, $v) = /^\s*(.*\W)\s*(\w+)\s*$/;
$t =~ s/^\s*(.*?)\s*$/$1/;
my ($tt, $tm) = $t =~ /^(.*?)\s*?(\*|&)?$/;
{type=>$t, var=>$v, base=>$tt, mod=>$tm//''}
} split /,/, $args;
say $out "$type CPerlModule::$name($args) {";
say $out "\t$type result = $default;" if $type ne 'void';
say $out "\tPSTART_IDF($name);";
given ($type) {
when ('CString') { print $out "\tPUSH_STR($default);" }
when (/\*$/) { my $t=$type; $t=~s/^const//; print $out "\tPUSH_PTR($t, $default);" }
when ('void') { print $out "\tmXPUSHi(0);" }
default { print $out "\tmXPUSHi(static_cast<int>($default));" }
}
say $out " // Default value";
for my $a (@arg) {
given ($a->{type}) {
when (/(vector\s*<\s*(.*)\*\s*>)/) {
my ($vec, $sub) = ($1, $2);
my $dot = '.';
$dot = '->' if $a->{mod} eq '*';
say $out "\tfor (${vec}::const_iterator i = $a->{var}${dot}begin(); i != $a->{var}${dot}end(); ++i) {";
#atm sub is always "...*" so...
say $out "\t\tPUSH_PTR($sub*, *i);";
say $out "\t}";
}
when (/CString/) { say $out "\tPUSH_STR($a->{var});" }
when (/\*$/) { my $t=$a->{type}; $t=~s/^const//; say $out "\tPUSH_PTR($t, $a->{var});" }
when (/&$/) { my $b=$a->{base}; $b=~s/^const//; say $out "\tPUSH_PTR($b*, &$a->{var});" }
}
}
say $out "\tPCALLMOD(,";
my $x = 0;
say $out "\t\tresult = ".sv($type)."(ST(0));" if $type ne 'void';
for my $a (@arg) {
$x++;
say $out "\t\t$a->{var} = PString(ST($x));" if $a->{base} eq 'CString' && $a->{mod} eq '&';
}
say $out "\t);";
say $out "\treturn result;" if $type ne 'void';
say $out "}\n";
}
sub sv {
my $type = shift;
given ($type) {
when (/^(.*)\*$/) { return "SvToPtr<$1>(\"$type\")" }
when ('CString') { return 'PString' }
when ('CModule::EModRet') { return 'SvToEModRet' }
default { return 'SvUV' }
}
}
+776
View File
@@ -0,0 +1,776 @@
/*
* Copyright (C) 2004-2010 See the AUTHORS file for details.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
/***************************************************************************
* This file is generated automatically using codegen.pl from functions.in *
* Don't change it manually. *
***************************************************************************/
/*#include "module.h"
#include "swigperlrun.h"
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#include "pstring.h"*/
namespace {
template<class T>
struct SvToPtr {
CString m_sType;
SvToPtr(const CString& sType) {
m_sType = sType;
}
T* operator()(SV* sv) {
T* result;
int res = SWIG_ConvertPtr(sv, (void**)&result, SWIG_TypeQuery(m_sType.c_str()), 0);
if (SWIG_IsOK(res)) {
return result;
}
return NULL;
}
};
CModule::EModRet SvToEModRet(SV* sv) {
return static_cast<CModule::EModRet>(SvUV(sv));
}
}
/*
#define PSTART dSP; I32 ax; int ret = 0; ENTER; SAVETMPS; PUSHMARK(SP)
#define PCALL(name) PUTBACK; ret = call_pv(name, G_EVAL|G_ARRAY); SPAGAIN; SP -= ret; ax = (SP - PL_stack_base) + 1
#define PEND PUTBACK; FREETMPS; LEAVE
#define PUSH_STR(s) XPUSHs(PString(s).GetSV())
#define PUSH_PTR(type, p) XPUSHs(SWIG_NewInstanceObj(const_cast<type>(p), SWIG_TypeQuery(#type), SWIG_SHADOW))
*/
#define PSTART_IDF(Func) PSTART; PUSH_STR(GetPerlID()); PUSH_STR(#Func)
#define PCALLMOD(Error, Success) PCALL("ZNC::Core::CallModFunc"); if (SvTRUE(ERRSV)) { DEBUG("Perl hook died with: " + PString(ERRSV)); Error; } else { Success; } PEND
bool CPerlModule::OnBoot() {
bool result = true;
PSTART_IDF(OnBoot);
mXPUSHi(static_cast<int>(true)); // Default value
PCALLMOD(,
result = SvUV(ST(0));
);
return result;
}
bool CPerlModule::WebRequiresLogin() {
bool result = true;
PSTART_IDF(WebRequiresLogin);
mXPUSHi(static_cast<int>(true)); // Default value
PCALLMOD(,
result = SvUV(ST(0));
);
return result;
}
bool CPerlModule::WebRequiresAdmin() {
bool result = false;
PSTART_IDF(WebRequiresAdmin);
mXPUSHi(static_cast<int>(false)); // Default value
PCALLMOD(,
result = SvUV(ST(0));
);
return result;
}
CString CPerlModule::GetWebMenuTitle() {
CString result = "";
PSTART_IDF(GetWebMenuTitle);
PUSH_STR(""); // Default value
PCALLMOD(,
result = PString(ST(0));
);
return result;
}
bool CPerlModule::OnWebPreRequest(CWebSock& WebSock, const CString& sPageName) {
bool result = false;
PSTART_IDF(OnWebPreRequest);
mXPUSHi(static_cast<int>(false)); // Default value
PUSH_PTR(CWebSock*, &WebSock);
PUSH_STR(sPageName);
PCALLMOD(,
result = SvUV(ST(0));
);
return result;
}
bool CPerlModule::OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl) {
bool result = false;
PSTART_IDF(OnWebRequest);
mXPUSHi(static_cast<int>(false)); // Default value
PUSH_PTR(CWebSock*, &WebSock);
PUSH_STR(sPageName);
PUSH_PTR(CTemplate*, &Tmpl);
PCALLMOD(,
result = SvUV(ST(0));
);
return result;
}
VWebSubPages* CPerlModule::_GetSubPages() {
VWebSubPages* result = (VWebSubPages*)NULL;
PSTART_IDF(_GetSubPages);
PUSH_PTR(VWebSubPages*, (VWebSubPages*)NULL); // Default value
PCALLMOD(,
result = SvToPtr<VWebSubPages>("VWebSubPages*")(ST(0));
);
return result;
}
void CPerlModule::OnPreRehash() {
PSTART_IDF(OnPreRehash);
mXPUSHi(0); // Default value
PCALLMOD(,
);
}
void CPerlModule::OnPostRehash() {
PSTART_IDF(OnPostRehash);
mXPUSHi(0); // Default value
PCALLMOD(,
);
}
void CPerlModule::OnIRCDisconnected() {
PSTART_IDF(OnIRCDisconnected);
mXPUSHi(0); // Default value
PCALLMOD(,
);
}
void CPerlModule::OnIRCConnected() {
PSTART_IDF(OnIRCConnected);
mXPUSHi(0); // Default value
PCALLMOD(,
);
}
CModule::EModRet CPerlModule::OnIRCConnecting(CIRCSock *pIRCSock) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnIRCConnecting);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CIRCSock *, pIRCSock);
PCALLMOD(,
result = SvToEModRet(ST(0));
);
return result;
}
CModule::EModRet CPerlModule::OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnIRCRegistration);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sPass);
PUSH_STR(sNick);
PUSH_STR(sIdent);
PUSH_STR(sRealName);
PCALLMOD(,
result = SvToEModRet(ST(0));
sPass = PString(ST(1));
sNick = PString(ST(2));
sIdent = PString(ST(3));
sRealName = PString(ST(4));
);
return result;
}
CModule::EModRet CPerlModule::OnBroadcast(CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnBroadcast);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(1));
);
return result;
}
CModule::EModRet CPerlModule::OnConfigLine(const CString& sName, const CString& sValue, CUser* pUser, CChan* pChan) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnConfigLine);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sName);
PUSH_STR(sValue);
PUSH_PTR(CUser*, pUser);
PUSH_PTR(CChan*, pChan);
PCALLMOD(,
result = SvToEModRet(ST(0));
);
return result;
}
void CPerlModule::OnWriteUserConfig(CFile& Config) {
PSTART_IDF(OnWriteUserConfig);
mXPUSHi(0); // Default value
PUSH_PTR(CFile*, &Config);
PCALLMOD(,
);
}
void CPerlModule::OnWriteChanConfig(CFile& Config, CChan& Chan) {
PSTART_IDF(OnWriteChanConfig);
mXPUSHi(0); // Default value
PUSH_PTR(CFile*, &Config);
PUSH_PTR(CChan*, &Chan);
PCALLMOD(,
);
}
CModule::EModRet CPerlModule::OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnDCCUserSend);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR( CNick*, &RemoteNick);
PUSH_STR(sFile);
PCALLMOD(,
result = SvToEModRet(ST(0));
);
return result;
}
void CPerlModule::OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange) {
PSTART_IDF(OnChanPermission);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
void CPerlModule::OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) {
PSTART_IDF(OnOp);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
void CPerlModule::OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) {
PSTART_IDF(OnDeop);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
void CPerlModule::OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) {
PSTART_IDF(OnVoice);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
void CPerlModule::OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange) {
PSTART_IDF(OnDevoice);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
void CPerlModule::OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange) {
PSTART_IDF(OnMode);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sArg);
PCALLMOD(,
);
}
void CPerlModule::OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs) {
PSTART_IDF(OnRawMode);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sModes);
PUSH_STR(sArgs);
PCALLMOD(,
);
}
CModule::EModRet CPerlModule::OnRaw(CString& sLine) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnRaw);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sLine);
PCALLMOD(,
result = SvToEModRet(ST(0));
sLine = PString(ST(1));
);
return result;
}
CModule::EModRet CPerlModule::OnStatusCommand(CString& sCommand) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnStatusCommand);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sCommand);
PCALLMOD(,
result = SvToEModRet(ST(0));
sCommand = PString(ST(1));
);
return result;
}
void CPerlModule::OnModCommand(const CString& sCommand) {
PSTART_IDF(OnModCommand);
mXPUSHi(0); // Default value
PUSH_STR(sCommand);
PCALLMOD(,
);
}
void CPerlModule::OnModNotice(const CString& sMessage) {
PSTART_IDF(OnModNotice);
mXPUSHi(0); // Default value
PUSH_STR(sMessage);
PCALLMOD(,
);
}
void CPerlModule::OnModCTCP(const CString& sMessage) {
PSTART_IDF(OnModCTCP);
mXPUSHi(0); // Default value
PUSH_STR(sMessage);
PCALLMOD(,
);
}
void CPerlModule::OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans) {
PSTART_IDF(OnQuit);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &Nick);
PUSH_STR(sMessage);
for (vector<CChan*>::const_iterator i = vChans.begin(); i != vChans.end(); ++i) {
PUSH_PTR(CChan*, *i);
}
PCALLMOD(,
);
}
void CPerlModule::OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans) {
PSTART_IDF(OnNick);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &Nick);
PUSH_STR(sNewNick);
for (vector<CChan*>::const_iterator i = vChans.begin(); i != vChans.end(); ++i) {
PUSH_PTR(CChan*, *i);
}
PCALLMOD(,
);
}
void CPerlModule::OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage) {
PSTART_IDF(OnKick);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &OpNick);
PUSH_STR(sKickedNick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sMessage);
PCALLMOD(,
);
}
void CPerlModule::OnJoin(const CNick& Nick, CChan& Channel) {
PSTART_IDF(OnJoin);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
void CPerlModule::OnPart(const CNick& Nick, CChan& Channel) {
PSTART_IDF(OnPart);
mXPUSHi(0); // Default value
PUSH_PTR( CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
);
}
CModule::EModRet CPerlModule::OnChanBufferStarting(CChan& Chan, CClient& Client) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanBufferStarting);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CChan*, &Chan);
PUSH_PTR(CClient*, &Client);
PCALLMOD(,
result = SvToEModRet(ST(0));
);
return result;
}
CModule::EModRet CPerlModule::OnChanBufferEnding(CChan& Chan, CClient& Client) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanBufferEnding);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CChan*, &Chan);
PUSH_PTR(CClient*, &Client);
PCALLMOD(,
result = SvToEModRet(ST(0));
);
return result;
}
CModule::EModRet CPerlModule::OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanBufferPlayLine);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CChan*, &Chan);
PUSH_PTR(CClient*, &Client);
PUSH_STR(sLine);
PCALLMOD(,
result = SvToEModRet(ST(0));
sLine = PString(ST(3));
);
return result;
}
CModule::EModRet CPerlModule::OnPrivBufferPlayLine(CClient& Client, CString& sLine) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnPrivBufferPlayLine);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CClient*, &Client);
PUSH_STR(sLine);
PCALLMOD(,
result = SvToEModRet(ST(0));
sLine = PString(ST(2));
);
return result;
}
void CPerlModule::OnClientLogin() {
PSTART_IDF(OnClientLogin);
mXPUSHi(0); // Default value
PCALLMOD(,
);
}
void CPerlModule::OnClientDisconnect() {
PSTART_IDF(OnClientDisconnect);
mXPUSHi(0); // Default value
PCALLMOD(,
);
}
CModule::EModRet CPerlModule::OnUserRaw(CString& sLine) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserRaw);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sLine);
PCALLMOD(,
result = SvToEModRet(ST(0));
sLine = PString(ST(1));
);
return result;
}
CModule::EModRet CPerlModule::OnUserCTCPReply(CString& sTarget, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserCTCPReply);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sTarget);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sTarget = PString(ST(1));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserCTCP(CString& sTarget, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserCTCP);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sTarget);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sTarget = PString(ST(1));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserAction(CString& sTarget, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserAction);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sTarget);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sTarget = PString(ST(1));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserMsg(CString& sTarget, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserMsg);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sTarget);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sTarget = PString(ST(1));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserNotice(CString& sTarget, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserNotice);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sTarget);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sTarget = PString(ST(1));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserJoin(CString& sChannel, CString& sKey) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserJoin);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sChannel);
PUSH_STR(sKey);
PCALLMOD(,
result = SvToEModRet(ST(0));
sChannel = PString(ST(1));
sKey = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserPart(CString& sChannel, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserPart);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sChannel);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sChannel = PString(ST(1));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserTopic(CString& sChannel, CString& sTopic) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserTopic);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sChannel);
PUSH_STR(sTopic);
PCALLMOD(,
result = SvToEModRet(ST(0));
sChannel = PString(ST(1));
sTopic = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnUserTopicRequest(CString& sChannel) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnUserTopicRequest);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_STR(sChannel);
PCALLMOD(,
result = SvToEModRet(ST(0));
sChannel = PString(ST(1));
);
return result;
}
CModule::EModRet CPerlModule::OnCTCPReply(CNick& Nick, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnCTCPReply);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnPrivCTCP(CNick& Nick, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnPrivCTCP);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanCTCP);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(3));
);
return result;
}
CModule::EModRet CPerlModule::OnPrivAction(CNick& Nick, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnPrivAction);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanAction);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(3));
);
return result;
}
CModule::EModRet CPerlModule::OnPrivMsg(CNick& Nick, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnPrivMsg);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanMsg);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(3));
);
return result;
}
CModule::EModRet CPerlModule::OnPrivNotice(CNick& Nick, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnPrivNotice);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(2));
);
return result;
}
CModule::EModRet CPerlModule::OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnChanNotice);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sMessage);
PCALLMOD(,
result = SvToEModRet(ST(0));
sMessage = PString(ST(3));
);
return result;
}
CModule::EModRet CPerlModule::OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnTopic);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CNick*, &Nick);
PUSH_PTR(CChan*, &Channel);
PUSH_STR(sTopic);
PCALLMOD(,
result = SvToEModRet(ST(0));
sTopic = PString(ST(3));
);
return result;
}
bool CPerlModule::OnServerCapAvailable(const CString& sCap) {
bool result = false;
PSTART_IDF(OnServerCapAvailable);
mXPUSHi(static_cast<int>(false)); // Default value
PUSH_STR(sCap);
PCALLMOD(,
result = SvUV(ST(0));
);
return result;
}
void CPerlModule::OnServerCapResult(const CString& sCap, bool bSuccess) {
PSTART_IDF(OnServerCapResult);
mXPUSHi(0); // Default value
PUSH_STR(sCap);
PCALLMOD(,
);
}
CModule::EModRet CPerlModule::OnTimerAutoJoin(CChan& Channel) {
CModule::EModRet result = CONTINUE;
PSTART_IDF(OnTimerAutoJoin);
mXPUSHi(static_cast<int>(CONTINUE)); // Default value
PUSH_PTR(CChan*, &Channel);
PCALLMOD(,
result = SvToEModRet(ST(0));
);
return result;
}
+65
View File
@@ -0,0 +1,65 @@
bool OnBoot()=true
bool WebRequiresLogin()=true
bool WebRequiresAdmin()=false
CString GetWebMenuTitle()
bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName)=false
bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl)=false
VWebSubPages* _GetSubPages()
void OnPreRehash()
void OnPostRehash()
void OnIRCDisconnected()
void OnIRCConnected()
EModRet OnIRCConnecting(CIRCSock *pIRCSock)
EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName)
EModRet OnBroadcast(CString& sMessage)
EModRet OnConfigLine(const CString& sName, const CString& sValue, CUser* pUser, CChan* pChan)
void OnWriteUserConfig(CFile& Config)
void OnWriteChanConfig(CFile& Config, CChan& Chan)
EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize)
void OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange)
void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
void OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
void OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange)
void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs)
EModRet OnRaw(CString& sLine)
EModRet OnStatusCommand(CString& sCommand)
void OnModCommand(const CString& sCommand)
void OnModNotice(const CString& sMessage)
void OnModCTCP(const CString& sMessage)
void OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans)
void OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans)
void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage)
void OnJoin(const CNick& Nick, CChan& Channel)
void OnPart(const CNick& Nick, CChan& Channel)
EModRet OnChanBufferStarting(CChan& Chan, CClient& Client)
EModRet OnChanBufferEnding(CChan& Chan, CClient& Client)
EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine)
EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine)
void OnClientLogin()
void OnClientDisconnect()
EModRet OnUserRaw(CString& sLine)
EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage)
EModRet OnUserCTCP(CString& sTarget, CString& sMessage)
EModRet OnUserAction(CString& sTarget, CString& sMessage)
EModRet OnUserMsg(CString& sTarget, CString& sMessage)
EModRet OnUserNotice(CString& sTarget, CString& sMessage)
EModRet OnUserJoin(CString& sChannel, CString& sKey)
EModRet OnUserPart(CString& sChannel, CString& sMessage)
EModRet OnUserTopic(CString& sChannel, CString& sTopic)
EModRet OnUserTopicRequest(CString& sChannel)
EModRet OnCTCPReply(CNick& Nick, CString& sMessage)
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage)
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage)
EModRet OnPrivAction(CNick& Nick, CString& sMessage)
EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage)
EModRet OnPrivMsg(CNick& Nick, CString& sMessage)
EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage)
EModRet OnPrivNotice(CNick& Nick, CString& sMessage)
EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage)
EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic)
bool OnServerCapAvailable(const CString& sCap)=false
void OnServerCapResult(const CString& sCap, bool bSuccess)
EModRet OnTimerAutoJoin(CChan& Channel)
+197
View File
@@ -0,0 +1,197 @@
/*
* Copyright (C) 2004-2010 See the AUTHORS file for details.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
%module ZNC %{
#ifdef Copy
# undef Copy
#endif
#include <utility>
#include "../Utils.h"
#include "../Socket.h"
#include "../Modules.h"
#include "../Nick.h"
#include "../Chan.h"
#include "../User.h"
#include "../Client.h"
#include "../IRCSock.h"
#include "../Listener.h"
#include "../HTTPSock.h"
#include "../Template.h"
#include "../WebModules.h"
#include "../znc.h"
#include "../Server.h"
#include "../ZNCString.h"
#include "../DCCBounce.h"
#include "../DCCSock.h"
#include "../FileUtils.h"
#include "modperl/module.h"
#define stat struct stat
%}
%include <typemaps.i>
%include <stl.i>
%include <std_list.i>
namespace std {
template<class K> class set {
public:
set();
set(const set<K>&);
};
}
%include "modperl/CString.i"
%template(_stringlist) std::list<CString>;
%typemap(out) std::list<CString> {
std::list<CString>::const_iterator i;
unsigned int j;
int len = $1.size();
SV **svs = new SV*[len];
for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
svs[j] = sv_newmortal();
SwigSvFromString(svs[j], *i);
}
AV *myav = av_make(len, svs);
delete[] svs;
$result = newRV_noinc((SV*) myav);
sv_2mortal($result);
argvi++;
}
#define u_short unsigned short
#define u_int unsigned int
#include "../ZNCString.h"
%include "../defines.h"
%include "../Utils.h"
%include "../Csocket.h"
%template(ZNCSocketManager) TSocketManager<CZNCSock>;
%include "../Socket.h"
%include "../DCCBounce.h"
%include "../DCCSock.h"
%include "../FileUtils.h"
%include "../Modules.h"
%include "../Nick.h"
%include "../Chan.h"
%include "../User.h"
%include "../Client.h"
%include "../IRCSock.h"
%include "../Listener.h"
%include "../HTTPSock.h"
%include "../Template.h"
%include "../WebModules.h"
%include "../znc.h"
%include "../Server.h"
%include "modperl/module.h"
%inline %{
class String : public CString {
public:
String() {}
String(const CString& s) : CString(s) {}
String(double d, int prec=2): CString(d, prec) {}
String(float f, int prec=2) : CString(f, prec) {}
String(int i) : CString(i) {}
String(unsigned int i) : CString(i) {}
String(long int i) : CString(i) {}
String(unsigned long int i) : CString(i) {}
String(char c) : CString(c) {}
String(unsigned char c) : CString(c) {}
String(short int i) : CString(i) {}
String(unsigned short int i): CString(i) {}
String(bool b) : CString(b) {}
CString GetPerlStr() {
return *this;
}
};
%}
%extend CModule {
std::list<CString> _GetNVKeys() {
std::list<CString> res;
for (MCString::iterator i = $self->BeginNV(); i != $self->EndNV(); ++i) {
res.push_back(i->first);
}
return res;
}
bool ExistsNV(const CString& sName) {
return $self->EndNV() != $self->FindNV(sName);
}
}
%perlcode %{
package ZNC::CModule;
sub GetNVKeys {
my $result = _GetNVKeys(@_);
return @$result;
}
%}
%extend CModules {
void push_back(CModule* p) {
$self->push_back(p);
}
bool removeModule(CModule* p) {
for (CModules::iterator i = $self->begin(); $self->end() != i; ++i) {
if (*i == p) {
$self->erase(i);
return true;
}
}
return false;
}
}
/* Web */
%template(StrPair) pair<CString, CString>;
%template(VPair) vector<pair<CString, CString> >;
typedef vector<pair<CString, CString> > VPair;
%template(VWebSubPages) vector<TWebSubPage>;
%inline %{
void _VPair_Add2Str(VPair* self, const CString& a, const CString& b) {
self->push_back(std::make_pair(a, b));
}
%}
%extend CTemplate {
void set(const CString& key, const CString& value) {
(*$self)[key] = value;
}
}
%inline %{
TWebSubPage _CreateWebSubPage(const CString& sName, const CString& sTitle, const VPair& vParams, unsigned int uFlags) {
return new CWebSubPage(sName, sTitle, vParams, uFlags);
}
%}
%perlcode %{
package ZNC;
sub CreateWebSubPage {
my ($name, %arg) = @_;
my $params = $arg{params}//{};
my $vpair = ZNC::VPair->new;
while (my ($key, $val) = each %$params) {
ZNC::_VPair_Add2Str($vpair, $key, $val);
}
my $flags = 0;
$flags |= $ZNC::CWebSubPage::F_ADMIN if $arg{admin}//0;
return _CreateWebSubPage($name, $arg{title}//'', $vpair, $flags);
}
%}
%perlcode %{
package ZNC;
*CONTINUE = *ZNC::CModule::CONTINUE;
*HALT = *ZNC::CModule::HALT;
*HALTMODS = *ZNC::CModule::HALTMODS;
*HALTCORE = *ZNC::CModule::HALTCORE;
*UNLOAD = *ZNC::CModule::UNLOAD;
%}
+157
View File
@@ -0,0 +1,157 @@
/*
* Copyright (C) 2004-2010 See the AUTHORS file for details.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#pragma once
#include "Modules.h"
class CPerlModule : public CModule {
CString m_sPerlID;
VWebSubPages* _GetSubPages();
public:
CPerlModule(CUser* pUser, const CString& sModName, const CString& sDataPath,
const CString& sPerlID)
: CModule(NULL, pUser, sModName, sDataPath) {
m_sPerlID = sPerlID;
}
CString GetPerlID() { return m_sPerlID; }
virtual bool OnBoot();
virtual bool WebRequiresLogin();
virtual bool WebRequiresAdmin();
virtual CString GetWebMenuTitle();
virtual bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName);
virtual bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl);
virtual VWebSubPages& GetSubPages();
virtual void OnPreRehash();
virtual void OnPostRehash();
virtual void OnIRCDisconnected();
virtual void OnIRCConnected();
virtual EModRet OnIRCConnecting(CIRCSock *pIRCSock);
virtual EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName);
virtual EModRet OnBroadcast(CString& sMessage);
virtual EModRet OnConfigLine(const CString& sName, const CString& sValue, CUser* pUser, CChan* pChan);
virtual void OnWriteUserConfig(CFile& Config);
virtual void OnWriteChanConfig(CFile& Config, CChan& Chan);
virtual EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize);
virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange);
virtual void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
virtual void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
virtual void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
virtual void OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
virtual void OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange);
virtual void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs);
virtual EModRet OnRaw(CString& sLine);
virtual EModRet OnStatusCommand(CString& sCommand);
virtual void OnModCommand(const CString& sCommand);
virtual void OnModNotice(const CString& sMessage);
virtual void OnModCTCP(const CString& sMessage);
virtual void OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans);
virtual void OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans);
virtual void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage);
virtual void OnJoin(const CNick& Nick, CChan& Channel);
virtual void OnPart(const CNick& Nick, CChan& Channel);
virtual EModRet OnChanBufferStarting(CChan& Chan, CClient& Client);
virtual EModRet OnChanBufferEnding(CChan& Chan, CClient& Client);
virtual EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine);
virtual EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine);
virtual void OnClientLogin();
virtual void OnClientDisconnect();
virtual EModRet OnUserRaw(CString& sLine);
virtual EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage);
virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage);
virtual EModRet OnUserAction(CString& sTarget, CString& sMessage);
virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage);
virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage);
virtual EModRet OnUserJoin(CString& sChannel, CString& sKey);
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage);
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic);
virtual EModRet OnUserTopicRequest(CString& sChannel);
virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage);
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage);
virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage);
virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage);
virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage);
virtual EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage);
virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic);
virtual bool OnServerCapAvailable(const CString& sCap);
virtual void OnServerCapResult(const CString& sCap, bool bSuccess);
virtual EModRet OnTimerAutoJoin(CChan& Channel);
};
static inline CPerlModule* AsPerlModule(CModule* p) {
return dynamic_cast<CPerlModule*>(p);
}
enum ELoadPerlMod {
Perl_NotFound,
Perl_Loaded,
Perl_LoadError,
};
class CPerlTimer : public CTimer {
CString m_sPerlID;
public:
CPerlTimer(CPerlModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription, const CString& sPerlID)
: CTimer (pModule, uInterval, uCycles, sLabel, sDescription), m_sPerlID(sPerlID) {
pModule->AddTimer(this);
}
virtual void RunJob();
CString GetPerlID() { return m_sPerlID; }
};
inline CPerlTimer* CreatePerlTimer(CPerlModule* pModule, unsigned int uInterval, unsigned int uCycles,
const CString& sLabel, const CString& sDescription, const CString& sPerlID) {
return new CPerlTimer(pModule, uInterval, uCycles, sLabel, sDescription, sPerlID);
}
class CPerlSocket : public CSocket {
CString m_sPerlID;
public:
CPerlSocket(CPerlModule* pModule, const CString& sPerlID) : CSocket(pModule), m_sPerlID(sPerlID) {}
CString GetPerlID() { return m_sPerlID; }
virtual void Connected();
virtual void Disconnected();
virtual void Timeout();
virtual void ConnectionRefused();
virtual void ReadData(const char *data, size_t len);
virtual void ReadLine(const CString& sLine);
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
};
inline CPerlSocket* CreatePerlSocket(CPerlModule* pModule, const CString& sPerlID) {
return new CPerlSocket(pModule, sPerlID);
}
inline bool HaveIPv6() {
#ifdef HAVE_IPV6
return true;
#endif
return false;
}
inline bool HaveSSL() {
#ifdef HAVE_LIBSSL
return true;
#endif
return false;
}
inline bool HaveCAres() {
#ifdef HAVE_C_ARES
return true;
#endif
return false;
}
inline int _GetSOMAXCONN() {
return SOMAXCONN;
}
+78
View File
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2004-2010 See the AUTHORS file for details.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#pragma once
class PString : public CString {
public:
enum EType {
STRING,
INT,
UINT,
NUM,
BOOL
};
PString() : CString() { m_eType = STRING; }
PString(const char* c) : CString(c) { m_eType = STRING; }
PString(const CString& s) : CString(s) { m_eType = STRING; }
PString(int i) : CString(i) { m_eType = INT; }
PString(u_int i) : CString(i) { m_eType = UINT; }
PString(long i) : CString(i) { m_eType = INT; }
PString(u_long i) : CString(i) { m_eType = UINT; }
PString(long long i) : CString(i) { m_eType = INT; }
PString(unsigned long long i) : CString(i) { m_eType = UINT; }
PString(double i) : CString(i) { m_eType = NUM; }
PString(bool b) : CString((b ? "1" : "0")) { m_eType = BOOL; }
PString(SV* sv) {
STRLEN len = SvCUR(sv);
char* c = SvPV(sv, len);
char* c2 = new char[len+1];
memcpy(c2, c, len);
c2[len] = 0;
*this = c2;
delete[] c2;
}
virtual ~PString() {}
EType GetType() const { return m_eType; }
void SetType(EType e) { m_eType = e; }
SV* GetSV(bool bMakeMortal = true) const
{
SV* pSV = NULL;
switch (GetType()) {
case NUM:
pSV = newSVnv(ToDouble());
break;
case INT:
pSV = newSViv(ToLongLong());
break;
case UINT:
case BOOL:
pSV = newSVuv(ToULongLong());
break;
case STRING:
default:
pSV = newSVpv(data(), length());
break;
}
if (bMakeMortal) {
pSV = sv_2mortal(pSV);
}
return pSV;
}
private:
EType m_eType;
};
+458
View File
@@ -0,0 +1,458 @@
#
# Copyright (C) 2004-2010 See the AUTHORS file for details.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
#
use strict;
use warnings;
use ZNC;
use Data::UUID;
use IO::File;
use feature 'switch';
package ZNC::Core;
my $uuidgen;
our %pmods;
sub Init {
$uuidgen = new Data::UUID;
}
sub CreateUUID {
$uuidgen->create_str;
}
sub unloadByIDUser {
my ($id, $user) = @_;
$pmods{$id}->OnShutdown;
$user->GetModules->removeModule($pmods{$id}{_cmod});
delete $pmods{$id}{_cmod};# Just for the case
delete $pmods{$id}{_nv};
delete $pmods{$id}{_ptimers};
delete $pmods{$id}{_sockets};
delete $pmods{$id};
}
sub UnloadModule {
my ($cmod) = @_;
unloadByIDUser($cmod->GetPerlID, $cmod->GetUser);
}
sub UnloadAll {
while (my ($id, $pmod) = each %pmods) {
unloadByIDUser($id, $pmod->{_cmod}->GetUser);
}
}
sub IsModule {
my $path = shift;
my $modname = shift;
my $f = IO::File->new($path);
grep {/package\s+$modname\s*;/} <$f>;
}
sub LoadModule {
my ($modname, $args, $user) = @_;
$modname =~ /^\w+$/ or return ($ZNC::Perl_LoadError, "Module names can only contain letters, numbers and underscores, [$modname] is invalid.");
return ($ZNC::Perl_LoadError, "Module [$modname] already loaded.") if defined $user->GetModules->FindModule($modname);
my $modpath = ZNC::String->new;
my $datapath = ZNC::String->new;
ZNC::CModules::FindModPath("$modname.pm", $modpath, $datapath) or return ($ZNC::Perl_NotFound, "Unable to find module [$modname]");
$modpath = $modpath->GetPerlStr;
return ($ZNC::Perl_LoadError, "Incorrect perl module.") unless IsModule $modpath, $modname;
require $modpath;
my $id = CreateUUID;
$datapath = $datapath->GetPerlStr;
$datapath =~ s/\.pm$//;
my $cmod = ZNC::CPerlModule->new($user, $modname, $datapath, $id);
my %nv;
tie %nv, 'ZNC::ModuleNV', $cmod;
my $pmod = bless {
_cmod=>$cmod,
_nv=>\%nv
}, $modname;
$cmod->SetDescription($pmod->description);
$cmod->SetArgs($args);
$cmod->SetModPath($modpath);
$pmods{$id} = $pmod;
$user->GetModules->push_back($cmod);
my $x = '';
my $loaded = 0;
eval {
$loaded = $pmod->OnLoad($args, $x);
};
if ($@) {
$x .= ' ' if '' ne $x;
$x .= $@;
}
if (!$loaded) {
unloadByIDUser($id, $user);
if ($x) {
return ($ZNC::Perl_LoadError, "Module [$modname] aborted: $x");
}
return ($ZNC::Perl_LoadError, "Module [$modname] aborted.");
}
if ($x) {
return ($ZNC::Perl_Loaded, "Loaded module [$modname] [$x] [$modpath]");
}
return ($ZNC::Perl_Loaded, "Loaded module [$modname] [$modpath]")
}
sub GetModInfo {
my ($modname) = @_;
$modname =~ /^\w+$/ or return ($ZNC::Perl_LoadError, "Module names can only contain letters, numbers and underscores, [$modname] is invalid.");
my $modpath = ZNC::String->new;
my $datapath = ZNC::String->new;
ZNC::CModules::FindModPath("$modname.pm", $modpath, $datapath) or return ($ZNC::Perl_NotFound, "Unable to find module [$modname]");
$modpath = $modpath->GetPerlStr;
return ($ZNC::Perl_LoadError, "Incorrect perl module.") unless IsModule $modpath, $modname;
require $modpath;
my $pmod = bless {}, $modname;
return ($ZNC::Perl_Loaded, $modpath->GetPerlStr, $pmod->description)
}
sub ModInfoByPath {
my ($modpath, $modname) = @_;
die "Incorrect perl module." unless IsModule $modpath, $modname;
require $modpath;
my $pmod = bless {}, $modname;
return ($pmod->description)
}
sub CallModFunc {
my $id = shift;
my $func = shift;
my $default = shift;
my @arg = @_;
my $res = $pmods{$id}->$func(@arg);
# print "Returned from $func(@_): $res, (@arg)\n";
unless (defined $res) {
$res = $default if defined $default;
}
($res, @arg)
}
sub CallTimer {
my $modid = shift;
my $timerid = shift;
$pmods{$modid}->_CallTimer($timerid)
}
sub CallSocket {
my $modid = shift;
$pmods{$modid}->_CallSocket(@_)
}
package ZNC::ModuleNV;
sub TIEHASH {
my $name = shift;
my $cmod = shift;
bless {cmod=>$cmod, last=>-1}, $name
}
sub FETCH {
my $self = shift;
my $key = shift;
return $self->{cmod}->GetNV($key) if $self->{cmod}->ExistsNV($key);
return undef
}
sub STORE {
my $self = shift;
my $key = shift;
my $value = shift;
$self->{cmod}->SetNV($key, $value);
}
sub DELETE {
my $self = shift;
my $key = shift;
$self->{cmod}->DelNV($key);
}
sub CLEAR {
my $self = shift;
$self->{cmod}->ClearNV;
}
sub EXISTS {
my $self = shift;
my $key = shift;
$self->{cmod}->ExistsNV($key)
}
sub FIRSTKEY {
my $self = shift;
my @keys = $self->{cmod}->GetNVKeys;
$self->{last} = 0;
return $keys[0];
return undef;
}
sub NEXTKEY {
my $self = shift;
my $last = shift;
my @keys = $self->{cmod}->GetNVKeys;
if ($#keys < $self->{last}) {
$self->{last} = -1;
return undef
}
# Probably caller called delete on last key?
if ($last eq $keys[$self->{last}]) {
$self->{last}++
}
if ($#keys < $self->{last}) {
$self->{last} = -1;
return undef
}
return $keys[$self->{last}]
}
sub SCALAR {
my $self = shift;
my @keys = $self->{cmod}->GetNVKeys;
return $#keys + 1
}
package ZNC::Module;
sub description {
"< Placeholder for a description >"
}
# Default implementations for module hooks. They can be overriden in derived modules.
sub OnLoad {1}
sub OnBoot {}
sub OnShutdown {}
sub WebRequiresLogin {}
sub WebRequiresAdmin {}
sub GetWebMenuTitle {}
sub OnWebPreRequest {}
sub OnWebRequest {}
sub GetSubPages {}
sub _GetSubPages { my $self = shift; $self->GetSubPages }
sub OnPreRehash {}
sub OnPostRehash {}
sub OnIRCDisconnected {}
sub OnIRCConnected {}
sub OnIRCConnecting {}
sub OnIRCRegistration {}
sub OnBroadcast {}
sub OnConfigLine {}
sub OnWriteUserConfig {}
sub OnWriteChanConfig {}
sub OnDCCUserSend {}
sub OnChanPermission {}
sub OnOp {}
sub OnDeop {}
sub OnVoice {}
sub OnDevoice {}
sub OnMode {}
sub OnRawMode {}
sub OnRaw {}
sub OnStatusCommand {}
sub OnModCommand {}
sub OnModNotice {}
sub OnModCTCP {}
sub OnQuit {}
sub OnNick {}
sub OnKick {}
sub OnJoin {}
sub OnPart {}
sub OnChanBufferStarting {}
sub OnChanBufferEnding {}
sub OnChanBufferPlayLine {}
sub OnPrivBufferPlayLine {}
sub OnClientLogin {}
sub OnClientDisconnect {}
sub OnUserRaw {}
sub OnUserCTCPReply {}
sub OnUserCTCP {}
sub OnUserAction {}
sub OnUserMsg {}
sub OnUserNotice {}
sub OnUserJoin {}
sub OnUserPart {}
sub OnUserTopic {}
sub OnUserTopicRequest {}
sub OnCTCPReply {}
sub OnPrivCTCP {}
sub OnChanCTCP {}
sub OnPrivAction {}
sub OnChanAction {}
sub OnPrivMsg {}
sub OnChanMsg {}
sub OnPrivNotice {}
sub OnChanNotice {}
sub OnTopic {}
sub OnServerCapAvailable {}
sub OnServerCapResult {}
sub OnTimerAutoJoin {}
# Functions of CModule will be usable from perl modules.
our $AUTOLOAD;
sub AUTOLOAD {
my $name = $AUTOLOAD;
$name =~ s/^.*:://; # Strip fully-qualified portion.
my $sub = sub {
my $self = shift;
$self->{_cmod}->$name(@_)
};
no strict 'refs';
*{$AUTOLOAD} = $sub;
use strict 'refs';
goto &{$sub};
}
sub DESTROY {}
sub BeginNV {
die "Don't use BeginNV from perl modules, use GetNVKeys or NV instead!";
}
sub EndNV {
die "Don't use EndNV from perl modules, use GetNVKeys or NV instead!";
}
sub FindNV {
die "Don't use FindNV from perl modules, use GetNVKeys/ExistsNV or NV instead!";
}
sub NV {
my $self = shift;
$self->{_nv}
}
sub CreateTimer {
my ($self, $job, $interval, $cycles, $description) = @_;
my $id = ZNC::Core::CreateUUID;
my $ctimer = ZNC::CreatePerlTimer($self->{_cmod}, $interval, $cycles, "perl-timer-$id", $description, $id);
$self->{_ptimers}{$id}{job} = $job;
$self->{_ptimers}{$id}{cobj} = $ctimer;
}
sub _CallTimer {
my $self = shift;
my $id = shift;
&{$self->{_ptimers}{$id}{job}}($self, $self->{_ptimers}{$id}{obj});
}
sub CreateSocket {
my $self = shift;
my $class = shift;
my $id = ZNC::Core::CreateUUID;
my $csock = ZNC::CreatePerlSocket($self->{_cmod}, $id);
my $psock = bless {
_csock=>$csock,
_modid=>$self->GetPerlID
}, $class;
$self->{_sockets}{$id} = $psock;
$psock->Init(@_);
$psock;
}
sub _CallSocket {
my $self = shift;
my $id = shift;
my $func = shift;
$self->{_sockets}{$id}->$func(@_)
}
package ZNC::Socket;
sub GetModule {
my $self = shift;
$ZNC::Core::pmods{$self->{_modid}};
}
sub Init {}
sub OnConnected {}
sub OnDisconnected {}
sub OnTimeout {}
sub OnConnectionRefused {}
sub OnReadData {}
sub OnReadLine {}
sub OnAccepted {}
sub _Accepted {
my $self = shift;
my $psock = $self->OnAccepted(@_);
return $psock->{_csock} if defined $psock;
return undef;
}
our $AUTOLOAD;
sub AUTOLOAD {
my $name = $AUTOLOAD;
$name =~ s/^.*:://; # Strip fully-qualified portion.
my $sub = sub {
my $self = shift;
$self->{_csock}->$name(@_)
};
no strict 'refs';
*{$AUTOLOAD} = $sub;
use strict 'refs';
goto &{$sub};
}
sub DESTROY {}
sub Connect {
my $self = shift;
my $host = shift;
my $port = shift;
my %arg = @_;
$self->GetModule->GetManager->Connect(
$host,
$port,
"perl-socket-".$self->GetPerlID,
$arg{timeout}//60,
$arg{ssl}//0,
$arg{bindhost}//'',
$self->{_csock}
);
}
sub Listen {
my $self = shift;
my %arg = @_;
my $addrtype = $ZNC::ADDR_ALL;
if (defined $arg{addrtype}) {
given ($arg{addrtype}) {
when (/^ipv4$/i) { $addrtype = $ZNC::ADDR_IPV4ONLY }
when (/^ipv6$/i) { $addrtype = $ZNC::ADDR_IPV6ONLY }
when (/^all$/i) { }
default { die "Specified addrtype [$arg{addrtype}] isn't supported" }
}
}
if (defined $arg{port}) {
return $arg{port} if $self->GetModule->GetManager->ListenHost(
$arg{port},
"perl-socket-".$self->GetPerlID,
$arg{bindhost}//'',
$arg{ssl}//0,
$arg{maxconns}//ZNC::_GetSOMAXCONN,
$self->{_csock},
$arg{timeout}//0,
$addrtype
);
return 0;
}
$self->GetModule->GetManager->ListenRand(
"perl-socket-".$self->GetPerlID,
$arg{bindhost}//'',
$arg{ssl}//0,
$arg{maxconns}//ZNC::_GetSOMAXCONN,
$self->{_csock},
$arg{timeout}//0,
$addrtype
);
}
1