Changed plugin_init() backend return semantics: If returns NULL, _without_ calling clicon_err(), the module is disabled.
Also, example documentation corrected according to: https://github.com/clicon/clixon/issues/33
This commit is contained in:
parent
60ce7b12bd
commit
ee946a00f5
7 changed files with 52 additions and 17 deletions
|
|
@ -9,7 +9,8 @@
|
||||||
* 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
|
* Changed `plugin_init()` backend return semantics: If returns NULL, _without_ calling clicon_err(), the module is disabled.
|
||||||
|
* Dedicated standalone xml,json,yang and xsl parser utility test programs added under lib/src/.
|
||||||
* 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
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ routing example. It contains the following files:
|
||||||
```
|
```
|
||||||
Start backend:
|
Start backend:
|
||||||
```
|
```
|
||||||
clixon_backend -f /usr/local/etc/example.xml -I
|
sudo clixon_backend -f /usr/local/etc/example.xml -s init
|
||||||
```
|
```
|
||||||
Edit cli:
|
Edit cli:
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,13 @@ static clixon_plugin_api api = {
|
||||||
clixon_plugin_api *
|
clixon_plugin_api *
|
||||||
clixon_plugin_init(clicon_handle h)
|
clixon_plugin_init(clicon_handle h)
|
||||||
{
|
{
|
||||||
|
char *nacm_mode;
|
||||||
|
|
||||||
clicon_debug(1, "%s backend nacm", __FUNCTION__);
|
clicon_debug(1, "%s backend nacm", __FUNCTION__);
|
||||||
|
nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE");
|
||||||
|
if (nacm_mode==NULL || strcmp(nacm_mode, "disabled") == 0){
|
||||||
|
clicon_debug(1, "%s CLICON_NACM_MODE not enabled: example nacm module disabled", __FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return &api;
|
return &api;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,9 @@
|
||||||
/*
|
/*
|
||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
/* Hardcoded plugin symbol. Must exist in all plugins to kickstart */
|
/* Hardcoded plugin symbol. Must exist in all plugins to kickstart
|
||||||
|
* @see clixon_plugin_init
|
||||||
|
*/
|
||||||
#define CLIXON_PLUGIN_INIT "clixon_plugin_init"
|
#define CLIXON_PLUGIN_INIT "clixon_plugin_init"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -181,6 +183,7 @@ typedef struct clixon_plugin clixon_plugin;
|
||||||
/*! Plugin initialization function. Must appear in all plugins
|
/*! Plugin initialization function. Must appear in all plugins
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @retval api Pointer to API struct
|
* @retval api Pointer to API struct
|
||||||
|
* @retval NULL Failure (if clixon_err() called), module disabled otherwise.
|
||||||
* @see CLIXON_PLUGIN_INIT default symbol
|
* @see CLIXON_PLUGIN_INIT default symbol
|
||||||
*/
|
*/
|
||||||
clixon_plugin_api *clixon_plugin_init(clicon_handle h);
|
clixon_plugin_api *clixon_plugin_init(clicon_handle h);
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
@ -204,12 +205,16 @@ plugin_load_one(clicon_handle h,
|
||||||
clicon_err(OE_UNIX, 0, "dlsym: %s: %s", file, error);
|
clicon_err(OE_UNIX, 0, "dlsym: %s: %s", file, error);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
clicon_err_reset();
|
||||||
if ((api = initfn(h)) == NULL) {
|
if ((api = initfn(h)) == NULL) {
|
||||||
clicon_err(OE_PLUGIN, errno, "Failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
|
if (!clicon_errno){ /* if clicon_err() is not called then log and continue */
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
clicon_log(LOG_WARNING, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
|
||||||
clicon_err(OE_DB, 0, "Unknown error: %s: plugin_init does not make clicon_err call on error",
|
dlclose(handle);
|
||||||
file);
|
}
|
||||||
goto err;
|
else{
|
||||||
|
clicon_err(OE_PLUGIN, errno, "Failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */
|
/* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */
|
||||||
if ((cp = (clixon_plugin *)malloc(sizeof(struct clixon_plugin))) == NULL){
|
if ((cp = (clixon_plugin *)malloc(sizeof(struct clixon_plugin))) == NULL){
|
||||||
|
|
@ -228,7 +233,8 @@ plugin_load_one(clicon_handle h,
|
||||||
|
|
||||||
snprintf(cp->cp_name, sizeof(cp->cp_name), "%*s",
|
snprintf(cp->cp_name, sizeof(cp->cp_name), "%*s",
|
||||||
(int)strlen(name), name);
|
(int)strlen(name), name);
|
||||||
cp->cp_api = *api;
|
if (api)
|
||||||
|
cp->cp_api = *api;
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
done:
|
done:
|
||||||
return cp;
|
return cp;
|
||||||
|
|
|
||||||
|
|
@ -1487,8 +1487,6 @@ int
|
||||||
xml_copy_one(cxobj *x0,
|
xml_copy_one(cxobj *x0,
|
||||||
cxobj *x1)
|
cxobj *x1)
|
||||||
{
|
{
|
||||||
cg_var *cv1;
|
|
||||||
|
|
||||||
xml_type_set(x1, xml_type(x0));
|
xml_type_set(x1, xml_type(x0));
|
||||||
if (xml_value(x0)){ /* malloced string */
|
if (xml_value(x0)){ /* malloced string */
|
||||||
if ((x1->x_value = strdup(x0->x_value)) == NULL){
|
if ((x1->x_value = strdup(x0->x_value)) == NULL){
|
||||||
|
|
|
||||||
|
|
@ -1715,6 +1715,7 @@ xml_merge1(cxobj *x0,
|
||||||
cxobj *x1c; /* mod child */
|
cxobj *x1c; /* mod child */
|
||||||
char *x1bstr; /* mod body string */
|
char *x1bstr; /* mod body string */
|
||||||
yang_stmt *yc; /* yang child */
|
yang_stmt *yc; /* yang child */
|
||||||
|
cbuf *cbr = NULL; /* Reason buffer */
|
||||||
|
|
||||||
assert(x1 && xml_type(x1) == CX_ELMNT);
|
assert(x1 && xml_type(x1) == CX_ELMNT);
|
||||||
assert(y0);
|
assert(y0);
|
||||||
|
|
@ -1753,9 +1754,16 @@ xml_merge1(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_datanode(y0, x1cname)) == NULL){
|
if ((yc = yang_find_datanode(y0, x1cname)) == NULL){
|
||||||
if (reason && (*reason = strdup("XML node has no corresponding yang specification (Invalid XML or wrong Yang spec?")) == NULL){
|
if (reason){
|
||||||
clicon_err(OE_UNIX, errno, "strdup");
|
if ((cbr = cbuf_new()) == NULL){
|
||||||
goto done;
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cbr, "XML node %s/%s has no corresponding yang specification (Invalid XML or wrong Yang spec?", xml_name(x1), x1cname);
|
||||||
|
if ((*reason = strdup(cbuf_get(cbr))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1772,6 +1780,8 @@ xml_merge1(cxobj *x0,
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (cbr)
|
||||||
|
cbuf_free(cbr);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1797,6 +1807,7 @@ xml_merge(cxobj *x0,
|
||||||
cxobj *x0c; /* base child */
|
cxobj *x0c; /* base child */
|
||||||
cxobj *x1c; /* mod child */
|
cxobj *x1c; /* mod child */
|
||||||
yang_stmt *yc;
|
yang_stmt *yc;
|
||||||
|
cbuf *cbr = NULL; /* Reason buffer */
|
||||||
|
|
||||||
/* Loop through children of the modification tree */
|
/* Loop through children of the modification tree */
|
||||||
x1c = NULL;
|
x1c = NULL;
|
||||||
|
|
@ -1804,9 +1815,16 @@ xml_merge(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){
|
||||||
if (reason && (*reason = strdup("XML node has no corresponding yang specification (Invalid XML or wrong Yang spec?")) == NULL){
|
if (reason){
|
||||||
clicon_err(OE_UNIX, errno, "strdup");
|
if ((cbr = cbuf_new()) == NULL){
|
||||||
goto done;
|
clicon_err(OE_XML, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cbr, "XML node %s/%s has no corresponding yang specification (Invalid XML or wrong Yang spec?", xml_name(x1), x1cname);
|
||||||
|
if ((*reason = strdup(cbuf_get(cbr))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1820,6 +1838,8 @@ xml_merge(cxobj *x0,
|
||||||
}
|
}
|
||||||
retval = 0; /* OK */
|
retval = 0; /* OK */
|
||||||
done:
|
done:
|
||||||
|
if (cbr)
|
||||||
|
cbuf_free(cbr);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue