show_configuration and cli_copy_object added as generic cli commands
This commit is contained in:
parent
c59869a44e
commit
1e92304a52
7 changed files with 297 additions and 61 deletions
|
|
@ -29,7 +29,7 @@
|
||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
- show_configuration and cli_copy_object added as generic cli commands
|
||||||
- Alternative yang spec option -y added to all applications
|
- Alternative yang spec option -y added to all applications
|
||||||
- Many clicon special string functions have been removed
|
- Many clicon special string functions have been removed
|
||||||
- The netconf support has been extended with lock/unlock
|
- The netconf support has been extended with lock/unlock
|
||||||
|
|
|
||||||
|
|
@ -627,10 +627,7 @@ load_config_filev(clicon_handle h,
|
||||||
clicon_err(OE_PLUGIN, 0, "No such var name: %s", varstr);
|
clicon_err(OE_PLUGIN, 0, "No such var name: %s", varstr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((filename = realpath(cv_string_get(cv), NULL)) == NULL){
|
filename = cv_string_get(cv);
|
||||||
cli_output(stderr, "Failed to resolve filename\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (stat(filename, &st) < 0){
|
if (stat(filename, &st) < 0){
|
||||||
clicon_err(OE_UNIX, 0, "load_config: stat(%s): %s",
|
clicon_err(OE_UNIX, 0, "load_config: stat(%s): %s",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
|
|
@ -666,8 +663,6 @@ load_config_filev(clicon_handle h,
|
||||||
// }
|
// }
|
||||||
ret = 0;
|
ret = 0;
|
||||||
done:
|
done:
|
||||||
if (filename)
|
|
||||||
free(filename);
|
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
|
|
@ -723,10 +718,7 @@ save_config_filev(clicon_handle h,
|
||||||
clicon_err(OE_PLUGIN, 0, "No such var name: %s", varstr);
|
clicon_err(OE_PLUGIN, 0, "No such var name: %s", varstr);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((filename = realpath(cv_string_get(cv), NULL)) == NULL){
|
filename = cv_string_get(cv);
|
||||||
cli_output(stderr, "Failed to resolve filename\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (clicon_rpc_get_config(h, dbstr,"/", &xt) < 0)
|
if (clicon_rpc_get_config(h, dbstr,"/", &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((f = fopen(filename, "wb")) == NULL){
|
if ((f = fopen(filename, "wb")) == NULL){
|
||||||
|
|
@ -738,8 +730,6 @@ save_config_filev(clicon_handle h,
|
||||||
retval = 0;
|
retval = 0;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
done:
|
done:
|
||||||
if (filename)
|
|
||||||
free(filename);
|
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
|
|
@ -815,6 +805,7 @@ cli_notification_cb(int s,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
cxobj *xe;
|
cxobj *xe;
|
||||||
|
cxobj *x;
|
||||||
enum format_enum format = (enum format_enum)arg;
|
enum format_enum format = (enum format_enum)arg;
|
||||||
|
|
||||||
/* get msg (this is the reason this function is called) */
|
/* get msg (this is the reason this function is called) */
|
||||||
|
|
@ -829,22 +820,26 @@ cli_notification_cb(int s,
|
||||||
}
|
}
|
||||||
if (clicon_msg_decode(reply, &xt) < 0)
|
if (clicon_msg_decode(reply, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
xe = xpath_first(xt, "//event");
|
if ((xe = xpath_first(xt, "//event")) != NULL){
|
||||||
switch (format){
|
x = NULL;
|
||||||
case FORMAT_XML:
|
while ((x = xml_child_each(xe, x, -1)) != NULL) {
|
||||||
if (xml_print(stdout, xe) < 0)
|
switch (format){
|
||||||
goto done;
|
case FORMAT_XML:
|
||||||
break;
|
if (clicon_xml2file(stdout, x, 0, 1) < 0)
|
||||||
case FORMAT_TEXT:
|
goto done;
|
||||||
if (xml2txt(stdout, xe, 0) < 0)
|
break;
|
||||||
goto done;
|
case FORMAT_TEXT:
|
||||||
break;
|
if (xml2txt(stdout, x, 0) < 0)
|
||||||
case FORMAT_JSON:
|
goto done;
|
||||||
if (xml2json(stdout, xe, 0) < 0)
|
break;
|
||||||
goto done;
|
case FORMAT_JSON:
|
||||||
break;
|
if (xml2json(stdout, x, 1) < 0)
|
||||||
default:
|
goto done;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -963,6 +958,127 @@ cli_unlock(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Copy one configuration object to antother
|
||||||
|
*
|
||||||
|
* Works for objects that are items ina yang list with a keyname, eg as:
|
||||||
|
* list sender{
|
||||||
|
* key name;
|
||||||
|
* leaf name{...
|
||||||
|
*
|
||||||
|
* @param[in] h CLICON handle
|
||||||
|
* @param[in] cvv Vector of variables from CLIgen command-line
|
||||||
|
* @param[in] argv Vector: <db>, <xpath>, <field>, <fromvar>, <tovar>
|
||||||
|
* Explanation of argv fields:
|
||||||
|
* db: Database name, eg candidate|tmp|startup
|
||||||
|
* xpath: XPATH expression with exactly two %s pointing to field and from name
|
||||||
|
* field: Name of list key, eg name
|
||||||
|
* fromvar:Name of variable containing name of object to copy from (given by xpath)
|
||||||
|
* tovar: Name of variable containing name of object to copy to.
|
||||||
|
* @code
|
||||||
|
* cli spec:
|
||||||
|
* copy snd <n1:string> to <n2:string>, copy_object("candidate", "/sender[%s=%s]", "from", "n1", "n2");
|
||||||
|
* cli command:
|
||||||
|
* copy snd from to to
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cli_copy_object(clicon_handle h,
|
||||||
|
cvec *cvv,
|
||||||
|
cvec *argv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *db;
|
||||||
|
cxobj *x1 = NULL;
|
||||||
|
cxobj *x2 = NULL;
|
||||||
|
cxobj *x;
|
||||||
|
char *xpath;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
char *keyname;
|
||||||
|
char *fromvar;
|
||||||
|
cg_var *fromcv;
|
||||||
|
char *fromname = NULL;
|
||||||
|
char *tovar;
|
||||||
|
cg_var *tocv;
|
||||||
|
char *toname;
|
||||||
|
|
||||||
|
if (cvec_len(argv) != 5){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "%s: Requires four elements: <db> <xpath> <keyname> <from> <to>", __FUNCTION__);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* First argv argument: Database */
|
||||||
|
db = cv_string_get(cvec_i(argv, 0));
|
||||||
|
/* Second argv argument: xpath */
|
||||||
|
xpath = cv_string_get(cvec_i(argv, 1));
|
||||||
|
/* Third argv argument: name of keyname */
|
||||||
|
keyname = cv_string_get(cvec_i(argv, 2));
|
||||||
|
/* Fourth argv argument: from variable */
|
||||||
|
fromvar = cv_string_get(cvec_i(argv, 3));
|
||||||
|
/* Fifth argv argument: to variable */
|
||||||
|
tovar = cv_string_get(cvec_i(argv, 4));
|
||||||
|
|
||||||
|
/* Get from variable -> cv -> from name */
|
||||||
|
if ((fromcv = cvec_find_var(cvv, fromvar)) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "fromvar '%s' not found in cligen var list", fromvar);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Get from name from cv */
|
||||||
|
fromname = cv_string_get(fromcv);
|
||||||
|
/* Create xpath */
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Sanity check that xpath contains exactly one %s */
|
||||||
|
j = 0;
|
||||||
|
for (i=0; i<strlen(xpath); i++)
|
||||||
|
if (xpath[i] == '%')
|
||||||
|
j++;
|
||||||
|
if (j != 2){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have two '%%'");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb, xpath, keyname, fromname);
|
||||||
|
|
||||||
|
/* Get from object configuration and store in x1 */
|
||||||
|
if (clicon_rpc_get_config(h, db, cbuf_get(cb), &x1) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Get to variable -> cv -> to name */
|
||||||
|
if ((tocv = cvec_find_var(cvv, tovar)) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "tovar '%s' not found in cligen var list", tovar);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
toname = cv_string_get(tocv);
|
||||||
|
/* Create copy xml tree x2 */
|
||||||
|
if ((x2 = xml_new("new", NULL)) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (xml_copy(x1, x2) < 0)
|
||||||
|
goto done;
|
||||||
|
cprintf(cb, "/%s", keyname);
|
||||||
|
if ((x = xpath_first(x2, cbuf_get(cb))) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
x = xml_find(x, "body");
|
||||||
|
xml_value_set(x, toname);
|
||||||
|
/* resuse cb */
|
||||||
|
cbuf_reset(cb);
|
||||||
|
/* create xml copy tree and merge it with database configuration */
|
||||||
|
clicon_xml2cbuf(cb, x2, 0, 0);
|
||||||
|
if (clicon_rpc_edit_config(h, db, OP_MERGE, NULL, cbuf_get(cb)) < 0)
|
||||||
|
goto done;
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
if (x1 != NULL)
|
||||||
|
xml_free(x1);
|
||||||
|
if (x2 != NULL)
|
||||||
|
xml_free(x2);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/* Here are backward compatible cligen callback functions used when
|
/* Here are backward compatible cligen callback functions used when
|
||||||
* the option: CLICON_CLIGEN_CALLBACK_SINGLE_ARG is set.
|
* the option: CLICON_CLIGEN_CALLBACK_SINGLE_ARG is set.
|
||||||
|
|
@ -1045,6 +1161,7 @@ load_config_file(clicon_handle h,
|
||||||
free(vec);
|
free(vec);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
save_config_file(clicon_handle h,
|
save_config_file(clicon_handle h,
|
||||||
cvec *cvv,
|
cvec *cvv,
|
||||||
|
|
|
||||||
|
|
@ -406,9 +406,9 @@ xml2csv(FILE *f, cxobj *x, cvec *cvv)
|
||||||
* Utility function used by cligen spec file
|
* Utility function used by cligen spec file
|
||||||
* @param[in] h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
* @param[in] cvv Vector of variables from CLIgen command-line
|
* @param[in] cvv Vector of variables from CLIgen command-line
|
||||||
* @param[in] arg A string: <dbname> <xpath> [<varname>]
|
* @param[in] argv A string: <dbname> <xpath> [<varname>]
|
||||||
* @param[out] xt Configuration as xml tree.
|
* @param[out] xt Configuration as xml tree.
|
||||||
* Format of arg:
|
* Format of argv:
|
||||||
* <dbname> "running", "candidate", "startup"
|
* <dbname> "running", "candidate", "startup"
|
||||||
* <xpath> xpath expression
|
* <xpath> xpath expression
|
||||||
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
|
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
|
||||||
|
|
@ -620,13 +620,12 @@ show_confv_as_command(clicon_handle h,
|
||||||
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
|
||||||
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
||||||
goto done;
|
goto done;
|
||||||
xml2cli(stdout, xc, prepend, gt, __FUNCTION__); /* cli syntax */
|
xml2cli(stdout, xc, prepend, gt); /* cli syntax */
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (xt)
|
if (xt)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
unchunk_group(__FUNCTION__);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,6 +693,129 @@ show_confv_as_csv(clicon_handle h,
|
||||||
return show_confv_as_csv1(h, cvv, argv);
|
return show_confv_as_csv1(h, cvv, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Generic show configuration CLIGEN callback
|
||||||
|
* Utility function used by cligen spec file
|
||||||
|
* @param[in] h CLICON handle
|
||||||
|
* @param[in] cvv Vector of variables from CLIgen command-line
|
||||||
|
* @param[in] argv String vector: <dbname> <format> <xpath> [<varname>]
|
||||||
|
* Format of argv:
|
||||||
|
* <dbname> "running"|"candidate"|"startup"
|
||||||
|
* <dbname> "text"|"xml"|"json"|"cli"|"netconf" (see format_enum)
|
||||||
|
* <xpath> xpath expression, that may contain one %, eg "/sender[name=%s]"
|
||||||
|
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
|
||||||
|
* @code
|
||||||
|
* show config id <n:string>, show_conf_as("running","xml","iface[name=%s]","n");
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
show_configuration(clicon_handle h,
|
||||||
|
cvec *cvv,
|
||||||
|
cvec *argv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *db;
|
||||||
|
char *formatstr;
|
||||||
|
char *xpath;
|
||||||
|
enum format_enum format;
|
||||||
|
cbuf *cbxpath = NULL;
|
||||||
|
char *attr = NULL;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
cg_var *cvattr;
|
||||||
|
char *val = NULL;
|
||||||
|
cxobj *xt = NULL;
|
||||||
|
cxobj *xc;
|
||||||
|
enum genmodel_type gt;
|
||||||
|
|
||||||
|
if (cvec_len(argv) != 3 && cvec_len(argv) != 4){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "Got %d arguments. Expected: <dbname>,<format>,<xpath>[,<attr>]", cvec_len(argv));
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* First argv argument: Database */
|
||||||
|
db = cv_string_get(cvec_i(argv, 0));
|
||||||
|
/* Second argv argument: Format */
|
||||||
|
formatstr = cv_string_get(cvec_i(argv, 1));
|
||||||
|
if ((format = format_str2int(formatstr)) < 0){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Third argv argument: xpath */
|
||||||
|
xpath = cv_string_get(cvec_i(argv, 2));
|
||||||
|
|
||||||
|
/* Create XPATH variable string */
|
||||||
|
if ((cbxpath = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Fourth argument is stdarg to xpath format string */
|
||||||
|
if (cvec_len(argv) == 4){
|
||||||
|
attr = cv_string_get(cvec_i(argv, 3));
|
||||||
|
j = 0;
|
||||||
|
for (i=0; i<strlen(xpath); i++)
|
||||||
|
if (xpath[i] == '%')
|
||||||
|
j++;
|
||||||
|
if (j != 1){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have a single '%%'");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((cvattr = cvec_find_var(cvv, attr)) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, 0, "attr '%s' not found in cligen var list", attr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((val = cv2str_dup(cvattr)) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, errno, "cv2str_dup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cbxpath, xpath, val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cprintf(cbxpath, "%s", xpath);
|
||||||
|
/* Get configuration from database */
|
||||||
|
if (clicon_rpc_get_config(h, db, cbuf_get(cbxpath), &xt) < 0)
|
||||||
|
goto done;
|
||||||
|
/* Print configuration according to format */
|
||||||
|
switch (format){
|
||||||
|
case FORMAT_XML:
|
||||||
|
xc = NULL; /* Dont print xt itself */
|
||||||
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
|
||||||
|
clicon_xml2file(stdout, xc, 0, 1);
|
||||||
|
break;
|
||||||
|
case FORMAT_JSON:
|
||||||
|
xml2json(stdout, xt, 1);
|
||||||
|
break;
|
||||||
|
case FORMAT_TEXT:
|
||||||
|
xc = NULL; /* Dont print xt itself */
|
||||||
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
|
||||||
|
xml2txt(stdout, xc, 0); /* tree-formed text */
|
||||||
|
break;
|
||||||
|
case FORMAT_CLI:
|
||||||
|
xc = NULL; /* Dont print xt itself */
|
||||||
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
|
||||||
|
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
||||||
|
goto done;
|
||||||
|
xml2cli(stdout, xc, NULL, gt); /* cli syntax */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_NETCONF:
|
||||||
|
fprintf(stdout, "<rpc><edit-config><target><candidate/></target><config>\n");
|
||||||
|
xc = NULL; /* Dont print xt itself */
|
||||||
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
|
||||||
|
clicon_xml2file(stdout, xc, 2, 1);
|
||||||
|
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (xt)
|
||||||
|
xml_free(xt);
|
||||||
|
if (val)
|
||||||
|
free(val);
|
||||||
|
if (cbxpath)
|
||||||
|
cbuf_free(cbxpath);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Show configuration as text given an xpath
|
/*! Show configuration as text given an xpath
|
||||||
* Utility function used by cligen spec file
|
* Utility function used by cligen spec file
|
||||||
* @param[in] h CLICON handle
|
* @param[in] h CLICON handle
|
||||||
|
|
@ -1092,7 +1214,7 @@ show_conf_as_command(clicon_handle h, cvec *cvv, cg_var *arg, char *prepend)
|
||||||
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
|
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
|
||||||
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
||||||
goto done;
|
goto done;
|
||||||
xml2cli(stdout, xc, prepend, gt, __FUNCTION__); /* cli syntax */
|
xml2cli(stdout, xc, prepend, gt); /* cli syntax */
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ int discard_changesv(clicon_handle h, cvec *vars, cvec *argv);
|
||||||
int cli_notifyv(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_notifyv(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_lock(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_lock(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
int cli_unlock(clicon_handle h, cvec *cvv, cvec *argv);
|
int cli_unlock(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
|
int cli_copy_object(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
|
|
||||||
/* cli_common.c: CLIgen old single arg callbacks */
|
/* cli_common.c: CLIgen old single arg callbacks */
|
||||||
int cli_set(clicon_handle h, cvec *vars, cg_var *arg);
|
int cli_set(clicon_handle h, cvec *vars, cg_var *arg);
|
||||||
|
|
@ -125,6 +126,8 @@ int show_confv_as_csv(clicon_handle h, cvec *vars, cvec *argv);
|
||||||
int show_yangv(clicon_handle h, cvec *vars, cvec *argv);
|
int show_yangv(clicon_handle h, cvec *vars, cvec *argv);
|
||||||
int show_confv_xpath(clicon_handle h, cvec *cvv, cvec *argv);
|
int show_confv_xpath(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
|
|
||||||
|
int show_configuration(clicon_handle h, cvec *cvv, cvec *argv);
|
||||||
|
|
||||||
/* cli_show.c: CLIgen old single arg callbacks */
|
/* cli_show.c: CLIgen old single arg callbacks */
|
||||||
int show_conf_as_xml(clicon_handle h, cvec *vars, cg_var *arg);
|
int show_conf_as_xml(clicon_handle h, cvec *vars, cg_var *arg);
|
||||||
int show_conf_as_netconf(clicon_handle h, cvec *vars, cg_var *arg);
|
int show_conf_as_netconf(clicon_handle h, cvec *vars, cg_var *arg);
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,7 @@
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*! Controls how keywords a generated in CLI syntax / prints from object model
|
||||||
* enum gensyntx
|
|
||||||
* Controls how keywords a generated in CLI syntax / prints from obhect model
|
|
||||||
* Example syntax a.b[] $!x $y:
|
* Example syntax a.b[] $!x $y:
|
||||||
* NONE: a b <x> <y>;
|
* NONE: a b <x> <y>;
|
||||||
* VARS: a b <x> y <y>;
|
* VARS: a b <x> y <y>;
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ enum {
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int xml2txt(FILE *f, cxobj *x, int level);
|
int xml2txt(FILE *f, cxobj *x, int level);
|
||||||
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt, const char *label);
|
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt);
|
||||||
int xml_yang_validate(cxobj *xt, yang_stmt *ys) ;
|
int xml_yang_validate(cxobj *xt, yang_stmt *ys) ;
|
||||||
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
||||||
int cvec2xml_1(cvec *cvv, char *toptag, cxobj *xp, cxobj **xt0);
|
int cvec2xml_1(cvec *cvv, char *toptag, cxobj *xp, cxobj **xt0);
|
||||||
|
|
|
||||||
|
|
@ -197,23 +197,26 @@ xml2txt(FILE *f, cxobj *x, int level)
|
||||||
* @param[in] x XML Parse-tree (to translate)
|
* @param[in] x XML Parse-tree (to translate)
|
||||||
* @param[in] prepend0 Print this text in front of all commands.
|
* @param[in] prepend0 Print this text in front of all commands.
|
||||||
* @param[in] gt option to steer cli syntax
|
* @param[in] gt option to steer cli syntax
|
||||||
* @param[in] label Memory chunk allocation label
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml2cli(FILE *f,
|
xml2cli(FILE *f,
|
||||||
cxobj *x,
|
cxobj *x,
|
||||||
char *prepend0,
|
char *prepend0,
|
||||||
enum genmodel_type gt,
|
enum genmodel_type gt)
|
||||||
const char *label)
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xe = NULL;
|
cxobj *xe = NULL;
|
||||||
char *term;
|
char *term;
|
||||||
char *prepend;
|
|
||||||
int bool;
|
int bool;
|
||||||
int nr;
|
int nr;
|
||||||
int i;
|
int i;
|
||||||
|
cbuf *cbpre;
|
||||||
|
|
||||||
|
/* Create prepend variable string */
|
||||||
|
if ((cbpre = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
nr = xml_child_nr(x);
|
nr = xml_child_nr(x);
|
||||||
if (!nr){
|
if (!nr){
|
||||||
if (xml_type(x) == CX_BODY)
|
if (xml_type(x) == CX_BODY)
|
||||||
|
|
@ -226,10 +229,8 @@ xml2cli(FILE *f,
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
prepend = "";
|
|
||||||
if (prepend0)
|
if (prepend0)
|
||||||
if ((prepend = chunk_sprintf(label, "%s%s", prepend, prepend0)) == NULL)
|
cprintf(cbpre, "%s", prepend0);
|
||||||
goto done;
|
|
||||||
/* bool determines when to print a variable keyword:
|
/* bool determines when to print a variable keyword:
|
||||||
!leaf T for all (ie parameter)
|
!leaf T for all (ie parameter)
|
||||||
index GT_NONE F
|
index GT_NONE F
|
||||||
|
|
@ -241,12 +242,11 @@ xml2cli(FILE *f,
|
||||||
*/
|
*/
|
||||||
bool = !leaf(x) || gt == GT_ALL || (gt == GT_VARS && !xml_index(x));
|
bool = !leaf(x) || gt == GT_ALL || (gt == GT_VARS && !xml_index(x));
|
||||||
// bool = (!x->xn_index || gt == GT_ALL);
|
// bool = (!x->xn_index || gt == GT_ALL);
|
||||||
if (bool &&
|
if (bool){
|
||||||
(prepend = chunk_sprintf(label, "%s%s%s",
|
if (cbuf_len(cbpre))
|
||||||
prepend,
|
cprintf(cbpre, " ");
|
||||||
strlen(prepend)?" ":"",
|
cprintf(cbpre, "%s", xml_name(x));
|
||||||
xml_name(x))) == NULL)
|
}
|
||||||
goto done;
|
|
||||||
xe = NULL;
|
xe = NULL;
|
||||||
/* First child is unique, then add that, before looping. */
|
/* First child is unique, then add that, before looping. */
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
@ -255,23 +255,19 @@ xml2cli(FILE *f,
|
||||||
if (xml_index(xe) && i < nr-1)
|
if (xml_index(xe) && i < nr-1)
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
if (xml2cli(f, xe, prepend, gt, label) < 0)
|
if (xml2cli(f, xe, cbuf_get(cbpre), gt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_index(xe)){ /* assume index is first, otherwise need one more while */
|
if (xml_index(xe)){ /* assume index is first, otherwise need one more while */
|
||||||
if (gt ==GT_ALL && (prepend = chunk_sprintf(label, "%s %s",
|
if (gt == GT_ALL)
|
||||||
prepend,
|
cprintf(cbpre, " %s", xml_name(xe));
|
||||||
xml_name(xe))) == NULL)
|
cprintf(cbpre, " %s", xml_value(xml_child_i(xe, 0)));
|
||||||
|
|
||||||
goto done;
|
|
||||||
if ((prepend = chunk_sprintf(label, "%s %s",
|
|
||||||
prepend,
|
|
||||||
xml_value(xml_child_i(xe, 0)))) == NULL)
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (cbpre)
|
||||||
|
cbuf_free(cbpre);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue