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 ***** # ***** 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

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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
*----------------------------------------------------------*/ *----------------------------------------------------------*/

View file

@ -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());

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 * 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));
@ -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

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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 */

View file

@ -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>

View file

@ -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
View file

@ -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"

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
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, 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);

View file

@ -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);

View file

@ -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 \

View file

@ -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;
} }

View file

@ -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,27 +92,26 @@ 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;
@ -120,6 +119,7 @@ clicon_file_dirent(const char *dir,
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

View file

@ -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)
{ {

View file

@ -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"
/* /*

View file

@ -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;
} }

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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;
} }

View file

@ -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,14 +138,16 @@ 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);
} }
if (encr)
fprintf(f, "\"%s\";\n", term);
else
fprintf(f, "%s;\n", term); fprintf(f, "%s;\n", term);
retval = 0; retval = 0;
goto done; goto done;

View file

@ -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;
} }

View file

@ -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"