* ietf-netconf yang module added with candidate, validate, startup and xpath features enabled.
* Added urn:ietf:params:netconf:capability:yang-library:1.0 * Thanks SCadilhac for helping out, see https://github.com/clicon/clixon/issues/39 * uri_percent_encode() and xml_chardata_encode() changed to use stdarg parameters
This commit is contained in:
parent
7046925fc3
commit
40cda7b6a4
19 changed files with 245 additions and 93 deletions
|
|
@ -86,7 +86,7 @@ netconf_in_use(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -125,7 +125,7 @@ netconf_invalid_value(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -165,7 +165,7 @@ netconf_too_big(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -207,7 +207,7 @@ netconf_missing_attribute(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -248,7 +248,7 @@ netconf_bad_attribute(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -290,7 +290,7 @@ netconf_unknown_attribute(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -332,7 +332,7 @@ netconf_missing_element(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -375,7 +375,7 @@ netconf_bad_element(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -417,7 +417,7 @@ netconf_unknown_element(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -459,7 +459,7 @@ netconf_unknown_namespace(cbuf *cb,
|
|||
type, info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -498,7 +498,7 @@ netconf_access_denied(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -574,7 +574,7 @@ netconf_lock_denied(cbuf *cb,
|
|||
info) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -613,7 +613,7 @@ netconf_resource_denied(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -653,7 +653,7 @@ netconf_rollback_failed(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -691,7 +691,7 @@ netconf_data_exists(cbuf *cb,
|
|||
"<error-severity>error</error-severity>") <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -729,7 +729,7 @@ netconf_data_missing(cbuf *cb,
|
|||
"<error-severity>error</error-severity>") <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -769,7 +769,7 @@ netconf_operation_not_supported(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -809,7 +809,7 @@ netconf_operation_failed(cbuf *cb,
|
|||
type) <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -884,7 +884,7 @@ netconf_malformed_message(cbuf *cb,
|
|||
"<error-severity>error</error-severity>") <0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
|
|
@ -970,3 +970,40 @@ netconf_trymerge(cxobj *x,
|
|||
free(reason);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Load ietf netconf yang module and set enabled features
|
||||
* The features added are:
|
||||
* candidate (8.3)
|
||||
* validate (8.6)
|
||||
* startup (8.7)
|
||||
* xpath (8.9)
|
||||
*/
|
||||
int
|
||||
netconf_module_load(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xc;
|
||||
// cxobj *x;
|
||||
yang_spec *yspec;
|
||||
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
/* Load yang spec */
|
||||
if (yang_spec_parse_module(h, "ietf-netconf", CLIXON_DATADIR, NULL, yspec)< 0)
|
||||
goto done;
|
||||
if ((xc = clicon_conf_xml(h)) == NULL){
|
||||
clicon_err(OE_CFG, ENOENT, "Clicon configuration not loaded");
|
||||
goto done;
|
||||
}
|
||||
/* Enable features (hardcoded here) */
|
||||
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:candidate</CLICON_FEATURE>", yspec, &xc) < 0)
|
||||
goto done;
|
||||
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:validate</CLICON_FEATURE>", yspec, &xc) < 0)
|
||||
goto done;
|
||||
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>", yspec, &xc) < 0)
|
||||
goto done;
|
||||
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:xpath</CLICON_FEATURE>", yspec, &xc) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,8 +249,10 @@ clicon_options_main(clicon_handle h)
|
|||
xml_child_sort = 0;
|
||||
retval = 0;
|
||||
done:
|
||||
if (yspec) /* The clixon yang-spec is not used after this */
|
||||
#if 0 /* XXX yspec should be part of top-level yang but cant since it will be main module */
|
||||
if (yspec)
|
||||
yspec_free(yspec);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -589,6 +591,7 @@ clicon_dbspec_yang_set(clicon_handle h,
|
|||
|
||||
/*! Get YANG specification for Clixon system options and features
|
||||
* Must use hash functions directly since they are not strings.
|
||||
* Example: features are typically accessed directly in the config tree.
|
||||
*/
|
||||
cxobj *
|
||||
clicon_conf_xml(clicon_handle h)
|
||||
|
|
|
|||
|
|
@ -174,49 +174,77 @@ uri_unreserved(unsigned char in)
|
|||
}
|
||||
|
||||
/*! Percent encoding according to RFC 3986 URI Syntax
|
||||
* @param[in] str Not-encoded input string
|
||||
* @param[out] escp Encoded/escaped malloced output string
|
||||
* @param[out] encp Encoded malloced output string
|
||||
* @param[in] fmt Not-encoded input string (stdarg format string)
|
||||
* @param[in] ... stdarg variable parameters
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @code
|
||||
* char *enc;
|
||||
* if (uri_percent_encode(&enc, "formatstr: <>= %s", "substr<>") < 0)
|
||||
* err;
|
||||
* if(enc)
|
||||
* free(enc);
|
||||
* @endcode
|
||||
* @see RFC 3986 Uniform Resource Identifier (URI): Generic Syntax
|
||||
* @see uri_percent_decode
|
||||
* @see xml_chardata_encode
|
||||
*/
|
||||
int
|
||||
uri_percent_encode(char *str,
|
||||
char **escp)
|
||||
uri_percent_encode(char **encp,
|
||||
char *fmt, ...)
|
||||
{
|
||||
int retval = -1;
|
||||
char *esc = NULL;
|
||||
int len;
|
||||
int i, j;
|
||||
|
||||
int retval = -1;
|
||||
char *str = NULL; /* Expanded format string w stdarg */
|
||||
char *enc = NULL;
|
||||
int fmtlen;
|
||||
int len;
|
||||
int i, j;
|
||||
va_list args;
|
||||
|
||||
/* Two steps: (1) read in the complete format string */
|
||||
va_start(args, fmt); /* dryrun */
|
||||
fmtlen = vsnprintf(NULL, 0, fmt, args) + 1;
|
||||
va_end(args);
|
||||
if ((str = malloc(fmtlen)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(str, 0, fmtlen);
|
||||
va_start(args, fmt); /* real */
|
||||
fmtlen = vsnprintf(str, fmtlen, fmt, args) + 1;
|
||||
va_end(args);
|
||||
/* Now str is the combined fmt + ... */
|
||||
|
||||
/* Step (2) encode and expand str --> enc */
|
||||
/* This is max */
|
||||
len = strlen(str)*3+1;
|
||||
if ((esc = malloc(len)) == NULL){
|
||||
if ((enc = malloc(len)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(esc, 0, len);
|
||||
memset(enc, 0, len);
|
||||
j = 0;
|
||||
for (i=0; i<strlen(str); i++){
|
||||
if (uri_unreserved(str[i]))
|
||||
esc[j++] = str[i];
|
||||
enc[j++] = str[i];
|
||||
else{
|
||||
snprintf(&esc[j], 4, "%%%02X", str[i]&0xff);
|
||||
snprintf(&enc[j], 4, "%%%02X", str[i]&0xff);
|
||||
j += 3;
|
||||
}
|
||||
}
|
||||
*escp = esc;
|
||||
*encp = enc;
|
||||
retval = 0;
|
||||
done:
|
||||
if (retval < 0 && esc)
|
||||
free(esc);
|
||||
if (str)
|
||||
free(str);
|
||||
if (retval < 0 && enc)
|
||||
free(enc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Percent decoding according to RFC 3986 URI Syntax
|
||||
* @param[in] esc Escaped/encoded input string
|
||||
* @param[in] enc Encoded input string
|
||||
* @param[out] strp Decoded malloced output string. Deallocate with free()
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
|
|
@ -224,7 +252,7 @@ uri_percent_encode(char *str,
|
|||
* @see uri_percent_encode
|
||||
*/
|
||||
int
|
||||
uri_percent_decode(char *esc,
|
||||
uri_percent_decode(char *enc,
|
||||
char **strp)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -235,24 +263,24 @@ uri_percent_decode(char *esc,
|
|||
char *ptr;
|
||||
|
||||
/* This is max */
|
||||
len = strlen(esc)+1;
|
||||
len = strlen(enc)+1;
|
||||
if ((str = malloc(len)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(str, 0, len);
|
||||
j = 0;
|
||||
for (i=0; i<strlen(esc); i++){
|
||||
if (esc[i] == '%' && strlen(esc)-i > 2 &&
|
||||
isxdigit(esc[i+1]) && isxdigit(esc[i+2])){
|
||||
hstr[0] = esc[i+1];
|
||||
hstr[1] = esc[i+2];
|
||||
for (i=0; i<strlen(enc); i++){
|
||||
if (enc[i] == '%' && strlen(enc)-i > 2 &&
|
||||
isxdigit(enc[i+1]) && isxdigit(enc[i+2])){
|
||||
hstr[0] = enc[i+1];
|
||||
hstr[1] = enc[i+2];
|
||||
hstr[2] = 0;
|
||||
str[j] = strtoul(hstr, &ptr, 16);
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
str[j] = esc[i];
|
||||
str[j] = enc[i];
|
||||
j++;
|
||||
}
|
||||
str[j++] = '\0';
|
||||
|
|
@ -265,8 +293,9 @@ uri_percent_decode(char *esc,
|
|||
}
|
||||
|
||||
/*! Escape characters according to XML definition
|
||||
* @param[in] str Not-encoded input string
|
||||
* @param[out] escp Encoded/escaped malloced output string
|
||||
* @param[out] encp Encoded malloced output string
|
||||
* @param[in] fmt Not-encoded input string (stdarg format string)
|
||||
* @param[in] ... stdarg variable parameters
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#syntax chapter 2.6
|
||||
|
|
@ -274,8 +303,7 @@ uri_percent_decode(char *esc,
|
|||
* @see AMPERSAND mode in clixon_xml_parse.l
|
||||
* @code
|
||||
* char *encstr = NULL;
|
||||
* char *val = "a<>b";
|
||||
* if (xml_chardata_encode(str, &encstr) < 0)
|
||||
* if (xml_chardata_encode(&encstr, "fmtstr<>& %s", "substr<>") < 0)
|
||||
* err;
|
||||
* if (encstr)
|
||||
* free(encstr);
|
||||
|
|
@ -289,16 +317,34 @@ uri_percent_decode(char *esc,
|
|||
* Optionally >
|
||||
*/
|
||||
int
|
||||
xml_chardata_encode(char *str,
|
||||
char **escp)
|
||||
xml_chardata_encode(char **escp,
|
||||
char *fmt,...)
|
||||
{
|
||||
int retval = -1;
|
||||
char *esc = NULL;
|
||||
int l;
|
||||
int len;
|
||||
int i, j;
|
||||
int cdata; /* when set, skip encoding */
|
||||
int retval = -1;
|
||||
char *str = NULL; /* Expanded format string w stdarg */
|
||||
int fmtlen;
|
||||
char *esc = NULL;
|
||||
int l;
|
||||
int len;
|
||||
int i, j;
|
||||
int cdata; /* when set, skip encoding */
|
||||
va_list args;
|
||||
|
||||
/* Two steps: (1) read in the complete format string */
|
||||
va_start(args, fmt); /* dryrun */
|
||||
fmtlen = vsnprintf(NULL, 0, fmt, args) + 1;
|
||||
va_end(args);
|
||||
if ((str = malloc(fmtlen)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(str, 0, fmtlen);
|
||||
va_start(args, fmt); /* real */
|
||||
fmtlen = vsnprintf(str, fmtlen, fmt, args) + 1;
|
||||
va_end(args);
|
||||
/* Now str is the combined fmt + ... */
|
||||
|
||||
/* Step (2) encode and expand str --> enc */
|
||||
/* First compute length (do nothing) */
|
||||
len = 0; cdata = 0;
|
||||
for (i=0; i<strlen(str); i++){
|
||||
|
|
@ -381,6 +427,8 @@ xml_chardata_encode(char *str,
|
|||
*escp = esc;
|
||||
retval = 0;
|
||||
done:
|
||||
if (str)
|
||||
free(str);
|
||||
if (retval < 0 && esc)
|
||||
free(esc);
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -1018,7 +1018,7 @@ clicon_xml2file(FILE *f,
|
|||
case CX_BODY:
|
||||
if ((val = xml_value(x)) == NULL) /* incomplete tree */
|
||||
break;
|
||||
if (xml_chardata_encode(val, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", val) < 0)
|
||||
goto done;
|
||||
fprintf(f, "%s", encstr);
|
||||
break;
|
||||
|
|
@ -1142,7 +1142,7 @@ clicon_xml2cbuf(cbuf *cb,
|
|||
case CX_BODY:
|
||||
if ((val = xml_value(x)) == NULL) /* incomplete tree */
|
||||
break;
|
||||
if (xml_chardata_encode(val, &encstr) < 0)
|
||||
if (xml_chardata_encode(&encstr, "%s", val) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "%s", encstr);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ api_path_fmt2api_path(char *api_path_fmt,
|
|||
clicon_err(OE_UNIX, errno, "cv2str_dup");
|
||||
goto done;
|
||||
}
|
||||
if (uri_percent_encode(str, &strenc) < 0)
|
||||
if (uri_percent_encode(&strenc, "%s", str) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "%s", strenc);
|
||||
free(strenc); strenc = NULL;
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ x +--ro namespace inet:uri
|
|||
+--ro name yang:yang-identifier
|
||||
+--ro revision union
|
||||
+--ro schema? inet:uri
|
||||
* @see netconf_create_hello
|
||||
*/
|
||||
int
|
||||
yang_modules_state_get(clicon_handle h,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue