Dedicated xml,json,yang and xsl parser utility programs added
Sanity check of stdarg (...) added Cleanup of error messages.
This commit is contained in:
parent
1306174071
commit
85c4782e36
56 changed files with 1004 additions and 379 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
* Applications which have not strictly enforced the identities may now have problems with validation and may need to be modified.
|
* Applications which have not strictly enforced the identities may now have problems with validation and may need to be modified.
|
||||||
|
|
||||||
### Minor changes:
|
### Minor changes:
|
||||||
|
* Dedicated xml,json,yang and xsl parser utility programs added
|
||||||
* CDATA xml support (patch by David Cornejo, Netgate)
|
* CDATA xml support (patch by David Cornejo, Netgate)
|
||||||
* Encode and decode (parsing) support
|
* Encode and decode (parsing) support
|
||||||
* Validation of yang bits type space-separated list value
|
* Validation of yang bits type space-separated list value
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@
|
||||||
* string regexp checked.
|
* string regexp checked.
|
||||||
* See also db_lv_set() where defaults are also filled in. The case here for defaults
|
* See also db_lv_set() where defaults are also filled in. The case here for defaults
|
||||||
* are if code comes via XML/NETCONF.
|
* are if code comes via XML/NETCONF.
|
||||||
* @param yspec Yang spec
|
* @param[in] yspec Yang spec
|
||||||
* @param td Transaction data
|
* @param[in] td Transaction data
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
generic_validate(yang_spec *yspec,
|
generic_validate(yang_spec *yspec,
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ clixon_plugin_statedata(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Code complex to filter out anything that is outside of xpath */
|
/* Code complex to filter out anything that is outside of xpath */
|
||||||
if (xpath_vec(*xtop, xpath?xpath:"/", &xvec, &xlen) < 0)
|
if (xpath_vec(*xtop, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* If vectors are specified then mark the nodes found and
|
/* If vectors are specified then mark the nodes found and
|
||||||
|
|
|
||||||
|
|
@ -96,12 +96,12 @@ config_socket_init_ipv4(clicon_handle h, char *dst)
|
||||||
goto err; /* Could check getaddrinfo */
|
goto err; /* Could check getaddrinfo */
|
||||||
}
|
}
|
||||||
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0){
|
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: bind", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "bind");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
clicon_debug(1, "Listen on server socket at %s:%hu", dst, port);
|
clicon_debug(1, "Listen on server socket at %s:%hu", dst, port);
|
||||||
if (listen(s, 5) < 0){
|
if (listen(s, 5) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: listen", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "listen");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
|
@ -126,7 +126,7 @@ config_socket_init_unix(clicon_handle h, char *sock)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
if (lstat(sock, &st) == 0 && unlink(sock) < 0){
|
if (lstat(sock, &st) == 0 && unlink(sock) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: unlink(%s)", __FUNCTION__, sock);
|
clicon_err(OE_UNIX, errno, "unlink(%s)", sock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* then find configuration group (for clients) and find its groupid */
|
/* then find configuration group (for clients) and find its groupid */
|
||||||
|
|
@ -142,7 +142,7 @@ config_socket_init_unix(clicon_handle h, char *sock)
|
||||||
#endif
|
#endif
|
||||||
/* create unix socket */
|
/* create unix socket */
|
||||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||||
clicon_err(OE_UNIX, errno, "%s: socket", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof(one));
|
// setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof(one));
|
||||||
|
|
@ -151,20 +151,19 @@ config_socket_init_unix(clicon_handle h, char *sock)
|
||||||
strncpy(addr.sun_path, sock, sizeof(addr.sun_path)-1);
|
strncpy(addr.sun_path, sock, sizeof(addr.sun_path)-1);
|
||||||
old_mask = umask(S_IRWXO | S_IXGRP | S_IXUSR);
|
old_mask = umask(S_IRWXO | S_IXGRP | S_IXUSR);
|
||||||
if (bind(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){
|
if (bind(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: bind", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "bind");
|
||||||
umask(old_mask);
|
umask(old_mask);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
umask(old_mask);
|
umask(old_mask);
|
||||||
/* change socket path file group */
|
/* change socket path file group */
|
||||||
if (lchown(sock, -1, gid) < 0){
|
if (lchown(sock, -1, gid) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: lchown(%s, %s)", __FUNCTION__,
|
clicon_err(OE_UNIX, errno, "lchown(%s, %s)", sock, config_group);
|
||||||
sock, config_group);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
clicon_debug(1, "Listen on server socket at %s", addr.sun_path);
|
clicon_debug(1, "Listen on server socket at %s", addr.sun_path);
|
||||||
if (listen(s, 5) < 0){
|
if (listen(s, 5) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: listen", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "listen");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
|
@ -221,14 +220,14 @@ backend_accept_client(int fd,
|
||||||
clicon_debug(2, "%s", __FUNCTION__);
|
clicon_debug(2, "%s", __FUNCTION__);
|
||||||
len = sizeof(from);
|
len = sizeof(from);
|
||||||
if ((s = accept(fd, (struct sockaddr*)&from, &len)) < 0){
|
if ((s = accept(fd, (struct sockaddr*)&from, &len)) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: accept", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "accept");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
#if defined(SO_PEERCRED)
|
#if defined(SO_PEERCRED)
|
||||||
/* fill in the user data structure */
|
/* fill in the user data structure */
|
||||||
clen = sizeof(credentials);
|
clen = sizeof(credentials);
|
||||||
if(getsockopt(s, SOL_SOCKET, SO_PEERCRED/* XXX finns ej i freebsd*/, &credentials, &clen)){
|
if(getsockopt(s, SOL_SOCKET, SO_PEERCRED/* XXX finns ej i freebsd*/, &credentials, &clen)){
|
||||||
clicon_err(OE_UNIX, errno, "%s: getsockopt", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "getsockopt");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ backend_notify_xml(clicon_handle h,
|
||||||
ce_next = 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, "%s", su->su_filter) != NULL){
|
||||||
if (cb==NULL){
|
if (cb==NULL){
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
|
|
@ -255,7 +255,7 @@ backend_notify_xml(clicon_handle h,
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(hs->hs_stream, stream))
|
if (strcmp(hs->hs_stream, stream))
|
||||||
continue;
|
continue;
|
||||||
if (strlen(hs->hs_filter)==0 || xpath_first(x, hs->hs_filter) != NULL){
|
if (strlen(hs->hs_filter)==0 || xpath_first(x, "%s", hs->hs_filter) != NULL){
|
||||||
if ((*hs->hs_fn)(h, x, hs->hs_arg) < 0)
|
if ((*hs->hs_fn)(h, x, hs->hs_arg) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ cli_dbxml(clicon_handle h,
|
||||||
cxobj *xb; /* body */
|
cxobj *xb; /* body */
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires one element to be xml key format string", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires one element to be xml key format string");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
|
@ -396,7 +396,7 @@ cli_debug_cli(clicon_handle h,
|
||||||
|
|
||||||
if ((cv = cvec_find(vars, "level")) == NULL){
|
if ((cv = cvec_find(vars, "level")) == NULL){
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires either label var or single arg: 0|1", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires either label var or single arg: 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
|
|
@ -427,7 +427,7 @@ cli_debug_backend(clicon_handle h,
|
||||||
|
|
||||||
if ((cv = cvec_find(vars, "level")) == NULL){
|
if ((cv = cvec_find(vars, "level")) == NULL){
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires either label var or single arg: 0|1", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires either label var or single arg: 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
|
|
@ -457,7 +457,7 @@ cli_debug_restconf(clicon_handle h,
|
||||||
|
|
||||||
if ((cv = cvec_find(vars, "level")) == NULL){
|
if ((cv = cvec_find(vars, "level")) == NULL){
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires either label var or single arg: 0|1", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires either label var or single arg: 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cv = cvec_i(argv, 0);
|
cv = cvec_i(argv, 0);
|
||||||
|
|
@ -482,7 +482,7 @@ cli_set_mode(clicon_handle h,
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires one element to be cli mode", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires one element to be cli mode");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
str = cv_string_get(cvec_i(argv, 0));
|
str = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -494,6 +494,7 @@ cli_set_mode(clicon_handle h,
|
||||||
|
|
||||||
/*! Start bash from cli callback
|
/*! Start bash from cli callback
|
||||||
* XXX Application specific??
|
* XXX Application specific??
|
||||||
|
* XXX replace fprintf with clicon_err?
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cli_start_shell(clicon_handle h,
|
cli_start_shell(clicon_handle h,
|
||||||
|
|
@ -671,7 +672,7 @@ compare_dbs(clicon_handle h,
|
||||||
int astext;
|
int astext;
|
||||||
|
|
||||||
if (cvec_len(argv) > 1){
|
if (cvec_len(argv) > 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires 0 or 1 element. If given: astext flag 0|1", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires 0 or 1 element. If given: astext flag 0|1");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (cvec_len(argv))
|
if (cvec_len(argv))
|
||||||
|
|
@ -762,7 +763,7 @@ load_config_file(clicon_handle h,
|
||||||
}
|
}
|
||||||
/* Open and parse local file into xml */
|
/* Open and parse local file into xml */
|
||||||
if ((fd = open(filename, O_RDONLY)) < 0){
|
if ((fd = open(filename, O_RDONLY)) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: open(%s)", __FUNCTION__, filename);
|
clicon_err(OE_UNIX, errno, "open(%s)", filename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (xml_parse_file(fd, "</clicon>", NULL, &xt) < 0)
|
if (xml_parse_file(fd, "</clicon>", NULL, &xt) < 0)
|
||||||
|
|
@ -824,9 +825,11 @@ save_config_file(clicon_handle h,
|
||||||
|
|
||||||
if (cvec_len(argv) != 2){
|
if (cvec_len(argv) != 2){
|
||||||
if (cvec_len(argv)==1)
|
if (cvec_len(argv)==1)
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Got single argument:\"%s\". Expected \"<dbname>,<varname>\"", cv_string_get(cvec_i(argv,0)));
|
clicon_err(OE_PLUGIN, 0, "Got single argument:\"%s\". Expected \"<dbname>,<varname>\"",
|
||||||
|
cv_string_get(cvec_i(argv,0)));
|
||||||
else
|
else
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Got %d arguments. Expected: <dbname>,<varname>", cvec_len(argv));
|
clicon_err(OE_PLUGIN, 0, " Got %d arguments. Expected: <dbname>,<varname>",
|
||||||
|
cvec_len(argv));
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -886,7 +889,7 @@ delete_all(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires one element: dbname", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires one element: dbname");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
dbstr = cv_string_get(cvec_i(argv, 0));
|
dbstr = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -949,7 +952,7 @@ cli_notification_cb(int s,
|
||||||
if (clicon_msg_rcv(s, &reply, &eof) < 0)
|
if (clicon_msg_rcv(s, &reply, &eof) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (eof){
|
if (eof){
|
||||||
clicon_err(OE_PROTO, ESHUTDOWN, "%s: Socket unexpected close", __FUNCTION__);
|
clicon_err(OE_PROTO, ESHUTDOWN, "Socket unexpected close");
|
||||||
close(s);
|
close(s);
|
||||||
errno = ESHUTDOWN;
|
errno = ESHUTDOWN;
|
||||||
event_unreg_fd(s, cli_notification_cb);
|
event_unreg_fd(s, cli_notification_cb);
|
||||||
|
|
@ -1012,7 +1015,7 @@ cli_notify(clicon_handle h,
|
||||||
enum format_enum format = FORMAT_TEXT;
|
enum format_enum format = FORMAT_TEXT;
|
||||||
|
|
||||||
if (cvec_len(argv) != 2 && cvec_len(argv) != 3){
|
if (cvec_len(argv) != 2 && cvec_len(argv) != 3){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s Requires arguments: <logstream> <status> [<format>]", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires arguments: <logstream> <status> [<format>]");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
stream = cv_string_get(cvec_i(argv, 0));
|
stream = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -1215,7 +1218,7 @@ cli_copy_config(clicon_handle h,
|
||||||
cxobj *xerr;
|
cxobj *xerr;
|
||||||
|
|
||||||
if (cvec_len(argv) != 5){
|
if (cvec_len(argv) != 5){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires four elements: <db> <xpath> <keyname> <from> <to>", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires four elements: <db> <xpath> <keyname> <from> <to>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* First argv argument: Database */
|
/* First argv argument: Database */
|
||||||
|
|
@ -1247,7 +1250,7 @@ cli_copy_config(clicon_handle h,
|
||||||
if (xpath[i] == '%')
|
if (xpath[i] == '%')
|
||||||
j++;
|
j++;
|
||||||
if (j != 2){
|
if (j != 2){
|
||||||
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have two '%%'");
|
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have two '%%'", xpath);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cb, xpath, keyname, fromname);
|
cprintf(cb, xpath, keyname, fromname);
|
||||||
|
|
@ -1273,7 +1276,7 @@ cli_copy_config(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
xml_name_set(x2, "config");
|
xml_name_set(x2, "config");
|
||||||
cprintf(cb, "/%s", keyname);
|
cprintf(cb, "/%s", keyname);
|
||||||
if ((x = xpath_first(x2, cbuf_get(cb))) == NULL){
|
if ((x = xpath_first(x2, "%s", cbuf_get(cb))) == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
|
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -783,7 +783,7 @@ yang2cli(clicon_handle h,
|
||||||
cvec *globals; /* global variables from syntax */
|
cvec *globals; /* global variables from syntax */
|
||||||
|
|
||||||
if ((cbuf = cbuf_new()) == NULL){
|
if ((cbuf = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: cbuf_new", __FUNCTION__);
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Traverse YANG specification: loop through statements */
|
/* Traverse YANG specification: loop through statements */
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ dump_configfile_xml_fn(FILE *fout,
|
||||||
clicon_err(OE_UNIX, errno, "configure file: %s", filename);
|
clicon_err(OE_UNIX, errno, "configure file: %s", filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
clicon_debug(2, "Reading config file %s", __FUNCTION__, filename);
|
clicon_debug(2, "%s: Reading config file %s", __FUNCTION__, filename);
|
||||||
fprintf(fout, "<config>\n");
|
fprintf(fout, "<config>\n");
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
if ((cp = strchr(line, '\n')) != NULL) /* strip last \n */
|
if ((cp = strchr(line, '\n')) != NULL) /* strip last \n */
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ cli_load_syntax(clicon_handle h,
|
||||||
if ((cp = clixon_plugin_find(h, plgnam)) != NULL)
|
if ((cp = clixon_plugin_find(h, plgnam)) != NULL)
|
||||||
handle = cp->cp_handle;
|
handle = cp->cp_handle;
|
||||||
if (handle == NULL){
|
if (handle == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "CLICON_PLUGIN set to '%s' in %s but plugin %s.so not found in %s\n",
|
clicon_err(OE_PLUGIN, 0, "CLICON_PLUGIN set to '%s' in %s but plugin %s.so not found in %s",
|
||||||
plgnam, filename, plgnam,
|
plgnam, filename, plgnam,
|
||||||
clicon_cli_dir(h));
|
clicon_cli_dir(h));
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,7 @@ expand_dbvar(void *h,
|
||||||
char *reason = NULL;
|
char *reason = NULL;
|
||||||
|
|
||||||
if (argv == NULL || cvec_len(argv) != 2){
|
if (argv == NULL || cvec_len(argv) != 2){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: requires arguments: <db> <xmlkeyfmt>",
|
clicon_err(OE_PLUGIN, 0, "requires arguments: <db> <xmlkeyfmt>");
|
||||||
__FUNCTION__);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
|
@ -132,7 +131,7 @@ expand_dbvar(void *h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((cv = cvec_i(argv, 0)) == NULL){
|
if ((cv = cvec_i(argv, 0)) == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Error when accessing argument <db>");
|
clicon_err(OE_PLUGIN, 0, "Error when accessing argument <db>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
dbstr = cv_string_get(cv);
|
dbstr = cv_string_get(cv);
|
||||||
|
|
@ -143,7 +142,7 @@ expand_dbvar(void *h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((cv = cvec_i(argv, 1)) == NULL){
|
if ((cv = cvec_i(argv, 1)) == NULL){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Error when accessing argument <api_path>");
|
clicon_err(OE_PLUGIN, 0, "Error when accessing argument <api_path>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
api_path_fmt = cv_string_get(cv);
|
api_path_fmt = cv_string_get(cv);
|
||||||
|
|
@ -197,7 +196,7 @@ expand_dbvar(void *h,
|
||||||
cli_output(stderr, "%s\n", reason);
|
cli_output(stderr, "%s\n", reason);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xcur = xpath_first(xt, xpath)) == NULL){
|
if ((xcur = xpath_first(xt, "%s", xpath)) == NULL){
|
||||||
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
|
clicon_err(OE_DB, 0, "xpath %s should return merged content", xpath);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +204,7 @@ expand_dbvar(void *h,
|
||||||
/* One round to detect duplicates
|
/* One round to detect duplicates
|
||||||
*/
|
*/
|
||||||
j = 0;
|
j = 0;
|
||||||
if (xpath_vec(xcur, xpathcur, &xvec, &xlen) < 0)
|
if (xpath_vec(xcur, "%s", &xvec, &xlen, xpathcur) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i = 0; i < xlen; i++) {
|
for (i = 0; i < xlen; i++) {
|
||||||
char *str;
|
char *str;
|
||||||
|
|
@ -474,7 +473,8 @@ cli_show_config(clicon_handle h,
|
||||||
if (xpath[i] == '%')
|
if (xpath[i] == '%')
|
||||||
j++;
|
j++;
|
||||||
if (j != 1){
|
if (j != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have a single '%%'");
|
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have a single '%%'",
|
||||||
|
xpath);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((cvattr = cvec_find(cvv, attr)) == NULL){
|
if ((cvattr = cvec_find(cvv, attr)) == NULL){
|
||||||
|
|
@ -561,7 +561,7 @@ show_conf_xpath(clicon_handle h,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Requires one element to be <dbname>", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Requires one element to be <dbname>");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
str = cv_string_get(cvec_i(argv, 0));
|
str = cv_string_get(cvec_i(argv, 0));
|
||||||
|
|
@ -580,7 +580,7 @@ show_conf_xpath(clicon_handle h,
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (xpath_vec(xt, xpath, &xv, &xlen) < 0)
|
if (xpath_vec(xt, "%s", &xv, &xlen, xpath) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<xlen; i++)
|
for (i=0; i<xlen; i++)
|
||||||
xml_print(stdout, xv[i]);
|
xml_print(stdout, xv[i]);
|
||||||
|
|
@ -625,7 +625,7 @@ cli_show_auto(clicon_handle h,
|
||||||
enum genmodel_type gt;
|
enum genmodel_type gt;
|
||||||
|
|
||||||
if (cvec_len(argv) != 3){
|
if (cvec_len(argv) != 3){
|
||||||
clicon_err(OE_PLUGIN, 0, "%s: Usage: <api-path-fmt>* <database> <format>. (*) generated.", __FUNCTION__);
|
clicon_err(OE_PLUGIN, 0, "Usage: <api-path-fmt>* <database> <format>. (*) generated.");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* First argv argument: API_path format */
|
/* First argv argument: API_path format */
|
||||||
|
|
@ -654,7 +654,7 @@ cli_show_auto(clicon_handle h,
|
||||||
clicon_rpc_generate_error("Get configuration", xerr);
|
clicon_rpc_generate_error("Get configuration", xerr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((xp = xpath_first(xt, xpath)) != NULL)
|
if ((xp = xpath_first(xt, "%s", xpath)) != NULL)
|
||||||
/* Print configuration according to format */
|
/* Print configuration according to format */
|
||||||
switch (format){
|
switch (format){
|
||||||
case FORMAT_XML:
|
case FORMAT_XML:
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ netconf_get_target(cxobj *xn,
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
char *target = NULL;
|
char *target = NULL;
|
||||||
|
|
||||||
if ((x = xpath_first(xn, path)) != NULL){
|
if ((x = xpath_first(xn, "%s", path)) != NULL){
|
||||||
if (xpath_first(x, "candidate") != NULL)
|
if (xpath_first(x, "candidate") != NULL)
|
||||||
target = "candidate";
|
target = "candidate";
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ netconf_input_cb(int s,
|
||||||
int poll;
|
int poll;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: cbuf_new", __FUNCTION__);
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
|
||||||
|
|
@ -752,7 +752,7 @@ netconf_notification_cb(int s,
|
||||||
goto done;
|
goto done;
|
||||||
/* handle close from remote end: this will exit the client */
|
/* handle close from remote end: this will exit the client */
|
||||||
if (eof){
|
if (eof){
|
||||||
clicon_err(OE_PROTO, ESHUTDOWN, "%s: Socket unexpected close", __FUNCTION__);
|
clicon_err(OE_PROTO, ESHUTDOWN, "Socket unexpected close");
|
||||||
close(s);
|
close(s);
|
||||||
errno = ESHUTDOWN;
|
errno = ESHUTDOWN;
|
||||||
event_unreg_fd(s, netconf_notification_cb);
|
event_unreg_fd(s, netconf_notification_cb);
|
||||||
|
|
@ -770,13 +770,13 @@ netconf_notification_cb(int s,
|
||||||
/* find and apply filter */
|
/* find and apply filter */
|
||||||
if ((selector = xml_find_value(xfilter, "select")) == NULL)
|
if ((selector = xml_find_value(xfilter, "select")) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_first(xe, selector) == NULL) {
|
if (xpath_first(xe, "%s", selector) == NULL) {
|
||||||
fprintf(stderr, "%s no match\n", __FUNCTION__); /* debug */
|
fprintf(stderr, "%s no match\n", __FUNCTION__); /* debug */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* create netconf message */
|
/* create netconf message */
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_PLUGIN, errno, "%s: cbuf_new", __FUNCTION__);
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
add_preamble(cb); /* Make it well-formed netconf xml */
|
add_preamble(cb); /* Make it well-formed netconf xml */
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ api_data_get2(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (xpath_vec(xret, path, &xvec, &xlen) < 0)
|
if (xpath_vec(xret, "%s", &xvec, &xlen, path) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
clicon_debug(1, "%s: xpath:%s xlen:%d", __FUNCTION__, path, xlen);
|
clicon_debug(1, "%s: xpath:%s xlen:%d", __FUNCTION__, path, xlen);
|
||||||
if (use_xml){
|
if (use_xml){
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,8 @@ text_setopt(xmldb_handle xh,
|
||||||
else if (strcmp(value,"json")==0)
|
else if (strcmp(value,"json")==0)
|
||||||
th->th_format = "json";
|
th->th_format = "json";
|
||||||
else{
|
else{
|
||||||
clicon_err(OE_PLUGIN, 0, "Option %s unrecognized format: %s", optname, value);
|
clicon_err(OE_PLUGIN, 0, "Option %s unrecognized format: %s",
|
||||||
|
optname, (char*)value);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -473,7 +474,7 @@ text_get(xmldb_handle xh,
|
||||||
} /* xt == NULL */
|
} /* xt == NULL */
|
||||||
/* Here xt looks like: <config>...</config> */
|
/* Here xt looks like: <config>...</config> */
|
||||||
|
|
||||||
if (xpath_vec(xt, xpath?xpath:"/", &xvec, &xlen) < 0)
|
if (xpath_vec(xt, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* If vectors are specified then mark the nodes found with all ancestors
|
/* If vectors are specified then mark the nodes found with all ancestors
|
||||||
|
|
@ -806,7 +807,8 @@ text_modify_top(cxobj *x0,
|
||||||
x1cname = xml_name(x1c);
|
x1cname = xml_name(x1c);
|
||||||
/* Get yang spec of the child */
|
/* Get yang spec of the child */
|
||||||
if ((yc = yang_find_topnode(yspec, x1cname, YC_DATANODE)) == NULL){
|
if ((yc = yang_find_topnode(yspec, x1cname, YC_DATANODE)) == NULL){
|
||||||
clicon_err(OE_YANG, ENOENT, "XML node %s/%s has no corresponding yang specification (Invalid XML or wrong Yang spec?", x1, x1cname);
|
clicon_err(OE_YANG, ENOENT, "XML node %s/%s has no corresponding yang specification (Invalid XML or wrong Yang spec?",
|
||||||
|
xml_name(x1), x1cname);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* See if there is a corresponding node in the base tree */
|
/* See if there is a corresponding node in the base tree */
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,11 @@ extern char clicon_err_reason[ERR_STRLEN];
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int clicon_err_reset(void);
|
int clicon_err_reset(void);
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
int clicon_err_fn(const char *fn, const int line, int level, int err, char *format, ...) __attribute__ ((format (printf, 5, 6)));
|
||||||
|
#else
|
||||||
int clicon_err_fn(const char *fn, const int line, int level, int err, char *format, ...);
|
int clicon_err_fn(const char *fn, const int line, int level, int err, char *format, ...);
|
||||||
|
#endif
|
||||||
char *clicon_strerror(int err);
|
char *clicon_strerror(int err);
|
||||||
void *clicon_err_save(void);
|
void *clicon_err_save(void);
|
||||||
int clicon_err_restore(void *handle);
|
int clicon_err_restore(void *handle);
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,16 @@ extern int debug;
|
||||||
int clicon_log_init(char *ident, int upto, int flags);
|
int clicon_log_init(char *ident, int upto, int flags);
|
||||||
int clicon_get_logflags(void);
|
int clicon_get_logflags(void);
|
||||||
int clicon_log_str(int level, char *msg);
|
int clicon_log_str(int level, char *msg);
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
int clicon_log(int level, char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
|
int clicon_debug(int dbglevel, char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
|
#else
|
||||||
int clicon_log(int level, char *format, ...);
|
int clicon_log(int level, char *format, ...);
|
||||||
|
int clicon_debug(int dbglevel, char *format, ...);
|
||||||
|
#endif
|
||||||
clicon_log_notify_t *clicon_log_register_callback(clicon_log_notify_t *cb, void *arg);
|
clicon_log_notify_t *clicon_log_register_callback(clicon_log_notify_t *cb, void *arg);
|
||||||
int clicon_debug_init(int dbglevel, FILE *f);
|
int clicon_debug_init(int dbglevel, FILE *f);
|
||||||
int clicon_debug(int dbglevel, char *format, ...);
|
|
||||||
char *mon2name(int md);
|
char *mon2name(int md);
|
||||||
|
|
||||||
#endif /* _CLIXON_LOG_H_ */
|
#endif /* _CLIXON_LOG_H_ */
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,11 @@ struct clicon_msg {
|
||||||
char *format_int2str(enum format_enum showas);
|
char *format_int2str(enum format_enum showas);
|
||||||
enum format_enum format_str2int(char *str);
|
enum format_enum format_str2int(char *str);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
struct clicon_msg *clicon_msg_encode(char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
|
#else
|
||||||
struct clicon_msg *clicon_msg_encode(char *format, ...);
|
struct clicon_msg *clicon_msg_encode(char *format, ...);
|
||||||
|
#endif
|
||||||
int clicon_msg_decode(struct clicon_msg *msg, cxobj **xml);
|
int clicon_msg_decode(struct clicon_msg *msg, cxobj **xml);
|
||||||
|
|
||||||
int clicon_connect_unix(char *sockpath);
|
int clicon_connect_unix(char *sockpath);
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,17 @@
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
cxobj *xpath_first(cxobj *cxtop, char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
|
int xpath_vec(cxobj *cxtop, char *format, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 2, 5)));
|
||||||
|
int xpath_vec_flag(cxobj *cxtop, char *format, uint16_t flags,
|
||||||
|
cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 2, 6)));
|
||||||
|
#else
|
||||||
cxobj *xpath_first(cxobj *cxtop, char *format, ...);
|
cxobj *xpath_first(cxobj *cxtop, char *format, ...);
|
||||||
cxobj *xpath_each(cxobj *xn_top, char *xpath, cxobj *prev);
|
|
||||||
int xpath_vec(cxobj *cxtop, char *format, cxobj ***vec, size_t *veclen, ...);
|
int xpath_vec(cxobj *cxtop, char *format, cxobj ***vec, size_t *veclen, ...);
|
||||||
int xpath_vec_flag(cxobj *cxtop, char *xpath, uint16_t flags,
|
int xpath_vec_flag(cxobj *cxtop, char *xpath, uint16_t flags,
|
||||||
cxobj ***vec, size_t *veclen, ...);
|
cxobj ***vec, size_t *veclen, ...);
|
||||||
|
#endif
|
||||||
|
cxobj *xpath_each(cxobj *xn_top, char *xpath, cxobj *prev);
|
||||||
|
|
||||||
#endif /* _CLIXON_XSL_H */
|
#endif /* _CLIXON_XSL_H */
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,7 @@ char *yang_find_myprefix(yang_stmt *ys);
|
||||||
int yang_order(yang_stmt *y);
|
int yang_order(yang_stmt *y);
|
||||||
int yang_print(FILE *f, yang_node *yn);
|
int yang_print(FILE *f, yang_node *yn);
|
||||||
int yang_print_cbuf(cbuf *cb, yang_node *yn, int marginal);
|
int yang_print_cbuf(cbuf *cb, yang_node *yn, int marginal);
|
||||||
|
yang_stmt *yang_parse_file(int fd, const char *name, yang_spec *ysp);
|
||||||
int yang_parse(clicon_handle h, const char *yang_dir,
|
int yang_parse(clicon_handle h, const char *yang_dir,
|
||||||
const char *module, const char *revision, yang_spec *ysp);
|
const char *module, const char *revision, yang_spec *ysp);
|
||||||
int yang_apply(yang_node *yn, enum rfc_6020 key, yang_applyfn_t fn,
|
int yang_apply(yang_node *yn, enum rfc_6020 key, yang_applyfn_t fn,
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ sysconfdir = @sysconfdir@
|
||||||
HOST_VENDOR = @host_vendor@
|
HOST_VENDOR = @host_vendor@
|
||||||
|
|
||||||
SH_SUFFIX = @SH_SUFFIX@
|
SH_SUFFIX = @SH_SUFFIX@
|
||||||
|
|
||||||
CLIXON_VERSION = @CLIXON_VERSION@
|
CLIXON_VERSION = @CLIXON_VERSION@
|
||||||
CLIXON_MAJOR = @CLIXON_VERSION_MAJOR@
|
CLIXON_MAJOR = @CLIXON_VERSION_MAJOR@
|
||||||
CLIXON_MINOR = @CLIXON_VERSION_MINOR@
|
CLIXON_MINOR = @CLIXON_VERSION_MINOR@
|
||||||
|
|
@ -78,6 +79,14 @@ YACCOBJS := lex.clixon_xml_parse.o clixon_xml_parse.tab.o \
|
||||||
lex.clixon_json_parse.o clixon_json_parse.tab.o
|
lex.clixon_json_parse.o clixon_json_parse.tab.o
|
||||||
|
|
||||||
|
|
||||||
|
# Extra applications. Utilities, unit testings. Not installed.
|
||||||
|
APPSRC = clixon_util_xml.c
|
||||||
|
APPSRC += clixon_util_json.c
|
||||||
|
APPSRC += clixon_util_yang.c
|
||||||
|
APPSRC += clixon_util_xsl.c
|
||||||
|
|
||||||
|
APPS = $(APPSRC:.c=)
|
||||||
|
|
||||||
# Generated src
|
# Generated src
|
||||||
GENSRC = build.c
|
GENSRC = build.c
|
||||||
|
|
||||||
|
|
@ -91,10 +100,10 @@ MYLIB = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR).$(CLIXON_MINOR)
|
||||||
MYLIBSO = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR)
|
MYLIBSO = libclixon$(SH_SUFFIX).$(CLIXON_MAJOR)
|
||||||
MYLIBLINK = libclixon$(SH_SUFFIX)
|
MYLIBLINK = libclixon$(SH_SUFFIX)
|
||||||
|
|
||||||
all: $(MYLIB) $(MYLIBLINK)
|
all: $(MYLIB) $(MYLIBLINK) $(APPS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJS) $(MYLIB) $(MYLIBLINK) $(GENOBJS) $(GENSRC) *.core
|
rm -f $(OBJS) $(MYLIB) $(APPS) $(MYLIBLINK) $(GENOBJS) $(GENSRC) *.core
|
||||||
rm -f clixon_xml_parse.tab.[ch] clixon_xml_parse.yy.[co]
|
rm -f clixon_xml_parse.tab.[ch] clixon_xml_parse.yy.[co]
|
||||||
rm -f clixon_yang_parse.tab.[ch] clixon_yang_parse.[co]
|
rm -f clixon_yang_parse.tab.[ch] clixon_yang_parse.[co]
|
||||||
rm -f clixon_json_parse.tab.[ch] clixon_json_parse.[co]
|
rm -f clixon_json_parse.tab.[ch] clixon_json_parse.[co]
|
||||||
|
|
@ -150,6 +159,19 @@ clixon_json_parse.tab.c clixon_json_parse.tab.h: clixon_json_parse.y
|
||||||
lex.clixon_json_parse.o : lex.clixon_json_parse.c clixon_json_parse.tab.h
|
lex.clixon_json_parse.o : lex.clixon_json_parse.c clixon_json_parse.tab.h
|
||||||
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $<
|
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -Wno-error -c $<
|
||||||
|
|
||||||
|
# APPS
|
||||||
|
clixon_util_xml: clixon_util_xml.c $(MYLIB)
|
||||||
|
$(CC) $(INCLUDES) $(CPPFLAGS) @CFLAGS@ $^ $(LIBS) -o $@
|
||||||
|
|
||||||
|
clixon_util_json: clixon_util_json.c $(MYLIB)
|
||||||
|
$(CC) $(INCLUDES) $(CPPFLAGS) @CFLAGS@ $^ $(LIBS) -o $@
|
||||||
|
|
||||||
|
clixon_util_yang: clixon_util_yang.c $(MYLIB)
|
||||||
|
$(CC) $(INCLUDES) $(CPPFLAGS) @CFLAGS@ $^ $(LIBS) -o $@
|
||||||
|
|
||||||
|
clixon_util_xsl: clixon_util_xsl.c $(MYLIB)
|
||||||
|
$(CC) $(INCLUDES) $(CPPFLAGS) @CFLAGS@ $^ $(LIBS) -o $@
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f Makefile *~ .depend
|
rm -f Makefile *~ .depend
|
||||||
|
|
||||||
|
|
@ -164,7 +186,6 @@ build.c:
|
||||||
date +"const char CLIXON_BUILDSTR[64]=\"%Y.%m.%d %H:%M by `whoami` on `hostname`"\"\; > build.c;
|
date +"const char CLIXON_BUILDSTR[64]=\"%Y.%m.%d %H:%M by `whoami` on `hostname`"\"\; > build.c;
|
||||||
echo "const char CLIXON_VERSION[64]=\"$(CLIXON_VERSION)\""\; >> build.c;
|
echo "const char CLIXON_VERSION[64]=\"$(CLIXON_VERSION)\""\; >> build.c;
|
||||||
|
|
||||||
|
|
||||||
$(MYLIB) : $(GENOBJS) $(OBJS)
|
$(MYLIB) : $(GENOBJS) $(OBJS)
|
||||||
ifeq ($(HOST_VENDOR),apple)
|
ifeq ($(HOST_VENDOR),apple)
|
||||||
$(CC) $(LDFLAGS) -shared -o $@ $(GENOBJS) $(OBJS) $(LIBS) -undefined dynamic_lookup -o $@
|
$(CC) $(LDFLAGS) -shared -o $@ $(GENOBJS) $(OBJS) $(LIBS) -undefined dynamic_lookup -o $@
|
||||||
|
|
|
||||||
|
|
@ -135,11 +135,11 @@ clicon_err_reset(void)
|
||||||
* - Set global reason string clicon_err_reason
|
* - Set global reason string clicon_err_reason
|
||||||
* @note: err direction (syslog and/or stderr) controlled by clicon_log_init()
|
* @note: err direction (syslog and/or stderr) controlled by clicon_log_init()
|
||||||
*
|
*
|
||||||
* @param fn Inline function name (when called from clicon_err() macro)
|
* @param[in] fn Inline function name (when called from clicon_err() macro)
|
||||||
* @param line Inline file line number (when called from clicon_err() macro)
|
* @param[in] line Inline file line number (when called from clicon_err() macro)
|
||||||
* @param err Error number, typically errno
|
* @param[in] err Error number, typically errno
|
||||||
* @param suberr Sub-error number
|
* @param[in] suberr Sub-error number
|
||||||
* @param reason Error string, format with argv
|
* @param[in] reason Error string, format with argv
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_err_fn(const char *fn,
|
clicon_err_fn(const char *fn,
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,7 @@ event_poll(int fd)
|
||||||
FD_ZERO(&fdset);
|
FD_ZERO(&fdset);
|
||||||
FD_SET(fd, &fdset);
|
FD_SET(fd, &fdset);
|
||||||
if ((retval = select(FD_SETSIZE, &fdset, NULL, NULL, &tnull)) < 0)
|
if ((retval = select(FD_SETSIZE, &fdset, NULL, NULL, &tnull)) < 0)
|
||||||
clicon_err(OE_EVENTS, errno, "%s select1: %s", __FUNCTION__, strerror(errno));
|
clicon_err(OE_EVENTS, errno, "select");
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,18 +307,18 @@ event_loop(void)
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
if (errno == EINTR){
|
if (errno == EINTR){
|
||||||
clicon_debug(1, "%s select: %s", __FUNCTION__, strerror(errno));
|
clicon_debug(1, "%s select: %s", __FUNCTION__, strerror(errno));
|
||||||
clicon_err(OE_EVENTS, errno, "%s select1: %s", __FUNCTION__, strerror(errno));
|
clicon_err(OE_EVENTS, errno, "select");
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
clicon_err(OE_EVENTS, errno, "%s select2", __FUNCTION__);
|
clicon_err(OE_EVENTS, errno, "select");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (n==0){ /* Timeout */
|
if (n==0){ /* Timeout */
|
||||||
e = ee_timers;
|
e = ee_timers;
|
||||||
ee_timers = ee_timers->e_next;
|
ee_timers = ee_timers->e_next;
|
||||||
clicon_debug(2, "%s timeout: %s[%x]",
|
clicon_debug(2, "%s timeout: %s[%x]",
|
||||||
__FUNCTION__, e->e_string, e->e_arg);
|
__FUNCTION__, e->e_string, (int)e->e_arg);
|
||||||
if ((*e->e_fn)(0, e->e_arg) < 0){
|
if ((*e->e_fn)(0, e->e_arg) < 0){
|
||||||
free(e);
|
free(e);
|
||||||
goto err;
|
goto err;
|
||||||
|
|
@ -332,7 +332,7 @@ event_loop(void)
|
||||||
e_next = e->e_next;
|
e_next = e->e_next;
|
||||||
if(e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset)){
|
if(e->e_type == EVENT_FD && FD_ISSET(e->e_fd, &fdset)){
|
||||||
clicon_debug(2, "%s: FD_ISSET: %s[%x]",
|
clicon_debug(2, "%s: FD_ISSET: %s[%x]",
|
||||||
__FUNCTION__, e->e_string, e->e_arg);
|
__FUNCTION__, e->e_string, (int)e->e_arg);
|
||||||
if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){
|
if ((*e->e_fn)(e->e_fd, e->e_arg) < 0){
|
||||||
clicon_debug(1, "%s Error in: %s", __FUNCTION__, e->e_string);
|
clicon_debug(1, "%s Error in: %s", __FUNCTION__, e->e_string);
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
||||||
|
|
@ -241,12 +241,11 @@ group_name2gid(char *name,
|
||||||
gr = &g0;
|
gr = &g0;
|
||||||
/* This leaks memory in ubuntu */
|
/* This leaks memory in ubuntu */
|
||||||
if (getgrnam_r(name, gr, buf, sizeof(buf), >mp) < 0){
|
if (getgrnam_r(name, gr, buf, sizeof(buf), >mp) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "%s: getgrnam_r(%s): %s",
|
clicon_err(OE_UNIX, errno, "getgrnam_r(%s)", name);
|
||||||
__FUNCTION__, name, strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (gtmp == NULL){
|
if (gtmp == NULL){
|
||||||
clicon_err(OE_UNIX, 0, "%s: No such group: %s", __FUNCTION__, name);
|
clicon_err(OE_UNIX, 0, "No such group: %s", name);
|
||||||
fprintf(stderr, "No such group %s\n", name);
|
fprintf(stderr, "No such group %s\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -730,16 +730,14 @@ json_parse_file(int fd,
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if ((jsonbuf = malloc(jsonbuflen)) == NULL){
|
if ((jsonbuf = malloc(jsonbuflen)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: malloc", __FUNCTION__);
|
clicon_err(OE_XML, errno, "malloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memset(jsonbuf, 0, jsonbuflen);
|
memset(jsonbuf, 0, jsonbuflen);
|
||||||
ptr = jsonbuf;
|
ptr = jsonbuf;
|
||||||
while (1){
|
while (1){
|
||||||
if ((ret = read(fd, &ch, 1)) < 0){
|
if ((ret = read(fd, &ch, 1)) < 0){
|
||||||
clicon_err(OE_XML, errno, "%s: read: [pid:%d]\n",
|
clicon_err(OE_XML, errno, "read");
|
||||||
__FUNCTION__,
|
|
||||||
(int)getpid());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
|
@ -756,7 +754,7 @@ json_parse_file(int fd,
|
||||||
oldjsonbuflen = jsonbuflen;
|
oldjsonbuflen = jsonbuflen;
|
||||||
jsonbuflen *= 2;
|
jsonbuflen *= 2;
|
||||||
if ((jsonbuf = realloc(jsonbuf, jsonbuflen)) == NULL){
|
if ((jsonbuf = realloc(jsonbuf, jsonbuflen)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: realloc", __FUNCTION__);
|
clicon_err(OE_XML, errno, "realloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memset(jsonbuf+oldjsonbuflen, 0, jsonbuflen-oldjsonbuflen);
|
memset(jsonbuf+oldjsonbuflen, 0, jsonbuflen-oldjsonbuflen);
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ clicon_option_readfile_xml(clicon_hash_t *copt,
|
||||||
clicon_err(OE_UNIX, errno, "configure file: %s", filename);
|
clicon_err(OE_UNIX, errno, "configure file: %s", filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
clicon_debug(2, "Reading config file %s", __FUNCTION__, filename);
|
clicon_debug(2, "%s: Reading config file %s", __FUNCTION__, filename);
|
||||||
fd = fileno(f);
|
fd = fileno(f);
|
||||||
if (xml_parse_file(fd, "</clicon>", yspec, &xt) < 0)
|
if (xml_parse_file(fd, "</clicon>", yspec, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -290,8 +290,8 @@ clicon_option_str_set(clicon_handle h,
|
||||||
|
|
||||||
/*! Get options as integer but stored as string
|
/*! Get options as integer but stored as string
|
||||||
*
|
*
|
||||||
* @param h clicon handle
|
* @param[in] h clicon handle
|
||||||
* @param name name of option
|
* @param[in] name name of option
|
||||||
* @retval int An integer as aresult of atoi
|
* @retval int An integer as aresult of atoi
|
||||||
* @retval -1 If option does not exist
|
* @retval -1 If option does not exist
|
||||||
* @code
|
* @code
|
||||||
|
|
@ -331,8 +331,8 @@ clicon_option_int_set(clicon_handle h,
|
||||||
|
|
||||||
/*! Get options as bool but stored as string
|
/*! Get options as bool but stored as string
|
||||||
*
|
*
|
||||||
* @param h clicon handle
|
* @param[in] h clicon handle
|
||||||
* @param name name of option
|
* @param[in] name name of option
|
||||||
* @retval 0 false, or does not exist, or does not have a boolean value
|
* @retval 0 false, or does not exist, or does not have a boolean value
|
||||||
* @retval 1 true
|
* @retval 1 true
|
||||||
* @code
|
* @code
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ plugin_load_one(clicon_handle h,
|
||||||
dlerror(); /* Clear any existing error */
|
dlerror(); /* Clear any existing error */
|
||||||
if ((handle = dlopen(file, dlflags)) == NULL) {
|
if ((handle = dlopen(file, dlflags)) == NULL) {
|
||||||
error = (char*)dlerror();
|
error = (char*)dlerror();
|
||||||
clicon_err(OE_PLUGIN, errno, "dlopen: %s\n", error ? error : "Unknown error");
|
clicon_err(OE_PLUGIN, errno, "dlopen: %s", error ? error : "Unknown error");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* call plugin_init() if defined, eg CLIXON_PLUGIN_INIT or CLIXON_BACKEND_INIT */
|
/* call plugin_init() if defined, eg CLIXON_PLUGIN_INIT or CLIXON_BACKEND_INIT */
|
||||||
|
|
@ -342,7 +342,7 @@ clixon_plugin_exit(clicon_handle h)
|
||||||
}
|
}
|
||||||
if (dlclose(cp->cp_handle) != 0) {
|
if (dlclose(cp->cp_handle) != 0) {
|
||||||
error = (char*)dlerror();
|
error = (char*)dlerror();
|
||||||
clicon_err(OE_PLUGIN, errno, "dlclose: %s\n", error ? error : "Unknown error");
|
clicon_err(OE_PLUGIN, errno, "dlclose: %s", error ? error : "Unknown error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_clixon_plugins){
|
if (_clixon_plugins){
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ clicon_connect_unix(char *sockpath)
|
||||||
clicon_debug(2, "%s: connecting to %s", __FUNCTION__, addr.sun_path);
|
clicon_debug(2, "%s: connecting to %s", __FUNCTION__, addr.sun_path);
|
||||||
if (connect(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){
|
if (connect(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){
|
||||||
if (errno == EACCES)
|
if (errno == EACCES)
|
||||||
clicon_err(OE_CFG, errno, "connecting unix socket: %s.\n"
|
clicon_err(OE_CFG, errno, "connecting unix socket: %s."
|
||||||
"Client should be member of group $CLICON_SOCK_GROUP: ",
|
"Client should be member of group $CLICON_SOCK_GROUP: ",
|
||||||
sockpath);
|
sockpath);
|
||||||
else
|
else
|
||||||
|
|
@ -273,7 +273,7 @@ msg_dump(struct clicon_msg *msg)
|
||||||
for (i=0; i<ntohl(msg->op_len); i++){
|
for (i=0; i<ntohl(msg->op_len); i++){
|
||||||
snprintf(buf, sizeof(buf), "%s%02x", buf2, ((char*)msg)[i]&0xff);
|
snprintf(buf, sizeof(buf), "%s%02x", buf2, ((char*)msg)[i]&0xff);
|
||||||
if ((i+1)%32==0){
|
if ((i+1)%32==0){
|
||||||
clicon_debug(2, buf);
|
clicon_debug(2, "%s", buf);
|
||||||
snprintf(buf, sizeof(buf), "%s:", __FUNCTION__);
|
snprintf(buf, sizeof(buf), "%s:", __FUNCTION__);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -282,7 +282,7 @@ msg_dump(struct clicon_msg *msg)
|
||||||
strncpy(buf2, buf, sizeof(buf2));
|
strncpy(buf2, buf, sizeof(buf2));
|
||||||
}
|
}
|
||||||
if (i%32)
|
if (i%32)
|
||||||
clicon_debug(2, buf);
|
clicon_debug(2, "%s", buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,7 +302,7 @@ clicon_msg_send(int s,
|
||||||
msg_dump(msg);
|
msg_dump(msg);
|
||||||
if (atomicio((ssize_t (*)(int, void *, size_t))write,
|
if (atomicio((ssize_t (*)(int, void *, size_t))write,
|
||||||
s, msg, ntohl(msg->op_len)) < 0){
|
s, msg, ntohl(msg->op_len)) < 0){
|
||||||
clicon_err(OE_CFG, errno, "%s", __FUNCTION__);
|
clicon_err(OE_CFG, errno, "atomicio");
|
||||||
clicon_log(LOG_WARNING, "%s: write: %s len:%u msg:%s", __FUNCTION__,
|
clicon_log(LOG_WARNING, "%s: write: %s len:%u msg:%s", __FUNCTION__,
|
||||||
strerror(errno), ntohs(msg->op_len), msg->op_body);
|
strerror(errno), ntohs(msg->op_len), msg->op_body);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -344,7 +344,7 @@ clicon_msg_rcv(int s,
|
||||||
set_signal(SIGINT, atomicio_sig_handler, &oldhandler);
|
set_signal(SIGINT, atomicio_sig_handler, &oldhandler);
|
||||||
|
|
||||||
if ((hlen = atomicio(read, s, &hdr, sizeof(hdr))) < 0){
|
if ((hlen = atomicio(read, s, &hdr, sizeof(hdr))) < 0){
|
||||||
clicon_err(OE_CFG, errno, "%s", __FUNCTION__);
|
clicon_err(OE_CFG, errno, "atomicio");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (hlen == 0){
|
if (hlen == 0){
|
||||||
|
|
@ -353,7 +353,7 @@ clicon_msg_rcv(int s,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (hlen != sizeof(hdr)){
|
if (hlen != sizeof(hdr)){
|
||||||
clicon_err(OE_CFG, errno, "%s: header too short (%d)", __FUNCTION__, hlen);
|
clicon_err(OE_CFG, errno, "header too short (%d)", hlen);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
mlen = ntohl(hdr.op_len);
|
mlen = ntohl(hdr.op_len);
|
||||||
|
|
@ -365,11 +365,11 @@ clicon_msg_rcv(int s,
|
||||||
}
|
}
|
||||||
memcpy(*msg, &hdr, hlen);
|
memcpy(*msg, &hdr, hlen);
|
||||||
if ((len2 = atomicio(read, s, (*msg)->op_body, mlen - sizeof(hdr))) < 0){
|
if ((len2 = atomicio(read, s, (*msg)->op_body, mlen - sizeof(hdr))) < 0){
|
||||||
clicon_err(OE_CFG, errno, "%s: read", __FUNCTION__);
|
clicon_err(OE_CFG, errno, "read");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (len2 != mlen - sizeof(hdr)){
|
if (len2 != mlen - sizeof(hdr)){
|
||||||
clicon_err(OE_CFG, errno, "%s: body too short", __FUNCTION__);
|
clicon_err(OE_CFG, errno, "body too short");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
|
|
@ -504,7 +504,7 @@ clicon_rpc(int s,
|
||||||
if (clicon_msg_rcv(s, &reply, &eof) < 0)
|
if (clicon_msg_rcv(s, &reply, &eof) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (eof){
|
if (eof){
|
||||||
clicon_err(OE_PROTO, ESHUTDOWN, "%s: Socket unexpected close", __FUNCTION__);
|
clicon_err(OE_PROTO, ESHUTDOWN, "Socket unexpected close");
|
||||||
close(s);
|
close(s);
|
||||||
errno = ESHUTDOWN;
|
errno = ESHUTDOWN;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
102
lib/src/clixon_util_json.c
Normal file
102
lib/src/clixon_util_json.c
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
* JSON support functions.
|
||||||
|
* JSON syntax is according to:
|
||||||
|
* http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "clixon_config.h" /* generated by config & autoconf */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* cligen */
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
/* clixon */
|
||||||
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn this on to get a json parse and pretty print test program
|
||||||
|
* Usage: xpath
|
||||||
|
* read json from input
|
||||||
|
* Example compile:
|
||||||
|
gcc -g -o json -I. -I../clixon ./clixon_json.c -lclixon -lcligen
|
||||||
|
* Example run:
|
||||||
|
echo '{"foo": -23}' | ./json
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
usage(char *argv0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:%s.\n\tInput on stdin\n", argv0);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
cxobj *xt = NULL;
|
||||||
|
cxobj *xc;
|
||||||
|
cbuf *cb = cbuf_new();
|
||||||
|
|
||||||
|
if (argc != 1){
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR);
|
||||||
|
if (json_parse_file(0, NULL, &xt) < 0)
|
||||||
|
goto done;
|
||||||
|
xc = NULL;
|
||||||
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
|
||||||
|
clicon_xml2cbuf(cb, xc, 0, 0); /* print xml */
|
||||||
|
fprintf(stdout, "%s", cbuf_get(cb));
|
||||||
|
done:
|
||||||
|
if (xt)
|
||||||
|
xml_free(xt);
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
107
lib/src/clixon_util_xml.c
Normal file
107
lib/src/clixon_util_xml.c
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
* XML support functions.
|
||||||
|
* @see https://www.w3.org/TR/2008/REC-xml-20081126
|
||||||
|
* https://www.w3.org/TR/2009/REC-xml-names-20091208
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "clixon_config.h" /* generated by config & autoconf */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* cligen */
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
/* clixon */
|
||||||
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn this on to get a xml parse and pretty print test program
|
||||||
|
* Usage: xpath
|
||||||
|
* read xml from input
|
||||||
|
* Example compile:
|
||||||
|
gcc -g -o xml -I. -I../clixon ./clixon_xml.c -lclixon -lcligen
|
||||||
|
* Example run:
|
||||||
|
echo "<a><b/></a>" | xml
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
usage(char *argv0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:%s.\n\tInput on stdin\n", argv0);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
cxobj *xt = NULL;
|
||||||
|
cxobj *xc;
|
||||||
|
cbuf *cb = cbuf_new();
|
||||||
|
|
||||||
|
if (argc != 1){
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (xml_parse_file(0, "</config>", NULL, &xt) < 0){
|
||||||
|
fprintf(stderr, "xml parse error %s\n", clicon_err_reason);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
xc = NULL;
|
||||||
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
|
||||||
|
clicon_xml2cbuf(cb, xc, 0, 0); /* print xml */
|
||||||
|
fprintf(stdout, "%s\n", cbuf_get(cb));
|
||||||
|
#if 0
|
||||||
|
cbuf_reset(cb);
|
||||||
|
xmltree2cbuf(cb, xt, 0); /* dump data structures */
|
||||||
|
fprintf(stderr, "%s\n", cbuf_get(cb));
|
||||||
|
#endif
|
||||||
|
done:
|
||||||
|
if (xt)
|
||||||
|
xml_free(xt);
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
141
lib/src/clixon_util_xsl.c
Normal file
141
lib/src/clixon_util_xsl.c
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
See https://www.w3.org/TR/xpath/
|
||||||
|
|
||||||
|
* Turn this on to get an xpath test program
|
||||||
|
* Usage: xpath [<xpath>]
|
||||||
|
* read xpath on first line and xml on rest of lines from input
|
||||||
|
* Example compile:
|
||||||
|
gcc -g -o xpath -I. -I../clixon ./clixon_xsl.c -lclixon -lcligen
|
||||||
|
* Example run:
|
||||||
|
echo "a\n<a><b/></a>" | xpath
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "clixon_config.h" /* generated by config & autoconf */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
/* cligen */
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
/* clixon */
|
||||||
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
usage(char *argv0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:%s <xpath>.\n\tInput on stdin\n", argv0);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int i;
|
||||||
|
cxobj **xv;
|
||||||
|
cxobj *x;
|
||||||
|
cxobj *xn;
|
||||||
|
size_t xlen = 0;
|
||||||
|
int c;
|
||||||
|
int len;
|
||||||
|
char *buf = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc != 1){
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* First read xpath */
|
||||||
|
len = 1024; /* any number is fine */
|
||||||
|
if ((buf = malloc(len)) == NULL){
|
||||||
|
perror("pt_file malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(buf, 0, len);
|
||||||
|
i = 0;
|
||||||
|
while (1){
|
||||||
|
if ((ret = read(0, &c, 1)) < 0){
|
||||||
|
perror("read");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
if (len==i){
|
||||||
|
if ((buf = realloc(buf, 2*len)) == NULL){
|
||||||
|
fprintf(stderr, "%s: realloc: %s\n", __FUNCTION__, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(buf+len, 0, len);
|
||||||
|
len *= 2;
|
||||||
|
}
|
||||||
|
buf[i++] = (char)(c&0xff);
|
||||||
|
}
|
||||||
|
x = NULL;
|
||||||
|
if (xml_parse_file(0, "</clicon>", NULL, &x) < 0){
|
||||||
|
fprintf(stderr, "Error: parsing: %s\n", clicon_err_reason);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (xpath_vec(x, "%s", &xv, &xlen, buf) < 0)
|
||||||
|
return -1;
|
||||||
|
if (xv){
|
||||||
|
for (i=0; i<xlen; i++){
|
||||||
|
xn = xv[i];
|
||||||
|
fprintf(stdout, "%d:", i);
|
||||||
|
clicon_xml2file(stdout, xn, 0, 0);
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
free(xv);
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (x)
|
||||||
|
xml_free(x);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
93
lib/src/clixon_util_yang.c
Normal file
93
lib/src/clixon_util_yang.c
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "clixon_config.h" /* generated by config & autoconf */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#define __USE_GNU /* strverscmp */
|
||||||
|
#include <string.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* cligen */
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
/* clixon */
|
||||||
|
#include <clixon/clixon.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
usage(char *argv0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:%s.\n\tInput on stdin\n", argv0);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
yang_spec *yspec = NULL;
|
||||||
|
|
||||||
|
if (argc != 1){
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((yspec = yspec_new()) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (yang_parse_file(0, "yang test", yspec) < 0){
|
||||||
|
fprintf(stderr, "xml parse error %s\n", clicon_err_reason);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
yang_print(stdout, (yang_node*)yspec);
|
||||||
|
done:
|
||||||
|
if (yspec)
|
||||||
|
yspec_free(yspec);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1391,7 +1391,7 @@ xml_parse_file(int fd,
|
||||||
ptr = xmlbuf;
|
ptr = xmlbuf;
|
||||||
while (1){
|
while (1){
|
||||||
if ((ret = read(fd, &ch, 1)) < 0){
|
if ((ret = read(fd, &ch, 1)) < 0){
|
||||||
clicon_err(OE_XML, errno, "read: [pid:%d]\n",
|
clicon_err(OE_XML, errno, "read: [pid:%d]",
|
||||||
(int)getpid());
|
(int)getpid());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1806,7 +1806,7 @@ xml_body_parse(cxobj *xb,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (cvret == 0){ /* parsing failed */
|
if (cvret == 0){ /* parsing failed */
|
||||||
clicon_err(OE_XML, errno, "Parsing CV: %s", &reason);
|
clicon_err(OE_XML, errno, "Parsing CV: %s", reason);
|
||||||
if (reason)
|
if (reason)
|
||||||
free(reason);
|
free(reason);
|
||||||
}
|
}
|
||||||
|
|
@ -1939,7 +1939,7 @@ xml_operation2str(enum operation_type op)
|
||||||
* Example run:
|
* Example run:
|
||||||
echo "<a><b/></a>" | xml
|
echo "<a><b/></a>" | xml
|
||||||
*/
|
*/
|
||||||
#if 0 /* Test program */
|
#if 1 /* Test program */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
usage(char *argv0)
|
usage(char *argv0)
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ xmldb_plugin_load(clicon_handle h,
|
||||||
dlerror(); /* Clear any existing error */
|
dlerror(); /* Clear any existing error */
|
||||||
if ((handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL)) == NULL) {
|
if ((handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL)) == NULL) {
|
||||||
error = (char*)dlerror();
|
error = (char*)dlerror();
|
||||||
clicon_err(OE_PLUGIN, errno, "dlopen: %s\n", error ? error : "Unknown error");
|
clicon_err(OE_PLUGIN, errno, "dlopen: %s", error ? error : "Unknown error");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Try v1 */
|
/* Try v1 */
|
||||||
|
|
@ -162,7 +162,7 @@ xmldb_plugin_unload(clicon_handle h)
|
||||||
dlerror(); /* Clear any existing error */
|
dlerror(); /* Clear any existing error */
|
||||||
if (dlclose(handle) != 0) {
|
if (dlclose(handle) != 0) {
|
||||||
error = (char*)dlerror();
|
error = (char*)dlerror();
|
||||||
clicon_err(OE_PLUGIN, errno, "dlclose: %s\n", error ? error : "Unknown error");
|
clicon_err(OE_PLUGIN, errno, "dlclose: %s", error ? error : "Unknown error");
|
||||||
/* Just report no -1 return*/
|
/* Just report no -1 return*/
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ validate_leafref(cxobj *xt,
|
||||||
clicon_err(OE_DB, 0, "Leafref %s requires path statement", ytype->ys_argument);
|
clicon_err(OE_DB, 0, "Leafref %s requires path statement", ytype->ys_argument);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (xpath_vec(xt, ypath->ys_argument, &xvec, &xlen) < 0)
|
if (xpath_vec(xt, "%s", &xvec, &xlen, ypath->ys_argument) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i = 0; i < xlen; i++) {
|
for (i = 0; i < xlen; i++) {
|
||||||
x = xvec[i];
|
x = xvec[i];
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ int clixon_xml_parsewrap(void)
|
||||||
<AMPERSAND>"lt; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = "<"; return CHARDATA;}
|
<AMPERSAND>"lt; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = "<"; return CHARDATA;}
|
||||||
<AMPERSAND>"gt; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = ">"; return CHARDATA;}
|
<AMPERSAND>"gt; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = ">"; return CHARDATA;}
|
||||||
<AMPERSAND>"apos; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = "'"; return CHARDATA;}
|
<AMPERSAND>"apos; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = "'"; return CHARDATA;}
|
||||||
<AMPERSAND>"aquot; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = "'"; return CHARDATA;}
|
<AMPERSAND>"quot; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = "\""; return CHARDATA;}
|
||||||
|
|
||||||
<CDATA>. { clixon_xml_parselval.string = yytext; return CHARDATA;}
|
<CDATA>. { clixon_xml_parselval.string = yytext; return CHARDATA;}
|
||||||
<CDATA>\n { clixon_xml_parselval.string = yytext;_YA->ya_linenum++; return (CHARDATA);}
|
<CDATA>\n { clixon_xml_parselval.string = yytext;_YA->ya_linenum++; return (CHARDATA);}
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ xpath_parse_predicate(struct xpath_element *xe,
|
||||||
}
|
}
|
||||||
memset(xp, 0, sizeof(*xp));
|
memset(xp, 0, sizeof(*xp));
|
||||||
if ((xp->xp_expr = strdup(s)) == NULL){
|
if ((xp->xp_expr = strdup(s)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
xp->xp_next = xe->xe_predicate;
|
xp->xp_next = xe->xe_predicate;
|
||||||
|
|
@ -236,7 +236,7 @@ xpath_element_new(enum axis_type atype,
|
||||||
xe->xe_type = atype;
|
xe->xe_type = atype;
|
||||||
if (str){
|
if (str){
|
||||||
if ((str1 = strdup(str)) == NULL){
|
if ((str1 = strdup(str)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (xpath_split(str1, &pred) < 0) /* Can be more predicates */
|
if (xpath_split(str1, &pred) < 0) /* Can be more predicates */
|
||||||
|
|
@ -247,20 +247,20 @@ xpath_element_new(enum axis_type atype,
|
||||||
*local = '\0';
|
*local = '\0';
|
||||||
local++;
|
local++;
|
||||||
if ((xe->xe_prefix = strdup(str1)) == NULL){
|
if ((xe->xe_prefix = strdup(str1)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
local = str1;
|
local = str1;
|
||||||
if ((xe->xe_str = strdup(local)) == NULL){
|
if ((xe->xe_str = strdup(local)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if ((xe->xe_str = strdup("*")) == NULL){
|
if ((xe->xe_str = strdup("*")) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -326,7 +326,7 @@ xpath_parse(char *xpath,
|
||||||
int esc = 0;
|
int esc = 0;
|
||||||
|
|
||||||
if ((s0 = strdup(xpath)) == NULL){
|
if ((s0 = strdup(xpath)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
s = s0;
|
s = s0;
|
||||||
|
|
@ -502,8 +502,7 @@ xpath_expr(cxobj *xcur,
|
||||||
e_v=e;
|
e_v=e;
|
||||||
e_a = strsep(&e_v, "=");
|
e_a = strsep(&e_v, "=");
|
||||||
if (e_a == NULL){
|
if (e_a == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: malformed expression: [@%s]",
|
clicon_err(OE_XML, errno, "malformed expression: [@%s]", e);
|
||||||
__FUNCTION__, e);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
for (i=0; i<*vec0len; i++){
|
for (i=0; i<*vec0len; i++){
|
||||||
|
|
@ -534,15 +533,13 @@ xpath_expr(cxobj *xcur,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
clicon_err(OE_XML, errno, "%s: malformed expression: [%s]",
|
clicon_err(OE_XML, errno, "malformed expression: [%s]", e);
|
||||||
__FUNCTION__, e);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{ /* name = expr */
|
else{ /* name = expr */
|
||||||
if ((tag = strsep(&e, "=")) == NULL){
|
if ((tag = strsep(&e, "=")) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: malformed expression: [%s]",
|
clicon_err(OE_XML, errno, "malformed expression: [%s]", e);
|
||||||
__FUNCTION__, e);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Strip trailing spaces */
|
/* Strip trailing spaces */
|
||||||
|
|
@ -782,7 +779,7 @@ xpath_split(char *xpathstr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pe==NULL){
|
if (pe==NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: mismatched []: %s", __FUNCTION__, xpathstr);
|
clicon_err(OE_XML, errno, "mismatched []: %s", xpathstr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -859,7 +856,7 @@ xpath_choice(cxobj *xcur,
|
||||||
size_t vec0len = 0;
|
size_t vec0len = 0;
|
||||||
|
|
||||||
if ((s0 = strdup(xpath0)) == NULL){
|
if ((s0 = strdup(xpath0)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_XML, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
s2 = s1 = s0;
|
s2 = s1 = s0;
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,14 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
#define __USE_GNU /* strverscmp */
|
#define __USE_GNU /* strverscmp */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
@ -74,6 +77,8 @@
|
||||||
#include "clixon_yang_type.h"
|
#include "clixon_yang_type.h"
|
||||||
#include "clixon_yang_parse.h"
|
#include "clixon_yang_parse.h"
|
||||||
|
|
||||||
|
/* Size of json read buffer when reading from file*/
|
||||||
|
#define BUFLEN 1024
|
||||||
|
|
||||||
/* Mapping between yang keyword string <--> clicon constants */
|
/* Mapping between yang keyword string <--> clicon constants */
|
||||||
static const map_str2int ykmap[] = {
|
static const map_str2int ykmap[] = {
|
||||||
|
|
@ -158,7 +163,7 @@ yspec_new(void)
|
||||||
yang_spec *yspec;
|
yang_spec *yspec;
|
||||||
|
|
||||||
if ((yspec = malloc(sizeof(*yspec))) == NULL){
|
if ((yspec = malloc(sizeof(*yspec))) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: malloc", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "malloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(yspec, 0, sizeof(*yspec));
|
memset(yspec, 0, sizeof(*yspec));
|
||||||
|
|
@ -176,7 +181,7 @@ ys_new(enum rfc_6020 keyw)
|
||||||
yang_stmt *ys;
|
yang_stmt *ys;
|
||||||
|
|
||||||
if ((ys = malloc(sizeof(*ys))) == NULL){
|
if ((ys = malloc(sizeof(*ys))) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: malloc", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "malloc");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(ys, 0, sizeof(*ys));
|
memset(ys, 0, sizeof(*ys));
|
||||||
|
|
@ -184,7 +189,7 @@ ys_new(enum rfc_6020 keyw)
|
||||||
/* The cvec contains stmt-specific variables. Only few stmts need variables so the
|
/* The cvec contains stmt-specific variables. Only few stmts need variables so the
|
||||||
cvec could be lazily created to save some heap and cycles. */
|
cvec could be lazily created to save some heap and cycles. */
|
||||||
if ((ys->ys_cvec = cvec_new(0)) == NULL){
|
if ((ys->ys_cvec = cvec_new(0)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cvec_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cvec_new");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return ys;
|
return ys;
|
||||||
|
|
@ -247,7 +252,7 @@ yn_realloc(yang_node *yn)
|
||||||
yn->yn_len++;
|
yn->yn_len++;
|
||||||
|
|
||||||
if ((yn->yn_stmt = realloc(yn->yn_stmt, (yn->yn_len)*sizeof(yang_stmt *))) == 0){
|
if ((yn->yn_stmt = realloc(yn->yn_stmt, (yn->yn_len)*sizeof(yang_stmt *))) == 0){
|
||||||
clicon_err(OE_YANG, errno, "%s: realloc", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "realloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
yn->yn_stmt[yn->yn_len - 1] = NULL; /* init field */
|
yn->yn_stmt[yn->yn_len - 1] = NULL; /* init field */
|
||||||
|
|
@ -276,22 +281,22 @@ ys_cp(yang_stmt *ynew,
|
||||||
ynew->ys_parent = NULL;
|
ynew->ys_parent = NULL;
|
||||||
if (yold->ys_stmt)
|
if (yold->ys_stmt)
|
||||||
if ((ynew->ys_stmt = calloc(yold->ys_len, sizeof(yang_stmt *))) == NULL){
|
if ((ynew->ys_stmt = calloc(yold->ys_len, sizeof(yang_stmt *))) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: calloc", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "calloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yold->ys_argument)
|
if (yold->ys_argument)
|
||||||
if ((ynew->ys_argument = strdup(yold->ys_argument)) == NULL){
|
if ((ynew->ys_argument = strdup(yold->ys_argument)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yold->ys_cv)
|
if (yold->ys_cv)
|
||||||
if ((ynew->ys_cv = cv_dup(yold->ys_cv)) == NULL){
|
if ((ynew->ys_cv = cv_dup(yold->ys_cv)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cv_dup", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cv_dup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yold->ys_cvec)
|
if (yold->ys_cvec)
|
||||||
if ((ynew->ys_cvec = cvec_dup(yold->ys_cvec)) == NULL){
|
if ((ynew->ys_cvec = cvec_dup(yold->ys_cvec)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cvec_dup", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cvec_dup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yold->ys_typecache){
|
if (yold->ys_typecache){
|
||||||
|
|
@ -902,7 +907,7 @@ yang_print(FILE *f,
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cbuf_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yang_print_cbuf(cb, yn, 0) < 0)
|
if (yang_print_cbuf(cb, yn, 0) < 0)
|
||||||
|
|
@ -998,14 +1003,14 @@ ys_populate_leaf(yang_stmt *ys,
|
||||||
goto done;
|
goto done;
|
||||||
/* 2. Create the CV using cvtype and name it */
|
/* 2. Create the CV using cvtype and name it */
|
||||||
if ((cv = cv_new(cvtype)) == NULL){
|
if ((cv = cv_new(cvtype)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cv_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cv_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (options & YANG_OPTIONS_FRACTION_DIGITS && cvtype == CGV_DEC64) /* XXX: Seems misplaced? / too specific */
|
if (options & YANG_OPTIONS_FRACTION_DIGITS && cvtype == CGV_DEC64) /* XXX: Seems misplaced? / too specific */
|
||||||
cv_dec64_n_set(cv, fraction_digits);
|
cv_dec64_n_set(cv, fraction_digits);
|
||||||
|
|
||||||
if (cv_name_set(cv, ys->ys_argument) == NULL){
|
if (cv_name_set(cv, ys->ys_argument) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cv_new_set", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cv_new_set");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* 3. Check if default value. Here we parse the string in the default-stmt
|
/* 3. Check if default value. Here we parse the string in the default-stmt
|
||||||
|
|
@ -1083,7 +1088,7 @@ ys_populate_range(yang_stmt *ys,
|
||||||
|
|
||||||
yparent = ys->ys_parent; /* Find parent: type */
|
yparent = ys->ys_parent; /* Find parent: type */
|
||||||
if (yparent->yn_keyword != Y_TYPE){
|
if (yparent->yn_keyword != Y_TYPE){
|
||||||
clicon_err(OE_YANG, 0, "%s: parent should be type", __FUNCTION__);
|
clicon_err(OE_YANG, 0, "parent should be type");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yang_type_resolve(ys, (yang_stmt*)yparent, &yrestype,
|
if (yang_type_resolve(ys, (yang_stmt*)yparent, &yrestype,
|
||||||
|
|
@ -1103,7 +1108,8 @@ ys_populate_range(yang_stmt *ys,
|
||||||
}
|
}
|
||||||
if ((maxstr = strstr(minstr, "..")) != NULL){
|
if ((maxstr = strstr(minstr, "..")) != NULL){
|
||||||
if (strlen(maxstr) < 2){
|
if (strlen(maxstr) < 2){
|
||||||
clicon_err(OE_YANG, 0, "range statement: %s not on the form: <int>..<int>");
|
clicon_err(OE_YANG, 0, "range statement: %s not on the form: <int>..<int>",
|
||||||
|
ys->ys_argument);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
minstr[maxstr-minstr] = '\0';
|
minstr[maxstr-minstr] = '\0';
|
||||||
|
|
@ -1499,7 +1505,7 @@ yang_expand(yang_node *yn)
|
||||||
size = (yn->yn_len - i - 1)*sizeof(struct yang_stmt *);
|
size = (yn->yn_len - i - 1)*sizeof(struct yang_stmt *);
|
||||||
yn->yn_len += glen - 1;
|
yn->yn_len += glen - 1;
|
||||||
if (glen && (yn->yn_stmt = realloc(yn->yn_stmt, (yn->yn_len)*sizeof(yang_stmt *))) == 0){
|
if (glen && (yn->yn_stmt = realloc(yn->yn_stmt, (yn->yn_len)*sizeof(yang_stmt *))) == 0){
|
||||||
clicon_err(OE_YANG, errno, "%s: realloc", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "realloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Then move all existing elements up from i+1 (not uses-stmt) */
|
/* Then move all existing elements up from i+1 (not uses-stmt) */
|
||||||
|
|
@ -1540,10 +1546,10 @@ yang_expand(yang_node *yn)
|
||||||
* Syntax parsing. A string is input and a syntax-tree is returned (or error).
|
* Syntax parsing. A string is input and a syntax-tree is returned (or error).
|
||||||
* A variable record is also returned containing a list of (global) variable values.
|
* A variable record is also returned containing a list of (global) variable values.
|
||||||
* (cloned from cligen)
|
* (cloned from cligen)
|
||||||
* @param h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param str String of yang statements
|
* @param[in] str String of yang statements
|
||||||
* @param name Log string, typically filename
|
* @param[in] name Log string, typically filename
|
||||||
* @param ysp Yang specification. Should ave been created by caller using yspec_new
|
* @param[in] ysp Yang specification. Should ave been created by caller using yspec_new
|
||||||
* @retval ymod Top-level yang (sub)module
|
* @retval ymod Top-level yang (sub)module
|
||||||
* @retval NULL Error encountered
|
* @retval NULL Error encountered
|
||||||
* Calling order:
|
* Calling order:
|
||||||
|
|
@ -1554,15 +1560,17 @@ yang_expand(yang_node *yn)
|
||||||
* clixon_yang_parseparse # Actual yang parsing using yacc
|
* clixon_yang_parseparse # Actual yang parsing using yacc
|
||||||
*/
|
*/
|
||||||
static yang_stmt *
|
static yang_stmt *
|
||||||
yang_parse_str(clicon_handle h,
|
yang_parse_str(char *str,
|
||||||
char *str,
|
|
||||||
const char *name, /* just for errs */
|
const char *name, /* just for errs */
|
||||||
yang_spec *yspec)
|
yang_spec *yspec)
|
||||||
{
|
{
|
||||||
struct clicon_yang_yacc_arg yy = {0,};
|
struct clicon_yang_yacc_arg yy = {0,};
|
||||||
yang_stmt *ymod = NULL;
|
yang_stmt *ymod = NULL;
|
||||||
|
|
||||||
yy.yy_handle = h;
|
if (yspec == NULL){
|
||||||
|
clicon_err(OE_YANG, 0, "Yang parse need top level yang spec");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
yy.yy_name = (char*)name;
|
yy.yy_name = (char*)name;
|
||||||
yy.yy_linenum = 1;
|
yy.yy_linenum = 1;
|
||||||
yy.yy_parse_string = str;
|
yy.yy_parse_string = str;
|
||||||
|
|
@ -1595,13 +1603,64 @@ yang_parse_str(clicon_handle h,
|
||||||
return ymod; /* top-level (sub)module */
|
return ymod; /* top-level (sub)module */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Read an opened file into a string and call yang string parsing
|
/*! Parse yang spec from an open file descriptor
|
||||||
|
* @param[in] fd File descriptor containing the YANG file as ASCII characters
|
||||||
|
* @param[in] name For debug, eg filename
|
||||||
|
* @param[in] ysp Yang specification. Should ave been created by caller using yspec_new
|
||||||
|
* @retval ymod Top-level yang (sub)module
|
||||||
|
* @retval NULL Error
|
||||||
|
*/
|
||||||
|
yang_stmt *
|
||||||
|
yang_parse_file(int fd,
|
||||||
|
const char *name,
|
||||||
|
yang_spec *ysp)
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
int i;
|
||||||
|
int c;
|
||||||
|
int len;
|
||||||
|
yang_stmt *ymod = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
len = BUFLEN; /* any number is fine */
|
||||||
|
if ((buf = malloc(len)) == NULL){
|
||||||
|
perror("pt_file malloc");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(buf, 0, len);
|
||||||
|
i = 0; /* position in buf */
|
||||||
|
while (1){ /* read the whole file */
|
||||||
|
if ((ret = read(fd, &c, 1)) < 0){
|
||||||
|
clicon_err(OE_XML, errno, "read");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
break; /* eof */
|
||||||
|
if (len==i){
|
||||||
|
if ((buf = realloc(buf, 2*len)) == NULL){
|
||||||
|
clicon_err(OE_XML, errno, "realloc");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
memset(buf+len, 0, len);
|
||||||
|
len *= 2;
|
||||||
|
}
|
||||||
|
buf[i++] = (char)(c&0xff);
|
||||||
|
} /* read a line */
|
||||||
|
if ((ymod = yang_parse_str(buf, name, ysp)) < 0)
|
||||||
|
goto done;
|
||||||
|
done:
|
||||||
|
if (buf)
|
||||||
|
free(buf);
|
||||||
|
return ymod; /* top-level (sub)module */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Open a file, read into a string and invoke yang parsing
|
||||||
*
|
*
|
||||||
* Similar to clicon_yang_str(), just read a file first
|
* Similar to clicon_yang_str(), just read a file first
|
||||||
* (cloned from cligen)
|
* (cloned from cligen)
|
||||||
* @param h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param filename Name of file
|
* @param[in] filename Name of file
|
||||||
* @param ysp Yang specification. Should ave been created by caller using yspec_new
|
* @param[in] ysp Yang specification. Should ave been created by caller using yspec_new
|
||||||
* @retval ymod Top-level yang (sub)module
|
* @retval ymod Top-level yang (sub)module
|
||||||
* @retval NULL Error encountered
|
* @retval NULL Error encountered
|
||||||
|
|
||||||
|
|
@ -1614,17 +1673,11 @@ yang_parse_str(clicon_handle h,
|
||||||
* clixon_yang_parseparse # Actual yang parsing using yacc
|
* clixon_yang_parseparse # Actual yang parsing using yacc
|
||||||
*/
|
*/
|
||||||
static yang_stmt *
|
static yang_stmt *
|
||||||
yang_parse_file(clicon_handle h,
|
yang_parse_filename(const char *filename,
|
||||||
const char *filename,
|
yang_spec *ysp)
|
||||||
yang_spec *ysp
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
|
||||||
int i;
|
|
||||||
int c;
|
|
||||||
int len;
|
|
||||||
yang_stmt *ymod = NULL;
|
yang_stmt *ymod = NULL;
|
||||||
FILE *f = NULL;
|
int fd = -1;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
clicon_log(LOG_DEBUG, "Parsing yang file: %s", filename);
|
clicon_log(LOG_DEBUG, "Parsing yang file: %s", filename);
|
||||||
|
|
@ -1632,39 +1685,15 @@ yang_parse_file(clicon_handle h,
|
||||||
clicon_err(OE_YANG, errno, "%s not found", filename);
|
clicon_err(OE_YANG, errno, "%s not found", filename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((f = fopen(filename, "r")) == NULL){
|
if ((fd = open(filename, O_RDONLY)) < 0){
|
||||||
clicon_err(OE_UNIX, errno, "fopen(%s)", filename);
|
clicon_err(OE_YANG, errno, "open(%s)", filename);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if ((ymod = yang_parse_file(fd, filename, ysp)) < 0)
|
||||||
len = 1024; /* any number is fine */
|
|
||||||
if ((buf = malloc(len)) == NULL){
|
|
||||||
perror("pt_file malloc");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(buf, 0, len);
|
|
||||||
|
|
||||||
i = 0; /* position in buf */
|
|
||||||
while (1){ /* read the whole file */
|
|
||||||
if ((c = fgetc(f)) == EOF)
|
|
||||||
break;
|
|
||||||
if (len==i){
|
|
||||||
if ((buf = realloc(buf, 2*len)) == NULL){
|
|
||||||
fprintf(stderr, "%s: realloc: %s\n", __FUNCTION__, strerror(errno));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
memset(buf+len, 0, len);
|
|
||||||
len *= 2;
|
|
||||||
}
|
|
||||||
buf[i++] = (char)(c&0xff);
|
|
||||||
} /* read a line */
|
|
||||||
if ((ymod = yang_parse_str(h, buf, filename, ysp)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
done:
|
done:
|
||||||
if (f)
|
if (fd != -1)
|
||||||
fclose(f);
|
close(fd);
|
||||||
if (buf)
|
|
||||||
free(buf);
|
|
||||||
return ymod; /* top-level (sub)module */
|
return ymod; /* top-level (sub)module */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1679,8 +1708,7 @@ yang_parse_file(clicon_handle h,
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
yang_parse_find_match(clicon_handle h,
|
yang_parse_find_match(const char *yang_dir,
|
||||||
const char *yang_dir,
|
|
||||||
const char *module,
|
const char *module,
|
||||||
cbuf *fbuf)
|
cbuf *fbuf)
|
||||||
{
|
{
|
||||||
|
|
@ -1724,7 +1752,7 @@ yang_parse_find_match(clicon_handle h,
|
||||||
* @param[in] h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param[in] yang_dir Directory where all YANG module files reside
|
* @param[in] yang_dir Directory where all YANG module files reside
|
||||||
* @param[in] module Name of main YANG module. Or absolute file name.
|
* @param[in] module Name of main YANG module. Or absolute file name.
|
||||||
* @param[in] revision Optional module revision date
|
* @param[in] revision Module revision date or NULL
|
||||||
* @param[in] ysp Yang specification. Should have been created by caller using yspec_new
|
* @param[in] ysp Yang specification. Should have been created by caller using yspec_new
|
||||||
* @retval ymod Top-level yang (sub)module
|
* @retval ymod Top-level yang (sub)module
|
||||||
* @retval NULL Error encountered
|
* @retval NULL Error encountered
|
||||||
|
|
@ -1737,8 +1765,7 @@ yang_parse_find_match(clicon_handle h,
|
||||||
* clixon_yang_parseparse # Actual yang parsing using yacc
|
* clixon_yang_parseparse # Actual yang parsing using yacc
|
||||||
*/
|
*/
|
||||||
static yang_stmt *
|
static yang_stmt *
|
||||||
yang_parse_recurse(clicon_handle h,
|
yang_parse_recurse(const char *yang_dir,
|
||||||
const char *yang_dir,
|
|
||||||
const char *module,
|
const char *module,
|
||||||
const char *revision,
|
const char *revision,
|
||||||
yang_spec *ysp)
|
yang_spec *ysp)
|
||||||
|
|
@ -1752,26 +1779,26 @@ yang_parse_recurse(clicon_handle h,
|
||||||
int nr;
|
int nr;
|
||||||
|
|
||||||
if (module[0] == '/'){
|
if (module[0] == '/'){
|
||||||
if ((ymod = yang_parse_file(h, module, ysp)) == NULL)
|
if ((ymod = yang_parse_filename(module, ysp)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((fbuf = cbuf_new()) == NULL){
|
if ((fbuf = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cbuf_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (revision)
|
if (revision)
|
||||||
cprintf(fbuf, "%s/%s@%s.yang", yang_dir, module, revision);
|
cprintf(fbuf, "%s/%s@%s.yang", yang_dir, module, revision);
|
||||||
else{
|
else{
|
||||||
/* No specific revision, Match a yang file */
|
/* No specific revision, Match a yang file */
|
||||||
if ((nr = yang_parse_find_match(h, yang_dir, module, fbuf)) < 0)
|
if ((nr = yang_parse_find_match(yang_dir, module, fbuf)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (nr == 0){
|
if (nr == 0){
|
||||||
clicon_err(OE_YANG, errno, "No matching %s yang files found (expected module name or absolute filename)", module);
|
clicon_err(OE_YANG, errno, "No matching %s yang files found (expected module name or absolute filename)", module);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ymod = yang_parse_file(h, cbuf_get(fbuf), ysp)) == NULL)
|
if ((ymod = yang_parse_filename(cbuf_get(fbuf), ysp)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1786,7 +1813,7 @@ yang_parse_recurse(clicon_handle h,
|
||||||
subrevision = NULL;
|
subrevision = NULL;
|
||||||
if (yang_find((yang_node*)ysp, Y_MODULE, modname) == NULL)
|
if (yang_find((yang_node*)ysp, Y_MODULE, modname) == NULL)
|
||||||
/* recursive call */
|
/* recursive call */
|
||||||
if (yang_parse_recurse(h, yang_dir, modname, subrevision, ysp) == NULL){
|
if (yang_parse_recurse(yang_dir, modname, subrevision, ysp) == NULL){
|
||||||
ymod = NULL;
|
ymod = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -1845,7 +1872,7 @@ ys_schemanode_check(yang_stmt *ys,
|
||||||
* @param[in] h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param[in] yang_dir Directory where all YANG module files reside (except mainfile)
|
* @param[in] yang_dir Directory where all YANG module files reside (except mainfile)
|
||||||
* @param[in] mainmod Name of main YANG module. Or absolute file name.
|
* @param[in] mainmod Name of main YANG module. Or absolute file name.
|
||||||
* @param[in] revision Optional main module revision date.
|
* @param[in] revision Main module revision date string or NULL
|
||||||
* @param[out] ysp Yang specification. Should ave been created by caller using yspec_new
|
* @param[out] ysp Yang specification. Should ave been created by caller using yspec_new
|
||||||
* @retval 0 Everything OK
|
* @retval 0 Everything OK
|
||||||
* @retval -1 Error encountered
|
* @retval -1 Error encountered
|
||||||
|
|
@ -1854,7 +1881,8 @@ ys_schemanode_check(yang_stmt *ys,
|
||||||
* @note if mainmod is filename, revision is not considered.
|
* @note if mainmod is filename, revision is not considered.
|
||||||
* Calling order:
|
* Calling order:
|
||||||
* yang_parse # Parse top-level yang module. Expand and populate yang tree
|
* yang_parse # Parse top-level yang module. Expand and populate yang tree
|
||||||
* yang_parse_recurse # Parse one yang module, go through its (sub)modules, parse them and then recursively parse them
|
* yang_parse_recurse # Parse one yang module, go through its (sub)modules,
|
||||||
|
* parse them and then recursively parse them
|
||||||
* yang_parse_file # Read yang file into a string
|
* yang_parse_file # Read yang file into a string
|
||||||
* yang_parse_str # Set up yacc parser and call it given a string
|
* yang_parse_str # Set up yacc parser and call it given a string
|
||||||
* clixon_yang_parseparse # Actual yang parsing using yacc
|
* clixon_yang_parseparse # Actual yang parsing using yacc
|
||||||
|
|
@ -1870,7 +1898,7 @@ yang_parse(clicon_handle h,
|
||||||
yang_stmt *ymod; /* Top-level yang (sub)module */
|
yang_stmt *ymod; /* Top-level yang (sub)module */
|
||||||
|
|
||||||
/* Step 1: parse from text to yang parse-tree. */
|
/* Step 1: parse from text to yang parse-tree. */
|
||||||
if ((ymod = yang_parse_recurse(h, yang_dir, mainmodule, revision, ysp)) == NULL)
|
if ((ymod = yang_parse_recurse(yang_dir, mainmodule, revision, ysp)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
/* Add top module name as dbspec-name */
|
/* Add top module name as dbspec-name */
|
||||||
clicon_dbspec_name_set(h, ymod->ys_argument);
|
clicon_dbspec_name_set(h, ymod->ys_argument);
|
||||||
|
|
@ -2080,13 +2108,13 @@ yang_abs_schema_nodeid(yang_spec *yspec,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((vec = clicon_strsep(schema_nodeid, "/", &nvec)) == NULL){
|
if ((vec = clicon_strsep(schema_nodeid, "/", &nvec)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: strsep", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "strsep");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Assume schema nodeid looks like: "/prefix:id[/prefix:id]*" */
|
/* Assume schema nodeid looks like: "/prefix:id[/prefix:id]*" */
|
||||||
if (nvec < 2){
|
if (nvec < 2){
|
||||||
clicon_err(OE_YANG, 0, "%s: NULL or truncated path: %s",
|
clicon_err(OE_YANG, 0, "NULL or truncated path: %s",
|
||||||
__FUNCTION__, schema_nodeid);
|
schema_nodeid);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* split <prefix>:<id> */
|
/* split <prefix>:<id> */
|
||||||
|
|
@ -2095,7 +2123,7 @@ yang_abs_schema_nodeid(yang_spec *yspec,
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if ((prefix = strdup(vec[1])) == NULL){
|
if ((prefix = strdup(vec[1])) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "%s: strdup", __FUNCTION__);
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
prefix[id-vec[1]] = '\0';
|
prefix[id-vec[1]] = '\0';
|
||||||
|
|
@ -2183,7 +2211,7 @@ ys_parse(yang_stmt *ys,
|
||||||
|
|
||||||
assert(ys->ys_cv == NULL); /* Cv:s are parsed in different places, difficult to separate */
|
assert(ys->ys_cv == NULL); /* Cv:s are parsed in different places, difficult to separate */
|
||||||
if ((ys->ys_cv = cv_new(cvtype)) == NULL){
|
if ((ys->ys_cv = cv_new(cvtype)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cv_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cv_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((cvret = cv_parse1(ys->ys_argument, ys->ys_cv, &reason)) < 0){ /* error */
|
if ((cvret = cv_parse1(ys->ys_argument, ys->ys_cv, &reason)) < 0){ /* error */
|
||||||
|
|
@ -2252,7 +2280,7 @@ ys_parse_sub(yang_stmt *ys,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((ys->ys_cv = cv_new(CGV_STRING)) == NULL){
|
if ((ys->ys_cv = cv_new(CGV_STRING)) == NULL){
|
||||||
clicon_err(OE_YANG, errno, "%s: cv_new", __FUNCTION__);
|
clicon_err(OE_YANG, errno, "cv_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((cvret = cv_parse1(extra, ys->ys_cv, &reason)) < 0){ /* error */
|
if ((cvret = cv_parse1(extra, ys->ys_cv, &reason)) < 0){ /* error */
|
||||||
|
|
@ -2334,9 +2362,9 @@ yang_spec_netconf(clicon_handle h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Read, parse and save application yang specification as option
|
/*! Read, parse and save application yang specification as option
|
||||||
* @param h clicon handle
|
* @param[in] h clicon handle
|
||||||
* @param f file to print to (if printspec enabled)
|
* @param[in] f file to print to (if printspec enabled)
|
||||||
* @param printspec print database (YANG) specification as read from file
|
* @param[in] printspec print database (YANG) specification as read from file
|
||||||
*/
|
*/
|
||||||
yang_spec*
|
yang_spec*
|
||||||
yang_spec_main(clicon_handle h)
|
yang_spec_main(clicon_handle h)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ struct ys_stack{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clicon_yang_yacc_arg{ /* XXX: mostly unrelevant */
|
struct clicon_yang_yacc_arg{ /* XXX: mostly unrelevant */
|
||||||
clicon_handle yy_handle; /* cligen_handle */
|
|
||||||
char *yy_name; /* Name of syntax (for error string) */
|
char *yy_name; /* Name of syntax (for error string) */
|
||||||
int yy_linenum; /* Number of \n in parsed buffer */
|
int yy_linenum; /* Number of \n in parsed buffer */
|
||||||
char *yy_parse_string; /* original (copy of) parse string */
|
char *yy_parse_string; /* original (copy of) parse string */
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ ysp_add(struct clicon_yang_yacc_arg *yy,
|
||||||
clicon_err(OE_YANG, errno, "No stack");
|
clicon_err(OE_YANG, errno, "No stack");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
yn = ystack->ys_node;
|
assert(yn = ystack->ys_node);
|
||||||
if ((ys = ys_new(keyword)) == NULL)
|
if ((ys = ys_new(keyword)) == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
/* NOTE: does not make a copy of string, ie argument is 'consumed' here */
|
/* NOTE: does not make a copy of string, ie argument is 'consumed' here */
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#define __USE_GNU /* strverscmp */
|
#define __USE_GNU /* strverscmp */
|
||||||
|
|
@ -354,7 +355,7 @@ clicon_type2cv(char *origtype,
|
||||||
if (restype != NULL){
|
if (restype != NULL){
|
||||||
yang2cv_type(restype, cvtype);
|
yang2cv_type(restype, cvtype);
|
||||||
if (*cvtype == CGV_ERR){
|
if (*cvtype == CGV_ERR){
|
||||||
clicon_err(OE_DB, 0, "%s: \"%s\" type not translated", __FUNCTION__, restype);
|
clicon_err(OE_DB, 0, "\"%s\" type not translated", restype);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +366,7 @@ clicon_type2cv(char *origtype,
|
||||||
*/
|
*/
|
||||||
yang2cv_type(origtype, cvtype);
|
yang2cv_type(origtype, cvtype);
|
||||||
if (*cvtype == CGV_ERR){
|
if (*cvtype == CGV_ERR){
|
||||||
clicon_err(OE_DB, 0, "%s: \"%s\": type not resolved", __FUNCTION__, origtype);
|
clicon_err(OE_DB, 0, "\"%s\": type not resolved", origtype);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,8 +400,8 @@ cv_validate1(cg_var *cv,
|
||||||
int retval = 1; /* OK */
|
int retval = 1; /* OK */
|
||||||
int retval2;
|
int retval2;
|
||||||
yang_stmt *yi = NULL;
|
yang_stmt *yi = NULL;
|
||||||
uint64_t u = 0;
|
unsigned int u = 0;
|
||||||
int64_t i = 0;
|
int i = 0;
|
||||||
char *str;
|
char *str;
|
||||||
int found;
|
int found;
|
||||||
char **vec = NULL;
|
char **vec = NULL;
|
||||||
|
|
@ -417,7 +418,7 @@ cv_validate1(cg_var *cv,
|
||||||
i = cv_int8_get(cv);
|
i = cv_int8_get(cv);
|
||||||
if (range_check(i, range_min, range_max, int8)){
|
if (range_check(i, range_min, range_max, int8)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %ld", i);
|
*reason = cligen_reason("Number out of range: %d", i);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -428,7 +429,7 @@ cv_validate1(cg_var *cv,
|
||||||
i = cv_int16_get(cv);
|
i = cv_int16_get(cv);
|
||||||
if (range_check(i, range_min, range_max, int16)){
|
if (range_check(i, range_min, range_max, int16)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %ld", i);
|
*reason = cligen_reason("Number out of range: %d", i);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -439,29 +440,31 @@ cv_validate1(cg_var *cv,
|
||||||
i = cv_int32_get(cv);
|
i = cv_int32_get(cv);
|
||||||
if (range_check(i, range_min, range_max, int32)){
|
if (range_check(i, range_min, range_max, int32)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %ld", i);
|
*reason = cligen_reason("Number out of range: %d", i);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CGV_INT64:
|
case CGV_INT64:{
|
||||||
|
int64_t i64;
|
||||||
if ((options & YANG_OPTIONS_RANGE) != 0){
|
if ((options & YANG_OPTIONS_RANGE) != 0){
|
||||||
i = cv_int64_get(cv);
|
i64 = cv_int64_get(cv);
|
||||||
if (range_check(i, range_min, range_max, int64)){
|
if (range_check(i, range_min, range_max, int64)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %ld", i);
|
*reason = cligen_reason("Number out of range: %" PRId64, i64);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case CGV_UINT8:
|
case CGV_UINT8:
|
||||||
if ((options & YANG_OPTIONS_RANGE) != 0){
|
if ((options & YANG_OPTIONS_RANGE) != 0){
|
||||||
u = cv_uint8_get(cv);
|
u = cv_uint8_get(cv);
|
||||||
if (range_check(u, range_min, range_max, uint8)){
|
if (range_check(u, range_min, range_max, uint8)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %lu", u);
|
*reason = cligen_reason("Number out of range: %u", u);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -472,7 +475,7 @@ cv_validate1(cg_var *cv,
|
||||||
u = cv_uint16_get(cv);
|
u = cv_uint16_get(cv);
|
||||||
if (range_check(u, range_min, range_max, uint16)){
|
if (range_check(u, range_min, range_max, uint16)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %lu", u);
|
*reason = cligen_reason("Number out of range: %u", u);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -483,29 +486,31 @@ cv_validate1(cg_var *cv,
|
||||||
u = cv_uint32_get(cv);
|
u = cv_uint32_get(cv);
|
||||||
if (range_check(u, range_min, range_max, uint32)){
|
if (range_check(u, range_min, range_max, uint32)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %lu", u);
|
*reason = cligen_reason("Number out of range: %u", u);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CGV_UINT64:
|
case CGV_UINT64:{
|
||||||
|
uint64_t u64;
|
||||||
if ((options & YANG_OPTIONS_RANGE) != 0){
|
if ((options & YANG_OPTIONS_RANGE) != 0){
|
||||||
u = cv_uint64_get(cv);
|
u64 = cv_uint64_get(cv);
|
||||||
if (range_check(u, range_min, range_max, uint64)){
|
if (range_check(u, range_min, range_max, uint64)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %lu", u);
|
*reason = cligen_reason("Number out of range: %" PRIu64, u64);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case CGV_DEC64:
|
case CGV_DEC64:
|
||||||
if ((options & YANG_OPTIONS_RANGE) != 0){
|
if ((options & YANG_OPTIONS_RANGE) != 0){
|
||||||
i = cv_int64_get(cv);
|
i = cv_int64_get(cv);
|
||||||
if (range_check(i, range_min, range_max, int64)){
|
if (range_check(i, range_min, range_max, int64)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("Number out of range: %ld", i);
|
*reason = cligen_reason("Number out of range: %d", i);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +570,7 @@ cv_validate1(cg_var *cv,
|
||||||
u = strlen(str);
|
u = strlen(str);
|
||||||
if (range_check(u, range_min, range_max, uint64)){
|
if (range_check(u, range_min, range_max, uint64)){
|
||||||
if (reason)
|
if (reason)
|
||||||
*reason = cligen_reason("string length out of range: %lu", u);
|
*reason = cligen_reason("string length out of range: %u", u);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -748,8 +753,8 @@ ys_cv_validate(cg_var *cv,
|
||||||
if (cvtype == CGV_STRING && cv_type_get(ycv) == CGV_REST)
|
if (cvtype == CGV_STRING && cv_type_get(ycv) == CGV_REST)
|
||||||
;
|
;
|
||||||
else {
|
else {
|
||||||
clicon_err(OE_DB, 0, "%s: Type mismatch data:%s != yang:%s",
|
clicon_err(OE_DB, 0, "Type mismatch data:%s != yang:%s",
|
||||||
__FUNCTION__, cv_type2str(cvtype), cv_type2str(cv_type_get(ycv)));
|
cv_type2str(cvtype), cv_type2str(cv_type_get(ycv)));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -904,14 +909,14 @@ resolve_restrictions(yang_stmt *yrange,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Recursively resolve a yang type to built-in type with optional restrictions
|
/*! Recursively resolve a yang type to built-in type with optional restrictions
|
||||||
* @param [in] ys yang-stmt from where the current search is based
|
* @param[in] ys yang-stmt from where the current search is based
|
||||||
* @param [in] ytype yang-stmt object containing currently resolving type
|
* @param[in] ytype yang-stmt object containing currently resolving type
|
||||||
* @param [out] yrestype resolved type. return built-in type or NULL. mandatory
|
* @param[out] yrestype resolved type. return built-in type or NULL. mandatory
|
||||||
* @param [out] options pointer to flags field of optional values. optional
|
* @param[out] options pointer to flags field of optional values. optional
|
||||||
* @param [out] mincv pointer to cv with min range or length. If options&YANG_OPTIONS_RANGE
|
* @param[out] mincv pointer to cv with min range or length. If options&YANG_OPTIONS_RANGE
|
||||||
* @param [out] maxcv pointer to cv with max range or length. If options&YANG_OPTIONS_RANGE
|
* @param[out] maxcv pointer to cv with max range or length. If options&YANG_OPTIONS_RANGE
|
||||||
* @param [out] pattern pointer to static string of yang string pattern. optional
|
* @param[out] pattern pointer to static string of yang string pattern. optional
|
||||||
* @param [out] fraction for decimal64, how many digits after period
|
* @param[out] fraction for decimal64, how many digits after period
|
||||||
* @retval 0 OK. Note yrestype may still be NULL.
|
* @retval 0 OK. Note yrestype may still be NULL.
|
||||||
* @retval -1 Error, clicon_err handles errors
|
* @retval -1 Error, clicon_err handles errors
|
||||||
* The setting of the options argument has the following semantics:
|
* The setting of the options argument has the following semantics:
|
||||||
|
|
@ -996,7 +1001,7 @@ yang_type_resolve(yang_stmt *ys,
|
||||||
if (rytypedef != NULL){ /* We have found a typedef */
|
if (rytypedef != NULL){ /* We have found a typedef */
|
||||||
/* Find associated type statement */
|
/* Find associated type statement */
|
||||||
if ((rytype = yang_find((yang_node*)rytypedef, Y_TYPE, NULL)) == NULL){
|
if ((rytype = yang_find((yang_node*)rytypedef, Y_TYPE, NULL)) == NULL){
|
||||||
clicon_err(OE_DB, 0, "%s: mandatory type object is not found", __FUNCTION__);
|
clicon_err(OE_DB, 0, "mandatory type object is not found");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* recursively resolve this new type */
|
/* recursively resolve this new type */
|
||||||
|
|
@ -1034,14 +1039,14 @@ yang_type_resolve(yang_stmt *ys,
|
||||||
* if (options & YANG_OPTIONS_PATTERN != 0)
|
* if (options & YANG_OPTIONS_PATTERN != 0)
|
||||||
* printf("regexp: %s\n", pattern);
|
* printf("regexp: %s\n", pattern);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @param [in] ys yang-stmt, leaf or leaf-list
|
* @param[in] ys yang-stmt, leaf or leaf-list
|
||||||
* @param [out] origtype original type may be derived or built-in
|
* @param[out] origtype original type may be derived or built-in
|
||||||
* @param [out] yrestype pointer to resolved type stmt. should be built-in or NULL
|
* @param[out] yrestype pointer to resolved type stmt. should be built-in or NULL
|
||||||
* @param [out] options pointer to flags field of optional values
|
* @param[out] options pointer to flags field of optional values
|
||||||
* @param [out] mincv pointer to cv of min range or length. optional
|
* @param[out] mincv pointer to cv of min range or length. optional
|
||||||
* @param [out] maxcv pointer to cv of max range or length. optional
|
* @param[out] maxcv pointer to cv of max range or length. optional
|
||||||
* @param [out] pattern pointer to static string of yang string pattern. optional
|
* @param[out] pattern pointer to static string of yang string pattern. optional
|
||||||
* @param [out] fraction for decimal64, how many digits after period
|
* @param[out] fraction for decimal64, how many digits after period
|
||||||
* @retval 0 OK, but note that restype==NULL means not resolved.
|
* @retval 0 OK, but note that restype==NULL means not resolved.
|
||||||
* @retval -1 Error, clicon_err handles errors
|
* @retval -1 Error, clicon_err handles errors
|
||||||
* The setting of the options argument has the following semantics:
|
* The setting of the options argument has the following semantics:
|
||||||
|
|
@ -1071,7 +1076,7 @@ yang_type_get(yang_stmt *ys,
|
||||||
*options = 0x0;
|
*options = 0x0;
|
||||||
/* Find mandatory type */
|
/* Find mandatory type */
|
||||||
if ((ytype = yang_find((yang_node*)ys, Y_TYPE, NULL)) == NULL){
|
if ((ytype = yang_find((yang_node*)ys, Y_TYPE, NULL)) == NULL){
|
||||||
clicon_err(OE_DB, 0, "%s: mandatory type object is not found", __FUNCTION__);
|
clicon_err(OE_DB, 0, "mandatory type object is not found");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* XXX: here we seem to have some problems if type is union */
|
/* XXX: here we seem to have some problems if type is union */
|
||||||
|
|
|
||||||
6
test/Jenkinsfile
vendored
6
test/Jenkinsfile
vendored
|
|
@ -8,15 +8,15 @@ node {
|
||||||
/* `make check` returns non-zero on test failures,
|
/* `make check` returns non-zero on test failures,
|
||||||
* using `true` to allow the Pipeline to continue nonetheless
|
* using `true` to allow the Pipeline to continue nonetheless
|
||||||
*/
|
*/
|
||||||
sh 'make clean || true'
|
sh 'make clean'
|
||||||
sh './configure || true'
|
sh './configure'
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Make') {
|
stage('Make') {
|
||||||
/* `make check` returns non-zero on test failures,
|
/* `make check` returns non-zero on test failures,
|
||||||
* using `true` to allow the Pipeline to continue nonetheless
|
* using `true` to allow the Pipeline to continue nonetheless
|
||||||
*/
|
*/
|
||||||
sh 'make || true'
|
sh 'make'
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Testing') {
|
stage('Testing') {
|
||||||
|
|
|
||||||
22
test/lib.sh
22
test/lib.sh
|
|
@ -36,10 +36,11 @@ err(){
|
||||||
if [ $# -gt 1 ]; then
|
if [ $# -gt 1 ]; then
|
||||||
echo "Received: $2"
|
echo "Received: $2"
|
||||||
fi
|
fi
|
||||||
echo -e "\e[0m:"
|
echo -e "\e[0m"
|
||||||
echo "$ret"| od -t c > $dir/clixon-ret
|
echo "$ret"| od -t c > $dir/clixon-ret
|
||||||
echo "$expect"| od -t c > $dir/clixon-expect
|
echo "$expect"| od -t c > $dir/clixon-expect
|
||||||
diff $dir/clixon-ret $dir/clixon-expect
|
diff $dir/clixon-ret $dir/clixon-expect
|
||||||
|
|
||||||
exit $testnr
|
exit $testnr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,18 +111,29 @@ expecteq(){
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# clixon tester. First arg is command second is stdin and
|
# Pipe stdin to command
|
||||||
# third is expected outcome
|
# Arguments:
|
||||||
|
# - Command
|
||||||
|
# - expected command return value (0 if OK)
|
||||||
|
# - stdin input
|
||||||
|
# - expected stdout outcome
|
||||||
expecteof(){
|
expecteof(){
|
||||||
cmd=$1
|
cmd=$1
|
||||||
input=$2
|
retval=$2
|
||||||
expect=$3
|
input=$3
|
||||||
|
expect=$4
|
||||||
|
|
||||||
# Do while read stuff
|
# Do while read stuff
|
||||||
ret=$($cmd<<EOF
|
ret=$($cmd<<EOF
|
||||||
$input
|
$input
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
if [ $? -ne $retval ]; then
|
||||||
|
echo -e "\e[31m\nError in Test$testnr [$testname]:"
|
||||||
|
echo -e "\e[0m:"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
# Match if both are empty string
|
# Match if both are empty string
|
||||||
if [ -z "$ret" -a -z "$expect" ]; then
|
if [ -z "$ret" -a -z "$expect" ]; then
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -152,10 +152,10 @@ expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data)" '{"data
|
||||||
'
|
'
|
||||||
|
|
||||||
new "auth set authentication config"
|
new "auth set authentication config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "commit it"
|
new "commit it"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new2 "auth get (no user: access denied)"
|
new2 "auth get (no user: access denied)"
|
||||||
expecteq "$(curl -sS -X GET -H \"Accept:\ application/yang-data+json\" http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}}
'
|
expecteq "$(curl -sS -X GET -H \"Accept:\ application/yang-data+json\" http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}}
'
|
||||||
|
|
|
||||||
|
|
@ -120,47 +120,47 @@ if [ $? -ne 0 ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "Set crypto to aes"
|
new "Set crypto to aes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto>aes</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto>aes</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate "
|
new "netconf validate "
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to mc:aes"
|
new "Set crypto to mc:aes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto>mc:aes</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto>mc:aes</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to des:des3"
|
new "Set crypto to des:des3"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto>des:des3</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto>des:des3</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to mc:foo"
|
new "Set crypto to mc:foo"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto>mc:foo</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto>mc:foo</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to des:des3 using xmlns"
|
new "Set crypto to des:des3 using xmlns"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto xmlns:des=\"urn:example:des\">des:des3</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto xmlns:des=\"urn:example:des\">des:des3</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# XXX this is not supported
|
# XXX this is not supported
|
||||||
#new "Set crypto to x:des3 using xmlns"
|
#new "Set crypto to x:des3 using xmlns"
|
||||||
#expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto xmlns:x=\"urn:example:des\">x:des3</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
#expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto xmlns:x=\"urn:example:des\">x:des3</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#new "netconf validate"
|
#new "netconf validate"
|
||||||
#expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
#expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Set crypto to foo:bar"
|
new "Set crypto to foo:bar"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><crypto>foo:bar</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><crypto>foo:bar</crypto></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag><error-type>application</error-type><error-severity>error</error-severity><error-message>Identityref validation failed, foo:bar not derived from crypto-alg</error-message></rpc-error></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag><error-type>application</error-type><error-severity>error</error-severity><error-message>Identityref validation failed, foo:bar not derived from crypto-alg</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli set crypto to mc:aes"
|
new "cli set crypto to mc:aes"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -l o set crypto mc:aes" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o set crypto mc:aes" 0 "^$"
|
||||||
|
|
|
||||||
14
test/test_json.sh
Executable file
14
test/test_json.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Test: JSON parser tests
|
||||||
|
PROG=../lib/src/clixon_util_json
|
||||||
|
|
||||||
|
# include err() and new() functions and creates $dir
|
||||||
|
. ./lib.sh
|
||||||
|
|
||||||
|
new "json parse"
|
||||||
|
expecteof $PROG 0 '{"foo": -23}' "^<foo>-23</foo>$"
|
||||||
|
|
||||||
|
new "json parse list"
|
||||||
|
expecteof $PROG 0 '{"a":[0,1,2,3]}' "^<a>0</a><a>1</a><a>2</a><a>3</a>$"
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
@ -84,45 +84,45 @@ if [ $? -ne 0 ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "leafref base config"
|
new "leafref base config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces>
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces>
|
||||||
<interface><name>eth0</name><type>ex:eth</type> <ipv4><address><ip>192.0.2.1</ip></address><address><ip>192.0.2.2</ip></address></ipv4></interface>
|
<interface><name>eth0</name><type>ex:eth</type> <ipv4><address><ip>192.0.2.1</ip></address><address><ip>192.0.2.2</ip></address></ipv4></interface>
|
||||||
<interface><name>lo</name><type>ex:lo</type><ipv4><address><ip>127.0.0.1</ip></address></ipv4></interface>
|
<interface><name>lo</name><type>ex:lo</type><ipv4><address><ip>127.0.0.1</ip></address></ipv4></interface>
|
||||||
</interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
</interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "leafref get config"
|
new "leafref get config"
|
||||||
expecteof "$clixon_netconf -qf $cfg" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><interfaces><interface><name>eth0</name>'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><interfaces><interface><name>eth0</name>'
|
||||||
|
|
||||||
new "leafref base commit"
|
new "leafref base commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "leafref add wrong ref"
|
new "leafref add wrong ref"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><default-address><absname>eth3</absname><address>10.0.4.6</address></default-address></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><default-address><absname>eth3</absname><address>10.0.4.6</address></default-address></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "leafref validate XXX shouldnt really be operation-failed, more work in validate code"
|
new "leafref validate XXX shouldnt really be operation-failed, more work in validate code"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag>"
|
||||||
|
|
||||||
new "leafref discard-changes"
|
new "leafref discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "leafref add correct absref"
|
new "leafref add correct absref"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><default-address><absname>eth0</absname></default-address></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><default-address><absname>eth0</absname></default-address></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "leafref add correct relref"
|
new "leafref add correct relref"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><default-address><relname>eth0</relname></default-address></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><default-address><relname>eth0</relname></default-address></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# XXX add address
|
# XXX add address
|
||||||
|
|
||||||
new "leafref validate (ok)"
|
new "leafref validate (ok)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>"
|
||||||
|
|
||||||
new "leafref delete leaf"
|
new "leafref delete leaf"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation=\"delete\"><name>eth0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation=\"delete\"><name>eth0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>"
|
||||||
|
|
||||||
new "leafref validate (should fail)"
|
new "leafref validate (should fail)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>operation-failed</error-tag>"
|
||||||
|
|
||||||
new "leafref discard-changes"
|
new "leafref discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli leafref lo"
|
new "cli leafref lo"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang -l o set default-address absname lo" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -y $fyang -l o set default-address absname lo" 0 "^$"
|
||||||
|
|
|
||||||
|
|
@ -81,132 +81,132 @@ if [ $? -ne 0 ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "netconf get-config"
|
new "netconf get-config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "Add subtree eth/0/0 using none which should not change anything"
|
new "Add subtree eth/0/0 using none which should not change anything"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><default-operation>none</default-operation><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><default-operation>none</default-operation><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check nothing added"
|
new "Check nothing added"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check eth/0/0 added using xpath"
|
new "Check eth/0/0 added using xpath"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth/0/0]"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth/0/0]"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Re-create same eth/0/0 which should generate error"
|
new "Re-create same eth/0/0 which should generate error"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "Delete eth/0/0 using none config"
|
new "Delete eth/0/0 using none config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check deleted eth/0/0 (non-presence container)"
|
new "Check deleted eth/0/0 (non-presence container)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "Re-Delete eth/0/0 using none should generate error"
|
new "Re-Delete eth/0/0 using none should generate error"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf edit config"
|
new "netconf edit config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath"
|
new "netconf get config xpath"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth1</name><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth1</name><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath parent"
|
new "netconf get config xpath parent"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled/../.."/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><enabled>true</enabled></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><enabled>true</enabled><forwarding>false</forwarding><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled/../.."/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><enabled>true</enabled></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><enabled>true</enabled><forwarding>false</forwarding><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate missing type"
|
new "netconf validate missing type"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get empty config2"
|
new "netconf get empty config2"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit extra xml"
|
new "netconf edit extra xml"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><extra/></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><extra/></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit config eth1"
|
new "netconf edit config eth1"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth1</name><type>ex:eth</type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth1</name><type>ex:eth</type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit config merge"
|
new "netconf edit config merge"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth2</name><type>ex:eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth2</name><type>ex:eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit ampersand encoding(<&): name:'eth&' type:'t<>'"
|
new "netconf edit ampersand encoding(<&): name:'eth&' type:'t<>'"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth& </name><type>t< > </type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth& </name><type>t< > </type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get replaced config"
|
new "netconf get replaced config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth& </name><type>t< > </type><enabled>true</enabled></interface><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth& </name><type>t< > </type><enabled>true</enabled></interface><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli show configuration eth& - encoding tests"
|
new "cli show configuration eth& - encoding tests"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang show conf cli" 0 "interfaces interface eth& type t<>
|
expectfn "$clixon_cli -1 -f $cfg -y $fyang show conf cli" 0 "interfaces interface eth& type t<>
|
||||||
interfaces interface eth& enabled true"
|
interfaces interface eth& enabled true"
|
||||||
|
|
||||||
new "netconf edit CDATA"
|
new "netconf edit CDATA"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name><type>ex:eth</type><description><![CDATA[myeth&]]></description></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name><type>ex:eth</type><description><![CDATA[myeth&]]></description></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
#new "netconf get CDATA"
|
#new "netconf get CDATA"
|
||||||
#expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/interfaces/interface[name=eth/0/0]/description\" /></get-config></rpc>]]>]]>" "<rpc-reply><data><interfaces><interface><name>eth/0/0</name><description><![CDATA[myeth&]]></description><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>"
|
#expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/interfaces/interface[name=eth/0/0]/description\" /></get-config></rpc>]]>]]>" "<rpc-reply><data><interfaces><interface><name>eth/0/0</name><description><![CDATA[myeth&]]></description><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>"
|
||||||
|
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit state operation should fail"
|
new "netconf edit state operation should fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces-state><interface><name>eth1</name><type>ex:eth</type></interface></interfaces-state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><interfaces-state><interface><name>eth1</name><type>ex:eth</type></interface></interfaces-state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
||||||
|
|
||||||
new "netconf get state operation"
|
new "netconf get state operation"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><interfaces-state><interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface></interfaces-state></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><interfaces-state><interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface></interfaces-state></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf lock/unlock"
|
new "netconf lock/unlock"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]><rpc><unlock><target><candidate/></target></unlock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]><rpc><unlock><target><candidate/></target></unlock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf lock/lock"
|
new "netconf lock/lock"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf lock"
|
new "netconf lock"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "close-session"
|
new "close-session"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><close-session/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><close-session/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "kill-session"
|
new "kill-session"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><kill-session><session-id>44</session-id></kill-session></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><kill-session><session-id>44</session-id></kill-session></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "copy startup"
|
new "copy startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get startup"
|
new "netconf get startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf delete startup"
|
new "netconf delete startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check empty startup"
|
new "netconf check empty startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf rpc"
|
new "netconf rpc"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><rt:fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></rt:fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><rt:fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></rt:fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
||||||
|
|
||||||
new "netconf rpc w/o namespace"
|
new "netconf rpc w/o namespace"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
||||||
|
|
||||||
new "netconf empty rpc"
|
new "netconf empty rpc"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><empty/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><empty/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf client-side rpc"
|
new "netconf client-side rpc"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><ex:client-rpc><request>example</request></ex:client-rpc></rpc>]]>]]>" "^<rpc-reply><result>ok</result></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><ex:client-rpc><request>example</request></ex:client-rpc></rpc>]]>]]>" "^<rpc-reply><result>ok</result></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf subscription"
|
new "netconf subscription"
|
||||||
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
||||||
|
|
|
||||||
|
|
@ -119,53 +119,53 @@ fi
|
||||||
|
|
||||||
# Check as file
|
# Check as file
|
||||||
new "verify running from start, should be: l,c,y0,y1,y2,y3; y1 and y3 sorted. Note this fails if XML_SORT set to false"
|
new "verify running from start, should be: l,c,y0,y1,y2,y3; y1 and y3 sorted. Note this fails if XML_SORT set to false"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><c><d>hej</d></c><l>hopp</l><y0>d</y0><y0>b</y0><y0>c</y0><y0>a</y0><y1>a</y1><y1>b</y1><y1>c</y1><y1>d</y1><y2><k>d</k><a>bar</a></y2><y2><k>a</k><a>bar</a></y2><y2><k>c</k><a>bar</a></y2><y2><k>b</k><a>bar</a></y2><y3><k>a</k><a>bar</a></y3><y3><k>b</k><a>bar</a></y3><y3><k>c</k><a>bar</a></y3><y3><k>d</k><a>bar</a></y3></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><c><d>hej</d></c><l>hopp</l><y0>d</y0><y0>b</y0><y0>c</y0><y0>a</y0><y1>a</y1><y1>b</y1><y1>c</y1><y1>d</y1><y2><k>d</k><a>bar</a></y2><y2><k>a</k><a>bar</a></y2><y2><k>c</k><a>bar</a></y2><y2><k>b</k><a>bar</a></y2><y3><k>a</k><a>bar</a></y3><y3><k>b</k><a>bar</a></y3><y3><k>c</k><a>bar</a></y3><y3><k>d</k><a>bar</a></y3></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k=a]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y2><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k=a]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y2><k>a</k><a>bar</a></y2></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k=a]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y3><k>a</k><a>bar</a></y3></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k=a]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y3><k>a</k><a>bar</a></y3></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k=b]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y2><k>b</k><a>bar</a></y2></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y2[k=b]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y2><k>b</k><a>bar</a></y2></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "get each ordered-by user leaf-list"
|
new "get each ordered-by user leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k=b]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y3><k>b</k><a>bar</a></y3></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y3[k=b]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y3><k>b</k><a>bar</a></y3></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "delete candidate"
|
new "delete candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><delete-config><target><candidate/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><delete-config><target><candidate/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# LEAF_LISTS
|
# LEAF_LISTS
|
||||||
|
|
||||||
new "add two entries to leaf-list user order"
|
new "add two entries to leaf-list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><y0>c</y0><y0>b</y0></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><y0>c</y0><y0>b</y0></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry to leaf-list user order"
|
new "add one entry to leaf-list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><y0>a</y0></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><y0>a</y0></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry to leaf-list user order after commit"
|
new "add one entry to leaf-list user order after commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><y0>0</y0></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><y0>0</y0></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "verify leaf-list user order in running (as entered)"
|
new "verify leaf-list user order in running (as entered)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y0\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y0>c</y0><y0>b</y0><y0>a</y0><y0>0</y0></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><running/></source><filter type=\"xpath\" select=\"/y0\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y0>c</y0><y0>b</y0><y0>a</y0><y0>0</y0></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# LISTS
|
# LISTS
|
||||||
|
|
||||||
new "add two entries to list user order"
|
new "add two entries to list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><y2><k>c</k><a>bar</a></y2><y2><k>b</k><a>foo</a></y2></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><y2><k>c</k><a>bar</a></y2><y2><k>b</k><a>foo</a></y2></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry to list user order"
|
new "add one entry to list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><y2><k>a</k><a>fie</a></y2></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><y2><k>a</k><a>fie</a></y2></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "verify list user order (as entered)"
|
new "verify list user order (as entered)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/y2\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y2><k>c</k><a>bar</a></y2><y2><k>b</k><a>foo</a></y2><y2><k>a</k><a>fie</a></y2></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/y2\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><y2><k>c</k><a>bar</a></y2><y2><k>b</k><a>foo</a></y2><y2><k>a</k><a>fie</a></y2></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
pid=`pgrep clixon_backend`
|
pid=`pgrep clixon_backend`
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
|
|
|
||||||
|
|
@ -99,13 +99,13 @@ expecteof_file "time -f %e $clixon_netconf -qf $cfg -y $fyang" "$fconfig" "^<rpc
|
||||||
rm $fconfig
|
rm $fconfig
|
||||||
|
|
||||||
new "netconf commit large config"
|
new "netconf commit large config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit large config again"
|
new "netconf commit large config again"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf add small (1 entry) config"
|
new "netconf add small (1 entry) config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>x</a><b>y</b></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>x</a><b>y</b></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get $req small config"
|
new "netconf get $req small config"
|
||||||
time -p for (( i=0; i<$req; i++ )); do
|
time -p for (( i=0; i<$req; i++ )); do
|
||||||
|
|
@ -132,7 +132,7 @@ time -p for (( i=0; i<$req; i++ )); do
|
||||||
done
|
done
|
||||||
|
|
||||||
new "netconf get large config"
|
new "netconf get large config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>0</a><b>0</b></y><y><a>1</a><b>1</b>"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>0</a><b>0</b></y><y><a>1</a><b>1</b>"
|
||||||
|
|
||||||
new "generate large leaf-list config"
|
new "generate large leaf-list config"
|
||||||
echo -n "<rpc><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><x>" > $fconfig
|
echo -n "<rpc><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><x>" > $fconfig
|
||||||
|
|
@ -147,7 +147,7 @@ expecteof_file "time -f %e $clixon_netconf -qf $cfg -y $fyang" "$fconfig" "^<rpc
|
||||||
rm $fconfig
|
rm $fconfig
|
||||||
|
|
||||||
new "netconf commit large leaf-list config"
|
new "netconf commit large leaf-list config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf add $req small leaf-list config"
|
new "netconf add $req small leaf-list config"
|
||||||
time -p for (( i=0; i<$req; i++ )); do
|
time -p for (( i=0; i<$req; i++ )); do
|
||||||
|
|
@ -156,13 +156,13 @@ time -p for (( i=0; i<$req; i++ )); do
|
||||||
done | $clixon_netconf -qf $cfg -y $fyang > /dev/null
|
done | $clixon_netconf -qf $cfg -y $fyang > /dev/null
|
||||||
|
|
||||||
new "netconf add small leaf-list config"
|
new "netconf add small leaf-list config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><c>x</c></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><c>x</c></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit small leaf-list config"
|
new "netconf commit small leaf-list config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit><source><candidate/></source></commit></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get large leaf-list config"
|
new "netconf get large leaf-list config"
|
||||||
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><c>0</c><c>1</c>"
|
expecteof "time -f %e $clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><c>0</c><c>1</c>"
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if still alive
|
# Check if still alive
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "Check $mode"
|
new "Check $mode"
|
||||||
expecteof "$clixon_netconf -qf $cfg" '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>' "^<rpc-reply>$expect</rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if still alive
|
# Check if still alive
|
||||||
|
|
|
||||||
|
|
@ -171,19 +171,19 @@ new "cli commit"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang -l o commit" 0 "^$"
|
||||||
|
|
||||||
new "netconf validate ok"
|
new "netconf validate ok"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf set ab wrong"
|
new "netconf set ab wrong"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><list><ip>a.b& c.d</ip></list></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><list><ip>a.b& c.d</ip></list></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli enum value"
|
new "cli enum value"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set status down" 0 "^$"
|
||||||
|
|
@ -196,7 +196,7 @@ expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits create" 0 "^$"
|
||||||
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 "^$"
|
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set mbits \"create read\"" 0 "^$"
|
||||||
|
|
||||||
new "netconf bits two values"
|
new "netconf bits two values"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><mbits>create read</mbits></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><mbits>create read</mbits></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli bits validate"
|
new "cli bits validate"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$"
|
||||||
|
|
|
||||||
46
test/test_xml.sh
Executable file
46
test/test_xml.sh
Executable file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Test: XML parser tests
|
||||||
|
PROG=../lib/src/clixon_util_xml
|
||||||
|
|
||||||
|
# include err() and new() functions and creates $dir
|
||||||
|
. ./lib.sh
|
||||||
|
|
||||||
|
new "xml parse"
|
||||||
|
expecteof $PROG 0 "<a><b/></a>" "^<a><b/></a>$"
|
||||||
|
|
||||||
|
XML=$(cat <<EOF
|
||||||
|
<a><description>An example of escaped CENDs</description>
|
||||||
|
<sometext>
|
||||||
|
<![CDATA[ They're saying "x < y" & that "z > y" so I guess that means that z > x ]]>
|
||||||
|
</sometext>
|
||||||
|
<!-- This text contains a CEND ]]> -->
|
||||||
|
<!-- In this first case we put the ]] at the end of the first CDATA block
|
||||||
|
and the > in the second CDATA block -->
|
||||||
|
<data><![CDATA[This text contains a CEND ]]]]><![CDATA[>]]></data>
|
||||||
|
<!-- In this second case we put a ] at the end of the first CDATA block
|
||||||
|
and the ]> in the second CDATA block -->
|
||||||
|
<alternative><![CDATA[This text contains a CEND ]]]><![CDATA[]>]]></alternative>
|
||||||
|
</a>
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
new "xml CDATA"
|
||||||
|
expecteof $PROG 0 "$XML" "^<a><description>An example of escaped CENDs</description><sometext>
|
||||||
|
<![CDATA[ They're saying \"x < y\" & that \"z > y\" so I guess that means that z > x ]]>
|
||||||
|
</sometext><data><![CDATA[This text contains a CEND ]]]]><![CDATA[>]]></data><alternative><![CDATA[This text contains a CEND ]]]><![CDATA[]>]]></alternative></a>$"
|
||||||
|
|
||||||
|
XML=$(cat <<EOF
|
||||||
|
<message>Less than: < , greater than: > ampersand: & </message>
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
new "xml encode <>&"
|
||||||
|
expecteof $PROG 0 "$XML" "^$XML$"
|
||||||
|
|
||||||
|
XML=$(cat <<EOF
|
||||||
|
<message>To allow attribute values to contain both single and double quotes, the apostrophe or single-quote character ' may be represented as ' and the double-quote character as " </message>
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
new "xml optional encode single and double quote"
|
||||||
|
expecteof $PROG 0 "$XML" "^<message>To allow attribute values to contain both single and double quotes, the apostrophe or single-quote character ' may be represented as ' and the double-quote character as \"</message>$"
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
||||||
12
test/test_xsl.sh
Executable file
12
test/test_xsl.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Test: XSL tests
|
||||||
|
PROG=../lib/src/clixon_util_xsl
|
||||||
|
|
||||||
|
# include err() and new() functions and creates $dir
|
||||||
|
. ./lib.sh
|
||||||
|
|
||||||
|
new "xsl test"
|
||||||
|
expecteof $PROG 0 "a
|
||||||
|
<a><b/></a>" "^0:<a><b/></a>$"
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
@ -118,29 +118,29 @@ new "cli not defined extension"
|
||||||
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" 0 "Yang error: Extension ex:not-defined not found"
|
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" 0 "Yang error: Extension ex:not-defined not found"
|
||||||
|
|
||||||
new "netconf edit config"
|
new "netconf edit config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# text empty type in running
|
# text empty type in running
|
||||||
new "netconf commit 2nd"
|
new "netconf commit 2nd"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath"
|
new "netconf get config xpath"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/y[a=1][b=2][c=5]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/y[a=1][b=2][c=5]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit leaf-list"
|
new "netconf edit leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><f><e>hej</e><e>hopp</e></f></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><f><e>hej</e><e>hopp</e></f></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get leaf-list"
|
new "netconf get leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f/e\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f/e\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get leaf-list path"
|
new "netconf get leaf-list path"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e=hej]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e=hej]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get (should be some)"
|
new "netconf get (should be some)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli set leaf-list"
|
new "cli set leaf-list"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" 0 ""
|
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" 0 ""
|
||||||
|
|
@ -148,50 +148,50 @@ expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" 0 ""
|
||||||
new "cli show leaf-list"
|
new "cli show leaf-list"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang show xpath /x/f/e" 0 "<e>foo</e>"
|
expectfn "$clixon_cli -1f $cfg -y $fyang show xpath /x/f/e" 0 "<e>foo</e>"
|
||||||
new "netconf set state data (not allowed)"
|
new "netconf set state data (not allowed)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><state><op>42</op></state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><state><op>42</op></state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value"
|
||||||
|
|
||||||
new "netconf set presence and not present"
|
new "netconf set presence and not present"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><nopresence/><presence/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><nopresence/><presence/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get presence only"
|
new "netconf get presence only"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/*presence"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><x><presence/></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/x/*presence"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><x><presence/></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf anyxml"
|
new "netconf anyxml"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><any><foo><bar a=\"nisse\"/></foo></any></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><any><foo><bar a=\"nisse\"/></foo></any></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate anyxml"
|
new "netconf validate anyxml"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf delete candidate"
|
new "netconf delete candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><delete-config><target><candidate/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><delete-config><target><candidate/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# Check 3-keys
|
# Check 3-keys
|
||||||
new "netconf add one 3-key entry"
|
new "netconf add one 3-key entry"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check add one 3-key"
|
new "netconf check add one 3-key"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf add another (with same 1st key)"
|
new "netconf add another (with same 1st key)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check add another"
|
new "netconf check add another"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf replace first"
|
new "netconf replace first"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>1</b><c>1</c><val>replace</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>1</b><c>1</c><val>replace</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check replace"
|
new "netconf check replace"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>replace</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>replace</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "netconf delete first"
|
new "netconf delete first"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><edit-config><target><candidate/></target><config><x><y operation="remove"><a>1</a><b>1</b><c>1</c></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><x><y operation="remove"><a>1</a><b>1</b><c>1</c></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check delete"
|
new "netconf check delete"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
# Check if still alive
|
# Check if still alive
|
||||||
pid=`pgrep clixon_backend`
|
pid=`pgrep clixon_backend`
|
||||||
|
|
|
||||||
24
test/test_yang_parse.sh
Executable file
24
test/test_yang_parse.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Test: XML parser tests
|
||||||
|
PROG=../lib/src/clixon_util_yang
|
||||||
|
|
||||||
|
# include err() and new() functions and creates $dir
|
||||||
|
. ./lib.sh
|
||||||
|
|
||||||
|
YANG=$(cat <<EOF
|
||||||
|
module test{
|
||||||
|
prefix ex;
|
||||||
|
extension c-define {
|
||||||
|
description "Example from RFC 6020";
|
||||||
|
argument "name";
|
||||||
|
}
|
||||||
|
ex:not-defined ARGUMENT;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
new "yang parse"
|
||||||
|
expecteof $PROG 0 "$YANG" "^$YANG$"
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue