blob: d82d2d199a88893597a8ed62a40c02ea4b9a3da5 [file] [log] [blame]
/*
* swig-plugin.c
*
* 'C' interface for swig-based openwsman server plugins
*
* This file implements the plugin API as needed by openwsman
*
*/
/*****************************************************************************
* Copyright (C) 2008 Novell Inc. All rights reserved.
* Copyright (C) 2008 SUSE Linux Products GmbH. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* - Neither the name of Novell Inc. nor of SUSE Linux Products GmbH nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Novell Inc. OR SUSE Linux Products GmbH OR
* THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
#undef PACKAGE_NAME
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#undef PACKAGE_STRING
#undef PACKAGE_BUGREPORT
#undef SIZEOF_SHORT
#undef SIZEOF_INT
#undef SIZEOF_LONG
#undef SIZEOF_LONG_LONG
#include "wsman_config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#include <wsman-xml-api.h>
#include <wsman-xml-serializer.h>
#include <wsman-declarations.h>
#define OWN 1
int init( void *self, void **data );
/*
* string2target
* char* -> Target_Type
*
* *must* be called within TARGET_THREAD_BEGIN_BLOCK/TARGET_THREAD_END_BLOCK
*/
static Target_Type
string2target(const char *s)
{
Target_Type obj;
if (s == NULL)
return Target_Null;
obj = Target_String(s);
return obj;
}
/*
* proplist2target
* char** -> Target_Type
*
* *must* be called within TARGET_THREAD_BEGIN_BLOCK/TARGET_THREAD_END_BLOCK
*/
static Target_Type
proplist2target(const char** cplist)
{
Target_Type pl;
if (cplist == NULL)
{
Target_INCREF(Target_Void);
return Target_Void;
}
pl = Target_Array();
for (; (cplist!=NULL && *cplist != NULL); ++cplist)
{
Target_Append(pl, Target_String(*cplist));
}
return pl;
}
static char *
fmtstr(const char* fmt, ...)
{
va_list ap;
int len;
char* str;
va_start(ap, fmt);
len = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
if (len <= 0)
{
return NULL;
}
str = (char*)malloc(len+1);
if (str == NULL)
{
return NULL;
}
va_start(ap, fmt);
vsnprintf(str, len+1, fmt, ap);
va_end(ap);
return str;
}
/*
**==============================================================================
**
** Local definitions:
**
**==============================================================================
*/
/*
* There is one target interpreter, serving multiple plugins
* The number of plugins using the interpreter is counted in _PLUGIN_COUNT,
* when the last user goes aways, the target interpreter is unloaded.
*
* _PLUGIN_INIT_MUTEX protects this references counter from concurrent access.
*
*/
#if defined(SWIGPERL)
static PerlInterpreter * _TARGET_INIT = 0; /* acts as a boolean - is target initialized? */
#else
static int _TARGET_INIT = 0; /* acts as a boolean - is target initialized? */
#endif
static int _PLUGIN_COUNT = 0; /* use count, number of plugins */
static pthread_mutex_t _PLUGIN_INIT_MUTEX = PTHREAD_MUTEX_INITIALIZER; /* mutex around _PLUGIN_COUNT */
static Target_Type _TARGET_MODULE = Target_Null; /* The target module (aka namespace) */
#if defined(SWIGPYTHON)
#include "target_python.c"
#endif
#if defined(SWIGRUBY)
#include "target_ruby.c"
#endif
#if defined(SWIGPERL)
#include "target_perl.c"
#endif
struct __Swig
{
char* xml;
};
typedef struct __Swig Swig;
/*
* Service endpoint declarations
*
*/
static int
Swig_Identify_EP( WsContextH cntx )
{
int rc;
Target_Type _context;
TARGET_THREAD_BEGIN_BLOCK;
_context = SWIG_NewPointerObj((void*) cntx, SWIGTYPE_p__WS_CONTEXT, OWN);
rc = TargetCall(cntx->indoc, _TARGET_MODULE, "identify", 1, _context);
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Enumerate_EP( WsContextH cntx, WsEnumerateInfo* enumInfo,
WsmanStatus *status,
void *opaqueData )
{
Target_Type _context, _enumInfo;
Target_Type _status;
int rc;
TARGET_THREAD_BEGIN_BLOCK;
debug("Swig_Enumerate_EP(cntx %p, enumInfo %p, status %p, opaqueData %p", cntx, enumInfo, status, opaqueData);
debug("enumInfo.epr_to %s, epr_uri %s", enumInfo->epr_to, enumInfo->epr_uri);
_context = SWIG_NewPointerObj((void*) cntx, SWIGTYPE_p__WS_CONTEXT, OWN);
_enumInfo = SWIG_NewPointerObj((void*) enumInfo, SWIGTYPE_p___WsEnumerateInfo, OWN);
_status = SWIG_NewPointerObj((void*) status, SWIGTYPE_p__WsmanStatus, OWN);
rc = TargetCall(cntx->indoc, _TARGET_MODULE, "enumerate", 3, _context, _enumInfo, _status );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Release_EP( WsContextH cntx, WsEnumerateInfo* enumInfo,
WsmanStatus *status,
void *opaqueData )
{
Target_Type _context;
Target_Type _enumInfo;
Target_Type _status;
int rc;
TARGET_THREAD_BEGIN_BLOCK;
_context = SWIG_NewPointerObj((void*) cntx, SWIGTYPE_p__WS_CONTEXT, OWN);
_enumInfo = SWIG_NewPointerObj((void*) enumInfo, SWIGTYPE_p___WsEnumerateInfo, OWN);
_status = SWIG_NewPointerObj((void*) status, SWIGTYPE_p__WsmanStatus, OWN);
rc = TargetCall(cntx->indoc, _TARGET_MODULE, "release", 3, _context, _enumInfo, _status );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Pull_EP( WsContextH cntx, WsEnumerateInfo* enumInfo,
WsmanStatus *status,
void *opaqueData )
{
Target_Type _context;
Target_Type _enumInfo;
Target_Type _status;
int rc;
TARGET_THREAD_BEGIN_BLOCK;
_context = SWIG_NewPointerObj((void*) cntx, SWIGTYPE_p__WS_CONTEXT, OWN);
_enumInfo = SWIG_NewPointerObj((void*) enumInfo, SWIGTYPE_p___WsEnumerateInfo, OWN);
_status = SWIG_NewPointerObj((void*) status, SWIGTYPE_p__WsmanStatus, OWN);
rc = TargetCall(cntx->indoc, _TARGET_MODULE, "pull", 3, _context, _enumInfo, _status );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Get_EP( SoapOpH op, void* appData, void *opaqueData )
{
Target_Type _op;
int rc;
WsXmlDocH in_doc = soap_get_op_doc( op, 1 );
TARGET_THREAD_BEGIN_BLOCK;
_op = SWIG_NewPointerObj((void*) op, SWIGTYPE_p___SoapOp, OWN);
rc = TargetCall(in_doc, _TARGET_MODULE, "get", 1, _op );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Custom_EP( SoapOpH op, void* appData, void *opaqueData )
{
Target_Type _op;
int rc;
WsXmlDocH in_doc = soap_get_op_doc( op, 1 );
TARGET_THREAD_BEGIN_BLOCK;
_op = SWIG_NewPointerObj((void*) op, SWIGTYPE_p___SoapOp, OWN);
rc = TargetCall(in_doc, _TARGET_MODULE, "custom", 1, _op );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Put_EP( SoapOpH op, void* appData, void *opaqueData )
{
Target_Type _op;
int rc;
WsXmlDocH in_doc = soap_get_op_doc( op, 1 );
TARGET_THREAD_BEGIN_BLOCK;
_op = SWIG_NewPointerObj((void*) op, SWIGTYPE_p___SoapOp, OWN);
rc = TargetCall(in_doc, _TARGET_MODULE, "put", 1, _op );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Create_EP( SoapOpH op, void* appData, void *opaqueData )
{
Target_Type _op;
int rc;
WsXmlDocH in_doc = soap_get_op_doc( op, 1 );
TARGET_THREAD_BEGIN_BLOCK;
_op = SWIG_NewPointerObj((void*) op, SWIGTYPE_p___SoapOp, OWN);
rc = TargetCall(in_doc, _TARGET_MODULE, "create", 1, _op );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_Delete_EP( SoapOpH op, void* appData, void *opaqueData )
{
Target_Type _op;
int rc;
WsXmlDocH in_doc = soap_get_op_doc( op, 1 );
TARGET_THREAD_BEGIN_BLOCK;
_op = SWIG_NewPointerObj((void*) op, SWIGTYPE_p___SoapOp, OWN);
rc = TargetCall(in_doc, _TARGET_MODULE, "delete", 1, _op );
TARGET_THREAD_END_BLOCK;
return rc;
}
static int
Swig_UnSubscribe_EP(WsContextH cntx,
WsSubscribeInfo* subsInfo,
WsmanStatus *status,
void *opaqueData)
{
return -1;
}
static int
Swig_SubscriptionCancel_EP(WsEventThreadContextH cntx)
{
WsmanStatus status;
return Swig_UnSubscribe_EP(cntx->soap->cntx, cntx->subsInfo, &status, NULL);
}
static int
Swig_Subscribe_EP(WsContextH cntx,
WsSubscribeInfo* subsInfo,
WsmanStatus *status,
void *opaqueData)
{
return -1;
}
static int
Swig_Renew_EP(WsContextH cntx,
WsSubscribeInfo* subsInfo,
WsmanStatus *status,
void *opaqueData)
{
return -1;
}
/* ************** Array of end points for resource ****************
*
* Must follow general convention xxx_EndPoints
*/
SER_START_ITEMS(Swig)
SER_END_ITEMS(Swig);
START_END_POINTS(Swig)
END_POINT_TRANSFER_DIRECT_GET(Swig, NULL),
END_POINT_TRANSFER_DIRECT_PUT(Swig, NULL),
END_POINT_TRANSFER_DIRECT_CREATE(Swig, NULL),
END_POINT_TRANSFER_DIRECT_DELETE(Swig, NULL),
END_POINT_ENUMERATE(Swig, NULL),
END_POINT_DIRECT_PULL(Swig, NULL),
END_POINT_RELEASE(Swig, NULL),
#ifdef ENABLE_EVENTING_SUPPORT
END_POINT_SUBSCRIBE(Swig,NULL),
END_POINT_UNSUBSCRIBE(Swig,NULL),
END_POINT_RENEW(Swig,NULL),
#endif
END_POINT_PULL(Swig,NULL),
END_POINT_CUSTOM_METHOD(Swig, NULL),
END_POINT_IDENTIFY(Swig, NULL),
FINISH_END_POINTS(Swig);
/*----------------------------------------------------------------
* register end points with server
* called from wsman_init_plugins()
*
* self: p_handle
* data: ifc (WsDispatchInterfaceInfo *)
*/
void
get_endpoints(void *self, void *data_ifc)
{
char *namespace = NULL;
WsDispatchInterfaceInfo *ifc = (WsDispatchInterfaceInfo *)data_ifc;
debug("get_endpoints (%p, %p)", self, ifc);
list_t *namespaces = TargetEndpoints( self, ifc->extraData );
WsDispatchEndPointInfo *epi = Swig_EndPoints;
while (epi->serviceEndPoint) {
epi->data = namespace;
++epi;
}
ifc->flags = 0;
ifc->actionUriBase = NULL;
ifc->version = OPENWSMAN_PLUGIN_API_VERSION;
ifc->config_id = "swig";
ifc->vendor = "SUSE Linux Products GmbH";
ifc->displayName = PLUGIN_FILE;
#if defined(SWIGPYTHON)
ifc->notes = "Python plugin";
#endif
#if defined(SWIGRUBY)
ifc->notes = "Ruby plugin";
#endif
ifc->compliance = XML_NS_WS_MAN;
ifc->wsmanResourceUri = NULL;
ifc->namespaces = namespaces;
ifc->endPoints = Swig_EndPoints;
}
/*----------------------------------------------------------------
* set configuration
* called from wsman_init_plugins()
*
* self: p_handle
* config: listener->config
*/
void
set_config( void *self, dictionary *config )
{
return;
}
/*----------------------------------------------------------------
* cleanup plugin
*/
void
cleanup( void *self, void *data )
{
TargetCleanup( self, data );
return;
}
/*----------------------------------------------------------------
* initialize plugin
* return zero on error
*
* self: p_handle
* data: pointer to 'void *data'
* init can fill this data which is passed to every other call
*/
int
init( void *self, void **data )
{
return (TargetInitialize( self, data ) == 0);
}