Add modpython module which allows to write ZNC modules on python3.

Notice for distro maintainers: perl interpreter is required to compile modpython.

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@2196 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
darthgandalf
2010-12-22 14:52:53 +00:00
parent c7c0d1714c
commit a564e25c13
11 changed files with 2440 additions and 96 deletions

View File

@@ -0,0 +1,418 @@
#!/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.
#
# Parts of SWIG are used here.
use strict;
use warnings;
use IO::File;
use feature 'switch', 'say';
open my $in, $ARGV[0] or die;
open my $out, ">", $ARGV[1] 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.
*
* Parts of SWIG are used here.
*/
/***************************************************************************
* This file is generated automatically using codegen.pl from functions.in *
* Don't change it manually. *
***************************************************************************/
namespace {
/* template<class T>
struct pyobj_to_ptr {
CString m_sType;
SvToPtr(const CString& sType) {
m_sType = sType;
}
bool operator()(PyObject* py, T** result) {
T* x = NULL;
int res = SWIG_ConvertPtr(sv, (void**)&x, SWIG_TypeQuery(m_sType.c_str()), 0);
if (SWIG_IsOK(res)) {
*result = x;
return true;
}
DEBUG("modpython: ");
return false;
}
};
CModule::EModRet SvToEModRet(PyObject* py, CModule::EModRet* result) {
long int x = PyLong_AsLong();
return static_cast<CModule::EModRet>(SvUV(sv));
}*/
inline swig_type_info* SWIG_pchar_descriptor(void) {
static int init = 0;
static swig_type_info* info = 0;
if (!init) {
info = SWIG_TypeQuery("_p_char");
init = 1;
}
return info;
}
inline int SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) {
#if PY_VERSION_HEX>=0x03000000
if (PyUnicode_Check(obj))
#else
if (PyString_Check(obj))
#endif
{
char *cstr; Py_ssize_t len;
#if PY_VERSION_HEX>=0x03000000
if (!alloc && cptr) {
/* We can't allow converting without allocation, since the internal
representation of string in Python 3 is UCS-2/UCS-4 but we require
a UTF-8 representation.
TODO(bhy) More detailed explanation */
return SWIG_RuntimeError;
}
obj = PyUnicode_AsUTF8String(obj);
PyBytes_AsStringAndSize(obj, &cstr, &len);
if(alloc) *alloc = SWIG_NEWOBJ;
#else
PyString_AsStringAndSize(obj, &cstr, &len);
#endif
if (cptr) {
if (alloc) {
/*
In python the user should not be able to modify the inner
string representation. To warranty that, if you define
SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
buffer is always returned.
The default behavior is just to return the pointer value,
so, be careful.
*/
#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
if (*alloc != SWIG_OLDOBJ)
#else
if (*alloc == SWIG_NEWOBJ)
#endif
{
*cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
*alloc = SWIG_NEWOBJ;
}
else {
*cptr = cstr;
*alloc = SWIG_OLDOBJ;
}
} else {
#if PY_VERSION_HEX>=0x03000000
assert(0); /* Should never reach here in Python 3 */
#endif
*cptr = SWIG_Python_str_AsChar(obj);
}
}
if (psize) *psize = len + 1;
#if PY_VERSION_HEX>=0x03000000
Py_XDECREF(obj);
#endif
return SWIG_OK;
} else {
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
if (pchar_descriptor) {
void* vptr = 0;
if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
if (cptr) *cptr = (char *) vptr;
if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
if (alloc) *alloc = SWIG_OLDOBJ;
return SWIG_OK;
}
}
}
return SWIG_TypeError;
}
inline int SWIG_AsPtr_std_string (PyObject * 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;
}
}
EOF
=b
bool OnFoo(const CString& x) {
PyObject* pyName = Py_BuildValue("s", "OnFoo");
if (!pyName) {
CString s = GetPyExceptionStr();
DEBUG("modpython: username/module/OnFoo: can't name method to call: " << s);
return default;
}
PyObject* pyArg1 = Py_BuildValue("s", x.c_str());
if (!pyArg1) {
CString s = GetPyExceptionStr();
DEBUG("modpython: username/module/OnFoo: can't convert parameter x to PyObject*: " << s);
Py_CLEAR(pyName);
return default;
}
PyObject* pyArg2 = ...;
if (!pyArg2) {
CString s = ...;
DEBUG(...);
Py_CLEAR(pyName);
Py_CLEAR(pyArg1);
return default;
}
PyObject* pyArg3 = ...;
if (!pyArg3) {
CString s = ...;
DEBUG(...);
Py_CLEAR(pyName);
Py_CLEAR(pyArg1);
Py_CLEAR(pyArg2);
return default;
}
PyObject* pyRes = PyObject_CallMethodObjArgs(m_pyObj, pyName, pyArg1, pyArg2, pyArg3, NULL);
if (!pyRes) {
CString s = ...;
DEBUG("modpython: username/module/OnFoo failed: " << s);
Py_CLEAR(pyName);
Py_CLEAR(pyArg1);
Py_CLEAR(pyArg2);
Py_CLEAR(pyArg3);
return default;
}
Py_CLEAR(pyName);
Py_CLEAR(pyArg1);
Py_CLEAR(pyArg2);
Py_CLEAR(pyArg3);
bool res = PyLong_AsLong(pyRes);
if (PyErr_Occured()) {
CString s = GetPyExceptionStr();
DEBUG("modpython: username/module/OnFoo returned unexpected value: " << s);
Py_CLEAR(pyRes);
return default;
}
Py_CLEAR(pyRes);
return res;
}
=cut
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 ($tb, $tm) = $t =~ /^(.*?)\s*?(\*|&)?$/;
{type=>$t, var=>$v, base=>$tb, mod=>$tm//'', pyvar=>"pyArg_$v", error=>"can't convert parameter '$v' to PyObject"}
} split /,/, $args;
unshift @arg, {type=>'$func$', var=>"", base=>"", mod=>"", pyvar=>"pyName", error=>"can't convert string '$name' to PyObject"};
my $cleanup = '';
$default = '' if $type eq 'void';
say $out "$type CPyModule::$name($args) {";
for my $a (@arg) {
print $out "\tPyObject* $a->{pyvar} = ";
given ($a->{type}) {
when ('$func$') {
say $out "Py_BuildValue(\"s\", \"$name\");";
}
when (/vector\s*<\s*.*\*\s*>/) {
say $out "PyList_New(0);";
}
when (/CString/) {
if ($a->{base} eq 'CString' && $a->{mod} eq '&') {
say $out "CPyRetString::wrap($a->{var});";
} else {
say $out "Py_BuildValue(\"s\", $a->{var}.c_str());";
}
}
when (/\*$/) {
(my $t = $a->{type}) =~ s/^const//;
say $out "SWIG_NewInstanceObj(const_cast<$t>($a->{var}), SWIG_TypeQuery(\"$t\"), 0);";
}
when (/&$/) {
(my $b = $a->{base}) =~ s/^const//;
say $out "SWIG_NewInstanceObj(const_cast<$b*>(&$a->{var}), SWIG_TypeQuery(\"$b*\"), 0);";
}
when ('bool') {
say $out "Py_BuildValue(\"l\", (long int)$a->{var});";
}
default {
my %letter = (
'int' => 'i',
'char' => 'b',
'short int' => 'h',
'long int' => 'l',
'unsigned char' => 'B',
'unsigned short' => 'H',
'unsigned int' => 'I',
'unsigned long' => 'k',
'long long' => 'L',
'unsigned long long' => 'K',
'ssize_t' => 'n',
'double' => 'd',
'float' => 'f',
);
if (exists $letter{$a->{type}}) {
say $out "Py_BuildValue(\"$letter{$a->{type}}\", $a->{var});"
} else {
say $out "...;";
}
}
}
say $out "\tif (!$a->{pyvar}) {";
say $out "\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
say $out "\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name: $a->{error}: \" << sPyErr);";
print $out $cleanup;
say $out "\t\treturn $default;";
say $out "\t}";
$cleanup .= "\t\tPy_CLEAR($a->{pyvar});\n";
if ($a->{type} =~ /(vector\s*<\s*(.*)\*\s*>)/) {
my ($vec, $sub) = ($1, $2);
(my $cleanup1 = $cleanup) =~ s/\t\t/\t\t\t/g;
my $dot = '.';
$dot = '->' if $a->{mod} eq '*';
say $out "\tfor (${vec}::const_iterator i = $a->{var}${dot}begin(); i != $a->{var}${dot}end(); ++i) {";
say $out "\t\tPyObject* pyVecEl = SWIG_NewInstanceObj(*i, SWIG_TypeQuery(\"$sub*\"), 0);";
say $out "\t\tif (!pyVecEl) {";
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '.
"\"/$name: can't convert element of vector '$a->{var}' to PyObject: \" << sPyErr);";
print $out $cleanup1;
say $out "\t\t\treturn $default;";
say $out "\t\t}";
say $out "\t\tif (PyList_Append($a->{pyvar}, pyVecEl)) {";
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '.
"\"/$name: can't add element of vector '$a->{var}' to PyObject: \" << sPyErr);";
say $out "\t\t\tPy_CLEAR(pyVecEl);";
print $out $cleanup1;
say $out "\t\t\treturn $default;";
say $out "\t\t}";
say $out "\t\tPy_CLEAR(pyVecEl);";
say $out "\t}";
}
}
print $out "\tPyObject* pyRes = PyObject_CallMethodObjArgs(m_pyObj";
print $out ", $_->{pyvar}" for @arg;
say $out ", NULL);";
say $out "\tif (!pyRes) {";
say $out "\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
say $out "\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name failed: \" << sPyErr);";
print $out $cleanup;
say $out "\t\treturn $default;";
say $out "\t}";
$cleanup =~ s/\t\t/\t/g;
print $out $cleanup;
if ($type ne 'void') {
say $out "\t$type result;";
say $out "\tif (pyRes == Py_None) {";
say $out "\t\tresult = $default;";
say $out "\t} else {";
given ($type) {
when (/^(.*)\*$/) {
say $out "\t\tint res = SWIG_ConvertPtr(pyRes, (void**)&result, SWIG_TypeQuery(\"$type\"), 0);";
say $out "\t\tif (!SWIG_IsOK(res)) {";
say $out "\t\t\tDEBUG(\"modpython: \" << GetUser()->GetUserName() << \"/\" << GetModName() << \"/$name was expected to return '$type' but error=\" << res);";
say $out "\t\t\tresult = $default;";
say $out "\t\t}";
}
when ('CString') {
say $out "\t\tCString* p = NULL;";
say $out "\t\tint res = SWIG_AsPtr_std_string(pyRes, &p);";
say $out "\t\tif (!SWIG_IsOK(res)) {";
say $out "\t\t\tDEBUG(\"modpython: \" << GetUser()->GetUserName() << \"/\" << GetModName() << \"/$name was expected to return '$type' but error=\" << res);";
say $out "\t\t\tresult = $default;";
say $out "\t\t} else if (!p) {";
say $out "\t\t\tDEBUG(\"modpython: \" << GetUser()->GetUserName() << \"/\" << GetModName() << \"/$name was expected to return '$type' but returned NULL\");";
say $out "\t\t\tresult = $default;";
say $out "\t\t} else result = *p;";
say $out "\t\tif (SWIG_IsNewObj(res)) free((char*)p); // Don't ask me, that's how SWIG works...";
}
when ('CModule::EModRet') {
say $out "\t\tlong int x = PyLong_AsLong(pyRes);";
say $out "\t\tif (PyErr_Occurred()) {";
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name was expected to return EModRet but: \" << sPyErr);";
say $out "\t\t\tresult = $default;";
say $out "\t\t} else { result = (CModule::EModRet)x; }";
}
when ('bool') {
say $out "\t\tint x = PyObject_IsTrue(pyRes);";
say $out "\t\tif (-1 == x) {";
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name was expected to return EModRet but: \" << sPyErr);";
say $out "\t\t\tresult = $default;";
say $out "\t\t} else result = x ? true : false;";
}
default {
say $out "\t\tI don't know how to convert PyObject to $type :(";
}
}
say $out "\t}";
say $out "\tPy_CLEAR(pyRes);";
say $out "\treturn result;";
} else {
say $out "\tPy_CLEAR(pyRes);";
}
say $out "}\n";
}
sub getres {
my $type = shift;
given ($type) {
when (/^(.*)\*$/) { return "pyobj_to_ptr<$1>(\"$type\")" }
when ('CString') { return 'PString' }
when ('CModule::EModRet') { return 'SvToEModRet' }
when (/unsigned/) { return 'SvUV' }
default { return 'SvIV' }
}
}

View File

@@ -0,0 +1,16 @@
/*
* 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.
*/
#include <Python.h>
int main() {
Py_Initialize();
int res = PyRun_SimpleString("import compileall; print('Optimizing python files for later use...'); compileall.compile_dir('.')");
Py_Finalize();
return res;
}

332
modules/modpython/cstring.i Normal file
View File

@@ -0,0 +1,332 @@
/*
SWIG-generated sources are used here.
*/
//
// String
//
%{
#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 (PyObject * 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 (PyObject * obj, CString *val)
{
CString* v = (CString *) 0;
int res = SWIG_AsPtr_std_string (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 PyObject *
SWIG_From_std_string (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,204,%typemaps_asptrfromn@*/
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,193,%typemaps_asptrfrom@*/
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,163,%typemaps_asptr@*/
%fragment("SWIG_" "AsVal" "_" {CString},"header",fragment="SWIG_" "AsPtr" "_" {CString}) {
SWIGINTERNINLINE int
SWIG_AsVal_std_string (PyObject * obj, CString *val)
{
CString *v = (CString *)0;
int res = SWIG_AsPtr_std_string (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,31,%ptr_in_typemap@*/
%typemap(in,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
CString *ptr = (CString *)0;
int res = SWIG_AsPtr_std_string($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($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,56,%ptr_varin_typemap@*/
%typemap(varin,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
CString *ptr = (CString *)0;
int res = SWIG_AsPtr_std_string($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,71,%ptr_directorout_typemap@*/
%typemap(directorargout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString *DIRECTOROUT ($*ltype temp) {
CString *swig_optr = 0;
int swig_ores = $input ? SWIG_AsPtr_std_string($input, &swig_optr) : 0;
if (!SWIG_IsOK(swig_ores) || !swig_optr) {
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError((swig_optr ? swig_ores : SWIG_TypeError))), "in output value of type '""$type""'");
}
temp = *swig_optr;
$result = &temp;
if (SWIG_IsNewObj(swig_ores)) free((char*)swig_optr);
}
%typemap(directorout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
CString *swig_optr = 0;
int swig_ores = SWIG_AsPtr_std_string($input, &swig_optr);
if (!SWIG_IsOK(swig_ores) || !swig_optr) {
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError((swig_optr ? swig_ores : SWIG_TypeError))), "in output value of type '""$type""'");
}
$result = *swig_optr;
if (SWIG_IsNewObj(swig_ores)) free((char*)swig_optr);
}
%typemap(directorout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString},warning= "473:Returning a pointer or reference in a director method is not recommended." ) CString* {
CString *swig_optr = 0;
int swig_ores = SWIG_AsPtr_std_string($input, &swig_optr);
if (!SWIG_IsOK(swig_ores)) {
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_ores)), "in output value of type '""$type""'");
}
$result = swig_optr;
if (SWIG_IsNewObj(swig_ores)) {
swig_acquire_ownership(swig_optr);
}
}
%typemap(directorfree,noblock=1) CString*
{
if (director) {
director->swig_release_ownership(SWIG_as_voidptr($input));
}
}
%typemap(directorout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString},warning= "473:Returning a pointer or reference in a director method is not recommended." ) CString& {
CString *swig_optr = 0;
int swig_ores = SWIG_AsPtr_std_string($input, &swig_optr);
if (!SWIG_IsOK(swig_ores)) {
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_ores)), "in output value of type '""$type""'");
} else {
if (!swig_optr) {
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ValueError), "invalid null reference " "in output value of type '""$type""'");
}
}
$result = swig_optr;
if (SWIG_IsNewObj(swig_ores)) {
swig_acquire_ownership(swig_optr);
}
}
%typemap(directorfree,noblock=1) CString&
{
if (director) {
director->swig_release_ownership(SWIG_as_voidptr($input));
}
}
%typemap(directorout,fragment="SWIG_" "AsPtr" "_" {CString}) CString &DIRECTOROUT = CString
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,146,%ptr_typecheck_typemap@*/
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString * {
int res = SWIG_AsPtr_std_string($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($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($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($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($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((CString)($1));
}
%typemap(out,noblock=1,fragment="SWIG_" "From" "_" {CString}) const CString& {
$result = SWIG_From_std_string((CString)(*$1));
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,79,%value_varout_typemap@*/
%typemap(varout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString& {
$result = SWIG_From_std_string((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_Python_SetConstant(d, "$symname",SWIG_From_std_string((CString)($value)));
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,98,%value_directorin_typemap@*/
%typemap(directorin,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString *DIRECTORIN {
$input = SWIG_From_std_string((CString)(*$1_name));
}
%typemap(directorin,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString& {
$input = SWIG_From_std_string((CString)($1_name));
}
/*@SWIG@*/;
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,154,%value_throws_typemap@*/
%typemap(throws,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString {
SWIG_Python_Raise(SWIG_From_std_string((CString)($1)), "$type", 0); 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)) {
$result = SWIG_Python_AppendOutput($result, SWIG_From_std_string((*$1)));
} else {
int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | 0 ) : 0 ;
$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags));
}
}
/*@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)) {
$result = SWIG_Python_AppendOutput($result, SWIG_From_std_string((*$1)));
} else {
int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | 0 ) : 0 ;
$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags));
}
}
/*@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@*/;

View File

@@ -0,0 +1,66 @@
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)
bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl)=false

View File

@@ -0,0 +1,176 @@
/*
* 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_core %{
#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 "modpython/module.h"
class CPyRetString {
public:
CString& s;
CPyRetString(CString& S) : s(S) {}
static PyObject* wrap(CString& S) {
CPyRetString* x = new CPyRetString(S);
return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetString*"), SWIG_POINTER_OWN);
}
};
#define stat struct stat
using std::allocator;
%}
%include <pyabc.i>
%include <typemaps.i>
%include <stl.i>
%include <std_list.i>
namespace std {
template<class K> class set {
public:
set();
set(const set<K>&);
};
}
%include "modpython/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++;
}*/
%typemap(out) CModules::ModDirList %{
$result = PyList_New($1.size());
if ($result) {
for (size_t i = 0; !$1.empty(); $1.pop(), ++i) {
PyList_SetItem($result, i, Py_BuildValue("ss", $1.front().first.c_str(), $1.front().second.c_str()));
}
}
%}
%typemap(in) CString& {
String* p;
int res = SWIG_IsOK(SWIG_ConvertPtr($input, (void**)&p, SWIG_TypeQuery("String*"), 0));
if (SWIG_IsOK(res)) {
$1 = &p->s;
} else {
SWIG_exception_fail(SWIG_ArgError(res), "need znc.String object as argument $argnum $1_name");
}
}
#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 "modpython/module.h"
/* Really it's CString& inside, but SWIG shouldn't know that :) */
class CPyRetString {
CPyRetString();
public:
CString s;
};
%extend CModule {
MCString_iter BeginNV_() {
return MCString_iter($self->BeginNV());
}
bool ExistsNV(const CString& sName) {
return $self->EndNV() != $self->FindNV(sName);
}
}
%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);
}
%}

221
modules/modpython/module.h Normal file
View File

@@ -0,0 +1,221 @@
#pragma once
class String {
public:
CString s;
};
class CModPython;
class CPyModule : public CModule {
PyObject* m_pyObj;
CModPython* m_pModPython;
VWebSubPages* _GetSubPages();
public:
CPyModule(CUser* pUser, const CString& sModName, const CString& sDataPath,
PyObject* pyObj, CGlobalModule* pModPython)
: CModule(NULL, pUser, sModName, sDataPath) {
m_pyObj = pyObj;
Py_INCREF(pyObj);
m_pModPython = reinterpret_cast<CModPython*>(pModPython);
}
PyObject* GetPyObj() { // borrows
return m_pyObj;
}
PyObject* GetNewPyObj() {
Py_INCREF(m_pyObj);
return m_pyObj;
}
void DeletePyModule() {
Py_CLEAR(m_pyObj);
delete this;
}
CString GetPyExceptionStr();
CModPython* GetModPython() {
return m_pModPython;
}
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);
bool OnEmbeddedWebRequest(CWebSock&, const CString&, CTemplate&);
};
static inline CPyModule* AsPyModule(CModule* p) {
return dynamic_cast<CPyModule*>(p);
}
inline CPyModule* CreatePyModule(CUser* pUser, const CString& sModName, const CString& sDataPath, PyObject* pyObj, CGlobalModule* pModPython) {
return new CPyModule(pUser, sModName, sDataPath, pyObj, pModPython);
}
class CPyTimer : public CTimer {
PyObject* m_pyObj;
CModPython* m_pModPython;
public:
CPyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription, PyObject* pyObj)
: CTimer (pModule, uInterval, uCycles, sLabel, sDescription), m_pyObj(pyObj) {
Py_INCREF(pyObj);
pModule->AddTimer(this);
m_pModPython = pModule->GetModPython();
}
virtual void RunJob();
PyObject* GetPyObj() { return m_pyObj; }
PyObject* GetNewPyObj() {
Py_INCREF(m_pyObj);
return m_pyObj;
}
~CPyTimer();
};
inline CPyTimer* CreatePyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles,
const CString& sLabel, const CString& sDescription, PyObject* pyObj) {
return new CPyTimer(pModule, uInterval, uCycles, sLabel, sDescription, pyObj);
}
class CPySocket : public CSocket {
PyObject* m_pyObj;
CModPython* m_pModPython;
public:
CPySocket(CPyModule* pModule, PyObject* pyObj) : CSocket(pModule), m_pyObj(pyObj) {
Py_INCREF(pyObj);
m_pModPython = pModule->GetModPython();
}
PyObject* GetPyObj() { return m_pyObj; }
PyObject* GetNewPyObj() {
Py_INCREF(m_pyObj);
return m_pyObj;
}
~CPySocket();
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);
PyObject* WriteBytes(PyObject* data);
};
inline CPySocket* CreatePySocket(CPyModule* pModule, PyObject* pyObj) {
return new CPySocket(pModule, pyObj);
}
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;
}
inline int GetVersionMajor() {
return VERSION_MAJOR;
}
inline int GetVersionMinor() {
return VERSION_MINOR;
}
inline double GetVersion() {
return VERSION;
}
inline CString GetVersionExtra() {
return VERSION_EXTRA;
}
class MCString_iter {
public:
MCString_iter() {}
MCString::iterator x;
MCString_iter(MCString::iterator z) : x(z) {}
void plusplus() {
++x;
}
CString get() {
return x->first;
}
bool is_end(CModule* m) {
return m->EndNV() == x;
}
};

377
modules/modpython/znc.py Normal file
View File

@@ -0,0 +1,377 @@
from znc_core import *
import imp
import re
import traceback
import collections
class Socket:
def _Accepted(self, host, port):
psock = self.OnAccepted(host, port)
print(psock)
try:
return psock._csock
except AttributeError:
return None
def GetModule(self):
return AsPyModule(self._csock.GetModule()).GetNewPyObj()
def Listen(self, addrtype='all', port=None, bindhost='', ssl=False, maxconns=GetSOMAXCONN(), timeout=0):
addr = ADDR_ALL
addrtype = addrtype.lower()
if addrtype == 'ipv4':
addr = ADDR_IPV4ONLY
elif addrtype == 'ipv6':
addr = ADDR_IPV6ONLY
elif addrtype != 'all':
raise ValueError("Specified addrtype [{0}] isn't supported".format(addrtype))
if port is None:
return self.GetModule().GetManager().ListenRand(
"python socket for {0}".format(self.GetModule().GetModName()),
bindhost,
ssl,
maxconns,
self._csock,
timeout,
addr
)
if self.GetModule().GetManager().ListenHost(
port,
'python socket for {0}'.format(self.GetModule().GetModName()),
bindhost,
ssl,
maxconns,
self._csock,
timeout,
addr):
return port
return 0
def Connect(self, host, port, timeout=60, ssl=False, bindhost=''):
return self.GetModule().GetManager().Connect(
host,
port,
'python conn socket for {0}'.format(self.GetModule().GetModName()),
timeout,
ssl,
bindhost,
self._csock)
def Write(self, data):
if (isinstance(data, str)):
return self._csock.Write(data)
raise TypeError('socket.Write needs str. If you want binary data, use WriteBytes')
def Init(self, *a, **b): pass
def OnConnected(self): pass
def OnDisconnected(self): pass
def OnTimeout(self): pass
def OnConnectionRefused(self): pass
def OnReadData(self, bytess): pass
def OnReadLine(self, line): pass
def OnAccepted(self, host, port): pass
def OnShutdown(self): pass
class Timer:
def GetModule(self):
return AsPyModule(self._ctimer.GetModule()).GetNewPyObj()
def RunJob(self): pass
def OnShutdown(self): pass
class ModuleNVIter(collections.Iterator):
def __init__(self, cmod):
self._cmod = cmod
self.it = cmod.BeginNV_()
def __next__(self):
if self.it.is_end(self._cmod):
raise StopIteration
res = self.it.get()
self.it.plusplus()
return res
class ModuleNV(collections.MutableMapping):
def __init__(self, cmod):
self._cmod = cmod
def __setitem__(self, key, value):
self._cmod.SetNV(key, value)
def __getitem__(self, key):
if not self._cmod.ExistsNV(key):
raise KeyError
return self._cmod.GetNV(key)
def __contains__(self, key):
return self._cmod.ExistsNV(key)
def __delitem__(self, key):
self._cmod.DelNV(key)
def keys(self):
return ModuleNVIter(self._cmod)
__iter__ = keys
def __len__(self):
raise NotImplemented
class Module:
def OnLoad(self, sArgs, sMessage):
return True
def _GetSubPages(self):
return self.GetSubPages()
def CreateSocket(self, socketclass, *the, **rest):
socket = socketclass()
socket._csock = CreatePySocket(self._cmod, socket)
socket.Init(*the, **rest)
return socket
def CreateTimer(self, timer, interval=10, cycles=1, label='pytimer', description='Some python timer'):
t = timer()
t._ctimer = CreatePyTimer(self._cmod, interval, cycles, label, description, t)
return t
def GetNV(self):
return self._nv
def GetSubPages(self): pass
def OnShutdown(self): pass
def OnBoot(self): pass
def WebRequiresLogin(self): pass
def WebRequiresAdmin(self): pass
def GetWebMenuTitle(self): pass
def OnWebPreRequest(self, WebSock, sPageName): pass
def OnWebRequest(self, WebSock, sPageName, Tmpl): pass
def OnPreRehash(self): pass
def OnPostRehash(self): pass
def OnIRCDisconnected(self): pass
def OnIRCConnected(self): pass
def OnIRCConnecting(self, IRCSock): pass
def OnIRCRegistration(self, sPass, sNick, sIdent, sRealName): pass
def OnBroadcast(self, sMessage): pass
def OnConfigLine(self, sName, sValue, pUser, pChan): pass
def OnWriteUserConfig(self, Config): pass
def OnWriteChanConfig(self, Config, Chan): pass
def OnDCCUserSend(self, RemoteNick, uLongIP, uPort, sFile, uFileSize): pass
def OnChanPermission(self, OpNick, Nick, Channel, uMode, bAdded, bNoChange): pass
def OnOp(self, OpNick, Nick, Channel, bNoChange): pass
def OnDeop(self, OpNick, Nick, Channel, bNoChange): pass
def OnVoice(self, OpNick, Nick, Channel, bNoChange): pass
def OnDevoice(self, OpNick, Nick, Channel, bNoChange): pass
def OnMode(self, OpNick, Channel, uMode, sArg, bAdded, bNoChange): pass
def OnRawMode(self, OpNick, Channel, sModes, sArgs): pass
def OnRaw(self, sLine): pass
def OnStatusCommand(self, sCommand): pass
def OnModCommand(self, sCommand): pass
def OnModNotice(self, sMessage): pass
def OnModCTCP(self, sMessage): pass
def OnQuit(self, Nick, sMessage, vChans): pass
def OnNick(self, Nick, sNewNick, vChans): pass
def OnKick(self, OpNick, sKickedNick, Channel, sMessage): pass
def OnJoin(self, Nick, Channel): pass
def OnPart(self, Nick, Channel): pass
def OnChanBufferStarting(self, Chan, Client): pass
def OnChanBufferEnding(self, Chan, Client): pass
def OnChanBufferPlayLine(self, Chan, Client, sLine): pass
def OnPrivBufferPlayLine(self, Client, sLine): pass
def OnClientLogin(self): pass
def OnClientDisconnect(self): pass
def OnUserRaw(self, sLine): pass
def OnUserCTCPReply(self, sTarget, sMessage): pass
def OnUserCTCP(self, sTarget, sMessage): pass
def OnUserAction(self, sTarget, sMessage): pass
def OnUserMsg(self, sTarget, sMessage): pass
def OnUserNotice(self, sTarget, sMessage): pass
def OnUserJoin(self, sChannel, sKey): pass
def OnUserPart(self, sChannel, sMessage): pass
def OnUserTopic(self, sChannel, sTopic): pass
def OnUserTopicRequest(self, sChannel): pass
def OnCTCPReply(self, Nick, sMessage): pass
def OnPrivCTCP(self, Nick, sMessage): pass
def OnChanCTCP(self, Nick, Channel, sMessage): pass
def OnPrivAction(self, Nick, sMessage): pass
def OnChanAction(self, Nick, Channel, sMessage): pass
def OnPrivMsg(self, Nick, sMessage): pass
def OnChanMsg(self, Nick, Channel, sMessage): pass
def OnPrivNotice(self, Nick, sMessage): pass
def OnChanNotice(self, Nick, Channel, sMessage): pass
def OnTopic(self, Nick, Channel, sTopic): pass
def OnServerCapAvailable(self, sCap): pass
def OnServerCapResult(self, sCap, bSuccess): pass
def OnTimerAutoJoin(self, Channel): pass
def OnEmbeddedWebRequest(self, WebSock, sPageName, Tmpl): pass
def make_inherit(cl, parent, attr):
def make_caller(parent, name, attr):
return lambda self, *a: parent.__dict__[name](self.__dict__[attr], *a)
while True:
for x in parent.__dict__:
if x[:1] != '_' and x not in cl.__dict__:
setattr(cl, x, make_caller(parent, x, attr))
if '_s' in parent.__dict__:
parent = parent._s
else:
break
make_inherit(Socket, CPySocket, '_csock')
make_inherit(Module, CPyModule, '_cmod')
make_inherit(Timer, CPyTimer, '_ctimer')
def find_open(modname):
'''Returns (pymodule, datapath)'''
for d in CModules.GetModDirs():
# d == (libdir, datadir)
try:
x = imp.find_module(modname, [d[0]])
except ImportError:
# no such file in dir d
continue
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>, './modules/admin.so', ('.so', 'rb', 3))
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
if x[0] is None:
# the same
continue
if x[2][0] == '.so':
try:
pymodule = imp.load_module(modname, *x)
except ImportError:
# found needed .so but can't load it...
# maybe it's normal (non-python) znc module?
# another option here could be to "continue"
# search of python module in other moddirs.
# but... we respect C++ modules ;)
return (None, None)
finally:
x[0].close()
else:
# this is not .so, so it can be only python module .py or .pyc
try:
pymodule = imp.load_module(modname, *x)
finally:
x[0].close()
return (pymodule, d[1])
else:
# nothing found
return (None, None)
def load_module(modname, args, user, retmsg, modpython):
'''Returns 0 if not found, 1 on loading error, 2 on success'''
if re.search(r'[^a-zA-Z0-9_]', modname) is not None:
retmsg.s = 'Module names can only contain letters, numbers and underscores, [{0}] is invalid.'.format(modname)
return 1
pymodule, datapath = find_open(modname)
if pymodule is None:
return 0
if modname not in pymodule.__dict__:
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(pymodule.__file__, modname)
return 1
cl = pymodule.__dict__[modname]
module = cl()
module._cmod = CreatePyModule(user, modname, datapath, module, modpython)
module._nv = ModuleNV(module._cmod)
descr = None
if '__doc__' in cl.__dict__:
descr = cl.__doc__
if descr is None:
descr = '< Placeholder for a description >'
module.SetDescription(descr)
module.SetArgs(args)
module.SetModPath(pymodule.__file__)
user.GetModules().push_back(module._cmod)
try:
loaded = True
if not module.OnLoad(args, retmsg):
if retmsg.s == '':
retmsg.s = 'Module [{0}] aborted.'.format(modname)
else:
retmsg.s = 'Module [{0}] aborted: {1}'.format(modname, retmsg.s)
loaded = False
except BaseException:
if retmsg.s == '':
retmsg.s = 'Got exception: {0}'.format(traceback.format_exc())
else:
retmsg.s = '{0}; Got exception: {1}'.format(retmsg.s, traceback.format_exc())
loaded = False
except:
if retmsg.s == '':
retmsg.s = 'Got exception.'
else:
retmsg.s = '{0}; Got exception.'.format(retmsg.s)
loaded = False
if loaded:
if retmsg.s == '':
retmsg.s = "Loaded module [{0}] [{1}]".format(modname, pymodule.__file__)
else:
retmsg.s = "Loaded module [{0}] [{2}] [{1}]".format(modname, pymodule.__file__, retmsg.s)
return 2
print(retmsg.s)
unload_module(module)
return 1
def unload_module(module):
module.OnShutdown()
cmod = module._cmod
del module._cmod
cmod.GetUser().GetModules().removeModule(cmod)
cmod.DeletePyModule()
del cmod
def get_mod_info(modname, retmsg, modinfo):
'''0-not found, 1-error, 2-success'''
pymodule, = find_open(modname)
if pymodule is None:
return 0
if modname not in pymodule.__dict__:
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(pymodule.__file__, modname)
return 1
cl = pymodule.__dict__[modname]
descr = None
if '__doc__' in cl.__dict__:
descr = cl.__doc__
if descr is None:
descr = '< Placeholder for a description >'
modinfo.SetGlobal(False)
modinfo.SetDescription(descr)
modinfo.SetName(modname)
modinfo.SetPath(pymodule.__file__)
return 2
def get_mod_info_path(path, modname, modinfo):
try:
x = imp.find_module(modname, [path])
except ImportError:
return 0
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>, './modules/admin.so', ('.so', 'rb', 3))
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
if x[0] is None:
return 0
try:
pymodule = imp.load_module(modname, *x)
except ImportError:
return 0
finally:
x[0].close()
if modname not in pymodule.__dict__:
return 0
cl = pymodule.__dict__[modname]
descr = None
if '__doc__' in cl.__dict__:
descr = cl.__doc__
if descr is None:
descr = '< Placeholder for a description >'
modinfo.SetGlobal(False)
modinfo.SetDescription(descr)
modinfo.SetName(modname)
modinfo.SetPath(pymodule.__file__)
return 1
CONTINUE = CModule.CONTINUE
HALT = CModule.HALT
HALTMODS = CModule.HALTMODS
HALTCORE = CModule.HALTCORE
UNLOAD = CModule.UNLOAD
HaveSSL = HaveSSL_()
HaveCAres = HaveCAres_()
HaveIPv6 = HaveIPv6_()
Version = GetVersion()
VersionMajor = GetVersionMajor()
VersionMinor = GetVersionMinor()
VersionExtra = GetVersionExtra()
def CreateWebSubPage(name, title='', params=dict(), admin=False):
vpair = VPair()
for k, v in params.items():
VPair_Add2Str_(vpair, k, v)
flags = 0
if admin:
flags |= CWebSubPage.F_ADMIN
return CreateWebSubPage_(name, title, vpair, flags)