Created xmldb plugin api

This commit is contained in:
Olof hagsand 2017-04-09 22:53:48 +02:00
parent 4169bd8d30
commit f6b3e95100
39 changed files with 492 additions and 504 deletions

View file

@ -29,7 +29,9 @@
#
# ***** END LICENSE BLOCK *****
- Ongoiing: xmldb datastore plugin framework
- Moved qdbm, chunk and xmldb to datastore keyvalue directories
Created xmldb plugin api
Removed all other clixon dependency on chunk code
- cli_copy_config added as generic cli command
- cli_show_config added as generic cli command

View file

@ -95,8 +95,6 @@ config_terminate(clicon_handle h)
event_exit();
clicon_log_register_callback(NULL, NULL);
clicon_debug(1, "%s done", __FUNCTION__);
if (debug)
chunk_check(stderr, NULL);
return 0;
}
@ -207,7 +205,6 @@ done:
xml_free(xt);
if (fd != -1)
close(fd);
unchunk_group(__FUNCTION__);
return retval;
}

View file

@ -178,15 +178,13 @@ plugin_unload(clicon_handle h,
* @param[in] h Clicon handle
* @param[in] file The plugin (.so) to load
* @param[in] dlflags Arguments to dlopen(3)
* @param[in] label Chunk label
* @retval plugin Plugin struct
* @retval NULL Error
*/
static struct plugin *
plugin_load (clicon_handle h,
char *file,
int dlflags,
const char *label)
int dlflags)
{
char *error;
void *handle;
@ -215,7 +213,7 @@ plugin_load (clicon_handle h,
return NULL;
}
if ((new = chunk(sizeof(*new), label)) == NULL) {
if ((new = malloc(sizeof(*new))) == NULL) {
clicon_err(OE_UNIX, errno, "dhunk: %s", strerror(errno));
dlclose(handle);
return NULL;
@ -319,8 +317,8 @@ plugin_append(struct plugin *p)
{
struct plugin *new;
if ((new = rechunk(plugins, (nplugins+1) * sizeof (*p), NULL)) == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
if ((new = realloc(plugins, (nplugins+1) * sizeof (*p))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
return -1;
}
@ -348,11 +346,11 @@ config_plugin_load_dir(clicon_handle h,
int np = 0;
int ndp;
struct stat st;
char *filename;
struct dirent *dp;
char filename[MAXPATHLEN];
struct dirent *dp = NULL;
struct plugin *new;
struct plugin *p = NULL;
char *master;
char master[MAXPATHLEN];
char *master_plugin;
/* Format master plugin path */
@ -360,50 +358,39 @@ config_plugin_load_dir(clicon_handle h,
clicon_err(OE_PLUGIN, 0, "clicon_master_plugin option not set");
goto quit;
}
master = chunk_sprintf(__FUNCTION__, "%s.so", master_plugin);
if (master == NULL) {
clicon_err(OE_PLUGIN, errno, "chunk_sprintf master plugin");
goto quit;
}
snprintf(master, MAXPATHLEN-1, "%s.so", master_plugin);
/* Allocate plugin group object */
/* Get plugin objects names from plugin directory */
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG, __FUNCTION__))<0)
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG))<0)
goto quit;
/* reset num plugins */
np = 0;
/* Master plugin must be loaded first if it exists. */
filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, master);
if (filename == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
goto quit;
}
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, master);
if (stat(filename, &st) == 0) {
clicon_debug(1, "Loading master plugin '%.*s' ...",
(int)strlen(filename), filename);
new = plugin_load(h, filename, RTLD_NOW|RTLD_GLOBAL, __FUNCTION__);
new = plugin_load(h, filename, RTLD_NOW|RTLD_GLOBAL);
if (new == NULL)
goto quit;
if (plugin_append(new) < 0)
goto quit;
}
/* Now load the rest */
/* Now load the rest. Note plugins is the global variable */
for (i = 0; i < ndp; i++) {
if (strcmp(dp[i].d_name, master) == 0)
continue; /* Skip master now */
filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dp[i].d_name);
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
clicon_debug(1, "Loading plugin '%.*s' ...", (int)strlen(filename), filename);
if (filename == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
goto quit;
}
new = plugin_load (h, filename, RTLD_NOW, __FUNCTION__);
new = plugin_load(h, filename, RTLD_NOW);
if (new == NULL)
goto quit;
/* Append to 'plugins' */
if (plugin_append(new) < 0)
goto quit;
}
@ -413,13 +400,19 @@ config_plugin_load_dir(clicon_handle h,
quit:
if (retval != 0) {
if (p) {
while (--np >= 0)
plugin_unload (h, &p[np]);
unchunk(p);
/* XXX p is always NULL */
if (plugins) {
while (--np >= 0){
if ((p = &plugins[np]) == NULL)
continue;
plugin_unload(h, p);
free(p);
}
free(plugins);
}
}
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}
@ -464,8 +457,10 @@ plugin_finish(clicon_handle h)
p = &plugins[i];
plugin_unload(h, p);
}
if (plugins)
unchunk(plugins);
if (plugins){
free(plugins);
plugins = NULL;
}
nplugins = 0;
return 0;
}

View file

@ -94,17 +94,19 @@ cli_notification_register(clicon_handle h,
void *arg)
{
int retval = -1;
char *logname;
char *logname = NULL;
void *p;
int s;
clicon_hash_t *cdat = clicon_data(h);
size_t len;
int s_exist = -1;
if ((logname = chunk_sprintf(__FUNCTION__, "log_socket_%s", stream)) == NULL){
clicon_err(OE_PLUGIN, errno, "%s: chunk_sprintf", __FUNCTION__);
len = strlen("log_socket_") + strlen(stream) + 1;
if ((logname = malloc(len)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
snprintf(logname, len, "log_socket_%s", stream);
if ((p = hash_value(cdat, logname, &len)) != NULL)
s_exist = *(int*)p;
@ -132,7 +134,8 @@ cli_notification_register(clicon_handle h,
}
retval = 0;
done:
unchunk_group(__FUNCTION__);
if (logname)
free(logname);
return retval;
}

View file

@ -112,21 +112,23 @@ cli_handle_init(void)
return h;
}
/*
* cli_handle_exit
* frees clicon handle
/*! Free clicon handle
*/
int
cli_handle_exit(clicon_handle h)
{
cligen_handle ch = cligen(h);
struct cli_handle *cl = handle(h);
if (cl->cl_stx)
free(cl->cl_stx);
clicon_handle_exit(h); /* frees h and options */
cligen_exit(ch);
return 0;
}
/*----------------------------------------------------------
* cli-specific handle access functions
*----------------------------------------------------------*/

View file

@ -174,7 +174,8 @@ main(int argc, char **argv)
int printgen = 0;
int logclisyntax = 0;
int help = 0;
char *treename;
char *treename = NULL;
int len;
int logdst = CLICON_LOG_STDERR;
char *restarg = NULL; /* what remains after options */
@ -343,8 +344,14 @@ main(int argc, char **argv)
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
goto done;
treename = chunk_sprintf(__FUNCTION__, "datamodel:%s", clicon_dbspec_name(h));
len = strlen("datamodel:") + strlen(clicon_dbspec_name(h)) + 1;
if ((treename = malloc(len)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
snprintf(treename, len, "datamodel:%s", clicon_dbspec_name(h));
cli_tree_add(h, treename, pt);
if (printgen)
cligen_print(stdout, pt, 1);
}
@ -400,9 +407,10 @@ main(int argc, char **argv)
if (!once)
cli_interactive(h);
done:
if (treename)
free(treename);
if (restarg)
free(restarg);
unchunk_group(__FUNCTION__);
// Gets in your face if we log on stderr
clicon_log_init(__PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
clicon_log(LOG_NOTICE, "%s: %u Terminated\n", __PROGRAM__, getpid());

View file

@ -81,8 +81,7 @@
*
*/
/*
* Find syntax mode named 'mode'. Create if specified
/*! Find syntax mode named 'mode'. Create if specified
*/
static cli_syntaxmode_t *
syntax_mode_find(cli_syntax_t *stx, const char *mode, int create)
@ -101,8 +100,8 @@ syntax_mode_find(cli_syntax_t *stx, const char *mode, int create)
if (create == 0)
return NULL;
if ((m = chunk(sizeof(cli_syntaxmode_t), stx->stx_cnklbl)) == NULL) {
perror("chunk");
if ((m = malloc(sizeof(cli_syntaxmode_t))) == NULL) {
perror("malloc");
return NULL;
}
memset (m, 0, sizeof (*m));
@ -205,14 +204,16 @@ syntax_unload(clicon_handle h)
plugin_unload(h, p->cp_handle);
clicon_debug(1, "DEBUG: Plugin '%s' unloaded.", p->cp_name);
DELQ(stx->stx_plugins, stx->stx_plugins, struct cli_plugin *);
if (stx->stx_plugins)
free(stx->stx_plugins);
stx->stx_nplugins--;
}
while (stx->stx_nmodes > 0) {
DELQ(stx->stx_modes, stx->stx_modes, cli_syntaxmode_t *);
if (stx->stx_modes)
free(stx->stx_modes);
stx->stx_nmodes--;
}
unchunk_group(stx->stx_cnklbl);
return 0;
}
@ -265,12 +266,14 @@ clixon_str2fn(char *name,
return NULL;
}
/*
* Load a dynamic plugin object and call it's init-function
/*! Load a dynamic plugin object and call it's init-function
* Note 'file' may be destructively modified
* @retval plugin-handle should be freed after use
*/
static plghndl_t
cli_plugin_load (clicon_handle h, char *file, int dlflags, const char *cnklbl)
cli_plugin_load(clicon_handle h,
char *file,
int dlflags)
{
char *error;
char *name;
@ -292,8 +295,8 @@ cli_plugin_load (clicon_handle h, char *file, int dlflags, const char *cnklbl)
}
}
if ((cp = chunk(sizeof (struct cli_plugin), cnklbl)) == NULL) {
perror("chunk");
if ((cp = malloc(sizeof (struct cli_plugin))) == NULL) {
perror("malloc");
goto quit;
}
memset (cp, 0, sizeof(*cp));
@ -323,7 +326,7 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
parse_tree pt = {0,};
int retval = -1;
FILE *f;
char *filepath;
char filepath[MAXPATHLEN];
cvec *vr = NULL;
char *prompt = NULL;
char **vec = NULL;
@ -331,12 +334,7 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
char *plgnam;
struct cli_plugin *p;
if ((filepath = chunk_sprintf(__FUNCTION__, "%s/%s",
clispec_dir,
filename)) == NULL){
clicon_err(OE_PLUGIN, errno, "chunk");
goto done;
}
snprintf(filepath, MAXPATHLEN-1, "%s/%s", clispec_dir, filename);
if ((vr = cvec_new(0)) == NULL){
clicon_err(OE_PLUGIN, errno, "cvec_new");
goto done;
@ -403,7 +401,6 @@ done:
cvec_free(vr);
if (vec)
free(vec);
unchunk_group(__FUNCTION__);
return retval;
}
@ -415,10 +412,10 @@ cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
{
int i;
int ndp;
struct dirent *dp;
char *file;
struct dirent *dp = NULL;
char *master_plugin;
char *master;
char master[MAXPATHLEN];
char filename[MAXPATHLEN];
struct cli_plugin *cp;
struct stat st;
int retval = -1;
@ -429,24 +426,18 @@ cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
clicon_err(OE_PLUGIN, 0, "clicon_master_plugin option not set");
goto quit;
}
if ((master = chunk_sprintf(__FUNCTION__, "%s.so", master_plugin)) == NULL){
clicon_err(OE_PLUGIN, errno, "chunk_sprintf master plugin");
goto quit;
}
snprintf(master, MAXPATHLEN-1, "%s.so", master_plugin);
/* Get plugin objects names from plugin directory */
ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG, __FUNCTION__);
ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG);
if (ndp < 0)
goto quit;
/* Load master plugin first */
file = chunk_sprintf(__FUNCTION__, "%s/%s", dir, master);
if (file == NULL) {
clicon_err(OE_UNIX, errno, "chunk_sprintf dir");
goto quit;
}
if (stat(file, &st) == 0) {
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, master);
if (stat(filename, &st) == 0) {
clicon_debug(1, "DEBUG: Loading master plugin '%s'", master);
cp = cli_plugin_load(h, file, RTLD_NOW|RTLD_GLOBAL, stx->stx_cnklbl);
cp = cli_plugin_load(h, filename, RTLD_NOW|RTLD_GLOBAL);
if (cp == NULL)
goto quit;
/* Look up certain call-backs in master plugin */
@ -459,33 +450,25 @@ cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
INSQ(cp, stx->stx_plugins);
stx->stx_nplugins++;
}
unchunk (file);
/* Load the rest */
for (i = 0; i < ndp; i++) {
if (strcmp (dp[i].d_name, master) == 0)
continue; /* Skip master now */
file = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dp[i].d_name);
if (file == NULL) {
clicon_err(OE_UNIX, errno, "chunk_sprintf dir");
goto quit;
}
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
clicon_debug(1, "DEBUG: Loading plugin '%s'", dp[i].d_name);
if ((cp = cli_plugin_load (h, file, RTLD_NOW, stx->stx_cnklbl)) == NULL)
if ((cp = cli_plugin_load (h, filename, RTLD_NOW)) == NULL)
goto quit;
INSQ(cp, stx->stx_plugins);
stx->stx_nplugins++;
unchunk (file);
}
if (dp)
unchunk(dp);
retval = 0;
quit:
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}
@ -501,8 +484,7 @@ cli_syntax_load (clicon_handle h)
char *clispec_dir = NULL;
int ndp;
int i;
char *cnklbl = "__CLICON_CLI_SYNTAX_CNK_LABEL__";
struct dirent *dp;
struct dirent *dp = NULL;
cli_syntax_t *stx;
cli_syntaxmode_t *m;
@ -521,13 +503,11 @@ cli_syntax_load (clicon_handle h)
}
/* Allocate plugin group object */
if ((stx = chunk(sizeof(*stx), cnklbl)) == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
if ((stx = malloc(sizeof(*stx))) == NULL) {
clicon_err(OE_UNIX, errno, "malloc");
goto quit;
}
memset (stx, 0, sizeof (*stx)); /* Zero out all */
/* populate name and chunk label */
strncpy (stx->stx_cnklbl, cnklbl, sizeof(stx->stx_cnklbl)-1);
cli_syntax_set(h, stx);
@ -541,7 +521,7 @@ cli_syntax_load (clicon_handle h)
goto quit;
/* load syntaxfiles */
if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG, __FUNCTION__)) < 0)
if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG)) < 0)
goto quit;
/* Load the rest */
for (i = 0; i < ndp; i++) {
@ -550,9 +530,6 @@ cli_syntax_load (clicon_handle h)
if (cli_load_syntax(h, dp[i].d_name, clispec_dir) < 0)
goto quit;
}
if (dp)
unchunk(dp);
/* Did we successfully load any syntax modes? */
if (stx->stx_nmodes <= 0) {
@ -577,10 +554,10 @@ cli_syntax_load (clicon_handle h)
quit:
if (retval != 0) {
syntax_unload(h);
unchunk_group(cnklbl);
cli_syntax_set(h, NULL);
}
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}
@ -663,39 +640,36 @@ clicon_eval(clicon_handle h, char *cmd, cg_obj *match_obj, cvec *vr)
}
/*
* clicon_parse
* Given a command string, parse and evaluate the string according to
/*! Given a command string, parse and evaluate.
* Parse and evaluate the string according to
* the syntax parse tree of the syntax mode specified by *mode.
* If there is no match in the tree for the command, the parse hook
* will be called to see if another mode should be evaluated. If a
* match is found in another mode, the mode variable is updated to point at
* the new mode string.
*
* INPUT:
* cmd The command string
* match_obj Pointer to CLIgen match object
* mode A pointer to the mode string pointer
* OUTPUT:
* kr Keyword vector
* vr Variable vector
* RETURNS:
* -2 : on eof (shouldnt happen)
* -1 : In parse error
* >=0 : Number of matches
* @param[in] h Clicon handle
* @param[in] cmd The command string
* @param[in,out] mode A pointer to the mode string pointer
* @param[out] result -2 On eof (shouldnt happen)
* -1 On parse error
* >=0 Number of matches
*/
int
clicon_parse(clicon_handle h, char *cmd, char **mode, int *result)
clicon_parse(clicon_handle h,
char *cmd,
char **mode,
int *result)
{
char *m, *msav;
int res = -1;
int r;
cli_syntax_t *stx;
cli_syntax_t *stx = NULL;
cli_syntaxmode_t *smode;
char *treename;
parse_tree *pt; /* Orig */
cg_obj *match_obj;
cvec *vr = NULL;
cvec *cvv = NULL;
stx = cli_syntax(h);
m = *mode;
@ -719,11 +693,11 @@ clicon_parse(clicon_handle h, char *cmd, char **mode, int *result)
fprintf(stderr, "No such parse-tree registered: %s\n", treename);
goto done;;
}
if ((vr = cvec_new(0)) == NULL){
fprintf(stderr, "%s: cvec_new: %s\n", __FUNCTION__, strerror(errno));
if ((cvv = cvec_new(0)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_new");
goto done;;
}
res = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, vr);
res = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv);
if (res != CG_MATCH)
pt_expand_cleanup_1(pt);
if (msav){
@ -755,7 +729,7 @@ clicon_parse(clicon_handle h, char *cmd, char **mode, int *result)
*mode = m;
cli_set_syntax_mode(h, m);
}
if ((r = clicon_eval(h, cmd, match_obj, vr)) < 0)
if ((r = clicon_eval(h, cmd, match_obj, cvv)) < 0)
cli_handler_err(stdout);
pt_expand_cleanup_1(pt);
if (result)
@ -769,8 +743,8 @@ clicon_parse(clicon_handle h, char *cmd, char **mode, int *result)
}
}
done:
if (vr)
cvec_free(vr);
if (cvv)
cvec_free(cvv);
return res;
}
@ -891,9 +865,7 @@ cli_set_prompt(clicon_handle h, const char *name, const char *prompt)
return 0;
}
/*
* Format prompt
* XXX: HOST_NAME_MAX from sysconf()
/*! Format prompt
*/
static int
prompt_fmt (char *prompt, size_t plen, char *fmt, ...)
@ -902,65 +874,56 @@ prompt_fmt (char *prompt, size_t plen, char *fmt, ...)
char *s = fmt;
char hname[1024];
char tty[32];
char *new;
char *tmp;
int ret = -1;
cbuf *cb = NULL;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
/* Start with empty string */
if((new = chunk_sprintf(__FUNCTION__, "%s", ""))==NULL)
goto done;
cprintf(cb, "");
while(*s) {
if (*s == '%' && *++s) {
switch(*s) {
case 'H': /* Hostname */
if (gethostname (hname, sizeof (hname)) != 0)
strncpy(hname, "unknown", sizeof(hname)-1);
if((new = chunk_strncat(new, hname, 0, __FUNCTION__))==NULL)
goto done;
cprintf(cb, "%s", hname);
break;
case 'U': /* Username */
tmp = getenv("USER");
if((new = chunk_strncat(new, (tmp ? tmp : "nobody"), 0, __FUNCTION__))==NULL)
goto done;
cprintf(cb, "%s", tmp?tmp:"nobody");
break;
case 'T': /* TTY */
if(ttyname_r(fileno(stdin), tty, sizeof(tty)-1) < 0)
strcpy(tty, "notty");
if((new = chunk_strncat(new, tty, strlen(tty), __FUNCTION__))==NULL)
goto done;
cprintf(cb, "%s", tty);
break;
default:
if((new = chunk_strncat(new, "%", 1, __FUNCTION__))==NULL ||
(new = chunk_strncat(new, s, 1, __FUNCTION__)))
goto done;
cprintf(cb, "%%");
cprintf(cb, "%c", *s);
}
}
else {
if ((new = chunk_strncat(new, s, 1, __FUNCTION__))==NULL)
goto done;
}
else
cprintf(cb, "%c", *s);
s++;
}
done:
if (new)
fmt = new;
if (cb)
fmt = cbuf_get(cb);
va_start(ap, fmt);
ret = vsnprintf(prompt, plen, fmt, ap);
va_end(ap);
unchunk_group(__FUNCTION__);
if (cb)
cbuf_free(cb);
return ret;
}
/*
* Return a formatted prompt string
/*! Return a formatted prompt string
*/
char *
cli_prompt(char *fmt)
@ -1069,11 +1032,10 @@ cli_ptpop(clicon_handle h, char *mode, char *op)
}
/*
* clicon_valcb
/*! Find a cli plugin based on name and resolve a function pointer in it.
* Callback from clicon_dbvars_parse()
* Find a cli plugin based on name if given and
* use dlsym to resolve a function pointer in it.
* Find a cli plugin based on name if given and use dlsym to resolve a
* function pointer in it.
* Call the resolved function to get the cgv populated
*/
int

View file

@ -74,7 +74,6 @@ struct cli_plugin {
/* Plugin group object */
typedef struct {
char stx_cnklbl[128]; /* Plugin group name */
int stx_nplugins; /* Number of plugins */
struct cli_plugin *stx_plugins; /* List of plugins */
int stx_nmodes; /* Number of syntax modes */

View file

@ -105,7 +105,7 @@ plugin_unload(clicon_handle h, void *handle)
* Note 'file' may be destructively modified
*/
static plghndl_t
plugin_load (clicon_handle h, char *file, int dlflags, const char *cnklbl)
plugin_load (clicon_handle h, char *file, int dlflags)
{
char *error;
void *handle = NULL;
@ -141,9 +141,9 @@ netconf_plugin_load(clicon_handle h)
int retval = -1;
char *dir;
int ndp;
struct dirent *dp;
struct dirent *dp = NULL;
int i;
char *filename;
char filename[MAXPATHLEN];
plghndl_t *handle;
if ((dir = clicon_netconf_dir(h)) == NULL){
@ -152,30 +152,26 @@ netconf_plugin_load(clicon_handle h)
}
/* Get plugin objects names from plugin directory */
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG, __FUNCTION__))<0)
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG))<0)
goto quit;
/* Load all plugins */
for (i = 0; i < ndp; i++) {
filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dp[i].d_name);
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
(int)strlen(filename), filename);
if (filename == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
goto quit;
}
if ((handle = plugin_load (h, filename, RTLD_NOW, __FUNCTION__)) == NULL)
goto quit;
if ((plugins = rechunk(plugins, (nplugins+1) * sizeof (*plugins), NULL)) == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
goto quit;
}
plugins[nplugins++] = handle;
unchunk (filename);
}
retval = 0;
quit:
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}
@ -194,8 +190,10 @@ netconf_plugin_unload(clicon_handle h)
}
for (i = 0; i < nplugins; i++)
plugin_unload(h, plugins[i]);
if (plugins)
unchunk(plugins);
if (plugins){
free(plugins);
plugins = NULL;
}
nplugins = 0;
return 0;
}

View file

@ -33,7 +33,6 @@
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -46,6 +45,7 @@
#include <fcgi_stdio.h>
#include <signal.h>
#include <dlfcn.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <curl/curl.h>
@ -175,7 +175,7 @@ str2cvec(char *string,
s++;
cv_name_set(cv, s);
cv_string_set(cv, valu);
free(valu);
curl_free(valu);
}
else{
if (strlen(s)){
@ -278,8 +278,7 @@ static credentials_t *p_credentials = NULL; /* Credentials callback */
static plghndl_t
plugin_load (clicon_handle h,
char *file,
int dlflags,
const char *cnklbl)
int dlflags)
{
char *error;
void *handle = NULL;
@ -319,40 +318,36 @@ restconf_plugin_load(clicon_handle h)
int retval = -1;
char *dir;
int ndp;
struct dirent *dp;
struct dirent *dp = NULL;
int i;
char *filename;
plghndl_t *handle;
char filename[MAXPATHLEN];
if ((dir = clicon_restconf_dir(h)) == NULL){
clicon_err(OE_PLUGIN, 0, "clicon_restconf_dir not defined");
goto quit;
}
/* Get plugin objects names from plugin directory */
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG, __FUNCTION__))<0)
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG))<0)
goto quit;
/* Load all plugins */
for (i = 0; i < ndp; i++) {
filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dp[i].d_name);
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
(int)strlen(filename), filename);
if (filename == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
goto quit;
}
if ((handle = plugin_load (h, filename, RTLD_NOW, __FUNCTION__)) == NULL)
goto quit;
if ((plugins = rechunk(plugins, (nplugins+1) * sizeof (*plugins), NULL)) == NULL) {
clicon_err(OE_UNIX, errno, "chunk");
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
goto quit;
}
plugins[nplugins++] = handle;
unchunk (filename);
}
retval = 0;
quit:
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}
@ -387,8 +382,10 @@ restconf_plugin_unload(clicon_handle h)
for (i = 0; i < nplugins; i++)
plugin_unload(h, plugins[i]);
if (plugins)
unchunk(plugins);
if (plugins){
free(plugins);
plugins = NULL;
}
nplugins = 0;
return 0;
}

View file

@ -58,7 +58,6 @@
#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <curl/curl.h>
#include <libgen.h>
/* cligen */

View file

@ -109,7 +109,6 @@ Mapping netconf error-tag -> status code
#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <curl/curl.h>
/* cligen */
#include <cligen/cligen.h>

View file

@ -73,10 +73,6 @@ CLICON_CLI_DIR libdir/APPNAME/cli
# Location of frontend .cli cligen spec files
CLICON_CLISPEC_DIR libdir/APPNAME/clispec
# Directory where to save configuration commit history (in XML). Snapshots
# are saved chronologically
CLICON_ARCHIVE_DIR localstatedir/APPNAME/archive
# Enabled uses "startup" configuration on boot
CLICON_USE_STARTUP_CONFIG 0
@ -121,6 +117,9 @@ CLICON_BACKEND_PIDFILE localstatedir/APPNAME/APPNAME.pidfile
# Directory where "running", "candidate" and "startup" are placed
CLICON_XMLDB_DIR localstatedir/APPNAME
# XMLDB datastore plugin filename (see datastore/ and clixon_xml_db.[ch])
CLICON_XMLDB_PLUGIN libdir/xmldb/keyvalue.so
# Dont include keys in cvec in cli vars callbacks, ie a & k in 'a <b> k <c>' ignored
# CLICON_CLI_VARONLY 1

30
configure vendored
View file

@ -703,7 +703,6 @@ ac_user_opts='
enable_option_checking
with_cligen
with_qdbm
enable_keycontent
'
ac_precious_vars='build_alias
host_alias
@ -1324,12 +1323,6 @@ if test -n "$ac_init_help"; then
cat <<\_ACEOF
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-keycontent Disable reverse lookup content keys
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
@ -4290,29 +4283,6 @@ else
fi
# Check if extra keys inserted for database lists containing content. Eg A.n.foo = 3
# means A.3 $!a=foo exists
# Check whether --enable-keycontent was given.
if test "${enable_keycontent+set}" = set; then :
enableval=$enable_keycontent;
if test "$enableval" = no; then
ac_enable_keycontent=no
else
ac_enable_keycontent=yes
fi
else
ac_enable_keycontent=yes
fi
if test "$ac_enable_keycontent" = "yes"; then
$as_echo "#define DB_KEYCONTENT 1" >>confdefs.h
fi
ac_config_files="$ac_config_files Makefile lib/Makefile lib/src/Makefile lib/clixon/Makefile apps/Makefile apps/cli/Makefile apps/backend/Makefile apps/netconf/Makefile apps/restconf/Makefile apps/dbctrl/Makefile include/Makefile etc/Makefile etc/clixonrc example/Makefile example/docker/Makefile docker/Makefile docker/cli/Makefile docker/cli/Dockerfile docker/backend/Makefile docker/backend/Dockerfile docker/netconf/Makefile docker/netconf/Dockerfile datastore/Makefile datastore/keyvalue/Makefile doc/Makefile"

View file

@ -159,24 +159,6 @@ AC_CHECK_FUNCS(inet_aton sigaction sigvec strlcpy strsep strndup alphasort versi
# Lives in libfcgi-dev
AC_CHECK_LIB(fcgi, FCGX_Init,, AC_MSG_ERROR([libfcgi-dev missing]))
# Check if extra keys inserted for database lists containing content. Eg A.n.foo = 3
# means A.3 $!a=foo exists
AC_ARG_ENABLE(keycontent, [ --disable-keycontent Disable reverse lookup content keys],[
if test "$enableval" = no; then
ac_enable_keycontent=no
else
ac_enable_keycontent=yes
fi
],[ ac_enable_keycontent=yes])
AH_TEMPLATE([DB_KEYCONTENT],
[ Check if extra keys inserted for database lists containing content.
Eg A.n.foo = 3 means A.3 $!a=foo exists])
if test "$ac_enable_keycontent" = "yes"; then
AC_DEFINE(DB_KEYCONTENT)
fi
AH_BOTTOM([#include <clixon_custom.h>])
AC_OUTPUT(Makefile

View file

@ -55,7 +55,7 @@ INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$
PLUGIN = $(DATASTORE).so
SRC = clixon_keyvalue.c clixon_qdb.c
SRC = clixon_keyvalue.c clixon_qdb.c clixon_chunk.c
OBJS = $(SRC:.c=.o)

View file

@ -119,70 +119,6 @@ static int _running_locked = 0;
static int _candidate_locked = 0;
static int _startup_locked = 0;
/*! Lock database
* @param[in] db Database name
* @param[in] pid process/session-id
*/
static int
db_lock(char *db,
int pid)
{
if (strcmp("running", db) == 0)
_running_locked = pid;
else if (strcmp("candidate", db) == 0)
_candidate_locked = pid;
else if (strcmp("startup", db) == 0)
_startup_locked = pid;
clicon_debug(1, "%s: locked by %u", db, pid);
return 0;
}
/*! Unlock database
* @param[in] db Database name
*/
static int
db_unlock(char *db)
{
if (strcmp("running", db) == 0)
_running_locked = 0;
else if (strcmp("candidate", db) == 0)
_candidate_locked = 0;
else if (strcmp("startup", db) == 0)
_startup_locked = 0;
return 0;
}
/*! Unlock all databases locked by pid (eg process dies)
* @param[in] pid process/session-id
*/
static int
db_unlock_all(int pid)
{
if (_running_locked == pid)
_running_locked = 0;
if (_candidate_locked == pid)
_candidate_locked = 0;
if (_startup_locked == pid)
_startup_locked = 0;
return 0;
}
/*! returns id of locker
* @retval 0 Not locked
* @retval >0 Id of locker
*/
static int
db_islocked(char *db)
{
if (strcmp("running", db) == 0)
return (_running_locked);
else if (strcmp("candidate", db) == 0)
return(_candidate_locked);
else if (strcmp("startup", db) == 0)
return(_startup_locked);
return 0;
}
/*! Translate from symbolic database name to actual filename in file-system
* @param[in] h Clicon handle
* @param[in] db Symbolic database name, eg "candidate", "running"
@ -273,7 +209,7 @@ append_listkeys(cbuf *ckey,
else
cprintf(ckey, "=");
cprintf(ckey, "%s", bodyenc);
free(bodyenc); bodyenc = NULL;
curl_free(bodyenc); bodyenc = NULL;
}
retval = 0;
done:
@ -436,7 +372,7 @@ get(char *dbname,
goto done;
/* Assume body is created at end of function */
}
free(argdec);
curl_free(argdec);
argdec = NULL;
break;
case Y_LIST:
@ -478,7 +414,7 @@ get(char *dbname,
goto done;
}
cprintf(cb, "[%s=%s]", cv_string_get(cvi), argdec);
free(argdec);
curl_free(argdec);
argdec=NULL;
}
if ((xc = xpath_first(x, cbuf_get(cb))) == NULL){
@ -502,7 +438,7 @@ get(char *dbname,
argdec,
keyname) < 0)
goto done;
free(argdec); argdec = NULL;
curl_free(argdec); argdec = NULL;
} /* while */
}
if (cb){
@ -710,7 +646,7 @@ kv_get(clicon_handle h,
int retval = -1;
yang_spec *yspec;
char *dbname = NULL;
cxobj **xvec;
cxobj **xvec = NULL;
size_t xlen;
int i;
int npairs;
@ -885,7 +821,7 @@ put(char *dbname,
if (cbxk)
cbuf_free(cbxk);
if (bodyenc)
free(bodyenc);
curl_free(bodyenc);
return retval;
}
@ -1400,7 +1336,6 @@ kv_put(clicon_handle h,
return retval;
}
/*! Raw dump of database, just keys and values, no xml interpretation
* @param[in] f File
* @param[in] dbfile File-name of database. This is a local file
@ -1477,19 +1412,14 @@ kv_lock(clicon_handle h,
char *db,
int pid)
{
int retval = -1;
if (db_islocked(db)){
if (pid != db_islocked(db)){
clicon_err(OE_DB, 0, "lock failed: locked by %d", db_islocked(db));
goto done;
}
}
else
db_lock(db, pid);
retval = 0;
done:
return retval;
if (strcmp("running", db) == 0)
_running_locked = pid;
else if (strcmp("candidate", db) == 0)
_candidate_locked = pid;
else if (strcmp("startup", db) == 0)
_startup_locked = pid;
clicon_debug(1, "%s: locked by %u", db, pid);
return 0;
}
/*! Unlock database
@ -1498,36 +1428,39 @@ kv_lock(clicon_handle h,
* @param[in] pid Process id
* @retval -1 Error
* @retval 0 OK
* Assume all sanity checks have been made
*/
int
kv_unlock(clicon_handle h,
char *db,
int pid)
{
int retval = -1;
int pid1;
pid1 = db_islocked(db);
if (pid1){
if (pid == pid1)
db_unlock(db);
else{
clicon_err(OE_DB, 0, "unlock failed: locked by %d", pid1);
goto done;
}
}
retval = 0;
done:
return retval;
if (strcmp("running", db) == 0)
_running_locked = 0;
else if (strcmp("candidate", db) == 0)
_candidate_locked = 0;
else if (strcmp("startup", db) == 0)
_startup_locked = 0;
return 0;
}
/*! Unlock all databases locked by pid (eg process dies)
* @param[in] h Clicon handle
* @param[in] pid Process / Session id
* @retval -1 Error
* @retval 0 Ok
*/
int
kv_unlock_all(clicon_handle h,
int pid)
{
return db_unlock_all(pid);
if (_running_locked == pid)
_running_locked = 0;
if (_candidate_locked == pid)
_candidate_locked = 0;
if (_startup_locked == pid)
_startup_locked = 0;
return 0;
}
/*! Check if database is locked
@ -1541,7 +1474,13 @@ int
kv_islocked(clicon_handle h,
char *db)
{
return db_islocked(db);
if (strcmp("running", db) == 0)
return (_running_locked);
else if (strcmp("candidate", db) == 0)
return(_candidate_locked);
else if (strcmp("startup", db) == 0)
return(_startup_locked);
return 0;
}
/*! Check if db exists

View file

@ -743,7 +743,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/config/ ../apps/netconf ../apps/dbctrl
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/config/ ../apps/netconf ../apps/dbctrl ../datastore
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View file

@ -743,7 +743,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/backend/ ../apps/restconf/ ../apps/netconf ../apps/dbctrl
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/backend/ ../apps/restconf/ ../apps/netconf ../apps/dbctrl ../datastore
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View file

@ -12,10 +12,6 @@
/* Clixon version string */
#undef CLIXON_VERSION_STRING
/* Check if extra keys inserted for database lists containing content. Eg
A.n.foo = 3 means A.3 $!a=foo exists */
#undef DB_KEYCONTENT
/* Define to 1 if you have the `alphasort' function. */
#undef HAVE_ALPHASORT

91
lib/clixon/clixon.h Normal file
View file

@ -0,0 +1,91 @@
/* lib/clixon/clixon.h. Generated from clixon.h.in by configure. */
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
This file is part of CLIXON.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the "GPL"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
* Meta-include file that includes all sub-files in control-lib
* Note: this include files is for external purposes. Do not include this
* file in clicon lib-routines.
*/
/* This include file requires the following include file dependencies */
#include <stdio.h>
#include <stdint.h>
#include <dirent.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
/*
* CLIXON version macros
*/
#define CLIXON_VERSION_STRING "3.2.0"
#define CLIXON_VERSION_MAJOR 3
#define CLIXON_VERSION_MINOR 2
#define CLIXON_VERSION_PATCH 0
/*
* Use this constant to disable some prototypes that should not be visible outside the lib.
* This is an alternative to use separate internal include files.
*/
#define LIBCLIXON_API 1
#include <clixon/clixon_sig.h>
#include <clixon/clixon_log.h>
#include <clixon/clixon_err.h>
#include <clixon/clixon_queue.h>
#include <clixon/clixon_hash.h>
#include <clixon/clixon_handle.h>
#include <clixon/clixon_yang.h>
#include <clixon/clixon_yang_type.h>
#include <clixon/clixon_event.h>
#include <clixon/clixon_string.h>
#include <clixon/clixon_file.h>
#include <clixon/clixon_xml.h>
#include <clixon/clixon_proto.h>
#include <clixon/clixon_proto_encode.h>
#include <clixon/clixon_proto_client.h>
#include <clixon/clixon_proc.h>
#include <clixon/clixon_options.h>
#include <clixon/clixon_xml_map.h>
#include <clixon/clixon_xml_db.h>
#include <clixon/clixon_xsl.h>
#include <clixon/clixon_json.h>
#include <clixon/clixon_plugin.h>
#include <clixon/clixon_plugin.h>
/*
* Global variables generated by Makefile
*/
extern const char CLIXON_BUILDSTR[];
extern const char CLIXON_VERSION[];

View file

@ -38,9 +38,7 @@
int clicon_file_dirent(const char *dir, struct dirent **ent,
const char *regexp, mode_t type, const char *label);
char *clicon_tmpfile(const char *label);
const char *regexp, mode_t type);
int clicon_file_copy(char *src, char *target);

View file

@ -92,7 +92,6 @@ char *clicon_cli_dir(clicon_handle h);
char *clicon_clispec_dir(clicon_handle h);
char *clicon_netconf_dir(clicon_handle h);
char *clicon_restconf_dir(clicon_handle h);
char *clicon_archive_dir(clicon_handle h);
char *clicon_xmldb_plugin(clicon_handle h);
int clicon_sock_family(clicon_handle h);
char *clicon_sock(clicon_handle h);

View file

@ -61,8 +61,7 @@ CPPFLAGS = @CPPFLAGS@
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \
clixon_chunk.c clixon_proc.c \
SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c clixon_proc.c \
clixon_string.c clixon_handle.c \
clixon_xml.c clixon_xml_map.c clixon_file.c \
clixon_json.c clixon_yang.c clixon_yang_type.c \

View file

@ -57,7 +57,6 @@
#include "clixon_log.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_err.h"
/*
@ -217,7 +216,7 @@ clicon_err_save(void)
{
struct err_state *es;
if ((es = chunk(sizeof(*es), NULL)) == NULL)
if ((es = malloc(sizeof(*es))) == NULL)
return NULL;
es->es_errno = clicon_errno;
es->es_suberrno = clicon_suberrno;
@ -232,10 +231,11 @@ clicon_err_restore(void* handle)
{
struct err_state *es;
es = (struct err_state *)handle;
if ((es = (struct err_state *)handle) != NULL){
clicon_errno = es->es_errno;
clicon_suberrno = es->es_suberrno;
strncpy(clicon_err_reason, es->es_reason, ERR_STRLEN-1);
unchunk(es);
free(es);
}
return 0;
}

View file

@ -58,7 +58,6 @@
/* clicon */
#include "clixon_err.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_string.h"
#include "clixon_file.h"
@ -66,7 +65,8 @@
* qsort function
*/
static int
clicon_file_dirent_sort(const void* arg1, const void* arg2)
clicon_file_dirent_sort(const void* arg1,
const void* arg2)
{
struct dirent *d1 = (struct dirent *)arg1;
struct dirent *d2 = (struct dirent *)arg2;
@ -81,10 +81,10 @@ clicon_file_dirent_sort(const void* arg1, const void* arg2)
/*! Return sorted matching files from a directory
* @param[in] dir Directory path
* @param[out] ent Entries pointer, will be filled in with dir entries
* @param[out] ent Entries pointer, will be filled in with dir entries. Free
* after use
* @param[in] regexp Regexp filename matching
* @param[in] type File type matching, see stat(2)
* @param[in] label Clicon Chunk label for memory handling, unchunk after use
*
* @retval n Number of matching files in directory
* @retval -1 Error
@ -92,27 +92,26 @@ clicon_file_dirent_sort(const void* arg1, const void* arg2)
* @code
* char *dir = "/root/fs";
* struct dirent *dp;
* if ((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG, __FUNCTION__)) < 0)
* if ((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG)) < 0)
* return -1;
* for (i = 0; i < ndp; i++)
* do something with dp[i].d_name;
* unchunk_group(__FUNCTION__);
* free(dp);
* @endcode
*/
int
clicon_file_dirent(const char *dir,
struct dirent **ent,
const char *regexp,
mode_t type,
const char *label)
mode_t type)
{
DIR *dirp;
int retval = -1;
DIR *dirp;
int res;
int nent;
char *filename;
regex_t re;
char errbuf[128];
char filename[MAXPATHLEN];
struct stat st;
struct dirent dent;
struct dirent *dresp;
@ -120,6 +119,7 @@ clicon_file_dirent(const char *dir,
struct dirent *new = NULL;
struct dirent *dvecp = NULL;
*ent = NULL;
nent = 0;
@ -137,7 +137,9 @@ clicon_file_dirent(const char *dir,
goto quit;
}
for (res = readdir_r (dirp, &dent, &dresp); dresp; res = readdir_r (dirp, &dent, &dresp)) {
for (res = readdir_r (dirp, &dent, &dresp);
dresp;
res = readdir_r (dirp, &dent, &dresp)) {
if (res != 0) {
clicon_err(OE_UNIX, 0, "readdir: %s", strerror(errno));
goto quit;
@ -150,12 +152,8 @@ clicon_file_dirent(const char *dir,
}
/* File type matching */
if (type) {
if ((filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dent.d_name)) == NULL) {
clicon_err(OE_UNIX, 0, "chunk: %s", strerror(errno));
goto quit;
}
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dent.d_name);
res = lstat(filename, &st);
unchunk (filename);
if (res != 0) {
clicon_err(OE_UNIX, 0, "lstat: %s", strerror(errno));
goto quit;
@ -164,8 +162,8 @@ clicon_file_dirent(const char *dir,
continue;
}
if ((tmp = rechunk(new, (nent+1)*sizeof(*dvecp), label)) == NULL) {
clicon_err(OE_UNIX, 0, "chunk: %s", strerror(errno));
if ((tmp = realloc(new, (nent+1)*sizeof(*dvecp))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
goto quit;
}
new = tmp;
@ -183,30 +181,9 @@ quit:
closedir(dirp);
if (regexp)
regfree(&re);
unchunk_group(__FUNCTION__);
return retval;
}
/*
* Use mkstep() to create an empty temporary file, accessible only by this user.
* A chunk:ed file name is returned so that caller can overwrite file safely.
*/
char *
clicon_tmpfile(const char *label)
{
int fd;
char file[] = "/tmp/.tmpXXXXXX";
if ((fd = mkstemp(file)) < 0){
clicon_err(OE_UNIX, errno, "mkstemp");
return NULL;
}
close(fd);
return (char *)chunkdup(file, strlen(file)+1, label);
}
/*! Make a copy of file src
* @retval 0 OK
* @retval -1 Error

View file

@ -61,7 +61,6 @@
#include "clixon_queue.h"
#include "clixon_hash.h"
#include "clixon_handle.h"
#include "clixon_chunk.h"
#include "clixon_log.h"
#include "clixon_yang.h"
#include "clixon_options.h"
@ -198,7 +197,6 @@ clicon_option_default(clicon_hash_t *copt)
}
retval = 0;
catch:
unchunk_group(__FUNCTION__);
return retval;
}
@ -233,10 +231,6 @@ clicon_option_sanity(clicon_hash_t *copt)
clicon_err(OE_UNIX, 0, "CLICON_YANG_DIR not defined in config file");
goto done;
}
if (!hash_lookup(copt, "CLICON_ARCHIVE_DIR")){
clicon_err(OE_UNIX, 0, "CLICON_ARCHIVE_DIR not defined in config file");
goto done;
}
if (!hash_lookup(copt, "CLICON_XMLDB_DIR")){
clicon_err(OE_UNIX, 0, "CLICON_XMLDB_DIR not defined in config file");
goto done;
@ -451,12 +445,6 @@ clicon_restconf_dir(clicon_handle h)
return clicon_option_str(h, "CLICON_RESTCONF_DIR");
}
char *
clicon_archive_dir(clicon_handle h)
{
return clicon_option_str(h, "CLICON_ARCHIVE_DIR");
}
char *
clicon_xmldb_plugin(clicon_handle h)
{

View file

@ -60,7 +60,6 @@
#include "clixon_sig.h"
#include "clixon_string.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_proc.h"
/*

View file

@ -66,7 +66,6 @@
#include "clixon_err.h"
#include "clixon_log.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_sig.h"
#include "clixon_xml.h"
#include "clixon_xsl.h"
@ -532,11 +531,11 @@ send_msg_reply(int s,
uint16_t datalen)
{
int retval = -1;
struct clicon_msg *reply;
struct clicon_msg *reply = NULL;
uint16_t len;
len = sizeof(*reply) + datalen;
if ((reply = (struct clicon_msg *)chunk(len, __FUNCTION__)) == NULL)
if ((reply = (struct clicon_msg *)malloc(len)) == NULL)
goto done;
memset(reply, 0, len);
reply->op_len = htons(len);
@ -546,7 +545,8 @@ send_msg_reply(int s,
goto done;
retval = 0;
done:
unchunk_group(__FUNCTION__);
if (reply)
free(reply);
return retval;
}

View file

@ -56,7 +56,6 @@
/* clicon */
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_log.h"
#include "clixon_hash.h"
#include "clixon_handle.h"

View file

@ -49,7 +49,6 @@
/* clicon */
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_string.h"
#include "clixon_err.h"

View file

@ -51,7 +51,6 @@
#include "clixon_err.h"
#include "clixon_log.h"
#include "clixon_queue.h"
#include "clixon_chunk.h"
#include "clixon_xml.h"
#include "clixon_xml_parse.h"

View file

@ -46,7 +46,6 @@
#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <curl/curl.h>
#include <libgen.h>
/* cligen */
@ -128,14 +127,36 @@ xmldb_get(clicon_handle h, char *db, char *xpath,
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_get_fn &&
_xa_api->xa_get_fn(h, db, xpath, xtop, xvec, xlen) < 0)
if (_xa_api->xa_get_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_get_fn(h, db, xpath, xtop, xvec, xlen);
done:
return retval;
}
/*! Modify database provided an xml tree and an operation
*
* @param[in] h CLICON handle
* @param[in] db running or candidate
* @param[in] xt xml-tree. Top-level symbol is dummy
* @param[in] op OP_MERGE: just add it.
* OP_REPLACE: first delete whole database
* OP_NONE: operation attribute in xml determines operation
* @param[in] api_path According to restconf (Sec 3.5.1.1 in [restconf-draft 13])
* @retval 0 OK
* @retval -1 Error
* The xml may contain the "operation" attribute which defines the operation.
* @code
* cxobj *xt;
* if (clicon_xml_parse_str("<a>17</a>", &xt) < 0)
* err;
* if (xmldb_put(h, "running", OP_MERGE, NULL, xt) < 0)
* err;
* @endcode
* @see xmldb_put_xkey for single key
*/
int
xmldb_put(clicon_handle h, char *db, enum operation_type op,
char *api_path, cxobj *xt)
@ -146,16 +167,24 @@ xmldb_put(clicon_handle h, char *db, enum operation_type op,
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_put_fn &&
_xa_api->xa_put_fn(h, db, op, api_path, xt) < 0)
if (_xa_api->xa_put_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_put_fn(h, db, op, api_path, xt);
done:
return retval;
}
/*! Raw dump of database, in internal format (depends on datastore)
* @param[in] f File
* @param[in] dbfile File-name of database. This is a local file
* @param[in] pattern Key regexp, eg "^.*$"
*/
int
xmldb_dump(FILE *f, char *dbfilename, char *rxkey)
xmldb_dump(FILE *f,
char *dbfilename,
char *pattern)
{
int retval = -1;
@ -163,14 +192,22 @@ xmldb_dump(FILE *f, char *dbfilename, char *rxkey)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_dump_fn &&
_xa_api->xa_dump_fn(f, dbfilename, rxkey) < 0)
if (_xa_api->xa_dump_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_dump_fn(f, dbfilename, pattern);
done:
return retval;
}
/*! Copy database from db1 to db2
* @param[in] h Clicon handle
* @param[in] from Source database copy
* @param[in] to Destination database
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_copy(clicon_handle h, char *from, char *to)
{
@ -180,14 +217,22 @@ xmldb_copy(clicon_handle h, char *from, char *to)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_copy_fn &&
_xa_api->xa_copy_fn(h, from, to) < 0)
if (_xa_api->xa_copy_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_copy_fn(h, from, to);
done:
return retval;
}
/*! Lock database
* @param[in] h Clicon handle
* @param[in] db Database
* @param[in] pid Process id
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_lock(clicon_handle h, char *db, int pid)
{
@ -197,14 +242,23 @@ xmldb_lock(clicon_handle h, char *db, int pid)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_lock_fn &&
_xa_api->xa_lock_fn(h, db, pid) < 0)
if (_xa_api->xa_lock_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_lock_fn(h, db, pid);
done:
return retval;
}
/*! Unlock database
* @param[in] h Clicon handle
* @param[in] db Database
* @param[in] pid Process id
* @retval -1 Error
* @retval 0 OK
* Assume all sanity checks have been made
*/
int
xmldb_unlock(clicon_handle h, char *db, int pid)
{
@ -214,14 +268,21 @@ xmldb_unlock(clicon_handle h, char *db, int pid)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_unlock_fn &&
_xa_api->xa_unlock_fn(h, db, pid) < 0)
if (_xa_api->xa_unlock_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_unlock_fn(h, db, pid);
done:
return retval;
}
/*! Unlock all databases locked by pid (eg process dies)
* @param[in] h Clicon handle
* @param[in] pid Process / Session id
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_unlock_all(clicon_handle h, int pid)
{
@ -231,14 +292,22 @@ xmldb_unlock_all(clicon_handle h, int pid)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_unlock_all_fn &&
_xa_api->xa_unlock_all_fn(h, pid) < 0)
if (_xa_api->xa_unlock_all_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval =_xa_api->xa_unlock_all_fn(h, pid);
done:
return retval;
}
/*! Check if database is locked
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error
* @retval 0 Not locked
* @retval >0 Id of locker
*/
int
xmldb_islocked(clicon_handle h, char *db)
{
@ -248,14 +317,22 @@ xmldb_islocked(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_islocked_fn &&
_xa_api->xa_islocked_fn(h, db) < 0)
if (_xa_api->xa_islocked_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval =_xa_api->xa_islocked_fn(h, db);
done:
return retval;
}
/*! Check if db exists
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error
* @retval 0 No it does not exist
* @retval 1 Yes it exists
*/
int
xmldb_exists(clicon_handle h, char *db)
{
@ -265,14 +342,21 @@ xmldb_exists(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_exists_fn &&
_xa_api->xa_exists_fn(h, db) < 0)
if (_xa_api->xa_exists_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_exists_fn(h, db);
done:
return retval;
}
/*! Delete database. Remove file
* @param[in] h Clicon handle
* @param[in] db Database
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_delete(clicon_handle h, char *db)
{
@ -282,14 +366,21 @@ xmldb_delete(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_delete_fn &&
_xa_api->xa_delete_fn(h, db) < 0)
if (_xa_api->xa_delete_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_delete_fn(h, db);
done:
return retval;
}
/*! Initialize database
* @param[in] h Clicon handle
* @param[in] db Database
* @retval 0 OK
* @retval -1 Error
*/
int
xmldb_init(clicon_handle h, char *db)
{
@ -299,10 +390,11 @@ xmldb_init(clicon_handle h, char *db)
clicon_err(OE_DB, 0, "No xmldb plugin");
goto done;
}
if (_xa_api->xa_init_fn &&
_xa_api->xa_init_fn(h, db) < 0)
if (_xa_api->xa_init_fn == NULL){
clicon_err(OE_DB, 0, "No xmldb function");
goto done;
retval = 0;
}
retval = _xa_api->xa_init_fn(h, db);
done:
return retval;
}

View file

@ -76,7 +76,6 @@
#include "clixon_string.h"
#include "clixon_queue.h"
#include "clixon_hash.h"
#include "clixon_chunk.h"
#include "clixon_handle.h"
#include "clixon_yang.h"
#include "clixon_yang_type.h"
@ -125,8 +124,9 @@ xml2txt(FILE *f, cxobj *x, int level)
{
cxobj *xe = NULL;
int children=0;
char *term;
char *term = NULL;
int retval = -1;
int encr=0;
#ifdef SPECIAL_TREATMENT_OF_NAME
cxobj *xname;
#endif
@ -138,14 +138,16 @@ xml2txt(FILE *f, cxobj *x, int level)
if (xml_type(x) == CX_BODY){
/* Kludge for escaping encrypted passwords */
if (strcmp(xml_name(xml_parent(x)), "encrypted-password")==0)
term = chunk_sprintf(__FUNCTION__, "\"%s\"", xml_value(x));
else
encr++;
term = xml_value(x);
}
else{
fprintf(f, "%*s", 4*level, "");
term = xml_name(x);
}
if (encr)
fprintf(f, "\"%s\";\n", term);
else
fprintf(f, "%s;\n", term);
retval = 0;
goto done;

View file

@ -66,7 +66,6 @@
#include "clixon_file.h"
#include "clixon_yang.h"
#include "clixon_hash.h"
#include "clixon_chunk.h"
#include "clixon_options.h"
#include "clixon_yang_type.h"
#include "clixon_yang_parse.h"
@ -1382,20 +1381,21 @@ yang_parse_file(clicon_handle h,
* @retval 1 Match founbd, Most recent entry returned in fbuf
* @retval 0 No matching entry found
* @retval -1 Error
*/static int
*/
static int
yang_parse_find_match(clicon_handle h,
const char *yang_dir,
const char *module,
cbuf *fbuf)
{
int retval = -1;
struct dirent *dp;
struct dirent *dp = NULL;
int ndp;
cbuf *regex = NULL;
char *regexstr;
if ((regex = cbuf_new()) == NULL){
clicon_err(OE_YANG, errno, "%s: cbuf_new", __FUNCTION__);
clicon_err(OE_YANG, errno, "cbuf_new");
goto done;
}
cprintf(regex, "^%s.*(.yang)$", module);
@ -1403,8 +1403,7 @@ yang_parse_find_match(clicon_handle h,
if ((ndp = clicon_file_dirent(yang_dir,
&dp,
regexstr,
S_IFREG,
__FUNCTION__)) < 0)
S_IFREG)) < 0)
goto done;
/* Entries are sorted, last entry should be most recent date */
if (ndp != 0){
@ -1416,7 +1415,8 @@ yang_parse_find_match(clicon_handle h,
done:
if (regex)
cbuf_free(regex);
unchunk_group(__FUNCTION__);
if (dp)
free(dp);
return retval;
}

View file

@ -63,7 +63,6 @@
#include "clixon_handle.h"
#include "clixon_yang.h"
#include "clixon_hash.h"
#include "clixon_chunk.h"
#include "clixon_options.h"
#include "clixon_yang.h"
#include "clixon_yang_type.h"