Output pipe function detection in configure.ac

This commit is contained in:
Olof hagsand 2023-07-05 15:48:26 +02:00
parent 3858cd93c2
commit fab8d35dff
5 changed files with 275 additions and 35 deletions

View file

@ -31,7 +31,7 @@
***** END LICENSE BLOCK *****
*
* Note, here assume all binaries are in /bin
* @note Paths to bins, such as GREP_BIN, are detected in configure.ac
*/
#ifdef HAVE_CONFIG_H
@ -80,33 +80,40 @@
*/
int
pipe_arg_fn(clicon_handle h,
const char *cmd,
const char *option,
const char *value)
char *cmd,
char *option,
char *value)
{
int retval = -1;
int retval = -1;
struct stat fstat;
char **argv = NULL;
int i;
/* 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);
}
if (cmd == NULL || strlen(cmd) == 0){
clicon_err(OE_PLUGIN, EINVAL, "cmd '%s' NULL or empty", cmd);
goto done;
}
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);
}
if (stat(cmd, &fstat) < 0) {
clicon_err(OE_UNIX, errno, "stat(%s)", cmd);
goto done;
}
if (!S_ISREG(fstat.st_mode)){
clicon_err(OE_UNIX, errno, "%s is not a regular file", cmd);
goto done;
}
if ((argv = calloc(4, sizeof(char *))) == NULL){
clicon_err(OE_UNIX, errno, "calloc");
goto done;
}
i = 0;
argv[i++] = cmd;
argv[i++] = option;
argv[i++] = value;
argv[i++] = NULL;
retval = execv(cmd, argv);
done:
if (argv)
free(argv);
return retval;
}
@ -146,12 +153,41 @@ pipe_grep_fn(clicon_handle h,
strlen(str))
value = str;
}
retval = pipe_arg_fn(h, "/bin/grep", option, value);
retval = pipe_arg_fn(h, GREP_BIN, option, value);
done:
return retval;
}
/* Grep pipe output function
/*! wc 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_wc_fn(clicon_handle h,
cvec *cvv,
cvec *argv)
{
int retval = -1;
cg_var *cv;
char *str;
char *option;
if (cvec_len(argv) != 1){
clicon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <option>", cvec_len(argv));
goto done;
}
if ((cv = cvec_i(argv, 0)) != NULL &&
(str = cv_string_get(cv)) != NULL &&
strlen(str))
option = str;
retval = pipe_arg_fn(h, WC_BIN, option, NULL);
done:
return retval;
}
/*! wc pipe output function
*
* @param[in] h Clicon handle
* @param[in] cvv Vector of cli string and instantiated variables
@ -159,12 +195,19 @@ pipe_grep_fn(clicon_handle h,
*/
int
pipe_tail_fn(clicon_handle h,
cvec *cvv,
cvec *argv)
cvec *cvv,
cvec *argv)
{
return pipe_arg_fn(h, "/bin/tail", "-5", NULL);
return pipe_arg_fn(h, TAIL_BIN, "-5", NULL);
}
/*! Show as JSON
*
* @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_json_fn(clicon_handle h,
cvec *cvv,

176
configure vendored
View file

@ -180,7 +180,8 @@ test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
test \$(( 1 + 1 )) = 2 || exit 1"
if (eval "$as_required") 2>/dev/null
then :
as_have_required=yes
@ -647,6 +648,9 @@ ac_includes_default="\
ac_header_c_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
WC_BIN
TAIL_BIN
GREP
SSH_BIN
LEXLIB
LEX_OUTPUT_ROOT
@ -5718,6 +5722,176 @@ fi
printf "%s\n" "#define SSH_BIN \"$SSH_BIN\"" >>confdefs.h
# For cli pipe output functions
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
printf %s "checking for grep that handles long lines and -e... " >&6; }
if test ${ac_cv_path_GREP+y}
then :
printf %s "(cached) " >&6
else $as_nop
if test -z "$GREP"; then
ac_path_GREP_found=false
# Loop through the user's path and test for each of PROGNAME-LIST
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
IFS=$as_save_IFS
case $as_dir in #(((
'') as_dir=./ ;;
*/) ;;
*) as_dir=$as_dir/ ;;
esac
for ac_prog in grep ggrep
do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
ac_count=0
printf %s 0123456789 >"conftest.in"
while :
do
cat "conftest.in" "conftest.in" >"conftest.tmp"
mv "conftest.tmp" "conftest.in"
cp "conftest.in" "conftest.nl"
printf "%s\n" 'GREP' >> "conftest.nl"
"$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
as_fn_arith $ac_count + 1 && ac_count=$as_val
if test $ac_count -gt ${ac_path_GREP_max-0}; then
# Best one so far, save it but keep looking for a better one
ac_cv_path_GREP="$ac_path_GREP"
ac_path_GREP_max=$ac_count
fi
# 10*(2^10) chars as input seems more than enough
test $ac_count -gt 10 && break
done
rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac
$ac_path_GREP_found && break 3
done
done
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_GREP"; then
as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_GREP=$GREP
fi
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
printf "%s\n" "$ac_cv_path_GREP" >&6; }
GREP="$ac_cv_path_GREP"
printf "%s\n" "#define GREP_BIN \"$GREP\"" >>confdefs.h
# Extract the first word of "tail", so it can be a program name with args.
set dummy tail; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_path_TAIL_BIN+y}
then :
printf %s "(cached) " >&6
else $as_nop
case $TAIL_BIN in
[\\/]* | ?:[\\/]*)
ac_cv_path_TAIL_BIN="$TAIL_BIN" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
case $as_dir in #(((
'') as_dir=./ ;;
*/) ;;
*) as_dir=$as_dir/ ;;
esac
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
ac_cv_path_TAIL_BIN="$as_dir$ac_word$ac_exec_ext"
printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
TAIL_BIN=$ac_cv_path_TAIL_BIN
if test -n "$TAIL_BIN"; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TAIL_BIN" >&5
printf "%s\n" "$TAIL_BIN" >&6; }
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
printf "%s\n" "#define TAIL_BIN \"$TAIL_BIN\"" >>confdefs.h
# Extract the first word of "wc", so it can be a program name with args.
set dummy wc; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_path_WC_BIN+y}
then :
printf %s "(cached) " >&6
else $as_nop
case $WC_BIN in
[\\/]* | ?:[\\/]*)
ac_cv_path_WC_BIN="$WC_BIN" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
case $as_dir in #(((
'') as_dir=./ ;;
*/) ;;
*) as_dir=$as_dir/ ;;
esac
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
ac_cv_path_WC_BIN="$as_dir$ac_word$ac_exec_ext"
printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
WC_BIN=$ac_cv_path_WC_BIN
if test -n "$WC_BIN"; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WC_BIN" >&5
printf "%s\n" "$WC_BIN" >&6; }
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
printf "%s\n" "#define WC_BIN \"$WC_BIN\"" >>confdefs.h
# Get "bison" from bison -y or other string
if test "$YACC" = "${YACC##bison}" ; then
as_fn_error $? "CLIXON does not find bison. There are several problems with yacc and byacc. Please install bison. YACC=\"$YACC\"" "$LINENO" 5

View file

@ -158,6 +158,14 @@ fi
AC_PATH_PROG(SSH_BIN, ssh)
AC_DEFINE_UNQUOTED(SSH_BIN, "$SSH_BIN", [SSH binary])
# For cli pipe output functions
AC_PROG_GREP
AC_DEFINE_UNQUOTED(GREP_BIN, "$GREP", [Grep binary])
AC_PATH_PROG(TAIL_BIN, tail)
AC_DEFINE_UNQUOTED(TAIL_BIN, "$TAIL_BIN", [tail binary])
AC_PATH_PROG(WC_BIN, wc)
AC_DEFINE_UNQUOTED(WC_BIN, "$WC_BIN", [wc binary])
# Get "bison" from bison -y or other string
if test "$YACC" = "${YACC##bison}" ; then
AC_MSG_ERROR(CLIXON does not find bison. There are several problems with yacc and byacc. Please install bison. YACC="$YACC")

View file

@ -21,6 +21,9 @@
/* Enable YANG patch, RFC 8072 */
#undef CLIXON_YANG_PATCH
/* Grep binary */
#undef GREP_BIN
/* Define to 1 if you have the `alphasort' function. */
#undef HAVE_ALPHASORT
@ -81,9 +84,6 @@
/* Define to 1 if you have the `xml2' library (-lxml2). */
#undef HAVE_LIBXML2
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <net-snmp/net-snmp-config.h> header file. */
#undef HAVE_NET_SNMP_NET_SNMP_CONFIG_H
@ -105,6 +105,9 @@
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@ -156,9 +159,17 @@
/* SSH binary */
#undef SSH_BIN
/* Define to 1 if you have the ANSI C header files. */
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* tail binary */
#undef TAIL_BIN
/* wc binary */
#undef WC_BIN
/* Restconf package */
#undef WITH_RESTCONF

View file

@ -125,6 +125,7 @@ CLICON_MODE="|mypipe"; # Must start with |
grep <arg:string>, pipe_grep_fn("-e", "arg");
except <arg:string>, pipe_grep_fn("-v", "arg");
tail, pipe_tail_fn();
count, pipe_wc_fn("-l");
showas {
json, pipe_json_fn();
text, pipe_text_fn();
@ -173,6 +174,9 @@ expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| grep par)"
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 | count"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| count)" 0 10
new "$mode show explicit | showas json"
expectpart "$($clixon_cli -1 -m $mode -f $cfg show explicit config \| showas json)" 0 '"name": "x",' --not-- "<name>"