removed cli single callback arg code

This commit is contained in:
Olof hagsand 2017-04-06 10:26:10 +02:00
parent 1e92304a52
commit 31c45e5c62
15 changed files with 368 additions and 1120 deletions

View file

@ -197,10 +197,10 @@ cli_signal_flush(clicon_handle h)
* @see cli_callback_generate where arg is generated
*/
static int
cli_dbxmlv(clicon_handle h,
cvec *cvv,
cvec *argv,
enum operation_type op)
cli_dbxml(clicon_handle h,
cvec *cvv,
cvec *argv,
enum operation_type op)
{
int retval = -1;
char *str = NULL;
@ -253,40 +253,54 @@ cli_dbxmlv(clicon_handle h,
}
int
cli_setv(clicon_handle h, cvec *cvv, cvec *argv)
cli_set(clicon_handle h, cvec *cvv, cvec *argv)
{
int retval = 1;
if (cli_dbxmlv(h, cvv, argv, OP_REPLACE) < 0)
if (cli_dbxml(h, cvv, argv, OP_REPLACE) < 0)
goto done;
retval = 0;
done:
return retval;
}
int cli_setv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_set(h, vars, argv);
}
int
cli_mergev(clicon_handle h, cvec *cvv, cvec *argv)
cli_merge(clicon_handle h, cvec *cvv, cvec *argv)
{
int retval = -1;
if (cli_dbxmlv(h, cvv, argv, OP_MERGE) < 0)
if (cli_dbxml(h, cvv, argv, OP_MERGE) < 0)
goto done;
retval = 0;
done:
return retval;
}
int cli_mergev(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_merge(h, vars, argv);
}
int
cli_delv(clicon_handle h, cvec *cvv, cvec *argv)
cli_del(clicon_handle h, cvec *cvv, cvec *argv)
{
int retval = -1;
if (cli_dbxmlv(h, cvv, argv, OP_REMOVE) < 0)
if (cli_dbxml(h, cvv, argv, OP_REMOVE) < 0)
goto done;
retval = 0;
done:
return retval;
}
int cli_delv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_del(h, vars, argv);
}
/*! Set debug level on CLI client (not backend daemon)
* @param[in] h Clicon handle
@ -296,7 +310,7 @@ cli_delv(clicon_handle h, cvec *cvv, cvec *argv)
* _or_ if a 'level' variable is present in vars use that value instead.
*/
int
cli_debug_cliv(clicon_handle h,
cli_debug_cli(clicon_handle h,
cvec *vars,
cvec *argv)
{
@ -318,6 +332,10 @@ cli_debug_cliv(clicon_handle h,
done:
return retval;
}
int cli_debug_cliv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_debug_cli(h, vars, argv);
}
/*! Set debug level on backend daemon (not CLI)
* @param[in] h Clicon handle
@ -327,9 +345,9 @@ cli_debug_cliv(clicon_handle h,
* _or_ if a 'level' variable is present in vars use that value instead.
*/
int
cli_debug_backendv(clicon_handle h,
cvec *vars,
cvec *argv)
cli_debug_backend(clicon_handle h,
cvec *vars,
cvec *argv)
{
int retval = -1;
cg_var *cv;
@ -348,11 +366,15 @@ cli_debug_backendv(clicon_handle h,
done:
return retval;
}
int cli_debug_backendv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_debug_backend(h, vars, argv);
}
/*! Set syntax mode
*/
int
cli_set_modev(clicon_handle h,
cli_set_mode(clicon_handle h,
cvec *vars,
cvec *argv)
{
@ -369,14 +391,18 @@ cli_set_modev(clicon_handle h,
done:
return retval;
}
int cli_set_modev(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_set_mode(h, vars, argv);
}
/*! Start bash from cli callback
* XXX Application specific??
*/
int
cli_start_shellv(clicon_handle h,
cvec *vars,
cvec *argv)
cli_start_shell(clicon_handle h,
cvec *vars,
cvec *argv)
{
char *cmd;
struct passwd *pw;
@ -426,23 +452,31 @@ cli_start_shellv(clicon_handle h,
return 0;
}
int cli_start_shellv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_start_shell(h, vars, argv);
}
/*! Generic quit callback
*/
int
cli_quitv(clicon_handle h,
cli_quit(clicon_handle h,
cvec *vars,
cvec *argv)
{
cli_set_exiting(h, 1);
return 0;
}
int cli_quitv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_quit(h, vars, argv);
}
/*! Generic commit callback
* @param[in] argv No arguments expected
*/
int
cli_commitv(clicon_handle h,
cli_commit(clicon_handle h,
cvec *vars,
cvec *argv)
{
@ -456,11 +490,15 @@ cli_commitv(clicon_handle h,
done:
return retval;
}
int cli_commitv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_commit(h, vars, argv);
}
/*! Generic validate callback
*/
int
cli_validatev(clicon_handle h,
cli_validate(clicon_handle h,
cvec *vars,
cvec *argv)
{
@ -472,7 +510,10 @@ cli_validatev(clicon_handle h,
done:
return retval;
}
int cli_validatev(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_validate(h, vars, argv);
}
/*! Compare two dbs using XML. Write to file and run diff
*/
@ -541,7 +582,7 @@ compare_xmls(cxobj *xc1,
* @param[in] arg arg: 0 as xml, 1: as text
*/
int
compare_dbsv(clicon_handle h,
compare_dbs(clicon_handle h,
cvec *cvv,
cvec *argv)
{
@ -573,6 +614,10 @@ compare_dbsv(clicon_handle h,
return retval;
}
int compare_dbsv(clicon_handle h, cvec *vars, cvec *argv)
{
return compare_dbs(h, vars, argv);
}
/*! Load a configuration file to candidate database
* Utility function used by cligen spec file
@ -589,9 +634,9 @@ compare_dbsv(clicon_handle h,
* @see save_config_file
*/
int
load_config_filev(clicon_handle h,
cvec *cvv,
cvec *argv)
load_config_file(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int ret = -1;
struct stat st;
@ -669,6 +714,10 @@ load_config_filev(clicon_handle h,
close(fd);
return ret;
}
int load_config_filev(clicon_handle h, cvec *vars, cvec *argv)
{
return load_config_file(h, vars, argv);
}
/*! Copy database to local file
* Utility function used by cligen spec file
@ -686,9 +735,9 @@ load_config_filev(clicon_handle h,
* @see load_config_file
*/
int
save_config_filev(clicon_handle h,
cvec *cvv,
cvec *argv)
save_config_file(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
char *filename = NULL;
@ -736,14 +785,18 @@ save_config_filev(clicon_handle h,
fclose(f);
return retval;
}
int save_config_filev(clicon_handle h, cvec *vars, cvec *argv)
{
return save_config_file(h, vars, argv);
}
/*! Delete all elements in a database
* Utility function used by cligen spec file
*/
int
delete_allv(clicon_handle h,
cvec *cvv,
cvec *argv)
delete_all(clicon_handle h,
cvec *cvv,
cvec *argv)
{
char *dbstr;
int retval = -1;
@ -765,16 +818,24 @@ delete_allv(clicon_handle h,
done:
return retval;
}
int delete_allv(clicon_handle h, cvec *vars, cvec *argv)
{
return delete_all(h, vars, argv);
}
/*! Discard all changes in candidate and replace with running
*/
int
discard_changesv(clicon_handle h,
cvec *cvv,
cvec *argv)
discard_changes(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return clicon_rpc_discard_changes(h);
}
int discard_changesv(clicon_handle h, cvec *vars, cvec *argv)
{
return discard_changes(h, vars, argv);
}
/*! Copy from one database to another, eg running->startup
* @param[in] argv a string: "<db1> <db2>" Copy from db1 to db2
@ -864,9 +925,9 @@ cli_notification_cb(int s,
* XXX: format is a memory leak
*/
int
cli_notifyv(clicon_handle h,
cvec *cvv,
cvec *argv)
cli_notify(clicon_handle h,
cvec *cvv,
cvec *argv)
{
char *stream = NULL;
int retval = -1;
@ -897,6 +958,10 @@ cli_notifyv(clicon_handle h,
done:
return retval;
}
int cli_notifyv(clicon_handle h, cvec *vars, cvec *argv)
{
return cli_notify(h, vars, argv);
}
/*! Lock database
*
@ -976,13 +1041,13 @@ cli_unlock(clicon_handle h,
* 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");
* copy snd <n1:string> to <n2:string>, cli_copy_config("candidate", "/sender[%s=%s]", "from", "n1", "n2");
* cli command:
* copy snd from to to
* @endcode
*/
int
cli_copy_object(clicon_handle h,
cli_copy_config(clicon_handle h,
cvec *cvv,
cvec *argv)
{
@ -1080,176 +1145,6 @@ cli_copy_object(clicon_handle h,
return retval;
}
/* Here are backward compatible cligen callback functions used when
* the option: CLICON_CLIGEN_CALLBACK_SINGLE_ARG is set.
*/
cb_single_arg(cli_set)
cb_single_arg(cli_merge)
cb_single_arg(cli_del)
cb_single_arg(cli_debug_cli)
cb_single_arg(cli_debug_backend)
cb_single_arg(cli_set_mode)
cb_single_arg(cli_start_shell)
cb_single_arg(cli_quit)
//cb_single_arg(cli_commit)
int cli_commit(clicon_handle h, cvec *cvv, cg_var *arg)
{
int retval=-1;
cvec *argv = NULL;
if (arg){
if (cv_type_get(arg) > CGV_EMPTY){
cligen_output(stderr, "%s: Illegal cvtype. This is most probably a single-argument cligen callback being used in a multi-argument setting. This can happen if option CLICON_CLIGEN_CALLBACK_SINGLE_ARG is 0 but you call a single argument callback (eg %s) from a .cli file. Please change to a multi-argument callback\n", __FUNCTION__, __FUNCTION__);
goto done;
}
if ((argv = cvec_from_var(arg)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_from_var");
goto done;
}
}
retval = cli_commitv(h, cvv, argv);
done:
if (argv) cvec_free(argv);
return retval;
}
cb_single_arg(cli_validate)
cb_single_arg(compare_dbs)
cb_single_arg(delete_all)
cb_single_arg(discard_changes)
/* Follows some functions not covered by translation macro */
int
load_config_file(clicon_handle h,
cvec *cvv,
cg_var *arg)
{
int retval=-1;
cvec *argv;
cg_var *cv;
char *str;
char **vec = NULL;
int nvec;
/* Split string into two parts and build a cvec of it and supply that to
the multi-arg callback */
if (arg == NULL || (str = cv_string_get(arg)) == NULL){
clicon_err(OE_PLUGIN, 0, "%s: requires string argument", __FUNCTION__);
goto done;
}
if ((vec = clicon_strsep(str, " ", &nvec)) == NULL)
goto done;
if (nvec != 2){
clicon_err(OE_PLUGIN, 0, "Arg syntax is <varname> <replace|merge>");
goto done;
}
if ((argv = cvec_new(nvec)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_from_var");
goto done;
}
cv = cvec_i(argv, 0);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[0]);
cv = cvec_i(argv, 1);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[1]);
retval = load_config_filev(h, cvv, argv);
done:
if (vec)
free(vec);
return retval;
}
int
save_config_file(clicon_handle h,
cvec *cvv,
cg_var *arg)
{
int retval=-1;
cvec *argv;
cg_var *cv;
char *str;
char **vec = NULL;
int nvec;
/* Split string into two parts and build a cvec of it and supply that to
the multi-arg callback */
if (arg == NULL || (str = cv_string_get(arg)) == NULL){
clicon_err(OE_PLUGIN, 0, "%s: requires string argument", __FUNCTION__);
goto done;
}
if ((vec = clicon_strsep(str, " ", &nvec)) == NULL)
goto done;
if (nvec != 2){
clicon_err(OE_PLUGIN, 0, "Arg syntax is <dbname> <varname>");
goto done;
}
if ((argv = cvec_new(nvec)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_from_var");
goto done;
}
cv = cvec_i(argv, 0);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[0]);
cv = cvec_i(argv, 1);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[1]);
retval = save_config_filev(h, cvv, argv);
done:
if (vec)
free(vec);
return retval;
}
int
cli_notify(clicon_handle h,
cvec *cvv,
cg_var *arg)
{
int retval=-1;
cvec *argv;
cg_var *cv;
char *str;
char **vec = NULL;
int nvec;
/* Split string into two parts and build a cvec of it and supply that to
the multi-arg callback */
if (arg == NULL || (str = cv_string_get(arg)) == NULL){
clicon_err(OE_PLUGIN, 0, "%s: requires string argument", __FUNCTION__);
goto done;
}
if ((vec = clicon_strsep(str, " ", &nvec)) == NULL)
goto done;
if (nvec != 2 && nvec != 3){
clicon_err(OE_PLUGIN, 0, "Arg syntax is <logstream> <status> [<format>]");
goto done;
}
if ((argv = cvec_new(nvec)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_from_var");
goto done;
}
cv = cvec_i(argv, 0);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[0]);
cv = cvec_i(argv, 1);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[1]);
if (nvec > 2){
cv = cvec_i(argv, 2);
cv_type_set(cv, CGV_STRING);
cv_string_set(cv, vec[2]);
}
retval = cli_notifyv(h, cvv, argv);
done:
if (vec)
free(vec);
return retval;
}
/*! set debug level on stderr (not syslog).
* The level is either what is specified in arg as int argument.

View file

@ -65,10 +65,9 @@
/* This is the default callback function. But this is typically overwritten */
#define GENERATE_CALLBACK "cli_set"
#define GENERATE_CALLBACKV "cli_setv"
/* variable expand function */
#define GENERATE_EXPAND_XMLDB "expandv_dbvar"
#define GENERATE_EXPAND_XMLDB "expand_dbvar"
/*=====================================================================
* YANG generate CLI
@ -154,10 +153,7 @@ cli_callback_generate(clicon_handle h,
if (yang2xmlkeyfmt(ys, 0, &xkfmt) < 0)
goto done;
if (clicon_option_int(h, "CLICON_CLIGEN_CALLBACK_SINGLE_ARG")==1)
cprintf(cb0, ",%s(\"%s\")", GENERATE_CALLBACK, xkfmt);
else
cprintf(cb0, ",%s(\"%s\")", GENERATE_CALLBACKV, xkfmt);
cprintf(cb0, ",%s(\"%s\")", GENERATE_CALLBACK, xkfmt);
retval = 0;
done:
if (xkfmt)

View file

@ -372,26 +372,13 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
}
/* Resolve callback names to function pointers. */
if (clicon_option_int(h, "CLICON_CLIGEN_CALLBACK_SINGLE_ARG")==1){
if (cligen_callback_str2fn(pt, (cg_str2fn_t*)clixon_str2fn, handle) < 0){
clicon_err(OE_PLUGIN, 0, "Mismatch between CLIgen file '%s' and CLI plugin file '%s'. Some possible errors:\n\t1. A function given in the CLIgen file does not exist in the plugin (ie link error)\n\t2. The CLIgen spec does not point to the correct plugin .so file (CLICON_PLUGIN=\"%s\" is wrong)",
filename, plgnam, plgnam);
goto done;
}
}
else
if (cligen_callbackv_str2fn(pt, (cgv_str2fn_t*)clixon_str2fn, handle) < 0){
clicon_err(OE_PLUGIN, 0, "Mismatch between CLIgen file '%s' and CLI plugin file '%s'. Some possible errors:\n\t1. A function given in the CLIgen file does not exist in the plugin (ie link error)\n\t2. The CLIgen spec does not point to the correct plugin .so file (CLICON_PLUGIN=\"%s\" is wrong)",
filename, plgnam, plgnam);
goto done;
}
if (clicon_option_int(h, "CLICON_CLIGEN_EXPAND_SINGLE_ARG")==1){
if (cligen_expand_str2fn(pt, (expand_str2fn_t*)clixon_str2fn, handle) < 0)
goto done;
if (cligen_callbackv_str2fn(pt, (cgv_str2fn_t*)clixon_str2fn, handle) < 0){
clicon_err(OE_PLUGIN, 0, "Mismatch between CLIgen file '%s' and CLI plugin file '%s'. Some possible errors:\n\t1. A function given in the CLIgen file does not exist in the plugin (ie link error)\n\t2. The CLIgen spec does not point to the correct plugin .so file (CLICON_PLUGIN=\"%s\" is wrong)",
filename, plgnam, plgnam);
goto done;
}
else
if (cligen_expandv_str2fn(pt, (expandv_str2fn_t*)clixon_str2fn, handle) < 0)
goto done;
if (cligen_expandv_str2fn(pt, (expandv_str2fn_t*)clixon_str2fn, handle) < 0)
goto done;
/* Make sure we have a syntax mode specified */
if (mode == NULL || strlen(mode) < 1) { /* may be null if not given in file */

View file

@ -74,9 +74,6 @@
#include "clixon_cli_api.h"
#include "cli_common.h" /* internal functions */
static int xml2csv(FILE *f, cxobj *x, cvec *cvv);
//static int xml2csv_raw(FILE *f, cxobj *x);
/*! Completion callback intended for automatically generated data model
*
* Returns an expand-type list of commands as used by cligen 'expand'
@ -94,12 +91,12 @@ static int xml2csv(FILE *f, cxobj *x, cvec *cvv);
* XXX: helptexts?
*/
int
expandv_dbvar(void *h,
char *name,
cvec *cvv,
cvec *argv,
cvec *commands,
cvec *helptexts)
expand_dbvar(void *h,
char *name,
cvec *cvv,
cvec *argv,
cvec *commands,
cvec *helptexts)
{
int retval = -1;
char *xkfmt;
@ -197,13 +194,24 @@ expandv_dbvar(void *h,
free(xkpath);
return retval;
}
int
expandv_dbvar(void *h,
char *name,
cvec *cvv,
cvec *argv,
cvec *commands,
cvec *helptexts)
{
return expand_dbvar(h, name, cvv, argv, commands, helptexts);
}
/*! List files in a directory
*/
int
expand_dir(char *dir, int *nr, char ***commands, mode_t flags, int detail)
expand_dir(char *dir,
int *nr,
char ***commands,
mode_t flags,
int detail)
{
DIR *dirp;
struct dirent *dp;
@ -313,13 +321,11 @@ expand_dir(char *dir, int *nr, char ***commands, mode_t flags, int detail)
return retval;
}
/*! CLI callback show yang spec. If arg given matches yang argument string */
int
show_yangv(clicon_handle h,
cvec *cvv,
cvec *argv)
show_yang(clicon_handle h,
cvec *cvv,
cvec *argv)
{
yang_node *yn;
char *str = NULL;
@ -335,362 +341,9 @@ show_yangv(clicon_handle h,
yang_print(stdout, yn, 0);
return 0;
}
#ifdef notused
/*! XML to CSV raw variant
* @see xml2csv
*/
static int
xml2csv_raw(FILE *f, cxobj *x)
int show_yangv(clicon_handle h, cvec *vars, cvec *argv)
{
cxobj *xc;
cxobj *xb;
int retval = -1;
int i = 0;
xc = NULL;
while ((xc = xml_child_each(x, xc, CX_ELMNT)) != NULL) {
if (xml_child_nr(xc)){
xb = xml_child_i(xc, 0);
if (xml_type(xb) == CX_BODY){
if (i++)
fprintf(f, ";");
fprintf(f, "%s", xml_value(xb));
}
}
}
fprintf(f, "\n");
retval = 0;
return retval;
}
#endif
/*! Translate XML -> CSV commands
* Can only be made in a 'flat tree', ie on the form:
* <X><A>B</A></X> -->
* Type, A
* X, B
* @param[in] f Output file
* @param[in] x XML tree
* @param[in] cvv A vector of field names present in XML
* This means that only fields in x that are listed in cvv will be printed.
*/
static int
xml2csv(FILE *f, cxobj *x, cvec *cvv)
{
cxobj *xe, *xb;
int retval = -1;
cg_var *vs;
fprintf(f, "%s", xml_name(x));
xe = NULL;
vs = NULL;
while ((vs = cvec_each(cvv, vs))) {
if ((xe = xml_find(x, cv_name_get(vs))) == NULL){
fprintf(f, ";");
continue;
}
if (xml_child_nr(xe)){
xb = xml_child_i(xe, 0);
fprintf(f, ";%s", xml_value(xb));
}
}
fprintf(f, "\n");
retval = 0;
return retval;
}
/*! Generic function for showing configurations.
* 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 A string: <dbname> <xpath> [<varname>]
* @param[out] xt Configuration as xml tree.
* Format of argv:
* <dbname> "running", "candidate", "startup"
* <xpath> xpath expression
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
* @code
* show config id <n:string>, show_conf_as("running interfaces/interface[name=%s] n");
* @endcode
*/
static int
show_confv_as(clicon_handle h,
cvec *cvv,
cvec *argv,
cxobj **xt) /* top xml */
{
int retval = -1;
char *db;
char *xpath;
char *attr = NULL;
cbuf *cbx = NULL;
int i;
int j;
cg_var *cvattr;
char *val = NULL;
if (cvec_len(argv) != 2 && cvec_len(argv) != 3){
if (cvec_len(argv)==1)
clicon_err(OE_PLUGIN, 0, "Got single argument:\"%s\". Expected \"<dbname>,<xpath>[,<attr>]\"", cv_string_get(cvec_i(argv,0)));
else
clicon_err(OE_PLUGIN, 0, "Got %d arguments. Expected: <dbname>,<xpath>[,<attr>]", cvec_len(argv));
goto done;
}
/* Dont get attr here, take it from arg instead */
db = cv_string_get(cvec_i(argv, 0));
if (strcmp(db, "running") != 0 &&
strcmp(db, "candidate") != 0 &&
strcmp(db, "startup") != 0) {
clicon_err(OE_PLUGIN, 0, "No such db name: %s", db);
goto done;
}
xpath = cv_string_get(cvec_i(argv, 1));
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_PLUGIN, errno, "cbuf_new");
goto done;
}
if (cvec_len(argv) == 3){
attr = cv_string_get(cvec_i(argv, 2));
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(cbx, xpath, val);
}
else
cprintf(cbx, "%s", xpath);
if (clicon_rpc_get_config(h, db, cbuf_get(cbx), xt) < 0)
goto done;
retval = 0;
done:
if (val)
free(val);
if (cbx)
cbuf_free(cbx);
return retval;
}
/*! Show a configuration database on stdout using XML format
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @param[in] netconf If set print as netconf edit-config, otherwise just xml
* @see show_conf_as the main function
*/
static int
show_confv_as_xml1(clicon_handle h,
cvec *cvv,
cvec *argv,
int netconf)
{
cxobj *xt = NULL;
cxobj *xc;
int retval = -1;
if (show_confv_as(h, cvv, argv, &xt) < 0)
goto done;
if (netconf) /* netconf prefix */
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, netconf?2:0, 1);
if (netconf) /* netconf postfix */
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\n");
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
/*! Show configuration as prettyprinted xml
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @see show_conf_as the main function
*/
int
show_confv_as_xml(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return show_confv_as_xml1(h, cvv, argv, 0);
}
/*! Show configuration as prettyprinted xml with netconf hdr/tail
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @see show_conf_as the main function
*/
int
show_confv_as_netconf(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return show_confv_as_xml1(h, cvv, argv, 1);
}
/*! Show configuration as JSON
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @see show_conf_as the main function
*/
int
show_confv_as_json(clicon_handle h,
cvec *cvv,
cvec *argv)
{
cxobj *xt = NULL;
int retval = -1;
if (show_confv_as(h, cvv, argv, &xt) < 0)
goto done;
xml2json(stdout, xt, 1);
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
/*! Show configuration as text
* Utility function used by cligen spec file
*/
static int
show_confv_as_text1(clicon_handle h,
cvec *cvv,
cvec *argv)
{
cxobj *xt = NULL;
cxobj *xc;
int retval = -1;
if (show_confv_as(h, cvv, argv, &xt) < 0)
goto done;
xc = NULL; /* Dont print xt itself */
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
xml2txt(stdout, xc, 0); /* tree-formed text */
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
/* Show configuration as commands, ie not tree format but as one-line commands
*/
static int
show_confv_as_command(clicon_handle h,
cvec *cvv,
cvec *argv,
char *prepend)
{
cxobj *xt = NULL;
cxobj *xc;
enum genmodel_type gt;
int retval = -1;
if (show_confv_as(h, cvv, argv, &xt) < 0)
goto done;
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, prepend, gt); /* cli syntax */
}
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
int
show_confv_as_text(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return show_confv_as_text1(h, cvv, argv);
}
int
show_confv_as_cli(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return show_confv_as_command(h, cvv, argv, NULL); /* XXX: how to set prepend? */
}
static int
show_confv_as_csv1(clicon_handle h,
cvec *cvv0,
cvec *argv)
{
cxobj *xt = NULL;
cxobj *xc;
int retval = -1;
cvec *cvv=NULL;
char *str;
if (show_confv_as(h, cvv0, argv, &xt) < 0)
goto done;
xc = NULL; /* Dont print xt itself */
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
if ((str = chunk_sprintf(__FUNCTION__, "%s[]", xml_name(xc))) == NULL)
goto done;
#ifdef NOTYET /* yang-spec? */
if (ds==NULL && (ds = key2spec_key(dbspec, str)) != NULL){
cg_var *vs;
fprintf(stdout, "Type");
cvv = db_spec2cvec(ds);
vs = NULL;
while ((vs = cvec_each(cvv, vs)))
fprintf(stdout, ";%s", cv_name_get(vs));
fprintf(stdout, "\n");
} /* Now values just need to follow,... */
#endif /* yang-spec? */
if (cvv== NULL)
goto done;
xml2csv(stdout, xc, cvv); /* csv syntax */
}
retval = 0;
done:
if (xt)
xml_free(xt);
unchunk_group(__FUNCTION__);
return retval;
}
int
show_confv_as_csv(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return show_confv_as_csv1(h, cvv, argv);
return show_yang(h, vars, argv);
}
/*! Generic show configuration CLIGEN callback
@ -704,13 +357,13 @@ show_confv_as_csv(clicon_handle h,
* <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");
* show config id <n:string>, cli_show_config("running","xml","iface[name=%s]","n");
* @endcode
*/
int
show_configuration(clicon_handle h,
cvec *cvv,
cvec *argv)
cli_show_config(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
char *db;
@ -824,9 +477,9 @@ done:
* @note Hardcoded that a variable in cvv is named "xpath"
*/
int
show_confv_xpath(clicon_handle h,
cvec *cvv,
cvec *argv)
show_conf_xpath(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
char *str;
@ -866,417 +519,7 @@ done:
xml_free(xt);
return retval;
}
/*=================================================================
* Here are backward compatible cligen callback functions used when
* the option: CLICON_CLIGEN_CALLBACK_SINGLE_ARG is set.
*/
cb_single_arg(show_yang)
/*! This is obsolete version of expandv_dbvar
* If CLICON_CLIGEN_EXPAND_SINGLE_ARG is set
*/
int
expand_dbvar(void *h,
char *name,
cvec *cvv,
cg_var *arg,
int *nr,
char ***commands,
char ***helptexts)
int show_confv_xpath(clicon_handle h, cvec *vars, cvec *argv)
{
int nvec;
char **vec = NULL;
int retval = -1;
char *xkfmt;
char *str;
char *dbstr;
cxobj *xt = NULL;
char *xkpath = NULL;
cxobj **xvec = NULL;
size_t xlen = 0;
cxobj *x;
char *bodystr;
int i;
int j;
int k;
int i0;
if (arg == NULL || (str = cv_string_get(arg)) == NULL){
clicon_err(OE_PLUGIN, 0, "%s: requires string argument", __FUNCTION__);
goto done;
}
/* In the example, str = "candidate /x/m1/%s/b" */
if ((vec = clicon_strsep(str, " ", &nvec)) == NULL)
goto done;
dbstr = vec[0];
if (strcmp(dbstr, "running") != 0 &&
strcmp(dbstr, "candidate") != 0 &&
strcmp(dbstr, "startup") != 0){
clicon_err(OE_PLUGIN, 0, "No such db name: %s", dbstr);
goto done;
}
xkfmt = vec[1];
/* xkfmt = /interface=%s/address=%s
--> /interface=eth0/address=1.2.3.4
*/
if (xmlkeyfmt2xpath(xkfmt, cvv, &xkpath) < 0)
goto done;
if (clicon_rpc_get_config(h, dbstr, "/", &xt) < 0)
goto done;
if (xpath_vec(xt, xkpath, &xvec, &xlen) < 0)
goto done;
/* One round to detect duplicates
* XXX The code below would benefit from some cleanup
*/
j = 0;
for (i = 0; i < xlen; i++) {
char *str;
x = xvec[i];
if (xml_type(x) == CX_BODY)
bodystr = xml_value(x);
else
bodystr = xml_body(x);
if (bodystr == NULL){
clicon_err(OE_CFG, 0, "No xml body");
goto done;
}
/* detect duplicates */
for (k=0; k<j; k++){
if (xml_type(xvec[k]) == CX_BODY)
str = xml_value(xvec[k]);
else
str = xml_body(xvec[k]);
if (strcmp(str, bodystr)==0)
break;
}
if (k==j) /* not duplicate */
xvec[j++] = x;
}
xlen = j;
i0 = *nr;
*nr += xlen;
if ((*commands = realloc(*commands, sizeof(char *) * (*nr))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc: %s", strerror (errno));
goto done;
}
for (i = 0; i < xlen; i++) {
x = xvec[i];
if (xml_type(x) == CX_BODY)
bodystr = xml_value(x);
else
bodystr = xml_body(x);
if (bodystr == NULL){
clicon_err(OE_CFG, 0, "No xml body");
goto done;
}
(*commands)[i0+i] = strdup(bodystr);
}
retval = 0;
done:
if (vec)
free(vec);
if (xvec)
free(xvec);
if (xt)
xml_free(xt);
if (xkpath)
free(xkpath);
return retval;
return show_conf_xpath(h, vars, argv);
}
/*! Generic function for showing configurations.
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @param[out] xt Configuration as xml tree.
* Format of arg:
* <dbname> "running", "candidate", "startup"
* <xpath> xpath expression
* <varname> optional name of variable in cvv. If set, xpath must have a '%s'
* @code
* show config id <n:string>, show_conf_as("running interfaces/interface[name=%s] n");
* @endcode
*/
static int
show_conf_as(clicon_handle h,
cvec *cvv,
cg_var *arg,
cxobj **xt) /* top xml */
{
int retval = -1;
char *db;
char **vec = NULL;
int nvec;
char *str;
char *xpath;
char *attr = NULL;
cbuf *cbx = NULL;
int i;
int j;
cg_var *cvattr;
char *val = NULL;
if (arg == NULL || (str = cv_string_get(arg)) == NULL){
clicon_err(OE_PLUGIN, 0, "%s: requires string argument", __FUNCTION__);
goto done;
}
if ((vec = clicon_strsep(str, " ", &nvec)) == NULL)
goto done;
if (nvec != 2 && nvec != 3){
clicon_err(OE_PLUGIN, 0, "format error \"%s\" - expected <dbname> <xpath> [<attr>] got %d arg", str, nvec);
goto done;
}
/* Dont get attr here, take it from arg instead */
db = vec[0];
if (strcmp(db, "running") != 0 &&
strcmp(db, "candidate") != 0 &&
strcmp(db, "startup") != 0) {
clicon_err(OE_PLUGIN, 0, "No such db name: %s", db);
goto done;
}
xpath = vec[1];
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_PLUGIN, errno, "cbuf_new");
goto done;
}
if (nvec == 3){
attr = vec[2];
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(cbx, xpath, val);
}
else
cprintf(cbx, "%s", xpath);
if (clicon_rpc_get_config(h, db, cbuf_get(cbx), xt) < 0)
goto done;
retval = 0;
done:
if (val)
free(val);
if (cbx)
cbuf_free(cbx);
if (vec)
free(vec);
return retval;
}
/*! Show a configuration database on stdout using XML format
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @param[in] netconf If set print as netconf edit-config, otherwise just xml
* @see show_conf_as the main function
*/
static int
show_conf_as_xml1(clicon_handle h,
cvec *cvv,
cg_var *arg,
int netconf)
{
cxobj *xt = NULL;
cxobj *xc;
int retval = -1;
if (show_conf_as(h, cvv, arg, &xt) < 0)
goto done;
if (netconf) /* netconf prefix */
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, netconf?2:0, 1);
if (netconf) /* netconf postfix */
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\n");
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
/*! Show configuration as prettyprinted xml
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @see show_conf_as the main function
*/
int
show_conf_as_xml(clicon_handle h,
cvec *cvv,
cg_var *arg)
{
return show_conf_as_xml1(h, cvv, arg, 0);
}
/*! Show configuration as prettyprinted xml with netconf hdr/tail
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @see show_conf_as the main function
*/
int
show_conf_as_netconf(clicon_handle h,
cvec *cvv,
cg_var *arg)
{
return show_conf_as_xml1(h, cvv, arg, 1);
}
/*! Show configuration as JSON
* Utility function used by cligen spec file
* @param[in] h CLICON handle
* @param[in] cvv Vector of variables from CLIgen command-line
* @param[in] arg A string: <dbname> <xpath> [<varname>]
* @see show_conf_as the main function
*/
int
show_conf_as_json(clicon_handle h,
cvec *cvv,
cg_var *arg)
{
cxobj *xt = NULL;
int retval = -1;
if (show_conf_as(h, cvv, arg, &xt) < 0)
goto done;
xml2json(stdout, xt, 1);
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
/*! Show configuration as text
* Utility function used by cligen spec file
*/
static int
show_conf_as_text1(clicon_handle h, cvec *cvv, cg_var *arg)
{
cxobj *xt = NULL;
cxobj *xc;
int retval = -1;
if (show_conf_as(h, cvv, arg, &xt) < 0)
goto done;
xc = NULL; /* Dont print xt itself */
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
xml2txt(stdout, xc, 0); /* tree-formed text */
retval = 0;
done:
if (xt)
xml_free(xt);
unchunk_group(__FUNCTION__);
return retval;
}
/* Show configuration as commands, ie not tree format but as one-line commands
*/
static int
show_conf_as_command(clicon_handle h, cvec *cvv, cg_var *arg, char *prepend)
{
cxobj *xt = NULL;
cxobj *xc;
enum genmodel_type gt;
int retval = -1;
if ((xt = xml_new("tmp", NULL)) == NULL)
goto done;
if (show_conf_as(h, cvv, arg, &xt) < 0)
goto done;
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, prepend, gt); /* cli syntax */
}
retval = 0;
done:
if (xt)
xml_free(xt);
unchunk_group(__FUNCTION__);
return retval;
}
int
show_conf_as_text(clicon_handle h, cvec *cvv, cg_var *arg)
{
return show_conf_as_text1(h, cvv, arg);
}
int
show_conf_as_cli(clicon_handle h, cvec *cvv, cg_var *arg)
{
return show_conf_as_command(h, cvv, arg, NULL); /* XXX: how to set prepend? */
}
static int
show_conf_as_csv1(clicon_handle h, cvec *cvv0, cg_var *arg)
{
cxobj *xt = NULL;
cxobj *xc;
int retval = -1;
cvec *cvv=NULL;
char *str;
if (show_conf_as(h, cvv0, arg, &xt) < 0)
goto done;
xc = NULL; /* Dont print xt itself */
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
if ((str = chunk_sprintf(__FUNCTION__, "%s[]", xml_name(xc))) == NULL)
goto done;
#ifdef NOTYET /* yang-spec? */
if (ds==NULL && (ds = key2spec_key(dbspec, str)) != NULL){
cg_var *vs;
fprintf(stdout, "Type");
cvv = db_spec2cvec(ds);
vs = NULL;
while ((vs = cvec_each(cvv, vs)))
fprintf(stdout, ";%s", cv_name_get(vs));
fprintf(stdout, "\n");
} /* Now values just need to follow,... */
#endif /* yang-spec? */
if (cvv== NULL)
goto done;
xml2csv(stdout, xc, cvv); /* csv syntax */
}
retval = 0;
done:
if (xt)
xml_free(xt);
unchunk_group(__FUNCTION__);
return retval;
}
int
show_conf_as_csv(clicon_handle h, cvec *cvv, cg_var *arg)
{
return show_conf_as_csv1(h, cvv, arg);
}

View file

@ -74,67 +74,76 @@ int cli_notification_register(clicon_handle h, char *stream, enum format_enum fo
#define cli_output cligen_output
/* cli_common.c: CLIgen new vector callbacks */
int cli_set(clicon_handle h, cvec *vars, cvec *argv);
int cli_setv(clicon_handle h, cvec *vars, cvec *argv);
int cli_merge(clicon_handle h, cvec *vars, cvec *argv);
int cli_mergev(clicon_handle h, cvec *vars, cvec *argv);
int cli_del(clicon_handle h, cvec *vars, cvec *argv);
int cli_delv(clicon_handle h, cvec *vars, cvec *argv);
int cli_debug_cli(clicon_handle h, cvec *vars, cvec *argv);
int cli_debug_cliv(clicon_handle h, cvec *vars, cvec *argv);
int cli_debug_backend(clicon_handle h, cvec *vars, cvec *argv);
int cli_debug_backendv(clicon_handle h, cvec *vars, cvec *argv);
int cli_set_mode(clicon_handle h, cvec *vars, cvec *argv);
int cli_set_modev(clicon_handle h, cvec *vars, cvec *argv);
int cli_start_shell(clicon_handle h, cvec *vars, cvec *argv);
int cli_start_shellv(clicon_handle h, cvec *vars, cvec *argv);
int cli_quit(clicon_handle h, cvec *vars, cvec *argv);
int cli_quitv(clicon_handle h, cvec *vars, cvec *argv);
int cli_commit(clicon_handle h, cvec *vars, cvec *argv);
int cli_commitv(clicon_handle h, cvec *vars, cvec *argv);
int cli_validate(clicon_handle h, cvec *vars, cvec *argv);
int cli_validatev(clicon_handle h, cvec *vars, cvec *argv);
int compare_dbs(clicon_handle h, cvec *vars, cvec *argv);
int compare_dbsv(clicon_handle h, cvec *vars, cvec *argv);
int load_config_file(clicon_handle h, cvec *vars, cvec *argv);
int load_config_filev(clicon_handle h, cvec *vars, cvec *argv);
int save_config_file(clicon_handle h, cvec *vars, cvec *argv);
int save_config_filev(clicon_handle h, cvec *vars, cvec *argv);
int delete_all(clicon_handle h, cvec *vars, cvec *argv);
int delete_allv(clicon_handle h, cvec *vars, cvec *argv);
int discard_changes(clicon_handle h, cvec *vars, cvec *argv);
int discard_changesv(clicon_handle h, cvec *vars, cvec *argv);
int cli_notify(clicon_handle h, cvec *cvv, cvec *argv);
int cli_notifyv(clicon_handle h, cvec *cvv, cvec *argv);
int db_copy(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_copy_object(clicon_handle h, cvec *cvv, cvec *argv);
/* cli_common.c: CLIgen old single arg callbacks */
int cli_set(clicon_handle h, cvec *vars, cg_var *arg);
int cli_merge(clicon_handle h, cvec *vars, cg_var *arg);
int cli_del(clicon_handle h, cvec *vars, cg_var *arg);
int cli_debug_cli(clicon_handle h, cvec *vars, cg_var *arg);
int cli_debug_backend(clicon_handle h, cvec *vars, cg_var *argv);
int cli_set_mode(clicon_handle h, cvec *vars, cg_var *argv);
int cli_start_shell(clicon_handle h, cvec *vars, cg_var *argv);
int cli_quit(clicon_handle h, cvec *vars, cg_var *arg);
int cli_commit(clicon_handle h, cvec *vars, cg_var *arg);
int cli_validate(clicon_handle h, cvec *vars, cg_var *arg);
int compare_dbs(clicon_handle h, cvec *vars, cg_var *arg);
int load_config_file(clicon_handle h, cvec *vars, cg_var *arg);
int save_config_file(clicon_handle h, cvec *vars, cg_var *arg);
int delete_all(clicon_handle h, cvec *vars, cg_var *arg);
int discard_changes(clicon_handle h, cvec *vars, cg_var *arg);
int cli_notify(clicon_handle h, cvec *cvv, cg_var *arg);
int cli_copy_config(clicon_handle h, cvec *cvv, cvec *argv);
/* In cli_show.c */
int expand_dir(char *dir, int *nr, char ***commands, mode_t flags, int detail);
int expand_dbvar(void *h, char *name, cvec *cvv, cvec *argv,
cvec *commands, cvec *helptexts);
int expandv_dbvar(void *h, char *name, cvec *cvv, cvec *argv,
cvec *commands, cvec *helptexts);
/* cli_show.c: CLIgen new vector arg callbacks */
int show_confv_as_xml(clicon_handle h, cvec *vars, cvec *argv);
int show_confv_as_netconf(clicon_handle h, cvec *vars, cvec *argv);
int show_confv_as_json(clicon_handle h, cvec *vars, cvec *argv);
int show_confv_as_text(clicon_handle h, cvec *vars, cvec *argv);
int show_confv_as_cli(clicon_handle h, cvec *vars, cvec *argv);
int show_confv_as_csv(clicon_handle h, cvec *vars, cvec *argv);
int show_yang(clicon_handle h, cvec *vars, cvec *argv);
int show_yangv(clicon_handle h, cvec *vars, cvec *argv);
int show_conf_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 */
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_json(clicon_handle h, cvec *vars, cg_var *arg);
int show_conf_as_text(clicon_handle h, cvec *vars, cg_var *arg);
int show_conf_as_cli(clicon_handle h, cvec *vars, cg_var *arg);
int show_conf_as_csv(clicon_handle h, cvec *vars, cg_var *arg);
int show_yang(clicon_handle h, cvec *vars, cg_var *arg);
int cli_show_config(clicon_handle h, cvec *cvv, cvec *argv);
#endif /* _CLIXON_CLI_API_H_ */