getting legacy grideye application to work on clixon
This commit is contained in:
parent
6169ea6bed
commit
c1c1670a74
22 changed files with 952 additions and 805 deletions
|
|
@ -183,6 +183,10 @@ clicon_option_default(clicon_hash_t *copt)
|
|||
if (hash_add(copt, "CLICON_CLI_GENMODEL_COMPLETION", "0", strlen("0")+1) < 0)
|
||||
goto catch;
|
||||
}
|
||||
if (!hash_lookup(copt, "CLICON_XMLDB_RPC")){
|
||||
if (hash_add(copt, "CLICON_XMLDB_RPC", "0", strlen("0")+1) < 0)
|
||||
goto catch;
|
||||
}
|
||||
retval = 0;
|
||||
catch:
|
||||
unchunk_group(__FUNCTION__);
|
||||
|
|
@ -600,7 +604,7 @@ clicon_xmldb_rpc(clicon_handle h)
|
|||
char *s;
|
||||
|
||||
if ((s = clicon_option_str(h, "CLICON_XMLDB_RPC")) == NULL)
|
||||
return -1;
|
||||
return 0; /* default 0 */
|
||||
return atoi(s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ clicon_proc_sigint(int sig)
|
|||
kill (_clicon_proc_child, SIGINT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork a child process, setup a pipe between parent and child, allowing
|
||||
* parent to read the output of the child. If 'doerr' is non-zero, stderr
|
||||
* will be directed to the pipe as well. The pipe for the parent to write
|
||||
/*! Fork a child process, setup a pipe between parent and child.
|
||||
* Allowing parent to read the output of the child.
|
||||
* @param[in] doerr If non-zero, stderr will be directed to the pipe as well.
|
||||
* The pipe for the parent to write
|
||||
* to the child is closed and cannot be used.
|
||||
*
|
||||
* When child process is done with the pipe setup, execute the specified
|
||||
|
|
@ -85,10 +85,13 @@ clicon_proc_sigint(int sig)
|
|||
* until eof. The read output will be sent to the specified output callback,
|
||||
* 'outcb' function.
|
||||
*
|
||||
* Return number of matches (processes affected). -1 on error.
|
||||
* @retval number Matches (processes affected).
|
||||
* @retval -1 Error.
|
||||
*/
|
||||
int
|
||||
clicon_proc_run (char *cmd, void (outcb)(char *), int doerr)
|
||||
clicon_proc_run (char *cmd,
|
||||
void (outcb)(char *),
|
||||
int doerr)
|
||||
{
|
||||
char
|
||||
**argv,
|
||||
|
|
@ -182,9 +185,7 @@ clicon_proc_run (char *cmd, void (outcb)(char *), int doerr)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Spawm command and report exit status
|
||||
/*! Spawn command and report exit status
|
||||
*/
|
||||
int
|
||||
clicon_proc_daemon (char *cmd)
|
||||
|
|
@ -251,81 +252,6 @@ clicon_proc_daemon (char *cmd)
|
|||
}
|
||||
|
||||
|
||||
#ifdef moved_to_osr
|
||||
#ifdef linux
|
||||
/*
|
||||
* Send 'sig' (if not 0) to all processes matching 'name'.
|
||||
* Return the number of matches.
|
||||
*/
|
||||
int
|
||||
clicon_proc_killbyname (const char *name, int sig)
|
||||
{
|
||||
/* XXXX FIXME. Should scan /proc/<pid>/status */
|
||||
char buf[512];
|
||||
snprintf (buf, sizeof (buf)-1, "pkill -%d %s", sig, name);
|
||||
|
||||
return clicon_proc_run (buf, NULL, 0);
|
||||
}
|
||||
#endif /* Linux */
|
||||
|
||||
|
||||
#ifdef BSD
|
||||
/*
|
||||
* Send 'sig' (if not 0) to all processes matching 'name'.
|
||||
* Return the number of matches.
|
||||
*/
|
||||
int
|
||||
clicon_proc_killbyname (const char *name, int sig)
|
||||
{
|
||||
int
|
||||
i,
|
||||
nproc,
|
||||
nmatch,
|
||||
mib[3];
|
||||
size_t
|
||||
size;
|
||||
struct proc
|
||||
*p;
|
||||
struct kinfo_proc
|
||||
*kp = NULL;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_NPROCS; /* KERN_MACPROC, KERN_PROC */
|
||||
size = sizeof (nproc);
|
||||
if (sysctl(mib, 2, &nproc, &size, NULL, 0) < 0)
|
||||
return -1;
|
||||
|
||||
size = nproc * sizeof(struct kinfo_proc);
|
||||
kp = chunk(size * sizeof(char), "bsdkill");
|
||||
if (kp == NULL)
|
||||
goto error;
|
||||
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_ALL;
|
||||
|
||||
if (sysctl(mib, 3, kp, &size, NULL, 0) < 0)
|
||||
goto error;
|
||||
|
||||
nproc = size / sizeof(struct kinfo_proc);
|
||||
for (nmatch = i = 0; i < nproc; i++) {
|
||||
p = (struct proc *)&kp[i].kp_proc;
|
||||
if (!strcmp (name, p->p_comm)) {
|
||||
nmatch++;
|
||||
kill (p->p_pid, sig);
|
||||
}
|
||||
}
|
||||
|
||||
unchunk (kp);
|
||||
return nmatch;
|
||||
|
||||
error:
|
||||
if (kp)
|
||||
unchunk (kp);
|
||||
return -1;
|
||||
}
|
||||
#endif /* BSD */
|
||||
#endif
|
||||
|
||||
/*! Translate group name to gid. Return -1 if error or not found.
|
||||
*/
|
||||
int
|
||||
|
|
|
|||
|
|
@ -464,7 +464,9 @@ send_msg_ok(int s)
|
|||
}
|
||||
|
||||
int
|
||||
send_msg_notify(int s, int level, char *event)
|
||||
send_msg_notify(int s,
|
||||
int level,
|
||||
char *event)
|
||||
{
|
||||
int retval = -1;
|
||||
struct clicon_msg *msg;
|
||||
|
|
|
|||
|
|
@ -174,11 +174,11 @@ clicon_rpc_validate(clicon_handle h,
|
|||
* @note special case: remove all: key:"/" op:OP_REMOVE
|
||||
*/
|
||||
int
|
||||
clicon_rpc_change(clicon_handle h,
|
||||
char *db,
|
||||
clicon_rpc_change(clicon_handle h,
|
||||
char *db,
|
||||
enum operation_type op,
|
||||
char *key,
|
||||
char *val)
|
||||
char *key,
|
||||
char *val)
|
||||
{
|
||||
int retval = -1;
|
||||
struct clicon_msg *msg;
|
||||
|
|
|
|||
|
|
@ -83,14 +83,15 @@ db_init_mode(char *file,
|
|||
|
||||
/* Open database for writing */
|
||||
if ((dp = dpopen(file, omode | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, 0, "db_init: dpopen(%s): %s",
|
||||
file,
|
||||
dperrmsg(dpecode));
|
||||
clicon_err(OE_DB, errno, "dpopen(%s): %s",
|
||||
file,
|
||||
dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
clicon_debug(1, "db_init(%s)", file);
|
||||
if (dpclose(dp) == 0){
|
||||
clicon_err(OE_DB, 0, "db_set: dpclose: %s", dperrmsg(dpecode));
|
||||
clicon_err(OE_DB, errno, "db_set: dpclose: %s",
|
||||
dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -138,7 +139,7 @@ db_set(char *file, char *key, void *data, size_t datalen)
|
|||
|
||||
/* Open database for writing */
|
||||
if ((dp = dpopen(file, DP_OWRITER|DP_OLCKNB , 0)) == NULL){
|
||||
clicon_err(OE_DB, 0, "db_set: dpopen(%s): %s",
|
||||
clicon_err(OE_DB, errno, "db_set: dpopen(%s): %s",
|
||||
file,
|
||||
dperrmsg(dpecode));
|
||||
return -1;
|
||||
|
|
@ -146,7 +147,7 @@ db_set(char *file, char *key, void *data, size_t datalen)
|
|||
clicon_debug(2, "%s: db_put(%s, len:%d)",
|
||||
file, key, (int)datalen);
|
||||
if (dpput(dp, key, -1, data, datalen, DP_DOVER) == 0){
|
||||
clicon_err(OE_DB, 0, "%s: db_set: dpput(%s, %d): %s",
|
||||
clicon_err(OE_DB, errno, "%s: db_set: dpput(%s, %d): %s",
|
||||
file,
|
||||
key,
|
||||
datalen,
|
||||
|
|
@ -181,7 +182,7 @@ db_get(char *file,
|
|||
|
||||
/* Open database for readinf */
|
||||
if ((dp = dpopen(file, DP_OREADER | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, dpecode, "%s: db_get(%s, %d): dpopen: %s",
|
||||
clicon_err(OE_DB, errno, "%s: db_get(%s, %d): dpopen: %s",
|
||||
file,
|
||||
key,
|
||||
datalen,
|
||||
|
|
@ -195,7 +196,7 @@ db_get(char *file,
|
|||
*datalen = 0;
|
||||
}
|
||||
else{
|
||||
clicon_err(OE_DB, 0, "db_get: dpgetwb: %s (%d)",
|
||||
clicon_err(OE_DB, errno, "db_get: dpgetwb: %s (%d)",
|
||||
dperrmsg(dpecode), dpecode);
|
||||
dpclose(dp);
|
||||
return -1;
|
||||
|
|
@ -205,7 +206,7 @@ db_get(char *file,
|
|||
*datalen = len;
|
||||
clicon_debug(2, "db_get(%s, %s)=%s", file, key, (char*)data);
|
||||
if (dpclose(dp) == 0){
|
||||
clicon_err(OE_DB, 0, "db_get: dpclose: %s", dperrmsg(dpecode));
|
||||
clicon_err(OE_DB, errno, "db_get: dpclose: %s", dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -243,7 +244,7 @@ db_get_alloc(char *file,
|
|||
|
||||
/* Open database for writing */
|
||||
if ((dp = dpopen(file, DP_OREADER | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, 0, "%s: dpopen(%s): %s",
|
||||
clicon_err(OE_DB, errno, "%s: dpopen(%s): %s",
|
||||
__FUNCTION__,
|
||||
file,
|
||||
dperrmsg(dpecode));
|
||||
|
|
@ -257,7 +258,7 @@ db_get_alloc(char *file,
|
|||
}
|
||||
else{
|
||||
/* No entry vs error? */
|
||||
clicon_err(OE_DB, 0, "db_get_alloc: dpgetwb: %s (%d)",
|
||||
clicon_err(OE_DB, errno, "db_get_alloc: dpgetwb: %s (%d)",
|
||||
dperrmsg(dpecode), dpecode);
|
||||
dpclose(dp);
|
||||
return -1;
|
||||
|
|
@ -265,7 +266,7 @@ db_get_alloc(char *file,
|
|||
}
|
||||
*datalen = len;
|
||||
if (dpclose(dp) == 0){
|
||||
clicon_err(OE_DB, 0, "db_get_alloc: dpclose: %s", dperrmsg(dpecode));
|
||||
clicon_err(OE_DB, errno, "db_get_alloc: dpclose: %s", dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -286,7 +287,7 @@ db_del(char *file, char *key)
|
|||
|
||||
/* Open database for writing */
|
||||
if ((dp = dpopen(file, DP_OWRITER | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, 0, "db_del: dpopen(%s): %s",
|
||||
clicon_err(OE_DB, errno, "db_del: dpopen(%s): %s",
|
||||
file,
|
||||
dperrmsg(dpecode));
|
||||
return -1;
|
||||
|
|
@ -295,7 +296,7 @@ db_del(char *file, char *key)
|
|||
retval = 1;
|
||||
}
|
||||
if (dpclose(dp) == 0){
|
||||
clicon_err(OE_DB, 0, "db_del: dpclose: %s", dperrmsg(dpecode));
|
||||
clicon_err(OE_DB, errno, "db_del: dpclose: %s", dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
return retval;
|
||||
|
|
@ -316,18 +317,18 @@ db_exists(char *file, char *key)
|
|||
|
||||
/* Open database for reading */
|
||||
if ((dp = dpopen(file, DP_OREADER | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, dpecode, "%s: dpopen: %s",
|
||||
clicon_err(OE_DB, errno, "%s: dpopen: %s",
|
||||
__FUNCTION__, dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = dpvsiz(dp, key, -1);
|
||||
if (len < 0 && dpecode != DP_ENOITEM)
|
||||
clicon_err(OE_DB, 0, "^s: dpvsiz: %s (%d)",
|
||||
clicon_err(OE_DB, errno, "^s: dpvsiz: %s (%d)",
|
||||
__FUNCTION__, dperrmsg(dpecode), dpecode);
|
||||
|
||||
if (dpclose(dp) == 0) {
|
||||
clicon_err(OE_DB, 0, "%s: dpclose: %s", dperrmsg(dpecode),__FUNCTION__);
|
||||
clicon_err(OE_DB, errno, "%s: dpclose: %s", dperrmsg(dpecode),__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +379,7 @@ db_regexp(char *file,
|
|||
if (regexp) {
|
||||
if ((status = regcomp(&iterre, regexp, REG_EXTENDED)) != 0) {
|
||||
regerror(status, &iterre, errbuf, sizeof(errbuf));
|
||||
clicon_err(OE_DB, 0, "%s: regcomp: %s", __FUNCTION__, errbuf);
|
||||
clicon_err(OE_DB, errno, "%s: regcomp: %s", __FUNCTION__, errbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -392,7 +393,7 @@ db_regexp(char *file,
|
|||
|
||||
/* Initiate iterator */
|
||||
if(dpiterinit(iterdp) == 0) {
|
||||
clicon_err(OE_DB, 0, "%s: dpiterinit: %s", __FUNCTION__, dperrmsg(dpecode));
|
||||
clicon_err(OE_DB, errno, "%s: dpiterinit: %s", __FUNCTION__, dperrmsg(dpecode));
|
||||
goto quit;
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +550,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
else if (strcmp(verb, "openread")==0){
|
||||
if ((dp = dpopen(filename, DP_OREADER | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, dpecode, "dbopen: %s",
|
||||
clicon_err(OE_DB, errno, "dbopen: %s",
|
||||
dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -557,7 +558,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
else if (strcmp(verb, "openwrite")==0){
|
||||
if ((dp = dpopen(filename, DP_OWRITER | DP_OLCKNB, 0)) == NULL){
|
||||
clicon_err(OE_DB, dpecode, "dbopen: %s",
|
||||
clicon_err(OE_DB, errno, "dbopen: %s",
|
||||
dperrmsg(dpecode));
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ xml_value(cxobj *xn)
|
|||
return xn->x_value;
|
||||
}
|
||||
|
||||
/*! Set value of xnode, value is copied
|
||||
/*! Set value of xml node, value is copied
|
||||
* @param[in] xn xml node
|
||||
* @param[in] val new value, null-terminated string, copied by function
|
||||
* @retval -1 on error with clicon-err set
|
||||
|
|
@ -230,7 +230,8 @@ xml_value_set(cxobj *xn, char *val)
|
|||
* @retval new value
|
||||
*/
|
||||
char *
|
||||
xml_value_append(cxobj *xn, char *val)
|
||||
xml_value_append(cxobj *xn,
|
||||
char *val)
|
||||
{
|
||||
int len0;
|
||||
int len;
|
||||
|
|
@ -263,7 +264,8 @@ xml_type(cxobj *xn)
|
|||
* @retval type old type
|
||||
*/
|
||||
enum cxobj_type
|
||||
xml_type_set(cxobj *xn, enum cxobj_type type)
|
||||
xml_type_set(cxobj *xn,
|
||||
enum cxobj_type type)
|
||||
{
|
||||
enum cxobj_type old = xn->x_type;
|
||||
|
||||
|
|
@ -289,7 +291,8 @@ xml_index(cxobj *xn)
|
|||
* index/key is used in case of yang list constructs where one element is key
|
||||
*/
|
||||
int
|
||||
xml_index_set(cxobj *xn, int index)
|
||||
xml_index_set(cxobj *xn,
|
||||
int index)
|
||||
{
|
||||
int old = xn->x_index;
|
||||
|
||||
|
|
@ -313,7 +316,8 @@ xml_child_nr(cxobj *xn)
|
|||
* @retval child in XML tree, or NULL if no such child, or empty child
|
||||
*/
|
||||
cxobj *
|
||||
xml_child_i(cxobj *xn, int i)
|
||||
xml_child_i(cxobj *xn,
|
||||
int i)
|
||||
{
|
||||
if (i < xn->x_childvec_len)
|
||||
return xn->x_childvec[i];
|
||||
|
|
@ -321,7 +325,9 @@ xml_child_i(cxobj *xn, int i)
|
|||
}
|
||||
|
||||
cxobj *
|
||||
xml_child_i_set(cxobj *xt, int i, cxobj *xc)
|
||||
xml_child_i_set(cxobj *xt,
|
||||
int i,
|
||||
cxobj *xc)
|
||||
{
|
||||
if (i < xt->x_childvec_len)
|
||||
xt->x_childvec[i] = xc;
|
||||
|
|
@ -460,7 +466,8 @@ xml_spec(cxobj *x)
|
|||
* @retval NULL if no such node found.
|
||||
*/
|
||||
cxobj *
|
||||
xml_find(cxobj *x_up, char *name)
|
||||
xml_find(cxobj *x_up,
|
||||
char *name)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
|
||||
|
|
@ -478,14 +485,25 @@ xml_find(cxobj *x_up, char *name)
|
|||
* @see xml_insert
|
||||
*/
|
||||
int
|
||||
xml_addsub(cxobj *xp, cxobj *xc)
|
||||
xml_addsub(cxobj *xp,
|
||||
cxobj *xc)
|
||||
{
|
||||
cxobj *oldp;
|
||||
int i;
|
||||
|
||||
if ((oldp = xml_parent(xc)) != NULL)
|
||||
xml_prune(oldp, xc, 0);
|
||||
if ((oldp = xml_parent(xc)) != NULL){
|
||||
/* Find child order i in old parent*/
|
||||
for (i=0; i<xml_child_nr(oldp); i++)
|
||||
if (xml_child_i(oldp, i) == xc)
|
||||
break;
|
||||
/* Remove xc from old parent */
|
||||
if (i < xml_child_nr(oldp))
|
||||
xml_child_rm(oldp, i);
|
||||
}
|
||||
/* Add xc to new parent */
|
||||
if (xml_child_append(xp, xc) < 0)
|
||||
return -1;
|
||||
/* Set new parent in child */
|
||||
xml_parent_set(xc, xp);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -515,6 +533,110 @@ xml_insert(cxobj *xp, char *tag)
|
|||
return xc;
|
||||
}
|
||||
|
||||
/*! Remove and free an xml node child from xml parent
|
||||
* @param[in] xparent xml parent node
|
||||
* @param[in] xchild xml child node (to be renmoved and freed)
|
||||
* @retval 0 OK
|
||||
* @retval -1
|
||||
* @note you cannot remove xchild in the loop (unless yoy keep track of xprev)
|
||||
*
|
||||
* @see xml_free Free, dont remove from parent
|
||||
* @see xml_child_rm Only remove dont free
|
||||
* Differs from xml_free it is removed from parent.
|
||||
*/
|
||||
int
|
||||
xml_purge(cxobj *xc)
|
||||
{
|
||||
int retval = -1;
|
||||
int i;
|
||||
cxobj *xp;
|
||||
|
||||
if ((xp = xml_parent(xc)) != NULL){
|
||||
/* Find child order i in parent*/
|
||||
for (i=0; i<xml_child_nr(xp); i++)
|
||||
if (xml_child_i(xp, i) == xc)
|
||||
break;
|
||||
/* Remove xc from parent */
|
||||
if (i < xml_child_nr(xp))
|
||||
if (xml_child_rm(xp, i) < 0)
|
||||
goto done;
|
||||
}
|
||||
xml_free(xc);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Remove xml node from parent xml node. No freeing and child is new own root
|
||||
* @param[in] xp xml parent node
|
||||
* @param[in] i Number of xml child node (to remove)
|
||||
* @retval 0 OK
|
||||
* @retval -1
|
||||
* @note you should not remove xchild in loop (unless yoy keep track of xprev)
|
||||
*
|
||||
* @see xml_rootchild
|
||||
*/
|
||||
int
|
||||
xml_child_rm(cxobj *xp,
|
||||
int i)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xc = NULL;
|
||||
|
||||
if ((xc = xml_child_i(xp, i)) == NULL){
|
||||
clicon_err(OE_XML, 0, "Child not found");
|
||||
goto done;
|
||||
}
|
||||
xp->x_childvec[i] = NULL;
|
||||
xml_parent_set(xc, NULL);
|
||||
xp->x_childvec_len--;
|
||||
/* shift up, note same index i used but ok since we break */
|
||||
for (; i<xp->x_childvec_len; i++)
|
||||
xp->x_childvec[i] = xp->x_childvec[i+1];
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Return a child sub-tree, while removing parent and all other children
|
||||
* Given a root xml node, and the i:th child, remove the child from its parent
|
||||
* and return it, remove the parent and all other children.
|
||||
* Before: xp-->[..xc..]
|
||||
* After: xc
|
||||
* @param[in] xp xml parent node. Will be deleted
|
||||
* @param[in] i Child nr in parent child vector
|
||||
* @param[out] xcp xml child node. New root
|
||||
* @code
|
||||
* @endcode
|
||||
* @see xml_child_rm
|
||||
*/
|
||||
int
|
||||
xml_rootchild(cxobj *xp,
|
||||
int i,
|
||||
cxobj **xcp)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xc;
|
||||
|
||||
if (xml_parent(xp) != NULL){
|
||||
clicon_err(OE_XML, 0, "Parent is not root");
|
||||
goto done;
|
||||
}
|
||||
if ((xc = xml_child_i(xp, i)) == NULL){
|
||||
clicon_err(OE_XML, 0, "Child not found");
|
||||
goto done;
|
||||
}
|
||||
if (xml_child_rm(xp, i) < 0)
|
||||
goto done;
|
||||
if (xml_free(xp) < 0)
|
||||
goto done;
|
||||
*xcp = xc;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Get the first sub-node which is an XML body.
|
||||
* @param[in] xn xml tree node
|
||||
* @retval The returned body as a pointer to the name string
|
||||
|
|
@ -532,7 +654,6 @@ xml_body(cxobj *xn)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*! Find and return the value of a sub xml node
|
||||
*
|
||||
* The value can be of an attribute or body.
|
||||
|
|
@ -554,14 +675,13 @@ xml_find_value(cxobj *x_up, char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*! Find and return a body (string) of a sub xml node
|
||||
* @param[in] xn xml tree node
|
||||
* @param[in] name name of xml tree node
|
||||
* @retval The returned body as a pointer to the name string
|
||||
* @retval NULL if no such node or no body in found node
|
||||
* Note, make a copy of the return value to use it properly
|
||||
* See also xml_find_value
|
||||
* @note, make a copy of the return value to use it properly
|
||||
* @see xml_find_value
|
||||
*/
|
||||
char *
|
||||
xml_find_body(cxobj *xn, char *name)
|
||||
|
|
@ -573,51 +693,9 @@ xml_find_body(cxobj *xn, char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*! Remove an xml node from a parent xml node.
|
||||
* @param[in] xparent xml parent node
|
||||
* @param[in] xchild xml child node (to remove)
|
||||
* @param[in] purge if 1, free the child node, not just remove from parent
|
||||
* @retval 0 OK
|
||||
* @retval -1
|
||||
* @note you cannot remove xchild in the loop (unless yoy keep track of xprev)
|
||||
*
|
||||
* @see xml_free
|
||||
* Differs from xml_free in two ways:
|
||||
* 1. It is removed from parent.
|
||||
* 2. If you set the purge flag to 1, the child tree will be freed
|
||||
* (otherwise it will not)
|
||||
*/
|
||||
int
|
||||
xml_prune(cxobj *xparent,
|
||||
cxobj *xchild,
|
||||
int purge)
|
||||
{
|
||||
int i;
|
||||
cxobj *xc = NULL;
|
||||
|
||||
for (i=0; i<xml_child_nr(xparent); i++){
|
||||
xc = xml_child_i(xparent, i);
|
||||
if (xc != xchild)
|
||||
continue;
|
||||
/* matching child */
|
||||
xparent->x_childvec[i] = NULL;
|
||||
xml_parent_set(xc, NULL);
|
||||
if (purge)
|
||||
xml_free(xchild);
|
||||
xparent->x_childvec_len--;
|
||||
/* shift up, note same index i used but ok since we break */
|
||||
for (;i<xparent->x_childvec_len; i++)
|
||||
xparent->x_childvec[i] = xparent->x_childvec[i+1];
|
||||
return 0;
|
||||
}
|
||||
clicon_err(OE_XML, 0, "%s: child not found", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*! Free an xl sub-tree recursively, but do not remove it from parent
|
||||
* @param[in] x the xml tree to be freed.
|
||||
* @see xml_prune
|
||||
* Differs from xml_prune in that it is _not_ removed from parent.
|
||||
* @see xml_purge where x is also removed from parent
|
||||
*/
|
||||
int
|
||||
xml_free(cxobj *x)
|
||||
|
|
@ -662,7 +740,7 @@ clicon_xml2file(FILE *f,
|
|||
int retval = -1;
|
||||
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "%s: cbuf_new", __FUNCTION__);
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (clicon_xml2cbuf(cb, xn, level, prettyprint) < 0)
|
||||
|
|
@ -864,7 +942,6 @@ clicon_xml_parse_file(int fd,
|
|||
return (*cx)?0:-1;
|
||||
}
|
||||
|
||||
|
||||
/*! Read an XML definition from string and parse it into a parse-tree.
|
||||
*
|
||||
* @param[in] str Pointer to string containing XML definition. NOTE: destructively
|
||||
|
|
@ -1081,6 +1158,7 @@ xml_apply_ancestor(cxobj *xn,
|
|||
goto done;
|
||||
if (xml_apply_ancestor(xp, fn, arg) < 0)
|
||||
goto done;
|
||||
xn = xp;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -389,6 +389,9 @@ db_islocked(char *db)
|
|||
* @param[out] filename Filename. Unallocate after use with free()
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @note Could need a way to extend which databases exists, eg to register new.
|
||||
* The currently allowed databases are:
|
||||
* candidate, tmp, running, result
|
||||
* The filename reside in CLICON_XMLDB_DIR option
|
||||
*/
|
||||
static int
|
||||
|
|
@ -410,6 +413,7 @@ db2file(clicon_handle h,
|
|||
}
|
||||
if (strcmp(db, "running") != 0 &&
|
||||
strcmp(db, "candidate") != 0 &&
|
||||
strcmp(db, "result") != 0 &&
|
||||
strcmp(db, "tmp") != 0){
|
||||
clicon_err(OE_XML, 0, "Unexpected database: %s", db);
|
||||
goto done;
|
||||
|
|
@ -539,7 +543,7 @@ xml_tree_prune_unmarked(cxobj *xt,
|
|||
if (submark)
|
||||
mark++;
|
||||
else{ /* Safe with xml_child_each if last */
|
||||
if (xml_prune(xt, x, 1) < 0)
|
||||
if (xml_purge(x) < 0)
|
||||
goto done;
|
||||
x = xprev;
|
||||
}
|
||||
|
|
@ -816,14 +820,16 @@ xmldb_get_tree(char *dbname,
|
|||
}
|
||||
if (xml_tree_prune_unmarked(xt, NULL) < 0)
|
||||
goto done;
|
||||
if (xml_apply(xt, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
|
||||
goto done;
|
||||
}
|
||||
*xtop = xt;
|
||||
if (xml_apply(xt, CX_ELMNT, xml_default, NULL) < 0)
|
||||
goto done;
|
||||
if (1)
|
||||
if (1) /* sanity */
|
||||
if (xml_apply(xt, CX_ELMNT, xml_sanity, NULL) < 0)
|
||||
goto done;
|
||||
if (0)
|
||||
if (debug)
|
||||
clicon_xml2file(stdout, xt, 0, 1);
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -841,7 +847,7 @@ xmldb_get_tree(char *dbname,
|
|||
* The function returns a minimal tree that includes all sub-trees that match
|
||||
* xpath.
|
||||
* @param[in] dbname Name of database to search in (filename including dir path
|
||||
* @param[in] xpath String with XPATH syntax (or NULL for all)
|
||||
* @param[in] xpath String with XPATH syntax
|
||||
* @param[in] yspec Yang specification
|
||||
* @param[out] xtop Single XML tree which xvec points to. Free with xml_free()
|
||||
* @param[out] xvec Vector of xml trees. Free after use
|
||||
|
|
@ -955,9 +961,9 @@ xmldb_get_local(clicon_handle h,
|
|||
* xpath.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db running | candidate
|
||||
* @param[in] xpath String with XPATH syntax (or NULL for all)
|
||||
* @param[in] xpath String with XPATH syntax
|
||||
* @param[in] vector If set, return list of results in xvec, else single tree.
|
||||
* @param[out] xtop XML tree. Freed by xml_free()
|
||||
* @param[out] xtop XML tree. Freed by xml_free()p
|
||||
* @param[out] xvec Vector of xml trees. Free after use
|
||||
* @param[out] xlen Length of vector.
|
||||
* @retval 0 OK
|
||||
|
|
@ -967,7 +973,7 @@ xmldb_get_local(clicon_handle h,
|
|||
* cxobj **xvec;
|
||||
* size_t xlen;
|
||||
* yang_spec *yspec = clicon_dbspec_yang(h);
|
||||
* if (xmldb_get(dbname, "/interfaces/interface[name="eth"]", yspec,
|
||||
* if (xmldb_get("running", "/interfaces/interface[name="eth"]",
|
||||
* 1, &xt, &xvec, &xlen) < 0)
|
||||
* err;
|
||||
* for (i=0; i<xlen; i++){
|
||||
|
|
@ -989,6 +995,7 @@ xmldb_get(clicon_handle h,
|
|||
cxobj ***xvec,
|
||||
size_t *xlen)
|
||||
{
|
||||
assert(xpath);
|
||||
if (clicon_xmldb_rpc(h))
|
||||
return xmldb_get_rpc(h, db, xpath, vector, xtop, xvec, xlen);
|
||||
else
|
||||
|
|
@ -1729,10 +1736,8 @@ main(int argc, char **argv)
|
|||
usage(argv[0]);
|
||||
if (clicon_xml_parse_file(0, &xt, "</clicon>") < 0)
|
||||
goto done;
|
||||
xn = xml_child_i(xt, 0);
|
||||
xml_prune(xt, xn, 0); /* kludge to remove top-level tag (eg top/clicon) */
|
||||
xml_parent_set(xn, NULL);
|
||||
xml_free(xt);
|
||||
if (xml_rootchild(xt, 0, &xn) < 0)
|
||||
goto done;
|
||||
if (strcmp(argv[5], "set") == 0)
|
||||
op = OP_REPLACE;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
#include "clixon_xml_db.h"
|
||||
#include "clixon_xml_db_rpc.h"
|
||||
|
||||
/*! Make an rpc call to xmldb daemon
|
||||
*/
|
||||
static int
|
||||
xmldb_rpc(clicon_handle h,
|
||||
char *data,
|
||||
|
|
@ -273,13 +275,9 @@ xmldb_get_rpc(clicon_handle h,
|
|||
xt = NULL;
|
||||
}
|
||||
else{
|
||||
if ((xc = xml_child_i(xt, 0)) != NULL){
|
||||
xml_prune(xt, xc, 0); /* kludge to remove top-level tag (eg top/clicon) */
|
||||
xml_parent_set(xc, NULL);
|
||||
if (debug > 1)
|
||||
clicon_xml2file(stderr, xc, 0, 1);
|
||||
}
|
||||
*xtop = xc;
|
||||
if (xml_rootchild(xt, 0, xtop) < 0)
|
||||
goto done;
|
||||
xt = NULL;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -520,7 +520,9 @@ xml2cvec(cxobj *xt,
|
|||
* @see cvec2xml This does more but has an internal xml2cvec translation
|
||||
*/
|
||||
int
|
||||
cvec2xml_1(cvec *cvv, char *toptag, cxobj **xt0)
|
||||
cvec2xml_1(cvec *cvv,
|
||||
char *toptag,
|
||||
cxobj **xt0)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xt = NULL;
|
||||
|
|
|
|||
|
|
@ -784,14 +784,14 @@ xpath_each(cxobj *cxtop,
|
|||
*
|
||||
* @code
|
||||
* cxobj **xv;
|
||||
* int xlen;
|
||||
* if ((xv = xpath_vec(cxtop, "//symbol/foo", &xlen)) != NULL) {
|
||||
* for (i=0; i<xlen; i++){
|
||||
* xn = xv[i];
|
||||
* size_t xlen;
|
||||
* if (xpath_vec(cxtop, "//symbol/foo", &xv, &xlen) < 0)
|
||||
* got err;
|
||||
* for (i=0; i<xlen; i++){
|
||||
* xn = xv[i];
|
||||
* ...
|
||||
* }
|
||||
* free(xv);
|
||||
* }
|
||||
* free(xv);
|
||||
* @endcode
|
||||
* Note that although the returned vector must be freed after use, the returned xml
|
||||
* trees need not be.
|
||||
|
|
|
|||
|
|
@ -770,7 +770,8 @@ yang_type_resolve(yang_stmt *ys,
|
|||
*yrestype = NULL; /* Initialization of resolved type that may not be necessary */
|
||||
type = ytype_id(ytype); /* This is the type to resolve */
|
||||
prefix = ytype_prefix(ytype); /* And this its prefix */
|
||||
if (ytype->ys_typecache != NULL){
|
||||
/* Cache does not work for eg string length 32 */
|
||||
if (!yang_builtin(type) && ytype->ys_typecache != NULL){
|
||||
if (yang_type_cache_get(ytype->ys_typecache,
|
||||
yrestype, options, mincv, maxcv, pattern, fraction) < 0)
|
||||
goto done;
|
||||
|
|
@ -803,7 +804,7 @@ yang_type_resolve(yang_stmt *ys,
|
|||
}
|
||||
else
|
||||
while (1){
|
||||
/* Check upwards in hierarchy for matcing typedefs */
|
||||
/* Check upwards in hierarchy for matching typedefs */
|
||||
if ((ys = ys_typedef_up(ys)) == NULL){ /* If reach top */
|
||||
*yrestype = NULL;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue