From dfa30aa39c69d9ded9129ecbc69361a5e26d1113 Mon Sep 17 00:00:00 2001 From: Olof Hagsand Date: Sun, 17 Apr 2016 17:52:48 +0200 Subject: [PATCH] xml_print --- apps/backend/backend_client.c | 8 ++-- apps/backend/clixon_backend_handle.c | 52 ++++++++++++++++++++--- apps/backend/clixon_backend_transaction.c | 8 ++-- apps/cli/cli_common.c | 8 ++-- apps/cli/cli_show.c | 2 +- apps/netconf/netconf_rpc.c | 2 +- apps/xmldb/xmldb_main.c | 2 +- example/routing_backend.c | 2 +- example/routing_cli.c | 2 +- lib/clixon/clixon_xml.h | 1 + lib/src/clixon_xml.c | 16 +++++++ lib/src/clixon_xml_map.c | 25 +++++++++-- 12 files changed, 101 insertions(+), 27 deletions(-) diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 28c11602..fea04fd1 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -133,7 +133,9 @@ client_subscription_find(struct client_entry *ce, char *stream) /*! Remove client entry state * Close down everything wrt clients (eg sockets, subscriptions) * 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 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) goto done; - if (clicon_xml2file(f, xn, 0, 1) < 0) + if (xml_print(f, xn) < 0) goto done; retval = 0; done: @@ -404,7 +406,7 @@ from_client_save(clicon_handle h, } if (xmldb_get(h, db, "/", 0, &xn, NULL, NULL) < 0) goto done; - if (clicon_xml2file(f, xn, 0, 1) < 0) + if (xml_print(f, xn) < 0) goto done; } if (send_msg_ok(s) < 0) diff --git a/apps/backend/clixon_backend_handle.c b/apps/backend/clixon_backend_handle.c index 1b88a5a8..ffd0b43a 100644 --- a/apps/backend/clixon_backend_handle.c +++ b/apps/backend/clixon_backend_handle.c @@ -37,6 +37,7 @@ #include #include #include +#include #include /* cligen */ @@ -114,18 +115,35 @@ backend_notify(clicon_handle h, char *event) { struct client_entry *ce; + struct client_entry *ce_next; struct client_subscription *su; struct handle_subscription *hs; int retval = -1; /* 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) if (strcmp(su->su_stream, stream) == 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; + } } + } /* Then go thru all global (handle) subscriptions and find matches */ hs = NULL; while ((hs = subscription_each(h, hs)) != NULL){ @@ -162,6 +180,7 @@ backend_notify_xml(clicon_handle h, cxobj *x) { struct client_entry *ce; + struct client_entry *ce_next; struct client_subscription *su; int retval = -1; cbuf *cb = NULL; @@ -169,7 +188,8 @@ backend_notify_xml(clicon_handle h, clicon_debug(1, "%s %s", __FUNCTION__, stream); /* 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) if (strcmp(su->su_stream, stream) == 0){ 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) 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; + } } } + } /* Then go thru all global (handle) subscriptions and find matches */ hs = NULL; while ((hs = subscription_each(h, hs)) != NULL){ @@ -230,11 +265,14 @@ backend_client_list(clicon_handle h) return cb->cb_ce_list; } -/*! Actually remove client from list - * See also backend_client_rm() +/*! Actually remove client from client list + * @param[in] h Clicon handle + * @param[in] ce Client hadnle + * @see backend_client_rm which is more high-level */ 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 **ce_prev; diff --git a/apps/backend/clixon_backend_transaction.c b/apps/backend/clixon_backend_transaction.c index 48ee54be..94d461d6 100644 --- a/apps/backend/clixon_backend_transaction.c +++ b/apps/backend/clixon_backend_transaction.c @@ -188,19 +188,19 @@ transaction_print(FILE *f, fprintf(f, "Removed\n=========\n"); for (i=0; itd_dlen; i++){ xn = td->td_dvec[i]; - clicon_xml2file(f, xn, 0, 1); + xml_print(f, xn); } fprintf(f, "Added\n=========\n"); for (i=0; itd_alen; i++){ xn = td->td_avec[i]; - clicon_xml2file(f, xn, 0, 1); + xml_print(f, xn); } fprintf(stderr, "Changed\n=========\n"); for (i=0; itd_clen; i++){ xn = td->td_scvec[i]; - clicon_xml2file(f, xn, 0, 1); + xml_print(f, xn); xn = td->td_tcvec[i]; - clicon_xml2file(f, xn, 0, 1); + xml_print(f, xn); } return 0; } diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index 7080f4af..ca06b589 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -361,7 +361,7 @@ compare_xmls(cxobj *xc1, xml2txt(f, xc, 0); else while ((xc = xml_child_each(xc1, xc, -1)) != NULL) - clicon_xml2file(f, xc, 0, 1); + xml_print(f, xc); fclose(f); close(fd); @@ -378,7 +378,7 @@ compare_xmls(cxobj *xc1, xml2txt(f, xc, 0); else while ((xc = xml_child_each(xc2, xc, -1)) != NULL) - clicon_xml2file(f, xc, 0, 1); + xml_print(f, xc); fclose(f); close(fd); @@ -676,7 +676,7 @@ save_config_file(clicon_handle h, clicon_err(OE_CFG, errno, "Creating file %s", filename); goto done; } - if (clicon_xml2file(f, xt, 0, 1) < 0) + if (xml_print(f, xt) < 0) goto done; retval = 0; /* Fall through */ @@ -771,7 +771,7 @@ cli_notification_cb(int s, void *arg) if (clicon_xml_parse_string(&eventstr, &xt) < 0) goto done; if ((xn = xml_child_i(xt, 0)) != NULL) - if (clicon_xml2file(stdout, xn, 0, 1) < 0) + if (xml_print(stdout, xn) < 0) goto done; } else diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index 17f3298f..81fd2d69 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -489,7 +489,7 @@ show_conf_xpath(clicon_handle h, if (xmldb_get(h, str, xpath, 1, &xt, &xv, &xlen) < 0) goto done; for (i=0; iys_argument); - continue; + name = xml_name(xc); + if ((ys = yang_find_syntax((yang_node*)yt, name)) == NULL){ + clicon_debug(0, "%s: yang sanity problem: %s in xml but not present in yang under %s", + __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 ((body = xml_body(xc)) != NULL){ /* XXX: cvec_add uses realloc, can we avoid that? */