#include "global.h"
/*
* rpc_srv_freeValsCall() Free return variables for RPC call
* @call = RPC function call
* return: none
*/
inline void
rpc_srv_freeValsCall(rpc_func_t * __restrict call)
{
rpc_srv_declValsCall(call, 0);
}
/*
* rpc_srv_declValsCall() Declare return variables for RPC call
* @call = RPC function call
* @return_vals = Number of return variables
* return: -1 error, !=-1 ok
*/
inline int
rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals)
{
void *ptr;
if (!call || return_vals < 0) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t declare return variables for RPC call...\n");
return -1;
} else
call->func_args = return_vals;
if (!return_vals) {
if (call->func_vals) {
free(call->func_vals);
call->func_vals = NULL;
}
} else {
ptr = realloc(call->func_vals, return_vals * sizeof(rpc_val_t));
if (!ptr) {
LOGERR;
return -1;
} else
call->func_vals = ptr;
}
return call->func_args;
}
/*
* rpc_srv_delValsCall() Clean values from return variables of RPC call
* @call = RPC function call
* return: -1 error, !=-1 Returned number of cleaned RPC variables
*/
inline int
rpc_srv_delValsCall(rpc_func_t * __restrict call)
{
if (!call) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete return variables ...\n");
return -1;
}
memset(call->func_vals, 0, call->func_args * sizeof(rpc_val_t));
return call->func_args;
}
/*
* rpc_srv_copyValsCall() Copy return variables for RPC call to new variable
* @call = RPC function call
* @newvals = New allocated variables array, must be free after use
* return: -1 error, !=-1 Returned number of copied RPC variables
*/
inline int
rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals)
{
if (!call || !newvals) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t copy return variables to new array\n");
return -1;
}
*newvals = calloc(call->func_args, sizeof(rpc_val_t));
if (!*newvals) {
LOGERR;
return -1;
} else
memcpy(*newvals, call->func_vals, call->func_args * sizeof(rpc_val_t));
return call->func_args;
}
/*
* rpc_srv_getValsCall() Get return variables for RPC call
* @call = RPC function call
* @vals = Returned variables, may be NULL
* return: -1 error, !=-1 Number of returned variables
*/
inline int
rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals)
{
if (!call) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get return variables ...\n");
return -1;
}
if (vals)
*vals = call->func_vals;
return call->func_args;
}
// ---------------------------------------------------------
/*
* rpc_srv_registerCall() Register call to RPC server
* @srv = RPC Server instance
* @csModule = Module name, if NULL self binary
* @csFunc = Function name
* @args = Number of function arguments
* return: -1 error or 0 register ok
*/
int
rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, u_char args)
{
rpc_func_t *func;
u_char str[MAXPATHLEN + UCHAR_MAX + 1];
memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
if (!srv || !csFunc) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register function to RPC server ...\n");
return -1;
}
if (!(func = malloc(sizeof(rpc_func_t)))) {
LOGERR;
return -1;
} else {
memset(func, 0, sizeof(rpc_func_t));
strlcpy((char*) func->func_name, csFunc, UCHAR_MAX + 1);
}
if (csModule) {
strlcpy((char*) func->func_file, csModule, MAXPATHLEN);
strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
}
strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
func->func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
func->func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
if (rpc_srv_declValsCall(func, args) == -1) {
free(func);
return -1;
}
pthread_mutex_lock(&srv->srv_mtx);
func->func_next = srv->srv_funcs;
srv->srv_funcs = func;
pthread_mutex_unlock(&srv->srv_mtx);
return 0;
}
/*
* rpc_srv_unregisterCall() Unregister call from RPC server
* @srv = RPC Server instance
* @csModule = Module name, if NULL self binary
* @csFunc = Function name
* return: -1 error, 0 not found call, 1 unregister ok
*/
int
rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
{
rpc_func_t func, *f, *curr;
u_char str[MAXPATHLEN + UCHAR_MAX + 1];
memset(&func, 0, sizeof(rpc_func_t));
memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
if (!srv || !csFunc) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister function from RPC server ...\n");
return -1;
} else
strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
if (csModule) {
strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
}
strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
f = rpc_srv_getCall(srv, func.func_tag, func.func_hash);
if (!f) // not found element for unregister
return 0;
pthread_mutex_lock(&srv->srv_mtx);
if (srv->srv_funcs == f) { // if is 1st element
srv->srv_funcs = srv->srv_funcs->func_next;
if (f->func_args && f->func_vals)
free(f->func_vals);
free(f);
} else {
for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next);
curr->func_next = curr->func_next->func_next;
if (f->func_args && f->func_vals)
free(f->func_vals);
free(f);
}
pthread_mutex_unlock(&srv->srv_mtx);
return 1;
}
/*
* rpc_srv_getCall() Get registered call from RPC server
* @srv = RPC Server instance
* @tag = tag for function
* @hash = hash for function
* return: NULL not found call, !=NULL return call
*/
inline rpc_func_t *
rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash)
{
rpc_func_t *f;
if (!srv) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
return NULL;
}
for (f = srv->srv_funcs; f; f = f->func_next)
if (f->func_tag == tag && f->func_hash == hash)
break;
return f;
}
/*
* rpc_srv_getFunc() Get registered call from RPC server by Name
* @srv = RPC Server instance
* @csModule = Module name, if NULL self binary
* @csFunc = Function name
* return: NULL not found call, !=NULL return call
*/
rpc_func_t *
rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
{
rpc_func_t func;
u_char str[MAXPATHLEN + UCHAR_MAX + 1];
memset(&func, 0, sizeof(rpc_func_t));
memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
if (!srv || !csFunc) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
return NULL;
} else
strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
if (csModule) {
strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
}
strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
return rpc_srv_getCall(srv, func.func_tag, func.func_hash);
}
// ---------------------------------------------------------
/*
* rpc_srv_getBLOB() Get registered BLOB
* @srv = RPC Server instance
* @var = hash for variable
* return: NULL not found, !=NULL return blob var
*/
inline rpc_blob_t *
rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)
{
rpc_blob_t *b;
if (!srv) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variable from BLOB server ...\n");
return NULL;
}
for (b = srv->srv_blob.blobs; b; b = b->blob_next)
if (b->blob_var == var)
break;
return b;
}
/*
* rpc_srv_registerBLOB() Register new BLOB to server
* @srv = RPC Server instance
* @len = BLOB length
* return: -1 error or 0 register ok
*/
rpc_blob_t *
rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len)
{
rpc_blob_t *blob = NULL;
if (!srv || !len) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register BLOB to server ...\n");
return blob;
}
blob = rpc_srv_blobCreate(srv, len);
if (blob) {
pthread_mutex_lock(&srv->srv_blob.mtx);
blob->blob_next = srv->srv_blob.blobs;
srv->srv_blob.blobs = blob;
pthread_mutex_unlock(&srv->srv_blob.mtx);
}
return blob;
}
/*
* rpc_srv_unregisterBLOB() Unregister BLOB from server
* @srv = RPC Server instance
* @var = BLOB Variable for unregister
* return: -1 error, 0 not found call, 1 unregister ok
*/
int
rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)
{
rpc_blob_t *b, *curr;
if (!srv) {
rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister BLOB from server ...\n");
return -1;
}
b = rpc_srv_getBLOB(srv, var);
if (!b) // not found element for unregister
return 0;
pthread_mutex_lock(&srv->srv_blob.mtx);
if (srv->srv_blob.blobs == b) { // if is 1st element
srv->srv_blob.blobs = srv->srv_blob.blobs->blob_next;
} else {
for (curr = srv->srv_blob.blobs; curr->blob_next != b; curr = curr->blob_next);
curr->blob_next = curr->blob_next->blob_next;
}
rpc_srv_blobFree(srv, b);
free(b);
pthread_mutex_unlock(&srv->srv_blob.mtx);
return 1;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>