1ab2043b8SDevin Teskeif [ ! "$_STARTUP_RCVAR_SUBR" ]; then _STARTUP_RCVAR_SUBR=1 2ab2043b8SDevin Teske# 3d3a0f918SDevin Teske# Copyright (c) 2006-2013 Devin Teske 4f8ea072aSDevin Teske# All rights reserved. 5ab2043b8SDevin Teske# 6ab2043b8SDevin Teske# Redistribution and use in source and binary forms, with or without 7ab2043b8SDevin Teske# modification, are permitted provided that the following conditions 8ab2043b8SDevin Teske# are met: 9ab2043b8SDevin Teske# 1. Redistributions of source code must retain the above copyright 10ab2043b8SDevin Teske# notice, this list of conditions and the following disclaimer. 11ab2043b8SDevin Teske# 2. Redistributions in binary form must reproduce the above copyright 12ab2043b8SDevin Teske# notice, this list of conditions and the following disclaimer in the 13ab2043b8SDevin Teske# documentation and/or other materials provided with the distribution. 14ab2043b8SDevin Teske# 15ab2043b8SDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 168e37a7c8SDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17ab2043b8SDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18ab2043b8SDevin Teske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19ab2043b8SDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 208e37a7c8SDevin Teske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21ab2043b8SDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22ab2043b8SDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23ab2043b8SDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24ab2043b8SDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25ab2043b8SDevin Teske# SUCH DAMAGE. 26ab2043b8SDevin Teske# 27ab2043b8SDevin Teske# 28ab2043b8SDevin Teske############################################################ INCLUDES 29ab2043b8SDevin Teske 30ab2043b8SDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig" 31ab2043b8SDevin Teske. $BSDCFG_SHARE/common.subr || exit 1 3256961fd7SDevin Teskef_dprintf "%s: loading includes..." startup/rcvar.subr 33ab2043b8SDevin Teskef_include $BSDCFG_SHARE/sysrc.subr 34ab2043b8SDevin Teske 35ab2043b8SDevin Teske############################################################ CONFIGURATION 36ab2043b8SDevin Teske 37ab2043b8SDevin Teske# 38ab2043b8SDevin Teske# Default path to the `/etc/rc.d' directory where service(8) scripts are stored 39ab2043b8SDevin Teske# 40ab2043b8SDevin Teske: ${ETC_RC_D:=/etc/rc.d} 41ab2043b8SDevin Teske 42ab2043b8SDevin Teske# 43ab2043b8SDevin Teske# Default path to `/etc/rc.subr' (for find_local_scripts_new()) 44ab2043b8SDevin Teske# 45ab2043b8SDevin Teske: ${ETC_RC_SUBR:=/etc/rc.subr} 46ab2043b8SDevin Teske 47ab2043b8SDevin Teske############################################################ GLOBALS 48ab2043b8SDevin Teske 49ab2043b8SDevin Teske# 50ab2043b8SDevin Teske# Initialize in-memory cache variables 51ab2043b8SDevin Teske# 52ab2043b8SDevin TeskeSTARTUP_RCVAR_MAP= 53ab2043b8SDevin Teske_STARTUP_RCVAR_MAP= 54ab2043b8SDevin Teske 55ab2043b8SDevin Teske# 56ab2043b8SDevin Teske# Define what an rcvar looks like 57ab2043b8SDevin Teske# 58ab2043b8SDevin TeskeSTARTUP_RCVAR_REGEX='[[:alpha:]_][[:alnum:]_]*="([Yy][Ee][Ss]|[Nn][Oo])"' 59ab2043b8SDevin Teske 60ab2043b8SDevin Teske# 61ab2043b8SDevin Teske# Default path to on-disk cache file(s) 62ab2043b8SDevin Teske# 63ab2043b8SDevin TeskeSTARTUP_RCVAR_MAP_CACHEFILE="/var/run/bsdconfig/startup_rcvar_map.cache" 64ab2043b8SDevin Teske 65ab2043b8SDevin Teske############################################################ FUNCTIONS 66ab2043b8SDevin Teske 67d3a0f918SDevin Teske# f_startup_rcvar_map [$var_to_set] 68ab2043b8SDevin Teske# 69ab2043b8SDevin Teske# Produce a map (beit from in-memory cache or on-disk cache) of rc.d scripts 70ab2043b8SDevin Teske# and their associated rcvar's. The map returned has the following format: 71ab2043b8SDevin Teske# 72ab2043b8SDevin Teske# rcvar default script description 73ab2043b8SDevin Teske# 74ab2043b8SDevin Teske# With each as follows: 75ab2043b8SDevin Teske# 76ab2043b8SDevin Teske# rcvar the variable used to enable this rc.d script 77ab2043b8SDevin Teske# default default value for this variable 78ab2043b8SDevin Teske# script the rc.d script in-question 79ab2043b8SDevin Teske# description description of the variable from rc.conf(5) defaults 80ab2043b8SDevin Teske# 81d3a0f918SDevin Teske# If $var_to_set is missing or NULL, the map is printed to standard output for 82d3a0f918SDevin Teske# capturing in a sub-shell (which is less-recommended because of performance 83d3a0f918SDevin Teske# degredation; for example, when called in a loop). 84d3a0f918SDevin Teske# 85ab2043b8SDevin Teskef_startup_rcvar_map() 86ab2043b8SDevin Teske{ 87d4ae33f0SDevin Teske local __funcname=f_startup_rcvar_map 88d3a0f918SDevin Teske local __var_to_set="$1" 89d3a0f918SDevin Teske 90ab2043b8SDevin Teske # If the in-memory cached value is available, return it immediately 91ab2043b8SDevin Teske if [ "$_STARTUP_RCVAR_MAP" ]; then 92d3a0f918SDevin Teske if [ "$__var_to_set" ]; then 93d3a0f918SDevin Teske setvar "$__var_to_set" "$STARTUP_RCVAR_MAP" 94d3a0f918SDevin Teske else 95ab2043b8SDevin Teske echo "$STARTUP_RCVAR_MAP" 96d3a0f918SDevin Teske fi 97ab2043b8SDevin Teske return $SUCCESS 98ab2043b8SDevin Teske fi 99ab2043b8SDevin Teske 100ab2043b8SDevin Teske # 101ab2043b8SDevin Teske # create the in-memory cache (potentially from validated on-disk cache) 102ab2043b8SDevin Teske # 103ab2043b8SDevin Teske 104ab2043b8SDevin Teske # Get a list of /etc/rc.d scripts ... 105d3a0f918SDevin Teske local __file __rc_script_list= 106d3a0f918SDevin Teske for __file in "$ETC_RC_D"/*; do 107d3a0f918SDevin Teske [ -f "$__file" ] || continue 108d3a0f918SDevin Teske [ -x "$__file" ] || continue 109d3a0f918SDevin Teske __rc_script_list="$__rc_script_list $__file" 110ab2043b8SDevin Teske done 111ab2043b8SDevin Teske # ... and /usr/local/etc/rc.d scripts 112d3a0f918SDevin Teske __rc_script_list="$__rc_script_list $( 113ab2043b8SDevin Teske local_startup=$( f_sysrc_get local_startup ) 114ab2043b8SDevin Teske f_include "$ETC_RC_SUBR" 115ab2043b8SDevin Teske find_local_scripts_new 116ab2043b8SDevin Teske echo $local_rc 117ab2043b8SDevin Teske )" 118d3a0f918SDevin Teske __rc_script_list="${__rc_script_list# }" # Trim leading space 119ab2043b8SDevin Teske 120ab2043b8SDevin Teske # 121d1bb7ccaSDevin Teske # Calculate a digest given the checksums of all dependencies (scripts 122d1bb7ccaSDevin Teske # and the defaults file). This digest will be used to determine if an 123ec65e4f8SPedro F. Giffuni # on-disk global persistent cache file (containg this digest on the 124d1bb7ccaSDevin Teske # first line) is valid and can be used to quickly populate the cache 125d1bb7ccaSDevin Teske # value for immediate return. 126ab2043b8SDevin Teske # 127d3a0f918SDevin Teske local __rc_script_list_digest 128d4ae33f0SDevin Teske __rc_script_list_digest=$( cd "$ETC_RC_D" 2> /dev/null && 129d4ae33f0SDevin Teske cksum "$RC_DEFAULTS" $__rc_script_list 2> /dev/null | md5 ) 130ab2043b8SDevin Teske 131ab2043b8SDevin Teske # 132ec65e4f8SPedro F. Giffuni # Check to see if the global persistent cache file exists 133ab2043b8SDevin Teske # 134ab2043b8SDevin Teske if [ -f "$STARTUP_RCVAR_MAP_CACHEFILE" ]; then 135ab2043b8SDevin Teske # 136ab2043b8SDevin Teske # Attempt to populate the in-memory cache with the (soon to be) 137d3a0f918SDevin Teske # validated on-disk cache. If validation fails, fall-back to 138d3a0f918SDevin Teske # the current value and return error. 139ab2043b8SDevin Teske # 140ab2043b8SDevin Teske STARTUP_RCVAR_MAP=$( 141d3a0f918SDevin Teske ( # Get digest as first word on first line 142ab2043b8SDevin Teske read digest rest_ignored 143ab2043b8SDevin Teske 144ab2043b8SDevin Teske # 145d1bb7ccaSDevin Teske # If the stored digest matches the calculated- 146d1bb7ccaSDevin Teske # one populate the in-memory cache from the on- 147d3a0f918SDevin Teske # disk cache and return success. 148ab2043b8SDevin Teske # 149d3a0f918SDevin Teske if [ "$digest" = "$__rc_script_list_digest" ] 150d1bb7ccaSDevin Teske then 151ab2043b8SDevin Teske cat 152ab2043b8SDevin Teske exit $SUCCESS 153ab2043b8SDevin Teske else 154ab2043b8SDevin Teske # Otherwise, return the current value 155ab2043b8SDevin Teske echo "$STARTUP_RCVAR_MAP" 156ab2043b8SDevin Teske exit $FAILURE 157ab2043b8SDevin Teske fi 158ab2043b8SDevin Teske ) < "$STARTUP_RCVAR_MAP_CACHEFILE" 159ab2043b8SDevin Teske ) 160d3a0f918SDevin Teske local __retval=$? 161d3a0f918SDevin Teske export STARTUP_RCVAR_MAP # Make children faster (export cache) 162d3a0f918SDevin Teske if [ $__retval -eq $SUCCESS ]; then 163ab2043b8SDevin Teske export _STARTUP_RCVAR_MAP=1 164d3a0f918SDevin Teske if [ "$__var_to_set" ]; then 165d3a0f918SDevin Teske setvar "$__var_to_set" "$STARTUP_RCVAR_MAP" 166d3a0f918SDevin Teske else 167ab2043b8SDevin Teske echo "$STARTUP_RCVAR_MAP" 168d3a0f918SDevin Teske fi 169ab2043b8SDevin Teske return $SUCCESS 170ab2043b8SDevin Teske fi 171d1bb7ccaSDevin Teske # Otherwise, fall-thru to create in-memory cache from scratch 172ab2043b8SDevin Teske fi 173ab2043b8SDevin Teske 174ab2043b8SDevin Teske # 175ab2043b8SDevin Teske # If we reach this point, we need to generate the data from scratch 176ec65e4f8SPedro F. Giffuni # (and after we do, we'll attempt to create the global persistent 177ab2043b8SDevin Teske # cache file to speed up future executions). 178ab2043b8SDevin Teske # 179ab2043b8SDevin Teske 180ab2043b8SDevin Teske STARTUP_RCVAR_MAP=$( 181d3a0f918SDevin Teske for script in $__rc_script_list; do 182d4ae33f0SDevin Teske rcvar_list=$( $script rcvar 2> /dev/null | awk -F= \ 183ab2043b8SDevin Teske -v script="$script" ' 184ab2043b8SDevin Teske /^'"$STARTUP_RCVAR_REGEX"'/ { 185ab2043b8SDevin Teske if ( $2 ~ /^"[Yy][Ee][Ss]"$/ ) 186ab2043b8SDevin Teske print $1 ",YES" 187ab2043b8SDevin Teske else 188ab2043b8SDevin Teske print $1 ",NO" 189ab2043b8SDevin Teske }' ) 190ab2043b8SDevin Teske for entry in $rcvar_list; do 191ab2043b8SDevin Teske rcvar="${entry%%,*}" 192ab2043b8SDevin Teske rcvar_default=$( f_sysrc_get_default "$rcvar" ) 193ab2043b8SDevin Teske [ "$rcvar_default" ] || 194ab2043b8SDevin Teske rcvar_default="${entry#*,}" 195ab2043b8SDevin Teske rcvar_desc=$( f_sysrc_desc "$rcvar" ) 196ab2043b8SDevin Teske echo $rcvar ${rcvar_default:-NO} \ 197ab2043b8SDevin Teske $script "$rcvar_desc" 198ab2043b8SDevin Teske done 199ab2043b8SDevin Teske done | sort -u 200ab2043b8SDevin Teske ) 201ab2043b8SDevin Teske export STARTUP_RCVAR_MAP 202ab2043b8SDevin Teske export _STARTUP_RCVAR_MAP=1 203d3a0f918SDevin Teske if [ "$__var_to_set" ]; then 204d3a0f918SDevin Teske setvar "$__var_to_set" "$STARTUP_RCVAR_MAP" 205d3a0f918SDevin Teske else 206ab2043b8SDevin Teske echo "$STARTUP_RCVAR_MAP" 207d3a0f918SDevin Teske fi 208ab2043b8SDevin Teske 209ab2043b8SDevin Teske # 210ec65e4f8SPedro F. Giffuni # Attempt to create/update the persistent global cache 211ab2043b8SDevin Teske # 212ab2043b8SDevin Teske 213ab2043b8SDevin Teske # Create a new temporary file to write to 214d4ae33f0SDevin Teske local __tmpfile 215d4ae33f0SDevin Teske f_eval_catch -dk __tmpfile $__funcname mktemp \ 216d4ae33f0SDevin Teske 'mktemp -t "%s"' "$__tmpfile" || return $FAILURE 217ab2043b8SDevin Teske 218ab2043b8SDevin Teske # Write the temporary file contents 219d3a0f918SDevin Teske echo "$__rc_script_list_digest" > "$__tmpfile" 220d3a0f918SDevin Teske echo "$STARTUP_RCVAR_MAP" >> "$__tmpfile" 221ab2043b8SDevin Teske 222ab2043b8SDevin Teske # Finally, move the temporary file into place 223ab2043b8SDevin Teske case "$STARTUP_RCVAR_MAP_CACHEFILE" in 224d4ae33f0SDevin Teske */*) f_eval_catch -d $__funcname mkdir \ 225d4ae33f0SDevin Teske 'mkdir -p "%s"' "${STARTUP_RCVAR_MAP_CACHEFILE%/*}" 226ab2043b8SDevin Teske esac 227d4ae33f0SDevin Teske f_eval_catch -d $__funcname mv \ 228d4ae33f0SDevin Teske 'mv "%s" "%s"' "$__tmpfile" "$STARTUP_RCVAR_MAP_CACHEFILE" 229ab2043b8SDevin Teske} 230ab2043b8SDevin Teske 23156961fd7SDevin Teske############################################################ MAIN 23256961fd7SDevin Teske 23356961fd7SDevin Teskef_dprintf "%s: Successfully loaded." startup/rcvar.subr 23456961fd7SDevin Teske 235ab2043b8SDevin Teskefi # ! $_STARTUP_RCVAR_SUBR 236