Merge branch 'master' into feature_openconfig_compress
This commit is contained in:
commit
9d8d9ac042
43 changed files with 997 additions and 139 deletions
|
|
@ -931,16 +931,21 @@ from_client_restart_one(clicon_handle h,
|
|||
yang_stmt *yspec;
|
||||
int i;
|
||||
cxobj *xn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if (xmldb_db_reset(h, db) < 0)
|
||||
goto done;
|
||||
/* Application may define extra xml in its reset function*/
|
||||
if ((resetfn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if ((retval = resetfn(h, db)) < 0) {
|
||||
clicon_debug(1, "plugin_start() failed");
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 1. Start transaction */
|
||||
if ((td = transaction_new()) == NULL)
|
||||
|
|
@ -1021,6 +1026,8 @@ from_client_restart_one(clicon_handle h,
|
|||
goto fail;
|
||||
retval = 1;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
if (td){
|
||||
xmldb_get0_free(h, &td->td_target);
|
||||
transaction_free(td);
|
||||
|
|
|
|||
|
|
@ -284,9 +284,10 @@ get_client_statedata(clicon_handle h,
|
|||
* @param[in] h Clicon handle
|
||||
* @param[in] yspec Yang spec
|
||||
* @param[in] xret Result XML tree
|
||||
* @param[in] xvec xpath lookup result on xret
|
||||
* @param[in] xlen length of xvec
|
||||
* @param[in] xpath XPath point to object to get
|
||||
* @param[in] nsc Namespace context of xpath
|
||||
* @param[out] x1p Pointer to first matching object if any
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
|
|
@ -294,17 +295,14 @@ static int
|
|||
filter_xpath_again(clicon_handle h,
|
||||
yang_stmt *yspec,
|
||||
cxobj *xret,
|
||||
cxobj **xvec,
|
||||
size_t xlen,
|
||||
char *xpath,
|
||||
cvec *nsc,
|
||||
cxobj **x1p)
|
||||
cvec *nsc)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj **xvec = NULL;
|
||||
size_t xlen;
|
||||
int i;
|
||||
|
||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
/* If vectors are specified then mark the nodes found and
|
||||
* then filter out everything else,
|
||||
* otherwise return complete tree.
|
||||
|
|
@ -326,12 +324,8 @@ filter_xpath_again(clicon_handle h,
|
|||
/* Add default recursive values */
|
||||
if (xml_default_recurse(xret, 0) < 0)
|
||||
goto done;
|
||||
if (xlen && x1p)
|
||||
*x1p = xvec[0];
|
||||
retval = 0;
|
||||
done:
|
||||
if (xvec)
|
||||
free(xvec);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -339,6 +333,8 @@ filter_xpath_again(clicon_handle h,
|
|||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xret Result XML tree
|
||||
* @param[in] xvec xpath lookup result on xret
|
||||
* @param[in] xlen length of xvec
|
||||
* @param[in] xpath XPath point to object to get
|
||||
* @param[in] nsc Namespace context of xpath
|
||||
* @param[in] username User name for NACM access
|
||||
|
|
@ -350,6 +346,8 @@ filter_xpath_again(clicon_handle h,
|
|||
static int
|
||||
get_nacm_and_reply(clicon_handle h,
|
||||
cxobj *xret,
|
||||
cxobj **xvec,
|
||||
size_t xlen,
|
||||
char *xpath,
|
||||
cvec *nsc,
|
||||
char *username,
|
||||
|
|
@ -357,15 +355,11 @@ get_nacm_and_reply(clicon_handle h,
|
|||
cbuf *cbret)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj **xvec = NULL;
|
||||
size_t xlen;
|
||||
cxobj *xnacm = NULL;
|
||||
|
||||
/* Pre-NACM access step */
|
||||
xnacm = clicon_nacm_cache(h);
|
||||
if (xnacm != NULL){ /* Do NACM validation */
|
||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
/* NACM datanode/module read validation */
|
||||
if (nacm_datanode_read(h, xret, xvec, xlen, username, xnacm) < 0)
|
||||
goto done;
|
||||
|
|
@ -383,8 +377,6 @@ get_nacm_and_reply(clicon_handle h,
|
|||
cprintf(cbret, "</rpc-reply>");
|
||||
retval = 0;
|
||||
done:
|
||||
if (xvec)
|
||||
free(xvec);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -454,11 +446,7 @@ get_list_pagination(clicon_handle h,
|
|||
int retval = -1;
|
||||
uint32_t offset = 0;
|
||||
uint32_t limit = 0;
|
||||
char *direction = NULL;
|
||||
char *sort = NULL;
|
||||
char *where = NULL;
|
||||
cbuf *cbpath = NULL;
|
||||
cxobj *x;
|
||||
int list_config;
|
||||
yang_stmt *ylist;
|
||||
cxobj *xerr = NULL;
|
||||
|
|
@ -468,7 +456,15 @@ get_list_pagination(clicon_handle h,
|
|||
int ret;
|
||||
uint32_t iddb; /* DBs lock, if any */
|
||||
int locked;
|
||||
cxobj *x1 = NULL;
|
||||
cbuf *cberr = NULL;
|
||||
cxobj **xvec = NULL;
|
||||
size_t xlen;
|
||||
#ifdef NOTYET
|
||||
cxobj *x;
|
||||
char *direction = NULL;
|
||||
char *sort = NULL;
|
||||
char *where = NULL;
|
||||
#endif
|
||||
|
||||
/* Check if list/leaf-list */
|
||||
if (yang_path_arg(yspec, xpath, &ylist) < 0)
|
||||
|
|
@ -504,11 +500,6 @@ get_list_pagination(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
#if 0 /* XXX For now state lists are not implemenetd */
|
||||
if (netconf_operation_not_supported(cbret, "protocol", "List pagination for state lists is not yet implemented") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
#endif
|
||||
}
|
||||
/* offset */
|
||||
if ((ret = element2value(h, xe, "offset", "none", cbret, &offset)) < 0)
|
||||
|
|
@ -516,6 +507,7 @@ get_list_pagination(clicon_handle h,
|
|||
/* limit */
|
||||
if (ret && (ret = element2value(h, xe, "limit", "unbounded", cbret, &limit)) < 0)
|
||||
goto done;
|
||||
#ifdef NOTYET
|
||||
/* direction */
|
||||
if (ret && (x = xml_find_type(xe, NULL, "direction", CX_ELMNT)) != NULL){
|
||||
direction = xml_body(x);
|
||||
|
|
@ -535,7 +527,7 @@ get_list_pagination(clicon_handle h,
|
|||
/* where */
|
||||
if (ret && (x = xml_find_type(xe, NULL, "where", CX_ELMNT)) != NULL)
|
||||
where = xml_body(x);
|
||||
|
||||
#endif
|
||||
/* Read config */
|
||||
switch (content){
|
||||
case CONTENT_CONFIG: /* config data only */
|
||||
|
|
@ -553,8 +545,10 @@ get_list_pagination(clicon_handle h,
|
|||
cprintf(cbpath, "%s", xpath);
|
||||
else
|
||||
cprintf(cbpath, "/");
|
||||
#ifdef NOTYET
|
||||
if (where)
|
||||
cprintf(cbpath, "[%s]", where);
|
||||
#endif
|
||||
if (offset){
|
||||
cprintf(cbpath, "[%u <= position()", offset);
|
||||
if (limit)
|
||||
|
|
@ -607,11 +601,40 @@ get_list_pagination(clicon_handle h,
|
|||
offset, limit,
|
||||
xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
if (ret == 0){
|
||||
if ((cberr = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
/* error reason should be in clicon_err_reason */
|
||||
cprintf(cberr, "Internal error, pagination state callback invalid return : %s",
|
||||
clicon_err_reason);
|
||||
if (netconf_operation_failed_xml(&xerr, "application", cbuf_get(cberr)) < 0)
|
||||
goto done;
|
||||
if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* System makes the binding */
|
||||
if ((ret = xml_bind_yang(xret, YB_MODULE, yspec, &xerr)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
if (clicon_debug_get() && xret)
|
||||
clicon_log_xml(LOG_DEBUG, xret, "Yang bind pagination state");
|
||||
if (clixon_netconf_internal_error(xerr,
|
||||
". Internal error, state callback returned invalid XML",
|
||||
NULL) < 0)
|
||||
goto done;
|
||||
if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
/* Help function to filter out anything that is outside of xpath */
|
||||
if (filter_xpath_again(h, yspec, xret, xpath, nsc, &x1) < 0)
|
||||
if (filter_xpath_again(h, yspec, xret, xvec, xlen, xpath, nsc) < 0)
|
||||
goto done;
|
||||
#ifdef LIST_PAGINATION_REMAINING
|
||||
/* Add remaining attribute Sec 3.1.5:
|
||||
|
|
@ -639,17 +662,21 @@ get_list_pagination(clicon_handle h,
|
|||
cbuf_free(cba);
|
||||
}
|
||||
#endif /* LIST_PAGINATION_REMAINING */
|
||||
if (get_nacm_and_reply(h, xret, xpath, nsc, username, depth, cbret) < 0)
|
||||
if (get_nacm_and_reply(h, xret, xvec, xlen, xpath, nsc, username, depth, cbret) < 0)
|
||||
goto done;
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (xvec)
|
||||
free(xvec);
|
||||
if (cbmsg)
|
||||
cbuf_free(cbmsg);
|
||||
if (cbpath)
|
||||
cbuf_free(cbpath);
|
||||
if (xerr)
|
||||
xml_free(xerr);
|
||||
if (cberr)
|
||||
cbuf_free(cberr);
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
return retval;
|
||||
|
|
@ -696,6 +723,10 @@ get_common(clicon_handle h,
|
|||
int list_pagination = 0;
|
||||
char *valstr;
|
||||
cxobj *x;
|
||||
#if 1
|
||||
cxobj **xvec = NULL;
|
||||
size_t xlen;
|
||||
#endif
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
username = clicon_username_get(h);
|
||||
|
|
@ -852,14 +883,18 @@ get_common(clicon_handle h,
|
|||
if (xml_apply(xret, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (filter_xpath_again(h, yspec, xret, xpath, nsc, NULL) < 0)
|
||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
if (get_nacm_and_reply(h, xret, xpath, nsc, username, depth, cbret) < 0)
|
||||
if (filter_xpath_again(h, yspec, xret, xvec, xlen, xpath, nsc) < 0)
|
||||
goto done;
|
||||
if (get_nacm_and_reply(h, xret, xvec, xlen, xpath, nsc, username, depth, cbret) < 0)
|
||||
goto done;
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
||||
if (xvec)
|
||||
free(xvec);
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
if (cbreason)
|
||||
|
|
|
|||
|
|
@ -78,19 +78,26 @@ clixon_plugin_reset_one(clixon_plugin_t *cp,
|
|||
clicon_handle h,
|
||||
char *db)
|
||||
{
|
||||
int retval = -1;
|
||||
plgreset_t *fn; /* callback */
|
||||
int retval = -1;
|
||||
plgreset_t *fn; /* callback */
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, db) < 0) {
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Reset callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -108,6 +115,7 @@ clixon_plugin_reset_all(clicon_handle h,
|
|||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* Loop through all plugins, call callbacks in each */
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (clixon_plugin_reset_one(cp, h, db) < 0)
|
||||
|
|
@ -130,8 +138,12 @@ clixon_plugin_pre_daemon_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_pre_daemon) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
|
||||
if (fn(h) < 0) {
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Pre-daemon callback in plugin:\
|
||||
|
|
@ -139,9 +151,13 @@ clixon_plugin_pre_daemon_one(clixon_plugin_t *cp,
|
|||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +176,7 @@ clixon_plugin_pre_daemon_all(clicon_handle h)
|
|||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* Loop through all plugins, call callbacks in each */
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (clixon_plugin_pre_daemon_one(cp, h) < 0)
|
||||
|
|
@ -182,17 +199,24 @@ clixon_plugin_daemon_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_daemon) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h) < 0) {
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Daemon callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +237,7 @@ clixon_plugin_daemon_all(clicon_handle h)
|
|||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* Loop through all plugins, call callbacks in each */
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (clixon_plugin_daemon_one(cp, h) < 0)
|
||||
|
|
@ -258,22 +283,28 @@ clixon_plugin_statedata_one(clixon_plugin_t *cp,
|
|||
int retval = -1;
|
||||
plgstatedata_t *fn; /* Plugin statedata fn */
|
||||
cxobj *x = NULL;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
clicon_debug(1, "%s %s", __FUNCTION__, clixon_plugin_name_get(cp));
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_statedata) != NULL){
|
||||
if ((x = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, nsc, xpath, x) < 0){
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: State callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto fail; /* Dont quit here on user callbacks */
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (xp && x)
|
||||
*xp = x;
|
||||
retval = 1;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
|
|
@ -406,14 +437,20 @@ clixon_plugin_lockdb_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
plglockdb_t *fn; /* Plugin statedata fn */
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
clicon_debug(1, "%s %s", __FUNCTION__, clixon_plugin_name_get(cp));
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_lockdb) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, db, lock, id) < 0)
|
||||
goto done;
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -576,17 +613,24 @@ plugin_transaction_begin_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_begin) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -605,6 +649,7 @@ plugin_transaction_begin_all(clicon_handle h,
|
|||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (plugin_transaction_begin_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
|
|
@ -628,17 +673,24 @@ plugin_transaction_validate_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_validate) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -679,17 +731,24 @@ plugin_transaction_complete_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_complete) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -762,17 +821,24 @@ plugin_transaction_commit_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -821,17 +887,24 @@ plugin_transaction_commit_done_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit_done) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -872,17 +945,24 @@ plugin_transaction_end_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_end) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -899,6 +979,7 @@ plugin_transaction_end_all(clicon_handle h,
|
|||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (plugin_transaction_end_one(cp, h, td) < 0)
|
||||
goto done;
|
||||
|
|
@ -915,17 +996,24 @@ plugin_transaction_abort_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_abort) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -942,6 +1030,7 @@ plugin_transaction_abort_all(clicon_handle h,
|
|||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if (plugin_transaction_abort_one(cp, h, td) < 0)
|
||||
; /* dont abort on error */
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <regex.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ cli_xml2file(cxobj *xn,
|
|||
if (xn == NULL)
|
||||
goto ok;
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, &opext) < 0) {
|
||||
if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) {
|
||||
goto ok;
|
||||
}
|
||||
if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){
|
||||
|
|
@ -273,13 +273,13 @@ cli_xml2txt(cxobj *xn,
|
|||
clicon_err(OE_XML, EINVAL, "xn or fn is NULL");
|
||||
goto done;
|
||||
}
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, &opext) < 0) {
|
||||
goto ok;
|
||||
}
|
||||
if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){
|
||||
goto ok;
|
||||
}
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) {
|
||||
goto ok;
|
||||
}
|
||||
if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){
|
||||
goto ok;
|
||||
}
|
||||
xc = NULL; /* count children (elements and bodies, not attributes) */
|
||||
while ((xc = xml_child_each(xn, xc, -1)) != NULL)
|
||||
if (xml_type(xc) == CX_ELMNT || xml_type(xc) == CX_BODY)
|
||||
|
|
@ -342,7 +342,7 @@ cli_xml2cli(cxobj *xn,
|
|||
if ((ys = xml_spec(xn)) == NULL)
|
||||
goto ok;
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, &opext) < 0) {
|
||||
if (yang_extension_value(xml_spec(xn), "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0) {
|
||||
goto ok;
|
||||
}
|
||||
if ((opext != NULL) && ((strcmp(opext, "hide-database") == 0) || (strcmp(opext, "hide-database-auto-completion") == 0))){
|
||||
|
|
|
|||
|
|
@ -165,17 +165,17 @@ cli_signal_flush(clicon_handle h)
|
|||
|
||||
sigfn_t h1, h2, h3, h4;
|
||||
|
||||
set_signal (SIGTSTP, SIG_IGN, &h1);
|
||||
set_signal (SIGQUIT, SIG_IGN, &h2);
|
||||
set_signal (SIGCHLD, SIG_IGN, &h3);
|
||||
set_signal (SIGINT, SIG_IGN, &h4);
|
||||
set_signal(SIGTSTP, SIG_IGN, &h1);
|
||||
set_signal(SIGQUIT, SIG_IGN, &h2);
|
||||
set_signal(SIGCHLD, SIG_IGN, &h3);
|
||||
set_signal(SIGINT, SIG_IGN, &h4);
|
||||
|
||||
cli_signal_unblock (h);
|
||||
|
||||
set_signal (SIGTSTP, h1, NULL);
|
||||
set_signal (SIGQUIT, h2, NULL);
|
||||
set_signal (SIGCHLD, h3, NULL);
|
||||
set_signal (SIGINT, h4, NULL);
|
||||
set_signal(SIGTSTP, h1, NULL);
|
||||
set_signal(SIGQUIT, h2, NULL);
|
||||
set_signal(SIGCHLD, h3, NULL);
|
||||
set_signal(SIGINT, h4, NULL);
|
||||
|
||||
cli_signal_block (h);
|
||||
}
|
||||
|
|
@ -562,9 +562,10 @@ cli_start_shell(clicon_handle h,
|
|||
int retval = -1;
|
||||
char bcmd[128];
|
||||
cg_var *cv1 = cvec_i(vars, 1);
|
||||
|
||||
sigset_t oldsigset;
|
||||
struct sigaction oldsigaction[32] = {0,};
|
||||
|
||||
cmd = (cvec_len(vars)>1 ? cv_string_get(cv1) : NULL);
|
||||
|
||||
if ((pw = getpwuid(getuid())) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "getpwuid");
|
||||
goto done;
|
||||
|
|
@ -575,6 +576,9 @@ cli_start_shell(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
endpwent();
|
||||
|
||||
if (clixon_signal_save(&oldsigset, oldsigaction) < 0)
|
||||
goto done;
|
||||
cli_signal_flush(h);
|
||||
cli_signal_unblock(h);
|
||||
if (cmd){
|
||||
|
|
@ -598,6 +602,8 @@ cli_start_shell(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
#endif
|
||||
if (clixon_signal_restore(&oldsigset, oldsigaction) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ You can see which CLISPEC it generates via clixon_cli -D 2:
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
/* cligen */
|
||||
|
|
@ -120,7 +121,7 @@ cli_expand_var_generate(clicon_handle h,
|
|||
int retval = -1;
|
||||
char *api_path_fmt = NULL, *opext = NULL;
|
||||
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, &opext) < 0)
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0)
|
||||
goto done;
|
||||
if (opext && strcmp(opext, "hide-database") == 0) {
|
||||
retval = 1;
|
||||
|
|
@ -761,7 +762,7 @@ yang2cli_leaf(clicon_handle h,
|
|||
}
|
||||
cprintf(cb, "%*s", level*3, "");
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, &opext) < 0)
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0)
|
||||
goto done;
|
||||
if (gt == GT_VARS || gt == GT_ALL || gt == GT_HIDE || gt == GT_OC_COMPRESS){
|
||||
cprintf(cb, "%s", yang_argument_get(ys));
|
||||
|
|
@ -866,14 +867,14 @@ yang2cli_container(clicon_handle h,
|
|||
if (cli_callback_generate(h, ys, cb) < 0)
|
||||
goto done;
|
||||
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, &opext) < 0)
|
||||
goto done;
|
||||
if (opext != NULL && strcmp(opext, "hide") == 0){
|
||||
cprintf(cb, ",hide");
|
||||
}
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0)
|
||||
goto done;
|
||||
if (opext != NULL && strcmp(opext, "hide") == 0){
|
||||
cprintf(cb, ",hide");
|
||||
}
|
||||
if (opext != NULL && strcmp(opext, "hide-database-auto-completion") == 0){
|
||||
cprintf(cb, ",hide-database-auto-completion");
|
||||
cprintf(cb, ",hide-database-auto-completion");
|
||||
}
|
||||
cprintf(cb, ";{\n");
|
||||
}
|
||||
|
|
@ -882,10 +883,10 @@ yang2cli_container(clicon_handle h,
|
|||
while ((yc = yn_each(ys, yc)) != NULL)
|
||||
if (yang2cli_stmt(h, yc, gt, level+1, state, show_tree, cb) < 0)
|
||||
goto done;
|
||||
if (hide == 0 && hide_oc == 0)
|
||||
cprintf(cb, "%*s}\n", level*3, "");
|
||||
retval = 0;
|
||||
done:
|
||||
if (hide == 0 && hide_oc == 0)
|
||||
cprintf(cb, "%*s}\n", level*3, "");
|
||||
retval = 0;
|
||||
done:
|
||||
if (helptext)
|
||||
free(helptext);
|
||||
return retval;
|
||||
|
|
@ -933,7 +934,7 @@ yang2cli_list(clicon_handle h,
|
|||
yang2cli_helptext(cb, helptext);
|
||||
}
|
||||
/* Look for autocli-op defined in clixon-lib.yang */
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, &opext) < 0)
|
||||
if (yang_extension_value(ys, "autocli-op", CLIXON_LIB_NS, NULL, &opext) < 0)
|
||||
goto done;
|
||||
if (opext != NULL && strcmp(opext, "hide") == 0){
|
||||
cprintf(cb, ",hide");
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <dirent.h>
|
||||
#include <grp.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <grp.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
|
@ -69,7 +70,6 @@
|
|||
#include "cli_handle.h"
|
||||
#include "cli_generate.h"
|
||||
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
|
@ -522,6 +522,53 @@ cli_handler_err(FILE *f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Variant of eval for context checking
|
||||
* @see cligen_eval
|
||||
*/
|
||||
int
|
||||
cligen_clixon_eval(cligen_handle h,
|
||||
cg_obj *co,
|
||||
cvec *cvv)
|
||||
{
|
||||
struct cg_callback *cc;
|
||||
int retval = 0;
|
||||
cvec *argv;
|
||||
plugin_context_t *pc = NULL;
|
||||
|
||||
if (h)
|
||||
cligen_co_match_set(h, co);
|
||||
for (cc = co->co_callbacks; cc; cc=cc->cc_next){
|
||||
/* Vector cvec argument to callback */
|
||||
if (cc->cc_fn_vec){
|
||||
argv = cc->cc_cvec ? cvec_dup(cc->cc_cvec) : NULL;
|
||||
cligen_fn_str_set(h, cc->cc_fn_str);
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
break;
|
||||
if ((retval = (*cc->cc_fn_vec)(
|
||||
cligen_userhandle(h)?cligen_userhandle(h):h,
|
||||
cvv,
|
||||
argv)) < 0){
|
||||
if (argv != NULL)
|
||||
cvec_free(argv);
|
||||
cligen_fn_str_set(h, NULL);
|
||||
break;
|
||||
}
|
||||
if (plugin_context_check(pc, "CLIgen", cc->cc_fn_str) < 0)
|
||||
break;
|
||||
if (pc){
|
||||
free(pc);
|
||||
pc = NULL;
|
||||
}
|
||||
if (argv != NULL)
|
||||
cvec_free(argv);
|
||||
cligen_fn_str_set(h, NULL);
|
||||
}
|
||||
}
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Evaluate a matched command
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] cmd The command string
|
||||
|
|
@ -541,7 +588,8 @@ clicon_eval(clicon_handle h,
|
|||
cli_output_reset();
|
||||
if (!cligen_exiting(cli_cligen(h))) {
|
||||
clicon_err_reset();
|
||||
if ((retval = cligen_eval(cli_cligen(h), match_obj, cvv)) < 0) {
|
||||
|
||||
if ((retval = cligen_clixon_eval(cli_cligen(h), match_obj, cvv)) < 0) {
|
||||
#if 0 /* This is removed since we get two error messages on failure.
|
||||
But maybe only sometime?
|
||||
Both a real log when clicon_err is called, and the here again.
|
||||
|
|
|
|||
|
|
@ -919,6 +919,7 @@ cli_pagination(clicon_handle h,
|
|||
uint32_t limit = 0;
|
||||
cxobj **xvec = NULL;
|
||||
size_t xlen;
|
||||
int locked = 0;
|
||||
|
||||
if (cvec_len(argv) != 5){
|
||||
clicon_err(OE_PLUGIN, 0, "Expected usage: <xpath> <prefix> <namespace> <format> <limit>");
|
||||
|
|
@ -950,6 +951,7 @@ cli_pagination(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_lock(h, "running") < 0)
|
||||
goto done;
|
||||
locked++;
|
||||
for (i = 0;; i++){
|
||||
if (clicon_rpc_get_pageable_list(h, "running", xpath, nsc,
|
||||
CONTENT_ALL,
|
||||
|
|
@ -1000,10 +1002,10 @@ cli_pagination(clicon_handle h,
|
|||
xvec = NULL;
|
||||
}
|
||||
} /* for i */
|
||||
if (clicon_rpc_unlock(h, "running") < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (locked)
|
||||
clicon_rpc_unlock(h, "running");
|
||||
if (xvec)
|
||||
free(xvec);
|
||||
if (xret)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue