Add pipe functions

This commit is contained in:
Olof hagsand 2023-07-04 20:48:01 +02:00
parent c16b9cbba4
commit 3858cd93c2
3 changed files with 142 additions and 24 deletions

View file

@ -31,6 +31,7 @@
***** END LICENSE BLOCK ***** ***** END LICENSE BLOCK *****
* *
* Note, here assume all binaries are in /bin
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -68,43 +69,142 @@
#include "clixon_cli_api.h" #include "clixon_cli_api.h"
/* Grep pipe output function /* Grep pipe output function
*
* @param[in] h Clixon handle
* @param[in] cmd Command to exec
* @param[in] option Option to command (or NULL)
* @param[in] value Command argument value (or NULL)
* @code
* grep <arg:rest>, grep_fn("-e", "arg");
* @endcode
*/ */
int int
grep_fn(cligen_handle h, pipe_arg_fn(clicon_handle h,
const char *cmd,
const char *option,
const char *value)
{
int retval = -1;
/* XXX rewrite using execv */
if (option){
if (value){
fprintf(stderr, "%s (1): %s %s %s %s NULL\n", __FUNCTION__, cmd, cmd, option, value);
retval = execl(cmd, cmd, option, value, NULL);
}
else{
fprintf(stderr, "%s (2): %s %s %s NULL\n", __FUNCTION__, cmd, cmd, option);
retval = execl(cmd, cmd, option, NULL);
}
}
else{
if (value){
fprintf(stderr, "%s (3): %s %s %s NULL\n", __FUNCTION__, cmd, cmd, value);
retval = execl(cmd, cmd, value, NULL);
}
else{
fprintf(stderr, "%s (4): %s %s NULL\n", __FUNCTION__, cmd, cmd);
retval = execl(cmd, cmd, NULL);
}
}
return retval;
}
/* Grep pipe output function
*
* @param[in] h Clicon handle
* @param[in] cvv Vector of cli string and instantiated variables
* @param[in] argv String vector of options. Format: <option> <value>
*/
int
pipe_grep_fn(clicon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
cbuf *cb = NULL; char *value = NULL;
cg_var *av;
cg_var *cv; cg_var *cv;
char *name; char *str;
char *option;
char *argname;
if ((cb = cbuf_new()) == NULL){ if (cvec_len(argv) != 2){
perror("cbuf_new"); clicon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <option> <argname>", cvec_len(argv));
goto done; goto done;
} }
if (argv && (av = cvec_i(argv, 0)) != NULL){ if ((cv = cvec_i(argv, 0)) != NULL &&
/* First arg is command */ (str = cv_string_get(cv)) != NULL &&
// cprintf(cb, "%s", cv_string_get(av)); strlen(str))
/* Rest are names of parameters from cvv */ option = str;
av = NULL; if ((cv = cvec_i(argv, 1)) != NULL &&
while ((av = cvec_each1(argv, av)) != NULL){ (str = cv_string_get(cv)) != NULL &&
name = cv_string_get(av); strlen(str))
if ((cv = cvec_find_var(cvv, name)) != NULL) argname = str;
cprintf(cb, "%s", cv_string_get(cv)); if (argname && strlen(argname)){
} if ((cv = cvec_find_var(cvv, argname)) != NULL &&
retval = execl("/bin/grep", "grep", "-e", cbuf_get(cb), (char *) NULL); (str = cv_string_get(cv)) != NULL &&
strlen(str))
value = str;
} }
retval = pipe_arg_fn(h, "/bin/grep", option, value);
done: done:
if (cb) return retval;
cbuf_free(cb); }
/* Grep pipe output function
*
* @param[in] h Clicon handle
* @param[in] cvv Vector of cli string and instantiated variables
* @param[in] argv String vector of options. Format: <option> <value>
*/
int
pipe_tail_fn(clicon_handle h,
cvec *cvv,
cvec *argv)
{
return pipe_arg_fn(h, "/bin/tail", "-5", NULL);
}
int
pipe_json_fn(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
cxobj *xt = NULL;
if (clixon_xml_parse_file(stdin, YB_NONE, NULL, &xt, NULL) < 0)
goto done;
if (clixon_json2file(stdout, xt, 1, cligen_output, 1, 0) < 0)
goto done;
retval = 0;
done:
if (xt)
xml_free(xt);
return retval;
}
int
pipe_text_fn(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
cxobj *xt = NULL;
if (clixon_xml_parse_file(stdin, YB_NONE, NULL, &xt, NULL) < 0)
goto done;
if (clixon_txt2file(stdout, xt, 0, cligen_output, 1, 0) < 0)
goto done;
retval = 0;
done:
if (xt)
xml_free(xt);
return retval; return retval;
} }
/*! Test cli callback calls cligen_output with output lines as given by function arguments /*! Test cli callback calls cligen_output with output lines as given by function arguments
* *
* This is to generate output to eg cligen_output scrolling * Only for test or debugging to generate output to eg cligen_output scrolling
* Example: * Example:
* a, printlines_fn("line1 abc", "line2 def"); * a, printlines_fn("line1 abc", "line2 def");
*/ */

View file

@ -163,7 +163,10 @@ This can be done by making an `exec` call to a UNIX command, as follows:
execl("/usr/bin/tail", (char *) NULL); execl("/usr/bin/tail", (char *) NULL);
``` ```
See the `pipe_grep_fn()` in the source code for an example.
Another way to write a pipe function is just by using stdin and stdout directly, without an exec. Another way to write a pipe function is just by using stdin and stdout directly, without an exec.
See the `pipe_json_fn()` in the source code for an example.
The clixon system itself arranges the input and output to be The clixon system itself arranges the input and output to be
redirected properly, if the pipe function is a part of a pipe tree as described below. redirected properly, if the pipe function is a part of a pipe tree as described below.

View file

@ -122,7 +122,13 @@ cat <<EOF > $clidir/clipipe.cli
CLICON_MODE="|mypipe"; # Must start with | CLICON_MODE="|mypipe"; # Must start with |
#CLICON_PIPETREE="|mypipe"; #CLICON_PIPETREE="|mypipe";
\| { \| {
grep <arg:rest>, grep_fn("grep -e", "arg"); grep <arg:string>, pipe_grep_fn("-e", "arg");
except <arg:string>, pipe_grep_fn("-v", "arg");
tail, pipe_tail_fn();
showas {
json, pipe_json_fn();
text, pipe_text_fn();
}
} }
EOF EOF
@ -164,6 +170,15 @@ expectpart "$($clixon_cli -1 -m $mode -f $cfg show implicit config \| grep par 2
new "$mode show explicit | grep par" new "$mode show explicit | grep par"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| grep par)" 0 "<parameter>" "</parameter>" --not-- "table" "value" expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| grep par)" 0 "<parameter>" "</parameter>" --not-- "table" "value"
new "$mode show explicit | tail"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| tail)" 0 "<name>y</name>" --not-- "<name>x</name>"
new "$mode show explicit | showas json"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| showas json)" 0 '"name": "x",' --not-- "<name>"
new "$mode show explicit | showas text"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| showas text)" 0 "name x;" --not-- "<name>"
new "$mode show treeref explicit | grep par" new "$mode show treeref explicit | grep par"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show treeref explicit \| grep par)" 0 "<parameter>" "</parameter>" --not-- "table" "value" expectpart "$($clixon_cli -1 -m $mode -f $cfg show treeref explicit \| grep par)" 0 "<parameter>" "</parameter>" --not-- "table" "value"