This commit is contained in:
Olof hagsand 2019-12-18 23:27:52 +01:00
commit 241ae26e55
137 changed files with 1558 additions and 1405 deletions

View file

@ -170,8 +170,8 @@ client_get_capabilities(clicon_handle h,
int retval = -1;
cxobj *xrstate = NULL; /* xml restconf-state node */
cxobj *xcap = NULL; /* xml capabilities node */
if ((xrstate = xpath_first(*xret, "restconf-state")) == NULL){
if ((xrstate = xpath_first(*xret, NULL, "restconf-state")) == NULL){
clicon_err(OE_YANG, ENOENT, "restconf-state not found in config node");
goto done;
}
@ -321,10 +321,10 @@ client_statedata(clicon_handle h,
if (ret == 0)
goto fail;
/* Code complex to filter out anything that is outside of xpath
* Actually this is a safety catch, should realy be done in plugins
* Actually this is a safety catch, should really be done in plugins
* and modules_state functions.
*/
if (xpath_vec_nsc(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
if (xpath_vec(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
goto done;
/* If vectors are specified then mark the nodes found and
* then filter out everything else,
@ -434,7 +434,7 @@ from_client_get_config(clicon_handle h,
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
goto done;
if (ret == 0){ /* Do NACM validation */
if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
goto done;
/* NACM datanode/module read validation */
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
@ -529,14 +529,14 @@ from_client_edit_config(clicon_handle h,
goto done;
goto ok;
}
if ((x = xpath_first(xn, "default-operation")) != NULL){
if ((x = xpath_first(xn, NULL, "default-operation")) != NULL){
if (xml_operation(xml_body(x), &operation) < 0){
if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0)
goto done;
goto ok;
}
}
if ((xc = xpath_first(xn, "config")) == NULL){
if ((xc = xpath_first(xn, NULL, "config")) == NULL){
if (netconf_missing_element(cbret, "protocol", "config", NULL) < 0)
goto done;
goto ok;
@ -967,7 +967,7 @@ from_client_get(clicon_handle h,
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
goto done;
if (ret == 0){ /* Do NACM validation */
if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
goto done;
/* NACM datanode/module read validation */
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
@ -1122,9 +1122,9 @@ from_client_create_subscription(clicon_handle h,
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netmod:notification")) == NULL)
goto done;
if ((x = xpath_first_nsc(xe, nsc, "//stream")) != NULL)
if ((x = xpath_first(xe, nsc, "//stream")) != NULL)
stream = xml_find_value(x, "body");
if ((x = xpath_first_nsc(xe, nsc, "//stopTime")) != NULL){
if ((x = xpath_first(xe, nsc, "//stopTime")) != NULL){
if ((stoptime = xml_find_value(x, "body")) != NULL &&
str2time(stoptime, &stop) < 0){
if (netconf_bad_element(cbret, "application", "stopTime", "Expected timestamp") < 0)
@ -1132,7 +1132,7 @@ from_client_create_subscription(clicon_handle h,
goto ok;
}
}
if ((x = xpath_first_nsc(xe, nsc, "//startTime")) != NULL){
if ((x = xpath_first(xe, nsc, "//startTime")) != NULL){
if ((starttime = xml_find_value(x, "body")) != NULL &&
str2time(starttime, &start) < 0){
if (netconf_bad_element(cbret, "application", "startTime", "Expected timestamp") < 0)
@ -1140,7 +1140,7 @@ from_client_create_subscription(clicon_handle h,
goto ok;
}
}
if ((xfilter = xpath_first_nsc(xe, nsc, "//filter")) != NULL){
if ((xfilter = xpath_first(xe, nsc, "//filter")) != NULL){
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
/* Only accept xpath as filter type */
if (strcmp(ftype, "xpath") != 0){
@ -1367,8 +1367,8 @@ from_client_msg(clicon_handle h,
goto reply;
}
if ((x = xpath_first_nsc(xt, NULL, "/rpc")) == NULL){
if ((x = xpath_first_nsc(xt, NULL, "/hello")) != NULL){
if ((x = xpath_first(xt, NULL, "/rpc")) == NULL){
if ((x = xpath_first(xt, NULL, "/hello")) != NULL){
if ((ret = from_client_hello(h, x, ce, cbret)) <0)
goto done;
goto reply;

View file

@ -118,10 +118,14 @@ generic_validate(clicon_handle h,
for (i=0; i<td->td_dlen; i++){
x1 = td->td_dvec[i];
ys = xml_spec(x1);
if (ys && yang_mandatory(ys) && yang_config(ys)==0){
if (netconf_missing_element_xml(xret, "protocol", xml_name(x1), "Missing mandatory variable") < 0)
goto done;
goto fail;
if (ys && yang_mandatory(ys) && yang_config(ys)==1){
yang_stmt *yp =yang_parent_get(ys);
if (yp== NULL ||
(yang_keyword_get(yp)!=Y_MODULE && yang_keyword_get(yp)!=Y_SUBMODULE)){
if (netconf_missing_element_xml(xret, "protocol", xml_name(x1), "May not remove mandatory variable") < 0)
goto done;
goto fail;
}
}
}
/* added entries */

View file

@ -92,6 +92,7 @@ backend_terminate(clicon_handle h)
cxobj *x;
struct stat st;
int ss;
cvec *nsctx;
clicon_debug(1, "%s", __FUNCTION__);
if ((ss = clicon_socket_get(h)) != -1)
@ -110,6 +111,8 @@ backend_terminate(clicon_handle h)
yspec_free(yspec);
if ((yspec = clicon_config_yang(h)) != NULL)
yspec_free(yspec);
if ((nsctx = clicon_nsctx_global_get(h)) != NULL)
cvec_free(nsctx);
if ((x = clicon_nacm_ext(h)) != NULL)
xml_free(x);
if ((x = clicon_conf_xml(h)) != NULL)
@ -443,7 +446,6 @@ main(int argc,
char *nacm_mode;
int logdst = CLICON_LOG_SYSLOG|CLICON_LOG_STDERR;
yang_stmt *yspec = NULL;
yang_stmt *yspecfg = NULL; /* For config XXX clixon bug */
char *str;
int ss = -1; /* server socket */
cbuf *cbret = NULL; /* startup cbuf if invalid */
@ -451,6 +453,7 @@ main(int argc,
int ret;
char *dir;
gid_t gid = -1;
cvec *nsctx_global = NULL; /* Global namespace context */
/* In the startup, logs to stderr & syslog and debug flag set later */
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
@ -505,17 +508,13 @@ main(int argc,
clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst);
clicon_debug_init(debug, NULL);
/* Create configure yang-spec */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h, yspecfg) < 0){
if (clicon_options_main(h) < 0){
if (help)
usage(h, argv[0]);
return -1;
}
clicon_config_yang_set(h, yspecfg);
/* External NACM file? */
nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE");
if (nacm_mode && strcmp(nacm_mode, "external") == 0)
@ -722,10 +721,10 @@ main(int argc,
if ((str = clicon_yang_main_dir(h)) != NULL)
if (yang_spec_load_dir(h, str, yspec) < 0)
goto done;
/* Load clixon lib yang module */
/* Load clixon lib yang module */
if (yang_spec_parse_module(h, "clixon-lib", NULL, yspec) < 0)
goto done;
/* Load yang module library, RFC7895 */
/* Load yang module library, RFC7895 */
if (yang_modules_init(h) < 0)
goto done;
/* Add netconf yang spec, used by netconf client and as internal protocol
@ -736,13 +735,21 @@ main(int argc,
if (yang_spec_parse_module(h, "ietf-restconf", NULL, yspec)< 0)
goto done;
/* Load yang Restconf stream discovery */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
goto done;
/* Load yang Netconf stream discovery */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
goto done;
/* Load yang Netconf stream discovery */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done;
/* Here all modules are loaded
* Compute and set canonical namespace context
*/
if (xml_nsctx_yangspec(yspec, &nsctx_global) < 0)
goto done;
if (clicon_nsctx_global_set(h, nsctx_global) < 0)
goto done;
/* Initialize server socket and save it to handle */
if (backend_rpc_init(h) < 0)
goto done;
@ -895,7 +902,7 @@ main(int argc,
goto done;
ok:
retval = 0;
done:
done:
if (cbret)
cbuf_free(cbret);
clicon_log(LOG_NOTICE, "%s: %u Terminated retval:%d", __PROGRAM__, getpid(), retval);

View file

@ -111,9 +111,11 @@ clixon_plugin_statedata(clicon_handle h,
{
int retval = -1;
int ret;
cxobj *xerr = NULL;
cxobj *x = NULL;
clixon_plugin *cp = NULL;
plgstatedata_t *fn; /* Plugin statedata fn */
cbuf *cberr = NULL;
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if ((fn = cp->cp_api.ca_statedata) == NULL)
@ -124,6 +126,38 @@ clixon_plugin_statedata(clicon_handle h,
goto fail; /* Dont quit here on user callbacks */
if (xml_apply(x, CX_ELMNT, xml_spec_populate, yspec) < 0)
goto done;
/* Check XML from state callback by validating it. return internal
* error with error cause
*/
if ((ret = xml_yang_validate_all_top(h, x, &xerr)) < 0)
goto done;
if (ret > 0 && (ret = xml_yang_validate_add(h, x, &xerr)) < 0)
goto done;
if (ret == 0){
if ((cberr = cbuf_new()) ==NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
cprintf(cberr, "Internal error: state callback returned invalid XML: ");
if (netconf_err2cb(xpath_first(xerr, NULL, "rpc-error"), cberr) < 0)
goto done;
if (*xret){
xml_free(*xret);
*xret = NULL;
}
if (netconf_operation_failed_xml(xret, "application", cbuf_get(cberr))< 0)
goto done;
goto fail;
}
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, x, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s MERGE: %s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
}
#endif
if ((ret = netconf_trymerge(x, yspec, xret)) < 0)
goto done;
if (ret == 0)
@ -135,8 +169,12 @@ clixon_plugin_statedata(clicon_handle h,
}
retval = 1;
done:
if (cberr)
cbuf_free(cberr);
if (x)
xml_free(x);
if (xerr)
xml_free(xerr);
return retval;
fail:
retval = 0;

View file

@ -270,10 +270,12 @@ backend_accept_client(int fd,
#error "Need getsockopt O_PEERCRED or getpeereid for unix socket peer cred"
#endif
if (name != NULL){
if ((ce->ce_username = strdup(name)) == NULL){
if ((ce->ce_username = name) == NULL){
clicon_err(OE_UNIX, errno, "strdup");
name = NULL;
goto done;
}
name = NULL;
}
break;
case AF_INET:
@ -291,5 +293,7 @@ backend_accept_client(int fd,
goto done;
retval = 0;
done:
if (name)
free(name);
return retval;
}

View file

@ -241,7 +241,7 @@ startup_extraxml(clicon_handle h,
* It should be empty if extra-xml is null and reset plugins did nothing
* then skip validation.
*/
if (xmldb_get(h, tmp_db, NULL, &xt0) < 0)
if (xmldb_get(h, tmp_db, NULL, NULL, &xt0) < 0)
goto done;
if (xt0==NULL || xml_child_nr(xt0)==0)
goto ok;

View file

@ -46,7 +46,6 @@
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <fnmatch.h>
#include <sys/types.h>
#include <sys/time.h>
#include <regex.h>

View file

@ -714,13 +714,13 @@ compare_dbs(clicon_handle h,
astext = 0;
if (clicon_rpc_get_config(h, NULL, "running", "/", NULL, &xc1) < 0)
goto done;
if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if (clicon_rpc_get_config(h, NULL, "candidate", "/", NULL, &xc2) < 0)
goto done;
if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -884,7 +884,7 @@ save_config_file(clicon_handle h,
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -992,7 +992,7 @@ cli_notification_cb(int s,
}
if (clicon_msg_decode(reply, NULL, NULL, &xt) < 0) /* XXX pass yang_spec */
goto done;
if ((xe = xpath_first(xt, "//event")) != NULL){
if ((xe = xpath_first(xt, NULL, "//event")) != NULL){
x = NULL;
while ((x = xml_child_each(xe, x, -1)) != NULL) {
switch (format){
@ -1224,7 +1224,7 @@ cli_copy_config(clicon_handle h,
/* Get from object configuration and store in x1 */
if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cb), nsc, &x1) < 0)
goto done;
if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){
if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -1243,7 +1243,7 @@ cli_copy_config(clicon_handle h,
xml_name_set(x2, "config");
cprintf(cb, "/%s", keyname);
if ((x = xpath_first_nsc(x2, nsc, "%s", cbuf_get(cb))) == NULL){
if ((x = xpath_first(x2, nsc, "%s", cbuf_get(cb))) == NULL){
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
goto done;
}

View file

@ -162,10 +162,10 @@ cli_cligen(clicon_handle h)
int
cli_parse_file(clicon_handle h,
FILE *f,
char *name, /* just for errs */
parse_tree *pt,
cvec *globals)
FILE *f,
char *name, /* just for errs */
parse_tree *pt,
cvec *globals)
{
cligen_handle ch = cligen(h);
@ -182,7 +182,7 @@ cli_susp_hook(clicon_handle h,
return cligen_susp_hook(ch, fn);
}
int
cli_interrupt_hook(clicon_handle h,
cli_interrupt_hook(clicon_handle h,
cligen_interrupt_cb_t *fn)
{
cligen_handle ch = cligen(h);
@ -200,14 +200,16 @@ cli_nomatch(clicon_handle h)
}
int
cli_prompt_set(clicon_handle h, char *prompt)
cli_prompt_set(clicon_handle h,
char *prompt)
{
cligen_handle ch = cligen(h);
return cligen_prompt_set(ch, prompt);
}
int
cli_logsyntax_set(clicon_handle h, int status)
cli_logsyntax_set(clicon_handle h,
int status)
{
cligen_handle ch = cligen(h);
return cligen_logsyntax_set(ch, status);

View file

@ -163,6 +163,7 @@ static int
cli_terminate(clicon_handle h)
{
yang_stmt *yspec;
cvec *nsctx;
cxobj *x;
clicon_rpc_close_session(h);
@ -170,6 +171,8 @@ cli_terminate(clicon_handle h)
yspec_free(yspec);
if ((yspec = clicon_config_yang(h)) != NULL)
yspec_free(yspec);
if ((nsctx = clicon_nsctx_global_get(h)) != NULL)
cvec_free(nsctx);
if ((x = clicon_conf_xml(h)) != NULL)
xml_free(x);
cli_plugin_finish(h);
@ -280,12 +283,12 @@ main(int argc, char **argv)
int logdst = CLICON_LOG_STDERR;
char *restarg = NULL; /* what remains after options */
yang_stmt *yspec;
yang_stmt *yspecfg = NULL; /* For config XXX clixon bug */
struct passwd *pw;
char *str;
int tabmode;
char *dir;
uint32_t id = 0;
cvec *nsctx_global = NULL; /* Global namespace context */
/* Defaults */
once = 0;
@ -348,16 +351,13 @@ main(int argc, char **argv)
clicon_debug_init(debug, NULL);
/* Create top-level yang spec and store as option */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h, yspecfg) < 0){
/* Find, read and parse configfile */
if (clicon_options_main(h) < 0){
if (help)
usage(h, argv[0]);
return -1;
}
clicon_config_yang_set(h, yspecfg);
/* Now rest of options */
opterr = 0;
optind = 1;
@ -513,6 +513,14 @@ main(int argc, char **argv)
if (netconf_module_load(h) < 0)
goto done;
/* Here all modules are loaded
* Compute and set canonical namespace context
*/
if (xml_nsctx_yangspec(yspec, &nsctx_global) < 0)
goto done;
if (clicon_nsctx_global_set(h, nsctx_global) < 0)
goto done;
/* Create tree generated from dataspec. If no other trees exists, this is
* the only one.
* The following code creates the tree @datamodel
@ -533,7 +541,7 @@ main(int argc, char **argv)
cligen_tree_add(cli_cligen(h), treeref, pt);
if (printgen)
cligen_print(stdout, pt, 1);
cligen_print(stdout, pt, 1); /* pt_print */
}
/* Initialize cli syntax */

View file

@ -45,7 +45,6 @@
#include <stdarg.h>
#include <syslog.h>
#include <errno.h>
#include <assert.h>
#include <dlfcn.h>
#include <dirent.h>
#include <libgen.h>
@ -209,27 +208,29 @@ clixon_str2fn(char *name,
return NULL;
}
/*! Append to syntax mode from file
* @param[in] h Clixon handle
* @param[in] filename Name of file where syntax is specified (in syntax-group dir)
* @param[in] dir Name of dir, or NULL
/*! Load a file containing syntax and append to specified modes, also load C plugin
* @param[in] h Clixon handle
* @param[in] filename Name of file where syntax is specified (in syntax-group dir)
* @param[in] dir Name of dir, or NULL
* @param[out] allpt Universal CLIgen parse tree: apply to all modes
*/
static int
cli_load_syntax(clicon_handle h,
const char *filename,
const char *dir)
cli_load_syntax_file(clicon_handle h,
const char *filename,
const char *dir,
parse_tree *ptall)
{
void *handle = NULL; /* Handle to plugin .so module */
char *mode = NULL; /* Name of syntax mode to append new syntax */
parse_tree pt = {0,};
int retval = -1;
FILE *f;
char filepath[MAXPATHLEN];
cvec *cvv = NULL;
char *prompt = NULL;
char **vec = NULL;
int i, nvec;
char *plgnam;
void *handle = NULL; /* Handle to plugin .so module */
char *mode = NULL; /* Name of syntax mode to append new syntax */
parse_tree pt = {0,};
int retval = -1;
FILE *f;
char filepath[MAXPATHLEN];
cvec *cvv = NULL;
char *prompt = NULL;
char **vec = NULL;
int i, nvec;
char *plgnam;
clixon_plugin *cp;
if (dir)
@ -253,10 +254,18 @@ cli_load_syntax(clicon_handle h,
goto done;
}
fclose(f);
/* Get CLICON specific global variables */
/* Get CLICON specific global variables:
* CLICON_MODE: which mode(s) this syntax applies to
* CLICON_PROMPT: Cli prompt in this mode
* CLICON_PLUGIN: Name of C API plugin
* Note: the base case is that it is:
* (1) a single mode or
* (2) "*" all modes or "m1:m2" - a list of modes
* but for (2), prompt and plgnam may have unclear semantics
*/
mode = cvec_find_str(cvv, "CLICON_MODE");
prompt = cvec_find_str(cvv, "CLICON_PROMPT");
plgnam = cvec_find_str(cvv, "CLICON_PLUGIN");
mode = cvec_find_str(cvv, "CLICON_MODE");
if (plgnam != NULL) { /* Find plugin for callback resolving */
if ((cp = clixon_plugin_find(h, plgnam)) != NULL)
@ -288,8 +297,19 @@ cli_load_syntax(clicon_handle h,
goto done;
}
}
/* Find all modes in CLICON_MODE string: where to append the pt syntax tree */
if ((vec = clicon_strsep(mode, ":", &nvec)) == NULL)
goto done;
if (nvec == 1 && strcmp(vec[0], "*") == 0){
/* Special case: Add this to all modes. Add to special "universal" syntax
* and add to all syntaxes after all files have been loaded. At this point
* all modes may not be known (not yet loaded)
*/
if (cligen_parsetree_merge(ptall, NULL, pt) < 0)
return -1;
}
else {
for (i = 0; i < nvec; i++) {
if (syntax_append(h,
cli_syntax(h),
@ -300,6 +320,7 @@ cli_load_syntax(clicon_handle h,
if (prompt)
cli_set_prompt(h, vec[i], prompt);
}
}
cligen_parsetree_free(pt, 1);
retval = 0;
@ -329,6 +350,7 @@ cli_syntax_load(clicon_handle h)
cligen_susp_cb_t *fns = NULL;
cligen_interrupt_cb_t *fni = NULL;
clixon_plugin *cp;
parse_tree ptall = {0,}; /* Universal CLIgen parse tree all modes */
/* Syntax already loaded. XXX should we re-load?? */
if ((stx = cli_syntax(h)) != NULL)
@ -347,30 +369,38 @@ cli_syntax_load(clicon_handle h)
cli_syntax_set(h, stx);
/* Load single specific clispec file */
if (clispec_file){
if (cli_load_syntax(h, clispec_file, NULL) < 0)
if (cli_load_syntax_file(h, clispec_file, NULL, &ptall) < 0)
goto done;
}
/* Load all clispec .cli files in directory */
if (clispec_dir){
/* load syntaxfiles */
/* Get directory list of files */
if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG)) < 0)
goto done;
/* Load the rest */
/* Load the syntax parse trees into cli_syntax stx structure */
for (i = 0; i < ndp; i++) {
clicon_debug(1, "DEBUG: Loading syntax '%.*s'",
(int)strlen(dp[i].d_name)-4, dp[i].d_name);
if (cli_load_syntax(h, dp[i].d_name, clispec_dir) < 0)
if (cli_load_syntax_file(h, dp[i].d_name, clispec_dir, &ptall) < 0)
goto done;
}
}
/* Did we successfully load any syntax modes? */
/* Were any syntax modes successfully loaded? If not, leave */
if (stx->stx_nmodes <= 0) {
retval = 0;
goto done;
}
/* Parse syntax tree for all modes */
/* Go thorugh all modes and :
* 1) Add the universal syntax
* 2) add syntax tree (of those modes - "activate" syntax from stx to CLIgen)
*/
m = stx->stx_modes;
do {
if (cligen_parsetree_merge(&m->csm_pt, NULL, ptall) < 0)
return -1;
if (gen_parse_tree(h, m) != 0)
goto done;
m = NEXTQ(cli_syntaxmode_t *, m);
@ -389,13 +419,13 @@ cli_syntax_load(clicon_handle h)
/* All good. We can now proudly return a new group */
retval = 0;
done:
if (retval != 0) {
clixon_plugin_exit(h);
cli_syntax_unload(h);
cli_syntax_set(h, NULL);
}
cligen_parsetree_free(ptall, 1);
if (dp)
free(dp);
return retval;

View file

@ -157,7 +157,7 @@ expand_dbvar(void *h,
/* Get configuration */
if (clicon_rpc_get_config(h, NULL, dbstr, xpath, nsc, &xt) < 0) /* XXX */
goto done;
if ((xe = xpath_first(xt, "/rpc-error")) != NULL){
if ((xe = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xe);
goto ok;
}
@ -204,12 +204,12 @@ expand_dbvar(void *h,
fprintf(stderr, "%s\n", reason);
goto done;
}
if ((xcur = xpath_first_nsc(xt, nsc, "%s", xpath)) == NULL){
if ((xcur = xpath_first(xt, nsc, "%s", xpath)) == NULL){
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
goto done;
}
}
if (xpath_vec_nsc(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0)
if (xpath_vec(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0)
goto done;
/* Loop for inserting into commands cvec.
* Detect duplicates: for ordered-by system assume list is ordered, so you need
@ -486,7 +486,7 @@ cli_show_config1(clicon_handle h,
if (clicon_rpc_get(h, cbuf_get(cbxpath), nsc, CONTENT_ALL, -1, &xt) < 0)
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
@ -634,12 +634,12 @@ show_conf_xpath(clicon_handle h,
goto done;
if (clicon_rpc_get_config(h, NULL, str, xpath, nsc, &xt) < 0)
goto done;
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if (xpath_vec_nsc(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
if (xpath_vec(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
goto done;
for (i=0; i<xlen; i++)
xml_print(stdout, xv[i]);
@ -737,11 +737,11 @@ cli_show_auto1(clicon_handle h,
goto done;
}
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
clicon_rpc_generate_error("Get configuration", xerr);
goto done;
}
if ((xp = xpath_first_nsc(xt, nsc, "%s", xpath)) != NULL)
if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL)
/* Print configuration according to format */
switch (format){
case FORMAT_XML:

View file

@ -121,7 +121,6 @@ xml_filter_recursive(cxobj *xfilter,
int remove_s;
*remove_me = 0;
assert(xfilter && xparent && strcmp(xml_name(xfilter), xml_name(xparent))==0);
/* 1. Check selection */
if (xml_child_nr(xfilter) == 0)
goto match;

View file

@ -164,14 +164,14 @@ netconf_get_target(cxobj *xn,
cxobj *x;
char *target = NULL;
if ((x = xpath_first(xn, "%s", path)) != NULL){
if (xpath_first(x, "candidate") != NULL)
if ((x = xpath_first(xn, NULL, "%s", path)) != NULL){
if (xpath_first(x, NULL, "candidate") != NULL)
target = "candidate";
else
if (xpath_first(x, "running") != NULL)
if (xpath_first(x, NULL, "running") != NULL)
target = "running";
else
if (xpath_first(x, "startup") != NULL)
if (xpath_first(x, NULL, "startup") != NULL)
target = "startup";
}
return target;

View file

@ -98,7 +98,7 @@ netconf_hello_dispatch(cxobj *xn)
cxobj *xp;
int retval = -1;
if ((xp = xpath_first(xn, "//hello")) != NULL)
if ((xp = xpath_first(xn, NULL, "//hello")) != NULL)
retval = netconf_hello(xp);
return retval;
}
@ -147,7 +147,7 @@ netconf_input_packet(clicon_handle h,
goto done;
}
free(str0);
if ((xrpc=xpath_first(xreq, "//rpc")) != NULL){
if ((xrpc=xpath_first(xreq, NULL, "//rpc")) != NULL){
isrpc++;
if (xml_spec_populate_rpc(h, xrpc, yspec) < 0)
goto done;
@ -160,7 +160,7 @@ netconf_input_packet(clicon_handle h,
}
}
else
if (xpath_first(xreq, "//hello") != NULL)
if (xpath_first(xreq, NULL, "//hello") != NULL)
;
else{
clicon_log(LOG_WARNING, "Invalid netconf msg: neither rpc or hello: dropped");
@ -323,6 +323,7 @@ static int
netconf_terminate(clicon_handle h)
{
yang_stmt *yspec;
cvec *nsctx;
cxobj *x;
clixon_plugin_exit(h);
@ -332,6 +333,8 @@ netconf_terminate(clicon_handle h)
yspec_free(yspec);
if ((yspec = clicon_config_yang(h)) != NULL)
yspec_free(yspec);
if ((nsctx = clicon_nsctx_global_get(h)) != NULL)
cvec_free(nsctx);
if ((x = clicon_conf_xml(h)) != NULL)
xml_free(x);
event_exit();
@ -392,9 +395,9 @@ main(int argc,
struct passwd *pw;
struct timeval tv = {0,}; /* timeout */
yang_stmt *yspec = NULL;
yang_stmt *yspecfg = NULL; /* For config XXX clixon bug */
char *str;
uint32_t id;
cvec *nsctx_global = NULL; /* Global namespace context */
/* Create handle */
if ((h = clicon_handle_init()) == NULL)
@ -439,13 +442,10 @@ main(int argc,
clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst);
clicon_debug_init(debug, NULL);
/* Create configure yang-spec */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h, yspecfg) < 0)
/* Find, read and parse configfile */
if (clicon_options_main(h) < 0)
return -1;
clicon_config_yang_set(h, yspecfg);
/* Now rest of options */
optind = 1;
opterr = 0;
@ -554,6 +554,14 @@ main(int argc,
/* Add netconf yang spec, used by netconf client and as internal protocol */
if (netconf_module_load(h) < 0)
goto done;
/* Here all modules are loaded
* Compute and set canonical namespace context
*/
if (xml_nsctx_yangspec(yspec, &nsctx_global) < 0)
goto done;
if (clicon_nsctx_global_set(h, nsctx_global) < 0)
goto done;
/* Call start function is all plugins before we go interactive */
if (clixon_plugin_start(h) < 0)
goto done;

View file

@ -80,6 +80,31 @@
</rpc>
*/
static int
netconf_get_config_subtree(clicon_handle h,
cxobj *xfilter,
cxobj **xret)
{
int retval = -1;
cxobj *xdata;
/* a subtree filter is comprised of zero or more element subtrees*/
if ((xdata = xpath_first(*xret, NULL, "/rpc-reply/data")) == NULL)
goto ok;
if (xml_filter(xfilter, xdata) < 0){
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
"<error-info>filtering</error-info>"
"</rpc-error></rpc-reply>");
}
ok:
retval = 0;
// done:
return retval;
}
/*! Get configuration
* @param[in] h Clicon handle
* @param[in] xn Sub-tree (under xorig) at <rpc>...</rpc> level.
@ -136,37 +161,22 @@ netconf_get_config(clicon_handle h,
cxobj *xfilter; /* filter */
int retval = -1;
char *ftype = NULL;
cxobj *xfilterconf;
cxobj *xconf;
/* ie <filter>...</filter> */
if ((xfilter = xpath_first(xn, "filter")) != NULL)
if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL)
ftype = xml_find_value(xfilter, "type");
if (ftype == NULL || strcmp(ftype, "xpath")==0){
if (xfilter == NULL || ftype == NULL || strcmp(ftype, "xpath")==0){
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
}
else if (strcmp(ftype, "subtree")==0){
/* Default rfc filter is subtree. I prefer xpath and use it internally.
Get whole subtree and then filter aftwerwards. This is suboptimal.
Therefore please use xpath.
/* Get whole config first, then filter. This is suboptimal
*/
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
if (xfilter &&
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
(xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
"<error-info>filtering</error-info>"
"</rpc-error></rpc-reply>");
}
}
/* Now filter on whole tree */
if (netconf_get_config_subtree(h, xfilter, xret) < 0)
goto done;
}
else{
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
@ -208,7 +218,7 @@ get_edit_opts(cxobj *xn,
cxobj *x;
char *optstr;
if ((x = xpath_first(xn, "test-option")) != NULL){
if ((x = xpath_first(xn, NULL, "test-option")) != NULL){
if ((optstr = xml_body(x)) != NULL){
if (strcmp(optstr, "test-then-set") == 0)
*testopt = TEST_THEN_SET;
@ -220,7 +230,7 @@ get_edit_opts(cxobj *xn,
goto parerr;
}
}
if ((x = xpath_first(xn, "error-option")) != NULL){
if ((x = xpath_first(xn, NULL, "error-option")) != NULL){
if ((optstr = xml_body(x)) != NULL){
if (strcmp(optstr, "stop-on-error") == 0)
*erropt = STOP_ON_ERROR;
@ -348,37 +358,22 @@ netconf_get(clicon_handle h,
cxobj *xfilter; /* filter */
int retval = -1;
char *ftype = NULL;
cxobj *xfilterconf;
cxobj *xconf;
/* ie <filter>...</filter> */
if ((xfilter = xpath_first(xn, "filter")) != NULL)
if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL)
ftype = xml_find_value(xfilter, "type");
if (ftype == NULL || strcmp(ftype, "xpath")==0){
if (xfilter == NULL || ftype == NULL || strcmp(ftype, "xpath")==0){
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
}
else if (strcmp(ftype, "subtree")==0){
/* Default rfc filter is subtree. I prefer xpath and use it internally.
Get whole subtree and then filter aftwerwards. This is suboptimal.
Therefore please use xpath.
/* Get whole config + state first, then filter. This is suboptimal
*/
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
goto done;
if (xfilter &&
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
(xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
"<error-info>filtering</error-info>"
"</rpc-error></rpc-reply>");
}
}
/* Now filter on whole tree */
if (netconf_get_config_subtree(h, xfilter, xret) < 0)
goto done;
}
else{
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
@ -448,7 +443,7 @@ netconf_notification_cb(int s,
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
goto done;
if ((xn = xpath_first_nsc(xt, nsc, "notification")) == NULL)
if ((xn = xpath_first(xt, nsc, "notification")) == NULL)
goto ok;
/* create netconf message */
if ((cb = cbuf_new()) == NULL){
@ -500,7 +495,7 @@ netconf_create_subscription(clicon_handle h,
int s;
char *ftype;
if ((xfilter = xpath_first(xn, "//filter")) != NULL){
if ((xfilter = xpath_first(xn, NULL, "//filter")) != NULL){
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
if (strcmp(ftype, "xpath") != 0){
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
@ -516,7 +511,7 @@ netconf_create_subscription(clicon_handle h,
}
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, &s) < 0)
goto done;
if (xpath_first(*xret, "rpc-reply/rpc-error") != NULL)
if (xpath_first(*xret, NULL, "rpc-reply/rpc-error") != NULL)
goto ok;
if (event_reg_fd(s,
netconf_notification_cb,
@ -622,7 +617,7 @@ netconf_application_rpc(clicon_handle h,
*/
if (0)
if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){
xoutput=xpath_first(*xret, "/");
xoutput=xpath_first(*xret, NULL, "/");
xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
goto done;

View file

@ -476,7 +476,7 @@ api_return_err(clicon_handle h,
clicon_debug(1, "%s", __FUNCTION__);
if ((cb = cbuf_new()) == NULL)
goto done;
if ((xtag = xpath_first(xerr, "//error-tag")) == NULL){
if ((xtag = xpath_first(xerr, NULL, "//error-tag")) == NULL){
restconf_notfound(r);
goto ok;
}
@ -593,6 +593,7 @@ int
restconf_terminate(clicon_handle h)
{
yang_stmt *yspec;
cvec *nsctx;
cxobj *x;
int fs; /* fgcx socket */
@ -606,6 +607,8 @@ restconf_terminate(clicon_handle h)
yspec_free(yspec);
if ((yspec = clicon_config_yang(h)) != NULL)
yspec_free(yspec);
if ((nsctx = clicon_nsctx_global_get(h)) != NULL)
cvec_free(nsctx);
if ((x = clicon_conf_xml(h)) != NULL)
xml_free(x);
clicon_handle_exit(h);

View file

@ -418,7 +418,7 @@ api_restconf(clicon_handle h,
else{
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xerr, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -582,13 +582,13 @@ main(int argc,
char *dir;
int logdst = CLICON_LOG_SYSLOG;
yang_stmt *yspec = NULL;
yang_stmt *yspecfg = NULL; /* For config XXX clixon bug */
char *stream_path;
int finish = 0;
int start = 1;
char *str;
clixon_plugin *cp = NULL;
uint32_t id = 0;
cvec *nsctx_global = NULL; /* Global namespace context */
/* In the startup, logs to stderr & debug flag set later */
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
@ -641,13 +641,10 @@ main(int argc,
goto done;
}
/* Create configure yang-spec */
if ((yspecfg = yspec_new()) == NULL)
goto done;
/* Find and read configfile */
if (clicon_options_main(h, yspecfg) < 0)
if (clicon_options_main(h) < 0)
goto done;
clicon_config_yang_set(h, yspecfg);
stream_path = clicon_option_str(h, "CLICON_STREAM_PATH");
/* Now rest of options, some overwrite option file */
optind = 1;
@ -760,6 +757,14 @@ main(int argc,
yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done;
/* Here all modules are loaded
* Compute and set canonical namespace context
*/
if (xml_nsctx_yangspec(yspec, &nsctx_global) < 0)
goto done;
if (clicon_nsctx_global_set(h, nsctx_global) < 0)
goto done;
/* Dump configuration options on debug */
if (debug)
clicon_option_dump(h, debug);

View file

@ -283,7 +283,7 @@ api_data_write(clicon_handle h,
if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &nsc, &xerr)) < 0)
goto done;
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -296,7 +296,7 @@ api_data_write(clicon_handle h,
"candidate", cbuf_get(cbpath), nsc, &xret) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -341,7 +341,7 @@ api_data_write(clicon_handle h,
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot, &xerr)) < 0)
goto done;
if (ret == 0){ /* validation failed */
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -358,7 +358,7 @@ api_data_write(clicon_handle h,
if (data == NULL || strlen(data) == 0){
if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -373,7 +373,7 @@ api_data_write(clicon_handle h,
if (xml_parse_string(data, yspec, &xdata0) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -392,7 +392,7 @@ api_data_write(clicon_handle h,
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -401,7 +401,7 @@ api_data_write(clicon_handle h,
goto ok;
}
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -422,7 +422,7 @@ api_data_write(clicon_handle h,
if (xml_child_nr(xdata0) != 1){
if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -450,7 +450,7 @@ api_data_write(clicon_handle h,
if (ymoddata != ymodapi){
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -493,7 +493,7 @@ api_data_write(clicon_handle h,
if (strcmp(dname, xml_name(xbot))){
if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -518,7 +518,7 @@ api_data_write(clicon_handle h,
if (match_list_keys(ybot, xdata, xbot) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -542,7 +542,7 @@ api_data_write(clicon_handle h,
if (parbod == NULL || strcmp(parbod, xml_body(xdata))){
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -603,7 +603,7 @@ api_data_write(clicon_handle h,
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -616,14 +616,14 @@ api_data_write(clicon_handle h,
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
@ -646,7 +646,7 @@ api_data_write(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}
@ -840,7 +840,7 @@ api_data_delete(clicon_handle h,
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y, &xerr)) < 0)
goto done;
if (ret == 0){ /* validation failed */
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -871,7 +871,7 @@ api_data_delete(clicon_handle h,
cprintf(cbx, "</edit-config></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -885,14 +885,14 @@ api_data_delete(clicon_handle h,
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", clicon_nacm_recovery_user(h));
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
@ -915,7 +915,7 @@ api_data_delete(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}

View file

@ -130,7 +130,7 @@ api_data_get2(clicon_handle h,
if (netconf_bad_attribute_xml(&xerr, "application",
"<bad-attribute>content</bad-attribute>", "Unrecognized value of content attribute") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -152,7 +152,7 @@ api_data_get2(clicon_handle h,
if (netconf_bad_attribute_xml(&xerr, "application",
"<bad-attribute>depth</bad-attribute>", "Unrecognized value of depth attribute") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -172,7 +172,7 @@ api_data_get2(clicon_handle h,
if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &nsc, &xerr)) < 0)
goto done;
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -196,7 +196,7 @@ api_data_get2(clicon_handle h,
if (ret < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -218,7 +218,7 @@ api_data_get2(clicon_handle h,
}
#endif
/* Check if error return */
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -247,10 +247,10 @@ api_data_get2(clicon_handle h,
}
}
else{
if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){
if (netconf_operation_failed_xml(&xerr, "application", clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}

View file

@ -147,7 +147,7 @@ api_data_post(clicon_handle h,
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot, &xerr)) < 0)
goto done;
if (ret == 0){ /* validation failed */
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -171,7 +171,7 @@ api_data_post(clicon_handle h,
if (data == NULL || strlen(data) == 0){
if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -186,7 +186,7 @@ api_data_post(clicon_handle h,
if (xml_parse_string(data, NULL, &xdata0) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -208,7 +208,7 @@ api_data_post(clicon_handle h,
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -217,7 +217,7 @@ api_data_post(clicon_handle h,
goto ok;
}
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -237,7 +237,7 @@ api_data_post(clicon_handle h,
if (xml_child_nr(xdata0) != 1){
if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -268,7 +268,7 @@ api_data_post(clicon_handle h,
if (ys_real_module(ydata) != ymoddata){
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -282,7 +282,7 @@ api_data_post(clicon_handle h,
if (ybot && yang_parent_get(ydata) != ybot){
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -338,7 +338,7 @@ api_data_post(clicon_handle h,
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -352,14 +352,14 @@ api_data_post(clicon_handle h,
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) /* Use original xe */
goto done;
@ -382,7 +382,7 @@ api_data_post(clicon_handle h,
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}
@ -466,7 +466,7 @@ api_operations_post_input(clicon_handle h,
if (xml_parse_string(data, yspec, &xdata) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -479,7 +479,7 @@ api_operations_post_input(clicon_handle h,
if ((ret = json_parse_str(data, yspec, &xdata, &xerr)) < 0){
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -488,7 +488,7 @@ api_operations_post_input(clicon_handle h,
goto fail;
}
if (ret == 0){
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -527,7 +527,7 @@ api_operations_post_input(clicon_handle h,
else
if (netconf_malformed_message_xml(&xerr, "restconf RPC has malformed input statement (multiple or not called input)") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -601,7 +601,7 @@ api_operations_post_output(clicon_handle h,
xml_child_nr_type(xret, CX_ELMNT) != 1){
if (netconf_malformed_message_xml(&xerr, "restconf RPC does not have single input") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -639,7 +639,7 @@ api_operations_post_output(clicon_handle h,
(ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0)
goto done;
if (ret == 0){ /* validation failed */
if ((xe = xpath_first(xerr, "rpc-reply/rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-reply/rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -770,7 +770,7 @@ api_operations_post(clicon_handle h,
if (oppath == NULL || strcmp(oppath,"/")==0){
if (netconf_operation_failed_xml(&xerr, "protocol", "Operation name expected") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -789,7 +789,7 @@ api_operations_post(clicon_handle h,
if ((ys = yang_find(yspec, Y_MODULE, prefix)) == NULL){
if (netconf_operation_failed_xml(&xerr, "protocol", "yang module not found") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -800,7 +800,7 @@ api_operations_post(clicon_handle h,
if ((yrpc = yang_find(ys, Y_RPC, id)) == NULL){
if (netconf_missing_element_xml(&xerr, "application", id, "RPC not defined") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -826,7 +826,7 @@ api_operations_post(clicon_handle h,
if ((ret = api_path2xml(oppath, yspec, xtop, YC_SCHEMANODE, 1, &xbot, &y, &xerr)) < 0)
goto done;
if (ret == 0){ /* validation failed */
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
@ -867,7 +867,7 @@ api_operations_post(clicon_handle h,
if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0)
goto done;
if (ret == 0){
if ((xe = xpath_first(xret, "rpc-error")) == NULL){
if ((xe = xpath_first(xret, NULL, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto ok;
}
@ -900,7 +900,7 @@ api_operations_post(clicon_handle h,
if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0)
goto done;
/* Local error: return it and quit */
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -909,7 +909,7 @@ api_operations_post(clicon_handle h,
else { /* Send to backend */
if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0)
goto done;
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;

View file

@ -187,11 +187,11 @@ restconf_stream_cb(int s,
clicon_err(OE_PLUGIN, errno, "cbuf_new");
goto done;
}
if ((xn = xpath_first(xtop, "notification")) == NULL)
if ((xn = xpath_first(xtop, NULL, "notification")) == NULL)
goto ok;
#ifdef notused
xt = xpath_first(xn, "eventTime");
if ((xe = xpath_first(xn, "event")) == NULL) /* event can depend on yang? */
xt = xpath_first(xn, NULL, "eventTime");
if ((xe = xpath_first(xn, NULL, "event")) == NULL) /* event can depend on yang? */
goto ok;
if (xt)
@ -268,7 +268,7 @@ restconf_stream(clicon_handle h,
cprintf(cb, "</create-subscription></rpc>]]>]]>");
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0)
goto done;
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
@ -417,7 +417,7 @@ api_stream(clicon_handle h,
else{
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
goto done;
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
if (api_return_err(h, r, xerr, pretty, media_out, 0) < 0)
goto done;
goto ok;