Reverted some of the nsc xpath API changes. In the revert, xpath_first() and xpath_vec() retain their old syntax with nsc==NULL.
The reason is to be conservative with the API. However, less used functions, such as xpath_vec_bool(), xpath_vec_ctx() and xpath_vec_flag() are changed with a new `nsc`parameter, which should be set to NULL in most cases.
This commit is contained in:
parent
89f751357d
commit
40d5b99d3b
32 changed files with 391 additions and 266 deletions
16
CHANGELOG.md
16
CHANGELOG.md
|
|
@ -69,17 +69,18 @@
|
||||||
|
|
||||||
### API changes on existing features (you may need to change your code)
|
### API changes on existing features (you may need to change your code)
|
||||||
|
|
||||||
* The Clixon API has been extended with namespaces, or namespace contexts in the following cases [Netconf get/get-config :xpath capability does not support namespaces](https://github.com/clicon/clixon/issues/75)
|
* The Clixon API has been extended with namespaces, or namespace contexts in the following cases (see [README.md#xml-and-xpath] for explanation):
|
||||||
* CLIspec functions have added namespace parameter:
|
* CLIspec functions have added optional namespace parameter:
|
||||||
* `cli_show_config <db> <format> <xpath>` --> `cli_show_config <db> <format> <xpath> <namespace>`
|
* `cli_show_config <db> <format> <xpath>` --> `cli_show_config <db> <format> <xpath> <namespace>`
|
||||||
* `cli_copy_config <db> <xpath> ...` --> `cli_copy_config <db> <xpath> <namespace> ...`
|
* `cli_copy_config <db> <xpath> ...` --> `cli_copy_config <db> <xpath> <namespace> ...`
|
||||||
* Xpath API
|
* Change the following Xpath API functions (xpath_first and xpath_vec remain as-is):
|
||||||
* `xpath_first(x, format, ...)` --> `xpath_first(x, nsc, format, ...)`
|
* `xpath_vec_flag(x, format, flags, vec, veclen, ...)` --> `xpath_vec_flag(x, nsc, format, flags, vec, veclen, ...)`
|
||||||
* `xpath_vec(x, format, vec, veclen, ...)` --> `xpath_vec(x, nsc, format, vec, veclen, ...)`
|
|
||||||
* `xpath_vec_flag(x, format, flags, vec, veclen, ...)` --> `xpath_vec_flag(x, format, flags, vec, veclen, ...)`
|
|
||||||
* `xpath_vec_bool(x, format, ...)` --> `xpath_vec_bool(x, nsc, format, ...)`
|
* `xpath_vec_bool(x, format, ...)` --> `xpath_vec_bool(x, nsc, format, ...)`
|
||||||
* `xpath_vec_ctx(x, xpath, xp)` --> `xpath_vec_ctx(x, nsc, xpath, xp)`
|
* `xpath_vec_ctx(x, xpath, xp)` --> `xpath_vec_ctx(x, nsc, xpath, xp)`
|
||||||
* xmldb_get0 has an added `nsc` parameter:
|
* New Xpath API functions with namespace contexts:
|
||||||
|
* `xpath_first_nsc(x, nsc, format, ...)`
|
||||||
|
* `xpath_vec_nsc(x, nsc, format, vec, veclen, ...)`
|
||||||
|
* Change xmldb_get0 with added `nsc` parameter:
|
||||||
* `xmldb_get0(h, db, xpath, copy, xret, msd)` --> `xmldb_get0(h, db, nsc, xpath, copy, xret, msd)`
|
* `xmldb_get0(h, db, xpath, copy, xret, msd)` --> `xmldb_get0(h, db, nsc, xpath, copy, xret, msd)`
|
||||||
* The plugin statedata callback (ca_statedata) has been extended with an nsc parameter:
|
* The plugin statedata callback (ca_statedata) has been extended with an nsc parameter:
|
||||||
* `int example_statedata(clicon_handle h, cvec *nsc, char *xpath, cxobj *xstate);`
|
* `int example_statedata(clicon_handle h, cvec *nsc, char *xpath, cxobj *xstate);`
|
||||||
|
|
@ -104,7 +105,6 @@
|
||||||
```
|
```
|
||||||
curl -X PUT http://localhost/restconf/data/mod:a -d {"a":"x"}
|
curl -X PUT http://localhost/restconf/data/mod:a -d {"a":"x"}
|
||||||
```
|
```
|
||||||
* Undefine `RESTCONF_NS_DATA_CHECK` in include/clixon_custom.h to disable strict check.
|
|
||||||
* Many validation functions have changed error parameter from cbuf to xml tree.
|
* Many validation functions have changed error parameter from cbuf to xml tree.
|
||||||
* XML trees are more flexible for utility tools
|
* XML trees are more flexible for utility tools
|
||||||
* If you use these(mostly internal), you need to change the error function: `generic_validate, from_validate_common, xml_yang_validate_all_top, xml_yang_validate_all, xml_yang_validate_add, xml_yang_validate_rpc, xml_yang_validate_list_key_only`
|
* If you use these(mostly internal), you need to change the error function: `generic_validate, from_validate_common, xml_yang_validate_all_top, xml_yang_validate_all, xml_yang_validate_add, xml_yang_validate_rpc, xml_yang_validate_list_key_only`
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -131,14 +131,14 @@ The standards covered include:
|
||||||
- [Namespaces in XML 1.0](https://www.w3.org/TR/2009/REC-xml-names-20091208)
|
- [Namespaces in XML 1.0](https://www.w3.org/TR/2009/REC-xml-names-20091208)
|
||||||
- [XPATH 1.0](https://www.w3.org/TR/xpath-10)
|
- [XPATH 1.0](https://www.w3.org/TR/xpath-10)
|
||||||
|
|
||||||
Not supported:
|
Not supported in the XML:
|
||||||
- !DOCTYPE (ie DTD)
|
- !DOCTYPE (ie DTD)
|
||||||
|
|
||||||
The following xpath axes are supported:
|
The following XPATH axes are supported:
|
||||||
- CHILD, DESCENDANT, DESCENDANT_OR_SELF, SELF, and PARENT
|
- child, descendant, descendant_or_self, self, and parent
|
||||||
|
|
||||||
The following xpath axes are _not_ supported:
|
The following xpath axes are _not_ supported:
|
||||||
- PRECEEDING, PRECEEDING_SIBLING, NAMESPACE, FOLLOWING_SIBLING, FOLLOWING, ANCESTOR,ANCESTOR_OR_SELF, ATTRIBUTE
|
- preceeding, preceeding_sibling, namespace, following_sibling, following, ancestor,ancestor_or_self, and attribute
|
||||||
|
|
||||||
Note that base netconf namespace syntax is not enforced but recommended, which means that the following two expressions are treated equivalently:
|
Note that base netconf namespace syntax is not enforced but recommended, which means that the following two expressions are treated equivalently:
|
||||||
```
|
```
|
||||||
|
|
@ -157,7 +157,10 @@ XPATHs may contain prefixes. Example: `/if:a/if:b`. The prefixes have
|
||||||
associated namespaces. For example, `if` may be bound to
|
associated namespaces. For example, `if` may be bound to
|
||||||
`urn:ietf:params:xml:ns:yang:ietf-interfaces`. The prefix to namespace binding is called a _namespace context_ (nsc).
|
`urn:ietf:params:xml:ns:yang:ietf-interfaces`. The prefix to namespace binding is called a _namespace context_ (nsc).
|
||||||
|
|
||||||
|
In yang, the xpath and xml prefixes may not be well-known. For example, the import statement specifies a prefix to an imported module that is local in scope. Other modules may use another prefix. The module name and namespace however are unique.
|
||||||
|
|
||||||
In the Clixon API, there are two variants on namespace contexts: _implicit_ (given by the XML); or _explicit_ given by an external mapping.
|
In the Clixon API, there are two variants on namespace contexts: _implicit_ (given by the XML); or _explicit_ given by an external mapping.
|
||||||
|
|
||||||
#### 1. Implicit namespace mapping
|
#### 1. Implicit namespace mapping
|
||||||
|
|
||||||
Implicit mapping is typical for basic known XML, where the context is
|
Implicit mapping is typical for basic known XML, where the context is
|
||||||
|
|
@ -169,7 +172,8 @@ Example:
|
||||||
XML: <if:a xmlns:if="urn:example:if" xmlns:ip="urn:example:ip"><ip:b/></if>
|
XML: <if:a xmlns:if="urn:example:if" xmlns:ip="urn:example:ip"><ip:b/></if>
|
||||||
XPATH: /if:a/ip:b
|
XPATH: /if:a/ip:b
|
||||||
```
|
```
|
||||||
When you call an xpath API function, call it with nsc set to NULL. This is the default.
|
When you call an xpath API function, call it with nsc set to NULL, or use an API function without an nsc parameter.
|
||||||
|
This is the default and normal case.
|
||||||
|
|
||||||
#### 2. Explicit namespace mapping
|
#### 2. Explicit namespace mapping
|
||||||
|
|
||||||
|
|
@ -184,7 +188,7 @@ call. Example:
|
||||||
XML: <if:a xmlns:if="urn:example:if" xmlns:ip="urn:example:ip"><ip:b/></if>
|
XML: <if:a xmlns:if="urn:example:if" xmlns:ip="urn:example:ip"><ip:b/></if>
|
||||||
NETCONF:<get-config><filter select="/x:a/y:b" xmlns:x="urn:example:if" xmlns:y="urn:example:ip/>
|
NETCONF:<get-config><filter select="/x:a/y:b" xmlns:x="urn:example:if" xmlns:y="urn:example:ip/>
|
||||||
```
|
```
|
||||||
Here, x,y are prefixes used for two namespaces that are given by if,ip
|
Here, x,y are prefixes used for two namespaces that are given by `if,ip`
|
||||||
in the xml. In this case, the namespaces (eg `urn:example:if`) must be
|
in the xml. In this case, the namespaces (eg `urn:example:if`) must be
|
||||||
compared instead.
|
compared instead.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ client_statedata(clicon_handle h,
|
||||||
* Actually this is a safety catch, should realy be done in plugins
|
* Actually this is a safety catch, should realy be done in plugins
|
||||||
* and modules_state functions.
|
* and modules_state functions.
|
||||||
*/
|
*/
|
||||||
if (xpath_vec(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If vectors are specified then mark the nodes found and
|
/* If vectors are specified then mark the nodes found and
|
||||||
* then filter out everything else,
|
* then filter out everything else,
|
||||||
|
|
@ -363,7 +363,7 @@ from_client_get_config(clicon_handle h,
|
||||||
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
|
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* Do NACM validation */
|
if (ret == 0){ /* Do NACM validation */
|
||||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* NACM datanode/module read validation */
|
/* NACM datanode/module read validation */
|
||||||
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
|
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
|
||||||
|
|
@ -455,14 +455,14 @@ from_client_edit_config(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if ((x = xpath_first(xn, NULL, "default-operation")) != NULL){
|
if ((x = xpath_first(xn, "default-operation")) != NULL){
|
||||||
if (xml_operation(xml_body(x), &operation) < 0){
|
if (xml_operation(xml_body(x), &operation) < 0){
|
||||||
if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0)
|
if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((xc = xpath_first(xn, NULL, "config")) == NULL){
|
if ((xc = xpath_first(xn, "config")) == NULL){
|
||||||
if (netconf_missing_element(cbret, "protocol", "config", NULL) < 0)
|
if (netconf_missing_element(cbret, "protocol", "config", NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -858,7 +858,7 @@ from_client_get(clicon_handle h,
|
||||||
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
|
if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* Do NACM validation */
|
if (ret == 0){ /* Do NACM validation */
|
||||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* NACM datanode/module read validation */
|
/* NACM datanode/module read validation */
|
||||||
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
|
if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0)
|
||||||
|
|
@ -1016,9 +1016,9 @@ from_client_create_subscription(clicon_handle h,
|
||||||
|
|
||||||
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netmod:notification")) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netmod:notification")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if ((x = xpath_first(xe, nsc, "//stream")) != NULL)
|
if ((x = xpath_first_nsc(xe, nsc, "//stream")) != NULL)
|
||||||
stream = xml_find_value(x, "body");
|
stream = xml_find_value(x, "body");
|
||||||
if ((x = xpath_first(xe, nsc, "//stopTime")) != NULL){
|
if ((x = xpath_first_nsc(xe, nsc, "//stopTime")) != NULL){
|
||||||
if ((stoptime = xml_find_value(x, "body")) != NULL &&
|
if ((stoptime = xml_find_value(x, "body")) != NULL &&
|
||||||
str2time(stoptime, &stop) < 0){
|
str2time(stoptime, &stop) < 0){
|
||||||
if (netconf_bad_element(cbret, "application", "stopTime", "Expected timestamp") < 0)
|
if (netconf_bad_element(cbret, "application", "stopTime", "Expected timestamp") < 0)
|
||||||
|
|
@ -1026,7 +1026,7 @@ from_client_create_subscription(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((x = xpath_first(xe, nsc, "//startTime")) != NULL){
|
if ((x = xpath_first_nsc(xe, nsc, "//startTime")) != NULL){
|
||||||
if ((starttime = xml_find_value(x, "body")) != NULL &&
|
if ((starttime = xml_find_value(x, "body")) != NULL &&
|
||||||
str2time(starttime, &start) < 0){
|
str2time(starttime, &start) < 0){
|
||||||
if (netconf_bad_element(cbret, "application", "startTime", "Expected timestamp") < 0)
|
if (netconf_bad_element(cbret, "application", "startTime", "Expected timestamp") < 0)
|
||||||
|
|
@ -1034,7 +1034,7 @@ from_client_create_subscription(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((xfilter = xpath_first(xe, nsc, "//filter")) != NULL){
|
if ((xfilter = xpath_first_nsc(xe, nsc, "//filter")) != NULL){
|
||||||
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
|
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
|
||||||
/* Only accept xpath as filter type */
|
/* Only accept xpath as filter type */
|
||||||
if (strcmp(ftype, "xpath") != 0){
|
if (strcmp(ftype, "xpath") != 0){
|
||||||
|
|
@ -1175,7 +1175,7 @@ from_client_msg(clicon_handle h,
|
||||||
goto reply;
|
goto reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x = xpath_first(xt, NULL, "/rpc")) == NULL){
|
if ((x = xpath_first_nsc(xt, NULL, "/rpc")) == NULL){
|
||||||
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
|
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto reply;
|
goto reply;
|
||||||
|
|
|
||||||
|
|
@ -682,13 +682,13 @@ compare_dbs(clicon_handle h,
|
||||||
astext = 0;
|
astext = 0;
|
||||||
if (clicon_rpc_get_config(h, "running", "/", NULL, &xc1) < 0)
|
if (clicon_rpc_get_config(h, "running", "/", NULL, &xc1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_rpc_get_config(h, "candidate", "/", NULL, &xc2) < 0)
|
if (clicon_rpc_get_config(h, "candidate", "/", NULL, &xc2) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -853,7 +853,7 @@ save_config_file(clicon_handle h,
|
||||||
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
|
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -961,7 +961,7 @@ cli_notification_cb(int s,
|
||||||
}
|
}
|
||||||
if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */
|
if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xt, NULL, "//event")) != NULL){
|
if ((xe = xpath_first(xt, "//event")) != NULL){
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xe, x, -1)) != NULL) {
|
while ((x = xml_child_each(xe, x, -1)) != NULL) {
|
||||||
switch (format){
|
switch (format){
|
||||||
|
|
@ -1191,7 +1191,7 @@ cli_copy_config(clicon_handle h,
|
||||||
/* Get from object configuration and store in x1 */
|
/* Get from object configuration and store in x1 */
|
||||||
if (clicon_rpc_get_config(h, db, cbuf_get(cb), namespace, &x1) < 0)
|
if (clicon_rpc_get_config(h, db, cbuf_get(cb), namespace, &x1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1211,7 +1211,7 @@ cli_copy_config(clicon_handle h,
|
||||||
cprintf(cb, "/%s", keyname);
|
cprintf(cb, "/%s", keyname);
|
||||||
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if ((x = xpath_first(x2, nsc, "%s", cbuf_get(cb))) == NULL){
|
if ((x = xpath_first_nsc(x2, nsc, "%s", cbuf_get(cb))) == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
|
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ expand_dbvar(void *h,
|
||||||
/* Get configuration */
|
/* Get configuration */
|
||||||
if (clicon_rpc_get_config(h, dbstr, xpath, namespace, &xt) < 0) /* XXX */
|
if (clicon_rpc_get_config(h, dbstr, xpath, namespace, &xt) < 0) /* XXX */
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
@ -198,12 +198,12 @@ expand_dbvar(void *h,
|
||||||
fprintf(stderr, "%s\n", reason);
|
fprintf(stderr, "%s\n", reason);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xcur = xpath_first(xt, nsc, "%s", xpath)) == NULL){
|
if ((xcur = xpath_first_nsc(xt, nsc, "%s", xpath)) == NULL){
|
||||||
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
|
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xpath_vec(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0)
|
if (xpath_vec_nsc(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
bodystr0 = NULL; /* Assume sorted XML where duplicates are adjacent */
|
bodystr0 = NULL; /* Assume sorted XML where duplicates are adjacent */
|
||||||
for (i = 0; i < xlen; i++) {
|
for (i = 0; i < xlen; i++) {
|
||||||
|
|
@ -463,7 +463,7 @@ cli_show_config1(clicon_handle h,
|
||||||
if (clicon_rpc_get(h, cbuf_get(cbxpath), namespace, &xt) < 0)
|
if (clicon_rpc_get(h, cbuf_get(cbxpath), namespace, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -608,13 +608,13 @@ show_conf_xpath(clicon_handle h,
|
||||||
|
|
||||||
if (clicon_rpc_get_config(h, str, xpath, namespace, &xt) < 0)
|
if (clicon_rpc_get_config(h, str, xpath, namespace, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_vec(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
|
if (xpath_vec_nsc(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<xlen; i++)
|
for (i=0; i<xlen; i++)
|
||||||
xml_print(stdout, xv[i]);
|
xml_print(stdout, xv[i]);
|
||||||
|
|
@ -715,11 +715,11 @@ cli_show_auto1(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL)
|
if ((xp = xpath_first_nsc(xt, nsc, "%s", xpath)) != NULL)
|
||||||
/* Print configuration according to format */
|
/* Print configuration according to format */
|
||||||
switch (format){
|
switch (format){
|
||||||
case FORMAT_XML:
|
case FORMAT_XML:
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ netconf_hello_dispatch(cxobj *xn)
|
||||||
cxobj *xp;
|
cxobj *xp;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if ((xp = xpath_first(xn, NULL, "//hello")) != NULL)
|
if ((xp = xpath_first(xn, "//hello")) != NULL)
|
||||||
retval = netconf_hello(xp);
|
retval = netconf_hello(xp);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,14 +164,14 @@ netconf_get_target(cxobj *xn,
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
char *target = NULL;
|
char *target = NULL;
|
||||||
|
|
||||||
if ((x = xpath_first(xn, NULL, "%s", path)) != NULL){
|
if ((x = xpath_first(xn, "%s", path)) != NULL){
|
||||||
if (xpath_first(x, NULL, "candidate") != NULL)
|
if (xpath_first(x, "candidate") != NULL)
|
||||||
target = "candidate";
|
target = "candidate";
|
||||||
else
|
else
|
||||||
if (xpath_first(x, NULL, "running") != NULL)
|
if (xpath_first(x, "running") != NULL)
|
||||||
target = "running";
|
target = "running";
|
||||||
else
|
else
|
||||||
if (xpath_first(x, NULL, "startup") != NULL)
|
if (xpath_first(x, "startup") != NULL)
|
||||||
target = "startup";
|
target = "startup";
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ netconf_input_packet(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
free(str0);
|
free(str0);
|
||||||
if ((xrpc=xpath_first(xreq, NULL, "//rpc")) != NULL){
|
if ((xrpc=xpath_first(xreq, "//rpc")) != NULL){
|
||||||
isrpc++;
|
isrpc++;
|
||||||
if (xml_spec_populate_rpc(h, xrpc, yspec) < 0)
|
if (xml_spec_populate_rpc(h, xrpc, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -134,7 +134,7 @@ netconf_input_packet(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (xpath_first(xreq, NULL, "//hello") != NULL)
|
if (xpath_first(xreq, "//hello") != NULL)
|
||||||
;
|
;
|
||||||
else{
|
else{
|
||||||
clicon_log(LOG_WARNING, "Invalid netconf msg: neither rpc or hello: dropped");
|
clicon_log(LOG_WARNING, "Invalid netconf msg: neither rpc or hello: dropped");
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ netconf_get_config(clicon_handle h,
|
||||||
cxobj *xconf;
|
cxobj *xconf;
|
||||||
|
|
||||||
/* ie <filter>...</filter> */
|
/* ie <filter>...</filter> */
|
||||||
if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL)
|
if ((xfilter = xpath_first(xn, "filter")) != NULL)
|
||||||
ftype = xml_find_value(xfilter, "type");
|
ftype = xml_find_value(xfilter, "type");
|
||||||
if (ftype == NULL || strcmp(ftype, "xpath")==0){
|
if (ftype == NULL || strcmp(ftype, "xpath")==0){
|
||||||
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
||||||
|
|
@ -154,8 +154,8 @@ netconf_get_config(clicon_handle h,
|
||||||
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xfilter &&
|
if (xfilter &&
|
||||||
(xfilterconf = xpath_first(xfilter, NULL, "//configuration"))!= NULL &&
|
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
|
||||||
(xconf = xpath_first(*xret, NULL, "/rpc-reply/data")) != NULL){
|
(xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
|
||||||
/* xml_filter removes parts of xml tree not matching */
|
/* xml_filter removes parts of xml tree not matching */
|
||||||
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
|
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
|
||||||
xml_filter(xfilterconf, xconf) < 0){
|
xml_filter(xfilterconf, xconf) < 0){
|
||||||
|
|
@ -208,7 +208,7 @@ get_edit_opts(cxobj *xn,
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
char *optstr;
|
char *optstr;
|
||||||
|
|
||||||
if ((x = xpath_first(xn, NULL, "test-option")) != NULL){
|
if ((x = xpath_first(xn, "test-option")) != NULL){
|
||||||
if ((optstr = xml_body(x)) != NULL){
|
if ((optstr = xml_body(x)) != NULL){
|
||||||
if (strcmp(optstr, "test-then-set") == 0)
|
if (strcmp(optstr, "test-then-set") == 0)
|
||||||
*testopt = TEST_THEN_SET;
|
*testopt = TEST_THEN_SET;
|
||||||
|
|
@ -220,7 +220,7 @@ get_edit_opts(cxobj *xn,
|
||||||
goto parerr;
|
goto parerr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((x = xpath_first(xn, NULL, "error-option")) != NULL){
|
if ((x = xpath_first(xn, "error-option")) != NULL){
|
||||||
if ((optstr = xml_body(x)) != NULL){
|
if ((optstr = xml_body(x)) != NULL){
|
||||||
if (strcmp(optstr, "stop-on-error") == 0)
|
if (strcmp(optstr, "stop-on-error") == 0)
|
||||||
*erropt = STOP_ON_ERROR;
|
*erropt = STOP_ON_ERROR;
|
||||||
|
|
@ -352,7 +352,7 @@ netconf_get(clicon_handle h,
|
||||||
cxobj *xconf;
|
cxobj *xconf;
|
||||||
|
|
||||||
/* ie <filter>...</filter> */
|
/* ie <filter>...</filter> */
|
||||||
if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL)
|
if ((xfilter = xpath_first(xn, "filter")) != NULL)
|
||||||
ftype = xml_find_value(xfilter, "type");
|
ftype = xml_find_value(xfilter, "type");
|
||||||
if (ftype == NULL || strcmp(ftype, "xpath")==0){
|
if (ftype == NULL || strcmp(ftype, "xpath")==0){
|
||||||
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
||||||
|
|
@ -366,8 +366,8 @@ netconf_get(clicon_handle h,
|
||||||
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xfilter &&
|
if (xfilter &&
|
||||||
(xfilterconf = xpath_first(xfilter, NULL, "//configuration"))!= NULL &&
|
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
|
||||||
(xconf = xpath_first(*xret, NULL, "/rpc-reply/data")) != NULL){
|
(xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
|
||||||
/* xml_filter removes parts of xml tree not matching */
|
/* xml_filter removes parts of xml tree not matching */
|
||||||
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
|
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
|
||||||
xml_filter(xfilterconf, xconf) < 0){
|
xml_filter(xfilterconf, xconf) < 0){
|
||||||
|
|
@ -448,7 +448,7 @@ netconf_notification_cb(int s,
|
||||||
|
|
||||||
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xn = xpath_first(xt, nsc, "notification")) == NULL)
|
if ((xn = xpath_first_nsc(xt, nsc, "notification")) == NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
/* create netconf message */
|
/* create netconf message */
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
|
@ -500,7 +500,7 @@ netconf_create_subscription(clicon_handle h,
|
||||||
int s;
|
int s;
|
||||||
char *ftype;
|
char *ftype;
|
||||||
|
|
||||||
if ((xfilter = xpath_first(xn, NULL, "//filter")) != NULL){
|
if ((xfilter = xpath_first(xn, "//filter")) != NULL){
|
||||||
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
|
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
|
||||||
if (strcmp(ftype, "xpath") != 0){
|
if (strcmp(ftype, "xpath") != 0){
|
||||||
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
|
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
|
||||||
|
|
@ -516,7 +516,7 @@ netconf_create_subscription(clicon_handle h,
|
||||||
}
|
}
|
||||||
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, &s) < 0)
|
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, &s) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_first(*xret, NULL, "rpc-reply/rpc-error") != NULL)
|
if (xpath_first(*xret, "rpc-reply/rpc-error") != NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
if (event_reg_fd(s,
|
if (event_reg_fd(s,
|
||||||
netconf_notification_cb,
|
netconf_notification_cb,
|
||||||
|
|
@ -622,7 +622,7 @@ netconf_application_rpc(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
if (0)
|
if (0)
|
||||||
if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){
|
if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){
|
||||||
xoutput=xpath_first(*xret, NULL, "/");
|
xoutput=xpath_first(*xret, "/");
|
||||||
xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */
|
xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */
|
||||||
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,7 @@ api_return_err(clicon_handle h,
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if ((cb = cbuf_new()) == NULL)
|
if ((cb = cbuf_new()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xtag = xpath_first(xerr, NULL, "//error-tag")) == NULL){
|
if ((xtag = xpath_first(xerr, "//error-tag")) == NULL){
|
||||||
notfound(r);
|
notfound(r);
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -396,7 +396,7 @@ api_restconf(clicon_handle h,
|
||||||
else{
|
else{
|
||||||
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
|
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ api_data_get2(clicon_handle h,
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +229,7 @@ api_data_get2(clicon_handle h,
|
||||||
if (clicon_rpc_get(h, xpath, namespace, &xret) < 0){
|
if (clicon_rpc_get(h, xpath, namespace, &xret) < 0){
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +251,7 @@ api_data_get2(clicon_handle h,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Check if error return */
|
/* Check if error return */
|
||||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -276,10 +276,10 @@ api_data_get2(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){
|
if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){
|
||||||
if (netconf_operation_failed_xml(&xerr, "application", clicon_err_reason) < 0)
|
if (netconf_operation_failed_xml(&xerr, "application", clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -465,10 +465,8 @@ api_data_post(clicon_handle h,
|
||||||
cxobj *xtop = NULL; /* top of api-path */
|
cxobj *xtop = NULL; /* top of api-path */
|
||||||
cxobj *xbot = NULL; /* bottom of api-path */
|
cxobj *xbot = NULL; /* bottom of api-path */
|
||||||
yang_stmt *ybot = NULL; /* yang of xbot */
|
yang_stmt *ybot = NULL; /* yang of xbot */
|
||||||
#ifdef RESTCONF_NS_DATA_CHECK
|
|
||||||
yang_stmt *ymodapi = NULL; /* yang module of api-path (if any) */
|
yang_stmt *ymodapi = NULL; /* yang module of api-path (if any) */
|
||||||
yang_stmt *ymoddata = NULL; /* yang module of data (-d) */
|
yang_stmt *ymoddata = NULL; /* yang module of data (-d) */
|
||||||
#endif
|
|
||||||
yang_stmt *yspec;
|
yang_stmt *yspec;
|
||||||
cxobj *xa;
|
cxobj *xa;
|
||||||
cxobj *xret = NULL;
|
cxobj *xret = NULL;
|
||||||
|
|
@ -496,15 +494,13 @@ api_data_post(clicon_handle h,
|
||||||
if (api_path){
|
if (api_path){
|
||||||
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot)) < 0)
|
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#ifdef RESTCONF_NS_DATA_CHECK
|
|
||||||
if (ybot)
|
if (ybot)
|
||||||
ymodapi=ys_module(ybot);
|
ymodapi=ys_module(ybot);
|
||||||
#endif
|
|
||||||
if (ret == 0){ /* validation failed */
|
if (ret == 0){ /* validation failed */
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -518,7 +514,7 @@ api_data_post(clicon_handle h,
|
||||||
if (xml_parse_string(data, NULL, &xdata0) < 0){
|
if (xml_parse_string(data, NULL, &xdata0) < 0){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -531,7 +527,7 @@ api_data_post(clicon_handle h,
|
||||||
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
|
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -540,7 +536,7 @@ api_data_post(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -555,7 +551,7 @@ api_data_post(clicon_handle h,
|
||||||
if (xml_child_nr(xdata0) != 1){
|
if (xml_child_nr(xdata0) != 1){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -564,7 +560,6 @@ api_data_post(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
xdata = xml_child_i(xdata0,0);
|
xdata = xml_child_i(xdata0,0);
|
||||||
#ifdef RESTCONF_NS_DATA_CHECK
|
|
||||||
/* If the api-path (above) defines a module, then xdata must have a prefix
|
/* If the api-path (above) defines a module, then xdata must have a prefix
|
||||||
* and it match the module defined in api-path.
|
* and it match the module defined in api-path.
|
||||||
* In a POST, maybe there are cornercases where xdata (which is a child) and
|
* In a POST, maybe there are cornercases where xdata (which is a child) and
|
||||||
|
|
@ -577,7 +572,7 @@ api_data_post(clicon_handle h,
|
||||||
if (ymoddata != ymodapi){
|
if (ymoddata != ymodapi){
|
||||||
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
|
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -594,7 +589,6 @@ api_data_post(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* RESTCONF_NS_DATA_CHECK */
|
|
||||||
|
|
||||||
/* Add operation (create/replace) as attribute */
|
/* Add operation (create/replace) as attribute */
|
||||||
if ((xa = xml_new("operation", xdata, NULL)) == NULL)
|
if ((xa = xml_new("operation", xdata, NULL)) == NULL)
|
||||||
|
|
@ -620,7 +614,7 @@ api_data_post(clicon_handle h,
|
||||||
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
|
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)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -634,14 +628,14 @@ api_data_post(clicon_handle h,
|
||||||
cprintf(cbx, "<commit/></rpc>");
|
cprintf(cbx, "<commit/></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
|
||||||
cbuf_reset(cbx);
|
cbuf_reset(cbx);
|
||||||
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
|
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
|
||||||
cprintf(cbx, "<discard-changes/></rpc>");
|
cprintf(cbx, "<discard-changes/></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* log errors from discard, but ignore */
|
/* log errors from discard, but ignore */
|
||||||
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
|
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
|
||||||
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
|
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, use_xml, 0) < 0) /* Use original xe */
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) /* Use original xe */
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -664,7 +658,7 @@ api_data_post(clicon_handle h,
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If copy-config failed, log and ignore (already committed) */
|
/* If copy-config failed, log and ignore (already committed) */
|
||||||
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
|
||||||
|
|
||||||
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
@ -809,10 +803,8 @@ api_data_put(clicon_handle h,
|
||||||
cxobj *xtop = NULL; /* top of api-path */
|
cxobj *xtop = NULL; /* top of api-path */
|
||||||
cxobj *xbot = NULL; /* bottom of api-path */
|
cxobj *xbot = NULL; /* bottom of api-path */
|
||||||
yang_stmt *ybot = NULL; /* yang of xbot */
|
yang_stmt *ybot = NULL; /* yang of xbot */
|
||||||
#ifdef RESTCONF_NS_DATA_CHECK
|
|
||||||
yang_stmt *ymodapi = NULL; /* yang module of api-path (if any) */
|
yang_stmt *ymodapi = NULL; /* yang module of api-path (if any) */
|
||||||
yang_stmt *ymoddata = NULL; /* yang module of data (-d) */
|
yang_stmt *ymoddata = NULL; /* yang module of data (-d) */
|
||||||
#endif
|
|
||||||
cxobj *xparent;
|
cxobj *xparent;
|
||||||
yang_stmt *yp; /* yang parent */
|
yang_stmt *yp; /* yang parent */
|
||||||
yang_stmt *yspec;
|
yang_stmt *yspec;
|
||||||
|
|
@ -845,15 +837,13 @@ api_data_put(clicon_handle h,
|
||||||
if (api_path){
|
if (api_path){
|
||||||
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot)) < 0)
|
if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#ifdef RESTCONF_NS_DATA_CHECK
|
|
||||||
if (ybot)
|
if (ybot)
|
||||||
ymodapi=ys_module(ybot);
|
ymodapi=ys_module(ybot);
|
||||||
#endif
|
|
||||||
if (ret == 0){ /* validation failed */
|
if (ret == 0){ /* validation failed */
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -868,7 +858,7 @@ api_data_put(clicon_handle h,
|
||||||
if (xml_parse_string(data, yspec, &xdata0) < 0){
|
if (xml_parse_string(data, yspec, &xdata0) < 0){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -881,7 +871,7 @@ api_data_put(clicon_handle h,
|
||||||
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
|
if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -890,7 +880,7 @@ api_data_put(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -905,7 +895,7 @@ api_data_put(clicon_handle h,
|
||||||
if (xml_child_nr(xdata0) != 1){
|
if (xml_child_nr(xdata0) != 1){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -914,7 +904,6 @@ api_data_put(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
xdata = xml_child_i(xdata0,0);
|
xdata = xml_child_i(xdata0,0);
|
||||||
#ifdef RESTCONF_NS_DATA_CHECK
|
|
||||||
/* If the api-path (above) defines a module, then xdata must have a prefix
|
/* If the api-path (above) defines a module, then xdata must have a prefix
|
||||||
* and it match the module defined in api-path
|
* and it match the module defined in api-path
|
||||||
* This does not apply if api-path is / (no module)
|
* This does not apply if api-path is / (no module)
|
||||||
|
|
@ -925,7 +914,7 @@ api_data_put(clicon_handle h,
|
||||||
if (ymoddata != ymodapi){
|
if (ymoddata != ymodapi){
|
||||||
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
|
if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -934,7 +923,6 @@ api_data_put(clicon_handle h,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* RESTCONF_NS_DATA_CHECK */
|
|
||||||
|
|
||||||
/* Add operation (create/replace) as attribute */
|
/* Add operation (create/replace) as attribute */
|
||||||
if ((xa = xml_new("operation", xdata, NULL)) == NULL)
|
if ((xa = xml_new("operation", xdata, NULL)) == NULL)
|
||||||
|
|
@ -965,7 +953,7 @@ api_data_put(clicon_handle h,
|
||||||
if (strcmp(dname, xml_name(xbot))){
|
if (strcmp(dname, xml_name(xbot))){
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -990,7 +978,7 @@ api_data_put(clicon_handle h,
|
||||||
if (match_list_keys(ybot, xdata, xbot) < 0){
|
if (match_list_keys(ybot, xdata, xbot) < 0){
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1014,7 +1002,7 @@ api_data_put(clicon_handle h,
|
||||||
if (parbod == NULL || strcmp(parbod, xml_body(xdata))){
|
if (parbod == NULL || strcmp(parbod, xml_body(xdata))){
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1053,7 +1041,7 @@ api_data_put(clicon_handle h,
|
||||||
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
|
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)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -1066,14 +1054,14 @@ api_data_put(clicon_handle h,
|
||||||
cprintf(cbx, "<commit/></rpc>");
|
cprintf(cbx, "<commit/></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
|
||||||
cbuf_reset(cbx);
|
cbuf_reset(cbx);
|
||||||
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
|
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
|
||||||
cprintf(cbx, "<discard-changes/></rpc>");
|
cprintf(cbx, "<discard-changes/></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* log errors from discard, but ignore */
|
/* log errors from discard, but ignore */
|
||||||
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
|
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
|
||||||
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
|
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, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1096,7 +1084,7 @@ api_data_put(clicon_handle h,
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If copy-config failed, log and ignore (already committed) */
|
/* If copy-config failed, log and ignore (already committed) */
|
||||||
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
|
||||||
|
|
||||||
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
@ -1204,7 +1192,7 @@ api_data_delete(clicon_handle h,
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1231,7 +1219,7 @@ api_data_delete(clicon_handle h,
|
||||||
cprintf(cbx, "</edit-config></rpc>");
|
cprintf(cbx, "</edit-config></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -1245,14 +1233,14 @@ api_data_delete(clicon_handle h,
|
||||||
cprintf(cbx, "<commit/></rpc>");
|
cprintf(cbx, "<commit/></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
|
||||||
cbuf_reset(cbx);
|
cbuf_reset(cbx);
|
||||||
cprintf(cbx, "<rpc username=\"%s\">", NACM_RECOVERY_USER);
|
cprintf(cbx, "<rpc username=\"%s\">", NACM_RECOVERY_USER);
|
||||||
cprintf(cbx, "<discard-changes/></rpc>");
|
cprintf(cbx, "<discard-changes/></rpc>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* log errors from discard, but ignore */
|
/* log errors from discard, but ignore */
|
||||||
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
|
if ((xpath_first(xretdis, "//rpc-error")) != NULL)
|
||||||
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
|
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, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1275,7 +1263,7 @@ api_data_delete(clicon_handle h,
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If copy-config failed, log and ignore (already committed) */
|
/* If copy-config failed, log and ignore (already committed) */
|
||||||
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
|
if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){
|
||||||
|
|
||||||
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
@ -1442,7 +1430,7 @@ api_operations_post_input(clicon_handle h,
|
||||||
if (xml_parse_string(data, yspec, &xdata) < 0){
|
if (xml_parse_string(data, yspec, &xdata) < 0){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1455,7 +1443,7 @@ api_operations_post_input(clicon_handle h,
|
||||||
if ((ret = json_parse_str(data, yspec, &xdata, &xerr)) < 0){
|
if ((ret = json_parse_str(data, yspec, &xdata, &xerr)) < 0){
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1464,7 +1452,7 @@ api_operations_post_input(clicon_handle h,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1497,7 +1485,7 @@ api_operations_post_input(clicon_handle h,
|
||||||
else
|
else
|
||||||
if (netconf_malformed_message_xml(&xerr, "restconf RPC has malformed input statement (multiple or not called input)") < 0)
|
if (netconf_malformed_message_xml(&xerr, "restconf RPC has malformed input statement (multiple or not called input)") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1571,7 +1559,7 @@ api_operations_post_output(clicon_handle h,
|
||||||
xml_child_nr_type(xret, CX_ELMNT) != 1){
|
xml_child_nr_type(xret, CX_ELMNT) != 1){
|
||||||
if (netconf_malformed_message_xml(&xerr, "restconf RPC does not have single input") < 0)
|
if (netconf_malformed_message_xml(&xerr, "restconf RPC does not have single input") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1608,7 +1596,7 @@ api_operations_post_output(clicon_handle h,
|
||||||
(ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0)
|
(ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* validation failed */
|
if (ret == 0){ /* validation failed */
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-reply/rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-reply/rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1741,7 +1729,7 @@ api_operations_post(clicon_handle h,
|
||||||
if (oppath == NULL || strcmp(oppath,"/")==0){
|
if (oppath == NULL || strcmp(oppath,"/")==0){
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", "Operation name expected") < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", "Operation name expected") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1760,7 +1748,7 @@ api_operations_post(clicon_handle h,
|
||||||
if ((ys = yang_find(yspec, Y_MODULE, prefix)) == NULL){
|
if ((ys = yang_find(yspec, Y_MODULE, prefix)) == NULL){
|
||||||
if (netconf_operation_failed_xml(&xerr, "protocol", "yang module not found") < 0)
|
if (netconf_operation_failed_xml(&xerr, "protocol", "yang module not found") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1771,7 +1759,7 @@ api_operations_post(clicon_handle h,
|
||||||
if ((yrpc = yang_find(ys, Y_RPC, id)) == NULL){
|
if ((yrpc = yang_find(ys, Y_RPC, id)) == NULL){
|
||||||
if (netconf_missing_element_xml(&xerr, "application", id, "RPC not defined") < 0)
|
if (netconf_missing_element_xml(&xerr, "application", id, "RPC not defined") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1800,7 +1788,7 @@ api_operations_post(clicon_handle h,
|
||||||
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1840,7 +1828,7 @@ api_operations_post(clicon_handle h,
|
||||||
if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0)
|
if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
if ((xe = xpath_first(xret, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xret, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
@ -1872,7 +1860,7 @@ api_operations_post(clicon_handle h,
|
||||||
if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0)
|
if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Local error: return it and quit */
|
/* Local error: return it and quit */
|
||||||
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -1881,7 +1869,7 @@ api_operations_post(clicon_handle h,
|
||||||
else { /* Send to backend */
|
else { /* Send to backend */
|
||||||
if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0)
|
if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
|
||||||
|
|
@ -187,11 +187,11 @@ restconf_stream_cb(int s,
|
||||||
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xn = xpath_first(xtop, NULL, "notification")) == NULL)
|
if ((xn = xpath_first(xtop, "notification")) == NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
#ifdef notused
|
#ifdef notused
|
||||||
xt = xpath_first(xn, NULL, "eventTime");
|
xt = xpath_first(xn, "eventTime");
|
||||||
if ((xe = xpath_first(xn, NULL, "event")) == NULL) /* event can depend on yang? */
|
if ((xe = xpath_first(xn, "event")) == NULL) /* event can depend on yang? */
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
||||||
if (xt)
|
if (xt)
|
||||||
|
|
@ -268,7 +268,7 @@ restconf_stream(clicon_handle h,
|
||||||
cprintf(cb, "</create-subscription></rpc>]]>]]>");
|
cprintf(cb, "</create-subscription></rpc>]]>]]>");
|
||||||
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0)
|
if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){
|
if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -416,7 +416,7 @@ api_stream(clicon_handle h,
|
||||||
else{
|
else{
|
||||||
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
|
if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0)
|
if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
|
||||||
|
|
@ -480,7 +480,7 @@ You use XPATHs on the XML trees in the transaction commit callback.
|
||||||
Suppose you want to print all added interfaces:
|
Suppose you want to print all added interfaces:
|
||||||
```
|
```
|
||||||
cxobj *target = transaction_target(td); # wanted XML tree
|
cxobj *target = transaction_target(td); # wanted XML tree
|
||||||
vec = xpath_vec_flag(target, "//interface", &len, XML_FLAG_ADD); /* Get added i/fs */
|
vec = xpath_vec_flag(target, NULL, "//interface", &len, XML_FLAG_ADD); /* Get added i/fs */
|
||||||
for (i=0; i<len; i++) /* Loop over added i/fs */
|
for (i=0; i<len; i++) /* Loop over added i/fs */
|
||||||
clicon_xml2file(stdout, vec[i], 0, 1); /* Print the added interface */
|
clicon_xml2file(stdout, vec[i], 0, 1); /* Print the added interface */
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ main_commit(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Get all added i/fs */
|
/* Get all added i/fs */
|
||||||
if (xpath_vec_flag(target, NULL, "//interface", XML_FLAG_ADD, &vec, &len) < 0)
|
if (xpath_vec_flag(target, nsc, "//interface", XML_FLAG_ADD, &vec, &len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (debug)
|
if (debug)
|
||||||
for (i=0; i<len; i++) /* Loop over added i/fs */
|
for (i=0; i<len; i++) /* Loop over added i/fs */
|
||||||
|
|
@ -319,7 +319,7 @@ example_statedata(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
if ((nsc1 = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:yang:ietf-interfaces")) == NULL)
|
if ((nsc1 = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:yang:ietf-interfaces")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_vec(xt, nsc1, "/interfaces/interface/name", &xvec, &xlen) < 0)
|
if (xpath_vec_nsc(xt, nsc1, "/interfaces/interface/name", &xvec, &xlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xlen){
|
if (xlen){
|
||||||
cprintf(cb, "<interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\">");
|
cprintf(cb, "<interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\">");
|
||||||
|
|
@ -415,7 +415,7 @@ upgrade_2016(clicon_handle h,
|
||||||
if ((name = xml_find_body(xi, "name")) == NULL)
|
if ((name = xml_find_body(xi, "name")) == NULL)
|
||||||
continue; /* shouldnt happen */
|
continue; /* shouldnt happen */
|
||||||
/* Get corresponding /interfaces/interface entry */
|
/* Get corresponding /interfaces/interface entry */
|
||||||
xif = xpath_first(xt, NULL, "/interfaces/interface[name=\"%s\"]", name);
|
xif = xpath_first(xt, "/interfaces/interface[name=\"%s\"]", name);
|
||||||
/* - Move /if:interfaces-state/if:interface/if:admin-status to
|
/* - Move /if:interfaces-state/if:interface/if:admin-status to
|
||||||
* /if:interfaces/if:interface/ */
|
* /if:interfaces/if:interface/ */
|
||||||
if ((x = xml_find(xi, "admin-status")) != NULL && xif){
|
if ((x = xml_find(xi, "admin-status")) != NULL && xif){
|
||||||
|
|
@ -518,7 +518,7 @@ upgrade_2018(clicon_handle h,
|
||||||
/* Change type /interfaces/interface/statistics/in-octets to
|
/* Change type /interfaces/interface/statistics/in-octets to
|
||||||
* decimal64 with fraction-digits 3 and divide values with 1000
|
* decimal64 with fraction-digits 3 and divide values with 1000
|
||||||
*/
|
*/
|
||||||
if ((x = xpath_first(xi, NULL, "statistics/in-octets")) != NULL){
|
if ((x = xpath_first(xi, "statistics/in-octets")) != NULL){
|
||||||
if ((xb = xml_body_get(x)) != NULL){
|
if ((xb = xml_body_get(x)) != NULL){
|
||||||
uint64_t u64;
|
uint64_t u64;
|
||||||
cbuf *cb = cbuf_new();
|
cbuf *cb = cbuf_new();
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ nacm_validate(clicon_handle h,
|
||||||
if (_transaction_log){
|
if (_transaction_log){
|
||||||
transaction_log(h, td, LOG_NOTICE, __FUNCTION__);
|
transaction_log(h, td, LOG_NOTICE, __FUNCTION__);
|
||||||
if (_transaction_error_toggle==0 &&
|
if (_transaction_error_toggle==0 &&
|
||||||
xpath_first(transaction_target(td), NULL, "%s", _transaction_xpath)){
|
xpath_first(transaction_target(td), "%s", _transaction_xpath)){
|
||||||
_transaction_error_toggle=1; /* toggle if triggered */
|
_transaction_error_toggle=1; /* toggle if triggered */
|
||||||
clicon_err(OE_XML, 0, "User error");
|
clicon_err(OE_XML, 0, "User error");
|
||||||
return -1; /* induce fail */
|
return -1; /* induce fail */
|
||||||
|
|
@ -116,7 +116,7 @@ nacm_commit(clicon_handle h,
|
||||||
if (_transaction_log){
|
if (_transaction_log){
|
||||||
transaction_log(h, td, LOG_NOTICE, __FUNCTION__);
|
transaction_log(h, td, LOG_NOTICE, __FUNCTION__);
|
||||||
if (_transaction_error_toggle==1 &&
|
if (_transaction_error_toggle==1 &&
|
||||||
xpath_first(target, NULL, "%s", _transaction_xpath)){
|
xpath_first(target, "%s", _transaction_xpath)){
|
||||||
_transaction_error_toggle=0; /* toggle if triggered */
|
_transaction_error_toggle=0; /* toggle if triggered */
|
||||||
clicon_err(OE_XML, 0, "User error");
|
clicon_err(OE_XML, 0, "User error");
|
||||||
return -1; /* induce fail */
|
return -1; /* induce fail */
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ example_client_rpc(clicon_handle h,
|
||||||
/* Send to backend */
|
/* Send to backend */
|
||||||
if (clicon_rpc_netconf_xml(h, xrpc, &xret, NULL) < 0)
|
if (clicon_rpc_netconf_xml(h, xrpc, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,3 @@
|
||||||
*/
|
*/
|
||||||
#define USE_NETCONF_NS_AS_DEFAULT
|
#define USE_NETCONF_NS_AS_DEFAULT
|
||||||
|
|
||||||
/* Make namespace check on RESTCONF PUT and POST -d data
|
|
||||||
* Should be defined according to standard
|
|
||||||
* Undefine it if you want allow no namespace (pick first name it finds in list
|
|
||||||
* of loaded modules).
|
|
||||||
*/
|
|
||||||
#define RESTCONF_NS_DATA_CHECK
|
|
||||||
|
|
|
||||||
|
|
@ -116,20 +116,39 @@ char* xpath_tree_int2str(int nodetype);
|
||||||
int xpath_tree_print(cbuf *cb, xpath_tree *xs);
|
int xpath_tree_print(cbuf *cb, xpath_tree *xs);
|
||||||
int xpath_tree_free(xpath_tree *xs);
|
int xpath_tree_free(xpath_tree *xs);
|
||||||
int xpath_parse(cvec *nsc, char *xpath, xpath_tree **xptree);
|
int xpath_parse(cvec *nsc, char *xpath, xpath_tree **xptree);
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
|
||||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
|
||||||
int xpath_vec(cxobj *xcur, cvec *nsc, char *format, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 6)));
|
|
||||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *format, uint16_t flags,
|
|
||||||
cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 7)));
|
|
||||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
|
||||||
#else
|
|
||||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...);
|
|
||||||
int xpath_vec(cxobj *xcur, cvec *nsc, char *format, cxobj ***vec, size_t *veclen, ...);
|
|
||||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *format, uint16_t flags,
|
|
||||||
cxobj ***vec, size_t *veclen, ...);
|
|
||||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *format, ...);
|
|
||||||
#endif
|
|
||||||
int xpath_vec_ctx(cxobj *xcur, cvec *nsc, char *xpath, xp_ctx **xrp);
|
int xpath_vec_ctx(cxobj *xcur, cvec *nsc, char *xpath, xp_ctx **xrp);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *xpformat, ...) __attribute__ ((format (printf, 3, 4)));
|
||||||
|
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *xpformat, uint16_t flags,
|
||||||
|
cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 7)));
|
||||||
|
|
||||||
|
#else
|
||||||
|
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *xpformat, ...);
|
||||||
|
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *xpformat, uint16_t flags,
|
||||||
|
cxobj ***vec, size_t *veclen, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Functions with explicit namespace context (nsc) set. If you do not need
|
||||||
|
* explicit namespace contexts (most do not) consider using the API functions
|
||||||
|
* below without nsc set.
|
||||||
|
* If you do not know what a namespace context is, see README.md#xml-and-xpath
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
cxobj *xpath_first_nsc(cxobj *xcur, cvec *nsc, char *xpformat, ...) __attribute__ ((format (printf, 3, 4)));
|
||||||
|
int xpath_vec_nsc(cxobj *xcur, cvec *nsc, char *xpformat, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 6)));
|
||||||
|
#else
|
||||||
|
cxobj *xpath_first_nsc(cxobj *xcur, cvec *nsc, char *xpformat, ...);
|
||||||
|
int xpath_vec_nsc(cxobj *xcur, cvec *nsc, char *xpformat, cxobj ***vec, size_t *veclen, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Functions with nsc == NULL (implicit xpath context). */
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
cxobj *xpath_first(cxobj *xcur, char *xpformat, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
|
int xpath_vec(cxobj *xcur, char *xpformat, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 2, 5)));
|
||||||
|
#else
|
||||||
|
cxobj *xpath_first(cxobj *xcur, char *xpformat, ...);
|
||||||
|
int xpath_vec(cxobj *xcur, char *xpformat, cxobj ***vec, size_t *veclen, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _CLIXON_XPATH_H */
|
#endif /* _CLIXON_XPATH_H */
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,7 @@ text_read_modstate(clicon_handle h,
|
||||||
if ((name = xml_find_body(xm, "name")) == NULL)
|
if ((name = xml_find_body(xm, "name")) == NULL)
|
||||||
continue;
|
continue;
|
||||||
/* 3a) There is no such module in the system */
|
/* 3a) There is no such module in the system */
|
||||||
if ((xs = xpath_first(xmcache, NULL, "module[name=\"%s\"]", name)) == NULL){
|
if ((xs = xpath_first(xmcache, "module[name=\"%s\"]", name)) == NULL){
|
||||||
// fprintf(stderr, "%s: Module %s: not in system\n", __FUNCTION__, name);
|
// fprintf(stderr, "%s: Module %s: not in system\n", __FUNCTION__, name);
|
||||||
if ((xm2 = xml_dup(xm)) == NULL)
|
if ((xm2 = xml_dup(xm)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -420,7 +420,7 @@ xmldb_get_nocache(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
/* Here xt looks like: <config>...</config> */
|
/* Here xt looks like: <config>...</config> */
|
||||||
/* Given the xpath, return a vector of matches in xvec */
|
/* Given the xpath, return a vector of matches in xvec */
|
||||||
if (xpath_vec(xt, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(xt, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* If vectors are specified then mark the nodes found with all ancestors
|
/* If vectors are specified then mark the nodes found with all ancestors
|
||||||
|
|
@ -526,7 +526,7 @@ xmldb_get_cache(clicon_handle h,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Here xt looks like: <config>...</config> */
|
/* Here xt looks like: <config>...</config> */
|
||||||
if (xpath_vec(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Make new tree by copying top-of-tree from x0t to x1t */
|
/* Make new tree by copying top-of-tree from x0t to x1t */
|
||||||
|
|
@ -615,7 +615,7 @@ xmldb_get_zerocopy(clicon_handle h,
|
||||||
else
|
else
|
||||||
x0t = de->de_xml;
|
x0t = de->de_xml;
|
||||||
/* Here xt looks like: <config>...</config> */
|
/* Here xt looks like: <config>...</config> */
|
||||||
if (xpath_vec(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Iterate through the match vector
|
/* Iterate through the match vector
|
||||||
* For every node found in x0, mark the tree up to t1
|
* For every node found in x0, mark the tree up to t1
|
||||||
|
|
|
||||||
|
|
@ -662,7 +662,7 @@ xmldb_put(clicon_handle h,
|
||||||
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:yang:ietf-netconf-acm")) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:yang:ietf-netconf-acm")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xnacm0 != NULL &&
|
if (xnacm0 != NULL &&
|
||||||
(xnacm = xpath_first(xnacm0, nsc, "nacm")) != NULL){
|
(xnacm = xpath_first_nsc(xnacm0, nsc, "nacm")) != NULL){
|
||||||
/* Pre-NACM access step, if permit, then dont do any nacm checks in
|
/* Pre-NACM access step, if permit, then dont do any nacm checks in
|
||||||
* text_modify_* below */
|
* text_modify_* below */
|
||||||
if ((permit = nacm_access(mode, xnacm, username)) < 0)
|
if ((permit = nacm_access(mode, xnacm, username)) < 0)
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ nacm_rpc(char *rpc,
|
||||||
goto step10;
|
goto step10;
|
||||||
|
|
||||||
/* User's group */
|
/* User's group */
|
||||||
if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 5. If no groups are found, continue with step 10. */
|
/* 5. If no groups are found, continue with step 10. */
|
||||||
if (glen == 0)
|
if (glen == 0)
|
||||||
|
|
@ -223,14 +223,14 @@ nacm_rpc(char *rpc,
|
||||||
configuration. If a rule-list's "group" leaf-list does not
|
configuration. If a rule-list's "group" leaf-list does not
|
||||||
match any of the user's groups, proceed to the next rule-list
|
match any of the user's groups, proceed to the next rule-list
|
||||||
entry. */
|
entry. */
|
||||||
if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<rlistlen; i++){
|
for (i=0; i<rlistlen; i++){
|
||||||
rlist = rlistvec[i];
|
rlist = rlistvec[i];
|
||||||
/* Loop through user's group to find match in this rule-list */
|
/* Loop through user's group to find match in this rule-list */
|
||||||
for (j=0; j<glen; j++){
|
for (j=0; j<glen; j++){
|
||||||
gname = xml_find_body(gvec[j], "name");
|
gname = xml_find_body(gvec[j], "name");
|
||||||
if (xpath_first(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
if (xpath_first_nsc(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||||
break; /* found */
|
break; /* found */
|
||||||
}
|
}
|
||||||
if (j==glen) /* not found */
|
if (j==glen) /* not found */
|
||||||
|
|
@ -239,7 +239,7 @@ nacm_rpc(char *rpc,
|
||||||
until a rule that matches the requested access operation is
|
until a rule that matches the requested access operation is
|
||||||
found.
|
found.
|
||||||
*/
|
*/
|
||||||
if (xpath_vec(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
if (xpath_vec_nsc(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (j=0; j<rlen; j++){
|
for (j=0; j<rlen; j++){
|
||||||
xrule = rvec[j];
|
xrule = rvec[j];
|
||||||
|
|
@ -390,7 +390,7 @@ nacm_rule_datanode(cxobj *xt,
|
||||||
}
|
}
|
||||||
/* Here module is matched, now check for path if any NYI */
|
/* Here module is matched, now check for path if any NYI */
|
||||||
if (path){
|
if (path){
|
||||||
if ((xpath = xpath_first(xt, nsc, "%s", path)) == NULL)
|
if ((xpath = xpath_first_nsc(xt, nsc, "%s", path)) == NULL)
|
||||||
goto nomatch;
|
goto nomatch;
|
||||||
/* The requested node xr is the node specified by the path or is a
|
/* The requested node xr is the node specified by the path or is a
|
||||||
* descendant node of the path:
|
* descendant node of the path:
|
||||||
|
|
@ -447,7 +447,7 @@ nacm_data_read_xr(cxobj *xt,
|
||||||
/* Loop through user's group to find match in this rule-list */
|
/* Loop through user's group to find match in this rule-list */
|
||||||
for (j=0; j<glen; j++){
|
for (j=0; j<glen; j++){
|
||||||
gname = xml_find_body(gvec[j], "name");
|
gname = xml_find_body(gvec[j], "name");
|
||||||
if (xpath_first(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
if (xpath_first_nsc(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||||
break; /* found */
|
break; /* found */
|
||||||
}
|
}
|
||||||
if (j==glen) /* not found */
|
if (j==glen) /* not found */
|
||||||
|
|
@ -456,7 +456,7 @@ nacm_data_read_xr(cxobj *xt,
|
||||||
until a rule that matches the requested access operation is
|
until a rule that matches the requested access operation is
|
||||||
found. (see 6 sub rules in nacm_rule_datanode
|
found. (see 6 sub rules in nacm_rule_datanode
|
||||||
*/
|
*/
|
||||||
if (xpath_vec(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
if (xpath_vec_nsc(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (j=0; j<rlen; j++){ /* Loop through rules */
|
for (j=0; j<rlen; j++){ /* Loop through rules */
|
||||||
xrule = rvec[j];
|
xrule = rvec[j];
|
||||||
|
|
@ -588,7 +588,7 @@ nacm_datanode_read(cxobj *xt,
|
||||||
if (username == NULL)
|
if (username == NULL)
|
||||||
goto step9;
|
goto step9;
|
||||||
/* User's group */
|
/* User's group */
|
||||||
if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 4. If no groups are found (glen=0), continue and check read-default
|
/* 4. If no groups are found (glen=0), continue and check read-default
|
||||||
in step 11. */
|
in step 11. */
|
||||||
|
|
@ -596,7 +596,7 @@ nacm_datanode_read(cxobj *xt,
|
||||||
configuration. If a rule-list's "group" leaf-list does not
|
configuration. If a rule-list's "group" leaf-list does not
|
||||||
match any of the user's groups, proceed to the next rule-list
|
match any of the user's groups, proceed to the next rule-list
|
||||||
entry. */
|
entry. */
|
||||||
if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* read-default has default permit so should never be NULL */
|
/* read-default has default permit so should never be NULL */
|
||||||
if ((read_default = xml_find_body(xnacm, "read-default")) == NULL){
|
if ((read_default = xml_find_body(xnacm, "read-default")) == NULL){
|
||||||
|
|
@ -713,7 +713,7 @@ nacm_datanode_write(cxobj *xt,
|
||||||
if (username == NULL)
|
if (username == NULL)
|
||||||
goto step9;
|
goto step9;
|
||||||
/* User's group */
|
/* User's group */
|
||||||
if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 4. If no groups are found, continue with step 9. */
|
/* 4. If no groups are found, continue with step 9. */
|
||||||
if (glen == 0)
|
if (glen == 0)
|
||||||
|
|
@ -722,19 +722,19 @@ nacm_datanode_write(cxobj *xt,
|
||||||
configuration. If a rule-list's "group" leaf-list does not
|
configuration. If a rule-list's "group" leaf-list does not
|
||||||
match any of the user's groups, proceed to the next rule-list
|
match any of the user's groups, proceed to the next rule-list
|
||||||
entry. */
|
entry. */
|
||||||
if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<rlistlen; i++){
|
for (i=0; i<rlistlen; i++){
|
||||||
rlist = rlistvec[i];
|
rlist = rlistvec[i];
|
||||||
/* Loop through user's group to find match in this rule-list */
|
/* Loop through user's group to find match in this rule-list */
|
||||||
for (j=0; j<glen; j++){
|
for (j=0; j<glen; j++){
|
||||||
gname = xml_find_body(gvec[j], "name");
|
gname = xml_find_body(gvec[j], "name");
|
||||||
if (xpath_first(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
if (xpath_first_nsc(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||||
break; /* found */
|
break; /* found */
|
||||||
}
|
}
|
||||||
if (j==glen) /* not found */
|
if (j==glen) /* not found */
|
||||||
continue;
|
continue;
|
||||||
if (xpath_vec(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
if (xpath_vec_nsc(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* 6. For each rule-list entry found, process all rules, in order,
|
/* 6. For each rule-list entry found, process all rules, in order,
|
||||||
until a rule that matches the requested access operation is
|
until a rule that matches the requested access operation is
|
||||||
|
|
@ -862,7 +862,7 @@ nacm_access(char *mode,
|
||||||
* RFC8341 3.4 */
|
* RFC8341 3.4 */
|
||||||
/* 1. If the "enable-nacm" leaf is set to "false", then the protocol
|
/* 1. If the "enable-nacm" leaf is set to "false", then the protocol
|
||||||
operation is permitted. */
|
operation is permitted. */
|
||||||
if ((x = xpath_first(xnacm, nsc, "enable-nacm")) == NULL)
|
if ((x = xpath_first_nsc(xnacm, nsc, "enable-nacm")) == NULL)
|
||||||
goto permit;
|
goto permit;
|
||||||
enabled = xml_body(x);
|
enabled = xml_body(x);
|
||||||
if (strcmp(enabled, "true") != 0)
|
if (strcmp(enabled, "true") != 0)
|
||||||
|
|
@ -937,7 +937,7 @@ nacm_access_pre(clicon_handle h,
|
||||||
if (xnacm0 == NULL)
|
if (xnacm0 == NULL)
|
||||||
goto permit;
|
goto permit;
|
||||||
/* If config does not exist then the operation is permitted(?) */
|
/* If config does not exist then the operation is permitted(?) */
|
||||||
if ((xnacm = xpath_first(xnacm0, nsc, "nacm")) == NULL)
|
if ((xnacm = xpath_first_nsc(xnacm0, nsc, "nacm")) == NULL)
|
||||||
goto permit;
|
goto permit;
|
||||||
if (xml_rootchild_node(xnacm0, xnacm) < 0)
|
if (xml_rootchild_node(xnacm0, xnacm) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -1303,13 +1303,13 @@ netconf_err2cb(cxobj *xerr,
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((x=xpath_first(xerr, NULL, "error-type"))!=NULL)
|
if ((x=xpath_first(xerr, "error-type"))!=NULL)
|
||||||
cprintf(cb, "%s ", xml_body(x));
|
cprintf(cb, "%s ", xml_body(x));
|
||||||
if ((x=xpath_first(xerr, NULL, "error-tag"))!=NULL)
|
if ((x=xpath_first(xerr, "error-tag"))!=NULL)
|
||||||
cprintf(cb, "%s ", xml_body(x));
|
cprintf(cb, "%s ", xml_body(x));
|
||||||
if ((x=xpath_first(xerr, NULL, "error-message"))!=NULL)
|
if ((x=xpath_first(xerr, "error-message"))!=NULL)
|
||||||
cprintf(cb, "%s ", xml_body(x));
|
cprintf(cb, "%s ", xml_body(x));
|
||||||
if ((x=xpath_first(xerr, NULL, "error-info"))!=NULL)
|
if ((x=xpath_first(xerr, "error-info"))!=NULL)
|
||||||
clicon_xml2cbuf(cb, xml_child_i(x,0), 0, 0);
|
clicon_xml2cbuf(cb, xml_child_i(x,0), 0, 0);
|
||||||
*cberr = cb;
|
*cberr = cb;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
|
||||||
|
|
@ -201,8 +201,8 @@ parse_configfile(clicon_handle h,
|
||||||
/* Hard-coded config for < 3.10 and clixon-config for >= 3.10 */
|
/* Hard-coded config for < 3.10 and clixon-config for >= 3.10 */
|
||||||
if ((nsc = xml_nsctx_init(NULL, CLIXON_CONF_NS)) == NULL)
|
if ((nsc = xml_nsctx_init(NULL, CLIXON_CONF_NS)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xc = xpath_first(xt, nsc, "clixon-config")) == NULL){
|
if ((xc = xpath_first_nsc(xt, nsc, "clixon-config")) == NULL){
|
||||||
clicon_err(OE_CFG, 0, "Config file %s: Lacks top-level \"clixon-config\" element\nClixon config files should begin with: <clixon-config xmlns=\"%s\" (See Changelog in Clixon 3.10)>", filename, CLIXON_CONF_NS);
|
clicon_err(OE_CFG, 0, "Config file %s: Lacks top-level \"clixon-config\" element\nClixon config files should begin with: <clixon-config xmlns=\"%s\">", filename, CLIXON_CONF_NS);
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -362,7 +362,6 @@ clicon_options_main(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_spec(xconfig) == NULL){
|
if (xml_spec(xconfig) == NULL){
|
||||||
clicon_err(OE_CFG, 0, "Config file %s: did not find corresponding Yang specification\nHint: File does not begin with: <clixon-config xmlns=\"%s\"> or clixon-config.yang not found?", configfile, CLIXON_CONF_NS);
|
clicon_err(OE_CFG, 0, "Config file %s: did not find corresponding Yang specification\nHint: File does not begin with: <clixon-config xmlns=\"%s\"> or clixon-config.yang not found?", configfile, CLIXON_CONF_NS);
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Set clixon_conf pointer to handle */
|
/* Set clixon_conf pointer to handle */
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ clicon_rpc_generate_error(char *prefix,
|
||||||
* cxobj *xt = NULL;
|
* cxobj *xt = NULL;
|
||||||
* if (clicon_rpc_get_config(h, "running", "/hello/world", "urn:example:hello", &xt) < 0)
|
* if (clicon_rpc_get_config(h, "running", "/hello/world", "urn:example:hello", &xt) < 0)
|
||||||
* err;
|
* err;
|
||||||
* if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
* if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
* clicon_rpc_generate_error("", xerr);
|
* clicon_rpc_generate_error("", xerr);
|
||||||
* err;
|
* err;
|
||||||
* }
|
* }
|
||||||
|
|
@ -306,9 +306,9 @@ clicon_rpc_get_config(clicon_handle h,
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Send xml error back: first check error, then ok */
|
/* Send xml error back: first check error, then ok */
|
||||||
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
|
if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
|
||||||
xd = xml_parent(xd); /* point to rpc-reply */
|
xd = xml_parent(xd); /* point to rpc-reply */
|
||||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL)
|
else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
|
||||||
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xt){
|
if (xt){
|
||||||
|
|
@ -369,7 +369,7 @@ clicon_rpc_edit_config(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Editing configuration", xerr);
|
clicon_rpc_generate_error("Editing configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -415,7 +415,7 @@ clicon_rpc_copy_config(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Copying configuration", xerr);
|
clicon_rpc_generate_error("Copying configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -454,7 +454,7 @@ clicon_rpc_delete_config(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Deleting configuration", xerr);
|
clicon_rpc_generate_error("Deleting configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -489,7 +489,7 @@ clicon_rpc_lock(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Locking configuration", xerr);
|
clicon_rpc_generate_error("Locking configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -523,7 +523,7 @@ clicon_rpc_unlock(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Configuration unlock", xerr);
|
clicon_rpc_generate_error("Configuration unlock", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -550,7 +550,7 @@ clicon_rpc_unlock(clicon_handle h,
|
||||||
* cxobj *xt = NULL;
|
* cxobj *xt = NULL;
|
||||||
* if (clicon_rpc_get(h, "/hello/world", "urn:example:hello", &xt) < 0)
|
* if (clicon_rpc_get(h, "/hello/world", "urn:example:hello", &xt) < 0)
|
||||||
* err;
|
* err;
|
||||||
* if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
* if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||||
* clicon_rpc_generate_error(xerr);
|
* clicon_rpc_generate_error(xerr);
|
||||||
* err;
|
* err;
|
||||||
* }
|
* }
|
||||||
|
|
@ -593,9 +593,9 @@ clicon_rpc_get(clicon_handle h,
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Send xml error back: first check error, then ok */
|
/* Send xml error back: first check error, then ok */
|
||||||
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
|
if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
|
||||||
xd = xml_parent(xd); /* point to rpc-reply */
|
xd = xml_parent(xd); /* point to rpc-reply */
|
||||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL)
|
else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
|
||||||
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xt){
|
if (xt){
|
||||||
|
|
@ -634,7 +634,7 @@ clicon_rpc_close_session(clicon_handle h)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Close session", xerr);
|
clicon_rpc_generate_error("Close session", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -669,7 +669,7 @@ clicon_rpc_kill_session(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Kill session", xerr);
|
clicon_rpc_generate_error("Kill session", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -703,7 +703,7 @@ clicon_rpc_validate(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error(CLIXON_ERRSTR_VALIDATE_FAILED, xerr);
|
clicon_rpc_generate_error(CLIXON_ERRSTR_VALIDATE_FAILED, xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -735,7 +735,7 @@ clicon_rpc_commit(clicon_handle h)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error(CLIXON_ERRSTR_COMMIT_FAILED, xerr);
|
clicon_rpc_generate_error(CLIXON_ERRSTR_COMMIT_FAILED, xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -767,7 +767,7 @@ clicon_rpc_discard_changes(clicon_handle h)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Discard changes", xerr);
|
clicon_rpc_generate_error("Discard changes", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -812,7 +812,7 @@ clicon_rpc_create_subscription(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, s0) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, s0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Create subscription", xerr);
|
clicon_rpc_generate_error("Create subscription", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -847,11 +847,11 @@ clicon_rpc_debug(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||||
clicon_rpc_generate_error("Debug",xerr);
|
clicon_rpc_generate_error("Debug",xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (xpath_first(xret, NULL, "//rpc-reply/ok") == NULL){
|
if (xpath_first(xret, "//rpc-reply/ok") == NULL){
|
||||||
clicon_err(OE_XML, 0, "rpc error"); /* XXX extract info from rpc-error */
|
clicon_err(OE_XML, 0, "rpc error"); /* XXX extract info from rpc-error */
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -514,7 +514,7 @@ stream_notify1(clicon_handle h,
|
||||||
else{ /* xpath match */
|
else{ /* xpath match */
|
||||||
if (ss->ss_xpath == NULL ||
|
if (ss->ss_xpath == NULL ||
|
||||||
strlen(ss->ss_xpath)==0 ||
|
strlen(ss->ss_xpath)==0 ||
|
||||||
xpath_first(xevent, NULL, "%s", ss->ss_xpath) != NULL)
|
xpath_first(xevent, "%s", ss->ss_xpath) != NULL)
|
||||||
if ((*ss->ss_fn)(h, 0, xevent, ss->ss_arg) < 0)
|
if ((*ss->ss_fn)(h, 0, xevent, ss->ss_arg) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
ss = NEXTQ(struct stream_subscription *, ss);
|
ss = NEXTQ(struct stream_subscription *, ss);
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ changelog_move(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xp; /* destination parent node */
|
cxobj *xp; /* destination parent node */
|
||||||
|
|
||||||
if ((xp = xpath_first(xt, nsc, "%s", dst)) == NULL){
|
if ((xp = xpath_first_nsc(xt, nsc, "%s", dst)) == NULL){
|
||||||
clicon_err(OE_XML, 0, "path required");
|
clicon_err(OE_XML, 0, "path required");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -253,7 +253,7 @@ changelog_op(clicon_handle h,
|
||||||
if ((wxpath = xml_find_body(xi, "where")) == NULL)
|
if ((wxpath = xml_find_body(xi, "where")) == NULL)
|
||||||
goto ok;
|
goto ok;
|
||||||
/* Get vector of target nodes meeting the where requirement */
|
/* Get vector of target nodes meeting the where requirement */
|
||||||
if (xpath_vec(xt, nsc, "%s", &wvec, &wlen, wxpath) < 0)
|
if (xpath_vec_nsc(xt, nsc, "%s", &wvec, &wlen, wxpath) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<wlen; i++){
|
for (i=0; i<wlen; i++){
|
||||||
xw = wvec[i];
|
xw = wvec[i];
|
||||||
|
|
@ -328,7 +328,7 @@ changelog_iterate(clicon_handle h,
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (xpath_vec(xch, NULL, "step", &vec, &veclen) < 0)
|
if (xpath_vec(xch, "step", &vec, &veclen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Iterate through changelog items */
|
/* Iterate through changelog items */
|
||||||
for (i=0; i<veclen; i++){
|
for (i=0; i<veclen; i++){
|
||||||
|
|
@ -392,7 +392,7 @@ xml_changelog_upgrade(clicon_handle h,
|
||||||
* - find all changelogs in the interval: [from, to]
|
* - find all changelogs in the interval: [from, to]
|
||||||
* - note it t=0 then no changelog is applied
|
* - note it t=0 then no changelog is applied
|
||||||
*/
|
*/
|
||||||
if (xpath_vec(xchlog, NULL, "changelog[namespace=\"%s\"]",
|
if (xpath_vec(xchlog, "changelog[namespace=\"%s\"]",
|
||||||
&vec, &veclen, namespace) < 0)
|
&vec, &veclen, namespace) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Get all changelogs in the interval [from,to]*/
|
/* Get all changelogs in the interval [from,to]*/
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ validate_leafref(cxobj *xt,
|
||||||
/* XXX see comment above regarding typeref or not */
|
/* XXX see comment above regarding typeref or not */
|
||||||
if (xml_nsctx_yang(ytype, &nsc) < 0)
|
if (xml_nsctx_yang(ytype, &nsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_vec(xt, nsc, "%s", &xvec, &xlen, yang_argument_get(ypath)) < 0)
|
if (xpath_vec_nsc(xt, nsc, "%s", &xvec, &xlen, yang_argument_get(ypath)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i = 0; i < xlen; i++) {
|
for (i = 0; i < xlen; i++) {
|
||||||
x = xvec[i];
|
x = xvec[i];
|
||||||
|
|
@ -2781,7 +2781,7 @@ xml2xpath(cxobj *x,
|
||||||
xt = xml_parent(xt);
|
xt = xml_parent(xt);
|
||||||
xcp = xml_parent(xt);
|
xcp = xml_parent(xt);
|
||||||
xml_parent_set(xt, NULL);
|
xml_parent_set(xt, NULL);
|
||||||
x2 = xpath_first(xt, NULL, "%s", xpath); /* +1: skip first / */
|
x2 = xpath_first(xt, "%s", xpath); /* +1: skip first / */
|
||||||
xml_parent_set(xt, xcp);
|
xml_parent_set(xt, xcp);
|
||||||
assert(x2 && x==x2);
|
assert(x2 && x==x2);
|
||||||
if (x==x2)
|
if (x==x2)
|
||||||
|
|
|
||||||
|
|
@ -183,17 +183,17 @@ xpath_tree_free(xpath_tree *xs)
|
||||||
/*! Given XML tree and xpath, parse xpath, eval it and return xpath context,
|
/*! Given XML tree and xpath, parse xpath, eval it and return xpath context,
|
||||||
* This is a raw form of xpath where you can do type conversion, etc,
|
* This is a raw form of xpath where you can do type conversion, etc,
|
||||||
* not just a nodeset.
|
* not just a nodeset.
|
||||||
* @param[in] nsc XML Namespace context
|
* @param[in] nsc External XML namespace context, or NULL
|
||||||
* @param[in] xpath String with XPATH 1.0 syntax
|
* @param[in] xpath String with XPATH 1.0 syntax
|
||||||
* @param[out] xptree Xpath-tree, parsed, structured XPATH, free:xpath_tree_free
|
* @param[out] xptree Xpath-tree, parsed, structured XPATH, free:xpath_tree_free
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @code
|
* @code
|
||||||
* xp_ctx *xc = NULL;
|
* xpath_tree *xpt = NULL;
|
||||||
* if (xpath_vec_ctx(x, NULL, xpath, &xc) < 0)
|
* if (xpath_parse(NULL, xpath, &xpt) < 0)
|
||||||
* err;
|
* err;
|
||||||
* if (xc)
|
* if (xpt)
|
||||||
* ctx_free(xc);
|
* xptree_free(xpt);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @see xpath_tree_free
|
* @see xpath_tree_free
|
||||||
*/
|
*/
|
||||||
|
|
@ -238,7 +238,7 @@ xpath_parse(cvec *nsc,
|
||||||
* This is a raw form of xpath where you can do type conversion of the return
|
* This is a raw form of xpath where you can do type conversion of the return
|
||||||
* value, etc, not just a nodeset.
|
* value, etc, not just a nodeset.
|
||||||
* @param[in] xcur XML-tree where to search
|
* @param[in] xcur XML-tree where to search
|
||||||
* @param[in] nsc XML Namespace context
|
* @param[in] nsc External XML namespace context, or NULL
|
||||||
* @param[in] xpath String with XPATH 1.0 syntax
|
* @param[in] xpath String with XPATH 1.0 syntax
|
||||||
* @param[out] xrp Return XPATH context
|
* @param[out] xrp Return XPATH context
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
|
|
@ -278,34 +278,32 @@ xpath_vec_ctx(cxobj *xcur,
|
||||||
done:
|
done:
|
||||||
if (xptree)
|
if (xptree)
|
||||||
xpath_tree_free(xptree);
|
xpath_tree_free(xptree);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Xpath nodeset function where only the first matching entry is returned
|
/*! Xpath nodeset function where only the first matching entry is returned
|
||||||
* args:
|
*
|
||||||
* @param[in] xcur XML tree where to search
|
* @param[in] xcur XML tree where to search
|
||||||
* @param[in] nsc XML Namespace context
|
* @param[in] nsc External XML namespace context, or NULL
|
||||||
* @param[in] format string with XPATH syntax
|
* @param[in] xpformat Format string for XPATH syntax
|
||||||
* @retval xml-tree XML tree of first match
|
* @retval xml-tree XML tree of first match
|
||||||
* @retval NULL Error or not found
|
* @retval NULL Error or not found
|
||||||
*
|
*
|
||||||
* @code
|
* @code
|
||||||
* cxobj *x;
|
* cxobj *x;
|
||||||
* cvec *nsc; // namespace context
|
* cvec *nsc; // namespace context
|
||||||
* if ((x = xpath_first(xtop, nsc, "//symbol/foo")) != NULL) {
|
* if ((x = xpath_first_nsc(xtop, nsc, "//symbol/foo")) != NULL) {
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @endcode
|
||||||
* @note the returned pointer points into the original tree so should not be freed fter use.
|
* @note the returned pointer points into the original tree so should not be freed after use.
|
||||||
* @note return value does not see difference between error and not found
|
* @note return value does not see difference between error and not found
|
||||||
* @see also xpath_vec.
|
* @see also xpath_vec.
|
||||||
* @experimental
|
|
||||||
*/
|
*/
|
||||||
cxobj *
|
cxobj *
|
||||||
xpath_first(cxobj *xcur,
|
xpath_first_nsc(cxobj *xcur,
|
||||||
cvec *nsc,
|
cvec *nsc,
|
||||||
char *format,
|
char *xpformat,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
cxobj *cx = NULL;
|
cxobj *cx = NULL;
|
||||||
|
|
@ -314,8 +312,8 @@ xpath_first(cxobj *xcur,
|
||||||
char *xpath = NULL;
|
char *xpath = NULL;
|
||||||
xp_ctx *xr = NULL;
|
xp_ctx *xr = NULL;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, xpformat);
|
||||||
len = vsnprintf(NULL, 0, format, ap);
|
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
/* allocate a message string exactly fitting the message length */
|
/* allocate a message string exactly fitting the message length */
|
||||||
if ((xpath = malloc(len+1)) == NULL){
|
if ((xpath = malloc(len+1)) == NULL){
|
||||||
|
|
@ -323,8 +321,8 @@ xpath_first(cxobj *xcur,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* second round: compute write message from reason and args */
|
/* second round: compute write message from reason and args */
|
||||||
va_start(ap, format);
|
va_start(ap, xpformat);
|
||||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -342,11 +340,68 @@ xpath_first(cxobj *xcur,
|
||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Xpath nodeset function where only the first matching entry is returned
|
||||||
|
*
|
||||||
|
* @param[in] xcur XML tree where to search
|
||||||
|
* @param[in] xpformat Format string for XPATH syntax
|
||||||
|
* @retval xml-tree XML tree of first match
|
||||||
|
* @retval NULL Error or not found
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* cxobj *x;
|
||||||
|
* if ((x = xpath_first(xtop, "//symbol/foo")) != NULL) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @note the returned pointer points into the original tree so should not be freed after use.
|
||||||
|
* @note return value does not see difference between error and not found
|
||||||
|
* @see also xpath_vec.
|
||||||
|
* @see xpath_first_nsc which is more generic with namespace context
|
||||||
|
*/
|
||||||
|
cxobj *
|
||||||
|
xpath_first(cxobj *xcur,
|
||||||
|
char *xpformat,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
cxobj *cx = NULL;
|
||||||
|
va_list ap;
|
||||||
|
size_t len;
|
||||||
|
char *xpath = NULL;
|
||||||
|
xp_ctx *xr = NULL;
|
||||||
|
|
||||||
|
va_start(ap, xpformat);
|
||||||
|
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||||
|
va_end(ap);
|
||||||
|
/* allocate a message string exactly fitting the message length */
|
||||||
|
if ((xpath = malloc(len+1)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "malloc");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* second round: compute write message from reason and args */
|
||||||
|
va_start(ap, xpformat);
|
||||||
|
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||||
|
va_end(ap);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
if (xpath_vec_ctx(xcur, NULL, xpath, &xr) < 0)
|
||||||
|
goto done;
|
||||||
|
if (xr && xr->xc_type == XT_NODESET && xr->xc_size)
|
||||||
|
cx = xr->xc_nodeset[0];
|
||||||
|
done:
|
||||||
|
if (xr)
|
||||||
|
ctx_free(xr);
|
||||||
|
if (xpath)
|
||||||
|
free(xpath);
|
||||||
|
return cx;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Given XML tree and xpath, returns nodeset as xml node vector
|
/*! Given XML tree and xpath, returns nodeset as xml node vector
|
||||||
* If result is not nodeset, return empty nodeset
|
* If result is not nodeset, return empty nodeset
|
||||||
* @param[in] xcur xml-tree where to search
|
* @param[in] xcur xml-tree where to search
|
||||||
* @param[in] format stdarg string with XPATH 1.0 syntax
|
* @param[in] nsc External XML namespace context, or NULL
|
||||||
* @param[in] nsc XML Namespace context for XPATH
|
* @param[in] xpformat Format string for XPATH syntax
|
||||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||||
* @param[out] veclen returns length of vector in return value
|
* @param[out] veclen returns length of vector in return value
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
|
|
@ -355,7 +410,7 @@ xpath_first(cxobj *xcur,
|
||||||
* cvec *nsc; // namespace context
|
* cvec *nsc; // namespace context
|
||||||
* cxobj **vec;
|
* cxobj **vec;
|
||||||
* size_t veclen;
|
* size_t veclen;
|
||||||
* if (xpath_vec(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0)
|
* if (xpath_vec_nsc(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0)
|
||||||
* goto err;
|
* goto err;
|
||||||
* for (i=0; i<veclen; i++){
|
* for (i=0; i<veclen; i++){
|
||||||
* xn = vec[i];
|
* xn = vec[i];
|
||||||
|
|
@ -363,12 +418,11 @@ xpath_first(cxobj *xcur,
|
||||||
* }
|
* }
|
||||||
* free(vec);
|
* free(vec);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @note Namespace prefix checking is not properly implemented
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xpath_vec(cxobj *xcur,
|
xpath_vec_nsc(cxobj *xcur,
|
||||||
cvec *nsc,
|
cvec *nsc,
|
||||||
char *format,
|
char *xpformat,
|
||||||
cxobj ***vec,
|
cxobj ***vec,
|
||||||
size_t *veclen,
|
size_t *veclen,
|
||||||
...)
|
...)
|
||||||
|
|
@ -380,7 +434,7 @@ xpath_vec(cxobj *xcur,
|
||||||
xp_ctx *xr = NULL;
|
xp_ctx *xr = NULL;
|
||||||
|
|
||||||
va_start(ap, veclen);
|
va_start(ap, veclen);
|
||||||
len = vsnprintf(NULL, 0, format, ap);
|
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
/* allocate a message string exactly fitting the message length */
|
/* allocate a message string exactly fitting the message length */
|
||||||
if ((xpath = malloc(len+1)) == NULL){
|
if ((xpath = malloc(len+1)) == NULL){
|
||||||
|
|
@ -389,7 +443,7 @@ xpath_vec(cxobj *xcur,
|
||||||
}
|
}
|
||||||
/* second round: compute write message from reason and args */
|
/* second round: compute write message from reason and args */
|
||||||
va_start(ap, veclen);
|
va_start(ap, veclen);
|
||||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -413,9 +467,77 @@ xpath_vec(cxobj *xcur,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Given XML tree and xpath, returns nodeset as xml node vector
|
||||||
|
* If result is not nodeset, return empty nodeset
|
||||||
|
* @param[in] xcur xml-tree where to search
|
||||||
|
* @param[in] xpformat Format string for XPATH syntax
|
||||||
|
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||||
|
* @param[out] veclen returns length of vector in return value
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
* @code
|
||||||
|
* cxobj **vec;
|
||||||
|
* size_t veclen;
|
||||||
|
* if (xpath_vec(xcur, "//symbol/foo", &vec, &veclen) < 0)
|
||||||
|
* goto err;
|
||||||
|
* for (i=0; i<veclen; i++){
|
||||||
|
* xn = vec[i];
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* free(vec);
|
||||||
|
* @endcode
|
||||||
|
* @see xpath_vec_nsc which is more generic with namespace context
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xpath_vec(cxobj *xcur,
|
||||||
|
char *xpformat,
|
||||||
|
cxobj ***vec,
|
||||||
|
size_t *veclen,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
va_list ap;
|
||||||
|
size_t len;
|
||||||
|
char *xpath = NULL;
|
||||||
|
xp_ctx *xr = NULL;
|
||||||
|
|
||||||
|
va_start(ap, veclen);
|
||||||
|
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||||
|
va_end(ap);
|
||||||
|
/* allocate a message string exactly fitting the message length */
|
||||||
|
if ((xpath = malloc(len+1)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "malloc");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* second round: compute write message from reason and args */
|
||||||
|
va_start(ap, veclen);
|
||||||
|
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||||
|
va_end(ap);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
*vec=NULL;
|
||||||
|
*veclen = 0;
|
||||||
|
if (xpath_vec_ctx(xcur, NULL, xpath, &xr) < 0)
|
||||||
|
goto done;
|
||||||
|
if (xr && xr->xc_type == XT_NODESET){
|
||||||
|
*vec = xr->xc_nodeset;
|
||||||
|
xr->xc_nodeset = NULL;
|
||||||
|
*veclen = xr->xc_size;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (xr)
|
||||||
|
ctx_free(xr);
|
||||||
|
if (xpath)
|
||||||
|
free(xpath);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/* Xpath that returns a vector of matches (only nodes marked with flags)
|
/* Xpath that returns a vector of matches (only nodes marked with flags)
|
||||||
* @param[in] xcur xml-tree where to search
|
* @param[in] xcur xml-tree where to search
|
||||||
* @param[in] xpath string with XPATH syntax
|
* @param[in] xpformat Format string for XPATH syntax
|
||||||
* @param[in] nsc External XML namespace context, or NULL
|
* @param[in] nsc External XML namespace context, or NULL
|
||||||
* @param[in] flags Set of flags that return nodes must match (0 if all)
|
* @param[in] flags Set of flags that return nodes must match (0 if all)
|
||||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||||
|
|
@ -434,14 +556,13 @@ xpath_vec(cxobj *xcur,
|
||||||
* }
|
* }
|
||||||
* free(vec);
|
* free(vec);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @Note that although the returned vector must be freed after use, the returned xml
|
* @Note that although the returned vector must be freed after use, the returned xml trees need not be.
|
||||||
* trees need not be.
|
|
||||||
* @see also xpath_vec This is a specialized version.
|
* @see also xpath_vec This is a specialized version.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xpath_vec_flag(cxobj *xcur,
|
xpath_vec_flag(cxobj *xcur,
|
||||||
cvec *nsc,
|
cvec *nsc,
|
||||||
char *format,
|
char *xpformat,
|
||||||
uint16_t flags,
|
uint16_t flags,
|
||||||
cxobj ***vec,
|
cxobj ***vec,
|
||||||
size_t *veclen,
|
size_t *veclen,
|
||||||
|
|
@ -456,7 +577,7 @@ xpath_vec_flag(cxobj *xcur,
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
|
|
||||||
va_start(ap, veclen);
|
va_start(ap, veclen);
|
||||||
len = vsnprintf(NULL, 0, format, ap);
|
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
/* allocate a message string exactly fitting the message length */
|
/* allocate a message string exactly fitting the message length */
|
||||||
if ((xpath = malloc(len+1)) == NULL){
|
if ((xpath = malloc(len+1)) == NULL){
|
||||||
|
|
@ -465,7 +586,7 @@ xpath_vec_flag(cxobj *xcur,
|
||||||
}
|
}
|
||||||
/* second round: compute write message from reason and args */
|
/* second round: compute write message from reason and args */
|
||||||
va_start(ap, veclen);
|
va_start(ap, veclen);
|
||||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -496,7 +617,7 @@ xpath_vec_flag(cxobj *xcur,
|
||||||
* Returns true if the nodeset is non-empty
|
* Returns true if the nodeset is non-empty
|
||||||
* @param[in] xcur xml-tree where to search
|
* @param[in] xcur xml-tree where to search
|
||||||
* @param[in] nsc External XML namespace context, or NULL
|
* @param[in] nsc External XML namespace context, or NULL
|
||||||
* @param[in] xpath stdarg string with XPATH 1.0 syntax
|
* @param[in] xpformat Format string for XPATH syntax
|
||||||
* @retval 1 True
|
* @retval 1 True
|
||||||
* @retval 0 False
|
* @retval 0 False
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
@ -504,7 +625,7 @@ xpath_vec_flag(cxobj *xcur,
|
||||||
int
|
int
|
||||||
xpath_vec_bool(cxobj *xcur,
|
xpath_vec_bool(cxobj *xcur,
|
||||||
cvec *nsc,
|
cvec *nsc,
|
||||||
char *format,
|
char *xpformat,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -513,8 +634,8 @@ xpath_vec_bool(cxobj *xcur,
|
||||||
char *xpath = NULL;
|
char *xpath = NULL;
|
||||||
xp_ctx *xr = NULL;
|
xp_ctx *xr = NULL;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, xpformat);
|
||||||
len = vsnprintf(NULL, 0, format, ap);
|
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
/* allocate a message string exactly fitting the message length */
|
/* allocate a message string exactly fitting the message length */
|
||||||
if ((xpath = malloc(len+1)) == NULL){
|
if ((xpath = malloc(len+1)) == NULL){
|
||||||
|
|
@ -522,8 +643,8 @@ xpath_vec_bool(cxobj *xcur,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* second round: compute write message from reason and args */
|
/* second round: compute write message from reason and args */
|
||||||
va_start(ap, format);
|
va_start(ap, xpformat);
|
||||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ yang_modules_state_get(clicon_handle h,
|
||||||
/* xc is also original tree, need to copy it */
|
/* xc is also original tree, need to copy it */
|
||||||
if ((xw = xml_wrap(xc, "top")) == NULL)
|
if ((xw = xml_wrap(xc, "top")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_first(xw, NULL, "%s", xpath)){
|
if (xpath_first(xw, "%s", xpath)){
|
||||||
if ((x = xml_dup(xc)) == NULL) /* Make copy and use below */
|
if ((x = xml_dup(xc)) == NULL) /* Make copy and use below */
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +337,7 @@ yang_modules_state_get(clicon_handle h,
|
||||||
if ((x = xml_wrap(x, "top")) < 0)
|
if ((x = xml_wrap(x, "top")) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* extract xpath part of module-state tree */
|
/* extract xpath part of module-state tree */
|
||||||
if (xpath_vec(x, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec_nsc(x, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xvec != NULL){
|
if (xvec != NULL){
|
||||||
for (i=0; i<xlen; i++)
|
for (i=0; i<xlen; i++)
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
if (xml_apply(x0, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply(x0, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xb = xpath_first(x0, NULL, "%s", xpath)) == NULL){
|
if ((xb = xpath_first(x0, "%s", xpath)) == NULL){
|
||||||
clicon_err(OE_XML, 0, "xpath: %s not found in x0", xpath);
|
clicon_err(OE_XML, 0, "xpath: %s not found in x0", xpath);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +169,7 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
if (xml_apply(xi, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
if (xml_apply(xi, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xi = xpath_first(xi, NULL, "%s", xpath)) == NULL){
|
if ((xi = xpath_first(xi, "%s", xpath)) == NULL){
|
||||||
clicon_err(OE_XML, 0, "xpath: %s not found in xi", xpath);
|
clicon_err(OE_XML, 0, "xpath: %s not found in xi", xpath);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
/* If xpath0 given, position current x */
|
/* If xpath0 given, position current x */
|
||||||
if (xpath0){
|
if (xpath0){
|
||||||
if ((x = xpath_first(x0, NULL, "%s", xpath0)) == NULL){
|
if ((x = xpath_first(x0, "%s", xpath0)) == NULL){
|
||||||
fprintf(stderr, "Error: xpath0 returned NULL\n");
|
fprintf(stderr, "Error: xpath0 returned NULL\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue