Created xmldb plugin api
This commit is contained in:
parent
4169bd8d30
commit
f6b3e95100
39 changed files with 492 additions and 504 deletions
|
|
@ -29,7 +29,9 @@
|
||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** 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_copy_config added as generic cli command
|
||||||
- cli_show_config added as generic cli command
|
- cli_show_config added as generic cli command
|
||||||
|
|
|
||||||
|
|
@ -95,8 +95,6 @@ config_terminate(clicon_handle h)
|
||||||
event_exit();
|
event_exit();
|
||||||
clicon_log_register_callback(NULL, NULL);
|
clicon_log_register_callback(NULL, NULL);
|
||||||
clicon_debug(1, "%s done", __FUNCTION__);
|
clicon_debug(1, "%s done", __FUNCTION__);
|
||||||
if (debug)
|
|
||||||
chunk_check(stderr, NULL);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,7 +205,6 @@ done:
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
unchunk_group(__FUNCTION__);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,15 +178,13 @@ plugin_unload(clicon_handle h,
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] file The plugin (.so) to load
|
* @param[in] file The plugin (.so) to load
|
||||||
* @param[in] dlflags Arguments to dlopen(3)
|
* @param[in] dlflags Arguments to dlopen(3)
|
||||||
* @param[in] label Chunk label
|
|
||||||
* @retval plugin Plugin struct
|
* @retval plugin Plugin struct
|
||||||
* @retval NULL Error
|
* @retval NULL Error
|
||||||
*/
|
*/
|
||||||
static struct plugin *
|
static struct plugin *
|
||||||
plugin_load (clicon_handle h,
|
plugin_load (clicon_handle h,
|
||||||
char *file,
|
char *file,
|
||||||
int dlflags,
|
int dlflags)
|
||||||
const char *label)
|
|
||||||
{
|
{
|
||||||
char *error;
|
char *error;
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
@ -215,7 +213,7 @@ plugin_load (clicon_handle h,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((new = chunk(sizeof(*new), label)) == NULL) {
|
if ((new = malloc(sizeof(*new))) == NULL) {
|
||||||
clicon_err(OE_UNIX, errno, "dhunk: %s", strerror(errno));
|
clicon_err(OE_UNIX, errno, "dhunk: %s", strerror(errno));
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -319,8 +317,8 @@ plugin_append(struct plugin *p)
|
||||||
{
|
{
|
||||||
struct plugin *new;
|
struct plugin *new;
|
||||||
|
|
||||||
if ((new = rechunk(plugins, (nplugins+1) * sizeof (*p), NULL)) == NULL) {
|
if ((new = realloc(plugins, (nplugins+1) * sizeof (*p))) == NULL) {
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
clicon_err(OE_UNIX, errno, "realloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,11 +346,11 @@ config_plugin_load_dir(clicon_handle h,
|
||||||
int np = 0;
|
int np = 0;
|
||||||
int ndp;
|
int ndp;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *filename;
|
char filename[MAXPATHLEN];
|
||||||
struct dirent *dp;
|
struct dirent *dp = NULL;
|
||||||
struct plugin *new;
|
struct plugin *new;
|
||||||
struct plugin *p = NULL;
|
struct plugin *p = NULL;
|
||||||
char *master;
|
char master[MAXPATHLEN];
|
||||||
char *master_plugin;
|
char *master_plugin;
|
||||||
|
|
||||||
/* Format master plugin path */
|
/* 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");
|
clicon_err(OE_PLUGIN, 0, "clicon_master_plugin option not set");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
master = chunk_sprintf(__FUNCTION__, "%s.so", master_plugin);
|
snprintf(master, MAXPATHLEN-1, "%s.so", master_plugin);
|
||||||
if (master == NULL) {
|
|
||||||
clicon_err(OE_PLUGIN, errno, "chunk_sprintf master plugin");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate plugin group object */
|
/* Allocate plugin group object */
|
||||||
/* Get plugin objects names from plugin directory */
|
/* 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;
|
goto quit;
|
||||||
|
|
||||||
/* reset num plugins */
|
/* reset num plugins */
|
||||||
np = 0;
|
np = 0;
|
||||||
|
|
||||||
/* Master plugin must be loaded first if it exists. */
|
/* Master plugin must be loaded first if it exists. */
|
||||||
filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, master);
|
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, master);
|
||||||
if (filename == NULL) {
|
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
if (stat(filename, &st) == 0) {
|
if (stat(filename, &st) == 0) {
|
||||||
clicon_debug(1, "Loading master plugin '%.*s' ...",
|
clicon_debug(1, "Loading master plugin '%.*s' ...",
|
||||||
(int)strlen(filename), filename);
|
(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)
|
if (new == NULL)
|
||||||
goto quit;
|
goto quit;
|
||||||
if (plugin_append(new) < 0)
|
if (plugin_append(new) < 0)
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now load the rest */
|
/* Now load the rest. Note plugins is the global variable */
|
||||||
for (i = 0; i < ndp; i++) {
|
for (i = 0; i < ndp; i++) {
|
||||||
if (strcmp(dp[i].d_name, master) == 0)
|
if (strcmp(dp[i].d_name, master) == 0)
|
||||||
continue; /* Skip master now */
|
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);
|
clicon_debug(1, "Loading plugin '%.*s' ...", (int)strlen(filename), filename);
|
||||||
if (filename == NULL) {
|
new = plugin_load(h, filename, RTLD_NOW);
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
new = plugin_load (h, filename, RTLD_NOW, __FUNCTION__);
|
|
||||||
if (new == NULL)
|
if (new == NULL)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
/* Append to 'plugins' */
|
||||||
if (plugin_append(new) < 0)
|
if (plugin_append(new) < 0)
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
@ -413,13 +400,19 @@ config_plugin_load_dir(clicon_handle h,
|
||||||
|
|
||||||
quit:
|
quit:
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
if (p) {
|
/* XXX p is always NULL */
|
||||||
while (--np >= 0)
|
if (plugins) {
|
||||||
plugin_unload (h, &p[np]);
|
while (--np >= 0){
|
||||||
unchunk(p);
|
if ((p = &plugins[np]) == NULL)
|
||||||
|
continue;
|
||||||
|
plugin_unload(h, p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
free(plugins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unchunk_group(__FUNCTION__);
|
if (dp)
|
||||||
|
free(dp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,8 +457,10 @@ plugin_finish(clicon_handle h)
|
||||||
p = &plugins[i];
|
p = &plugins[i];
|
||||||
plugin_unload(h, p);
|
plugin_unload(h, p);
|
||||||
}
|
}
|
||||||
if (plugins)
|
if (plugins){
|
||||||
unchunk(plugins);
|
free(plugins);
|
||||||
|
plugins = NULL;
|
||||||
|
}
|
||||||
nplugins = 0;
|
nplugins = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,17 +94,19 @@ cli_notification_register(clicon_handle h,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *logname;
|
char *logname = NULL;
|
||||||
void *p;
|
void *p;
|
||||||
int s;
|
int s;
|
||||||
clicon_hash_t *cdat = clicon_data(h);
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
size_t len;
|
size_t len;
|
||||||
int s_exist = -1;
|
int s_exist = -1;
|
||||||
|
|
||||||
if ((logname = chunk_sprintf(__FUNCTION__, "log_socket_%s", stream)) == NULL){
|
len = strlen("log_socket_") + strlen(stream) + 1;
|
||||||
clicon_err(OE_PLUGIN, errno, "%s: chunk_sprintf", __FUNCTION__);
|
if ((logname = malloc(len)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "malloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
snprintf(logname, len, "log_socket_%s", stream);
|
||||||
if ((p = hash_value(cdat, logname, &len)) != NULL)
|
if ((p = hash_value(cdat, logname, &len)) != NULL)
|
||||||
s_exist = *(int*)p;
|
s_exist = *(int*)p;
|
||||||
|
|
||||||
|
|
@ -132,7 +134,8 @@ cli_notification_register(clicon_handle h,
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
unchunk_group(__FUNCTION__);
|
if (logname)
|
||||||
|
free(logname);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,21 +112,23 @@ cli_handle_init(void)
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*! Free clicon handle
|
||||||
* cli_handle_exit
|
|
||||||
* frees clicon handle
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cli_handle_exit(clicon_handle h)
|
cli_handle_exit(clicon_handle h)
|
||||||
{
|
{
|
||||||
cligen_handle ch = cligen(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 */
|
clicon_handle_exit(h); /* frees h and options */
|
||||||
|
|
||||||
cligen_exit(ch);
|
cligen_exit(ch);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------
|
/*----------------------------------------------------------
|
||||||
* cli-specific handle access functions
|
* cli-specific handle access functions
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,8 @@ main(int argc, char **argv)
|
||||||
int printgen = 0;
|
int printgen = 0;
|
||||||
int logclisyntax = 0;
|
int logclisyntax = 0;
|
||||||
int help = 0;
|
int help = 0;
|
||||||
char *treename;
|
char *treename = NULL;
|
||||||
|
int len;
|
||||||
int logdst = CLICON_LOG_STDERR;
|
int logdst = CLICON_LOG_STDERR;
|
||||||
char *restarg = NULL; /* what remains after options */
|
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)
|
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
|
||||||
goto done;
|
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);
|
cli_tree_add(h, treename, pt);
|
||||||
|
|
||||||
if (printgen)
|
if (printgen)
|
||||||
cligen_print(stdout, pt, 1);
|
cligen_print(stdout, pt, 1);
|
||||||
}
|
}
|
||||||
|
|
@ -400,9 +407,10 @@ main(int argc, char **argv)
|
||||||
if (!once)
|
if (!once)
|
||||||
cli_interactive(h);
|
cli_interactive(h);
|
||||||
done:
|
done:
|
||||||
|
if (treename)
|
||||||
|
free(treename);
|
||||||
if (restarg)
|
if (restarg)
|
||||||
free(restarg);
|
free(restarg);
|
||||||
unchunk_group(__FUNCTION__);
|
|
||||||
// Gets in your face if we log on stderr
|
// Gets in your face if we log on stderr
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
|
clicon_log_init(__PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
|
||||||
clicon_log(LOG_NOTICE, "%s: %u Terminated\n", __PROGRAM__, getpid());
|
clicon_log(LOG_NOTICE, "%s: %u Terminated\n", __PROGRAM__, getpid());
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*! Find syntax mode named 'mode'. Create if specified
|
||||||
* Find syntax mode named 'mode'. Create if specified
|
|
||||||
*/
|
*/
|
||||||
static cli_syntaxmode_t *
|
static cli_syntaxmode_t *
|
||||||
syntax_mode_find(cli_syntax_t *stx, const char *mode, int create)
|
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)
|
if (create == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((m = chunk(sizeof(cli_syntaxmode_t), stx->stx_cnklbl)) == NULL) {
|
if ((m = malloc(sizeof(cli_syntaxmode_t))) == NULL) {
|
||||||
perror("chunk");
|
perror("malloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset (m, 0, sizeof (*m));
|
memset (m, 0, sizeof (*m));
|
||||||
|
|
@ -195,7 +194,7 @@ static int
|
||||||
syntax_unload(clicon_handle h)
|
syntax_unload(clicon_handle h)
|
||||||
{
|
{
|
||||||
struct cli_plugin *p;
|
struct cli_plugin *p;
|
||||||
cli_syntax_t *stx = cli_syntax(h);
|
cli_syntax_t *stx = cli_syntax(h);
|
||||||
|
|
||||||
if (stx == NULL)
|
if (stx == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -205,14 +204,16 @@ syntax_unload(clicon_handle h)
|
||||||
plugin_unload(h, p->cp_handle);
|
plugin_unload(h, p->cp_handle);
|
||||||
clicon_debug(1, "DEBUG: Plugin '%s' unloaded.", p->cp_name);
|
clicon_debug(1, "DEBUG: Plugin '%s' unloaded.", p->cp_name);
|
||||||
DELQ(stx->stx_plugins, stx->stx_plugins, struct cli_plugin *);
|
DELQ(stx->stx_plugins, stx->stx_plugins, struct cli_plugin *);
|
||||||
|
if (stx->stx_plugins)
|
||||||
|
free(stx->stx_plugins);
|
||||||
stx->stx_nplugins--;
|
stx->stx_nplugins--;
|
||||||
}
|
}
|
||||||
while (stx->stx_nmodes > 0) {
|
while (stx->stx_nmodes > 0) {
|
||||||
DELQ(stx->stx_modes, stx->stx_modes, cli_syntaxmode_t *);
|
DELQ(stx->stx_modes, stx->stx_modes, cli_syntaxmode_t *);
|
||||||
|
if (stx->stx_modes)
|
||||||
|
free(stx->stx_modes);
|
||||||
stx->stx_nmodes--;
|
stx->stx_nmodes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
unchunk_group(stx->stx_cnklbl);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,12 +266,14 @@ clixon_str2fn(char *name,
|
||||||
return NULL;
|
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
|
* Note 'file' may be destructively modified
|
||||||
|
* @retval plugin-handle should be freed after use
|
||||||
*/
|
*/
|
||||||
static plghndl_t
|
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 *error;
|
||||||
char *name;
|
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) {
|
if ((cp = malloc(sizeof (struct cli_plugin))) == NULL) {
|
||||||
perror("chunk");
|
perror("malloc");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
memset (cp, 0, sizeof(*cp));
|
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,};
|
parse_tree pt = {0,};
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *filepath;
|
char filepath[MAXPATHLEN];
|
||||||
cvec *vr = NULL;
|
cvec *vr = NULL;
|
||||||
char *prompt = NULL;
|
char *prompt = NULL;
|
||||||
char **vec = NULL;
|
char **vec = NULL;
|
||||||
|
|
@ -331,12 +334,7 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
|
||||||
char *plgnam;
|
char *plgnam;
|
||||||
struct cli_plugin *p;
|
struct cli_plugin *p;
|
||||||
|
|
||||||
if ((filepath = chunk_sprintf(__FUNCTION__, "%s/%s",
|
snprintf(filepath, MAXPATHLEN-1, "%s/%s", clispec_dir, filename);
|
||||||
clispec_dir,
|
|
||||||
filename)) == NULL){
|
|
||||||
clicon_err(OE_PLUGIN, errno, "chunk");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((vr = cvec_new(0)) == NULL){
|
if ((vr = cvec_new(0)) == NULL){
|
||||||
clicon_err(OE_PLUGIN, errno, "cvec_new");
|
clicon_err(OE_PLUGIN, errno, "cvec_new");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -403,7 +401,6 @@ done:
|
||||||
cvec_free(vr);
|
cvec_free(vr);
|
||||||
if (vec)
|
if (vec)
|
||||||
free(vec);
|
free(vec);
|
||||||
unchunk_group(__FUNCTION__);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -415,10 +412,10 @@ cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ndp;
|
int ndp;
|
||||||
struct dirent *dp;
|
struct dirent *dp = NULL;
|
||||||
char *file;
|
|
||||||
char *master_plugin;
|
char *master_plugin;
|
||||||
char *master;
|
char master[MAXPATHLEN];
|
||||||
|
char filename[MAXPATHLEN];
|
||||||
struct cli_plugin *cp;
|
struct cli_plugin *cp;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int retval = -1;
|
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");
|
clicon_err(OE_PLUGIN, 0, "clicon_master_plugin option not set");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
if ((master = chunk_sprintf(__FUNCTION__, "%s.so", master_plugin)) == NULL){
|
snprintf(master, MAXPATHLEN-1, "%s.so", master_plugin);
|
||||||
clicon_err(OE_PLUGIN, errno, "chunk_sprintf master plugin");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
/* Get plugin objects names from plugin directory */
|
/* 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)
|
if (ndp < 0)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
/* Load master plugin first */
|
/* Load master plugin first */
|
||||||
file = chunk_sprintf(__FUNCTION__, "%s/%s", dir, master);
|
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, master);
|
||||||
if (file == NULL) {
|
if (stat(filename, &st) == 0) {
|
||||||
clicon_err(OE_UNIX, errno, "chunk_sprintf dir");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
if (stat(file, &st) == 0) {
|
|
||||||
clicon_debug(1, "DEBUG: Loading master plugin '%s'", master);
|
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)
|
if (cp == NULL)
|
||||||
goto quit;
|
goto quit;
|
||||||
/* Look up certain call-backs in master plugin */
|
/* 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);
|
INSQ(cp, stx->stx_plugins);
|
||||||
stx->stx_nplugins++;
|
stx->stx_nplugins++;
|
||||||
}
|
}
|
||||||
unchunk (file);
|
|
||||||
|
|
||||||
/* Load the rest */
|
/* Load the rest */
|
||||||
for (i = 0; i < ndp; i++) {
|
for (i = 0; i < ndp; i++) {
|
||||||
if (strcmp (dp[i].d_name, master) == 0)
|
if (strcmp (dp[i].d_name, master) == 0)
|
||||||
continue; /* Skip master now */
|
continue; /* Skip master now */
|
||||||
file = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dp[i].d_name);
|
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
|
||||||
if (file == NULL) {
|
|
||||||
clicon_err(OE_UNIX, errno, "chunk_sprintf dir");
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
clicon_debug(1, "DEBUG: Loading plugin '%s'", 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;
|
goto quit;
|
||||||
INSQ(cp, stx->stx_plugins);
|
INSQ(cp, stx->stx_plugins);
|
||||||
stx->stx_nplugins++;
|
stx->stx_nplugins++;
|
||||||
unchunk (file);
|
|
||||||
}
|
}
|
||||||
if (dp)
|
|
||||||
unchunk(dp);
|
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
quit:
|
quit:
|
||||||
unchunk_group(__FUNCTION__);
|
if (dp)
|
||||||
|
free(dp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -501,8 +484,7 @@ cli_syntax_load (clicon_handle h)
|
||||||
char *clispec_dir = NULL;
|
char *clispec_dir = NULL;
|
||||||
int ndp;
|
int ndp;
|
||||||
int i;
|
int i;
|
||||||
char *cnklbl = "__CLICON_CLI_SYNTAX_CNK_LABEL__";
|
struct dirent *dp = NULL;
|
||||||
struct dirent *dp;
|
|
||||||
cli_syntax_t *stx;
|
cli_syntax_t *stx;
|
||||||
cli_syntaxmode_t *m;
|
cli_syntaxmode_t *m;
|
||||||
|
|
||||||
|
|
@ -521,13 +503,11 @@ cli_syntax_load (clicon_handle h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate plugin group object */
|
/* Allocate plugin group object */
|
||||||
if ((stx = chunk(sizeof(*stx), cnklbl)) == NULL) {
|
if ((stx = malloc(sizeof(*stx))) == NULL) {
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
clicon_err(OE_UNIX, errno, "malloc");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
memset (stx, 0, sizeof (*stx)); /* Zero out all */
|
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);
|
cli_syntax_set(h, stx);
|
||||||
|
|
||||||
|
|
@ -541,7 +521,7 @@ cli_syntax_load (clicon_handle h)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
/* load syntaxfiles */
|
/* 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;
|
goto quit;
|
||||||
/* Load the rest */
|
/* Load the rest */
|
||||||
for (i = 0; i < ndp; i++) {
|
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)
|
if (cli_load_syntax(h, dp[i].d_name, clispec_dir) < 0)
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
if (dp)
|
|
||||||
unchunk(dp);
|
|
||||||
|
|
||||||
|
|
||||||
/* Did we successfully load any syntax modes? */
|
/* Did we successfully load any syntax modes? */
|
||||||
if (stx->stx_nmodes <= 0) {
|
if (stx->stx_nmodes <= 0) {
|
||||||
|
|
@ -577,10 +554,10 @@ cli_syntax_load (clicon_handle h)
|
||||||
quit:
|
quit:
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
syntax_unload(h);
|
syntax_unload(h);
|
||||||
unchunk_group(cnklbl);
|
|
||||||
cli_syntax_set(h, NULL);
|
cli_syntax_set(h, NULL);
|
||||||
}
|
}
|
||||||
unchunk_group(__FUNCTION__);
|
if (dp)
|
||||||
|
free(dp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -663,39 +640,36 @@ clicon_eval(clicon_handle h, char *cmd, cg_obj *match_obj, cvec *vr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*! Given a command string, parse and evaluate.
|
||||||
* clicon_parse
|
* Parse and evaluate the string according to
|
||||||
* Given a command string, parse and evaluate the string according to
|
|
||||||
* the syntax parse tree of the syntax mode specified by *mode.
|
* 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
|
* 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
|
* 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
|
* match is found in another mode, the mode variable is updated to point at
|
||||||
* the new mode string.
|
* the new mode string.
|
||||||
*
|
*
|
||||||
* INPUT:
|
* @param[in] h Clicon handle
|
||||||
* cmd The command string
|
* @param[in] cmd The command string
|
||||||
* match_obj Pointer to CLIgen match object
|
* @param[in,out] mode A pointer to the mode string pointer
|
||||||
* mode A pointer to the mode string pointer
|
* @param[out] result -2 On eof (shouldnt happen)
|
||||||
* OUTPUT:
|
* -1 On parse error
|
||||||
* kr Keyword vector
|
* >=0 Number of matches
|
||||||
* vr Variable vector
|
|
||||||
* RETURNS:
|
|
||||||
* -2 : on eof (shouldnt happen)
|
|
||||||
* -1 : In parse error
|
|
||||||
* >=0 : Number of matches
|
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
char *m, *msav;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int r;
|
int r;
|
||||||
cli_syntax_t *stx;
|
cli_syntax_t *stx = NULL;
|
||||||
cli_syntaxmode_t *smode;
|
cli_syntaxmode_t *smode;
|
||||||
char *treename;
|
char *treename;
|
||||||
parse_tree *pt; /* Orig */
|
parse_tree *pt; /* Orig */
|
||||||
cg_obj *match_obj;
|
cg_obj *match_obj;
|
||||||
cvec *vr = NULL;
|
cvec *cvv = NULL;
|
||||||
|
|
||||||
stx = cli_syntax(h);
|
stx = cli_syntax(h);
|
||||||
m = *mode;
|
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);
|
fprintf(stderr, "No such parse-tree registered: %s\n", treename);
|
||||||
goto done;;
|
goto done;;
|
||||||
}
|
}
|
||||||
if ((vr = cvec_new(0)) == NULL){
|
if ((cvv = cvec_new(0)) == NULL){
|
||||||
fprintf(stderr, "%s: cvec_new: %s\n", __FUNCTION__, strerror(errno));
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
goto done;;
|
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)
|
if (res != CG_MATCH)
|
||||||
pt_expand_cleanup_1(pt);
|
pt_expand_cleanup_1(pt);
|
||||||
if (msav){
|
if (msav){
|
||||||
|
|
@ -755,7 +729,7 @@ clicon_parse(clicon_handle h, char *cmd, char **mode, int *result)
|
||||||
*mode = m;
|
*mode = m;
|
||||||
cli_set_syntax_mode(h, 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);
|
cli_handler_err(stdout);
|
||||||
pt_expand_cleanup_1(pt);
|
pt_expand_cleanup_1(pt);
|
||||||
if (result)
|
if (result)
|
||||||
|
|
@ -769,8 +743,8 @@ clicon_parse(clicon_handle h, char *cmd, char **mode, int *result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
if (vr)
|
if (cvv)
|
||||||
cvec_free(vr);
|
cvec_free(cvv);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -891,9 +865,7 @@ cli_set_prompt(clicon_handle h, const char *name, const char *prompt)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*! Format prompt
|
||||||
* Format prompt
|
|
||||||
* XXX: HOST_NAME_MAX from sysconf()
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
prompt_fmt (char *prompt, size_t plen, char *fmt, ...)
|
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 *s = fmt;
|
||||||
char hname[1024];
|
char hname[1024];
|
||||||
char tty[32];
|
char tty[32];
|
||||||
char *new;
|
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Start with empty string */
|
/* Start with empty string */
|
||||||
if((new = chunk_sprintf(__FUNCTION__, "%s", ""))==NULL)
|
cprintf(cb, "");
|
||||||
goto done;
|
|
||||||
|
|
||||||
while(*s) {
|
while(*s) {
|
||||||
if (*s == '%' && *++s) {
|
if (*s == '%' && *++s) {
|
||||||
switch(*s) {
|
switch(*s) {
|
||||||
|
|
||||||
case 'H': /* Hostname */
|
case 'H': /* Hostname */
|
||||||
if (gethostname (hname, sizeof (hname)) != 0)
|
if (gethostname (hname, sizeof (hname)) != 0)
|
||||||
strncpy(hname, "unknown", sizeof(hname)-1);
|
strncpy(hname, "unknown", sizeof(hname)-1);
|
||||||
if((new = chunk_strncat(new, hname, 0, __FUNCTION__))==NULL)
|
cprintf(cb, "%s", hname);
|
||||||
goto done;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U': /* Username */
|
case 'U': /* Username */
|
||||||
tmp = getenv("USER");
|
tmp = getenv("USER");
|
||||||
if((new = chunk_strncat(new, (tmp ? tmp : "nobody"), 0, __FUNCTION__))==NULL)
|
cprintf(cb, "%s", tmp?tmp:"nobody");
|
||||||
goto done;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T': /* TTY */
|
case 'T': /* TTY */
|
||||||
if(ttyname_r(fileno(stdin), tty, sizeof(tty)-1) < 0)
|
if(ttyname_r(fileno(stdin), tty, sizeof(tty)-1) < 0)
|
||||||
strcpy(tty, "notty");
|
strcpy(tty, "notty");
|
||||||
if((new = chunk_strncat(new, tty, strlen(tty), __FUNCTION__))==NULL)
|
cprintf(cb, "%s", tty);
|
||||||
goto done;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if((new = chunk_strncat(new, "%", 1, __FUNCTION__))==NULL ||
|
cprintf(cb, "%%");
|
||||||
(new = chunk_strncat(new, s, 1, __FUNCTION__)))
|
cprintf(cb, "%c", *s);
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if ((new = chunk_strncat(new, s, 1, __FUNCTION__))==NULL)
|
cprintf(cb, "%c", *s);
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (new)
|
if (cb)
|
||||||
fmt = new;
|
fmt = cbuf_get(cb);
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
ret = vsnprintf(prompt, plen, fmt, ap);
|
ret = vsnprintf(prompt, plen, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
if (cb)
|
||||||
unchunk_group(__FUNCTION__);
|
cbuf_free(cb);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*! Return a formatted prompt string
|
||||||
* Return a formatted prompt string
|
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
cli_prompt(char *fmt)
|
cli_prompt(char *fmt)
|
||||||
|
|
@ -1069,11 +1032,10 @@ cli_ptpop(clicon_handle h, char *mode, char *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*! Find a cli plugin based on name and resolve a function pointer in it.
|
||||||
* clicon_valcb
|
|
||||||
* Callback from clicon_dbvars_parse()
|
* Callback from clicon_dbvars_parse()
|
||||||
* Find a cli plugin based on name if given and
|
* Find a cli plugin based on name if given and use dlsym to resolve a
|
||||||
* use dlsym to resolve a function pointer in it.
|
* function pointer in it.
|
||||||
* Call the resolved function to get the cgv populated
|
* Call the resolved function to get the cgv populated
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ struct cli_plugin {
|
||||||
|
|
||||||
/* Plugin group object */
|
/* Plugin group object */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char stx_cnklbl[128]; /* Plugin group name */
|
|
||||||
int stx_nplugins; /* Number of plugins */
|
int stx_nplugins; /* Number of plugins */
|
||||||
struct cli_plugin *stx_plugins; /* List of plugins */
|
struct cli_plugin *stx_plugins; /* List of plugins */
|
||||||
int stx_nmodes; /* Number of syntax modes */
|
int stx_nmodes; /* Number of syntax modes */
|
||||||
|
|
|
||||||
|
|
@ -213,15 +213,15 @@ expand_dir(char *dir,
|
||||||
mode_t flags,
|
mode_t flags,
|
||||||
int detail)
|
int detail)
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *str;
|
char *str;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
int len;
|
int len;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
char filename[MAXPATHLEN];
|
char filename[MAXPATHLEN];
|
||||||
|
|
||||||
if ((dirp = opendir(dir)) == 0){
|
if ((dirp = opendir(dir)) == 0){
|
||||||
fprintf(stderr, "expand_dir: opendir(%s) %s\n",
|
fprintf(stderr, "expand_dir: opendir(%s) %s\n",
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ plugin_unload(clicon_handle h, void *handle)
|
||||||
* Note 'file' may be destructively modified
|
* Note 'file' may be destructively modified
|
||||||
*/
|
*/
|
||||||
static plghndl_t
|
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;
|
char *error;
|
||||||
void *handle = NULL;
|
void *handle = NULL;
|
||||||
|
|
@ -141,9 +141,9 @@ netconf_plugin_load(clicon_handle h)
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *dir;
|
char *dir;
|
||||||
int ndp;
|
int ndp;
|
||||||
struct dirent *dp;
|
struct dirent *dp = NULL;
|
||||||
int i;
|
int i;
|
||||||
char *filename;
|
char filename[MAXPATHLEN];
|
||||||
plghndl_t *handle;
|
plghndl_t *handle;
|
||||||
|
|
||||||
if ((dir = clicon_netconf_dir(h)) == NULL){
|
if ((dir = clicon_netconf_dir(h)) == NULL){
|
||||||
|
|
@ -152,30 +152,26 @@ netconf_plugin_load(clicon_handle h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get plugin objects names from plugin directory */
|
/* 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;
|
goto quit;
|
||||||
|
|
||||||
/* Load all plugins */
|
/* Load all plugins */
|
||||||
for (i = 0; i < ndp; i++) {
|
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' ...",
|
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
|
||||||
(int)strlen(filename), filename);
|
(int)strlen(filename), filename);
|
||||||
if (filename == NULL) {
|
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
|
||||||
if ((handle = plugin_load (h, filename, RTLD_NOW, __FUNCTION__)) == NULL)
|
clicon_err(OE_UNIX, errno, "realloc");
|
||||||
goto quit;
|
|
||||||
if ((plugins = rechunk(plugins, (nplugins+1) * sizeof (*plugins), NULL)) == NULL) {
|
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
plugins[nplugins++] = handle;
|
plugins[nplugins++] = handle;
|
||||||
unchunk (filename);
|
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
quit:
|
quit:
|
||||||
unchunk_group(__FUNCTION__);
|
if (dp)
|
||||||
|
free(dp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,8 +190,10 @@ netconf_plugin_unload(clicon_handle h)
|
||||||
}
|
}
|
||||||
for (i = 0; i < nplugins; i++)
|
for (i = 0; i < nplugins; i++)
|
||||||
plugin_unload(h, plugins[i]);
|
plugin_unload(h, plugins[i]);
|
||||||
if (plugins)
|
if (plugins){
|
||||||
unchunk(plugins);
|
free(plugins);
|
||||||
|
plugins = NULL;
|
||||||
|
}
|
||||||
nplugins = 0;
|
nplugins = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -46,6 +45,7 @@
|
||||||
#include <fcgi_stdio.h>
|
#include <fcgi_stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
@ -175,7 +175,7 @@ str2cvec(char *string,
|
||||||
s++;
|
s++;
|
||||||
cv_name_set(cv, s);
|
cv_name_set(cv, s);
|
||||||
cv_string_set(cv, valu);
|
cv_string_set(cv, valu);
|
||||||
free(valu);
|
curl_free(valu);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (strlen(s)){
|
if (strlen(s)){
|
||||||
|
|
@ -278,8 +278,7 @@ static credentials_t *p_credentials = NULL; /* Credentials callback */
|
||||||
static plghndl_t
|
static plghndl_t
|
||||||
plugin_load (clicon_handle h,
|
plugin_load (clicon_handle h,
|
||||||
char *file,
|
char *file,
|
||||||
int dlflags,
|
int dlflags)
|
||||||
const char *cnklbl)
|
|
||||||
{
|
{
|
||||||
char *error;
|
char *error;
|
||||||
void *handle = NULL;
|
void *handle = NULL;
|
||||||
|
|
@ -319,40 +318,36 @@ restconf_plugin_load(clicon_handle h)
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *dir;
|
char *dir;
|
||||||
int ndp;
|
int ndp;
|
||||||
struct dirent *dp;
|
struct dirent *dp = NULL;
|
||||||
int i;
|
int i;
|
||||||
char *filename;
|
|
||||||
plghndl_t *handle;
|
plghndl_t *handle;
|
||||||
|
char filename[MAXPATHLEN];
|
||||||
|
|
||||||
if ((dir = clicon_restconf_dir(h)) == NULL){
|
if ((dir = clicon_restconf_dir(h)) == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "clicon_restconf_dir not defined");
|
clicon_err(OE_PLUGIN, 0, "clicon_restconf_dir not defined");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
/* Get plugin objects names from plugin directory */
|
/* 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;
|
goto quit;
|
||||||
|
|
||||||
/* Load all plugins */
|
/* Load all plugins */
|
||||||
for (i = 0; i < ndp; i++) {
|
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' ...",
|
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
|
||||||
(int)strlen(filename), filename);
|
(int)strlen(filename), filename);
|
||||||
if (filename == NULL) {
|
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
|
||||||
if ((handle = plugin_load (h, filename, RTLD_NOW, __FUNCTION__)) == NULL)
|
clicon_err(OE_UNIX, errno, "realloc");
|
||||||
goto quit;
|
|
||||||
if ((plugins = rechunk(plugins, (nplugins+1) * sizeof (*plugins), NULL)) == NULL) {
|
|
||||||
clicon_err(OE_UNIX, errno, "chunk");
|
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
plugins[nplugins++] = handle;
|
plugins[nplugins++] = handle;
|
||||||
unchunk (filename);
|
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
quit:
|
quit:
|
||||||
unchunk_group(__FUNCTION__);
|
if (dp)
|
||||||
|
free(dp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -387,8 +382,10 @@ restconf_plugin_unload(clicon_handle h)
|
||||||
|
|
||||||
for (i = 0; i < nplugins; i++)
|
for (i = 0; i < nplugins; i++)
|
||||||
plugin_unload(h, plugins[i]);
|
plugin_unload(h, plugins[i]);
|
||||||
if (plugins)
|
if (plugins){
|
||||||
unchunk(plugins);
|
free(plugins);
|
||||||
|
plugins = NULL;
|
||||||
|
}
|
||||||
nplugins = 0;
|
nplugins = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,6 @@ Mapping netconf error-tag -> status code
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
#include <cligen/cligen.h>
|
#include <cligen/cligen.h>
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,6 @@ CLICON_CLI_DIR libdir/APPNAME/cli
|
||||||
# Location of frontend .cli cligen spec files
|
# Location of frontend .cli cligen spec files
|
||||||
CLICON_CLISPEC_DIR libdir/APPNAME/clispec
|
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
|
# Enabled uses "startup" configuration on boot
|
||||||
CLICON_USE_STARTUP_CONFIG 0
|
CLICON_USE_STARTUP_CONFIG 0
|
||||||
|
|
||||||
|
|
@ -121,6 +117,9 @@ CLICON_BACKEND_PIDFILE localstatedir/APPNAME/APPNAME.pidfile
|
||||||
# Directory where "running", "candidate" and "startup" are placed
|
# Directory where "running", "candidate" and "startup" are placed
|
||||||
CLICON_XMLDB_DIR localstatedir/APPNAME
|
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
|
# Dont include keys in cvec in cli vars callbacks, ie a & k in 'a <b> k <c>' ignored
|
||||||
# CLICON_CLI_VARONLY 1
|
# CLICON_CLI_VARONLY 1
|
||||||
|
|
||||||
|
|
|
||||||
30
configure
vendored
30
configure
vendored
|
|
@ -703,7 +703,6 @@ ac_user_opts='
|
||||||
enable_option_checking
|
enable_option_checking
|
||||||
with_cligen
|
with_cligen
|
||||||
with_qdbm
|
with_qdbm
|
||||||
enable_keycontent
|
|
||||||
'
|
'
|
||||||
ac_precious_vars='build_alias
|
ac_precious_vars='build_alias
|
||||||
host_alias
|
host_alias
|
||||||
|
|
@ -1324,12 +1323,6 @@ if test -n "$ac_init_help"; then
|
||||||
|
|
||||||
cat <<\_ACEOF
|
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:
|
Optional Packages:
|
||||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||||
|
|
@ -4290,29 +4283,6 @@ else
|
||||||
fi
|
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"
|
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"
|
||||||
|
|
|
||||||
18
configure.ac
18
configure.ac
|
|
@ -159,24 +159,6 @@ AC_CHECK_FUNCS(inet_aton sigaction sigvec strlcpy strsep strndup alphasort versi
|
||||||
# Lives in libfcgi-dev
|
# Lives in libfcgi-dev
|
||||||
AC_CHECK_LIB(fcgi, FCGX_Init,, AC_MSG_ERROR([libfcgi-dev missing]))
|
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>])
|
AH_BOTTOM([#include <clixon_custom.h>])
|
||||||
|
|
||||||
AC_OUTPUT(Makefile
|
AC_OUTPUT(Makefile
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$
|
||||||
|
|
||||||
PLUGIN = $(DATASTORE).so
|
PLUGIN = $(DATASTORE).so
|
||||||
|
|
||||||
SRC = clixon_keyvalue.c clixon_qdb.c
|
SRC = clixon_keyvalue.c clixon_qdb.c clixon_chunk.c
|
||||||
|
|
||||||
OBJS = $(SRC:.c=.o)
|
OBJS = $(SRC:.c=.o)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,70 +119,6 @@ static int _running_locked = 0;
|
||||||
static int _candidate_locked = 0;
|
static int _candidate_locked = 0;
|
||||||
static int _startup_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
|
/*! Translate from symbolic database name to actual filename in file-system
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] db Symbolic database name, eg "candidate", "running"
|
* @param[in] db Symbolic database name, eg "candidate", "running"
|
||||||
|
|
@ -273,7 +209,7 @@ append_listkeys(cbuf *ckey,
|
||||||
else
|
else
|
||||||
cprintf(ckey, "=");
|
cprintf(ckey, "=");
|
||||||
cprintf(ckey, "%s", bodyenc);
|
cprintf(ckey, "%s", bodyenc);
|
||||||
free(bodyenc); bodyenc = NULL;
|
curl_free(bodyenc); bodyenc = NULL;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -436,7 +372,7 @@ get(char *dbname,
|
||||||
goto done;
|
goto done;
|
||||||
/* Assume body is created at end of function */
|
/* Assume body is created at end of function */
|
||||||
}
|
}
|
||||||
free(argdec);
|
curl_free(argdec);
|
||||||
argdec = NULL;
|
argdec = NULL;
|
||||||
break;
|
break;
|
||||||
case Y_LIST:
|
case Y_LIST:
|
||||||
|
|
@ -478,7 +414,7 @@ get(char *dbname,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cb, "[%s=%s]", cv_string_get(cvi), argdec);
|
cprintf(cb, "[%s=%s]", cv_string_get(cvi), argdec);
|
||||||
free(argdec);
|
curl_free(argdec);
|
||||||
argdec=NULL;
|
argdec=NULL;
|
||||||
}
|
}
|
||||||
if ((xc = xpath_first(x, cbuf_get(cb))) == NULL){
|
if ((xc = xpath_first(x, cbuf_get(cb))) == NULL){
|
||||||
|
|
@ -502,7 +438,7 @@ get(char *dbname,
|
||||||
argdec,
|
argdec,
|
||||||
keyname) < 0)
|
keyname) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
free(argdec); argdec = NULL;
|
curl_free(argdec); argdec = NULL;
|
||||||
} /* while */
|
} /* while */
|
||||||
}
|
}
|
||||||
if (cb){
|
if (cb){
|
||||||
|
|
@ -710,7 +646,7 @@ kv_get(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_spec *yspec;
|
yang_spec *yspec;
|
||||||
char *dbname = NULL;
|
char *dbname = NULL;
|
||||||
cxobj **xvec;
|
cxobj **xvec = NULL;
|
||||||
size_t xlen;
|
size_t xlen;
|
||||||
int i;
|
int i;
|
||||||
int npairs;
|
int npairs;
|
||||||
|
|
@ -885,7 +821,7 @@ put(char *dbname,
|
||||||
if (cbxk)
|
if (cbxk)
|
||||||
cbuf_free(cbxk);
|
cbuf_free(cbxk);
|
||||||
if (bodyenc)
|
if (bodyenc)
|
||||||
free(bodyenc);
|
curl_free(bodyenc);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1400,7 +1336,6 @@ kv_put(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Raw dump of database, just keys and values, no xml interpretation
|
/*! Raw dump of database, just keys and values, no xml interpretation
|
||||||
* @param[in] f File
|
* @param[in] f File
|
||||||
* @param[in] dbfile File-name of database. This is a local file
|
* @param[in] dbfile File-name of database. This is a local file
|
||||||
|
|
@ -1477,19 +1412,14 @@ kv_lock(clicon_handle h,
|
||||||
char *db,
|
char *db,
|
||||||
int pid)
|
int pid)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
if (strcmp("running", db) == 0)
|
||||||
|
_running_locked = pid;
|
||||||
if (db_islocked(db)){
|
else if (strcmp("candidate", db) == 0)
|
||||||
if (pid != db_islocked(db)){
|
_candidate_locked = pid;
|
||||||
clicon_err(OE_DB, 0, "lock failed: locked by %d", db_islocked(db));
|
else if (strcmp("startup", db) == 0)
|
||||||
goto done;
|
_startup_locked = pid;
|
||||||
}
|
clicon_debug(1, "%s: locked by %u", db, pid);
|
||||||
}
|
return 0;
|
||||||
else
|
|
||||||
db_lock(db, pid);
|
|
||||||
retval = 0;
|
|
||||||
done:
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Unlock database
|
/*! Unlock database
|
||||||
|
|
@ -1498,36 +1428,39 @@ kv_lock(clicon_handle h,
|
||||||
* @param[in] pid Process id
|
* @param[in] pid Process id
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
|
* Assume all sanity checks have been made
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
kv_unlock(clicon_handle h,
|
kv_unlock(clicon_handle h,
|
||||||
char *db,
|
char *db,
|
||||||
int pid)
|
int pid)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
if (strcmp("running", db) == 0)
|
||||||
int pid1;
|
_running_locked = 0;
|
||||||
|
else if (strcmp("candidate", db) == 0)
|
||||||
pid1 = db_islocked(db);
|
_candidate_locked = 0;
|
||||||
if (pid1){
|
else if (strcmp("startup", db) == 0)
|
||||||
if (pid == pid1)
|
_startup_locked = 0;
|
||||||
db_unlock(db);
|
return 0;
|
||||||
else{
|
|
||||||
clicon_err(OE_DB, 0, "unlock failed: locked by %d", pid1);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
retval = 0;
|
|
||||||
done:
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Unlock all databases locked by pid (eg process dies)
|
/*! 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
|
int
|
||||||
kv_unlock_all(clicon_handle h,
|
kv_unlock_all(clicon_handle h,
|
||||||
int pid)
|
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
|
/*! Check if database is locked
|
||||||
|
|
@ -1541,7 +1474,13 @@ int
|
||||||
kv_islocked(clicon_handle h,
|
kv_islocked(clicon_handle h,
|
||||||
char *db)
|
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
|
/*! Check if db exists
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
||||||
# spaces.
|
# spaces.
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# 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
|
# 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
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
||||||
# spaces.
|
# spaces.
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# 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
|
# 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
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,6 @@
|
||||||
/* Clixon version string */
|
/* Clixon version string */
|
||||||
#undef 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. */
|
/* Define to 1 if you have the `alphasort' function. */
|
||||||
#undef HAVE_ALPHASORT
|
#undef HAVE_ALPHASORT
|
||||||
|
|
||||||
|
|
|
||||||
91
lib/clixon/clixon.h
Normal file
91
lib/clixon/clixon.h
Normal 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[];
|
||||||
|
|
@ -38,9 +38,7 @@
|
||||||
|
|
||||||
|
|
||||||
int clicon_file_dirent(const char *dir, struct dirent **ent,
|
int clicon_file_dirent(const char *dir, struct dirent **ent,
|
||||||
const char *regexp, mode_t type, const char *label);
|
const char *regexp, mode_t type);
|
||||||
|
|
||||||
char *clicon_tmpfile(const char *label);
|
|
||||||
|
|
||||||
int clicon_file_copy(char *src, char *target);
|
int clicon_file_copy(char *src, char *target);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,6 @@ char *clicon_cli_dir(clicon_handle h);
|
||||||
char *clicon_clispec_dir(clicon_handle h);
|
char *clicon_clispec_dir(clicon_handle h);
|
||||||
char *clicon_netconf_dir(clicon_handle h);
|
char *clicon_netconf_dir(clicon_handle h);
|
||||||
char *clicon_restconf_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);
|
char *clicon_xmldb_plugin(clicon_handle h);
|
||||||
int clicon_sock_family(clicon_handle h);
|
int clicon_sock_family(clicon_handle h);
|
||||||
char *clicon_sock(clicon_handle h);
|
char *clicon_sock(clicon_handle h);
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,7 @@ CPPFLAGS = @CPPFLAGS@
|
||||||
|
|
||||||
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
|
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 \
|
SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c clixon_proc.c \
|
||||||
clixon_chunk.c clixon_proc.c \
|
|
||||||
clixon_string.c clixon_handle.c \
|
clixon_string.c clixon_handle.c \
|
||||||
clixon_xml.c clixon_xml_map.c clixon_file.c \
|
clixon_xml.c clixon_xml_map.c clixon_file.c \
|
||||||
clixon_json.c clixon_yang.c clixon_yang_type.c \
|
clixon_json.c clixon_yang.c clixon_yang_type.c \
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@
|
||||||
|
|
||||||
#include "clixon_log.h"
|
#include "clixon_log.h"
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -217,7 +216,7 @@ clicon_err_save(void)
|
||||||
{
|
{
|
||||||
struct err_state *es;
|
struct err_state *es;
|
||||||
|
|
||||||
if ((es = chunk(sizeof(*es), NULL)) == NULL)
|
if ((es = malloc(sizeof(*es))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
es->es_errno = clicon_errno;
|
es->es_errno = clicon_errno;
|
||||||
es->es_suberrno = clicon_suberrno;
|
es->es_suberrno = clicon_suberrno;
|
||||||
|
|
@ -232,10 +231,11 @@ clicon_err_restore(void* handle)
|
||||||
{
|
{
|
||||||
struct err_state *es;
|
struct err_state *es;
|
||||||
|
|
||||||
es = (struct err_state *)handle;
|
if ((es = (struct err_state *)handle) != NULL){
|
||||||
clicon_errno = es->es_errno;
|
clicon_errno = es->es_errno;
|
||||||
clicon_suberrno = es->es_suberrno;
|
clicon_suberrno = es->es_suberrno;
|
||||||
strncpy(clicon_err_reason, es->es_reason, ERR_STRLEN-1);
|
strncpy(clicon_err_reason, es->es_reason, ERR_STRLEN-1);
|
||||||
unchunk(es);
|
free(es);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@
|
||||||
/* clicon */
|
/* clicon */
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_string.h"
|
#include "clixon_string.h"
|
||||||
#include "clixon_file.h"
|
#include "clixon_file.h"
|
||||||
|
|
||||||
|
|
@ -66,7 +65,8 @@
|
||||||
* qsort function
|
* qsort function
|
||||||
*/
|
*/
|
||||||
static int
|
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 *d1 = (struct dirent *)arg1;
|
||||||
struct dirent *d2 = (struct dirent *)arg2;
|
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
|
/*! Return sorted matching files from a directory
|
||||||
* @param[in] dir Directory path
|
* @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] regexp Regexp filename matching
|
||||||
* @param[in] type File type matching, see stat(2)
|
* @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 n Number of matching files in directory
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -92,34 +92,34 @@ clicon_file_dirent_sort(const void* arg1, const void* arg2)
|
||||||
* @code
|
* @code
|
||||||
* char *dir = "/root/fs";
|
* char *dir = "/root/fs";
|
||||||
* struct dirent *dp;
|
* 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;
|
* return -1;
|
||||||
* for (i = 0; i < ndp; i++)
|
* for (i = 0; i < ndp; i++)
|
||||||
* do something with dp[i].d_name;
|
* do something with dp[i].d_name;
|
||||||
* unchunk_group(__FUNCTION__);
|
* free(dp);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_file_dirent(const char *dir,
|
clicon_file_dirent(const char *dir,
|
||||||
struct dirent **ent,
|
struct dirent **ent,
|
||||||
const char *regexp,
|
const char *regexp,
|
||||||
mode_t type,
|
mode_t type)
|
||||||
const char *label)
|
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
int retval = -1;
|
||||||
int retval = -1;
|
DIR *dirp;
|
||||||
int res;
|
int res;
|
||||||
int nent;
|
int nent;
|
||||||
char *filename;
|
regex_t re;
|
||||||
regex_t re;
|
char errbuf[128];
|
||||||
char errbuf[128];
|
char filename[MAXPATHLEN];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct dirent dent;
|
struct dirent dent;
|
||||||
struct dirent *dresp;
|
struct dirent *dresp;
|
||||||
struct dirent *tmp;
|
struct dirent *tmp;
|
||||||
struct dirent *new = NULL;
|
struct dirent *new = NULL;
|
||||||
struct dirent *dvecp = NULL;
|
struct dirent *dvecp = NULL;
|
||||||
|
|
||||||
|
|
||||||
*ent = NULL;
|
*ent = NULL;
|
||||||
nent = 0;
|
nent = 0;
|
||||||
|
|
||||||
|
|
@ -137,7 +137,9 @@ clicon_file_dirent(const char *dir,
|
||||||
goto quit;
|
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) {
|
if (res != 0) {
|
||||||
clicon_err(OE_UNIX, 0, "readdir: %s", strerror(errno));
|
clicon_err(OE_UNIX, 0, "readdir: %s", strerror(errno));
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
@ -150,12 +152,8 @@ clicon_file_dirent(const char *dir,
|
||||||
}
|
}
|
||||||
/* File type matching */
|
/* File type matching */
|
||||||
if (type) {
|
if (type) {
|
||||||
if ((filename = chunk_sprintf(__FUNCTION__, "%s/%s", dir, dent.d_name)) == NULL) {
|
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dent.d_name);
|
||||||
clicon_err(OE_UNIX, 0, "chunk: %s", strerror(errno));
|
|
||||||
goto quit;
|
|
||||||
}
|
|
||||||
res = lstat(filename, &st);
|
res = lstat(filename, &st);
|
||||||
unchunk (filename);
|
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
clicon_err(OE_UNIX, 0, "lstat: %s", strerror(errno));
|
clicon_err(OE_UNIX, 0, "lstat: %s", strerror(errno));
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
@ -164,8 +162,8 @@ clicon_file_dirent(const char *dir,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tmp = rechunk(new, (nent+1)*sizeof(*dvecp), label)) == NULL) {
|
if ((tmp = realloc(new, (nent+1)*sizeof(*dvecp))) == NULL) {
|
||||||
clicon_err(OE_UNIX, 0, "chunk: %s", strerror(errno));
|
clicon_err(OE_UNIX, errno, "realloc");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
new = tmp;
|
new = tmp;
|
||||||
|
|
@ -183,30 +181,9 @@ quit:
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
if (regexp)
|
if (regexp)
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
unchunk_group(__FUNCTION__);
|
|
||||||
|
|
||||||
return retval;
|
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
|
/*! Make a copy of file src
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_hash.h"
|
#include "clixon_hash.h"
|
||||||
#include "clixon_handle.h"
|
#include "clixon_handle.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_log.h"
|
#include "clixon_log.h"
|
||||||
#include "clixon_yang.h"
|
#include "clixon_yang.h"
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
|
|
@ -198,7 +197,6 @@ clicon_option_default(clicon_hash_t *copt)
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
catch:
|
catch:
|
||||||
unchunk_group(__FUNCTION__);
|
|
||||||
return retval;
|
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");
|
clicon_err(OE_UNIX, 0, "CLICON_YANG_DIR not defined in config file");
|
||||||
goto done;
|
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")){
|
if (!hash_lookup(copt, "CLICON_XMLDB_DIR")){
|
||||||
clicon_err(OE_UNIX, 0, "CLICON_XMLDB_DIR not defined in config file");
|
clicon_err(OE_UNIX, 0, "CLICON_XMLDB_DIR not defined in config file");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -451,12 +445,6 @@ clicon_restconf_dir(clicon_handle h)
|
||||||
return clicon_option_str(h, "CLICON_RESTCONF_DIR");
|
return clicon_option_str(h, "CLICON_RESTCONF_DIR");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
clicon_archive_dir(clicon_handle h)
|
|
||||||
{
|
|
||||||
return clicon_option_str(h, "CLICON_ARCHIVE_DIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
clicon_xmldb_plugin(clicon_handle h)
|
clicon_xmldb_plugin(clicon_handle h)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@
|
||||||
#include "clixon_sig.h"
|
#include "clixon_sig.h"
|
||||||
#include "clixon_string.h"
|
#include "clixon_string.h"
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_proc.h"
|
#include "clixon_proc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
#include "clixon_log.h"
|
#include "clixon_log.h"
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_sig.h"
|
#include "clixon_sig.h"
|
||||||
#include "clixon_xml.h"
|
#include "clixon_xml.h"
|
||||||
#include "clixon_xsl.h"
|
#include "clixon_xsl.h"
|
||||||
|
|
@ -532,11 +531,11 @@ send_msg_reply(int s,
|
||||||
uint16_t datalen)
|
uint16_t datalen)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct clicon_msg *reply;
|
struct clicon_msg *reply = NULL;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
|
|
||||||
len = sizeof(*reply) + datalen;
|
len = sizeof(*reply) + datalen;
|
||||||
if ((reply = (struct clicon_msg *)chunk(len, __FUNCTION__)) == NULL)
|
if ((reply = (struct clicon_msg *)malloc(len)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
memset(reply, 0, len);
|
memset(reply, 0, len);
|
||||||
reply->op_len = htons(len);
|
reply->op_len = htons(len);
|
||||||
|
|
@ -546,7 +545,8 @@ send_msg_reply(int s,
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
unchunk_group(__FUNCTION__);
|
if (reply)
|
||||||
|
free(reply);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,6 @@
|
||||||
|
|
||||||
/* clicon */
|
/* clicon */
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_log.h"
|
#include "clixon_log.h"
|
||||||
#include "clixon_hash.h"
|
#include "clixon_hash.h"
|
||||||
#include "clixon_handle.h"
|
#include "clixon_handle.h"
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@
|
||||||
|
|
||||||
/* clicon */
|
/* clicon */
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_string.h"
|
#include "clixon_string.h"
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@
|
||||||
#include "clixon_err.h"
|
#include "clixon_err.h"
|
||||||
#include "clixon_log.h"
|
#include "clixon_log.h"
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_xml.h"
|
#include "clixon_xml.h"
|
||||||
#include "clixon_xml_parse.h"
|
#include "clixon_xml_parse.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
|
|
@ -128,14 +127,36 @@ xmldb_get(clicon_handle h, char *db, char *xpath,
|
||||||
clicon_err(OE_DB, 0, "No xmldb plugin");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_get_fn &&
|
if (_xa_api->xa_get_fn == NULL){
|
||||||
_xa_api->xa_get_fn(h, db, xpath, xtop, xvec, xlen) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_get_fn(h, db, xpath, xtop, xvec, xlen);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_put(clicon_handle h, char *db, enum operation_type op,
|
xmldb_put(clicon_handle h, char *db, enum operation_type op,
|
||||||
char *api_path, cxobj *xt)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_put_fn &&
|
if (_xa_api->xa_put_fn == NULL){
|
||||||
_xa_api->xa_put_fn(h, db, op, api_path, xt) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_put_fn(h, db, op, api_path, xt);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_dump(FILE *f, char *dbfilename, char *rxkey)
|
xmldb_dump(FILE *f,
|
||||||
|
char *dbfilename,
|
||||||
|
char *pattern)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
|
|
@ -163,14 +192,22 @@ xmldb_dump(FILE *f, char *dbfilename, char *rxkey)
|
||||||
clicon_err(OE_DB, 0, "No xmldb plugin");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_dump_fn &&
|
if (_xa_api->xa_dump_fn == NULL){
|
||||||
_xa_api->xa_dump_fn(f, dbfilename, rxkey) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_dump_fn(f, dbfilename, pattern);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_copy(clicon_handle h, char *from, char *to)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_copy_fn &&
|
if (_xa_api->xa_copy_fn == NULL){
|
||||||
_xa_api->xa_copy_fn(h, from, to) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_copy_fn(h, from, to);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_lock(clicon_handle h, char *db, int pid)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_lock_fn &&
|
if (_xa_api->xa_lock_fn == NULL){
|
||||||
_xa_api->xa_lock_fn(h, db, pid) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_lock_fn(h, db, pid);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_unlock(clicon_handle h, char *db, int pid)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_unlock_fn &&
|
if (_xa_api->xa_unlock_fn == NULL){
|
||||||
_xa_api->xa_unlock_fn(h, db, pid) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_unlock_fn(h, db, pid);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_unlock_all(clicon_handle h, int pid)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_unlock_all_fn &&
|
if (_xa_api->xa_unlock_all_fn == NULL){
|
||||||
_xa_api->xa_unlock_all_fn(h, pid) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval =_xa_api->xa_unlock_all_fn(h, pid);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_islocked(clicon_handle h, char *db)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_islocked_fn &&
|
if (_xa_api->xa_islocked_fn == NULL){
|
||||||
_xa_api->xa_islocked_fn(h, db) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval =_xa_api->xa_islocked_fn(h, db);
|
||||||
done:
|
done:
|
||||||
return retval;
|
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
|
int
|
||||||
xmldb_exists(clicon_handle h, char *db)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_exists_fn &&
|
if (_xa_api->xa_exists_fn == NULL){
|
||||||
_xa_api->xa_exists_fn(h, db) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_exists_fn(h, db);
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Delete database. Remove file
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] db Database
|
||||||
|
* @retval -1 Error
|
||||||
|
* @retval 0 OK
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
xmldb_delete(clicon_handle h, char *db)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_delete_fn &&
|
if (_xa_api->xa_delete_fn == NULL){
|
||||||
_xa_api->xa_delete_fn(h, db) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_delete_fn(h, db);
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Initialize database
|
||||||
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] db Database
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
xmldb_init(clicon_handle h, char *db)
|
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");
|
clicon_err(OE_DB, 0, "No xmldb plugin");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (_xa_api->xa_init_fn &&
|
if (_xa_api->xa_init_fn == NULL){
|
||||||
_xa_api->xa_init_fn(h, db) < 0)
|
clicon_err(OE_DB, 0, "No xmldb function");
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
}
|
||||||
|
retval = _xa_api->xa_init_fn(h, db);
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@
|
||||||
#include "clixon_string.h"
|
#include "clixon_string.h"
|
||||||
#include "clixon_queue.h"
|
#include "clixon_queue.h"
|
||||||
#include "clixon_hash.h"
|
#include "clixon_hash.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_handle.h"
|
#include "clixon_handle.h"
|
||||||
#include "clixon_yang.h"
|
#include "clixon_yang.h"
|
||||||
#include "clixon_yang_type.h"
|
#include "clixon_yang_type.h"
|
||||||
|
|
@ -125,8 +124,9 @@ xml2txt(FILE *f, cxobj *x, int level)
|
||||||
{
|
{
|
||||||
cxobj *xe = NULL;
|
cxobj *xe = NULL;
|
||||||
int children=0;
|
int children=0;
|
||||||
char *term;
|
char *term = NULL;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
int encr=0;
|
||||||
#ifdef SPECIAL_TREATMENT_OF_NAME
|
#ifdef SPECIAL_TREATMENT_OF_NAME
|
||||||
cxobj *xname;
|
cxobj *xname;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -138,15 +138,17 @@ xml2txt(FILE *f, cxobj *x, int level)
|
||||||
if (xml_type(x) == CX_BODY){
|
if (xml_type(x) == CX_BODY){
|
||||||
/* Kludge for escaping encrypted passwords */
|
/* Kludge for escaping encrypted passwords */
|
||||||
if (strcmp(xml_name(xml_parent(x)), "encrypted-password")==0)
|
if (strcmp(xml_name(xml_parent(x)), "encrypted-password")==0)
|
||||||
term = chunk_sprintf(__FUNCTION__, "\"%s\"", xml_value(x));
|
encr++;
|
||||||
else
|
term = xml_value(x);
|
||||||
term = xml_value(x);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
fprintf(f, "%*s", 4*level, "");
|
fprintf(f, "%*s", 4*level, "");
|
||||||
term = xml_name(x);
|
term = xml_name(x);
|
||||||
}
|
}
|
||||||
fprintf(f, "%s;\n", term);
|
if (encr)
|
||||||
|
fprintf(f, "\"%s\";\n", term);
|
||||||
|
else
|
||||||
|
fprintf(f, "%s;\n", term);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@
|
||||||
#include "clixon_file.h"
|
#include "clixon_file.h"
|
||||||
#include "clixon_yang.h"
|
#include "clixon_yang.h"
|
||||||
#include "clixon_hash.h"
|
#include "clixon_hash.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
#include "clixon_yang_type.h"
|
#include "clixon_yang_type.h"
|
||||||
#include "clixon_yang_parse.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 1 Match founbd, Most recent entry returned in fbuf
|
||||||
* @retval 0 No matching entry found
|
* @retval 0 No matching entry found
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/static int
|
*/
|
||||||
|
static int
|
||||||
yang_parse_find_match(clicon_handle h,
|
yang_parse_find_match(clicon_handle h,
|
||||||
const char *yang_dir,
|
const char *yang_dir,
|
||||||
const char *module,
|
const char *module,
|
||||||
cbuf *fbuf)
|
cbuf *fbuf)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
struct dirent *dp;
|
struct dirent *dp = NULL;
|
||||||
int ndp;
|
int ndp;
|
||||||
cbuf *regex = NULL;
|
cbuf *regex = NULL;
|
||||||
char *regexstr;
|
char *regexstr;
|
||||||
|
|
||||||
if ((regex = cbuf_new()) == NULL){
|
if ((regex = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cbuf_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(regex, "^%s.*(.yang)$", module);
|
cprintf(regex, "^%s.*(.yang)$", module);
|
||||||
|
|
@ -1403,8 +1403,7 @@ yang_parse_find_match(clicon_handle h,
|
||||||
if ((ndp = clicon_file_dirent(yang_dir,
|
if ((ndp = clicon_file_dirent(yang_dir,
|
||||||
&dp,
|
&dp,
|
||||||
regexstr,
|
regexstr,
|
||||||
S_IFREG,
|
S_IFREG)) < 0)
|
||||||
__FUNCTION__)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
/* Entries are sorted, last entry should be most recent date */
|
/* Entries are sorted, last entry should be most recent date */
|
||||||
if (ndp != 0){
|
if (ndp != 0){
|
||||||
|
|
@ -1416,7 +1415,8 @@ yang_parse_find_match(clicon_handle h,
|
||||||
done:
|
done:
|
||||||
if (regex)
|
if (regex)
|
||||||
cbuf_free(regex);
|
cbuf_free(regex);
|
||||||
unchunk_group(__FUNCTION__);
|
if (dp)
|
||||||
|
free(dp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@
|
||||||
#include "clixon_handle.h"
|
#include "clixon_handle.h"
|
||||||
#include "clixon_yang.h"
|
#include "clixon_yang.h"
|
||||||
#include "clixon_hash.h"
|
#include "clixon_hash.h"
|
||||||
#include "clixon_chunk.h"
|
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
#include "clixon_yang.h"
|
#include "clixon_yang.h"
|
||||||
#include "clixon_yang_type.h"
|
#include "clixon_yang_type.h"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue