2008-05-24 18:18:21 +02:00
/*
Unix SMB / CIFS implementation .
Copyright © Jelmer Vernooij < jelmer @ samba . org > 2008
Based on the equivalent for EJS :
Copyright © Andrew Tridgell < tridge @ samba . org > 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2009-01-08 12:20:20 +01:00
# include <Python.h>
2009-10-23 16:23:01 +11:00
# include "includes.h"
2008-10-24 13:13:27 +02:00
# include "scripting/python/modules.h"
2008-05-25 16:26:34 +02:00
# include "libcli/util/pyerrors.h"
2008-05-26 03:07:18 +02:00
# include "librpc/rpc/pyrpc.h"
2010-03-18 19:36:50 +01:00
# include "librpc/ndr/libndr.h"
2008-05-24 18:18:21 +02:00
# include "lib/messaging/irpc.h"
2008-05-26 01:52:35 +02:00
# include "lib/messaging/messaging.h"
2008-05-25 16:26:34 +02:00
# include "lib/events/events.h"
# include "cluster/cluster.h"
# include "param/param.h"
2009-06-02 15:00:41 +02:00
# include "param/pyparam.h"
2008-05-24 18:18:21 +02:00
2008-05-25 16:26:34 +02:00
PyAPI_DATA ( PyTypeObject ) messaging_Type ;
2008-05-26 04:14:28 +02:00
PyAPI_DATA ( PyTypeObject ) irpc_ClientConnectionType ;
2008-05-26 01:10:24 +02:00
2008-12-22 04:21:20 +01:00
/* FIXME: This prototype should be in py_irpc.h, or shared otherwise */
extern const struct PyNdrRpcMethodDef py_ndr_irpc_methods [ ] ;
2008-05-26 01:10:24 +02:00
static bool server_id_from_py ( PyObject * object , struct server_id * server_id )
{
if ( ! PyTuple_Check ( object ) ) {
PyErr_SetString ( PyExc_ValueError , " Expected tuple " ) ;
return false ;
}
2008-05-26 01:52:35 +02:00
if ( PyTuple_Size ( object ) = = 3 ) {
return PyArg_ParseTuple ( object , " iii " , & server_id - > id , & server_id - > id2 , & server_id - > node ) ;
} else {
int id , id2 ;
if ( ! PyArg_ParseTuple ( object , " ii " , & id , & id2 ) )
return false ;
* server_id = cluster_id ( id , id2 ) ;
return true ;
}
2008-05-26 01:10:24 +02:00
}
2008-05-25 16:26:34 +02:00
typedef struct {
PyObject_HEAD
TALLOC_CTX * mem_ctx ;
struct messaging_context * msg_ctx ;
} messaging_Object ;
PyObject * py_messaging_connect ( PyTypeObject * self , PyObject * args , PyObject * kwargs )
{
2008-12-29 20:24:57 +01:00
struct tevent_context * ev ;
2008-05-26 01:10:24 +02:00
const char * kwnames [ ] = { " own_id " , " messaging_path " , NULL } ;
PyObject * own_id = Py_None ;
2008-05-25 16:26:34 +02:00
const char * messaging_path = NULL ;
messaging_Object * ret ;
2008-05-26 04:14:28 +02:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |Oz:connect " ,
2008-05-26 01:10:24 +02:00
discard_const_p ( char * , kwnames ) , & own_id , & messaging_path ) ) {
2008-05-25 16:26:34 +02:00
return NULL ;
}
ret = PyObject_New ( messaging_Object , & messaging_Type ) ;
if ( ret = = NULL )
return NULL ;
ret - > mem_ctx = talloc_new ( NULL ) ;
2008-06-14 13:00:53 -04:00
ev = s4_event_context_init ( ret - > mem_ctx ) ;
2008-05-25 16:26:34 +02:00
if ( messaging_path = = NULL ) {
2008-11-02 16:50:11 +01:00
messaging_path = lp_messaging_path ( ret - > mem_ctx ,
py_default_loadparm_context ( ret - > mem_ctx ) ) ;
2008-05-25 16:26:34 +02:00
} else {
messaging_path = talloc_strdup ( ret - > mem_ctx , messaging_path ) ;
}
2008-05-26 01:10:24 +02:00
if ( own_id ! = Py_None ) {
struct server_id server_id ;
if ( ! server_id_from_py ( own_id , & server_id ) )
return NULL ;
2008-05-25 16:26:34 +02:00
ret - > msg_ctx = messaging_init ( ret - > mem_ctx ,
messaging_path ,
2008-05-26 01:10:24 +02:00
server_id ,
2008-10-24 13:22:12 +02:00
py_iconv_convenience ( ret - > mem_ctx ) ,
2008-05-26 01:10:24 +02:00
ev ) ;
} else {
ret - > msg_ctx = messaging_client_init ( ret - > mem_ctx ,
messaging_path ,
2008-10-24 13:22:12 +02:00
py_iconv_convenience ( ret - > mem_ctx ) ,
2008-05-25 16:26:34 +02:00
ev ) ;
}
if ( ret - > msg_ctx = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError , " messaging_connect unable to create a messaging context " ) ;
talloc_free ( ret - > mem_ctx ) ;
return NULL ;
}
return ( PyObject * ) ret ;
}
static void py_messaging_dealloc ( PyObject * self )
{
messaging_Object * iface = ( messaging_Object * ) self ;
talloc_free ( iface - > msg_ctx ) ;
PyObject_Del ( self ) ;
}
static PyObject * py_messaging_send ( PyObject * self , PyObject * args , PyObject * kwargs )
{
messaging_Object * iface = ( messaging_Object * ) self ;
2008-05-26 01:10:24 +02:00
uint32_t msg_type ;
2008-05-25 16:26:34 +02:00
DATA_BLOB data ;
PyObject * target ;
NTSTATUS status ;
struct server_id server ;
const char * kwnames [ ] = { " target " , " msg_type " , " data " , NULL } ;
2008-05-30 16:11:07 +10:00
int length ;
2008-05-25 16:26:34 +02:00
2009-11-07 17:57:50 +01:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " Ois#:send " ,
2008-05-30 16:11:07 +10:00
discard_const_p ( char * , kwnames ) , & target , & msg_type , & data . data , & length ) ) {
2009-11-07 17:57:50 +01:00
2008-05-25 16:26:34 +02:00
return NULL ;
}
2008-05-30 16:11:07 +10:00
data . length = length ;
2008-05-25 16:26:34 +02:00
if ( ! server_id_from_py ( target , & server ) )
return NULL ;
status = messaging_send ( iface - > msg_ctx , server , msg_type , & data ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
return NULL ;
}
2009-01-06 04:13:57 +01:00
Py_RETURN_NONE ;
2008-05-25 16:26:34 +02:00
}
2009-02-02 08:20:52 +01:00
static void py_msg_callback_wrapper ( struct messaging_context * msg , void * private_data ,
2008-05-25 16:26:34 +02:00
uint32_t msg_type ,
struct server_id server_id , DATA_BLOB * data )
{
2009-02-02 08:20:52 +01:00
PyObject * callback = ( PyObject * ) private_data ;
2008-05-25 16:26:34 +02:00
PyObject_CallFunction ( callback , discard_const_p ( char , " i(iii)s# " ) , msg_type ,
server_id . id , server_id . id2 , server_id . node ,
data - > data , data - > length ) ;
}
static PyObject * py_messaging_register ( PyObject * self , PyObject * args , PyObject * kwargs )
{
messaging_Object * iface = ( messaging_Object * ) self ;
2008-05-30 16:19:22 +10:00
int msg_type = - 1 ;
2008-05-25 16:26:34 +02:00
PyObject * callback ;
NTSTATUS status ;
2008-05-26 01:10:24 +02:00
const char * kwnames [ ] = { " callback " , " msg_type " , NULL } ;
2008-05-30 16:19:22 +10:00
2009-11-07 17:57:50 +01:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O|i:register " ,
2008-05-26 01:10:24 +02:00
discard_const_p ( char * , kwnames ) , & callback , & msg_type ) ) {
2008-05-25 16:26:34 +02:00
return NULL ;
}
Py_INCREF ( callback ) ;
2008-05-26 01:10:24 +02:00
if ( msg_type = = - 1 ) {
2008-05-30 16:19:22 +10:00
uint32_t msg_type32 = msg_type ;
2008-05-26 01:10:24 +02:00
status = messaging_register_tmp ( iface - > msg_ctx , callback ,
2008-05-30 16:19:22 +10:00
py_msg_callback_wrapper , & msg_type32 ) ;
msg_type = msg_type32 ;
2008-05-26 01:10:24 +02:00
} else {
status = messaging_register ( iface - > msg_ctx , callback ,
msg_type , py_msg_callback_wrapper ) ;
}
2008-05-25 16:26:34 +02:00
if ( NT_STATUS_IS_ERR ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
return NULL ;
}
2008-05-26 01:10:24 +02:00
return PyLong_FromLong ( msg_type ) ;
2008-05-25 16:26:34 +02:00
}
2008-05-26 01:15:15 +02:00
static PyObject * py_messaging_deregister ( PyObject * self , PyObject * args , PyObject * kwargs )
{
messaging_Object * iface = ( messaging_Object * ) self ;
2008-05-30 16:19:22 +10:00
int msg_type = - 1 ;
2008-05-26 01:15:15 +02:00
PyObject * callback ;
const char * kwnames [ ] = { " callback " , " msg_type " , NULL } ;
2009-11-07 17:57:50 +01:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O|i:deregister " ,
2008-05-26 01:15:15 +02:00
discard_const_p ( char * , kwnames ) , & callback , & msg_type ) ) {
return NULL ;
}
messaging_deregister ( iface - > msg_ctx , msg_type , callback ) ;
Py_DECREF ( callback ) ;
2009-01-06 04:13:57 +01:00
Py_RETURN_NONE ;
2008-05-26 01:15:15 +02:00
}
2008-05-26 00:50:07 +02:00
static PyObject * py_messaging_add_name ( PyObject * self , PyObject * args , PyObject * kwargs )
{
messaging_Object * iface = ( messaging_Object * ) self ;
NTSTATUS status ;
char * name ;
const char * kwnames [ ] = { " name " , NULL } ;
2009-11-07 17:57:50 +01:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|:add_name " ,
2008-05-26 00:50:07 +02:00
discard_const_p ( char * , kwnames ) , & name ) ) {
return NULL ;
}
status = irpc_add_name ( iface - > msg_ctx , name ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
return NULL ;
}
2009-01-06 04:13:57 +01:00
Py_RETURN_NONE ;
2008-05-26 00:50:07 +02:00
}
static PyObject * py_messaging_remove_name ( PyObject * self , PyObject * args , PyObject * kwargs )
{
messaging_Object * iface = ( messaging_Object * ) self ;
char * name ;
const char * kwnames [ ] = { " name " , NULL } ;
2009-11-07 17:57:50 +01:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|:remove_name " ,
2008-05-26 00:50:07 +02:00
discard_const_p ( char * , kwnames ) , & name ) ) {
return NULL ;
}
irpc_remove_name ( iface - > msg_ctx , name ) ;
2009-01-06 04:13:57 +01:00
Py_RETURN_NONE ;
2008-05-26 00:50:07 +02:00
}
2008-05-25 16:26:34 +02:00
static PyMethodDef py_messaging_methods [ ] = {
{ " send " , ( PyCFunction ) py_messaging_send , METH_VARARGS | METH_KEYWORDS ,
" S.send(target, msg_type, data) -> None \n Send a message " } ,
{ " register " , ( PyCFunction ) py_messaging_register , METH_VARARGS | METH_KEYWORDS ,
2008-05-26 01:52:35 +02:00
" S.register(callback, msg_type=None) -> msg_type \n Register a message handler " } ,
2008-05-26 01:15:15 +02:00
{ " deregister " , ( PyCFunction ) py_messaging_deregister , METH_VARARGS | METH_KEYWORDS ,
2008-05-26 01:52:35 +02:00
" S.deregister(callback, msg_type) -> None \n Deregister a message handler " } ,
2008-05-26 00:50:07 +02:00
{ " add_name " , ( PyCFunction ) py_messaging_add_name , METH_VARARGS | METH_KEYWORDS , " S.add_name(name) -> None \n Listen on another name " } ,
{ " remove_name " , ( PyCFunction ) py_messaging_remove_name , METH_VARARGS | METH_KEYWORDS , " S.remove_name(name) -> None \n Stop listening on a name " } ,
2008-05-25 16:26:34 +02:00
{ NULL , NULL , 0 , NULL }
} ;
2008-05-26 01:52:35 +02:00
static PyObject * py_messaging_server_id ( PyObject * obj , void * closure )
{
messaging_Object * iface = ( messaging_Object * ) obj ;
struct server_id server_id = messaging_get_server_id ( iface - > msg_ctx ) ;
return Py_BuildValue ( " (iii) " , server_id . id , server_id . id2 ,
server_id . node ) ;
}
static PyGetSetDef py_messaging_getset [ ] = {
{ discard_const_p ( char , " server_id " ) , py_messaging_server_id , NULL ,
discard_const_p ( char , " local server id " ) } ,
{ NULL } ,
} ;
2008-05-25 16:26:34 +02:00
PyTypeObject messaging_Type = {
PyObject_HEAD_INIT ( NULL ) 0 ,
. tp_name = " irpc.Messaging " ,
. tp_basicsize = sizeof ( messaging_Object ) ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
. tp_new = py_messaging_connect ,
. tp_dealloc = py_messaging_dealloc ,
. tp_methods = py_messaging_methods ,
2008-05-26 01:52:35 +02:00
. tp_getset = py_messaging_getset ,
2008-05-26 04:14:28 +02:00
. tp_doc = " Messaging(own_id=None, messaging_path=None) \n " \
" Create a new object that can be used to communicate with the peers in the specified messaging path. \n " \
" If no path is specified, the default path from smb.conf will be used. "
2008-05-25 16:26:34 +02:00
} ;
2008-05-24 18:18:21 +02:00
/*
state of a irpc ' connection '
*/
2008-05-25 16:26:34 +02:00
typedef struct {
PyObject_HEAD
2008-05-24 18:18:21 +02:00
const char * server_name ;
struct server_id * dest_ids ;
struct messaging_context * msg_ctx ;
2008-05-25 16:26:34 +02:00
TALLOC_CTX * mem_ctx ;
2008-05-26 04:14:28 +02:00
} irpc_ClientConnectionObject ;
2008-05-24 18:18:21 +02:00
/*
setup a context for talking to a irpc server
example :
status = irpc . connect ( " smb_server " ) ;
*/
2008-05-25 16:26:34 +02:00
PyObject * py_irpc_connect ( PyTypeObject * self , PyObject * args , PyObject * kwargs )
2008-05-24 18:18:21 +02:00
{
2008-12-29 20:24:57 +01:00
struct tevent_context * ev ;
2008-05-26 01:10:24 +02:00
const char * kwnames [ ] = { " server " , " own_id " , " messaging_path " , NULL } ;
2008-05-25 16:26:34 +02:00
char * server ;
const char * messaging_path = NULL ;
2008-05-26 01:10:24 +02:00
PyObject * own_id = Py_None ;
2008-05-26 04:14:28 +02:00
irpc_ClientConnectionObject * ret ;
2008-05-24 18:18:21 +02:00
2008-05-26 04:14:28 +02:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|Oz:connect " ,
2008-05-26 01:10:24 +02:00
discard_const_p ( char * , kwnames ) , & server , & own_id , & messaging_path ) ) {
2008-05-25 16:26:34 +02:00
return NULL ;
2008-05-24 18:18:21 +02:00
}
2008-05-26 04:14:28 +02:00
ret = PyObject_New ( irpc_ClientConnectionObject , & irpc_ClientConnectionType ) ;
2008-05-25 16:26:34 +02:00
if ( ret = = NULL )
return NULL ;
ret - > mem_ctx = talloc_new ( NULL ) ;
2008-05-24 18:18:21 +02:00
2008-05-25 16:26:34 +02:00
ret - > server_name = server ;
2008-05-24 18:18:21 +02:00
2008-06-14 13:00:53 -04:00
ev = s4_event_context_init ( ret - > mem_ctx ) ;
2008-05-25 16:26:34 +02:00
if ( messaging_path = = NULL ) {
2008-11-02 16:50:11 +01:00
messaging_path = lp_messaging_path ( ret - > mem_ctx ,
py_default_loadparm_context ( ret - > mem_ctx ) ) ;
2008-05-26 04:14:28 +02:00
} else {
messaging_path = talloc_strdup ( ret - > mem_ctx , messaging_path ) ;
2008-05-25 16:26:34 +02:00
}
2008-05-24 18:18:21 +02:00
2008-05-26 01:10:24 +02:00
if ( own_id ! = Py_None ) {
struct server_id server_id ;
if ( ! server_id_from_py ( own_id , & server_id ) )
return NULL ;
2008-05-25 16:26:34 +02:00
ret - > msg_ctx = messaging_init ( ret - > mem_ctx ,
messaging_path ,
2008-05-26 01:10:24 +02:00
server_id ,
2008-10-24 13:13:27 +02:00
py_iconv_convenience ( ret - > mem_ctx ) ,
2008-05-26 01:10:24 +02:00
ev ) ;
} else {
ret - > msg_ctx = messaging_client_init ( ret - > mem_ctx ,
messaging_path ,
2008-10-24 13:13:27 +02:00
py_iconv_convenience ( ret - > mem_ctx ) ,
2008-05-24 18:18:21 +02:00
ev ) ;
}
2008-05-26 01:10:24 +02:00
2008-05-25 16:26:34 +02:00
if ( ret - > msg_ctx = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError , " irpc_connect unable to create a messaging context " ) ;
talloc_free ( ret - > mem_ctx ) ;
return NULL ;
2008-05-24 18:18:21 +02:00
}
2008-05-25 16:26:34 +02:00
ret - > dest_ids = irpc_servers_byname ( ret - > msg_ctx , ret - > mem_ctx , ret - > server_name ) ;
if ( ret - > dest_ids = = NULL | | ret - > dest_ids [ 0 ] . id = = 0 ) {
talloc_free ( ret - > mem_ctx ) ;
PyErr_SetNTSTATUS ( NT_STATUS_OBJECT_NAME_NOT_FOUND ) ;
return NULL ;
2008-05-24 18:18:21 +02:00
} else {
2008-05-25 16:26:34 +02:00
return ( PyObject * ) ret ;
2008-05-24 18:18:21 +02:00
}
2008-05-25 16:26:34 +02:00
}
2008-05-24 18:18:21 +02:00
2008-05-26 03:07:18 +02:00
typedef struct {
PyObject_HEAD
struct irpc_request * * reqs ;
int count ;
int current ;
TALLOC_CTX * mem_ctx ;
py_data_unpack_fn unpack_fn ;
} irpc_ResultObject ;
static PyObject * irpc_result_next ( irpc_ResultObject * iterator )
2008-05-25 16:26:34 +02:00
{
2008-05-26 03:07:18 +02:00
NTSTATUS status ;
if ( iterator - > current > = iterator - > count ) {
PyErr_SetString ( PyExc_StopIteration , " No more results " ) ;
return NULL ;
}
status = irpc_call_recv ( iterator - > reqs [ iterator - > current ] ) ;
iterator - > current + + ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
PyErr_SetNTSTATUS ( status ) ;
return NULL ;
}
return iterator - > unpack_fn ( iterator - > reqs [ iterator - > current - 1 ] - > r ) ;
}
static PyObject * irpc_result_len ( irpc_ResultObject * self )
{
return PyLong_FromLong ( self - > count ) ;
}
static PyMethodDef irpc_result_methods [ ] = {
{ " __len__ " , ( PyCFunction ) irpc_result_len , METH_NOARGS ,
" Number of elements returned " } ,
{ NULL }
} ;
static void irpc_result_dealloc ( PyObject * self )
{
talloc_free ( ( ( irpc_ResultObject * ) self ) - > mem_ctx ) ;
2008-05-25 16:26:34 +02:00
PyObject_Del ( self ) ;
2008-05-24 18:18:21 +02:00
}
2008-05-26 03:07:18 +02:00
PyTypeObject irpc_ResultIteratorType = {
2008-05-25 16:26:34 +02:00
PyObject_HEAD_INIT ( NULL ) 0 ,
2008-05-26 03:07:18 +02:00
. tp_name = " irpc.ResultIterator " ,
. tp_basicsize = sizeof ( irpc_ResultObject ) ,
2008-05-25 16:26:34 +02:00
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
2008-05-26 04:14:28 +02:00
. tp_iternext = ( iternextfunc ) irpc_result_next ,
. tp_iter = PyObject_SelfIter ,
2008-05-26 03:07:18 +02:00
. tp_methods = irpc_result_methods ,
. tp_dealloc = irpc_result_dealloc ,
2008-05-25 16:26:34 +02:00
} ;
2008-05-26 04:14:28 +02:00
static PyObject * py_irpc_call ( irpc_ClientConnectionObject * p , struct PyNdrRpcMethodDef * method_def , PyObject * args , PyObject * kwargs )
2008-05-24 18:18:21 +02:00
{
void * ptr ;
struct irpc_request * * reqs ;
int i , count ;
2008-05-26 03:07:18 +02:00
NTSTATUS status ;
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
irpc_ResultObject * ret ;
2008-05-24 18:18:21 +02:00
/* allocate the C structure */
2008-05-26 03:07:18 +02:00
ptr = talloc_zero_size ( mem_ctx , method_def - > table - > calls [ method_def - > opnum ] . struct_size ) ;
2008-05-24 18:18:21 +02:00
if ( ptr = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
/* convert the mpr object into a C structure */
2008-05-26 03:07:18 +02:00
if ( ! method_def - > pack_in_data ( args , kwargs , ptr ) ) {
talloc_free ( mem_ctx ) ;
return NULL ;
2008-05-24 18:18:21 +02:00
}
for ( count = 0 ; p - > dest_ids [ count ] . id ; count + + ) /* noop */ ;
/* we need to make a call per server */
2008-05-26 03:07:18 +02:00
reqs = talloc_array ( mem_ctx , struct irpc_request * , count ) ;
2008-05-24 18:18:21 +02:00
if ( reqs = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
/* make the actual calls */
for ( i = 0 ; i < count ; i + + ) {
reqs [ i ] = irpc_call_send ( p - > msg_ctx , p - > dest_ids [ i ] ,
2008-05-26 03:07:18 +02:00
method_def - > table , method_def - > opnum , ptr , ptr ) ;
2008-05-24 18:18:21 +02:00
if ( reqs [ i ] = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
talloc_steal ( reqs , reqs [ i ] ) ;
}
2008-05-26 03:07:18 +02:00
ret = PyObject_New ( irpc_ResultObject , & irpc_ResultIteratorType ) ;
ret - > mem_ctx = mem_ctx ;
ret - > reqs = reqs ;
ret - > count = count ;
ret - > current = 0 ;
ret - > unpack_fn = method_def - > unpack_out_data ;
2008-05-24 18:18:21 +02:00
2008-05-26 03:07:18 +02:00
return ( PyObject * ) ret ;
done :
talloc_free ( mem_ctx ) ;
PyErr_SetNTSTATUS ( status ) ;
return NULL ;
}
2008-05-24 18:18:21 +02:00
2008-05-26 03:07:18 +02:00
static PyObject * py_irpc_call_wrapper ( PyObject * self , PyObject * args , void * wrapped , PyObject * kwargs )
{
2008-05-26 04:14:28 +02:00
irpc_ClientConnectionObject * iface = ( irpc_ClientConnectionObject * ) self ;
2008-05-26 03:07:18 +02:00
struct PyNdrRpcMethodDef * md = wrapped ;
2008-05-24 18:18:21 +02:00
2008-05-26 03:07:18 +02:00
return py_irpc_call ( iface , md , args , kwargs ) ;
}
static void py_irpc_dealloc ( PyObject * self )
{
2008-05-26 04:14:28 +02:00
irpc_ClientConnectionObject * iface = ( irpc_ClientConnectionObject * ) self ;
2008-05-26 03:07:18 +02:00
talloc_free ( iface - > mem_ctx ) ;
PyObject_Del ( self ) ;
}
2008-05-26 04:14:28 +02:00
PyTypeObject irpc_ClientConnectionType = {
2008-05-26 03:07:18 +02:00
PyObject_HEAD_INIT ( NULL ) 0 ,
. tp_name = " irpc.ClientConnection " ,
2008-05-26 04:14:28 +02:00
. tp_basicsize = sizeof ( irpc_ClientConnectionObject ) ,
2008-05-26 03:07:18 +02:00
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
. tp_new = py_irpc_connect ,
. tp_dealloc = py_irpc_dealloc ,
2008-05-26 04:14:28 +02:00
. tp_doc = " ClientConnection(server, own_id=None, messaging_path=None) \n " \
" Create a new IRPC client connection to communicate with the servers in the specified path. \n " \
" If no path is specified, the default path from smb.conf will be used. "
2008-05-26 03:07:18 +02:00
} ;
2008-05-26 04:14:28 +02:00
static bool irpc_AddNdrRpcMethods ( PyTypeObject * ifacetype , const struct PyNdrRpcMethodDef * mds )
2008-05-26 03:07:18 +02:00
{
int i ;
for ( i = 0 ; mds [ i ] . name ; i + + ) {
PyObject * ret ;
struct wrapperbase * wb = calloc ( sizeof ( struct wrapperbase ) , 1 ) ;
wb - > name = discard_const_p ( char , mds [ i ] . name ) ;
wb - > flags = PyWrapperFlag_KEYWORDS ;
wb - > wrapper = ( wrapperfunc ) py_irpc_call_wrapper ;
wb - > doc = discard_const_p ( char , mds [ i ] . doc ) ;
2008-05-26 04:14:28 +02:00
ret = PyDescr_NewWrapper ( ifacetype , wb , discard_const_p ( void , & mds [ i ] ) ) ;
2008-05-26 03:07:18 +02:00
PyDict_SetItemString ( ifacetype - > tp_dict , mds [ i ] . name ,
( PyObject * ) ret ) ;
2008-05-24 18:18:21 +02:00
}
2008-05-26 03:07:18 +02:00
return true ;
2008-05-24 18:18:21 +02:00
}
2008-05-26 04:14:28 +02:00
void initmessaging ( void )
2008-05-24 18:18:21 +02:00
{
2008-05-24 18:25:27 +02:00
PyObject * mod ;
2008-12-22 04:03:55 +01:00
PyObject * dep_irpc ;
dep_irpc = PyImport_ImportModule ( " samba.dcerpc.irpc " ) ;
if ( dep_irpc = = NULL )
return ;
2008-05-25 16:26:34 +02:00
2008-05-26 04:14:28 +02:00
if ( PyType_Ready ( & irpc_ClientConnectionType ) < 0 )
2008-05-25 16:26:34 +02:00
return ;
if ( PyType_Ready ( & messaging_Type ) < 0 )
return ;
2008-05-26 03:07:18 +02:00
if ( PyType_Ready ( & irpc_ResultIteratorType ) < 0 )
return ;
2008-05-26 04:14:28 +02:00
if ( ! irpc_AddNdrRpcMethods ( & irpc_ClientConnectionType , py_ndr_irpc_methods ) )
2008-05-26 03:07:18 +02:00
return ;
2008-05-26 04:14:28 +02:00
mod = Py_InitModule3 ( " messaging " , NULL , " Internal RPC " ) ;
2008-05-25 16:26:34 +02:00
if ( mod = = NULL )
return ;
2008-05-26 04:14:28 +02:00
Py_INCREF ( ( PyObject * ) & irpc_ClientConnectionType ) ;
PyModule_AddObject ( mod , " ClientConnection " , ( PyObject * ) & irpc_ClientConnectionType ) ;
2008-05-25 16:26:34 +02:00
Py_INCREF ( ( PyObject * ) & messaging_Type ) ;
PyModule_AddObject ( mod , " Messaging " , ( PyObject * ) & messaging_Type ) ;
2008-05-24 18:18:21 +02:00
}