Loosen the processing of *_IF_aliasN vars to be less strict. Previously,

the first alias had to be _alias0 and processing stopped at the first non-
defined variable (preventing gaps). Allowing gaps gives the administrator
the ability to group aliases in an adhoc manner and also lifts the
requirement to renumber aliases simply to comment-out an existing one.
Aliases are processed in numerical ascending order.

Discussed on:	-rc
MFC after:	1 week
This commit is contained in:
dteske 2014-04-07 22:40:29 +00:00
parent 4fc5a92a24
commit 6b8b017a4a
4 changed files with 293 additions and 38 deletions

View File

@ -283,10 +283,8 @@ get_if_var()
fi
_if=$1
_punct=". - / +"
for _punct_c in $_punct; do
_if=`ltr ${_if} ${_punct_c} '_'`
done
_punct=".-/+"
ltr ${_if} "${_punct}" '_' _if
_var=$2
_default=$3
@ -1076,6 +1074,7 @@ ifalias_af_common_handler()
ifalias_af_common()
{
local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf
local _punct=".-/+"
_ret=1
_aliasn=
@ -1083,10 +1082,14 @@ ifalias_af_common()
_af=$2
_action=$3
# Normalize $_if before using it in a pattern to list_vars()
ltr "$_if" "$_punct" "_" _if
# ifconfig_IF_aliasN which starts with $_af
alias=0
while : ; do
ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}`
for alias in `list_vars ifconfig_${_if}_alias[0-9]\* |
sort_lite -nk1.$((9+${#_if}+7))`
do
eval ifconfig_args=\"\$$alias\"
_iaf=
case $ifconfig_args in
inet\ *) _iaf=inet ;;
@ -1107,15 +1110,15 @@ ifalias_af_common()
warn "\$ifconfig_${_if}_alias${alias} needs " \
"\"inet\" keyword for an IPv4 address."
esac
alias=$(($alias + 1))
done
# backward compatibility: ipv6_ifconfig_IF_aliasN.
case $_af in
inet6)
alias=0
while : ; do
ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}`
for alias in `list_vars ipv6_ifconfig_${_if}_alias[0-9]\* |
sort_lite -nk1.$((14+${#_if}+7))`
do
eval ifconfig_args=\"\$$alias\"
case ${_action}:"${ifconfig_args}" in
*:"")
break
@ -1127,7 +1130,6 @@ ifalias_af_common()
"instead."
;;
esac
alias=$(($alias + 1))
done
esac

View File

@ -181,17 +181,14 @@ fi
load_rc_config $name
_mdconfig_unit=0
if [ -z "${_mdconfig_list}" ]; then
while :; do
eval _mdconfig_config=\$mdconfig_md${_mdconfig_unit}
if [ -z "${_mdconfig_config}" ]; then
break
else
_mdconfig_list="${_mdconfig_list}${_mdconfig_list:+ }md${_mdconfig_unit}"
_mdconfig_unit=$((${_mdconfig_unit} + 1))
fi
for _mdconfig_config in `list_vars mdconfig_md[0-9]\* |
sort_lite -nk1.12`
do
_mdconfig_unit=${_mdconfig_config#mdconfig_md}
_mdconfig_list="$_mdconfig_list md$_mdconfig_unit"
done
_mdconfig_list="${_mdconfig_list# }"
fi
run_rc_command "${_mdconfig_cmd}"

View File

@ -211,17 +211,14 @@ fi
load_rc_config $name
_mdconfig2_unit=0
if [ -z "${_mdconfig2_list}" ]; then
while :; do
eval _mdconfig2_config=\$mdconfig_md${_mdconfig2_unit}
if [ -z "${_mdconfig2_config}" ]; then
break
else
_mdconfig2_list="${_mdconfig2_list}${_mdconfig2_list:+ }md${_mdconfig2_unit}"
_mdconfig2_unit=$((${_mdconfig2_unit} + 1))
fi
for _mdconfig2_config in `list_vars mdconfig_md[0-9]\* |
sort_lite -nk1.12`
do
_mdconfig2_unit=${_mdconfig2_config#mdconfig_md}
_mdconfig2_list="$_mdconfig2_list md$_mdconfig2_unit"
done
_mdconfig2_list="${_mdconfig2_list# }"
fi
run_rc_command "${_mdconfig2_cmd}"

View File

@ -54,6 +54,20 @@ JID=`$PS -p $$ -o jid=`
# functions
# ---------
# list_vars pattern
# List vars matching pattern.
#
list_vars()
{
set | { while read LINE; do
var="${LINE%%=*}"
case "$var" in
"$LINE"|*[!a-zA-Z0-9_]*) continue ;;
$1) echo $var
esac
done; }
}
# set_rcvar_obsolete oldvar [newvar] [msg]
# Define obsolete variable.
# Global variable $rcvars_obsolete is used.
@ -314,6 +328,246 @@ _find_processes()
eval $_proccheck
}
# sort_lite [-b] [-n] [-k POS] [-t SEP]
# A lite version of sort(1) (supporting a few options) that can be used
# before the real sort(1) is available (e.g., in scripts that run prior
# to mountcritremote). Requires only shell built-in functionality.
#
sort_lite()
{
local funcname=sort_lite
local sort_sep="$IFS" sort_ignore_leading_space=
local sort_field=0 sort_strict_fields= sort_numeric=
local nitems=0 skip_leading=0 trim=
local OPTIND flag
while getopts bnk:t: flag; do
case "$flag" in
b) sort_ignore_leading_space=1 ;;
n) sort_numeric=1 sort_ignore_leading_space=1 ;;
k) sort_field="${OPTARG%%,*}" ;; # only up to first comma
# NB: Unlike sort(1) only one POS allowed
t) sort_sep="$OPTARG"
if [ ${#sort_sep} -gt 1 ]; then
echo "$funcname: multi-character tab \`$sort_sep'" >&2
return 1
fi
sort_strict_fields=1
;;
\?) return 1 ;;
esac
done
shift $(( $OPTIND - 1 ))
# Create transformation pattern to trim leading text if desired
case "$sort_field" in
""|[!0-9]*|*[!0-9.]*)
echo "$funcname: invalid sort field \`$sort_field'" >&2
return 1
;;
*.*)
skip_leading=${sort_field#*.} sort_field=${sort_field%%.*}
while [ ${skip_leading:-0} -gt 1 ] 2> /dev/null; do
trim="$trim?" skip_leading=$(( $skip_leading - 1 ))
done
esac
# Copy input to series of local numbered variables
# NB: IFS of NULL preserves leading whitespace
local LINE
while IFS= read -r LINE || [ "$LINE" ]; do
nitems=$(( $nitems + 1 ))
local src_$nitems="$LINE"
done
#
# Sort numbered locals using insertion sort
#
local curitem curitem_orig curitem_mod curitem_haskey
local dest dest_orig dest_mod dest_haskey
local d gt n
local i=1
while [ $i -le $nitems ]; do
curitem_haskey=1 # Assume sort field (-k POS) exists
eval curitem=\"\$src_$i\"
curitem_mod="$curitem" # for modified comparison
curitem_orig="$curitem" # for original comparison
# Trim leading whitespace if desired
if [ "$sort_ignore_leading_space" ]; then
while case "$curitem_orig" in
[$IFS]*) : ;; *) false; esac
do
curitem_orig="${curitem_orig#?}"
done
curitem_mod="$curitem_orig"
fi
# Shift modified comparison value if sort field (-k POS) is > 1
n=$sort_field
while [ $n -gt 1 ]; do
case "$curitem_mod" in
*[$sort_sep]*)
# Cut text up-to (and incl.) first separator
curitem_mod="${curitem_mod#*[$sort_sep]}"
# Skip NULLs unless strict field splitting
[ "$sort_strict_fields" ] ||
[ "${curitem_mod%%[$sort_sep]*}" ] ||
[ $n -eq 2 ] ||
continue
;;
*)
# Asked for a field that doesn't exist
curitem_haskey= break
esac
n=$(( $n - 1 ))
done
# Trim trailing words if sort field >= 1
[ $sort_field -ge 1 -a "$sort_numeric" ] &&
curitem_mod="${curitem_mod%%[$sort_sep]*}"
# Apply optional trim (-k POS.TRIM) to cut leading characters
curitem_mod="${curitem_mod#$trim}"
# Determine the type of modified comparison to use initially
# NB: Prefer numerical if requested but fallback to standard
case "$curitem_mod" in
""|[!0-9]*) # NULL or begins with non-number
gt=">"
[ "$sort_numeric" ] && curitem_mod=0
;;
*)
if [ "$sort_numeric" ]; then
gt="-gt"
curitem_mod="${curitem_mod%%[!0-9]*}"
# NB: trailing non-digits removed
# otherwise numeric comparison fails
else
gt=">"
fi
esac
# If first time through, short-circuit below position-search
if [ $i -le 1 ]; then
d=0
else
d=1
fi
#
# Find appropriate element position
#
while [ $d -gt 0 ]
do
dest_haskey=$curitem_haskey
eval dest=\"\$dest_$d\"
dest_mod="$dest" # for modified comparison
dest_orig="$dest" # for original comparison
# Trim leading whitespace if desired
if [ "$sort_ignore_leading_space" ]; then
while case "$dest_orig" in
[$IFS]*) : ;; *) false; esac
do
dest_orig="${dest_orig#?}"
done
dest_mod="$dest_orig"
fi
# Shift modified value if sort field (-k POS) is > 1
n=$sort_field
while [ $n -gt 1 ]; do
case "$dest_mod" in
*[$sort_sep]*)
# Cut text up-to (and incl.) 1st sep
dest_mod="${dest_mod#*[$sort_sep]}"
# Skip NULLs unless strict fields
[ "$sort_strict_fields" ] ||
[ "${dest_mod%%[$sort_sep]*}" ] ||
[ $n -eq 2 ] ||
continue
;;
*)
# Asked for a field that doesn't exist
dest_haskey= break
esac
n=$(( $n - 1 ))
done
# Trim trailing words if sort field >= 1
[ $sort_field -ge 1 -a "$sort_numeric" ] &&
dest_mod="${dest_mod%%[$sort_sep]*}"
# Apply optional trim (-k POS.TRIM), cut leading chars
dest_mod="${dest_mod#$trim}"
# Determine type of modified comparison to use
# NB: Prefer numerical if requested, fallback to std
case "$dest_mod" in
""|[!0-9]*) # NULL or begins with non-number
gt=">"
[ "$sort_numeric" ] && dest_mod=0
;;
*)
if [ "$sort_numeric" ]; then
gt="-gt"
dest_mod="${dest_mod%%[!0-9]*}"
# NB: kill trailing non-digits
# for numeric comparison safety
else
gt=">"
fi
esac
# Break if we've found the proper element position
if [ "$curitem_haskey" -a "$dest_haskey" ]; then
if [ "$dest_mod" = "$curitem_mod" ]; then
[ "$dest_orig" ">" "$curitem_orig" ] &&
break
elif [ "$dest_mod" $gt "$curitem_mod" ] \
2> /dev/null
then
break
fi
else
[ "$dest_orig" ">" "$curitem_orig" ] && break
fi
# Break if we've hit the end
[ $d -ge $i ] && break
d=$(( $d + 1 ))
done
# Shift remaining positions forward, making room for new item
n=$i
while [ $n -ge $d ]; do
# Shift destination item forward one placement
eval dest_$(( $n + 1 ))=\"\$dest_$n\"
n=$(( $n - 1 ))
done
# Place the element
if [ $i -eq 1 ]; then
local dest_1="$curitem"
else
local dest_$d="$curitem"
fi
i=$(( $i + 1 ))
done
# Print sorted results
d=1
while [ $d -le $nitems ]; do
eval echo \"\$dest_$d\"
d=$(( $d + 1 ))
done
}
#
# wait_for_pids pid [pid ...]
# spins until none of the pids exist
@ -1524,19 +1778,20 @@ load_kld()
return 0
}
# ltr str src dst
# ltr str src dst [var]
# Change every $src in $str to $dst.
# Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor
# awk(1).
# awk(1). If var is non-NULL, set it to the result.
ltr()
{
local _str _src _dst _out _com
_str=$1
_src=$2
_dst=$3
local _str _src _dst _out _com _var
_str="$1"
_src="$2"
_dst="$3"
_var="$4"
_out=""
IFS=${_src}
local IFS="${_src}"
for _com in ${_str}; do
if [ -z "${_out}" ]; then
_out="${_com}"
@ -1544,7 +1799,11 @@ ltr()
_out="${_out}${_dst}${_com}"
fi
done
echo "${_out}"
if [ -n "${_var}" ]; then
setvar "${_var}" "${_out}"
else
echo "${_out}"
fi
}
# Creates a list of providers for GELI encryption.