Merge branch 'develop' of https://github.com/clicon/clixon into develop

This commit is contained in:
Olof hagsand 2018-07-16 16:18:36 +02:00
commit 5d7c4a8d18
14 changed files with 203 additions and 46 deletions

View file

@ -43,6 +43,7 @@
#include <errno.h>
#include <dlfcn.h>
#include <dirent.h>
#include <syslog.h>
#include <sys/stat.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);
goto done;
}
clicon_err_reset();
if ((api = initfn(h)) == NULL) {
clicon_err(OE_PLUGIN, errno, "Failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
clicon_err(OE_DB, 0, "Unknown error: %s: plugin_init does not make clicon_err call on error",
file);
goto err;
if (!clicon_errno){ /* if clicon_err() is not called then log and continue */
clicon_log(LOG_WARNING, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
dlclose(handle);
}
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 */
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",
(int)strlen(name), name);
cp->cp_api = *api;
if (api)
cp->cp_api = *api;
clicon_debug(1, "%s", __FUNCTION__);
done:
return cp;

View file

@ -1725,6 +1725,7 @@ xml_merge1(cxobj *x0,
cxobj *x1c; /* mod child */
char *x1bstr; /* mod body string */
yang_stmt *yc; /* yang child */
cbuf *cbr = NULL; /* Reason buffer */
assert(x1 && xml_type(x1) == CX_ELMNT);
assert(y0);
@ -1763,9 +1764,16 @@ xml_merge1(cxobj *x0,
x1cname = xml_name(x1c);
/* Get yang spec of the child */
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){
clicon_err(OE_UNIX, errno, "strdup");
goto done;
if (reason){
if ((cbr = cbuf_new()) == NULL){
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;
}
@ -1782,6 +1790,8 @@ xml_merge1(cxobj *x0,
ok:
retval = 0;
done:
if (cbr)
cbuf_free(cbr);
return retval;
}
@ -1807,6 +1817,7 @@ xml_merge(cxobj *x0,
cxobj *x0c; /* base child */
cxobj *x1c; /* mod child */
yang_stmt *yc;
cbuf *cbr = NULL; /* Reason buffer */
/* Loop through children of the modification tree */
x1c = NULL;
@ -1814,9 +1825,16 @@ xml_merge(cxobj *x0,
x1cname = xml_name(x1c);
/* Get yang spec of the child */
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){
clicon_err(OE_UNIX, errno, "strdup");
goto done;
if (reason){
if ((cbr = cbuf_new()) == NULL){
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;
}
@ -1830,6 +1848,8 @@ xml_merge(cxobj *x0,
}
retval = 0; /* OK */
done:
if (cbr)
cbuf_free(cbr);
return retval;
}

View file

@ -611,8 +611,8 @@ yang_find_schemanode(yang_node *yn,
/*! Find first matching data node in all (sub)modules in a yang spec
*
* @param[in] ysp Yang specification
* @param[in] argument if NULL, match any(first) argument. XXX is that really a case?
* @param[in] schemanode If set look for schema nodes, otherwise only data nodes
* @param[in] argument Name of node. If NULL match first
* @param[in] class See yang_class for class of yang nodes
* A yang specification has modules as children which in turn can have
* syntax-nodes as children. This function goes through all the modules to
* look for nodes. Note that if a child to a module is a choice,
@ -803,7 +803,7 @@ yarg_id(yang_stmt *ys)
return id;
}
/* Assume argument is id on the type: <[prefix:]id>, return 'prefix'
/*! Assume argument is id on the type: <[prefix:]id>, return 'prefix'
* @param[in] ys A yang statement
* @retval NULL No prefix
* @retval prefix Malloced string that needs to be freed by caller.
@ -822,6 +822,46 @@ yarg_prefix(yang_stmt *ys)
return prefix;
}
/*! Split yang node identifier into prefix and identifer.
* @param[in] node-id
* @param[out] prefix Malloced string. May be NULL.
* @param[out] id Malloced identifier.
* @retval 0 OK
* @retval -1 Error
* @note caller need to free id and prefix after use
*/
int
yang_nodeid_split(char *nodeid,
char **prefix,
char **id)
{
int retval = -1;
char *str;
if ((str = strchr(nodeid, ':')) == NULL){
if ((*id = strdup(nodeid)) == NULL){
clicon_err(OE_YANG, errno, "strdup");
goto done;
}
}
else{
if ((*prefix = strdup(nodeid)) == NULL){
clicon_err(OE_YANG, errno, "strdup");
goto done;
}
(*prefix)[str-nodeid] = '\0';
str++;
if ((*id = strdup(str)) == NULL){
clicon_err(OE_YANG, errno, "strdup");
goto done;
}
}
retval = 0;
done:
return retval;
}
/*! Given a yang statement and a prefix, return yang module to that prefix
* Note, not the other module but the proxy import statement only
* @param[in] ys A yang statement