[sanewall-dev] [PATCH] Detect commands at configure-time not run-time

Jerome BENOIT g6299304p at rezozer.net
Sun May 12 22:26:30 CEST 2013


Hello Again,

On 12/05/13 21:59, Phil Whineray wrote:
>  - Enable GNU autotools ./configure script to select programs
>    including alternates where available but allowing unconfigured
>    operation for developer benefit
> 
>  - Remove wget_cmd which was only used by the ECN shame helper and
>    which is no longer available
> 
>  - Tidied up based on feedback
> ---
>  configure.ac     |   47 ++++++++
>  sbin/sanewall.in |  334 ++++++++++++------------------------------------------
>  2 files changed, 117 insertions(+), 264 deletions(-)
> 
> Hi
> 
> Version 2 of the same patch, based on Jerome's feedback:
> 
>> 1] the AC_SUBST([XXXX_CMD]) are redundant;
> 
> They have been removed, as suggested.
> 
>> 2] AC_PROG_AWK, AC_PROG_GREP and alike may be favoured:
>> http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Particular-Programs.html#Particular-Programs
> 
> These are now used where available. The AC_PROG_AWK has different behaviour
> to the others though - it does not include the path to the exe. Is that
> expected?

no idea.

> 
> I have not used the AC_MKDIR_P since that would require checking and
> changing all of the calling sites also. Maybe a separate patch later.
> 
>> 3] a room for bzcat and xzcat may be anticipated.
> 
> The use of this command in Sanewall is to check the kernel's
> /proc/config.gz file, if present. I don't think the other programs
> will be beneficial unless the kernel starts to support those schemes.

that is what can be anticipated:
google search to proc/config.bz2 gives a few outputs,
but it seems indeed not supported (at least in kernel version 3.2
as shipped in Wheeze Debian).
Whatever it is rather unimportant.


> 
> Cheers
> Phil

Best wishes,
Jerome

> 
> diff --git a/configure.ac b/configure.ac
> index 0306812..046360b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -28,6 +28,53 @@ fi
>  SANEWALL_CONFIG_DIR=$(eval echo "$sysconfdir/sanewall" | sed -e 's|^NONE|/usr/local|')
>  AC_SUBST(SANEWALL_CONFIG_DIR)
>  
> +AC_PROG_AWK()
> +AC_PATH_PROG([CAT_CMD], [cat], [])
> +AC_PATH_PROG([CHMOD_CMD], [chmod], [])
> +AC_PATH_PROG([CHOWN_CMD], [chown], [])
> +AC_PATH_PROG([CUT_CMD], [cut], [])
> +AC_PATH_PROG([DATE_CMD], [date], [])
> +AC_PATH_PROG([EGREP_CMD], [egrep], [])
> +AC_PATH_PROG([EXPR_CMD], [expr], [])
> +AC_PATH_PROG([FIND_CMD], [find], [])
> +AC_PATH_PROG([FOLD_CMD], [fold], [])
> +AC_PROG_GREP()
> +AC_PATH_PROG([HEAD_CMD], [head], [])
> +AC_PATH_PROG([HOSTNAME_CMD], [hostname], [])
> +AC_PATH_PROGS([INSMOD_CMD], [modprobe insmod], [])
> +AC_PATH_PROG([IP6TABLES_CMD], [ip6tables], [])
> +AC_PATH_PROG([IP_CMD], [ip], [])
> +AC_PATH_PROG([IP6TABLES_RESTORE_CMD], [ip6tables-restore], [], [$PATH:/sbin])
> +AC_PATH_PROG([IP6TABLES_SAVE_CMD], [ip6tables-save], [], [$PATH:/sbin])
> +AC_PATH_PROG([IPTABLES_CMD], [iptables], [], [$PATH:/sbin])
> +AC_PATH_PROG([IPTABLES_RESTORE_CMD], [iptables-restore], [], [$PATH:/sbin])
> +AC_PATH_PROG([IPTABLES_SAVE_CMD], [iptables-save], [], [$PATH:/sbin])
> +AC_PATH_PROG([LOGGER_CMD], [logger], [])
> +AC_PATH_PROG([LSMOD_CMD], [lsmod], [], [$PATH:/sbin])
> +AC_PATH_PROG([MKDIR_CMD], [mkdir], [])
> +AC_PATH_PROG([MV_CMD], [mv], [])
> +AC_PATH_PROGS([PAGER_CMD], [pager less more cat], [])
> +AC_PATH_PROG([RENICE_CMD], [echo], [:])
> +AC_PATH_PROG([RM_CMD], [rm], [])
> +AC_PROG_SED()
> +AC_PATH_PROG([SORT_CMD], [sort], [])
> +AC_PATH_PROG([SS_CMD], [ss], [])
> +AC_PATH_PROG([SYSCTL_CMD], [sysctl], [], [$PATH:/sbin])
> +AC_PATH_PROG([TOUCH_CMD], [touch], [])
> +AC_PATH_PROG([TR_CMD], [tr], [])
> +AC_PATH_PROG([UNAME_CMD], [uname], [])
> +AC_PATH_PROG([UNIQ_CMD], [uniq], [])
> +AC_PATH_PROGS([ZCAT_CMD], [zcat gzcat gunzip gzip], [])
> +AC_CHECK_PROGS([ZCAT_PROG], [zcat gzcat gunzip gzip], [])
> +ZCAT_OPTS=
> +if test "z$ZCAT_PROG" = zgunzip; then
> +ZCAT_OPTS="-c"
> +fi
> +if test "z$ZCAT_PROG" = zgzip; then
> +ZCAT_OPTS="-d -c"
> +fi
> +AC_SUBST(ZCAT_OPTS)
> +
>  AC_CONFIG_FILES([
>  	Makefile
>  	sbin/Makefile
> diff --git a/sbin/sanewall.in b/sbin/sanewall.in
> index 27ae0b7..f0c8500 100755
> --- a/sbin/sanewall.in
> +++ b/sbin/sanewall.in
> @@ -110,236 +110,80 @@ both() {
>  
>  export PATH="${PATH}:/bin:/usr/bin:/sbin:/usr/sbin"
>  
> -# External commands sanewall will need.
> -# If one of those is not found, sanewall will refuse to run.
> -
> -which_cmd() {
> -	local block=1
> -	if [ "a${1}" = "a-n" ]
> +# Set the environment variable to the value given, unless the value
> +# starts with an @ (./configure has not been run). In that case, try
> +# to use the built-in default but verify it can be found with "which".
> +set_or_def() {
> +	if [ "$1" = "-n" ]; then local notreq="Y"; shift; fi
> +	if [ "$(echo $2 | grep '^@')" ]
>  	then
> -		local block=0
> -		shift
> -	fi
> -
> -	unalias $2 >/dev/null 2>&1
> -	local cmd=`which $2 2>/dev/null | head -n 1`
> -	if [ $? -gt 0 -o ! -x "${cmd}" ]
> -	then
> -		if [ ${block} -eq 1 ]
> +		exe="$(which $3)"
> +		if [ "$exe" ]
>  		then
> -			echo >&2
> -			echo >&2 "ERROR:	Command '$2' not found in the system path."
> -			echo >&2 "	Sanewall requires this command for its operation."
> -			echo >&2 "	Please install the required package and retry."
> -			echo >&2
> -			echo >&2 "	Note that you need an operational 'which' command"
> -			echo >&2 "	for sanewall to find all the external programs it"
> -			echo >&2 "	needs. Check it yourself. Run:"
> -			echo >&2
> -			echo >&2 "	which $2"
> -			exit 1
> -		fi
> -		return 1
> -	fi
> -
> -	eval $1=${cmd}
> -	return 0
> -}
> -
> -# command on demand support.
> -require_cmd() {
> -	local block=1
> -	if [ "a$1" = "a-n" ]
> -	then
> -		local block=0
> -		shift
> -	fi
> -
> -	# if one is found, return success
> -	for x in "${@}"
> -	do
> -		eval var=`echo ${x} | tr 'a-z' 'A-Z'`_CMD
> -		eval val=\$\{${var}\}
> -		if [ -z "${val}" ]
> +			eval "$1=$exe"
> +		elif [ "$notreq" ]
>  		then
> -			which_cmd -n "${var}" "${x}"
> -			test $? -eq 0 && return 0
> +			eval "$1=$3"
> +		else
> +			echo "Missing required command: $1 (default $3)"
> +			exit 1
>  		fi
> -	done
> -
> -	if [ $block -eq 1 ]
> -	then
> -		echo >&2
> -		echo >&2 "ERROR:	SANEWALL REQUIRES THESE COMMANDS:"
> -		echo >&2
> -		echo >&2 "	${@}"
> -		echo >&2
> -		echo >&2 "	You have requested the use of an optional sanewall"
> -		echo >&2 "	feature that requires certain external programs"
> -		echo >&2 "	to be installed in the running system."
> -		echo >&2
> -		echo >&2 "	Please consult your Linux distribution manual to"
> -		echo >&2 "	install the package(s) that provide these external"
> -		echo >&2 "	programs and retry."
> -		echo >&2
> -		echo >&2 "	Note that you need an operational 'which' command"
> -		echo >&2 "	for sanewall to find all the external programs it"
> -		echo >&2 "	needs. Check it yourself. Run:"
> -		echo >&2
> -		for x in "${@}"
> -		do
> -			echo >&2 "	which $x"
> -		done
> -
> -		exit 1
> -	fi
> -
> -	return 1
> -}
> -
> -# Currently the following commands are required only when needed.
> -# (i.e. Command on Demand)
> -#
> -# wget or curl (either is fine)
> -# zcat or gzcat or gzip (either or none is fine)
> -# less or more (either or none is fine)
> -# ip
> -# ss
> -# date
> -# hostname
> -# modprobe or insmod
> -# gawk or awk
> -# nice (none is fine)
> -
> -# Commands that are mandatory for sanewall operation:
> -which_cmd CAT_CMD cat
> -which_cmd CUT_CMD cut
> -which_cmd CHOWN_CMD chown
> -which_cmd CHMOD_CMD chmod
> -which_cmd EGREP_CMD egrep
> -which_cmd EXPR_CMD expr
> -which_cmd FIND_CMD find
> -which_cmd FOLD_CMD fold
> -which_cmd GREP_CMD grep
> -which_cmd HEAD_CMD head
> -which_cmd LSMOD_CMD lsmod
> -which_cmd MKDIR_CMD mkdir
> -which_cmd MV_CMD mv
> -which_cmd RM_CMD rm
> -which_cmd SED_CMD sed
> -which_cmd SORT_CMD sort
> -which_cmd SYSCTL_CMD sysctl
> -which_cmd TOUCH_CMD touch
> -which_cmd TR_CMD tr
> -which_cmd UNAME_CMD uname
> -which_cmd UNIQ_CMD uniq
> -which_cmd LOGGER_CMD logger
> -
> -if [ "${IPVER}" = "both" -o  "${IPVER}" = "ipv4" ]
> -then
> -	which_cmd IPTABLES_CMD iptables
> -	which_cmd IPTABLES_SAVE_CMD iptables-save
> -	which_cmd IPTABLES_RESTORE_CMD iptables-restore
> -fi
> -
> -if [ "${IPVER}" = "both" -o  "${IPVER}" = "ipv6" ]
> -then
> -	which_cmd IP6TABLES_CMD ip6tables
> -	which_cmd IP6TABLES_SAVE_CMD ip6tables-save
> -	which_cmd IP6TABLES_RESTORE_CMD ip6tables-restore
> -fi
> -
> -# Special commands
> -pager_cmd() {
> -	if [ -z "${LESS_CMD}" ]
> -	then
> -		require_cmd -n less more
> -		test -z "${LESS_CMD}" && LESS_CMD="${MORE_CMD}"
> -		test -z "${LESS_CMD}" && LESS_CMD="${CAT_CMD}"
> -	fi
> -
> -	"${LESS_CMD}" "${@}"
> -}
> -
> -zcat_cmd() {
> -	require_cmd -n zcat gzcat gzip
> -	test -z "${ZCAT_CMD}" && ZCAT_CMD="${GZCAT_CMD}"
> -
> -	if [ ! -z "${ZCAT_CMD}" ]
> -	then
> -		"${ZCAT_CMD}" "${@}"
> -		return $?
> -	elif [ ! -z "${GZIP_CMD}" ]
> -	then
> -		"${CAT_CMD}" "${@}" | "${GZIP_CMD}" -dc
> -		return $?
> +	else
> +		eval "$1='$2'"
>  	fi
> -
> -	echo >&2 " "
> -	echo >&2 " IMPORTANT WARNING:"
> -	echo >&2 " ------------------"
> -	echo >&2 " Sanewall cannot find any of the commands: zcat, gzcat, gzip."
> -	echo >&2 " Make sure you have one of these available in the system path."
> -	echo >&2 " "
> -
> -	return 1
>  }
>  
> -gawk_cmd() {
> -	require_cmd -n gawk awk
> -	test -z "${GAWK_CMD}" && GAWK_CMD="${AWK_CMD}"
> -
> -	if [ ! -z "${GAWK_CMD}" ]
> -	then
> -		"${GAWK_CMD}" "${@}"
> -		return $?
> -	fi
> -
> -	echo >&2 " "
> -	echo >&2 " IMPORTANT WARNING:"
> -	echo >&2 " ------------------"
> -	echo >&2 " Sanewall cannot find any of the commands: gawk, awk."
> -	echo >&2 " Make sure you have one of these available in the system path."
> -	echo >&2 " "
> -
> -	return 1
> +set_or_def AWK_CMD "@AWK@" "awk"
> +set_or_def CAT_CMD "@CAT_CMD@" "cat"
> +set_or_def CHMOD_CMD "@CHMOD_CMD@" "chmod"
> +set_or_def CHOWN_CMD "@CHOWN_CMD@" "chown"
> +set_or_def CUT_CMD "@CUT_CMD@" "cut"
> +set_or_def DATE_CMD "@DATE_CMD@" "date"
> +set_or_def EGREP_CMD "@EGREP_CMD@" "egrep"
> +set_or_def EXPR_CMD "@EXPR_CMD@" "expr"
> +set_or_def FIND_CMD "@FIND_CMD@" "find"
> +set_or_def FOLD_CMD "@FOLD_CMD@" "fold"
> +set_or_def GREP_CMD "@GREP@" "grep"
> +set_or_def HEAD_CMD "@HEAD_CMD@" "head"
> +set_or_def INSMOD_CMD "@INSMOD_CMD@" "insmod"
> +set_or_def IP6TABLES_CMD "@IP6TABLES_CMD@" "ip6tables"
> +set_or_def IP6TABLES_RESTORE_CMD "@IP6TABLES_RESTORE_CMD@" "ip6tables-restore"
> +set_or_def IP6TABLES_SAVE_CMD "@IP6TABLES_SAVE_CMD@" "ip6tables-save"
> +set_or_def IPTABLES_CMD "@IPTABLES_CMD@" "iptables"
> +set_or_def IPTABLES_RESTORE_CMD "@IPTABLES_RESTORE_CMD@" "iptables-restore"
> +set_or_def IPTABLES_SAVE_CMD "@IPTABLES_SAVE_CMD@" "iptables-save"
> +set_or_def LOGGER_CMD "@LOGGER_CMD@" "logger"
> +set_or_def LSMOD_CMD "@LSMOD_CMD@" "lsmod"
> +set_or_def MKDIR_CMD "@MKDIR_CMD@" "mkdir"
> +set_or_def MV_CMD "@MV_CMD@" "mv"
> +set_or_def PAGER_CMD "@PAGER_CMD@" "cat"
> +set_or_def RENICE_CMD "@RENICE_CMD@" "echo"
> +set_or_def RM_CMD "@RM_CMD@" "rm"
> +set_or_def SED_CMD "@SED@" "sed"
> +set_or_def SORT_CMD "@SORT_CMD@" "sort"
> +set_or_def SYSCTL_CMD "@SYSCTL_CMD@" "sysctl"
> +set_or_def TOUCH_CMD "@TOUCH_CMD@" "touch"
> +set_or_def TR_CMD "@TR_CMD@" "tr"
> +set_or_def UNAME_CMD "@UNAME_CMD@" "uname"
> +set_or_def UNIQ_CMD "@UNIQ_CMD@" "uniq"
> +set_or_def ZCAT_CMD "@ZCAT_CMD@" "zcat"
> +set_or_def -n ZCAT_OPTS "@ZCAT_OPTS@" ""
> +
> +extra_wizard_commands() {
> +	set_or_def IP_CMD "@IP_CMD@" "ip"
> +	set_or_def SS_CMD "@SS_CMD@" "ss"
> +	set_or_def HOSTNAME_CMD "@HOSTNAME_CMD@" "hostname"
>  }
>  
>  modprobe_cmd() {
> -	require_cmd -n modprobe insmod
> -	test -z "${MODPROBE_CMD}" && MODPROBE_CMD="${INSMOD_CMD}"
> -
> -	if [ ! -z "${MODPROBE_CMD}" ]
> +	"${INSMOD_CMD}" "${@}"
> +	status=$?
> +	if [ $status -eq 17 ]
>  	then
> -		"${MODPROBE_CMD}" "${@}"
> -		status=$?
> -		if [ $status -eq 17 ]
> -		then
> -			# insmod: module already loaded - not a problem
> -			return 0
> -		else
> -			return $status
> -		fi
> -	fi
> -
> -	echo >&2 " "
> -	echo >&2 " IMPORTANT WARNING:"
> -	echo >&2 " ------------------"
> -	echo >&2 " Sanewall cannot find any of the commands: modprobe, insmod."
> -	echo >&2 " Make sure you have one of these available in the system path."
> -	echo >&2 " "
> -
> -	return 1
> -}
> -
> -renice_cmd() {
> -	if [ -z "${RENICE_CMD}" ]
> -	then
> -		require_cmd -n renice
> -		test -z "${RENICE_CMD}" && RENICE_CMD=":"
> +		# insmod: module already loaded - not a problem
> +		return 0
>  	fi
> -
> -	"${RENICE_CMD}" "${@}"
> +	return $status
>  }
>  
>  iptables_cmd() {
> @@ -576,35 +420,21 @@ sanewall_concurrent_run_lock() {
>  umask 077
>  
>  # Be nice on production environments
> -renice_cmd 10 $$ >/dev/null 2>/dev/null
> +${RENICE_CMD} 10 $$ >/dev/null 2>/dev/null
>  
>  # Use the old, static FIREHOL minor version
>  FIREHOL_MINOR_VERSION=257
>  
>  if [ "${IPVER}" = "ipv6" ]
>  then
> -  list="IP6TABLES_CMD IP6TABLES_SAVE_CMD IP6TABLES_RESTORE_CMD"
>    TABLES="/proc/net/ip6_tables_names"
>  elif [ "${IPVER}" = "ipv4" ]
>  then
> -  list="IPTABLES_CMD IPTABLES_SAVE_CMD IPTABLES_RESTORE_CMD"
>    TABLES="/proc/net/ip_tables_names"
>  else
> -  list="IPTABLES_CMD IPTABLES_SAVE_CMD IPTABLES_RESTORE_CMD IP6TABLES_CMD IP6TABLES_SAVE_CMD IP6TABLES_RESTORE_CMD"
>    TABLES="/proc/net/ip_tables_names /proc/net/ip6_tables_names"
>  fi
>  
> -for check in $list
> -do
> -        checkname=`echo $check | ${SED_CMD} -e 's/_CMD$//' | ${TR_CMD} A-Z_ a-z-`
> -	eval checkenv=\$$check
> -	if [ -z "${checkenv}" -o ! -x "${checkenv}" ]; then
> -		echo >&2 "Cannot find an executable ${checkname} command."
> -		exit 0
> -	fi
> -done
> -
> -
>  # Initialize iptables
>  iptables_cmd -nxvL >/dev/null 2>&1
>  
> @@ -648,7 +478,7 @@ else
>  fi
>  
>  # The default configuration file, it can be changed on the command line
> -SANEWALL_CONFIG_DIR="@SANEWALL_CONFIG_DIR@"
> +set_or_def -n SANEWALL_CONFIG_DIR "@SANEWALL_CONFIG_DIR@" "/etc/sanewall"
>  SANEWALL_CONFIG="${SANEWALL_CONFIG_DIR}/sanewall.conf"
>  
>  
> @@ -2628,26 +2458,6 @@ cd "${SANEWALL_DEFAULT_WORKING_DIRECTORY}" || exit 1
>  # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
>  # ------------------------------------------------------------------------------
>  
> -# Fetch a URL and output it to the standard output.
> -sanewall_wget() {
> -	local url="${1}"
> -
> -	require_cmd wget curl
> -
> -	if [ ! -z "${WGET_CMD}" ]
> -	then
> -		${WGET_CMD} -O - "${url}" 2>/dev/null
> -		return $?
> -	elif [ ! -z "${CURL_CMD}" ]
> -	then
> -		${CURL_CMD} -s "${url}"
> -		return $?
> -	fi
> -
> -	error "Cannot use either 'wget' or 'curl' to fetch '${url}'."
> -	return 1
> -}
> -
>  ecn_shame() {
>  	softwarning "ECN_SHAME IP list no longer available, helper is ignored."
>  	return 0
> @@ -3595,7 +3405,7 @@ fi
>  if [ -z "${KERNEL_CONFIG}" -a -f "/proc/config.gz" ]
>  then
>  	KERNEL_CONFIG="/proc/config.gz"
> -	zcat_cmd /proc/config.gz >"${SANEWALL_DIR}/kcfg" || KERNEL_CONFIG=
> +	${ZCAT_CMD} ${ZCAT_OPTS} /proc/config.gz >"${SANEWALL_DIR}/kcfg" || KERNEL_CONFIG=
>  fi
>  
>  if [ -z "${KERNEL_CONFIG}" -a -f "/lib/modules/`${UNAME_CMD} -r`/build/.config" ]
> @@ -6206,10 +6016,10 @@ wait_for_interface() {
>  		timeout=$1
>  	fi
>  
> -	local start=`date +%s`
> +	local start=`${DATE_CMD} +%s`
>  	local found=0
>  
> -	while [ "`date +%s`" -lt $(($start+$timeout)) -a $found -eq 0 ]
> +	while [ "`${DATE_CMD} +%s`" -lt $(($start+$timeout)) -a $found -eq 0 ]
>  	do
>  		local addr=`ip addr show $iface 2> /dev/null | awk '$1 ~ /^inet$/ {print $2}'`
>  		if [ -n "$addr" ]
> @@ -6386,7 +6196,7 @@ case "${arg}" in
>  			echo "--- FILTER ---------------------------------------------------------------------"
>  			echo
>  			iptables_cmd -nxvL
> -		) | pager_cmd
> +		) | ${PAGER_CMD}
>  		exit $?
>  		;;
>  
> @@ -6796,11 +6606,7 @@ fi
>  
>  if [ "${SANEWALL_MODE}" = "WIZARD" ]
>  then
> -	# require commands for wizard mode
> -	require_cmd ip
> -	require_cmd ss
> -	require_cmd date
> -	require_cmd hostname
> +	extra_wizard_commands
>  
>  	wizard_ask() {
>  		local prompt="${1}"; shift
> @@ -7638,7 +7444,7 @@ EOF
>  
>  # at the same time, replace all full iptables/ip6tables references with our
>  # versions to protect the currently running firewall
> -${CAT_CMD} ${SANEWALL_CONFIG} | ${SED_CMD} -e "s|${IPTABLES_CMD}|ipv4 iptables|g" -e "s|${IP6TABLES_CMD}|ipv6 iptables|g" | gawk_cmd -f "${SANEWALL_TMP}.awk" >${SANEWALL_TMP}
> +${CAT_CMD} ${SANEWALL_CONFIG} | ${SED_CMD} -e "s|${IPTABLES_CMD}|ipv4 iptables|g" -e "s|${IP6TABLES_CMD}|ipv6 iptables|g" | ${AWK_CMD} -f "${SANEWALL_TMP}.awk" >${SANEWALL_TMP}
>  ${RM_CMD} -f "${SANEWALL_TMP}.awk"
>  
>  # ------------------------------------------------------------------------------


More information about the Sanewall-Dev mailing list