|
|
|
@ -32,13 +32,160 @@ static long __cmp_int(const void *a, const void *b)
|
|
|
|
|
return *(int *)a - *(int *)b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static long __cmp_cstr(const void *a, const void *b)
|
|
|
|
|
{
|
|
|
|
|
return strcmp((char *)a, (char *)b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sntl_rpclist_init(usrtc_t *tree)
|
|
|
|
|
{
|
|
|
|
|
usrtc_init(tree, USRTC_REDBLACK, MAX_RPC_LIST, __cmp_int);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sntl_rpclist_add(usrtc_t *tree, int type, const char *description)
|
|
|
|
|
int sntl_rpclist_add(usrtc_t *tree, int type, const char *description,
|
|
|
|
|
const char *version)
|
|
|
|
|
{
|
|
|
|
|
rpc_typed_list_t *nlist = NULL;
|
|
|
|
|
cx_rpc_list_t *rpc_list = NULL;
|
|
|
|
|
usrtc_t *rtree = NULL;
|
|
|
|
|
usrtc_node_t *node = NULL;
|
|
|
|
|
int r = ENOMEM;
|
|
|
|
|
|
|
|
|
|
/* check for existing one */
|
|
|
|
|
node = usrtc_lookup(tree, &type);
|
|
|
|
|
if(node) return EEXIST;
|
|
|
|
|
|
|
|
|
|
/* allocate all */
|
|
|
|
|
if(!(nlist = malloc(sizeof(rpc_typed_list_t)))) goto __fail;
|
|
|
|
|
else memset(nlist, 0, sizeof(rpc_typed_list_t));
|
|
|
|
|
if(!(rpc_list = malloc(sizeof(cx_rpc_list_t)))) goto __fail;
|
|
|
|
|
else memset(rpc_list, 0, sizeof(cx_rpc_list_t));
|
|
|
|
|
if(!(rtree = malloc(sizeof(usrtc_t)))) goto __fail;
|
|
|
|
|
|
|
|
|
|
/* version and description */
|
|
|
|
|
if(!(nlist->description = strdup(description))) goto __fail_a;
|
|
|
|
|
if(version) { /* in case of existing version */
|
|
|
|
|
if(!(rpc_list->opt_version = strdup(version))) goto __fail_a;
|
|
|
|
|
}
|
|
|
|
|
/* initialize all */
|
|
|
|
|
nlist->type_id = type;
|
|
|
|
|
nlist->rpc_list = rpc_list;
|
|
|
|
|
rpc_list->rpc_tree = rtree;
|
|
|
|
|
usrtc_node_init(&(nlist->lnode), nlist);
|
|
|
|
|
usrtc_init(rtree, USRTC_SPLAY, MAX_RPC_LIST, __cmp_cstr);
|
|
|
|
|
node = &(nlist->lnode);
|
|
|
|
|
/* insert it */
|
|
|
|
|
usrtc_insert(tree, node, &(nlist->type_id));
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
__fail_a:
|
|
|
|
|
if(nlist->description) free(nlist->description);
|
|
|
|
|
if(rpc_list->opt_version) free(rpc_list->opt_version);
|
|
|
|
|
__fail:
|
|
|
|
|
if(nlist) free(nlist);
|
|
|
|
|
if(rpc_list) free(rpc_list);
|
|
|
|
|
if(rtree) free(rtree);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name,
|
|
|
|
|
int (*rpcf)(void *, sexp_t *))
|
|
|
|
|
{
|
|
|
|
|
usrtc_node_t *node;
|
|
|
|
|
rpc_typed_list_t *tlist;
|
|
|
|
|
cx_rpc_list_t *rlist;
|
|
|
|
|
cx_rpc_t *rentry = NULL;
|
|
|
|
|
|
|
|
|
|
node = usrtc_lookup(tree, &type);
|
|
|
|
|
if(!node) return ENOENT;
|
|
|
|
|
else tlist = (rpc_typed_list_t *)usrtc_node_getdata(node);
|
|
|
|
|
rlist = tlist->rpc_list; /* get rpc list */
|
|
|
|
|
|
|
|
|
|
/* ok, we don't allow dupes */
|
|
|
|
|
node = usrtc_lookup(rlist->rpc_tree, fu_name);
|
|
|
|
|
if(node) return EEXIST;
|
|
|
|
|
if(!(rentry = malloc(sizeof(cx_rpc_t)))) return ENOMEM;
|
|
|
|
|
else if(!(rentry->name = strdup(fu_name))) {
|
|
|
|
|
free(rentry);
|
|
|
|
|
return ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* init */
|
|
|
|
|
usrtc_node_init(&(rentry->node), rentry);
|
|
|
|
|
rentry->rpcf = rpcf;
|
|
|
|
|
node = &(rentry->node);
|
|
|
|
|
usrtc_insert(rlist->rpc_tree, node, rentry->name); /* insert it */
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter)
|
|
|
|
|
{
|
|
|
|
|
int r = 0, *f = filter, i;
|
|
|
|
|
usrtc_t *destination = NULL;
|
|
|
|
|
usrtc_node_t *node;
|
|
|
|
|
rpc_typed_list_t *tlist, *tlist_filter;
|
|
|
|
|
|
|
|
|
|
if(!filter) return EINVAL;
|
|
|
|
|
if(!(destination = malloc(sizeof(usrtc_t)))) return ENOMEM;
|
|
|
|
|
else usrtc_init(destination, USRTC_REDBLACK, MAX_RPC_LIST, __cmp_int);
|
|
|
|
|
|
|
|
|
|
switch(flag) {
|
|
|
|
|
case SNTL_FILTER_EXC:
|
|
|
|
|
for(node = usrtc_first(source); ; node = usrtc_next(source, node)) {
|
|
|
|
|
tlist = (rpc_typed_list_t *)usrtc_node_getdata(node);
|
|
|
|
|
r = ENOENT;
|
|
|
|
|
for(i = *f; i != SNTL_FILTER_END; f++, i = *f) {
|
|
|
|
|
if(tlist->type_id == i) {
|
|
|
|
|
r = 0; break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(r) { /* we should clone it */
|
|
|
|
|
if(!(tlist_filter = malloc(sizeof(rpc_typed_list_t)))) continue; /* skip */
|
|
|
|
|
else {
|
|
|
|
|
tlist_filter->type_id = tlist->type_id;
|
|
|
|
|
tlist_filter->description = tlist->description;
|
|
|
|
|
tlist_filter->rpc_list = tlist->rpc_list;
|
|
|
|
|
usrtc_node_init(&(tlist_filter->lnode), tlist_filter);
|
|
|
|
|
usrtc_insert(destination, &(tlist_filter->lnode), &(tlist_filter->type_id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(node == usrtc_last(source)) break;
|
|
|
|
|
}
|
|
|
|
|
r = 0;
|
|
|
|
|
break;
|
|
|
|
|
case SNTL_FILTER_INC:
|
|
|
|
|
for(i = *f; i != SNTL_FILTER_END; f++, i = *f) {
|
|
|
|
|
node = usrtc_lookup(source, &i);
|
|
|
|
|
if(!node) continue; /* skip it at all */
|
|
|
|
|
else tlist = (rpc_typed_list_t *)usrtc_node_getdata(node);
|
|
|
|
|
/* clone tlist */
|
|
|
|
|
if(!(tlist_filter = malloc(sizeof(rpc_typed_list_t)))) continue; /* skip */
|
|
|
|
|
else {
|
|
|
|
|
tlist_filter->type_id = tlist->type_id;
|
|
|
|
|
tlist_filter->description = tlist->description;
|
|
|
|
|
tlist_filter->rpc_list = tlist->rpc_list;
|
|
|
|
|
usrtc_node_init(&(tlist_filter->lnode), tlist_filter);
|
|
|
|
|
usrtc_insert(destination, &(tlist_filter->lnode), &(tlist_filter->type_id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
r = EINVAL;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!usrtc_count(destination)) { /* we have an empty list */
|
|
|
|
|
r = EINVAL;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*dest = destination;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
__fail:
|
|
|
|
|
if(destination) free(destination);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|