CLI argument to shell example callback
Save state of netconf chunked framing between inputs Treat EBADF in internal protocol (triggered by freebsd+notifications) Test: chunked encoding: use printf instead of echo
This commit is contained in:
parent
ac7673bc35
commit
ecac027d18
7 changed files with 45 additions and 17 deletions
|
|
@ -73,7 +73,7 @@ Users may have to change how they access the system
|
||||||
* There used to be some cornercases where function-names could not be used as nodes
|
* There used to be some cornercases where function-names could not be used as nodes
|
||||||
* For example, `node()` is a nodetest, so `/node/` caused an error.
|
* For example, `node()` is a nodetest, so `/node/` caused an error.
|
||||||
* In the grammar these include: axisnames, nodetests, functionnames
|
* In the grammar these include: axisnames, nodetests, functionnames
|
||||||
* The NCNames vs functionnames is now impölemented according to the lexical structure section
|
* The NCNames vs functionnames is now implemented according to the lexical structure section
|
||||||
* [provide support for load config of cli format along with json and xml format as save config is supported for all 3 formats](https://github.com/clicon/clixon/issues/320)
|
* [provide support for load config of cli format along with json and xml format as save config is supported for all 3 formats](https://github.com/clicon/clixon/issues/320)
|
||||||
* [prevent clixon-restconf@2021-05-20.yang module from loading](https://github.com/clicon/clixon/issues/318)
|
* [prevent clixon-restconf@2021-05-20.yang module from loading](https://github.com/clicon/clixon/issues/318)
|
||||||
* Instead of always loading it, load it to datastore YANGs only if `CLICON_BACKEND_RESTCONF_PROCESS` is `true`
|
* Instead of always loading it, load it to datastore YANGs only if `CLICON_BACKEND_RESTCONF_PROCESS` is `true`
|
||||||
|
|
|
||||||
|
|
@ -556,6 +556,9 @@ cli_set_mode(clicon_handle h,
|
||||||
|
|
||||||
/*! Start bash from cli callback
|
/*! Start bash from cli callback
|
||||||
* Typical usage: shell("System Bash") <source:rest>, cli_start_shell();
|
* Typical usage: shell("System Bash") <source:rest>, cli_start_shell();
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] cvv Vector of command variables
|
||||||
|
* @param[in] argv [<shell>], defaults to "sh"
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cli_start_shell(clicon_handle h,
|
cli_start_shell(clicon_handle h,
|
||||||
|
|
@ -563,6 +566,7 @@ cli_start_shell(clicon_handle h,
|
||||||
cvec *argv)
|
cvec *argv)
|
||||||
{
|
{
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
char *shcmd = "sh";
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char bcmd[128];
|
char bcmd[128];
|
||||||
|
|
@ -570,6 +574,14 @@ cli_start_shell(clicon_handle h,
|
||||||
sigset_t oldsigset;
|
sigset_t oldsigset;
|
||||||
struct sigaction oldsigaction[32] = {0,};
|
struct sigaction oldsigaction[32] = {0,};
|
||||||
|
|
||||||
|
if (cvec_len(argv) > 1){
|
||||||
|
clicon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: [<shell>]",
|
||||||
|
cvec_len(argv));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (cvec_len(argv) == 1){
|
||||||
|
shcmd = cv_string_get(cvec_i(argv, 0));
|
||||||
|
}
|
||||||
cmd = (cvec_len(vars)>1 ? cv_string_get(cv1) : NULL);
|
cmd = (cvec_len(vars)>1 ? cv_string_get(cv1) : NULL);
|
||||||
if ((pw = getpwuid(getuid())) == NULL){
|
if ((pw = getpwuid(getuid())) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "getpwuid");
|
clicon_err(OE_UNIX, errno, "getpwuid");
|
||||||
|
|
@ -587,19 +599,21 @@ cli_start_shell(clicon_handle h,
|
||||||
cli_signal_flush(h);
|
cli_signal_flush(h);
|
||||||
cli_signal_unblock(h);
|
cli_signal_unblock(h);
|
||||||
if (cmd){
|
if (cmd){
|
||||||
snprintf(bcmd, 128, "bash -l -c \"%s\"", cmd);
|
snprintf(bcmd, 128, "%s -l -c \"%s\"", shcmd, cmd);
|
||||||
if (system(bcmd) < 0){
|
if (system(bcmd) < 0){
|
||||||
cli_signal_block(h);
|
cli_signal_block(h);
|
||||||
clicon_err(OE_UNIX, errno, "system(bash -c)");
|
clicon_err(OE_UNIX, errno, "system(bash -c)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
if (system("bash -l") < 0){
|
snprintf(bcmd, 128, "%s -l", shcmd);
|
||||||
|
if (system(bcmd) < 0){
|
||||||
cli_signal_block(h);
|
cli_signal_block(h);
|
||||||
clicon_err(OE_UNIX, errno, "system(bash)");
|
clicon_err(OE_UNIX, errno, "system(bash)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cli_signal_block(h);
|
cli_signal_block(h);
|
||||||
#if 0 /* Allow errcodes from bash */
|
#if 0 /* Allow errcodes from bash */
|
||||||
if (retval != 0){
|
if (retval != 0){
|
||||||
|
|
@ -729,7 +743,7 @@ compare_xmls(cxobj *xc1,
|
||||||
/*! Compare two dbs using XML. Write to file and run diff
|
/*! Compare two dbs using XML. Write to file and run diff
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] cvv
|
* @param[in] cvv
|
||||||
* @param[in] arg arg: 0 as xml, 1: as text
|
* @param[in] argv arg: 0 as xml, 1: as text
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
compare_dbs(clicon_handle h,
|
compare_dbs(clicon_handle h,
|
||||||
|
|
@ -1459,3 +1473,4 @@ cli_restart_plugin(clicon_handle h,
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@
|
||||||
* <foo/> ..wait 1min ]]>]]>
|
* <foo/> ..wait 1min ]]>]]>
|
||||||
*/
|
*/
|
||||||
#define NETCONF_HASH_BUF "netconf_input_cbuf"
|
#define NETCONF_HASH_BUF "netconf_input_cbuf"
|
||||||
|
#define NETCONF_FRAME_STATE "netconf_input_frame_state"
|
||||||
|
#define NETCONF_FRAME_SIZE "netconf_input_frame_size"
|
||||||
|
|
||||||
/*! Ignore errors on packet errors: continue */
|
/*! Ignore errors on packet errors: continue */
|
||||||
static int ignore_packet_errors = 1;
|
static int ignore_packet_errors = 1;
|
||||||
|
|
@ -509,13 +511,23 @@ netconf_input_cb(int s,
|
||||||
size_t cdatlen = 0;
|
size_t cdatlen = 0;
|
||||||
clicon_hash_t *cdat = clicon_data(h); /* Save cbuf between calls if not done */
|
clicon_hash_t *cdat = clicon_data(h); /* Save cbuf between calls if not done */
|
||||||
int poll;
|
int poll;
|
||||||
int frame_state = 0;
|
|
||||||
int i;
|
int i;
|
||||||
int len;
|
int len;
|
||||||
|
int frame_state;
|
||||||
size_t frame_size;
|
size_t frame_size;
|
||||||
int ret;
|
int ret;
|
||||||
int eof = 0; /* Set to 1 if pending close socket */
|
int eof = 0; /* Set to 1 if pending close socket */
|
||||||
|
|
||||||
|
if (clicon_option_exists(h, NETCONF_FRAME_STATE) == 0)
|
||||||
|
frame_state = 0;
|
||||||
|
else
|
||||||
|
if ((frame_state = clicon_option_int(h, NETCONF_FRAME_STATE)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (clicon_option_exists(h, NETCONF_FRAME_SIZE) == 0)
|
||||||
|
frame_size = 0;
|
||||||
|
else
|
||||||
|
if ((frame_size = clicon_option_int(h, NETCONF_FRAME_SIZE)) < 0)
|
||||||
|
goto done;
|
||||||
if ((ptr = clicon_hash_value(cdat, NETCONF_HASH_BUF, &cdatlen)) != NULL){
|
if ((ptr = clicon_hash_value(cdat, NETCONF_HASH_BUF, &cdatlen)) != NULL){
|
||||||
if (cdatlen != sizeof(cb)){
|
if (cdatlen != sizeof(cb)){
|
||||||
clicon_err(OE_XML, errno, "size mismatch %lu %lu",
|
clicon_err(OE_XML, errno, "size mismatch %lu %lu",
|
||||||
|
|
@ -577,6 +589,7 @@ netconf_input_cb(int s,
|
||||||
else{
|
else{
|
||||||
cprintf(cb, "%c", buf[i]);
|
cprintf(cb, "%c", buf[i]);
|
||||||
if (detect_endtag("]]>]]>", buf[i], &frame_state)){
|
if (detect_endtag("]]>]]>", buf[i], &frame_state)){
|
||||||
|
frame_state = 0;
|
||||||
/* OK, we have an xml string from a client */
|
/* OK, we have an xml string from a client */
|
||||||
/* Remove trailer */
|
/* Remove trailer */
|
||||||
*(((char*)cbuf_get(cb)) + cbuf_len(cb) - strlen("]]>]]>")) = '\0';
|
*(((char*)cbuf_get(cb)) + cbuf_len(cb) - strlen("]]>]]>")) = '\0';
|
||||||
|
|
@ -596,13 +609,15 @@ netconf_input_cb(int s,
|
||||||
/* No data to read, save data and continue on next round */
|
/* No data to read, save data and continue on next round */
|
||||||
if (cbuf_len(cb) != 0){
|
if (cbuf_len(cb) != 0){
|
||||||
if (clicon_hash_add(cdat, NETCONF_HASH_BUF, &cb, sizeof(cb)) == NULL)
|
if (clicon_hash_add(cdat, NETCONF_HASH_BUF, &cb, sizeof(cb)) == NULL)
|
||||||
return -1;
|
goto done;
|
||||||
cb = NULL;
|
cb = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
ok:
|
ok:
|
||||||
|
clicon_option_int_set(h, NETCONF_FRAME_STATE, frame_state);
|
||||||
|
clicon_option_int_set(h, NETCONF_FRAME_SIZE, frame_size);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cb)
|
if (cb)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,9 @@ debug("Debugging parts of the system"){
|
||||||
restconf("Set restconf debug") <level:int32>("Set debug level (0..n)"), cli_debug_restconf();
|
restconf("Set restconf debug") <level:int32>("Set debug level (0..n)"), cli_debug_restconf();
|
||||||
}
|
}
|
||||||
|
|
||||||
shell("System command") <source:rest>, cli_start_shell();
|
shell("System command"), cli_start_shell("bash");{
|
||||||
|
<source:rest>("Single shell command"), cli_start_shell("bash");
|
||||||
|
}
|
||||||
copy("Copy and create a new object") {
|
copy("Copy and create a new object") {
|
||||||
running("Copy from running db") startup("Copy to startup config"), db_copy("running", "startup");
|
running("Copy from running db") startup("Copy to startup config"), db_copy("running", "startup");
|
||||||
interface("Copy interface"){
|
interface("Copy interface"){
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,8 @@ atomicio(ssize_t (*fn) (int, void *, size_t),
|
||||||
res = 0;
|
res = 0;
|
||||||
else if (errno == EPIPE) /* Client shutdown */
|
else if (errno == EPIPE) /* Client shutdown */
|
||||||
res = 0;
|
res = 0;
|
||||||
/* SIGPIPE if client is killed */
|
else if (errno == EBADF) /* client shutdown - freebsd */
|
||||||
|
res = 0;
|
||||||
case 0: /* fall thru */
|
case 0: /* fall thru */
|
||||||
return (res);
|
return (res);
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -375,13 +375,8 @@ function chunked_framing()
|
||||||
{
|
{
|
||||||
str=$1
|
str=$1
|
||||||
length=${#str}
|
length=${#str}
|
||||||
echo -n "
|
|
||||||
#${length}
|
printf "\n#%s\n%s\n##\n" ${length} "${str}"
|
||||||
"
|
|
||||||
echo -n "$str"
|
|
||||||
echo -n "
|
|
||||||
##
|
|
||||||
"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start backend with all varargs.
|
# Start backend with all varargs.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# autocli extension strict expansion
|
# autocli extension strict expansion
|
||||||
# See https://github.com/clicon/clixon/issues/163
|
# See https://github.com/clicon/clixon/issues/163
|
||||||
# test is: add a couple of expansion alternatives, ensure cli cannot select any oother option
|
# test is: add a couple of expansion alternatives, ensure cli cannot select any other option
|
||||||
|
|
||||||
# Magic line must be first in script (see README.md)
|
# Magic line must be first in script (see README.md)
|
||||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue