summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authordteske <dteske@FreeBSD.org>2014-04-14 01:44:56 +0000
committerdteske <dteske@FreeBSD.org>2014-04-14 01:44:56 +0000
commit4f557eb9380e350e00df186d627969b28ea499a8 (patch)
tree00bb6a6eea5764702d03d61c8ace4e43d4b012aa /etc
parent7c94aa998b99433249dd333543dac870e358fee1 (diff)
downloadFreeBSD-src-4f557eb9380e350e00df186d627969b28ea499a8.zip
FreeBSD-src-4f557eb9380e350e00df186d627969b28ea499a8.tar.gz
MFC r264243:
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. NB: Also Patches mdconfig{,2} rc(8) boot scripts to loosen the numbering scheme for mdconfig_mdN settings to be less strict in the same manner. Discussed on: -rc
Diffstat (limited to 'etc')
-rw-r--r--etc/network.subr26
-rwxr-xr-xetc/rc.d/mdconfig15
-rwxr-xr-xetc/rc.d/mdconfig215
-rw-r--r--etc/rc.subr275
4 files changed, 293 insertions, 38 deletions
diff --git a/etc/network.subr b/etc/network.subr
index f92cab1..7a289cf 100644
--- a/etc/network.subr
+++ b/etc/network.subr
@@ -285,10 +285,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
@@ -1081,6 +1079,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=
@@ -1088,10 +1087,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 ;;
@@ -1113,15 +1116,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
@@ -1133,7 +1136,6 @@ ifalias_af_common()
"instead."
;;
esac
- alias=$(($alias + 1))
done
esac
diff --git a/etc/rc.d/mdconfig b/etc/rc.d/mdconfig
index 7b9ddf8..627da87 100755
--- a/etc/rc.d/mdconfig
+++ b/etc/rc.d/mdconfig
@@ -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}"
diff --git a/etc/rc.d/mdconfig2 b/etc/rc.d/mdconfig2
index 4b1535e..85fd07f 100755
--- a/etc/rc.d/mdconfig2
+++ b/etc/rc.d/mdconfig2
@@ -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}"
diff --git a/etc/rc.subr b/etc/rc.subr
index 152b70e..b6172db 100644
--- a/etc/rc.subr
+++ b/etc/rc.subr
@@ -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.
OpenPOWER on IntegriCloud