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 -> < "); } +{ clicon_debug(3, "etg -> < ", $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 -> < "); } @@ -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 -> "); } ;