diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b656be..5a150706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,13 +12,14 @@ * Fixed multi-namespace for augmented state which was not covered in 4.2.0. ### API changes on existing features (you may need to change your code) -* C-API - * Added clicon_handle as parameter to all `clicon_connect_` functions to get better error message - * Added nsc parameter to `xmldb_get()` * Yang files reorganized into three classes: clixon, mandatory, optional (previous "standard" split into mandatory and optional). * Clixon and mandatory yang spec are always installed * Optional yang files are loaded only if configured with `--enable-optyangs` (flipped logic and changed from `disable-stdyangs`). NOTE: you must do this to run examples and tests. * Optional yang files can be installed in a separate dir with `--with-opt-yang-installdir=DIR` (renamed from `with-std-yang-installdir`) +* C-API + * Added namespace-context parameter `nsc` to `xpath_first` and `xpath_vec`, (`xpath_vec_nsc` and xpath_first_nsc` are removed). + * Added clicon_handle as parameter to all `clicon_connect_` functions to get better error message + * Added nsc parameter to `xmldb_get()` * The multi-namespace augment state may rearrange the XML namespace attributes. * Main example yang changed to incorporate augmented state, new revision is 2019-11-15. diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 2aee6dca..943e9510 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -171,7 +171,7 @@ client_get_capabilities(clicon_handle h, cxobj *xrstate = NULL; /* xml restconf-state node */ cxobj *xcap = NULL; /* xml capabilities node */ - if ((xrstate = xpath_first(*xret, "restconf-state")) == NULL){ + if ((xrstate = xpath_first(*xret, NULL, "restconf-state")) == NULL){ clicon_err(OE_YANG, ENOENT, "restconf-state not found in config node"); goto done; } @@ -324,7 +324,7 @@ client_statedata(clicon_handle h, * Actually this is a safety catch, should really be done in plugins * and modules_state functions. */ - if (xpath_vec_nsc(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(*xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; /* If vectors are specified then mark the nodes found and * then filter out everything else, @@ -434,7 +434,7 @@ from_client_get_config(clicon_handle h, if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0) goto done; if (ret == 0){ /* Do NACM validation */ - if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; /* NACM datanode/module read validation */ if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0) @@ -529,14 +529,14 @@ from_client_edit_config(clicon_handle h, goto done; goto ok; } - if ((x = xpath_first(xn, "default-operation")) != NULL){ + if ((x = xpath_first(xn, NULL, "default-operation")) != NULL){ if (xml_operation(xml_body(x), &operation) < 0){ if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0) goto done; goto ok; } } - if ((xc = xpath_first(xn, "config")) == NULL){ + if ((xc = xpath_first(xn, NULL, "config")) == NULL){ if (netconf_missing_element(cbret, "protocol", "config", NULL) < 0) goto done; goto ok; @@ -967,7 +967,7 @@ from_client_get(clicon_handle h, if ((ret = nacm_access_pre(h, username, NACM_DATA, &xnacm)) < 0) goto done; if (ret == 0){ /* Do NACM validation */ - if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; /* NACM datanode/module read validation */ if (nacm_datanode_read(xret, xvec, xlen, username, xnacm) < 0) @@ -1122,9 +1122,9 @@ from_client_create_subscription(clicon_handle h, if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netmod:notification")) == NULL) goto done; - if ((x = xpath_first_nsc(xe, nsc, "//stream")) != NULL) + if ((x = xpath_first(xe, nsc, "//stream")) != NULL) stream = xml_find_value(x, "body"); - if ((x = xpath_first_nsc(xe, nsc, "//stopTime")) != NULL){ + if ((x = xpath_first(xe, nsc, "//stopTime")) != NULL){ if ((stoptime = xml_find_value(x, "body")) != NULL && str2time(stoptime, &stop) < 0){ if (netconf_bad_element(cbret, "application", "stopTime", "Expected timestamp") < 0) @@ -1132,7 +1132,7 @@ from_client_create_subscription(clicon_handle h, goto ok; } } - if ((x = xpath_first_nsc(xe, nsc, "//startTime")) != NULL){ + if ((x = xpath_first(xe, nsc, "//startTime")) != NULL){ if ((starttime = xml_find_value(x, "body")) != NULL && str2time(starttime, &start) < 0){ if (netconf_bad_element(cbret, "application", "startTime", "Expected timestamp") < 0) @@ -1140,7 +1140,7 @@ from_client_create_subscription(clicon_handle h, goto ok; } } - if ((xfilter = xpath_first_nsc(xe, nsc, "//filter")) != NULL){ + if ((xfilter = xpath_first(xe, nsc, "//filter")) != NULL){ if ((ftype = xml_find_value(xfilter, "type")) != NULL){ /* Only accept xpath as filter type */ if (strcmp(ftype, "xpath") != 0){ @@ -1367,8 +1367,8 @@ from_client_msg(clicon_handle h, goto reply; } - if ((x = xpath_first_nsc(xt, NULL, "/rpc")) == NULL){ - if ((x = xpath_first_nsc(xt, NULL, "/hello")) != NULL){ + if ((x = xpath_first(xt, NULL, "/rpc")) == NULL){ + if ((x = xpath_first(xt, NULL, "/hello")) != NULL){ if ((ret = from_client_hello(h, x, ce, cbret)) <0) goto done; goto reply; diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 3f0925a3..6ca91325 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -139,7 +139,7 @@ clixon_plugin_statedata(clicon_handle h, goto done; } cprintf(cberr, "Internal error: state callback returned invalid XML: "); - if (netconf_err2cb(xpath_first(xerr, "rpc-error"), cberr) < 0) + if (netconf_err2cb(xpath_first(xerr, NULL, "rpc-error"), cberr) < 0) goto done; if (*xret){ xml_free(*xret); diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index 8a273cd4..7bc1f340 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -707,13 +707,13 @@ compare_dbs(clicon_handle h, astext = 0; if (clicon_rpc_get_config(h, NULL, "running", "/", NULL, &xc1) < 0) goto done; - if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){ + if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } if (clicon_rpc_get_config(h, NULL, "candidate", "/", NULL, &xc2) < 0) goto done; - if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){ + if ((xerr = xpath_first(xc2, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } @@ -877,7 +877,7 @@ save_config_file(clicon_handle h, clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */ goto done; } - if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ + if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } @@ -985,7 +985,7 @@ cli_notification_cb(int s, } if (clicon_msg_decode(reply, NULL, NULL, &xt) < 0) /* XXX pass yang_spec */ goto done; - if ((xe = xpath_first(xt, "//event")) != NULL){ + if ((xe = xpath_first(xt, NULL, "//event")) != NULL){ x = NULL; while ((x = xml_child_each(xe, x, -1)) != NULL) { switch (format){ @@ -1217,7 +1217,7 @@ cli_copy_config(clicon_handle h, /* Get from object configuration and store in x1 */ if (clicon_rpc_get_config(h, NULL, db, cbuf_get(cb), nsc, &x1) < 0) goto done; - if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){ + if ((xerr = xpath_first(x1, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } @@ -1236,7 +1236,7 @@ cli_copy_config(clicon_handle h, xml_name_set(x2, "config"); cprintf(cb, "/%s", keyname); - if ((x = xpath_first_nsc(x2, nsc, "%s", cbuf_get(cb))) == NULL){ + if ((x = xpath_first(x2, nsc, "%s", cbuf_get(cb))) == NULL){ clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname); goto done; } diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index 18af35cc..c0897b61 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -157,7 +157,7 @@ expand_dbvar(void *h, /* Get configuration */ if (clicon_rpc_get_config(h, NULL, dbstr, xpath, nsc, &xt) < 0) /* XXX */ goto done; - if ((xe = xpath_first(xt, "/rpc-error")) != NULL){ + if ((xe = xpath_first(xt, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xe); goto ok; } @@ -204,12 +204,12 @@ expand_dbvar(void *h, fprintf(stderr, "%s\n", reason); goto done; } - if ((xcur = xpath_first_nsc(xt, nsc, "%s", xpath)) == NULL){ + if ((xcur = xpath_first(xt, nsc, "%s", xpath)) == NULL){ clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath); goto done; } } - if (xpath_vec_nsc(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0) + if (xpath_vec(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0) goto done; /* Loop for inserting into commands cvec. * Detect duplicates: for ordered-by system assume list is ordered, so you need @@ -486,7 +486,7 @@ cli_show_config1(clicon_handle h, if (clicon_rpc_get(h, cbuf_get(cbxpath), nsc, CONTENT_ALL, -1, &xt) < 0) goto done; } - if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ + if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } @@ -634,12 +634,12 @@ show_conf_xpath(clicon_handle h, goto done; if (clicon_rpc_get_config(h, NULL, str, xpath, nsc, &xt) < 0) goto done; - if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ + if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } - if (xpath_vec_nsc(xt, nsc, "%s", &xv, &xlen, xpath) < 0) + if (xpath_vec(xt, nsc, "%s", &xv, &xlen, xpath) < 0) goto done; for (i=0; i" @@ -163,7 +163,7 @@ netconf_get_config(clicon_handle h, char *ftype = NULL; /* ie ... */ - if ((xfilter = xpath_first(xn, "filter")) != NULL) + if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL) ftype = xml_find_value(xfilter, "type"); if (xfilter == NULL || ftype == NULL || strcmp(ftype, "xpath")==0){ if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0) @@ -218,7 +218,7 @@ get_edit_opts(cxobj *xn, cxobj *x; char *optstr; - if ((x = xpath_first(xn, "test-option")) != NULL){ + if ((x = xpath_first(xn, NULL, "test-option")) != NULL){ if ((optstr = xml_body(x)) != NULL){ if (strcmp(optstr, "test-then-set") == 0) *testopt = TEST_THEN_SET; @@ -230,7 +230,7 @@ get_edit_opts(cxobj *xn, goto parerr; } } - if ((x = xpath_first(xn, "error-option")) != NULL){ + if ((x = xpath_first(xn, NULL, "error-option")) != NULL){ if ((optstr = xml_body(x)) != NULL){ if (strcmp(optstr, "stop-on-error") == 0) *erropt = STOP_ON_ERROR; @@ -360,7 +360,7 @@ netconf_get(clicon_handle h, char *ftype = NULL; /* ie ... */ - if ((xfilter = xpath_first(xn, "filter")) != NULL) + if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL) ftype = xml_find_value(xfilter, "type"); if (xfilter == NULL || ftype == NULL || strcmp(ftype, "xpath")==0){ if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0) @@ -443,7 +443,7 @@ netconf_notification_cb(int s, if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL) goto done; - if ((xn = xpath_first_nsc(xt, nsc, "notification")) == NULL) + if ((xn = xpath_first(xt, nsc, "notification")) == NULL) goto ok; /* create netconf message */ if ((cb = cbuf_new()) == NULL){ @@ -495,7 +495,7 @@ netconf_create_subscription(clicon_handle h, int s; char *ftype; - if ((xfilter = xpath_first(xn, "//filter")) != NULL){ + if ((xfilter = xpath_first(xn, NULL, "//filter")) != NULL){ if ((ftype = xml_find_value(xfilter, "type")) != NULL){ if (strcmp(ftype, "xpath") != 0){ xml_parse_va(xret, NULL, "" @@ -511,7 +511,7 @@ netconf_create_subscription(clicon_handle h, } if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, &s) < 0) goto done; - if (xpath_first(*xret, "rpc-reply/rpc-error") != NULL) + if (xpath_first(*xret, NULL, "rpc-reply/rpc-error") != NULL) goto ok; if (event_reg_fd(s, netconf_notification_cb, @@ -617,7 +617,7 @@ netconf_application_rpc(clicon_handle h, */ if (0) if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){ - xoutput=xpath_first(*xret, "/"); + xoutput=xpath_first(*xret, NULL, "/"); xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */ if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0) goto done; diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c index 22d474cb..a87ceec9 100644 --- a/apps/restconf/restconf_lib.c +++ b/apps/restconf/restconf_lib.c @@ -476,7 +476,7 @@ api_return_err(clicon_handle h, clicon_debug(1, "%s", __FUNCTION__); if ((cb = cbuf_new()) == NULL) goto done; - if ((xtag = xpath_first(xerr, "//error-tag")) == NULL){ + if ((xtag = xpath_first(xerr, NULL, "//error-tag")) == NULL){ restconf_notfound(r); goto ok; } diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c index e9354b18..3ee07a19 100644 --- a/apps/restconf/restconf_main.c +++ b/apps/restconf/restconf_main.c @@ -418,7 +418,7 @@ api_restconf(clicon_handle h, else{ if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ if (api_return_err(h, r, xerr, pretty, media_out, 0) < 0) goto done; goto ok; diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 0ecf18f4..0545cb72 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -283,7 +283,7 @@ api_data_write(clicon_handle h, if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &nsc, &xerr)) < 0) goto done; if (ret == 0){ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -296,7 +296,7 @@ api_data_write(clicon_handle h, "candidate", cbuf_get(cbpath), nsc, &xret) < 0){ if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -341,7 +341,7 @@ api_data_write(clicon_handle h, if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot, &xerr)) < 0) goto done; if (ret == 0){ /* validation failed */ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -358,7 +358,7 @@ api_data_write(clicon_handle h, if (data == NULL || strlen(data) == 0){ if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -373,7 +373,7 @@ api_data_write(clicon_handle h, if (xml_parse_string(data, yspec, &xdata0) < 0){ if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -392,7 +392,7 @@ api_data_write(clicon_handle h, if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){ if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -401,7 +401,7 @@ api_data_write(clicon_handle h, goto ok; } if (ret == 0){ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -422,7 +422,7 @@ api_data_write(clicon_handle h, if (xml_child_nr(xdata0) != 1){ if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -450,7 +450,7 @@ api_data_write(clicon_handle h, if (ymoddata != ymodapi){ if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -493,7 +493,7 @@ api_data_write(clicon_handle h, if (strcmp(dname, xml_name(xbot))){ if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -518,7 +518,7 @@ api_data_write(clicon_handle h, if (match_list_keys(ybot, xdata, xbot) < 0){ if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -542,7 +542,7 @@ api_data_write(clicon_handle h, if (parbod == NULL || strcmp(parbod, xml_body(xdata))){ if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -603,7 +603,7 @@ api_data_write(clicon_handle h, clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0) goto done; - if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; @@ -616,14 +616,14 @@ api_data_write(clicon_handle h, cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0) goto done; - if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){ cbuf_reset(cbx); cprintf(cbx, "", username?username:""); cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0) goto done; /* log errors from discard, but ignore */ - if ((xpath_first(xretdis, "//rpc-error")) != NULL) + if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL) clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__); if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; @@ -646,7 +646,7 @@ api_data_write(clicon_handle h, if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0) goto done; /* If copy-config failed, log and ignore (already committed) */ - if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){ clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__); } @@ -840,7 +840,7 @@ api_data_delete(clicon_handle h, if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y, &xerr)) < 0) goto done; if (ret == 0){ /* validation failed */ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -871,7 +871,7 @@ api_data_delete(clicon_handle h, cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0) goto done; - if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; @@ -885,14 +885,14 @@ api_data_delete(clicon_handle h, cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0) goto done; - if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){ cbuf_reset(cbx); cprintf(cbx, "", clicon_nacm_recovery_user(h)); cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0) goto done; /* log errors from discard, but ignore */ - if ((xpath_first(xretdis, "//rpc-error")) != NULL) + if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL) clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__); if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; @@ -915,7 +915,7 @@ api_data_delete(clicon_handle h, if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0) goto done; /* If copy-config failed, log and ignore (already committed) */ - if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){ clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__); } diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c index b62da0da..124b35b1 100644 --- a/apps/restconf/restconf_methods_get.c +++ b/apps/restconf/restconf_methods_get.c @@ -130,7 +130,7 @@ api_data_get2(clicon_handle h, if (netconf_bad_attribute_xml(&xerr, "application", "content", "Unrecognized value of content attribute") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -152,7 +152,7 @@ api_data_get2(clicon_handle h, if (netconf_bad_attribute_xml(&xerr, "application", "depth", "Unrecognized value of depth attribute") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -172,7 +172,7 @@ api_data_get2(clicon_handle h, if ((ret = api_path2xpath_cvv(pcvec, pi, yspec, cbpath, &nsc, &xerr)) < 0) goto done; if (ret == 0){ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -196,7 +196,7 @@ api_data_get2(clicon_handle h, if (ret < 0){ if (netconf_operation_failed_xml(&xerr, "protocol", clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -218,7 +218,7 @@ api_data_get2(clicon_handle h, } #endif /* Check if error return */ - if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; @@ -247,10 +247,10 @@ api_data_get2(clicon_handle h, } } else{ - if (xpath_vec_nsc(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){ + if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0){ if (netconf_operation_failed_xml(&xerr, "application", clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c index c7700f41..40763d88 100644 --- a/apps/restconf/restconf_methods_post.c +++ b/apps/restconf/restconf_methods_post.c @@ -147,7 +147,7 @@ api_data_post(clicon_handle h, if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &ybot, &xerr)) < 0) goto done; if (ret == 0){ /* validation failed */ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -171,7 +171,7 @@ api_data_post(clicon_handle h, if (data == NULL || strlen(data) == 0){ if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -186,7 +186,7 @@ api_data_post(clicon_handle h, if (xml_parse_string(data, NULL, &xdata0) < 0){ if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -208,7 +208,7 @@ api_data_post(clicon_handle h, if ((ret = json_parse_str(data, yspec, &xdata0, &xerr)) < 0){ if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -217,7 +217,7 @@ api_data_post(clicon_handle h, goto ok; } if (ret == 0){ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -237,7 +237,7 @@ api_data_post(clicon_handle h, if (xml_child_nr(xdata0) != 1){ if (netconf_malformed_message_xml(&xerr, "The message-body MUST contain exactly one instance of the expected data resource") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -268,7 +268,7 @@ api_data_post(clicon_handle h, if (ys_real_module(ydata) != ymoddata){ if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -282,7 +282,7 @@ api_data_post(clicon_handle h, if (ybot && yang_parent_get(ydata) != ybot){ if (netconf_malformed_message_xml(&xerr, "Data is not prefixed with matching namespace") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -338,7 +338,7 @@ api_data_post(clicon_handle h, clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0) goto done; - if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "//rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; @@ -352,14 +352,14 @@ api_data_post(clicon_handle h, cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0) goto done; - if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){ cbuf_reset(cbx); cprintf(cbx, "", username?username:""); cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0) goto done; /* log errors from discard, but ignore */ - if ((xpath_first(xretdis, "//rpc-error")) != NULL) + if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL) clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__); if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) /* Use original xe */ goto done; @@ -382,7 +382,7 @@ api_data_post(clicon_handle h, if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0) goto done; /* If copy-config failed, log and ignore (already committed) */ - if ((xe = xpath_first(xretcom, "//rpc-error")) != NULL){ + if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){ clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__); } @@ -466,7 +466,7 @@ api_operations_post_input(clicon_handle h, if (xml_parse_string(data, yspec, &xdata) < 0){ if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -479,7 +479,7 @@ api_operations_post_input(clicon_handle h, if ((ret = json_parse_str(data, yspec, &xdata, &xerr)) < 0){ if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -488,7 +488,7 @@ api_operations_post_input(clicon_handle h, goto fail; } if (ret == 0){ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -527,7 +527,7 @@ api_operations_post_input(clicon_handle h, else if (netconf_malformed_message_xml(&xerr, "restconf RPC has malformed input statement (multiple or not called input)") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -601,7 +601,7 @@ api_operations_post_output(clicon_handle h, xml_child_nr_type(xret, CX_ELMNT) != 1){ if (netconf_malformed_message_xml(&xerr, "restconf RPC does not have single input") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -639,7 +639,7 @@ api_operations_post_output(clicon_handle h, (ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0) goto done; if (ret == 0){ /* validation failed */ - if ((xe = xpath_first(xerr, "rpc-reply/rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-reply/rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -770,7 +770,7 @@ api_operations_post(clicon_handle h, if (oppath == NULL || strcmp(oppath,"/")==0){ if (netconf_operation_failed_xml(&xerr, "protocol", "Operation name expected") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -789,7 +789,7 @@ api_operations_post(clicon_handle h, if ((ys = yang_find(yspec, Y_MODULE, prefix)) == NULL){ if (netconf_operation_failed_xml(&xerr, "protocol", "yang module not found") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -800,7 +800,7 @@ api_operations_post(clicon_handle h, if ((yrpc = yang_find(ys, Y_RPC, id)) == NULL){ if (netconf_missing_element_xml(&xerr, "application", id, "RPC not defined") < 0) goto done; - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -826,7 +826,7 @@ api_operations_post(clicon_handle h, if ((ret = api_path2xml(oppath, yspec, xtop, YC_SCHEMANODE, 1, &xbot, &y, &xerr)) < 0) goto done; if (ret == 0){ /* validation failed */ - if ((xe = xpath_first(xerr, "rpc-error")) == NULL){ + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } @@ -867,7 +867,7 @@ api_operations_post(clicon_handle h, if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0) goto done; if (ret == 0){ - if ((xe = xpath_first(xret, "rpc-error")) == NULL){ + if ((xe = xpath_first(xret, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto ok; } @@ -900,7 +900,7 @@ api_operations_post(clicon_handle h, if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0) goto done; /* Local error: return it and quit */ - if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; @@ -909,7 +909,7 @@ api_operations_post(clicon_handle h, else { /* Send to backend */ if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0) goto done; - if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; diff --git a/apps/restconf/restconf_stream.c b/apps/restconf/restconf_stream.c index 47375a98..a6b6ecdb 100644 --- a/apps/restconf/restconf_stream.c +++ b/apps/restconf/restconf_stream.c @@ -187,11 +187,11 @@ restconf_stream_cb(int s, clicon_err(OE_PLUGIN, errno, "cbuf_new"); goto done; } - if ((xn = xpath_first(xtop, "notification")) == NULL) + if ((xn = xpath_first(xtop, NULL, "notification")) == NULL) goto ok; #ifdef notused - xt = xpath_first(xn, "eventTime"); - if ((xe = xpath_first(xn, "event")) == NULL) /* event can depend on yang? */ + xt = xpath_first(xn, NULL, "eventTime"); + if ((xe = xpath_first(xn, NULL, "event")) == NULL) /* event can depend on yang? */ goto ok; if (xt) @@ -268,7 +268,7 @@ restconf_stream(clicon_handle h, cprintf(cb, "]]>]]>"); if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0) goto done; - if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){ + if ((xe = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){ if (api_return_err(h, r, xe, pretty, media_out, 0) < 0) goto done; goto ok; @@ -417,7 +417,7 @@ api_stream(clicon_handle h, else{ if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ if (api_return_err(h, r, xerr, pretty, media_out, 0) < 0) goto done; goto ok; diff --git a/example/main/example_backend.c b/example/main/example_backend.c index 928c07d2..95542477 100644 --- a/example/main/example_backend.c +++ b/example/main/example_backend.c @@ -321,7 +321,7 @@ example_statedata(clicon_handle h, goto done; if (xmldb_get0(h, "running", nsc1, "/interfaces/interface/name", 1, &xt, NULL) < 0) goto done; - if (xpath_vec_nsc(xt, nsc1, "/interfaces/interface/name", &xvec, &xlen) < 0) + if (xpath_vec(xt, nsc1, "/interfaces/interface/name", &xvec, &xlen) < 0) goto done; if (xlen){ cprintf(cb, ""); @@ -475,7 +475,7 @@ upgrade_2016(clicon_handle h, if ((name = xml_find_body(xi, "name")) == NULL) continue; /* shouldnt happen */ /* Get corresponding /interfaces/interface entry */ - xif = xpath_first(xt, "/interfaces/interface[name=\"%s\"]", name); + xif = xpath_first(xt, NULL, "/interfaces/interface[name=\"%s\"]", name); /* - Move /if:interfaces-state/if:interface/if:admin-status to * /if:interfaces/if:interface/ */ if ((x = xml_find(xi, "admin-status")) != NULL && xif){ @@ -578,7 +578,7 @@ upgrade_2018(clicon_handle h, /* Change type /interfaces/interface/statistics/in-octets to * decimal64 with fraction-digits 3 and divide values with 1000 */ - if ((x = xpath_first(xi, "statistics/in-octets")) != NULL){ + if ((x = xpath_first(xi, NULL, "statistics/in-octets")) != NULL){ if ((xb = xml_body_get(x)) != NULL){ uint64_t u64; cbuf *cb = cbuf_new(); diff --git a/example/main/example_backend_nacm.c b/example/main/example_backend_nacm.c index c0f49a40..a3c42657 100644 --- a/example/main/example_backend_nacm.c +++ b/example/main/example_backend_nacm.c @@ -87,7 +87,7 @@ nacm_validate(clicon_handle h, if (_transaction_log){ transaction_log(h, td, LOG_NOTICE, __FUNCTION__); if (_transaction_error_toggle==0 && - xpath_first(transaction_target(td), "%s", _transaction_xpath)){ + xpath_first(transaction_target(td), NULL, "%s", _transaction_xpath)){ _transaction_error_toggle=1; /* toggle if triggered */ clicon_err(OE_XML, 0, "User error"); return -1; /* induce fail */ @@ -116,7 +116,7 @@ nacm_commit(clicon_handle h, if (_transaction_log){ transaction_log(h, td, LOG_NOTICE, __FUNCTION__); if (_transaction_error_toggle==1 && - xpath_first(target, "%s", _transaction_xpath)){ + xpath_first(target, NULL, "%s", _transaction_xpath)){ _transaction_error_toggle=0; /* toggle if triggered */ clicon_err(OE_XML, 0, "User error"); return -1; /* induce fail */ diff --git a/example/main/example_cli.c b/example/main/example_cli.c index 04658d2e..330c38e4 100644 --- a/example/main/example_cli.c +++ b/example/main/example_cli.c @@ -109,7 +109,7 @@ example_client_rpc(clicon_handle h, /* Send to backend */ if (clicon_rpc_netconf_xml(h, xrpc, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } diff --git a/lib/clixon/clixon_xpath.h b/lib/clixon/clixon_xpath.h index 338dc002..1b2dfbb9 100644 --- a/lib/clixon/clixon_xpath.h +++ b/lib/clixon/clixon_xpath.h @@ -143,21 +143,13 @@ int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *xpformat, uint16_t flags, * 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))); +cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *xpformat, ...) __attribute__ ((format (printf, 3, 4))); +int xpath_vec(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, ...); +cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *xpformat, ...); +int xpath_vec(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 int xpath2canonical(char *xpath0, cvec *nsc0, yang_stmt *yspec, char **xpath1, cvec **nsc1); #endif /* _CLIXON_XPATH_H */ diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 07fb53d4..29e096e5 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -263,7 +263,7 @@ text_read_modstate(clicon_handle h, if ((name = xml_find_body(xm, "name")) == NULL) continue; /* 3a) There is no such module in the system */ - if ((xs = xpath_first(xmcache, "module[name=\"%s\"]", name)) == NULL){ + if ((xs = xpath_first(xmcache, NULL, "module[name=\"%s\"]", name)) == NULL){ // fprintf(stderr, "%s: Module %s: not in system\n", __FUNCTION__, name); if ((xm2 = xml_dup(xm)) == NULL) goto done; @@ -425,7 +425,7 @@ xmldb_get_nocache(clicon_handle h, goto done; /* Here xt looks like: ... */ /* Given the xpath, return a vector of matches in xvec */ - if (xpath_vec_nsc(xt, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(xt, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; /* If vectors are specified then mark the nodes found with all ancestors @@ -531,7 +531,7 @@ xmldb_get_cache(clicon_handle h, */ /* Here xt looks like: ... */ - if (xpath_vec_nsc(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; /* Make new tree by copying top-of-tree from x0t to x1t */ @@ -620,7 +620,7 @@ xmldb_get_zerocopy(clicon_handle h, else x0t = de->de_xml; /* Here xt looks like: ... */ - if (xpath_vec_nsc(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; /* Iterate through the match vector * For every node found in x0, mark the tree up to t1 diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 9daf9b93..95eb5379 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -887,7 +887,7 @@ xmldb_put(clicon_handle h, if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:yang:ietf-netconf-acm")) == NULL) goto done; if (xnacm0 != NULL && - (xnacm = xpath_first_nsc(xnacm0, nsc, "nacm")) != NULL){ + (xnacm = xpath_first(xnacm0, nsc, "nacm")) != NULL){ /* Pre-NACM access step, if permit, then dont do any nacm checks in * text_modify_* below */ if ((permit = nacm_access(h, mode, xnacm, username)) < 0) diff --git a/lib/src/clixon_nacm.c b/lib/src/clixon_nacm.c index b0da26e6..51a83c51 100644 --- a/lib/src/clixon_nacm.c +++ b/lib/src/clixon_nacm.c @@ -213,7 +213,7 @@ nacm_rpc(char *rpc, goto step10; /* User's group */ - if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0) + if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0) goto done; /* 5. If no groups are found, continue with step 10. */ if (glen == 0) @@ -222,14 +222,14 @@ nacm_rpc(char *rpc, configuration. If a rule-list's "group" leaf-list does not match any of the user's groups, proceed to the next rule-list entry. */ - if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0) + if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0) goto done; for (i=0; i= 3.10 */ if ((nsc = xml_nsctx_init(NULL, CLIXON_CONF_NS)) == NULL) goto done; - if ((xc = xpath_first_nsc(xt, nsc, "clixon-config")) == NULL){ + if ((xc = xpath_first(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: ", filename, CLIXON_CONF_NS); goto done; diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 5a3e7bd6..5d4b8dba 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -272,7 +272,7 @@ clicon_rpc_generate_error(const char *prefix, * err; * if (clicon_rpc_get_config(h, NULL, "running", "/hello/world", nsc, &xt) < 0) * err; - * if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ + * if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ * clicon_rpc_generate_error("", xerr); * err; * } @@ -328,9 +328,9 @@ clicon_rpc_get_config(clicon_handle h, if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; /* Send xml error back: first check error, then ok */ - if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL) + if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL) xd = xml_parent(xd); /* point to rpc-reply */ - else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL) + else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL) if ((xd = xml_new("data", NULL, NULL)) == NULL) goto done; if (xt){ @@ -394,7 +394,7 @@ clicon_rpc_edit_config(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Editing configuration", xerr); goto done; } @@ -441,7 +441,7 @@ clicon_rpc_copy_config(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Copying configuration", xerr); goto done; } @@ -481,7 +481,7 @@ clicon_rpc_delete_config(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Deleting configuration", xerr); goto done; } @@ -517,7 +517,7 @@ clicon_rpc_lock(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Locking configuration", xerr); goto done; } @@ -552,7 +552,7 @@ clicon_rpc_unlock(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Configuration unlock", xerr); goto done; } @@ -586,7 +586,7 @@ clicon_rpc_unlock(clicon_handle h, * err; * if (clicon_rpc_get(h, "/hello/world", nsc, CONTENT_ALL, -1, &xt) < 0) * err; - * if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){ + * if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){ * clicon_rpc_generate_error(xerr); * err; * } @@ -650,9 +650,9 @@ clicon_rpc_get(clicon_handle h, if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; /* Send xml error back: first check error, then ok */ - if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL) + if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL) xd = xml_parent(xd); /* point to rpc-reply */ - else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL) + else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL) if ((xd = xml_new("data", NULL, NULL)) == NULL) goto done; if (xt){ @@ -693,7 +693,7 @@ clicon_rpc_close_session(clicon_handle h) goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Close session", xerr); goto done; } @@ -729,7 +729,7 @@ clicon_rpc_kill_session(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Kill session", xerr); goto done; } @@ -764,7 +764,7 @@ clicon_rpc_validate(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error(CLIXON_ERRSTR_VALIDATE_FAILED, xerr); goto done; } @@ -797,7 +797,7 @@ clicon_rpc_commit(clicon_handle h) goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error(CLIXON_ERRSTR_COMMIT_FAILED, xerr); goto done; } @@ -830,7 +830,7 @@ clicon_rpc_discard_changes(clicon_handle h) goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Discard changes", xerr); goto done; } @@ -876,7 +876,7 @@ clicon_rpc_create_subscription(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, s0) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Create subscription", xerr); goto done; } @@ -911,11 +911,11 @@ clicon_rpc_debug(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Debug",xerr); goto done; } - if (xpath_first(xret, "//rpc-reply/ok") == NULL){ + if (xpath_first(xret, NULL, "//rpc-reply/ok") == NULL){ clicon_err(OE_XML, 0, "rpc error"); /* XXX extract info from rpc-error */ goto done; } @@ -954,11 +954,11 @@ clicon_hello_req(clicon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; - if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Hello", xerr); goto done; } - if ((x = xpath_first(xret, "hello/session-id")) == NULL){ + if ((x = xpath_first(xret, NULL, "hello/session-id")) == NULL){ clicon_err(OE_XML, 0, "hello session-id"); goto done; } diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index 397b91db..85e48edd 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -514,7 +514,7 @@ stream_notify1(clicon_handle h, else{ /* xpath match */ if (ss->ss_xpath == NULL || strlen(ss->ss_xpath)==0 || - xpath_first(xevent, "%s", ss->ss_xpath) != NULL) + xpath_first(xevent, NULL, "%s", ss->ss_xpath) != NULL) if ((*ss->ss_fn)(h, 0, xevent, ss->ss_arg) < 0) goto done; ss = NEXTQ(struct stream_subscription *, ss); diff --git a/lib/src/clixon_xml_changelog.c b/lib/src/clixon_xml_changelog.c index 3335beb2..833ee800 100644 --- a/lib/src/clixon_xml_changelog.c +++ b/lib/src/clixon_xml_changelog.c @@ -199,7 +199,7 @@ changelog_move(clicon_handle h, int retval = -1; cxobj *xp; /* destination parent node */ - if ((xp = xpath_first_nsc(xt, nsc, "%s", dst)) == NULL){ + if ((xp = xpath_first(xt, nsc, "%s", dst)) == NULL){ clicon_err(OE_XML, 0, "path required"); goto done; } @@ -252,7 +252,7 @@ changelog_op(clicon_handle h, if ((wxpath = xml_find_body(xi, "where")) == NULL) goto ok; /* Get vector of target nodes meeting the where requirement */ - if (xpath_vec_nsc(xt, nsc, "%s", &wvec, &wlen, wxpath) < 0) + if (xpath_vec(xt, nsc, "%s", &wvec, &wlen, wxpath) < 0) goto done; for (i=0; ixc_type == XT_NODESET && xr->xc_size) - cx = xr->xc_nodeset[0]; - done: - if (xr) - ctx_free(xr); - if (xpath) - free(xpath); - 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, + cvec *nsc, char *xpformat, ...) { @@ -532,7 +475,7 @@ xpath_first(cxobj *xcur, goto done; } va_end(ap); - if (xpath_vec_ctx(xcur, NULL, xpath, &xr) < 0) + if (xpath_vec_ctx(xcur, nsc, xpath, &xr) < 0) goto done; if (xr && xr->xc_type == XT_NODESET && xr->xc_size) cx = xr->xc_nodeset[0]; @@ -557,7 +500,7 @@ xpath_first(cxobj *xcur, * cvec *nsc; // namespace context * cxobj **vec; * size_t veclen; - * if (xpath_vec_nsc(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0) + * if (xpath_vec(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0) * goto err; * for (i=0; ixc_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; -} - -/*! 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; ixc_type == XT_NODESET){ *vec = xr->xc_nodeset; @@ -682,7 +557,7 @@ xpath_vec(cxobj *xcur, 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] xpformat Format string for XPATH syntax * @param[in] nsc External XML namespace context, or NULL diff --git a/lib/src/clixon_yang_module.c b/lib/src/clixon_yang_module.c index 0459da1b..cc1fe48a 100644 --- a/lib/src/clixon_yang_module.c +++ b/lib/src/clixon_yang_module.c @@ -306,7 +306,7 @@ yang_modules_state_get(clicon_handle h, /* xc is also original tree, need to copy it */ if ((xw = xml_wrap(xc, "top")) == NULL) goto done; - if (xpath_first(xw, "%s", xpath)){ + if (xpath_first(xw, NULL, "%s", xpath)){ if ((x = xml_dup(xc)) == NULL) /* Make copy and use below */ goto done; } @@ -338,7 +338,7 @@ yang_modules_state_get(clicon_handle h, if ((x = xml_wrap(x, "top")) < 0) goto done; /* extract xpath part of module-state tree */ - if (xpath_vec_nsc(x, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + if (xpath_vec(x, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) goto done; if (xvec != NULL){ for (i=0; i