2008-01-13 18:44:42 +03:00
/*
Unix SMB / CIFS implementation .
Python / Talloc glue
Copyright ( C ) Jelmer Vernooij < jelmer @ samba . org > 2008
2013-06-05 17:48:24 +04:00
* * NOTE ! The following LGPL license applies to the talloc
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 3 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
2008-01-13 18:44:42 +03:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2013-06-05 17:48:24 +04:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2008-01-13 18:44:42 +03:00
*/
2010-01-20 05:07:09 +03:00
# include <Python.h>
2009-01-30 21:38:09 +03:00
# include "replace.h"
2008-10-24 04:52:51 +04:00
# include <talloc.h>
2010-03-29 01:35:30 +04:00
# include "pytalloc.h"
2010-10-24 21:52:01 +04:00
# include <assert.h>
2016-02-22 04:02:28 +03:00
# include "pytalloc_private.h"
2008-01-13 18:44:42 +03:00
2019-03-06 16:29:18 +03:00
static PyObject * pytalloc_steal_or_reference ( PyTypeObject * py_type ,
TALLOC_CTX * mem_ctx , void * ptr , bool steal ) ;
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyTypeObject * pytalloc_GetObjectType ( void )
2010-12-01 00:59:51 +03:00
{
static PyTypeObject * type = NULL ;
PyObject * mod ;
mod = PyImport_ImportModule ( " talloc " ) ;
if ( mod = = NULL ) {
return NULL ;
}
type = ( PyTypeObject * ) PyObject_GetAttrString ( mod , " Object " ) ;
Py_DECREF ( mod ) ;
return type ;
}
2016-02-22 04:02:28 +03:00
_PUBLIC_ PyTypeObject * pytalloc_GetBaseObjectType ( void )
{
static PyTypeObject * type = NULL ;
PyObject * mod ;
mod = PyImport_ImportModule ( " talloc " ) ;
if ( mod = = NULL ) {
return NULL ;
}
type = ( PyTypeObject * ) PyObject_GetAttrString ( mod , " BaseObject " ) ;
Py_DECREF ( mod ) ;
return type ;
}
2017-02-20 19:33:42 +03:00
static PyTypeObject * pytalloc_GetGenericObjectType ( void )
{
static PyTypeObject * type = NULL ;
PyObject * mod ;
mod = PyImport_ImportModule ( " talloc " ) ;
if ( mod = = NULL ) {
return NULL ;
}
type = ( PyTypeObject * ) PyObject_GetAttrString ( mod , " GenericObject " ) ;
Py_DECREF ( mod ) ;
return type ;
}
2008-12-23 06:06:21 +03:00
/**
* Import an existing talloc pointer into a Python object .
*/
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyObject * pytalloc_steal_ex ( PyTypeObject * py_type , TALLOC_CTX * mem_ctx ,
2016-02-22 04:02:28 +03:00
void * ptr )
2008-01-13 18:44:42 +03:00
{
2019-03-06 16:29:18 +03:00
return pytalloc_steal_or_reference ( py_type , mem_ctx , ptr , true ) ;
2009-07-01 08:05:17 +04:00
}
2010-08-25 08:29:59 +04:00
/**
* Import an existing talloc pointer into a Python object .
*/
2011-08-10 17:15:18 +04:00
_PUBLIC_ PyObject * pytalloc_steal ( PyTypeObject * py_type , void * ptr )
2010-08-25 08:29:59 +04:00
{
2019-03-06 16:29:18 +03:00
return pytalloc_steal_or_reference ( py_type , ptr , ptr , true ) ;
2010-08-25 08:29:59 +04:00
}
2009-07-01 08:05:17 +04:00
/**
* Import an existing talloc pointer into a Python object , leaving the
* original parent , and creating a reference to the object in the python
2016-02-22 04:02:28 +03:00
* object .
*
* We remember the object we hold the reference to ( a
* possibly - non - talloc pointer ) , the existing parent ( typically the
* start of the array ) and the new referenced parent . That way we can
* cope with the fact that we will have multiple parents , one per time
* python sees the object .
2009-07-01 08:05:17 +04:00
*/
2016-02-22 04:02:28 +03:00
_PUBLIC_ PyObject * pytalloc_reference_ex ( PyTypeObject * py_type ,
TALLOC_CTX * mem_ctx , void * ptr )
2009-07-01 08:05:17 +04:00
{
2019-03-06 16:29:18 +03:00
return pytalloc_steal_or_reference ( py_type , mem_ctx , ptr , false ) ;
}
/**
2023-04-13 14:14:10 +03:00
* Internal function that either steals or references the talloc
2019-03-06 16:29:18 +03:00
* pointer into a new talloc context .
*/
static PyObject * pytalloc_steal_or_reference ( PyTypeObject * py_type ,
TALLOC_CTX * mem_ctx , void * ptr , bool steal )
{
bool ok = false ;
2019-03-06 16:46:32 +03:00
TALLOC_CTX * talloc_ctx = NULL ;
bool is_baseobject = false ;
PyObject * obj = NULL ;
2019-03-06 16:54:58 +03:00
PyTypeObject * BaseObjectType = NULL , * ObjectType = NULL ;
2010-08-28 15:53:27 +04:00
2019-03-06 16:54:58 +03:00
BaseObjectType = pytalloc_GetBaseObjectType ( ) ;
if ( BaseObjectType = = NULL ) {
goto err ;
}
ObjectType = pytalloc_GetObjectType ( ) ;
if ( ObjectType = = NULL ) {
goto err ;
}
/* this should have been tested by caller */
2016-02-22 04:02:28 +03:00
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
2010-08-28 15:53:27 +04:00
}
2019-03-06 16:46:32 +03:00
is_baseobject = PyType_IsSubtype ( py_type , BaseObjectType ) ;
if ( ! is_baseobject ) {
if ( ! PyType_IsSubtype ( py_type , ObjectType ) ) {
2019-03-06 16:54:58 +03:00
PyErr_SetString ( PyExc_TypeError ,
2019-03-06 16:46:32 +03:00
" Expected type based on talloc " ) ;
2016-02-22 04:02:28 +03:00
return NULL ;
}
2019-03-06 16:46:32 +03:00
}
obj = py_type - > tp_alloc ( py_type , 0 ) ;
2019-03-06 16:54:58 +03:00
if ( obj = = NULL ) {
goto err ;
}
2019-03-06 16:46:32 +03:00
talloc_ctx = talloc_new ( NULL ) ;
if ( talloc_ctx = = NULL ) {
2019-03-06 16:54:58 +03:00
PyErr_NoMemory ( ) ;
goto err ;
2019-03-06 16:46:32 +03:00
}
if ( steal ) {
ok = ( talloc_steal ( talloc_ctx , mem_ctx ) ! = NULL ) ;
} else {
ok = ( talloc_reference ( talloc_ctx , mem_ctx ) ! = NULL ) ;
}
if ( ! ok ) {
2019-03-06 16:54:58 +03:00
goto err ;
2019-03-06 16:46:32 +03:00
}
talloc_set_name_const ( talloc_ctx , py_type - > tp_name ) ;
if ( is_baseobject ) {
pytalloc_BaseObject * ret = ( pytalloc_BaseObject * ) obj ;
ret - > talloc_ctx = talloc_ctx ;
2016-02-22 04:02:28 +03:00
ret - > talloc_ptr_ctx = mem_ctx ;
ret - > ptr = ptr ;
} else {
2019-03-06 16:46:32 +03:00
pytalloc_Object * ret = ( pytalloc_Object * ) obj ;
ret - > talloc_ctx = talloc_ctx ;
ret - > ptr = ptr ;
2008-05-23 17:09:51 +04:00
}
2019-03-06 16:46:32 +03:00
return obj ;
2019-03-06 16:54:58 +03:00
err :
TALLOC_FREE ( talloc_ctx ) ;
Py_XDECREF ( obj ) ;
return NULL ;
2008-01-13 18:44:42 +03:00
}
2008-01-13 20:38:12 +03:00
2017-02-20 19:33:42 +03:00
/*
* Wrap a generic talloc pointer into a talloc . GenericObject ,
* this is a subclass of talloc . BaseObject .
*/
_PUBLIC_ PyObject * pytalloc_GenericObject_steal_ex ( TALLOC_CTX * mem_ctx , void * ptr )
{
PyTypeObject * tp = pytalloc_GetGenericObjectType ( ) ;
return pytalloc_steal_ex ( tp , mem_ctx , ptr ) ;
}
/*
* Wrap a generic talloc pointer into a talloc . GenericObject ,
* this is a subclass of talloc . BaseObject .
*/
_PUBLIC_ PyObject * pytalloc_GenericObject_reference_ex ( TALLOC_CTX * mem_ctx , void * ptr )
{
PyTypeObject * tp = pytalloc_GetGenericObjectType ( ) ;
return pytalloc_reference_ex ( tp , mem_ctx , ptr ) ;
}
2011-08-10 17:15:18 +04:00
_PUBLIC_ int pytalloc_Check ( PyObject * obj )
2010-12-01 00:59:51 +03:00
{
2011-08-10 17:15:18 +04:00
PyTypeObject * tp = pytalloc_GetObjectType ( ) ;
2010-12-01 00:59:51 +03:00
return PyObject_TypeCheck ( obj , tp ) ;
}
2016-02-22 04:29:15 +03:00
2016-02-22 04:02:28 +03:00
_PUBLIC_ int pytalloc_BaseObject_check ( PyObject * obj )
{
PyTypeObject * tp = pytalloc_GetBaseObjectType ( ) ;
return PyObject_TypeCheck ( obj , tp ) ;
}
_PUBLIC_ size_t pytalloc_BaseObject_size ( void )
{
return sizeof ( pytalloc_BaseObject ) ;
}
2017-02-20 19:33:42 +03:00
static void * _pytalloc_get_checked_type ( PyObject * py_obj , const char * type_name ,
bool check_only , const char * function )
2016-02-22 10:47:07 +03:00
{
2017-02-20 19:33:42 +03:00
TALLOC_CTX * mem_ctx ;
void * ptr = NULL ;
2019-09-17 11:13:00 +03:00
void * type_obj ;
2016-02-22 10:47:07 +03:00
2017-02-20 19:33:42 +03:00
mem_ctx = _pytalloc_get_mem_ctx ( py_obj ) ;
ptr = _pytalloc_get_ptr ( py_obj ) ;
2019-07-09 12:44:12 +03:00
if ( mem_ctx ! = ptr | | ptr = = NULL ) {
2017-02-20 19:33:42 +03:00
if ( check_only ) {
return NULL ;
}
PyErr_Format ( PyExc_TypeError , " %s: expected %s, "
" but the pointer is no talloc pointer, "
" pytalloc_get_ptr() would get the raw pointer. " ,
function , type_name ) ;
return NULL ;
}
type_obj = talloc_check_name ( ptr , type_name ) ;
2016-02-22 10:47:07 +03:00
if ( type_obj = = NULL ) {
2017-02-20 19:33:42 +03:00
const char * name = NULL ;
if ( check_only ) {
return NULL ;
}
name = talloc_get_name ( ptr ) ;
PyErr_Format ( PyExc_TypeError , " %s: expected %s, got %s " ,
function , type_name , name ) ;
2016-02-22 10:47:07 +03:00
return NULL ;
}
return ptr ;
}
2017-02-20 19:33:42 +03:00
_PUBLIC_ int _pytalloc_check_type ( PyObject * py_obj , const char * type_name )
{
void * ptr = NULL ;
ptr = _pytalloc_get_checked_type ( py_obj , type_name ,
true , /* check_only */
" pytalloc_check_type " ) ;
if ( ptr = = NULL ) {
return 0 ;
}
return 1 ;
}
_PUBLIC_ void * _pytalloc_get_type ( PyObject * py_obj , const char * type_name )
{
return _pytalloc_get_checked_type ( py_obj , type_name ,
false , /* not check_only */
" pytalloc_get_type " ) ;
}
2016-02-22 04:29:15 +03:00
_PUBLIC_ void * _pytalloc_get_ptr ( PyObject * py_obj )
{
2016-02-22 04:02:28 +03:00
if ( pytalloc_BaseObject_check ( py_obj ) ) {
return ( ( pytalloc_BaseObject * ) py_obj ) - > ptr ;
}
if ( pytalloc_Check ( py_obj ) ) {
return ( ( pytalloc_Object * ) py_obj ) - > ptr ;
}
return NULL ;
2016-02-22 04:29:15 +03:00
}
_PUBLIC_ TALLOC_CTX * _pytalloc_get_mem_ctx ( PyObject * py_obj )
{
2016-02-22 04:02:28 +03:00
if ( pytalloc_BaseObject_check ( py_obj ) ) {
return ( ( pytalloc_BaseObject * ) py_obj ) - > talloc_ptr_ctx ;
}
if ( pytalloc_Check ( py_obj ) ) {
return ( ( pytalloc_Object * ) py_obj ) - > talloc_ctx ;
}
return NULL ;
2016-02-22 04:29:15 +03:00
}
2016-02-29 23:26:29 +03:00
_PUBLIC_ int pytalloc_BaseObject_PyType_Ready ( PyTypeObject * type )
{
PyTypeObject * talloc_type = pytalloc_GetBaseObjectType ( ) ;
if ( talloc_type = = NULL ) {
return - 1 ;
}
type - > tp_base = talloc_type ;
type - > tp_basicsize = pytalloc_BaseObject_size ( ) ;
return PyType_Ready ( type ) ;
}
2019-07-09 11:59:19 +03:00
_PUBLIC_ const char * _pytalloc_get_name ( PyObject * obj )
{
void * ptr = pytalloc_get_ptr ( obj ) ;
if ( ptr = = NULL ) {
return " non-talloc object " ;
}
return talloc_get_name ( ptr ) ;
}