xml_print
This commit is contained in:
parent
55201c9b4a
commit
dfa30aa39c
12 changed files with 101 additions and 27 deletions
|
|
@ -133,7 +133,9 @@ client_subscription_find(struct client_entry *ce, char *stream)
|
||||||
/*! Remove client entry state
|
/*! Remove client entry state
|
||||||
* Close down everything wrt clients (eg sockets, subscriptions)
|
* Close down everything wrt clients (eg sockets, subscriptions)
|
||||||
* Finally actually remove client struct in handle
|
* Finally actually remove client struct in handle
|
||||||
* @see backend_client_delete
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] ce Client hadnle
|
||||||
|
* @see backend_client_delete for actual deallocation of client entry struct
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
backend_client_rm(clicon_handle h,
|
backend_client_rm(clicon_handle h,
|
||||||
|
|
@ -338,7 +340,7 @@ config_snapshot(clicon_handle h,
|
||||||
}
|
}
|
||||||
if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0)
|
if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_xml2file(f, xn, 0, 1) < 0)
|
if (xml_print(f, xn) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -404,7 +406,7 @@ from_client_save(clicon_handle h,
|
||||||
}
|
}
|
||||||
if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0)
|
if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_xml2file(f, xn, 0, 1) < 0)
|
if (xml_print(f, xn) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (send_msg_ok(s) < 0)
|
if (send_msg_ok(s) < 0)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
#include <syslog.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
|
|
@ -114,18 +115,35 @@ backend_notify(clicon_handle h,
|
||||||
char *event)
|
char *event)
|
||||||
{
|
{
|
||||||
struct client_entry *ce;
|
struct client_entry *ce;
|
||||||
|
struct client_entry *ce_next;
|
||||||
struct client_subscription *su;
|
struct client_subscription *su;
|
||||||
struct handle_subscription *hs;
|
struct handle_subscription *hs;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
/* First thru all clients(sessions), and all subscriptions and find matches */
|
/* First thru all clients(sessions), and all subscriptions and find matches */
|
||||||
for (ce = backend_client_list(h); ce; ce = ce->ce_next)
|
for (ce = backend_client_list(h); ce; ce = ce_next){
|
||||||
|
ce_next = ce->ce_next;
|
||||||
for (su = ce->ce_subscription; su; su = su->su_next)
|
for (su = ce->ce_subscription; su; su = su->su_next)
|
||||||
if (strcmp(su->su_stream, stream) == 0){
|
if (strcmp(su->su_stream, stream) == 0){
|
||||||
if (fnmatch(su->su_filter, event, 0) == 0)
|
if (fnmatch(su->su_filter, event, 0) == 0)
|
||||||
if (send_msg_notify(ce->ce_s, level, event) < 0)
|
if (send_msg_notify(ce->ce_s, level, event) < 0){
|
||||||
|
if (errno == ECONNRESET){
|
||||||
|
clicon_log(LOG_WARNING, "client %s reset", ce->ce_nr);
|
||||||
|
#if 0
|
||||||
|
/* We should remove here but removal is not possible
|
||||||
|
from a client since backend_client is not linked.
|
||||||
|
Maybe we should add it to the plugin, but it feels
|
||||||
|
"safe" that you cant remove a client.
|
||||||
|
Instead, the client is (hopefully) removed elsewhere?
|
||||||
|
*/
|
||||||
|
backend_client_rm(h, ce);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Then go thru all global (handle) subscriptions and find matches */
|
/* Then go thru all global (handle) subscriptions and find matches */
|
||||||
hs = NULL;
|
hs = NULL;
|
||||||
while ((hs = subscription_each(h, hs)) != NULL){
|
while ((hs = subscription_each(h, hs)) != NULL){
|
||||||
|
|
@ -162,6 +180,7 @@ backend_notify_xml(clicon_handle h,
|
||||||
cxobj *x)
|
cxobj *x)
|
||||||
{
|
{
|
||||||
struct client_entry *ce;
|
struct client_entry *ce;
|
||||||
|
struct client_entry *ce_next;
|
||||||
struct client_subscription *su;
|
struct client_subscription *su;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
|
|
@ -169,7 +188,8 @@ backend_notify_xml(clicon_handle h,
|
||||||
|
|
||||||
clicon_debug(1, "%s %s", __FUNCTION__, stream);
|
clicon_debug(1, "%s %s", __FUNCTION__, stream);
|
||||||
/* Now go thru all clients(sessions), and all subscriptions and find matches */
|
/* Now go thru all clients(sessions), and all subscriptions and find matches */
|
||||||
for (ce = backend_client_list(h); ce; ce = ce->ce_next)
|
for (ce = backend_client_list(h); ce; ce = ce_next){
|
||||||
|
ce_next = ce->ce_next;
|
||||||
for (su = ce->ce_subscription; su; su = su->su_next)
|
for (su = ce->ce_subscription; su; su = su->su_next)
|
||||||
if (strcmp(su->su_stream, stream) == 0){
|
if (strcmp(su->su_stream, stream) == 0){
|
||||||
if (strlen(su->su_filter)==0 || xpath_first(x, su->su_filter) != NULL){
|
if (strlen(su->su_filter)==0 || xpath_first(x, su->su_filter) != NULL){
|
||||||
|
|
@ -181,10 +201,25 @@ backend_notify_xml(clicon_handle h,
|
||||||
if (clicon_xml2cbuf(cb, x, 0, 0) < 0)
|
if (clicon_xml2cbuf(cb, x, 0, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (send_msg_notify(ce->ce_s, level, cbuf_get(cb)) < 0)
|
if (send_msg_notify(ce->ce_s, level, cbuf_get(cb)) < 0){
|
||||||
|
if (errno == ECONNRESET){
|
||||||
|
clicon_log(LOG_WARNING, "client %s reset", ce->ce_nr);
|
||||||
|
#if 0
|
||||||
|
/* We should remove here but removal is not possible
|
||||||
|
from a client since backend_client is not linked.
|
||||||
|
Maybe we should add it to the plugin, but it feels
|
||||||
|
"safe" that you cant remove a client.
|
||||||
|
Instead, the client is (hopefully) removed elsewhere?
|
||||||
|
*/
|
||||||
|
backend_client_rm(h, ce);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Then go thru all global (handle) subscriptions and find matches */
|
/* Then go thru all global (handle) subscriptions and find matches */
|
||||||
hs = NULL;
|
hs = NULL;
|
||||||
while ((hs = subscription_each(h, hs)) != NULL){
|
while ((hs = subscription_each(h, hs)) != NULL){
|
||||||
|
|
@ -230,11 +265,14 @@ backend_client_list(clicon_handle h)
|
||||||
return cb->cb_ce_list;
|
return cb->cb_ce_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Actually remove client from list
|
/*! Actually remove client from client list
|
||||||
* See also backend_client_rm()
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] ce Client hadnle
|
||||||
|
* @see backend_client_rm which is more high-level
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
backend_client_delete(clicon_handle h, struct client_entry *ce)
|
backend_client_delete(clicon_handle h,
|
||||||
|
struct client_entry *ce)
|
||||||
{
|
{
|
||||||
struct client_entry *c;
|
struct client_entry *c;
|
||||||
struct client_entry **ce_prev;
|
struct client_entry **ce_prev;
|
||||||
|
|
|
||||||
|
|
@ -188,19 +188,19 @@ transaction_print(FILE *f,
|
||||||
fprintf(f, "Removed\n=========\n");
|
fprintf(f, "Removed\n=========\n");
|
||||||
for (i=0; i<td->td_dlen; i++){
|
for (i=0; i<td->td_dlen; i++){
|
||||||
xn = td->td_dvec[i];
|
xn = td->td_dvec[i];
|
||||||
clicon_xml2file(f, xn, 0, 1);
|
xml_print(f, xn);
|
||||||
}
|
}
|
||||||
fprintf(f, "Added\n=========\n");
|
fprintf(f, "Added\n=========\n");
|
||||||
for (i=0; i<td->td_alen; i++){
|
for (i=0; i<td->td_alen; i++){
|
||||||
xn = td->td_avec[i];
|
xn = td->td_avec[i];
|
||||||
clicon_xml2file(f, xn, 0, 1);
|
xml_print(f, xn);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Changed\n=========\n");
|
fprintf(stderr, "Changed\n=========\n");
|
||||||
for (i=0; i<td->td_clen; i++){
|
for (i=0; i<td->td_clen; i++){
|
||||||
xn = td->td_scvec[i];
|
xn = td->td_scvec[i];
|
||||||
clicon_xml2file(f, xn, 0, 1);
|
xml_print(f, xn);
|
||||||
xn = td->td_tcvec[i];
|
xn = td->td_tcvec[i];
|
||||||
clicon_xml2file(f, xn, 0, 1);
|
xml_print(f, xn);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -361,7 +361,7 @@ compare_xmls(cxobj *xc1,
|
||||||
xml2txt(f, xc, 0);
|
xml2txt(f, xc, 0);
|
||||||
else
|
else
|
||||||
while ((xc = xml_child_each(xc1, xc, -1)) != NULL)
|
while ((xc = xml_child_each(xc1, xc, -1)) != NULL)
|
||||||
clicon_xml2file(f, xc, 0, 1);
|
xml_print(f, xc);
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
@ -378,7 +378,7 @@ compare_xmls(cxobj *xc1,
|
||||||
xml2txt(f, xc, 0);
|
xml2txt(f, xc, 0);
|
||||||
else
|
else
|
||||||
while ((xc = xml_child_each(xc2, xc, -1)) != NULL)
|
while ((xc = xml_child_each(xc2, xc, -1)) != NULL)
|
||||||
clicon_xml2file(f, xc, 0, 1);
|
xml_print(f, xc);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
|
@ -676,7 +676,7 @@ save_config_file(clicon_handle h,
|
||||||
clicon_err(OE_CFG, errno, "Creating file %s", filename);
|
clicon_err(OE_CFG, errno, "Creating file %s", filename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_xml2file(f, xt, 0, 1) < 0)
|
if (xml_print(f, xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
@ -771,7 +771,7 @@ cli_notification_cb(int s, void *arg)
|
||||||
if (clicon_xml_parse_string(&eventstr, &xt) < 0)
|
if (clicon_xml_parse_string(&eventstr, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xn = xml_child_i(xt, 0)) != NULL)
|
if ((xn = xml_child_i(xt, 0)) != NULL)
|
||||||
if (clicon_xml2file(stdout, xn, 0, 1) < 0)
|
if (xml_print(stdout, xn) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -489,7 +489,7 @@ show_conf_xpath(clicon_handle h,
|
||||||
if (xmldb_get(h, str, xpath, 1, &xt, &xv, &xlen) < 0)
|
if (xmldb_get(h, str, xpath, 1, &xt, &xv, &xlen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<xlen; i++)
|
for (i=0; i<xlen; i++)
|
||||||
clicon_xml2file(stdout, xv[i], 0, 1);
|
xml_print(stdout, xv[i]);
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
|
|
@ -829,7 +829,7 @@ netconf_notification_cb(int s,
|
||||||
|
|
||||||
if (0){
|
if (0){
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__); /* debug */
|
fprintf(stderr, "%s\n", __FUNCTION__); /* debug */
|
||||||
clicon_xml2file(stderr, xfilter, 0, 1); /* debug */
|
xml_print(stderr, xfilter); /* debug */
|
||||||
}
|
}
|
||||||
/* get msg (this is the reason this function is called) */
|
/* get msg (this is the reason this function is called) */
|
||||||
if (clicon_msg_rcv(s, &reply, &eof, __FUNCTION__) < 0)
|
if (clicon_msg_rcv(s, &reply, &eof, __FUNCTION__) < 0)
|
||||||
|
|
|
||||||
|
|
@ -636,7 +636,7 @@ xmldb_from_client(clicon_handle h,
|
||||||
if (clicon_xml_parse_string(&str, &xrq) < 0)
|
if (clicon_xml_parse_string(&str, &xrq) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (debug)
|
if (debug)
|
||||||
clicon_xml2file(stderr, xrq, 0, 1);
|
xml_print(stderr, xrq);
|
||||||
if ((xr = xpath_first(xrq, "rpc")) != NULL){
|
if ((xr = xpath_first(xrq, "rpc")) != NULL){
|
||||||
if ((x = xpath_first(xr, "get")) != NULL){
|
if ((x = xpath_first(xr, "get")) != NULL){
|
||||||
if (xmldb_from_get(h, s, x) < 0)
|
if (xmldb_from_get(h, s, x) < 0)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ transaction_commit(clicon_handle h,
|
||||||
if (xpath_vec_flag(target, "//interface", XML_FLAG_ADD, &vec, &len) < 0)
|
if (xpath_vec_flag(target, "//interface", XML_FLAG_ADD, &vec, &len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
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 */
|
xml_print(stdout, vec[i]); /* Print the added interface */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ mycallback(clicon_handle h, cvec *cvv, cg_var *arg)
|
||||||
0,
|
0,
|
||||||
&xt, NULL, NULL) < 0)
|
&xt, NULL, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_xml2file(stdout, xt, 0, 1);
|
xml_print(stdout, xt);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (xt)
|
if (xt)
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ char *xml_find_body(cxobj *xn, char *name);
|
||||||
|
|
||||||
int xml_free(cxobj *xn);
|
int xml_free(cxobj *xn);
|
||||||
|
|
||||||
|
int xml_print(FILE *f, cxobj *xn);
|
||||||
int clicon_xml2file(FILE *f, cxobj *xn, int level, int prettyprint);
|
int clicon_xml2file(FILE *f, cxobj *xn, int level, int prettyprint);
|
||||||
int clicon_xml2cbuf(cbuf *xf, cxobj *xn, int level, int prettyprint);
|
int clicon_xml2cbuf(cbuf *xf, cxobj *xn, int level, int prettyprint);
|
||||||
int clicon_xml_parse_file(int fd, cxobj **xml_top, char *endtag);
|
int clicon_xml_parse_file(int fd, cxobj **xml_top, char *endtag);
|
||||||
|
|
|
||||||
|
|
@ -799,6 +799,22 @@ clicon_xml2file(FILE *f,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Print an XML tree structure to an output stream
|
||||||
|
*
|
||||||
|
* Uses clicon_xml2file internally
|
||||||
|
*
|
||||||
|
* @param[in] f UNIX output stream
|
||||||
|
* @param[in] xn clicon xml tree
|
||||||
|
* @see clicon_xml2cbuf
|
||||||
|
* @see clicon_xml2file
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xml_print(FILE *f,
|
||||||
|
cxobj *xn)
|
||||||
|
{
|
||||||
|
return clicon_xml2file(f, xn, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#define XML_INDENT 3 /* maybve we should set this programmatically? */
|
#define XML_INDENT 3 /* maybve we should set this programmatically? */
|
||||||
|
|
||||||
/*! Print an XML tree structure to a clicon buffer
|
/*! Print an XML tree structure to a clicon buffer
|
||||||
|
|
|
||||||
|
|
@ -461,6 +461,7 @@ xml2cvec(cxobj *xt,
|
||||||
int ret;
|
int ret;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
char *name;
|
||||||
|
|
||||||
xc = NULL;
|
xc = NULL;
|
||||||
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL)
|
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL)
|
||||||
|
|
@ -472,11 +473,27 @@ xml2cvec(cxobj *xt,
|
||||||
xc = NULL;
|
xc = NULL;
|
||||||
/* Go through all children of the xml tree */
|
/* Go through all children of the xml tree */
|
||||||
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL){
|
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL){
|
||||||
if ((ys = yang_find_syntax((yang_node*)yt, xml_name(xc))) == NULL){
|
name = xml_name(xc);
|
||||||
clicon_debug(1, "%s: yang sanity problem: %s in xml but not present in yang under %s",
|
if ((ys = yang_find_syntax((yang_node*)yt, name)) == NULL){
|
||||||
__FUNCTION__, xml_name(xc), yt->ys_argument);
|
clicon_debug(0, "%s: yang sanity problem: %s in xml but not present in yang under %s",
|
||||||
continue;
|
__FUNCTION__, name, yt->ys_argument);
|
||||||
|
if ((body = xml_body(xc)) != NULL){
|
||||||
|
cv = cvec_i(cvv, i++);
|
||||||
|
cv_type_set(cv, CGV_STRING);
|
||||||
|
cv_name_set(cv, name);
|
||||||
|
if ((ret = cv_parse1(body, cv, &reason)) < 0){
|
||||||
|
clicon_err(OE_PLUGIN, errno, "cv_parse");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (ret == 0){
|
||||||
|
clicon_err(OE_PLUGIN, errno, "cv_parse: %s", reason);
|
||||||
|
if (reason)
|
||||||
|
free(reason);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if ((ycv = ys->ys_cv) != NULL){
|
if ((ycv = ys->ys_cv) != NULL){
|
||||||
if ((body = xml_body(xc)) != NULL){
|
if ((body = xml_body(xc)) != NULL){
|
||||||
/* XXX: cvec_add uses realloc, can we avoid that? */
|
/* XXX: cvec_add uses realloc, can we avoid that? */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue