diff --git a/CHANGELOG b/CHANGELOG
index fffc0285..0e298e21 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -29,7 +29,34 @@
#
# ***** END LICENSE BLOCK *****
+- The netconf support has been extended with lock/unlock
+- clicon_rpc_call() has been removed and should be replaced by extending the
+ internal netconf protocol.
+ See downcall() function in example/routing_cli.c and
+ routing_downcall() in example/routing_backend.c
+- Replace clicon_rpc_xmlput with clicon_rpc_edit_config
+- Removed xmldb daemon. All xmldb acceses is made backend daemon.
+ No direct accesses by clients to xmldb API.
+ Instead use the rpc calls in clixon_proto_client.[ch]
+ In clients (eg cli/netconf) replace xmldb_get() in client code with
+ clicon_rpc_get_config().
+ If you use the vector arguments of xmldb_get(), replace as follows:
+ xmldb_get(h, db, api_path, &xt, &xvec, &xlen);
+ with
+ clicon_rpc_get_config(h, dbstr, api_path, &xt);
+ xpath_vec(xt, api_path, &xvec, &xlen)
+
+- xmdlb_put_xkey() and xmldb_put_tree() have been folded into xmldb_put()
+ Replace xmldb_put_xkey with xmldb_put as follows:
+ xmldb_put_xkey(h, "candidate", cbuf_get(cb), str, OP_REPLACE);
+ with
+ clicon_xml_parse(&xml, "%s", str);
+ xmldb_put(h, "candidate", OP_REPLACE, cbuf_get(cb), xml);
+ xml_free(xml);
+
- Change internal protocol from clicon_proto.h to netconf.
+ This means that the internal protocol defined in clixon_proto.[ch] is removed
+
- Netconf startup configuration support. Set CLICON_USE_STARTUP_CONFIG to 1 to
enable. Eg, if backend_main is started with -CIr startup will be copied to
running.
diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c
index 1f6518c8..e4402680 100644
--- a/apps/cli/cli_common.c
+++ b/apps/cli/cli_common.c
@@ -733,7 +733,7 @@ save_config_filev(clicon_handle h,
clicon_err(OE_CFG, errno, "Creating file %s", filename);
goto done;
}
- if (clicon_xml2file(f, xt, 0, 0) < 0)
+ if (clicon_xml2file(f, xt, 0, 1) < 0)
goto done;
retval = 0;
/* Fall through */
diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c
index 90f4c6ff..0b2c5031 100644
--- a/apps/restconf/restconf_methods.c
+++ b/apps/restconf/restconf_methods.c
@@ -103,6 +103,7 @@ Mapping netconf error-tag -> status code
#include
#include
#include
+#include
#include
#include
#include
@@ -161,7 +162,7 @@ api_data_get_gen(clicon_handle h,
cbuf *cbx = NULL;
cxobj **vec = NULL;
yang_spec *yspec;
- yang_stmt *y;
+ yang_stmt *y = NULL;
yang_stmt *ykey;
char *name;
cvec *cvk = NULL; /* vector of index keys */
@@ -189,6 +190,7 @@ api_data_get_gen(clicon_handle h,
}
}
else{
+ assert(y!=NULL);
if ((y = yang_find_syntax((yang_node*)y, name)) == NULL){
clicon_err(OE_UNIX, errno, "No yang node found: %s", name);
goto done;
diff --git a/clixon.conf.cpp.cpp b/clixon.conf.cpp.cpp
index 1dacc35a..22d4262c 100644
--- a/clixon.conf.cpp.cpp
+++ b/clixon.conf.cpp.cpp
@@ -121,11 +121,6 @@ CLICON_BACKEND_PIDFILE localstatedir/APPNAME/APPNAME.pidfile
# Directory where "running", "candidate" and "startup" are placed
CLICON_XMLDB_DIR localstatedir/APPNAME
-# CLICON_XMLDB_ADDR
-
-# xmldb tcp port (if CLICON_XMLDB_RPC)
-# CLICON_XMLDB_PORT
-
# Dont include keys in cvec in cli vars callbacks, ie a & k in 'a k ' ignored
# CLICON_CLI_VARONLY 1
diff --git a/lib/clixon/clixon_proto_client.h b/lib/clixon/clixon_proto_client.h
index 37420ca7..29ca939f 100644
--- a/lib/clixon/clixon_proto_client.h
+++ b/lib/clixon/clixon_proto_client.h
@@ -59,10 +59,6 @@ int clicon_rpc_commit(clicon_handle h);
int clicon_rpc_discard_changes(clicon_handle h);
int clicon_rpc_create_subscription(clicon_handle h, char *stream, char *filter,
int *s);
-
-int clicon_rpc_change(clicon_handle h, char *db,
- enum operation_type op, char *key, char *val);
-
int clicon_rpc_debug(clicon_handle h, int level);
#endif /* _CLIXON_PROTO_CLIENT_H_ */
diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c
index 9249e33b..7a6f4698 100644
--- a/lib/src/clixon_xml.c
+++ b/lib/src/clixon_xml.c
@@ -963,11 +963,11 @@ xml_parse(char *str,
return -1;
}
ya.ya_xparent = x_up;
+ ya.ya_skipspace = 1; /* remove all non-terminal bodies (strip pretty-print) */
if (clixon_xml_parsel_init(&ya) < 0)
goto done;
if (clixon_xml_parseparse(&ya) != 0) /* yacc returns 1 on error */
goto done;
-
retval = 0;
done:
clixon_xml_parsel_exit(&ya);
diff --git a/lib/src/clixon_xml_parse.h b/lib/src/clixon_xml_parse.h
index 05aeccdd..848bf55e 100644
--- a/lib/src/clixon_xml_parse.h
+++ b/lib/src/clixon_xml_parse.h
@@ -46,7 +46,7 @@ struct xml_parse_yacc_arg{
cxobj *ya_xelement; /* xml active element */
cxobj *ya_xparent; /* xml parent element*/
- int ya_skipspace; /* If set, translate successive space, \t \n with single space */
+ int ya_skipspace; /* If set, remove all non-terminal bodies (strip prettyr-print) */
};
extern char *clixon_xml_parsetext;
diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y
index c2923de4..ede62b8e 100644
--- a/lib/src/clixon_xml_parse.y
+++ b/lib/src/clixon_xml_parse.y
@@ -103,34 +103,19 @@ static int
xml_parse_content(struct xml_parse_yacc_arg *ya,
char *str)
{
- int sz;
- char s0;
cxobj *xn = ya->ya_xelement;
cxobj *xp = ya->ya_xparent;
int retval = -1;
ya->ya_xelement = NULL; /* init */
- s0 = str[0];
- if (xn != NULL){
- sz = strlen(xml_value(xn));
- if (ya->ya_skipspace && (s0 == ' ' || s0 == '\n' || s0 == '\t')){
- str[0] = ' ';
- if (xml_value(xn)[sz-1] == ' ')
- goto ok;
- }
- }
- else{
- if (ya->ya_skipspace && (s0 == ' ' || s0 == '\n' || s0 == '\t'))
- goto ok;
+ if (xn == NULL){
if ((xn = xml_new("body", xp)) == NULL)
goto done;
xml_type_set(xn, CX_BODY);
- sz = 0;
}
if (xml_value_append(xn, str)==NULL)
goto done;
ya->ya_xelement = xn;
- ok:
retval = 0;
done:
return retval;
@@ -148,7 +133,6 @@ xml_parse_version(struct xml_parse_yacc_arg *ya, char *ver)
return 0;
}
-
static int
xml_parse_id(struct xml_parse_yacc_arg *ya, char *name, char *namespace)
{
@@ -194,18 +178,31 @@ xml_parse_endslash_post(struct xml_parse_yacc_arg *ya)
static int
xml_parse_bslash1(struct xml_parse_yacc_arg *ya, char *name)
{
- int retval = -1;
+ int retval = -1;
+ cxobj *x = ya->ya_xelement;
+ cxobj *xc;
- if (strcmp(xml_name(ya->ya_xelement), name)){
+ if (strcmp(xml_name(x), name)){
clicon_err(OE_XML, 0, "Sanity check failed: %s vs %s",
- xml_name(ya->ya_xelement), name);
+ xml_name(x), name);
goto done;
}
- if (xml_namespace(ya->ya_xelement)!=NULL){
+ if (xml_namespace(x)!=NULL){
clicon_err(OE_XML, 0, "Sanity check failed: %s:%s vs %s\n",
- xml_namespace(ya->ya_xelement), xml_name(ya->ya_xelement), name);
+ xml_namespace(x), xml_name(x), name);
goto done;
}
+
+ /* remove all non-terminal bodies (strip pretty-print) */
+ if (ya->ya_skipspace){
+ if (xml_child_nr(x) == 1 && (xml_type(xml_child_i(x, 0))==CX_BODY))
+ ;
+ else{
+ xc = NULL;
+ while ((xc = xml_child_each(x, xc, CX_BODY)) != NULL)
+ xml_value_set(xc, ""); /* XXX remove */
+ }
+ }
retval = 0;
done:
free(name);
@@ -215,25 +212,37 @@ xml_parse_bslash1(struct xml_parse_yacc_arg *ya, char *name)
static int
xml_parse_bslash2(struct xml_parse_yacc_arg *ya, char *namespace, char *name)
{
- int retval = -1;
+ int retval = -1;
+ cxobj *x = ya->ya_xelement;
+ cxobj *xc;
- if (strcmp(xml_name(ya->ya_xelement), name)){
+ if (strcmp(xml_name(x), name)){
clicon_err(OE_XML, 0, "Sanity check failed: %s:%s vs %s:%s\n",
- xml_namespace(ya->ya_xelement),
- xml_name(ya->ya_xelement),
+ xml_namespace(x),
+ xml_name(x),
namespace,
name);
goto done;
}
- if (xml_namespace(ya->ya_xelement)==NULL ||
- strcmp(xml_namespace(ya->ya_xelement), namespace)){
+ if (xml_namespace(x)==NULL ||
+ strcmp(xml_namespace(x), namespace)){
clicon_err(OE_XML, 0, "Sanity check failed: %s:%s vs %s:%s\n",
- xml_namespace(ya->ya_xelement),
- xml_name(ya->ya_xelement),
+ xml_namespace(x),
+ xml_name(x),
namespace,
name);
goto done;
}
+ /* remove all non-terminal bodies (strip pretty-print) */
+ if (ya->ya_skipspace){
+ if (xml_child_nr(x) == 1 && (xml_type(xml_child_i(x, 0))==CX_BODY))
+ ;
+ else{
+ xc = NULL;
+ while ((xc = xml_child_each(x, xc, CX_BODY)) != NULL)
+ xml_value_set(xc, ""); /* XXX remove */
+ }
+ }
retval = 0;
done:
free(name);
@@ -301,7 +310,7 @@ emnt : '<' id attrs emnt1
;
id : NAME { if (xml_parse_id(_YA, $1, NULL) < 0) YYABORT;
- clicon_debug(3, "id -> NAME");}
+ clicon_debug(3, "id -> NAME %s", $1);}
| NAME ':' NAME { if (xml_parse_id(_YA, $3, $1) < 0) YYABORT;
clicon_debug(3, "id -> NAME : NAME");}
;
@@ -315,8 +324,8 @@ emnt1 : ESLASH {_YA->ya_xelement = NULL;
;
etg : BSLASH NAME '>'
- { if (xml_parse_bslash1(_YA, $2) < 0) YYABORT;
- clicon_debug(3, "etg -> < NAME >"); }
+{ clicon_debug(3, "etg -> < NAME %s>", $2); if (xml_parse_bslash1(_YA, $2) < 0) YYABORT; }
+
| BSLASH NAME ':' NAME '>'
{ if (xml_parse_bslash2(_YA, $2, $4) < 0) YYABORT;
clicon_debug(3, "etg -> < NAME:NAME >"); }
@@ -329,7 +338,7 @@ list : list content { clicon_debug(3, "list -> list content"); }
content : emnt { clicon_debug(3, "content -> emnt"); }
| comment { clicon_debug(3, "content -> comment"); }
| CHAR { if (xml_parse_content(_YA, $1) < 0) YYABORT;
- clicon_debug(3, "content -> CHAR", $1); }
+ clicon_debug(3, "content -> CHAR %s", $1); }
| { clicon_debug(3, "content -> "); }
;