You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.4 KiB
C
185 lines
4.4 KiB
C
/*
|
|
* Yet another daemon library especially designed to be used
|
|
* with libsxmp based daemons.
|
|
*
|
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
|
*
|
|
* libsxmp 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.
|
|
*
|
|
* libsxmp 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
|
*
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <tdata/usrtc.h>
|
|
#include <sexpr/sexp.h>
|
|
|
|
#include <ydaemon/ydaemon.h>
|
|
|
|
static long __cmp_cstrs(const void *a, const void *b)
|
|
{
|
|
return (long)(strcmp((const char *)a, (const char *)b));
|
|
}
|
|
|
|
static void __scm_func_tree_init(scm_function_tree_t *pt, void *priv)
|
|
{
|
|
usrtc_t *foost = (usrtc_t *)&(pt->functions);
|
|
|
|
usrtc_init(foost, USRTC_SPLAY, MAX_SCM_FUNCTIONS, __cmp_cstrs);
|
|
return;
|
|
}
|
|
|
|
static scm_function_tree_t *__scm_func_tree_alloc(void *priv)
|
|
{
|
|
scm_function_tree_t *t = malloc(sizeof(scm_function_tree_t));
|
|
|
|
if(!t) goto __fail;
|
|
else __scm_func_tree_init(t, priv);
|
|
|
|
__fail:
|
|
return t;
|
|
}
|
|
|
|
void scm_func_tree_free(scm_function_tree_t *pt)
|
|
{
|
|
usrtc_t *ftree = &(pt->functions);
|
|
usrtc_node_t *node = NULL;
|
|
scm_function_t *sf;
|
|
|
|
if(usrtc_count(ftree)) {
|
|
for(node = usrtc_first(ftree); node != NULL; node = usrtc_first(ftree)) {
|
|
sf = (scm_function_t *)usrtc_node_getdata(node);
|
|
/* remove from the tree first */
|
|
usrtc_delete(ftree, node);
|
|
/* free all */
|
|
free(sf->name);
|
|
free(sf);
|
|
}
|
|
}
|
|
|
|
free(pt);
|
|
|
|
return;
|
|
}
|
|
|
|
/* external API */
|
|
int scm_func_tree_init(scm_function_tree_t **pt, void *priv)
|
|
{
|
|
scm_function_tree_t *nt = __scm_func_tree_alloc(priv);
|
|
|
|
if(!nt) return ENOENT;
|
|
else *pt = nt;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int scm_func_tree_insert(yd_context_t *zdx, const char *name,
|
|
scret_t (*call)(yd_context_t *, sexp_t *, void *),
|
|
void *priv)
|
|
{
|
|
scm_function_tree_t *pt = zdx->func;
|
|
usrtc_t *ftree = &(pt->functions);
|
|
scm_function_t *n_func = malloc(sizeof(scm_function_t));
|
|
usrtc_node_t *node = NULL;
|
|
int e = 0;
|
|
|
|
/* just check existence */
|
|
if(!n_func) return ENOMEM;
|
|
if(usrtc_count(ftree) >= MAX_SCM_FUNCTIONS) {
|
|
e = ENOMEM;
|
|
goto __end;
|
|
}
|
|
if((node = usrtc_lookup(ftree, (const void *)name))) {
|
|
e = EEXIST;
|
|
goto __end;
|
|
}
|
|
|
|
/* init structure */
|
|
if(!(n_func->name = strdup(name))) {
|
|
free(n_func);
|
|
return ENOMEM;
|
|
}
|
|
n_func->call = call;
|
|
n_func->priv = priv;
|
|
node = &(n_func->node);
|
|
usrtc_node_init(node, n_func);
|
|
|
|
/* insert to the tree */
|
|
usrtc_insert(ftree, node, (const void *)name);
|
|
|
|
__end:
|
|
if(e) free(n_func);
|
|
|
|
return e;
|
|
}
|
|
|
|
int scm_func_tree_insert_t(yd_context_t *zdx, scm_function_t *f)
|
|
{
|
|
scm_function_tree_t *pt = zdx->func;
|
|
usrtc_t *ftree = &(pt->functions);
|
|
usrtc_node_t *node = usrtc_lookup(ftree, (const void *)f->name);
|
|
|
|
if(node) return EEXIST;
|
|
else node = &(f->node);
|
|
if(usrtc_count(ftree) >= MAX_SCM_FUNCTIONS) return ENOMEM;
|
|
|
|
usrtc_node_init(node, f);
|
|
usrtc_insert(ftree, node, (const void *)f->name);
|
|
|
|
return 0;
|
|
}
|
|
|
|
scret_t scm_func_tree_call(yd_context_t *zdx, void *cnf, sexp_t *sx,
|
|
char *name)
|
|
{
|
|
scm_function_tree_t *pt = zdx->func;
|
|
usrtc_t *ftree = &(pt->functions);
|
|
usrtc_node_t *node = usrtc_lookup(ftree, (const void *)name);
|
|
scm_function_t *fn;
|
|
|
|
if(!node) {
|
|
scret_t rets;
|
|
RETURN_SRET_SERR(rets, ENOENT);
|
|
} else fn = (scm_function_t *)usrtc_node_getdata(node);
|
|
|
|
cnf = zdx;
|
|
|
|
return fn->call(cnf, sx, fn->priv);
|
|
}
|
|
|
|
int scm_func_tree_delete(yd_context_t *zdx, char *name)
|
|
{
|
|
scm_function_tree_t *pt = zdx->func;
|
|
usrtc_t *ftree = &(pt->functions);
|
|
usrtc_node_t *node = usrtc_lookup(ftree, (const void *)name);
|
|
scm_function_t *fn;
|
|
|
|
if(!node) return ENOENT;
|
|
else fn = (scm_function_t *)usrtc_node_getdata(node);
|
|
|
|
/* remove from tree first */
|
|
usrtc_delete(ftree, node);
|
|
|
|
/* free */
|
|
free(fn->name);
|
|
free(fn);
|
|
|
|
return 0;
|
|
}
|