From b8831ee1956dca8eec7060eed556f64f975dd790 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sat, 25 Mar 2017 10:37:05 +0100 Subject: [PATCH 1/3] restconf format --- lib/src/clixon_xml_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/clixon_xml_db.c b/lib/src/clixon_xml_db.c index 25a51577..e85d5f58 100644 --- a/lib/src/clixon_xml_db.c +++ b/lib/src/clixon_xml_db.c @@ -1431,7 +1431,7 @@ xmldb_put_tree_local(clicon_handle h, clicon_err(OE_XML, errno, "List %s without argument", name); goto done; } - cprintf(ckey, "/%s", val2); + cprintf(ckey, "=%s", val2); cbuf_reset(csubkey); cprintf(csubkey, "%s/%s", cbuf_get(ckey), keyname); if (op == OP_MERGE || op == OP_REPLACE || op == OP_CREATE) From d58ffb2c72a462358716919d5fd9a16cbefc9fa1 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 25 May 2017 15:10:51 +0200 Subject: [PATCH 2/3] Strings in xmldb_put not properly encoded, eg eth/0 became eth.00000 --- CHANGELOG.md | 2 ++ configure | 6 +++--- configure.ac | 4 ++-- datastore/text/clixon_xmldb_text.c | 18 ++++++++++++++---- lib/src/clixon_proto_client.c | 4 ++-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0083e82a..9a99916f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Clixon CHANGELOG +- Strings in xmldb_put not properly encoded, eg eth/0 became eth.00000 + ## 3.3.0 May 2017 diff --git a/configure b/configure index d48a768e..5a53cb5e 100755 --- a/configure +++ b/configure @@ -2136,7 +2136,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu CLIXON_VERSION_MAJOR="3" CLIXON_VERSION_MINOR="3" -CLIXON_VERSION_PATCH="0" +CLIXON_VERSION_PATCH="1" CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\"" # Fix to specific version (eg 3.5) or head (3) CLIGEN_VERSION="3" @@ -2172,8 +2172,8 @@ _ACEOF # Bind to specific CLIgen version -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CLIXON version is ${CLIXON_VERSION}_PRE1" >&5 -$as_echo "CLIXON version is ${CLIXON_VERSION}_PRE1" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CLIXON version is ${CLIXON_VERSION}_PRE" >&5 +$as_echo "CLIXON version is ${CLIXON_VERSION}_PRE" >&6; } ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do diff --git a/configure.ac b/configure.ac index c7f30742..0232b9c6 100644 --- a/configure.ac +++ b/configure.ac @@ -43,7 +43,7 @@ AC_INIT(lib/clixon/clixon.h.in) CLIXON_VERSION_MAJOR="3" CLIXON_VERSION_MINOR="3" -CLIXON_VERSION_PATCH="0" +CLIXON_VERSION_PATCH="1" CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\"" # Fix to specific version (eg 3.5) or head (3) CLIGEN_VERSION="3" @@ -62,7 +62,7 @@ AC_SUBST(CLIXON_VERSION_MAJOR) AC_SUBST(CLIXON_VERSION_MINOR) AC_SUBST(CLIGEN_VERSION) # Bind to specific CLIgen version -AC_MSG_RESULT(CLIXON version is ${CLIXON_VERSION}_PRE1) +AC_MSG_RESULT(CLIXON version is ${CLIXON_VERSION}_PRE) AC_CANONICAL_TARGET AC_SUBST(CC) diff --git a/datastore/text/clixon_xmldb_text.c b/datastore/text/clixon_xmldb_text.c index 6ef443e8..4014426f 100644 --- a/datastore/text/clixon_xmldb_text.c +++ b/datastore/text/clixon_xmldb_text.c @@ -458,7 +458,8 @@ text_apipath_modify(char *api_path, int i; int j; char *name; - char *restval; + char *restval_enc; + char *restval = NULL; yang_stmt *y = NULL; yang_stmt *ykey; cxobj *x = NULL; @@ -490,9 +491,16 @@ text_apipath_modify(char *api_path, i = 1; while (i name:x restval=1,2 */ - if ((restval = index(name, '=')) != NULL){ - *restval = '\0'; - restval++; + /* restval is RFC 3896 encoded */ + if (restval){ + free(restval); + restval = NULL; + } + if ((restval_enc = index(name, '=')) != NULL){ + *restval_enc = '\0'; + restval_enc++; + if (percent_decode(restval_enc, &restval) < 0) + goto done; } if (y == NULL) /* top-node */ y = yang_find_topnode(yspec, name); @@ -646,6 +654,8 @@ text_apipath_modify(char *api_path, ok: retval = 0; done: + if (restval) + free(restval); if (vec) free(vec); if (valvec) diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 03558c57..a942306f 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -260,7 +260,7 @@ clicon_rpc_get_config(clicon_handle h, if (xpath && strlen(xpath)) cprintf(cb, "", xpath); cprintf(cb, ""); - if ((msg = clicon_msg_encode(cbuf_get(cb))) == NULL) + if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL) goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; @@ -325,7 +325,7 @@ clicon_rpc_edit_config(clicon_handle h, if (xmlstr) cprintf(cb, "%s", xmlstr); cprintf(cb, ""); - if ((msg = clicon_msg_encode(cbuf_get(cb))) == NULL) + if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL) goto done; if (clicon_rpc_msg(h, msg, &xret, NULL) < 0) goto done; From e5e1568a3eab4460910d6d3d2e2314cbbe4417ed Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 26 May 2017 11:31:04 +0200 Subject: [PATCH 3/3] debugging text datastore, pretty-print datastore --- datastore/keyvalue/Makefile.in | 6 +-- datastore/text/Makefile.in | 6 +-- datastore/text/clixon_xmldb_text.c | 67 ++++++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/datastore/keyvalue/Makefile.in b/datastore/keyvalue/Makefile.in index 9a116997..66e30ef7 100644 --- a/datastore/keyvalue/Makefile.in +++ b/datastore/keyvalue/Makefile.in @@ -80,13 +80,13 @@ distclean: clean $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c $< install: $(PLUGIN) - install -d $(DESTDIR)$(clixon_LIBDIR)/xmldb - install $(PLUGIN) $(DESTDIR)$(clixon_LIBDIR)/xmldb; + install -d $(DESTDIR)$(libdir)/xmldb + install $(PLUGIN) $(DESTDIR)$(libdir)/xmldb install-include: uninstall: - rm -rf $(DESTDIR)$(clixon_LIBDIR)/xmldb/$(PLUGIN); + rm -rf $(DESTDIR)$(libdir)/xmldb/$(PLUGIN) TAGS: find . -name '*.[chyl]' -print | etags - diff --git a/datastore/text/Makefile.in b/datastore/text/Makefile.in index 7b7cf6e9..fec58a71 100644 --- a/datastore/text/Makefile.in +++ b/datastore/text/Makefile.in @@ -79,13 +79,13 @@ distclean: clean $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c $< install: $(PLUGIN) - install -d $(DESTDIR)$(clixon_LIBDIR)/xmldb - install $(PLUGIN) $(DESTDIR)$(clixon_LIBDIR)/xmldb; + install -d $(DESTDIR)$(libdir)/xmldb + install $(PLUGIN) $(DESTDIR)$(libdir)/xmldb install-include: uninstall: - rm -rf $(DESTDIR)$(clixon_LIBDIR)/xmldb/$(PLUGIN); + rm -rf $(DESTDIR)$(clixon_LIBDIR)/xmldb/$(PLUGIN) TAGS: find . -name '*.[chyl]' -print | etags - diff --git a/datastore/text/clixon_xmldb_text.c b/datastore/text/clixon_xmldb_text.c index 4014426f..295beda1 100644 --- a/datastore/text/clixon_xmldb_text.c +++ b/datastore/text/clixon_xmldb_text.c @@ -265,9 +265,52 @@ xml_spec_populate(cxobj *x, y = yang_find_syntax((yang_node*)yp, xml_name(x)); else y = yang_find_topnode(yspec, name); /* still NULL for config */ + if (y==NULL){ + clicon_err(OE_XML, EBADF, "yang spec not found for xml node '%s' xml parent name: '%s' yangspec:'%s']", + name, + xp?xml_name(xp):"", yp?yp->ys_argument:""); + goto done; + } xml_spec_set(x, y); retval = 0; - // done: + done: + return retval; +} + +/*! Ensure that xt only has a single sub-element and that is "config" + */ +static int +singleconfigroot(cxobj *xt, + cxobj **xp) +{ + int retval = -1; + cxobj *x = NULL; + int i = 0; + + /* There should only be one element and called config */ + x = NULL; + while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL){ + i++; + if (strcmp(xml_name(x), "config")){ + clicon_err(OE_DB, ENOENT, "Wrong top-element %s expected config", + xml_name(x)); + goto done; + } + } + if (i != 1){ + clicon_err(OE_DB, ENOENT, "Top-element is not unique, expecting single config"); + goto done; + } + x = NULL; + while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL){ + if (xml_rm(x) < 0) + goto done; + if (xml_free(xt) < 0) + goto done; + *xp = x; + } + retval = 0; + done: return retval; } @@ -344,10 +387,15 @@ text_get(xmldb_handle xh, } /* 2. File is not empty ... -> replace root */ else{ - assert(xml_child_nr(xt)==1); - if (xml_rootchild(xt, 0, &xt) < 0) + /* There should only be one element and called config */ + if (singleconfigroot(xt, &xt) < 0) goto done; } + /* Here xt looks like: ... */ + /* Validate existing config tree */ + if (xml_apply(xt, CX_ELMNT, xml_spec_populate, yspec) < 0) + goto done; + /* XXX Maybe the below is general function and should be moved to xmldb? */ if (xpath_vec(xt, xpath?xpath:"/", &xvec, &xlen) < 0) goto done; @@ -974,11 +1022,14 @@ text_put(xmldb_handle xh, } /* 2. File is not empty ... -> replace root */ else{ - assert(xml_child_nr(xt)==1); - if (xml_rootchild(xt, 0, &xt) < 0) + /* The should only be one element and called config */ + if (singleconfigroot(xt, &xt) < 0) goto done; } - /* here xt looks like: ... */ + /* Here xt looks like: ... */ + /* Validate existing config tree */ + if (xml_apply(xt, CX_ELMNT, xml_spec_populate, yspec) < 0) + goto done; /* If xpath find first occurence or api-path (this is where we apply xml) */ if (api_path){ if (text_apipath_modify(api_path, xt, op, yspec, &xbase, &xbasep, &y) < 0) @@ -1021,7 +1072,7 @@ text_put(xmldb_handle xh, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(cb, xt, 0, 0) < 0) + if (clicon_xml2cbuf(cb, xt, 0, 1) < 0) goto done; /* Reopen file in write mode */ close(fd); @@ -1029,7 +1080,7 @@ text_put(xmldb_handle xh, clicon_err(OE_UNIX, errno, "open(%s)", dbfile); goto done; } - if (write(fd, cbuf_get(cb), cbuf_len(cb)+1) < 0){ + if (write(fd, cbuf_get(cb), cbuf_len(cb)) < 0){ clicon_err(OE_UNIX, errno, "write(%s)", dbfile); goto done; }