Added option CLICON_CLISPEC_FILE; Replaced cli_ functiuons with cligen_

This commit is contained in:
Olof hagsand 2017-10-17 19:35:46 +02:00
parent 1c871d9ba2
commit 4b0c060667
12 changed files with 184 additions and 250 deletions

View file

@ -2,6 +2,14 @@
## 3.3.3 Upcoming ## 3.3.3 Upcoming
* Added option CLICON_CLISPEC_FILE as complement to CLICON_CLISPEC_DIR to
specify single CLI specification file, not only directory containing files.
* Replaced the following cli_ functions with their original cligen_functions:
cli_exiting, cli_set_exiting, cli_comment,
cli_set_comment, cli_tree_add, cli_tree_active,
cli_tree_active_set, cli_tree.
* Apple Darwin port * Apple Darwin port
* Added a format parameter to clicon_rpc_generate_error() and changed error * Added a format parameter to clicon_rpc_generate_error() and changed error

View file

@ -128,14 +128,14 @@ usage(char *argv0, clicon_handle h)
fprintf(stderr, "usage:%s\n" fprintf(stderr, "usage:%s\n"
"where options are\n" "where options are\n"
" -h\t\tHelp\n" " -h\t\tHelp\n"
" -D <level>\tdebug\n" " -D <level>\tDebug level\n"
" -f <file>\tCLICON config file (mandatory)\n" " -f <file>\tCLICON config file (mandatory)\n"
" -d <dir>\tSpecify backend plugin directory (default: %s)\n" " -d <dir>\tSpecify backend plugin directory (default: %s)\n"
" -b <dir>\tSpecify XMLDB database directory\n" " -b <dir>\tSpecify XMLDB database directory\n"
" -z\t\tKill other config daemon and exit\n" " -z\t\tKill other config daemon and exit\n"
" -F\t\tforeground\n" " -F\t\tRun in foreground, do not run as daemon\n"
" -1\t\tonce (dont wait for events)\n" " -1\t\tRun once and then quit (dont wait for events)\n"
" -u <path>\tconfig UNIX domain path / ip address (default: %s)\n" " -u <path>\tConfig UNIX domain path / ip address (default: %s)\n"
" -P <file>\tPid filename (default: %s)\n" " -P <file>\tPid filename (default: %s)\n"
" -I\t\tInitialize running state database\n" " -I\t\tInitialize running state database\n"
" -R\t\tCall plugin_reset() in plugins to reset system state in running db (use with -I)\n" " -R\t\tCall plugin_reset() in plugins to reset system state in running db (use with -I)\n"

View file

@ -520,7 +520,7 @@ cli_quit(clicon_handle h,
cvec *vars, cvec *vars,
cvec *argv) cvec *argv)
{ {
cli_set_exiting(h, 1); cligen_exiting_set(cli_cligen(h), 1);
return 0; return 0;
} }
int cli_quitv(clicon_handle h, cvec *vars, cvec *argv) int cli_quitv(clicon_handle h, cvec *vars, cvec *argv)

View file

@ -86,9 +86,7 @@ struct cli_handle {
}; };
/* /*! Return a clicon handle for other CLICON API calls
* cli_handle_init
* returns a clicon handle for other CLICON API calls
*/ */
clicon_handle clicon_handle
cli_handle_init(void) cli_handle_init(void)
@ -153,85 +151,14 @@ cli_syntax_set(clicon_handle h,
return 0; return 0;
} }
/*----------------------------------------------------------
* cligen access functions /*! Return clicon handle */
*----------------------------------------------------------*/
cligen_handle cligen_handle
cli_cligen(clicon_handle h) cli_cligen(clicon_handle h)
{ {
return cligen(h); return cligen(h);
} }
/*
* cli_interactive and clicon_eval
*/
int
cli_exiting(clicon_handle h)
{
cligen_handle ch = cligen(h);
return cligen_exiting(ch);
}
/*
* cli_common.c: cli_quit
* cli_interactive()
*/
int
cli_set_exiting(clicon_handle h, int exiting)
{
cligen_handle ch = cligen(h);
return cligen_exiting_set(ch, exiting);
}
char
cli_comment(clicon_handle h)
{
cligen_handle ch = cligen(h);
return cligen_comment(ch);
}
char
cli_set_comment(clicon_handle h, char c)
{
cligen_handle ch = cligen(h);
return cligen_comment_set(ch, c);
}
char
cli_tree_add(clicon_handle h, char *tree, parse_tree pt)
{
cligen_handle ch = cligen(h);
return cligen_tree_add(ch, tree, pt);
}
char *
cli_tree_active(clicon_handle h)
{
cligen_handle ch = cligen(h);
return cligen_tree_active(ch);
}
int
cli_tree_active_set(clicon_handle h, char *treename)
{
cligen_handle ch = cligen(h);
return cligen_tree_active_set(ch, treename);
}
parse_tree *
cli_tree(clicon_handle h, char *name)
{
cligen_handle ch = cligen(h);
return cligen_tree(ch, name);
}
int int
cli_parse_file(clicon_handle h, cli_parse_file(clicon_handle h,
FILE *f, FILE *f,

View file

@ -41,20 +41,12 @@
* Prototypes * Prototypes
* Internal prototypes. For exported functions see clicon_cli_api.h * Internal prototypes. For exported functions see clicon_cli_api.h
*/ */
char cli_tree_add(clicon_handle h, char *tree, parse_tree pt);
int cli_parse_file(clicon_handle h, int cli_parse_file(clicon_handle h,
FILE *f, FILE *f,
char *name, /* just for errs */ char *name, /* just for errs */
parse_tree *pt, parse_tree *pt,
cvec *globals); cvec *globals);
char *cli_tree_active(clicon_handle h);
int cli_tree_active_set(clicon_handle h, char *treename);
parse_tree *cli_tree(clicon_handle h, char *name);
int cli_susp_hook(clicon_handle h, cli_susphook_t *fn); int cli_susp_hook(clicon_handle h, cli_susphook_t *fn);
char *cli_nomatch(clicon_handle h); char *cli_nomatch(clicon_handle h);

View file

@ -70,7 +70,7 @@
#include "cli_handle.h" #include "cli_handle.h"
/* Command line options to be passed to getopt(3) */ /* Command line options to be passed to getopt(3) */
#define CLI_OPTS "hD:f:F:1u:d:m:qpGLl:y:x" #define CLI_OPTS "hD:f:xl:F:1u:d:m:qpGLy:c:"
/*! terminate cli application */ /*! terminate cli application */
static int static int
@ -119,11 +119,10 @@ cli_interactive(clicon_handle h)
int result; int result;
/* Loop through all commands */ /* Loop through all commands */
while(!cli_exiting(h)) { while(!cligen_exiting(cli_cligen(h))) {
// save_mode =
new_mode = cli_syntax_mode(h); new_mode = cli_syntax_mode(h);
if ((cmd = clicon_cliread(h)) == NULL) { if ((cmd = clicon_cliread(h)) == NULL) {
cli_set_exiting(h, 1); /* EOF */ cligen_exiting_set(cli_cligen(h), 1); /* EOF */
retval = -1; retval = -1;
goto done; goto done;
} }
@ -215,7 +214,8 @@ usage(char *argv0, clicon_handle h)
"\t-G \t\tPrint CLI syntax generated from dbspec (if CLICON_CLI_GENMODEL enabled)\n" "\t-G \t\tPrint CLI syntax generated from dbspec (if CLICON_CLI_GENMODEL enabled)\n"
"\t-L \t\tDebug print dynamic CLI syntax including completions and expansions\n" "\t-L \t\tDebug print dynamic CLI syntax including completions and expansions\n"
"\t-l <s|e|o> \tLog on (s)yslog, std(e)rr or std(o)ut (stderr is default)\n" "\t-l <s|e|o> \tLog on (s)yslog, std(e)rr or std(o)ut (stderr is default)\n"
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n", "\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n"
"\t-c <file>\tSpecify cli spec file.\n",
argv0, argv0,
confsock ? confsock : "none", confsock ? confsock : "none",
plgdir ? plgdir : "none" plgdir ? plgdir : "none"
@ -254,7 +254,7 @@ main(int argc, char **argv)
if (cli_plugin_init(h) != 0) if (cli_plugin_init(h) != 0)
goto done; goto done;
once = 0; once = 0;
cli_set_comment(h, '#'); /* Default to handle #! clicon_cli scripts */ cligen_comment_set(cli_cligen(h), '#'); /* Default to handle #! clicon_cli scripts */
/* /*
* First-step command-line options for help, debug, config-file and log, * First-step command-line options for help, debug, config-file and log,
@ -263,7 +263,6 @@ main(int argc, char **argv)
opterr = 0; opterr = 0;
while ((c = getopt(argc, argv, CLI_OPTS)) != -1) while ((c = getopt(argc, argv, CLI_OPTS)) != -1)
switch (c) { switch (c) {
case '?':
case 'h': case 'h':
/* Defer the call to usage() to later. Reason is that for helpful /* Defer the call to usage() to later. Reason is that for helpful
text messages, default dirs, etc, are not set until later. text messages, default dirs, etc, are not set until later.
@ -281,7 +280,7 @@ main(int argc, char **argv)
usage(argv[0], h); usage(argv[0], h);
clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg); clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg);
break; break;
case 'x': /* dump config file as xml */ case 'x': /* dump config file as xml (migration from .conf file)*/
dump_configfile_xml++; dump_configfile_xml++;
break; break;
case 'l': /* Log destination: s|e|o */ case 'l': /* Log destination: s|e|o */
@ -329,8 +328,8 @@ main(int argc, char **argv)
switch (c) { switch (c) {
case 'D' : /* debug */ case 'D' : /* debug */
case 'f': /* config file */ case 'f': /* config file */
case 'l': /* Log destination */
case 'x': /* dump config file as xml */ case 'x': /* dump config file as xml */
case 'l': /* Log destination */
break; /* see above */ break; /* see above */
case 'F': /* read commands from file */ case 'F': /* read commands from file */
if (freopen(optarg, "r", stdin) == NULL){ if (freopen(optarg, "r", stdin) == NULL){
@ -372,6 +371,10 @@ main(int argc, char **argv)
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg); clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg);
break; break;
} }
case 'c' :{ /* Overwrite clispec with absolute filename */
clicon_option_str_set(h, "CLICON_CLISPEC_FILE", optarg);
break;
}
default: default:
usage(argv[0], h); usage(argv[0], h);
break; break;
@ -424,7 +427,7 @@ main(int argc, char **argv)
goto done; goto done;
} }
snprintf(treename, len, "datamodel:%s", clicon_dbspec_name(h)); snprintf(treename, len, "datamodel:%s", clicon_dbspec_name(h));
cli_tree_add(h, treename, pt); cligen_tree_add(cli_cligen(h), treename, pt);
if (printgen) if (printgen)
cligen_print(stdout, pt, 1); cligen_print(stdout, pt, 1);
@ -446,7 +449,7 @@ main(int argc, char **argv)
fprintf (stderr, "FATAL: No cli mode set (use -m or CLICON_CLI_MODE)\n"); fprintf (stderr, "FATAL: No cli mode set (use -m or CLICON_CLI_MODE)\n");
goto done; goto done;
} }
if (cli_tree(h, cli_syntax_mode(h)) == NULL) if (cligen_tree_find(cli_cligen(h), cli_syntax_mode(h)) == NULL)
clicon_log(LOG_WARNING, "No such cli mode: %s (Specify cli mode with CLICON_CLI_MODE in config file or -m <mode> on command line", cli_syntax_mode(h)); clicon_log(LOG_WARNING, "No such cli mode: %s (Specify cli mode with CLICON_CLI_MODE in config file or -m <mode> on command line", cli_syntax_mode(h));
if (logclisyntax) if (logclisyntax)
@ -454,7 +457,7 @@ main(int argc, char **argv)
if (debug) if (debug)
clicon_option_dump(h, debug); clicon_option_dump(h, debug);
/* Join rest of argv to a single command */ /* Join rest of argv to a single command */
restarg = clicon_strjoin(argc, argv, " "); restarg = clicon_strjoin(argc, argv, " ");

View file

@ -113,8 +113,7 @@ syntax_mode_find(cli_syntax_t *stx, const char *mode, int create)
return m; return m;
} }
/* /*! Find plugin by name
* Find plugin by name
*/ */
static struct cli_plugin * static struct cli_plugin *
plugin_find_cli(cli_syntax_t *stx, char *plgnam) plugin_find_cli(cli_syntax_t *stx, char *plgnam)
@ -131,19 +130,17 @@ plugin_find_cli(cli_syntax_t *stx, char *plgnam)
return NULL; return NULL;
} }
/* /*! Generate parse tree for syntax mode
* Generate parse tree for syntax mode
*/ */
static int static int
gen_parse_tree(clicon_handle h, cli_syntaxmode_t *m) gen_parse_tree(clicon_handle h, cli_syntaxmode_t *m)
{ {
cli_tree_add(h, m->csm_name, m->csm_pt); cligen_tree_add(cli_cligen(h), m->csm_name, m->csm_pt);
return 0; return 0;
} }
/* /*! Append syntax
* Append syntax
*/ */
static int static int
syntax_append(clicon_handle h, syntax_append(clicon_handle h,
@ -162,8 +159,7 @@ syntax_append(clicon_handle h,
return 0; return 0;
} }
/* /*! Unload all plugins in a group
* Unload all plugins in a group
*/ */
static int static int
cli_syntax_unload(clicon_handle h) cli_syntax_unload(clicon_handle h)
@ -271,13 +267,15 @@ quit:
return cp; return cp;
} }
/* /*! Append to syntax mode from file
* Append to syntax mode from file * @param[in] h Clixon handle
* Arguments: * @param[in] filename Name of file where syntax is specified (in syntax-group dir)
* filename : Name of file where syntax is specified (in syntax-group dir) * @param[in] dir Name of dir, or NULL
*/ */
static int static int
cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir) cli_load_syntax(clicon_handle h,
const char *filename,
const char *dir)
{ {
void *handle = NULL; /* Handle to plugin .so module */ void *handle = NULL; /* Handle to plugin .so module */
char *mode = NULL; /* Name of syntax mode to append new syntax */ char *mode = NULL; /* Name of syntax mode to append new syntax */
@ -285,15 +283,18 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
int retval = -1; int retval = -1;
FILE *f; FILE *f;
char filepath[MAXPATHLEN]; char filepath[MAXPATHLEN];
cvec *vr = NULL; cvec *cvv = NULL;
char *prompt = NULL; char *prompt = NULL;
char **vec = NULL; char **vec = NULL;
int i, nvec; int i, nvec;
char *plgnam; char *plgnam;
struct cli_plugin *p; struct cli_plugin *p;
snprintf(filepath, MAXPATHLEN-1, "%s/%s", clispec_dir, filename); if (dir)
if ((vr = cvec_new(0)) == NULL){ snprintf(filepath, MAXPATHLEN-1, "%s/%s", dir, filename);
else
snprintf(filepath, MAXPATHLEN-1, "%s", filename);
if ((cvv = cvec_new(0)) == NULL){
clicon_err(OE_PLUGIN, errno, "cvec_new"); clicon_err(OE_PLUGIN, errno, "cvec_new");
goto done; goto done;
} }
@ -304,7 +305,7 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
} }
/* Assuming this plugin is first in queue */ /* Assuming this plugin is first in queue */
if (cli_parse_file(h, f, filepath, &pt, vr) < 0){ if (cli_parse_file(h, f, filepath, &pt, cvv) < 0){
clicon_err(OE_PLUGIN, 0, "failed to parse cli file %s", filepath); clicon_err(OE_PLUGIN, 0, "failed to parse cli file %s", filepath);
fclose(f); fclose(f);
goto done; goto done;
@ -312,9 +313,9 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
fclose(f); fclose(f);
/* Get CLICON specific global variables */ /* Get CLICON specific global variables */
prompt = cvec_find_str(vr, "CLICON_PROMPT"); prompt = cvec_find_str(cvv, "CLICON_PROMPT");
plgnam = cvec_find_str(vr, "CLICON_PLUGIN"); plgnam = cvec_find_str(cvv, "CLICON_PLUGIN");
mode = cvec_find_str(vr, "CLICON_MODE"); mode = cvec_find_str(cvv, "CLICON_MODE");
if (plgnam != NULL) { /* Find plugin for callback resolving */ if (plgnam != NULL) { /* Find plugin for callback resolving */
if ((p = plugin_find_cli (cli_syntax(h), plgnam)) != NULL) if ((p = plugin_find_cli (cli_syntax(h), plgnam)) != NULL)
@ -355,15 +356,14 @@ cli_load_syntax(clicon_handle h, const char *filename, const char *clispec_dir)
retval = 0; retval = 0;
done: done:
if (vr) if (cvv)
cvec_free(vr); cvec_free(cvv);
if (vec) if (vec)
free(vec); free(vec);
return retval; return retval;
} }
/* /*! Load plugins within a directory
* Load plugins within a directory
*/ */
static int static int
cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx) cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
@ -431,8 +431,8 @@ cli_plugin_load_dir(clicon_handle h, char *dir, cli_syntax_t *stx)
} }
/* /*! Load a syntax group.
* Load a syntax group. * @param[in] h Clicon handle
*/ */
int int
cli_syntax_load (clicon_handle h) cli_syntax_load (clicon_handle h)
@ -440,6 +440,7 @@ cli_syntax_load (clicon_handle h)
int retval = -1; int retval = -1;
char *plugin_dir = NULL; char *plugin_dir = NULL;
char *clispec_dir = NULL; char *clispec_dir = NULL;
char *clispec_file = NULL;
int ndp; int ndp;
int i; int i;
struct dirent *dp = NULL; struct dirent *dp = NULL;
@ -455,10 +456,8 @@ cli_syntax_load (clicon_handle h)
clicon_err(OE_FATAL, 0, "clicon_cli_dir not set"); clicon_err(OE_FATAL, 0, "clicon_cli_dir not set");
goto quit; goto quit;
} }
if ((clispec_dir = clicon_clispec_dir(h)) == NULL){ clispec_dir = clicon_clispec_dir(h);
clicon_err(OE_FATAL, 0, "clicon_clispec_dir not set"); clispec_file = clicon_option_str(h, "CLICON_CLISPEC_FILE");
goto quit;
}
/* Allocate plugin group object */ /* Allocate plugin group object */
if ((stx = malloc(sizeof(*stx))) == NULL) { if ((stx = malloc(sizeof(*stx))) == NULL) {
@ -478,17 +477,22 @@ cli_syntax_load (clicon_handle h)
if (cli_plugin_load_dir(h, plugin_dir, stx) < 0) if (cli_plugin_load_dir(h, plugin_dir, stx) < 0)
goto quit; goto quit;
/* load syntaxfiles */ if (clispec_file){
if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG)) < 0) if (cli_load_syntax(h, clispec_file, NULL) < 0)
goto quit;
/* Load the rest */
for (i = 0; i < ndp; i++) {
clicon_debug(1, "DEBUG: Loading syntax '%.*s'",
(int)strlen(dp[i].d_name)-4, dp[i].d_name);
if (cli_load_syntax(h, dp[i].d_name, clispec_dir) < 0)
goto quit; goto quit;
} }
if (clispec_dir){
/* load syntaxfiles */
if ((ndp = clicon_file_dirent(clispec_dir, &dp, "(.cli)$", S_IFREG)) < 0)
goto quit;
/* Load the rest */
for (i = 0; i < ndp; i++) {
clicon_debug(1, "DEBUG: Loading syntax '%.*s'",
(int)strlen(dp[i].d_name)-4, dp[i].d_name);
if (cli_load_syntax(h, dp[i].d_name, clispec_dir) < 0)
goto quit;
}
}
/* Did we successfully load any syntax modes? */ /* Did we successfully load any syntax modes? */
if (stx->stx_nmodes <= 0) { if (stx->stx_nmodes <= 0) {
retval = 0; retval = 0;
@ -519,8 +523,7 @@ quit:
return retval; return retval;
} }
/* /*! Call plugin_start() in all plugins
* Call plugin_start() in all plugins
*/ */
int int
cli_plugin_start(clicon_handle h, int argc, char **argv) cli_plugin_start(clicon_handle h, int argc, char **argv)
@ -544,7 +547,6 @@ cli_plugin_start(clicon_handle h, int argc, char **argv)
} }
/* /*
*/ */
int int
cli_plugin_finish(clicon_handle h) cli_plugin_finish(clicon_handle h)
@ -575,16 +577,20 @@ cli_handler_err(FILE *f)
} }
/* /*! Evaluate a matched command
* Evaluate a matched command * @param[in] h Clicon handle
* @param[in] cmd The command string
*/ */
int int
clicon_eval(clicon_handle h, char *cmd, cg_obj *match_obj, cvec *vr) clicon_eval(clicon_handle h,
char *cmd,
cg_obj *match_obj,
cvec *cvv)
{ {
cli_output_reset(); cli_output_reset();
if (!cli_exiting(h)) { if (!cligen_exiting(cli_cligen(h))) {
clicon_err_reset(); clicon_err_reset();
if (cligen_eval(cli_cligen(h), match_obj, vr) < 0) { if (cligen_eval(cli_cligen(h), match_obj, cvv) < 0) {
#if 0 /* This is removed since we get two error messages on failure. #if 0 /* This is removed since we get two error messages on failure.
But maybe only sometime? But maybe only sometime?
Both a real log when clicon_err is called, and the here again. Both a real log when clicon_err is called, and the here again.
@ -606,24 +612,24 @@ clicon_eval(clicon_handle h, char *cmd, cg_obj *match_obj, cvec *vr)
* the new mode string. * the new mode string.
* *
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] cmd The command string * @param[in] cmd Command string
* @param[in,out] mode A pointer to the mode string pointer * @param[in,out] modenamep Pointer to the mode string pointer
* @param[out] result -2 On eof (shouldnt happen) * @param[out] result -2 On eof (shouldnt happen)
* -1 On parse error * -1 On parse error
* >=0 Number of matches * >=0 Number of matches
*/ */
int int
clicon_parse(clicon_handle h, clicon_parse(clicon_handle h,
char *cmd, char *cmd,
char **mode, char **modenamep,
int *result) int *result)
{ {
char *m, *msav; char *modename;
char *modename0;
int res = -1; int res = -1;
int r; int r;
cli_syntax_t *stx = NULL; cli_syntax_t *stx = NULL;
cli_syntaxmode_t *smode; cli_syntaxmode_t *smode;
char *treename;
parse_tree *pt; /* Orig */ parse_tree *pt; /* Orig */
cg_obj *match_obj; cg_obj *match_obj;
cvec *cvv = NULL; cvec *cvv = NULL;
@ -634,26 +640,23 @@ clicon_parse(clicon_handle h,
else else
f = stderr; f = stderr;
stx = cli_syntax(h); stx = cli_syntax(h);
m = *mode; if ((modename = *modenamep) == NULL) {
if (m == NULL) {
smode = stx->stx_active_mode; smode = stx->stx_active_mode;
m = smode->csm_name; modename = smode->csm_name;
} }
else { else {
if ((smode = syntax_mode_find(stx, m, 0)) == NULL) { if ((smode = syntax_mode_find(stx, modename, 0)) == NULL) {
cli_output(f, "Can't find syntax mode '%s'\n", m); cli_output(f, "Can't find syntax mode '%s'\n", modename);
return -1; return -1;
} }
} }
msav = NULL;
while(smode) { while(smode) {
if (cli_tree_active(h)) modename0 = NULL;
msav = strdup(cli_tree_active(h)); if ((pt = cligen_tree_active_get(cli_cligen(h))) != NULL)
cli_tree_active_set(h, m); modename0 = pt->pt_name;
treename = cli_tree_active(h); if (cligen_tree_active_set(cli_cligen(h), modename) < 0){
if ((pt = cli_tree(h, treename)) == NULL){ fprintf(stderr, "No such parse-tree registered: %s\n", modename);
fprintf(stderr, "No such parse-tree registered: %s\n", treename); goto done;
goto done;;
} }
if ((cvv = cvec_new(0)) == NULL){ if ((cvv = cvec_new(0)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_new"); clicon_err(OE_UNIX, errno, "cvec_new");
@ -662,12 +665,10 @@ clicon_parse(clicon_handle h,
res = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv); res = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv);
if (res != CG_MATCH) if (res != CG_MATCH)
pt_expand_cleanup_1(pt); /* XXX change to pt_expand_treeref_cleanup */ pt_expand_cleanup_1(pt); /* XXX change to pt_expand_treeref_cleanup */
if (msav){ if (modename0){
cli_tree_active_set(h, msav); cligen_tree_active_set(cli_cligen(h), modename0);
free(msav); modename0 = NULL;
} }
msav = NULL;
switch (res) { switch (res) {
case CG_EOF: /* eof */ case CG_EOF: /* eof */
case CG_ERROR: case CG_ERROR:
@ -677,11 +678,11 @@ clicon_parse(clicon_handle h,
smode = NULL; smode = NULL;
if (stx->stx_parse_hook) { if (stx->stx_parse_hook) {
/* Try to find a match in upper modes, a'la IOS. */ /* Try to find a match in upper modes, a'la IOS. */
if ((m = stx->stx_parse_hook(h, cmd, m)) != NULL) { if ((modename = stx->stx_parse_hook(h, cmd, modename)) != NULL) {
if ((smode = syntax_mode_find(stx, m, 0)) != NULL) if ((smode = syntax_mode_find(stx, modename, 0)) != NULL)
continue; continue;
else else
cli_output(f, "Can't find syntax mode '%s'\n", m); cli_output(f, "Can't find syntax mode '%s'\n", modename);
} }
} }
/* clicon_err(OE_CFG, 0, "CLI syntax error: \"%s\": %s", /* clicon_err(OE_CFG, 0, "CLI syntax error: \"%s\": %s",
@ -690,9 +691,9 @@ clicon_parse(clicon_handle h,
cmd, cli_nomatch(h)); cmd, cli_nomatch(h));
break; break;
case CG_MATCH: case CG_MATCH:
if (m != *mode){ /* Command in different mode */ if (strcmp(modename, *modenamep)){ /* Command in different mode */
*mode = m; *modenamep = modename;
cli_set_syntax_mode(h, m); cli_set_syntax_mode(h, modename);
} }
if ((r = clicon_eval(h, cmd, match_obj, cvv)) < 0) if ((r = clicon_eval(h, cmd, match_obj, cvv)) < 0)
cli_handler_err(stdout); cli_handler_err(stdout);
@ -734,7 +735,7 @@ clicon_cliread(clicon_handle h)
cli_prompt_set(h, ""); cli_prompt_set(h, "");
else else
cli_prompt_set(h, cli_prompt(pfmt ? pfmt : mode->csm_prompt)); cli_prompt_set(h, cli_prompt(pfmt ? pfmt : mode->csm_prompt));
cli_tree_active_set(h, mode->csm_name); cligen_tree_active_set(cli_cligen(h), mode->csm_name);
ret = cliread(cli_cligen(h)); ret = cliread(cli_cligen(h));
if (pfmt) if (pfmt)
free(pfmt); free(pfmt);

View file

@ -59,10 +59,6 @@ int cli_ptpush(clicon_handle h, char *mode, char *string, char *op);
int cli_ptpop(clicon_handle h, char *mode, char *op); int cli_ptpop(clicon_handle h, char *mode, char *op);
/* cli_handle.c */ /* cli_handle.c */
char cli_set_comment(clicon_handle h, char c);
char cli_comment(clicon_handle h);
int cli_set_exiting(clicon_handle h, int exiting);
int cli_exiting(clicon_handle h);
clicon_handle cli_handle_init(void); clicon_handle cli_handle_init(void);
int cli_handle_exit(clicon_handle h); int cli_handle_exit(clicon_handle h);
cligen_handle cli_cligen(clicon_handle h); cligen_handle cli_cligen(clicon_handle h);

View file

@ -50,7 +50,7 @@ NETCONF_PLUGIN = $(APPNAME)_netconf.so
PLUGINS = $(BE_PLUGIN) $(CLI_PLUGIN) $(NETCONF_PLUGIN) PLUGINS = $(BE_PLUGIN) $(CLI_PLUGIN) $(NETCONF_PLUGIN)
all: $(PLUGINS) $(APPNAME).conf all: $(PLUGINS)
# Note: clixon.mk has a rule for: # Note: clixon.mk has a rule for:
# $(APPNAME.conf) # $(APPNAME.conf)
@ -91,16 +91,15 @@ SRC = $(BE_SRC) $(CLI_SRC) $(NETCONF_SRC)
OBJS = $(BE_OBJ) $(CLI_OBJ) $(NETCONF_OBJ) OBJS = $(BE_OBJ) $(CLI_OBJ) $(NETCONF_OBJ)
clean: clean:
rm -f $(PLUGINS) $(OBJS) $(APPNAME).conf rm -f $(PLUGINS) $(OBJS)
(cd docker && $(MAKE) $(MFLAGS) $@) (cd docker && $(MAKE) $(MFLAGS) $@)
distclean: clean distclean: clean
rm -f Makefile *~ .depend rm -f Makefile *~ .depend
(cd docker && $(MAKE) $(MFLAGS) $@) (cd docker && $(MAKE) $(MFLAGS) $@)
install: $(YANGSPECS) $(CLISPECS) $(BE_PLUGIN) $(CLI_PLUGIN) $(NETCONF_PLUGIN) $(APPNAME).conf $(APPNAME).xml install: $(YANGSPECS) $(CLISPECS) $(BE_PLUGIN) $(CLI_PLUGIN) $(NETCONF_PLUGIN) $(APPNAME).xml
install -d $(DESTDIR)$(clixon_SYSCONFDIR) install -d $(DESTDIR)$(clixon_SYSCONFDIR)
install $(APPNAME).conf $(DESTDIR)$(clixon_SYSCONFDIR)
install $(APPNAME).xml $(DESTDIR)$(clixon_SYSCONFDIR) install $(APPNAME).xml $(DESTDIR)$(clixon_SYSCONFDIR)
install -d $(DESTDIR)$(clixon_DBSPECDIR)/yang install -d $(DESTDIR)$(clixon_DBSPECDIR)/yang
install $(YANGSPECS) $(DESTDIR)$(clixon_DBSPECDIR)/yang install $(YANGSPECS) $(DESTDIR)$(clixon_DBSPECDIR)/yang
@ -116,7 +115,6 @@ install: $(YANGSPECS) $(CLISPECS) $(BE_PLUGIN) $(CLI_PLUGIN) $(NETCONF_PLUGIN) $
(cd docker && $(MAKE) $(MFLAGS) $@) (cd docker && $(MAKE) $(MFLAGS) $@)
uninstall: uninstall:
rm -rf $(DESTDIR)$(clixon_SYSCONFDIR)/$(APPNAME).conf
rm -rf $(DESTDIR)$(clixon_SYSCONFDIR)/$(APPNAME).xml rm -rf $(DESTDIR)$(clixon_SYSCONFDIR)/$(APPNAME).xml
rm -rf $(DESTDIR)$(clixon_DBSPECDIR) rm -rf $(DESTDIR)$(clixon_DBSPECDIR)
rm -rf $(DESTDIR)$(clixon_LOCALSTATEDIR) rm -rf $(DESTDIR)$(clixon_LOCALSTATEDIR)

View file

@ -11,7 +11,7 @@ delete("Delete a configuration item") @datamodel:example, cli_del();
validate("Validate changes"), cli_validate(); validate("Validate changes"), cli_validate();
commit("Commit the changes"), cli_commit(); commit("Commit the changes"), cli_commit();
quit("Quit Hello"), cli_quit(); quit("Quit"), cli_quit();
delete("Delete a configuration item") all("Delete whole candidate configuration"), delete_all("candidate"); delete("Delete a configuration item") all("Delete whole candidate configuration"), delete_all("candidate");
startup("Store running as startup config"), db_copy("running", "startup"); startup("Store running as startup config"), db_copy("running", "startup");

View file

@ -100,7 +100,7 @@ clicon_rpc_msg(clicon_handle h,
if (errno == ESHUTDOWN) if (errno == ESHUTDOWN)
/* Maybe could reconnect on a higher layer, but lets fail /* Maybe could reconnect on a higher layer, but lets fail
loud and proud */ loud and proud */
cli_set_exiting(1); cligen_exiting_set(cli_cligen(h), 1);
#endif #endif
goto done; goto done;
} }
@ -478,7 +478,6 @@ clicon_rpc_unlock(clicon_handle h,
} }
/*! Get database configuration and state data /*! Get database configuration and state data
* Same as clicon_proto_change just with a cvec instead of lvec
* @param[in] h CLICON handle * @param[in] h CLICON handle
* @param[in] xpath XPath (or "") * @param[in] xpath XPath (or "")
* @param[out] xt XML tree. Free with xml_free. * @param[out] xt XML tree. Free with xml_free.

View file

@ -67,7 +67,8 @@
leaf CLICON_BACKEND_DIR { leaf CLICON_BACKEND_DIR {
type string; type string;
mandatory true; mandatory true;
description "Location of backend .so plugins"; description "Location of backend .so plugins. Load all .so
plugins in this dir as backend plugins";
} }
leaf CLICON_NETCONF_DIR { leaf CLICON_NETCONF_DIR {
type string; type string;
@ -77,23 +78,65 @@
leaf CLICON_RESTCONF_DIR { leaf CLICON_RESTCONF_DIR {
type string; type string;
mandatory true; mandatory true;
description "Location of restconf (frontend) .so plugins"; description "Location of restconf (frontend) .so plugins. Load all .so
plugins in this dir as restconf code plugins";
}
leaf CLICON_RESTCONF_PATH {
type string;
default "/www-data/fastcgi_restconf.sock";
description "FastCGI unix socket. Should be specified in webserver
Eg in nginx: fastcgi_pass unix:/www-data/clicon_restconf.sock";
} }
leaf CLICON_CLI_DIR { leaf CLICON_CLI_DIR {
type string; type string;
mandatory true; mandatory true;
description "Location of cli frontend .so plugins"; description "Location of cli frontend .so plugins. Load all .so
plugins in this dir as CLI object plugins";
} }
leaf CLICON_CLISPEC_DIR { leaf CLICON_CLISPEC_DIR {
type string; type string;
mandatory true; description "Location of frontend .cli cligen spec files. Load all .cli
description "Location of frontend .cli cligen spec files"; files in this dir as CLI specification files";
} }
leaf CLICON_USE_STARTUP_CONFIG { leaf CLICON_CLISPEC_FILE {
type string;
description "Specific frontend .cli cligen spec file.";
}
leaf CLICON_CLI_MODE {
type string;
default "base";
description "Startup CLI mode. This should match a CLICON_MODE set in
one of the clispec files";
}
leaf CLICON_CLI_GENMODEL {
type int32; type int32;
default 0; default 1;
description "Enabled uses \"startup\" configuration on boot"; description "Generate code for CLI completion of existing db symbols.
Example: Add name=\"myspec\" in datamodel spec and reference
as @myspec";
} }
leaf CLICON_CLI_GENMODEL_COMPLETION {
type int32;
default 1;
description "Generate code for CLI completion of existing db symbols";
}
leaf CLICON_CLI_GENMODEL_TYPE {
type string;
default "VARS";
description "How to generate and show CLI syntax: VARS|ALL";
}
leaf CLICON_CLI_VARONLY {
type int32;
default 1;
description "Dont include keys in cvec in cli vars callbacks, ie a & k in 'a <b> k <c>' ignored";
}
leaf CLICON_CLI_LINESCROLLING {
type int32;
default 1;
description "Set to 0 if you want CLI to wrap to next line.
Set to 1 if you want CLI to scroll sideways when approaching right margin";
}
leaf CLICON_SOCK_FAMILY { leaf CLICON_SOCK_FAMILY {
type string; type string;
default "UNIX"; default "UNIX";
@ -102,24 +145,24 @@
leaf CLICON_SOCK { leaf CLICON_SOCK {
type string; type string;
mandatory true; mandatory true;
description "If family above is AF_UNIX: Unix socket for communicating with description "If family above is AF_UNIX: Unix socket for communicating
clixon_backend. If family above is AF_INET: IPv4 address"; with clixon_backend. If family is AF_INET: IPv4 address";
} }
leaf CLICON_SOCK_PORT { leaf CLICON_SOCK_PORT {
type int32; type int32;
default 4535; default 4535;
description "Inet socket port for communicating with clixon_backend (only IPv4|IPv6)"; description "Inet socket port for communicating with clixon_backend (only IPv4|IPv6)";
} }
leaf CLICON_BACKEND_PIDFILE {
type string;
mandatory true;
description "Process-id file";
}
leaf CLICON_SOCK_GROUP { leaf CLICON_SOCK_GROUP {
type string; type string;
default "clicon"; default "clicon";
description "Group membership to access clixon_backend unix socket"; description "Group membership to access clixon_backend unix socket";
} }
leaf CLICON_BACKEND_PIDFILE {
type string;
mandatory true;
description "Process-id file";
}
leaf CLICON_AUTOCOMMIT { leaf CLICON_AUTOCOMMIT {
type int32; type int32;
default 0; default 0;
@ -131,56 +174,23 @@
default "master"; default "master";
description "Name of master plugin (both frontend and backend). description "Name of master plugin (both frontend and backend).
Master plugin has special callbacks for frontends. Master plugin has special callbacks for frontends.
See clicon user manual for more info."; See clicon user manual for more info. (Obsolete)";
}
leaf CLICON_CLI_MODE {
type string;
default "base";
description "Startup CLI mode. This should match the CLICON_MODE in your startup clispec file";
}
leaf CLICON_CLI_GENMODEL {
type int32;
default 1;
description "Generate code for CLI completion of existing db symbols.
Add name=\"myspec\" in datamodel spec and reference as @myspec";
}
leaf CLICON_CLI_GENMODEL_COMPLETION {
type int32;
default 1;
description "Generate code for CLI completion of existing db symbols";
}
leaf CLICON_CLI_GENMODEL_TYPE {
type string;
default "VARS";
description "How to generate and show CLI syntax: VARS|ALL";
} }
leaf CLICON_XMLDB_DIR { leaf CLICON_XMLDB_DIR {
type string; type string;
mandatory true; mandatory true;
description "Directory where \"running\", \"candidate\" and \"startup\" are placed"; description "Directory where \"running\", \"candidate\" and \"startup\" are placed";
} }
leaf CLICON_USE_STARTUP_CONFIG {
type int32;
default 0;
description "Enabled uses \"startup\" configuration on boot. It is called
startup_db and exists in XMLDB_DIR";
}
leaf CLICON_XMLDB_PLUGIN { leaf CLICON_XMLDB_PLUGIN {
type string; type string;
mandatory true; mandatory true;
description "XMLDB datastore plugin filename (see datastore/ and clixon_xml_db.[ch])"; description "XMLDB datastore plugin filename (see datastore/ and clixon_xml_db.[ch])";
} }
leaf CLICON_CLI_VARONLY { }
type int32;
default 1;
description "Dont include keys in cvec in cli vars callbacks, ie a & k in 'a <b> k <c>' ignored";
}
leaf CLICON_CLI_LINESCROLLING {
type int32;
default 1;
description "Set to 0 if you want CLI to wrap to next line.
Set to 1 if you want CLI to scroll sideways when approaching right margin";
}
leaf CLICON_RESTCONF_PATH {
type string;
default "/www-data/fastcgi_restconf.sock";
description "FastCGI unix socket. Should be specified in webserver
Eg in nginx: fastcgi_pass unix:/www-data/clicon_restconf.sock;";
}
}
} }