1ab2043b8SDevin Teskeif [ ! "$_COMMON_SUBR" ]; then _COMMON_SUBR=1 2ab2043b8SDevin Teske# 3ab2043b8SDevin Teske# Copyright (c) 2012 Ron McDowell 4d1eef61dSDevin Teske# Copyright (c) 2012-2016 Devin Teske 5ab2043b8SDevin Teske# All rights reserved. 6ab2043b8SDevin Teske# 7ab2043b8SDevin Teske# Redistribution and use in source and binary forms, with or without 8ab2043b8SDevin Teske# modification, are permitted provided that the following conditions 9ab2043b8SDevin Teske# are met: 10ab2043b8SDevin Teske# 1. Redistributions of source code must retain the above copyright 11ab2043b8SDevin Teske# notice, this list of conditions and the following disclaimer. 12ab2043b8SDevin Teske# 2. Redistributions in binary form must reproduce the above copyright 13ab2043b8SDevin Teske# notice, this list of conditions and the following disclaimer in the 14ab2043b8SDevin Teske# documentation and/or other materials provided with the distribution. 15ab2043b8SDevin Teske# 16ab2043b8SDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17ab2043b8SDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18ab2043b8SDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ab2043b8SDevin Teske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20ab2043b8SDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ab2043b8SDevin Teske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22ab2043b8SDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23ab2043b8SDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24ab2043b8SDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25ab2043b8SDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26ab2043b8SDevin Teske# SUCH DAMAGE. 27ab2043b8SDevin Teske# 28ab2043b8SDevin Teske# 29526e1dc1SDevin Teske############################################################ CONFIGURATION 30526e1dc1SDevin Teske 31526e1dc1SDevin Teske# 32526e1dc1SDevin Teske# Default file descriptors to link to stdout/stderr for passthru allowing 33526e1dc1SDevin Teske# redirection within a sub-shell to bypass directly to the terminal. 34526e1dc1SDevin Teske# 35dc68c8b3SDevin Teske: ${TERMINAL_STDOUT_PASSTHRU:=3} 36dc68c8b3SDevin Teske: ${TERMINAL_STDERR_PASSTHRU:=4} 37526e1dc1SDevin Teske 38cc42ef53SBrad Davis# 39cc42ef53SBrad Davis# Default OSNAME shown in the installer 40cc42ef53SBrad Davis# 41cc42ef53SBrad Davis: ${OSNAME:=FreeBSD} 42cc42ef53SBrad Davis: ${EFI_LABEL_NAME:=FreeBSD} 43cc42ef53SBrad Davis 44ab2043b8SDevin Teske############################################################ GLOBALS 45ab2043b8SDevin Teske 46ab2043b8SDevin Teske# 47ab2043b8SDevin Teske# Program name 48ab2043b8SDevin Teske# 49ab2043b8SDevin Teskepgm="${0##*/}" 50ab2043b8SDevin Teske 51ab2043b8SDevin Teske# 52ab2043b8SDevin Teske# Program arguments 53ab2043b8SDevin Teske# 54ab2043b8SDevin TeskeARGC="$#" 55ab2043b8SDevin TeskeARGV="$@" 56ab2043b8SDevin Teske 57ab2043b8SDevin Teske# 58ab2043b8SDevin Teske# Global exit status variables 59ab2043b8SDevin Teske# 60ab2043b8SDevin TeskeSUCCESS=0 61ab2043b8SDevin TeskeFAILURE=1 62ab2043b8SDevin Teske 6356961fd7SDevin Teske# 6456961fd7SDevin Teske# Operating environment details 6556961fd7SDevin Teske# 6656961fd7SDevin Teskeexport UNAME_S="$( uname -s )" # Operating System (i.e. FreeBSD) 6756961fd7SDevin Teskeexport UNAME_P="$( uname -p )" # Processor Architecture (i.e. i386) 68632d9a08SDevin Teskeexport UNAME_M="$( uname -m )" # Machine platform (i.e. i386) 6956961fd7SDevin Teskeexport UNAME_R="$( uname -r )" # Release Level (i.e. X.Y-RELEASE) 7056961fd7SDevin Teske 71e14ddd1fSDevin Teske# 72e14ddd1fSDevin Teske# Default behavior is to call f_debug_init() automatically when loaded. 73e14ddd1fSDevin Teske# 74e14ddd1fSDevin Teske: ${DEBUG_SELF_INITIALIZE=1} 75e14ddd1fSDevin Teske 76c3755aa3SDevin Teske# 7757f3f6eeSDevin Teske# Default behavior of f_debug_init() is to truncate $debugFile (set to NULL to 7857f3f6eeSDevin Teske# disable truncating the debug file when initializing). To get child processes 7957f3f6eeSDevin Teske# to append to the same log file, export this variarable (with a NULL value) 8057f3f6eeSDevin Teske# and also export debugFile with the desired value. 8157f3f6eeSDevin Teske# 8257f3f6eeSDevin Teske: ${DEBUG_INITIALIZE_FILE=1} 8357f3f6eeSDevin Teske 8457f3f6eeSDevin Teske# 85c3755aa3SDevin Teske# Define standard optstring arguments that should be supported by all programs 86c3755aa3SDevin Teske# using this include (unless DEBUG_SELF_INITIALIZE is set to NULL to prevent 87c3755aa3SDevin Teske# f_debug_init() from autamatically processing "$@" for the below arguments): 88c3755aa3SDevin Teske# 89c3755aa3SDevin Teske# d Sets $debug to 1 90c3755aa3SDevin Teske# D: Sets $debugFile to $OPTARG 91c3755aa3SDevin Teske# 92c3755aa3SDevin TeskeGETOPTS_STDARGS="dD:" 93c3755aa3SDevin Teske 945b4765c3SDevin Teske# 955b4765c3SDevin Teske# The getopts builtin will return 1 either when the end of "$@" or the first 965b4765c3SDevin Teske# invalid flag is reached. This makes it impossible to determine if you've 975b4765c3SDevin Teske# processed all the arguments or simply have hit an invalid flag. In the cases 985b4765c3SDevin Teske# where we want to tolerate invalid flags (f_debug_init() for example), the 995b4765c3SDevin Teske# following variable can be appended to your optstring argument to getopts, 1005b4765c3SDevin Teske# preventing it from prematurely returning 1 before the end of the arguments. 1015b4765c3SDevin Teske# 1025b4765c3SDevin Teske# NOTE: This assumes that all unknown flags are argument-less. 1035b4765c3SDevin Teske# 1045b4765c3SDevin TeskeGETOPTS_ALLFLAGS="abcdefghijklmnopqrstuvwxyz" 1055b4765c3SDevin TeskeGETOPTS_ALLFLAGS="${GETOPTS_ALLFLAGS}ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1065b4765c3SDevin TeskeGETOPTS_ALLFLAGS="${GETOPTS_ALLFLAGS}0123456789" 1075b4765c3SDevin Teske 1085b4765c3SDevin Teske# 1095b4765c3SDevin Teske# When we get included, f_debug_init() will fire (unless $DEBUG_SELF_INITIALIZE 1105b4765c3SDevin Teske# is set to disable automatic initialization) and process "$@" for a few global 1115b4765c3SDevin Teske# options such as `-d' and/or `-D file'. However, if your program takes custom 1125b4765c3SDevin Teske# flags that take arguments, this automatic processing may fail unexpectedly. 1135b4765c3SDevin Teske# 1145b4765c3SDevin Teske# The solution to this problem is to pre-define (before including this file) 1155b4765c3SDevin Teske# the following variable (which defaults to NULL) to indicate that there are 1165b4765c3SDevin Teske# extra flags that should be considered when performing automatic processing of 1175b4765c3SDevin Teske# globally persistent flags. 1185b4765c3SDevin Teske# 1195b4765c3SDevin Teske: ${GETOPTS_EXTRA:=} 1205b4765c3SDevin Teske 121ab2043b8SDevin Teske############################################################ FUNCTIONS 122ab2043b8SDevin Teske 1233e8cb79dSDevin Teske# f_dprintf $format [$arguments ...] 124ab2043b8SDevin Teske# 12556961fd7SDevin Teske# Sensible debug function. Override in ~/.bsdconfigrc if desired. 12656961fd7SDevin Teske# See /usr/share/examples/bsdconfig/bsdconfigrc for example. 127ab2043b8SDevin Teske# 128450f13a4SDevin Teske# If $debug is set and non-NULL, prints DEBUG info using printf(1) syntax: 129450f13a4SDevin Teske# + To $debugFile, if set and non-NULL 130450f13a4SDevin Teske# + To standard output if $debugFile is either NULL or unset 131450f13a4SDevin Teske# + To both if $debugFile begins with a single plus-sign (`+') 132450f13a4SDevin Teske# 133ab2043b8SDevin Teskef_dprintf() 134ab2043b8SDevin Teske{ 13556961fd7SDevin Teske [ "$debug" ] || return $SUCCESS 13656961fd7SDevin Teske local fmt="$1"; shift 1379c83db2dSDevin Teske case "$debugFile" in ""|+*) 13856961fd7SDevin Teske printf "DEBUG: $fmt${fmt:+\n}" "$@" >&${TERMINAL_STDOUT_PASSTHRU:-1} 1399c83db2dSDevin Teske esac 1409c83db2dSDevin Teske [ "${debugFile#+}" ] && 1419c83db2dSDevin Teske printf "DEBUG: $fmt${fmt:+\n}" "$@" >> "${debugFile#+}" 1429c83db2dSDevin Teske return $SUCCESS 143ab2043b8SDevin Teske} 144ab2043b8SDevin Teske 145e14ddd1fSDevin Teske# f_debug_init 146e14ddd1fSDevin Teske# 147e14ddd1fSDevin Teske# Initialize debugging. Truncates $debugFile to zero bytes if set. 148e14ddd1fSDevin Teske# 149e14ddd1fSDevin Teskef_debug_init() 150e14ddd1fSDevin Teske{ 151e14ddd1fSDevin Teske # 152e14ddd1fSDevin Teske # Process stored command-line arguments 153e14ddd1fSDevin Teske # 1548c944ff5SDevin Teske set -- $ARGV 1559ecd54f2SDevin Teske local OPTIND OPTARG flag 156c3755aa3SDevin Teske f_dprintf "f_debug_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \ 157c3755aa3SDevin Teske "$ARGV" "$GETOPTS_STDARGS" 1585b4765c3SDevin Teske while getopts "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" flag \ 1595b4765c3SDevin Teske > /dev/null; do 160e14ddd1fSDevin Teske case "$flag" in 1618c944ff5SDevin Teske d) debug=1 ;; 1628c944ff5SDevin Teske D) debugFile="$OPTARG" ;; 163e14ddd1fSDevin Teske esac 164e14ddd1fSDevin Teske done 1658c944ff5SDevin Teske shift $(( $OPTIND - 1 )) 166c3755aa3SDevin Teske f_dprintf "f_debug_init: debug=[%s] debugFile=[%s]" \ 167c3755aa3SDevin Teske "$debug" "$debugFile" 1688c944ff5SDevin Teske 1698c944ff5SDevin Teske # 1708c944ff5SDevin Teske # Automagically enable debugging if debugFile is set (and non-NULL) 1718c944ff5SDevin Teske # 1728c944ff5SDevin Teske [ "$debugFile" ] && { [ "${debug+set}" ] || debug=1; } 173e14ddd1fSDevin Teske 174e14ddd1fSDevin Teske # 175ec65e4f8SPedro F. Giffuni # Make debugging persistent if set 176e14ddd1fSDevin Teske # 177e14ddd1fSDevin Teske [ "$debug" ] && export debug 178dcfa0eb3SDevin Teske [ "$debugFile" ] && export debugFile 179e14ddd1fSDevin Teske 180e14ddd1fSDevin Teske # 18157f3f6eeSDevin Teske # Truncate debug file unless requested otherwise. Note that we will 18257f3f6eeSDevin Teske # trim a leading plus (`+') from the value of debugFile to support 183ec65e4f8SPedro F. Giffuni # persistent meaning that f_dprintf() should print both to standard 18457f3f6eeSDevin Teske # output and $debugFile (minus the leading plus, of course). 185e14ddd1fSDevin Teske # 186e14ddd1fSDevin Teske local _debug_file="${debugFile#+}" 18757f3f6eeSDevin Teske if [ "$_debug_file" -a "$DEBUG_INITIALIZE_FILE" ]; then 188e14ddd1fSDevin Teske if ( umask 022 && :> "$_debug_file" ); then 189e14ddd1fSDevin Teske f_dprintf "Successfully initialized debugFile \`%s'" \ 190e14ddd1fSDevin Teske "$_debug_file" 1913e8cb79dSDevin Teske f_isset debug || debug=1 # turn debugging on if not set 192e14ddd1fSDevin Teske else 193e14ddd1fSDevin Teske unset debugFile 194e14ddd1fSDevin Teske f_dprintf "Unable to initialize debugFile \`%s'" \ 195e14ddd1fSDevin Teske "$_debug_file" 196e14ddd1fSDevin Teske fi 197e14ddd1fSDevin Teske fi 198e14ddd1fSDevin Teske} 199e14ddd1fSDevin Teske 2003e8cb79dSDevin Teske# f_err $format [$arguments ...] 201ab2043b8SDevin Teske# 202ab2043b8SDevin Teske# Print a message to stderr (fd=2). 203ab2043b8SDevin Teske# 204ab2043b8SDevin Teskef_err() 205ab2043b8SDevin Teske{ 206d4ae33f0SDevin Teske printf "$@" >&2 207ab2043b8SDevin Teske} 208ab2043b8SDevin Teske 209ab2043b8SDevin Teske# f_quietly $command [$arguments ...] 210ab2043b8SDevin Teske# 2112d49f165SDevin Teske# Run a command quietly (quell any output to stdout or stderr) 212ab2043b8SDevin Teske# 213ab2043b8SDevin Teskef_quietly() 214ab2043b8SDevin Teske{ 215fb7d723eSDevin Teske "$@" > /dev/null 2>&1 216ab2043b8SDevin Teske} 217ab2043b8SDevin Teske 218ab2043b8SDevin Teske# f_have $anything ... 219ab2043b8SDevin Teske# 220ab2043b8SDevin Teske# A wrapper to the `type' built-in. Returns true if argument is a valid shell 221ab2043b8SDevin Teske# built-in, keyword, or externally-tracked binary, otherwise false. 222ab2043b8SDevin Teske# 223ab2043b8SDevin Teskef_have() 224ab2043b8SDevin Teske{ 225ab2043b8SDevin Teske f_quietly type "$@" 226ab2043b8SDevin Teske} 227ab2043b8SDevin Teske 2284d5a468dSDevin Teske# setvar $var_to_set [$value] 2294d5a468dSDevin Teske# 2307729d5e3SDevin Teske# Implement setvar for shells unlike FreeBSD sh(1). 2314d5a468dSDevin Teske# 2324d5a468dSDevin Teskeif ! f_have setvar; then 2334d5a468dSDevin Teskesetvar() 2344d5a468dSDevin Teske{ 2354d5a468dSDevin Teske [ $# -gt 0 ] || return $SUCCESS 2364d5a468dSDevin Teske local __setvar_var_to_set="$1" __setvar_right="$2" __setvar_left= 2374d5a468dSDevin Teske case $# in 2384d5a468dSDevin Teske 1) unset "$__setvar_var_to_set" 2394d5a468dSDevin Teske return $? ;; 2404d5a468dSDevin Teske 2) : fall through ;; 2414d5a468dSDevin Teske *) f_err "setvar: too many arguments\n" 2424d5a468dSDevin Teske return $FAILURE 2434d5a468dSDevin Teske esac 2447729d5e3SDevin Teske case "$__setvar_var_to_set" in *[!0-9A-Za-z_]*) 2457729d5e3SDevin Teske f_err "setvar: %s: bad variable name\n" "$__setvar_var_to_set" 2467729d5e3SDevin Teske return 2 2477729d5e3SDevin Teske esac 2484d5a468dSDevin Teske while case "$__setvar_r" in *\'*) : ;; *) false ; esac 2494d5a468dSDevin Teske do 2504d5a468dSDevin Teske __setvar_left="$__setvar_left${__setvar_right%%\'*}'\\''" 2514d5a468dSDevin Teske __setvar_right="${__setvar_right#*\'}" 2524d5a468dSDevin Teske done 2534d5a468dSDevin Teske __setvar_left="$__setvar_left${__setvar_right#*\'}" 2544d5a468dSDevin Teske eval "$__setvar_var_to_set='$__setvar_left'" 2554d5a468dSDevin Teske} 2564d5a468dSDevin Teskefi 2574d5a468dSDevin Teske 258c0adcdb9SDevin Teske# f_which $anything [$var_to_set] 259c0adcdb9SDevin Teske# 260c0adcdb9SDevin Teske# A fast built-in replacement for syntaxes such as foo=$( which bar ). In a 261c0adcdb9SDevin Teske# comparison of 10,000 runs of this function versus which, this function 262c0adcdb9SDevin Teske# completed in under 3 seconds, while `which' took almost a full minute. 263c0adcdb9SDevin Teske# 264c0adcdb9SDevin Teske# If $var_to_set is missing or NULL, output is (like which) to standard out. 265c0adcdb9SDevin Teske# Returns success if a match was found, failure otherwise. 266c0adcdb9SDevin Teske# 267c0adcdb9SDevin Teskef_which() 268c0adcdb9SDevin Teske{ 269c0adcdb9SDevin Teske local __name="$1" __var_to_set="$2" 270c0adcdb9SDevin Teske case "$__name" in */*|'') return $FAILURE; esac 27136fb8bfcSDevin Teske local __p __exec IFS=":" __found= 272c0adcdb9SDevin Teske for __p in $PATH; do 27336fb8bfcSDevin Teske __exec="$__p/$__name" 27436fb8bfcSDevin Teske [ -f "$__exec" -a -x "$__exec" ] && __found=1 break 275c0adcdb9SDevin Teske done 276c0adcdb9SDevin Teske if [ "$__found" ]; then 277c0adcdb9SDevin Teske if [ "$__var_to_set" ]; then 278c0adcdb9SDevin Teske setvar "$__var_to_set" "$__exec" 279c0adcdb9SDevin Teske else 280c0adcdb9SDevin Teske echo "$__exec" 281c0adcdb9SDevin Teske fi 282c0adcdb9SDevin Teske return $SUCCESS 283c0adcdb9SDevin Teske fi 284c0adcdb9SDevin Teske return $FAILURE 285c0adcdb9SDevin Teske} 286c0adcdb9SDevin Teske 28799bc932eSDevin Teske# f_getvar $var_to_get [$var_to_set] 28899bc932eSDevin Teske# 28999bc932eSDevin Teske# Utility function designed to go along with the already-builtin setvar. 29099bc932eSDevin Teske# Allows clean variable name indirection without forking or sub-shells. 29199bc932eSDevin Teske# 29299bc932eSDevin Teske# Returns error status if the requested variable ($var_to_get) is not set. 29399bc932eSDevin Teske# 29499bc932eSDevin Teske# If $var_to_set is missing or NULL, the value of $var_to_get is printed to 29599bc932eSDevin Teske# standard output for capturing in a sub-shell (which is less-recommended 29699bc932eSDevin Teske# because of performance degredation; for example, when called in a loop). 29799bc932eSDevin Teske# 29899bc932eSDevin Teskef_getvar() 29999bc932eSDevin Teske{ 3007323adacSDevin Teske local __var_to_get="$1" __var_to_set="$2" 3017323adacSDevin Teske [ "$__var_to_set" ] || local value 3027323adacSDevin Teske eval [ \"\${$__var_to_get+set}\" ] 3037323adacSDevin Teske local __retval=$? 3042a267449SDevin Teske eval ${__var_to_set:-value}=\"\${$__var_to_get}\" 30599bc932eSDevin Teske eval f_dprintf '"f_getvar: var=[%s] value=[%s] r=%u"' \ 3067323adacSDevin Teske \"\$__var_to_get\" \"\$${__var_to_set:-value}\" \$__retval 3077323adacSDevin Teske [ "$__var_to_set" ] || { [ "$value" ] && echo "$value"; } 3087323adacSDevin Teske return $__retval 30999bc932eSDevin Teske} 31099bc932eSDevin Teske 3111d17434bSDevin Teske# f_isset $var 3121d17434bSDevin Teske# 3131d17434bSDevin Teske# Check if variable $var is set. Returns success if variable is set, otherwise 3141d17434bSDevin Teske# returns failure. 3151d17434bSDevin Teske# 3161d17434bSDevin Teskef_isset() 3171d17434bSDevin Teske{ 3181d17434bSDevin Teske eval [ \"\${${1%%[$IFS]*}+set}\" ] 3191d17434bSDevin Teske} 3201d17434bSDevin Teske 3213e8cb79dSDevin Teske# f_die [$status [$format [$arguments ...]]] 322ab2043b8SDevin Teske# 323ab2043b8SDevin Teske# Abruptly terminate due to an error optionally displaying a message in a 324ab2043b8SDevin Teske# dialog box using printf(1) syntax. 325ab2043b8SDevin Teske# 326ab2043b8SDevin Teskef_die() 327ab2043b8SDevin Teske{ 328ab2043b8SDevin Teske local status=$FAILURE 329ab2043b8SDevin Teske 330ab2043b8SDevin Teske # If there is at least one argument, take it as the status 331ab2043b8SDevin Teske if [ $# -gt 0 ]; then 332ab2043b8SDevin Teske status=$1 333ab2043b8SDevin Teske shift 1 # status 334ab2043b8SDevin Teske fi 335ab2043b8SDevin Teske 336ab2043b8SDevin Teske # If there are still arguments left, pass them to f_show_msg 337ab2043b8SDevin Teske [ $# -gt 0 ] && f_show_msg "$@" 338ab2043b8SDevin Teske 339ab2043b8SDevin Teske # Optionally call f_clean_up() function if it exists 340ab2043b8SDevin Teske f_have f_clean_up && f_clean_up 341ab2043b8SDevin Teske 342ab2043b8SDevin Teske exit $status 343ab2043b8SDevin Teske} 344ab2043b8SDevin Teske 345ab2043b8SDevin Teske# f_interrupt 346ab2043b8SDevin Teske# 347ab2043b8SDevin Teske# Interrupt handler. 348ab2043b8SDevin Teske# 349ab2043b8SDevin Teskef_interrupt() 350ab2043b8SDevin Teske{ 351ab2043b8SDevin Teske exec 2>&1 # fix sh(1) bug where stderr gets lost within async-trap 352ab2043b8SDevin Teske f_die 353ab2043b8SDevin Teske} 354ab2043b8SDevin Teske 3553e8cb79dSDevin Teske# f_show_info $format [$arguments ...] 35613aadd84SDevin Teske# 35713aadd84SDevin Teske# Display a message in a dialog infobox using printf(1) syntax. 35813aadd84SDevin Teske# 35913aadd84SDevin Teskef_show_info() 36013aadd84SDevin Teske{ 36113aadd84SDevin Teske local msg 36213aadd84SDevin Teske msg=$( printf "$@" ) 36313aadd84SDevin Teske 36413aadd84SDevin Teske # 36513aadd84SDevin Teske # Use f_dialog_infobox from dialog.subr if possible, otherwise fall 36613aadd84SDevin Teske # back to dialog(1) (without options, making it obvious when using 36713aadd84SDevin Teske # un-aided system dialog). 36813aadd84SDevin Teske # 36913aadd84SDevin Teske if f_have f_dialog_info; then 37013aadd84SDevin Teske f_dialog_info "$msg" 37113aadd84SDevin Teske else 372*c36b3dbcSAlfonso S. Siciliano bsddialog --infobox "$msg" 0 0 37313aadd84SDevin Teske fi 37413aadd84SDevin Teske} 37513aadd84SDevin Teske 3763e8cb79dSDevin Teske# f_show_msg $format [$arguments ...] 377ab2043b8SDevin Teske# 378ab2043b8SDevin Teske# Display a message in a dialog box using printf(1) syntax. 379ab2043b8SDevin Teske# 380ab2043b8SDevin Teskef_show_msg() 381ab2043b8SDevin Teske{ 382ab2043b8SDevin Teske local msg 383ab2043b8SDevin Teske msg=$( printf "$@" ) 384ab2043b8SDevin Teske 385ab2043b8SDevin Teske # 386ab2043b8SDevin Teske # Use f_dialog_msgbox from dialog.subr if possible, otherwise fall 387ab2043b8SDevin Teske # back to dialog(1) (without options, making it obvious when using 388ab2043b8SDevin Teske # un-aided system dialog). 389ab2043b8SDevin Teske # 390ab2043b8SDevin Teske if f_have f_dialog_msgbox; then 391ab2043b8SDevin Teske f_dialog_msgbox "$msg" 392ab2043b8SDevin Teske else 393*c36b3dbcSAlfonso S. Siciliano bsddialog --msgbox "$msg" 0 0 394ab2043b8SDevin Teske fi 395ab2043b8SDevin Teske} 396ab2043b8SDevin Teske 3978a316c00SDevin Teske# f_show_err $format [$arguments ...] 3988a316c00SDevin Teske# 3998a316c00SDevin Teske# Display a message in a dialog box with ``Error'' i18n title (overridden by 40067602532SDevin Teske# setting msg_error) using printf(1) syntax. 4018a316c00SDevin Teske# 4028a316c00SDevin Teskef_show_err() 4038a316c00SDevin Teske{ 4048a316c00SDevin Teske local msg 4058a316c00SDevin Teske msg=$( printf "$@" ) 4068a316c00SDevin Teske 4078a316c00SDevin Teske : ${msg:=${msg_an_unknown_error_occurred:-An unknown error occurred}} 4088a316c00SDevin Teske 4098a316c00SDevin Teske if [ "$_DIALOG_SUBR" ]; then 4108a316c00SDevin Teske f_dialog_title "${msg_error:-Error}" 4118a316c00SDevin Teske f_dialog_msgbox "$msg" 4128a316c00SDevin Teske f_dialog_title_restore 4138a316c00SDevin Teske else 4148a316c00SDevin Teske dialog --title "${msg_error:-Error}" --msgbox "$msg" 0 0 4158a316c00SDevin Teske fi 4168a316c00SDevin Teske return $SUCCESS 4178a316c00SDevin Teske} 41827ff90aaSDevin Teske 4193e8cb79dSDevin Teske# f_yesno $format [$arguments ...] 42027ff90aaSDevin Teske# 42127ff90aaSDevin Teske# Display a message in a dialog yes/no box using printf(1) syntax. 42227ff90aaSDevin Teske# 42327ff90aaSDevin Teskef_yesno() 42427ff90aaSDevin Teske{ 42527ff90aaSDevin Teske local msg 42627ff90aaSDevin Teske msg=$( printf "$@" ) 42727ff90aaSDevin Teske 42827ff90aaSDevin Teske # 42927ff90aaSDevin Teske # Use f_dialog_yesno from dialog.subr if possible, otherwise fall 43027ff90aaSDevin Teske # back to dialog(1) (without options, making it obvious when using 43127ff90aaSDevin Teske # un-aided system dialog). 43227ff90aaSDevin Teske # 43327ff90aaSDevin Teske if f_have f_dialog_yesno; then 43427ff90aaSDevin Teske f_dialog_yesno "$msg" 43527ff90aaSDevin Teske else 436*c36b3dbcSAlfonso S. Siciliano bsddialog --yesno "$msg" 0 0 43727ff90aaSDevin Teske fi 43827ff90aaSDevin Teske} 43927ff90aaSDevin Teske 4403e8cb79dSDevin Teske# f_noyes $format [$arguments ...] 44127ff90aaSDevin Teske# 44227ff90aaSDevin Teske# Display a message in a dialog yes/no box using printf(1) syntax. 44327ff90aaSDevin Teske# NOTE: THis is just like the f_yesno function except "No" is default. 44427ff90aaSDevin Teske# 44527ff90aaSDevin Teskef_noyes() 44627ff90aaSDevin Teske{ 44727ff90aaSDevin Teske local msg 44827ff90aaSDevin Teske msg=$( printf "$@" ) 44927ff90aaSDevin Teske 45027ff90aaSDevin Teske # 45127ff90aaSDevin Teske # Use f_dialog_noyes from dialog.subr if possible, otherwise fall 45227ff90aaSDevin Teske # back to dialog(1) (without options, making it obvious when using 45327ff90aaSDevin Teske # un-aided system dialog). 45427ff90aaSDevin Teske # 45527ff90aaSDevin Teske if f_have f_dialog_noyes; then 45627ff90aaSDevin Teske f_dialog_noyes "$msg" 45727ff90aaSDevin Teske else 458*c36b3dbcSAlfonso S. Siciliano bsddialog --defaultno --yesno "$msg" 0 0 45927ff90aaSDevin Teske fi 46027ff90aaSDevin Teske} 46127ff90aaSDevin Teske 46240dfc82dSDevin Teske# f_show_help $file 46340dfc82dSDevin Teske# 46440dfc82dSDevin Teske# Display a language help-file. Automatically takes $LANG and $LC_ALL into 46540dfc82dSDevin Teske# consideration when displaying $file (suffix ".$LC_ALL" or ".$LANG" will 46640dfc82dSDevin Teske# automatically be added prior to loading the language help-file). 46740dfc82dSDevin Teske# 46840dfc82dSDevin Teske# If a language has been requested by setting either $LANG or $LC_ALL in the 46940dfc82dSDevin Teske# environment and the language-specific help-file does not exist we will fall 47040dfc82dSDevin Teske# back to $file without-suffix. 47140dfc82dSDevin Teske# 47240dfc82dSDevin Teske# If the language help-file does not exist, an error is displayed instead. 47340dfc82dSDevin Teske# 47440dfc82dSDevin Teskef_show_help() 47540dfc82dSDevin Teske{ 47640dfc82dSDevin Teske local file="$1" 47740dfc82dSDevin Teske local lang="${LANG:-$LC_ALL}" 47840dfc82dSDevin Teske 47940dfc82dSDevin Teske [ -f "$file.$lang" ] && file="$file.$lang" 48040dfc82dSDevin Teske 48140dfc82dSDevin Teske # 48240dfc82dSDevin Teske # Use f_dialog_textbox from dialog.subr if possible, otherwise fall 48340dfc82dSDevin Teske # back to dialog(1) (without options, making it obvious when using 48440dfc82dSDevin Teske # un-aided system dialog). 48540dfc82dSDevin Teske # 48640dfc82dSDevin Teske if f_have f_dialog_textbox; then 48740dfc82dSDevin Teske f_dialog_textbox "$file" 48840dfc82dSDevin Teske else 489*c36b3dbcSAlfonso S. Siciliano bsddialog --msgbox "$( cat "$file" 2>&1 )" 0 0 49040dfc82dSDevin Teske fi 49140dfc82dSDevin Teske} 49240dfc82dSDevin Teske 493ab2043b8SDevin Teske# f_include $file 494ab2043b8SDevin Teske# 495ab2043b8SDevin Teske# Include a shell subroutine file. 496ab2043b8SDevin Teske# 497ab2043b8SDevin Teske# If the subroutine file exists but returns error status during loading, exit 498ab2043b8SDevin Teske# is called and execution is prematurely terminated with the same error status. 499ab2043b8SDevin Teske# 500ab2043b8SDevin Teskef_include() 501ab2043b8SDevin Teske{ 502ab2043b8SDevin Teske local file="$1" 503526e1dc1SDevin Teske f_dprintf "f_include: file=[%s]" "$file" 504ab2043b8SDevin Teske . "$file" || exit $? 505ab2043b8SDevin Teske} 506ab2043b8SDevin Teske 507ab2043b8SDevin Teske# f_include_lang $file 508ab2043b8SDevin Teske# 509ab2043b8SDevin Teske# Include a language file. Automatically takes $LANG and $LC_ALL into 5107f72bb44SDevin Teske# consideration when including $file (suffix ".$LC_ALL" or ".$LANG" will 511ab2043b8SDevin Teske# automatically by added prior to loading the language file). 512ab2043b8SDevin Teske# 513ab2043b8SDevin Teske# No error is produced if (a) a language has been requested (by setting either 514ab2043b8SDevin Teske# $LANG or $LC_ALL in the environment) and (b) the language file does not 515ab2043b8SDevin Teske# exist -- in which case we will fall back to loading $file without-suffix. 516ab2043b8SDevin Teske# 517ab2043b8SDevin Teske# If the language file exists but returns error status during loading, exit 518ab2043b8SDevin Teske# is called and execution is prematurely terminated with the same error status. 519ab2043b8SDevin Teske# 520ab2043b8SDevin Teskef_include_lang() 521ab2043b8SDevin Teske{ 522ab2043b8SDevin Teske local file="$1" 523ab2043b8SDevin Teske local lang="${LANG:-$LC_ALL}" 524ab2043b8SDevin Teske 525526e1dc1SDevin Teske f_dprintf "f_include_lang: file=[%s] lang=[%s]" "$file" "$lang" 526ab2043b8SDevin Teske if [ -f "$file.$lang" ]; then 527ab2043b8SDevin Teske . "$file.$lang" || exit $? 528ab2043b8SDevin Teske else 529ab2043b8SDevin Teske . "$file" || exit $? 530ab2043b8SDevin Teske fi 531ab2043b8SDevin Teske} 532ab2043b8SDevin Teske 533ab2043b8SDevin Teske# f_usage $file [$key1 $value1 ...] 534ab2043b8SDevin Teske# 535ab2043b8SDevin Teske# Display USAGE file with optional pre-processor macro definitions. The first 536ab2043b8SDevin Teske# argument is the template file containing the usage text to be displayed. If 537ab2043b8SDevin Teske# $LANG or $LC_ALL (in order of preference, respectively) is set, ".encoding" 538ab2043b8SDevin Teske# will automatically be appended as a suffix to the provided $file pathname. 539ab2043b8SDevin Teske# 540ab2043b8SDevin Teske# When processing $file, output begins at the first line containing that is 541ab2043b8SDevin Teske# (a) not a comment, (b) not empty, and (c) is not pure-whitespace. All lines 542ab2043b8SDevin Teske# appearing after this first-line are output, including (a) comments (b) empty 543ab2043b8SDevin Teske# lines, and (c) lines that are purely whitespace-only. 544ab2043b8SDevin Teske# 545ab2043b8SDevin Teske# If additional arguments appear after $file, substitutions are made while 546ab2043b8SDevin Teske# printing the contents of the USAGE file. The pre-processor macro syntax is in 547ab2043b8SDevin Teske# the style of autoconf(1), for example: 548ab2043b8SDevin Teske# 549ab2043b8SDevin Teske# f_usage $file "FOO" "BAR" 550ab2043b8SDevin Teske# 551ab2043b8SDevin Teske# Will cause instances of "@FOO@" appearing in $file to be replaced with the 5529680f649SDevin Teske# text "BAR" before being printed to the screen. 553ab2043b8SDevin Teske# 554ab2043b8SDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 555ab2043b8SDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 556ab2043b8SDevin Teske# 557ab2043b8SDevin Teskef_usage_awk=' 558ab2043b8SDevin TeskeBEGIN { found = 0 } 559ab2043b8SDevin Teske{ 560ab2043b8SDevin Teske if ( !found && $0 ~ /^[[:space:]]*($|#)/ ) next 561ab2043b8SDevin Teske found = 1 562ab2043b8SDevin Teske print 563ab2043b8SDevin Teske} 564ab2043b8SDevin Teske' 565ab2043b8SDevin Teskef_usage() 566ab2043b8SDevin Teske{ 567ab2043b8SDevin Teske local file="$1" 568ab2043b8SDevin Teske local lang="${LANG:-$LC_ALL}" 569ab2043b8SDevin Teske 570526e1dc1SDevin Teske f_dprintf "f_usage: file=[%s] lang=[%s]" "$file" "$lang" 571ab2043b8SDevin Teske 572ab2043b8SDevin Teske shift 1 # file 573ab2043b8SDevin Teske 574ab2043b8SDevin Teske local usage 575ab2043b8SDevin Teske if [ -f "$file.$lang" ]; then 576ab2043b8SDevin Teske usage=$( awk "$f_usage_awk" "$file.$lang" ) || exit $FAILURE 577ab2043b8SDevin Teske else 578ab2043b8SDevin Teske usage=$( awk "$f_usage_awk" "$file" ) || exit $FAILURE 579ab2043b8SDevin Teske fi 580ab2043b8SDevin Teske 581ab2043b8SDevin Teske while [ $# -gt 0 ]; do 582ab2043b8SDevin Teske local key="$1" 583ab2043b8SDevin Teske export value="$2" 584ab2043b8SDevin Teske usage=$( echo "$usage" | awk \ 585ab2043b8SDevin Teske "{ gsub(/@$key@/, ENVIRON[\"value\"]); print }" ) 586ab2043b8SDevin Teske shift 2 587ab2043b8SDevin Teske done 588ab2043b8SDevin Teske 589ab2043b8SDevin Teske f_err "%s\n" "$usage" 590ab2043b8SDevin Teske 591ab2043b8SDevin Teske exit $FAILURE 592ab2043b8SDevin Teske} 593ab2043b8SDevin Teske 594d4ae33f0SDevin Teske# f_index_file $keyword [$var_to_set] 595ab2043b8SDevin Teske# 59648c5129fSDevin Teske# Process all INDEX files known to bsdconfig and return the path to first file 59748c5129fSDevin Teske# containing a menu_selection line with a keyword portion matching $keyword. 598ab2043b8SDevin Teske# 59948c5129fSDevin Teske# If $LANG or $LC_ALL (in order of preference, respectively) is set, 60048c5129fSDevin Teske# "INDEX.encoding" files will be searched first. 601ab2043b8SDevin Teske# 60248c5129fSDevin Teske# If no file is found, error status is returned along with the NULL string. 603ab2043b8SDevin Teske# 604d4ae33f0SDevin Teske# If $var_to_set is NULL or missing, output is printed to stdout (which is less 605d4ae33f0SDevin Teske# recommended due to performance degradation; in a loop for example). 606d4ae33f0SDevin Teske# 607ab2043b8SDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 608ab2043b8SDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 609ab2043b8SDevin Teske# 61048c5129fSDevin Teskef_index_file_awk=' 611ab2043b8SDevin Teske# Variables that should be defined on the invocation line: 61248c5129fSDevin Teske# -v keyword="keyword" 61348c5129fSDevin TeskeBEGIN { found = 0 } 61448c5129fSDevin Teske( $0 ~ "^menu_selection=\"" keyword "\\|" ) { 61548c5129fSDevin Teske print FILENAME 61648c5129fSDevin Teske found++ 617ab2043b8SDevin Teske exit 618ab2043b8SDevin Teske} 61948c5129fSDevin TeskeEND { exit ! found } 620ab2043b8SDevin Teske' 62148c5129fSDevin Teskef_index_file() 622ab2043b8SDevin Teske{ 623d4ae33f0SDevin Teske local __keyword="$1" __var_to_set="$2" 624d4ae33f0SDevin Teske local __lang="${LANG:-$LC_ALL}" 625d4ae33f0SDevin Teske local __indexes="$BSDCFG_LIBE${BSDCFG_LIBE:+/}*/INDEX" 626ab2043b8SDevin Teske 627d4ae33f0SDevin Teske f_dprintf "f_index_file: keyword=[%s] lang=[%s]" "$__keyword" "$__lang" 628ab2043b8SDevin Teske 629d4ae33f0SDevin Teske if [ "$__lang" ]; then 630d4ae33f0SDevin Teske if [ "$__var_to_set" ]; then 631d4ae33f0SDevin Teske eval "$__var_to_set"='"$( awk -v keyword="$__keyword" \ 632d4ae33f0SDevin Teske "$f_index_file_awk" $__indexes.$__lang 633d4ae33f0SDevin Teske )"' && return $SUCCESS 634d4ae33f0SDevin Teske else 635d4ae33f0SDevin Teske awk -v keyword="$__keyword" "$f_index_file_awk" \ 636d4ae33f0SDevin Teske $__indexes.$__lang && return $SUCCESS 637d4ae33f0SDevin Teske fi 63848c5129fSDevin Teske # No match, fall-thru to non-i18n sources 63948c5129fSDevin Teske fi 640d4ae33f0SDevin Teske if [ "$__var_to_set" ]; then 641d4ae33f0SDevin Teske eval "$__var_to_set"='"$( awk -v keyword="$__keyword" \ 642d4ae33f0SDevin Teske "$f_index_file_awk" $__indexes )"' && return $SUCCESS 643d4ae33f0SDevin Teske else 644d4ae33f0SDevin Teske awk -v keyword="$__keyword" "$f_index_file_awk" $__indexes && 645d4ae33f0SDevin Teske return $SUCCESS 646d4ae33f0SDevin Teske fi 6471da51566SDevin Teske 6481da51566SDevin Teske # No match? Fall-thru to `local' libexec sources (add-on modules) 6491da51566SDevin Teske 6501da51566SDevin Teske [ "$BSDCFG_LOCAL_LIBE" ] || return $FAILURE 651d4ae33f0SDevin Teske __indexes="$BSDCFG_LOCAL_LIBE/*/INDEX" 652d4ae33f0SDevin Teske if [ "$__lang" ]; then 653d4ae33f0SDevin Teske if [ "$__var_to_set" ]; then 654d4ae33f0SDevin Teske eval "$__var_to_set"='"$( awk -v keyword="$__keyword" \ 655d4ae33f0SDevin Teske "$f_index_file_awk" $__indexes.$__lang 656d4ae33f0SDevin Teske )"' && return $SUCCESS 657d4ae33f0SDevin Teske else 658d4ae33f0SDevin Teske awk -v keyword="$__keyword" "$f_index_file_awk" \ 659d4ae33f0SDevin Teske $__indexes.$__lang && return $SUCCESS 660d4ae33f0SDevin Teske fi 6611da51566SDevin Teske # No match, fall-thru to non-i18n sources 6621da51566SDevin Teske fi 663d4ae33f0SDevin Teske if [ "$__var_to_set" ]; then 664d4ae33f0SDevin Teske eval "$__var_to_set"='$( awk -v keyword="$__keyword" \ 665d4ae33f0SDevin Teske "$f_index_file_awk" $__indexes )"' 666d4ae33f0SDevin Teske else 667d4ae33f0SDevin Teske awk -v keyword="$__keyword" "$f_index_file_awk" $__indexes 668d4ae33f0SDevin Teske fi 66948c5129fSDevin Teske} 67048c5129fSDevin Teske 671d4ae33f0SDevin Teske# f_index_menusel_keyword $indexfile $pgm [$var_to_set] 67248c5129fSDevin Teske# 67348c5129fSDevin Teske# Process $indexfile and return only the keyword portion of the menu_selection 67448c5129fSDevin Teske# line with a command portion matching $pgm. 67548c5129fSDevin Teske# 67648c5129fSDevin Teske# This function is for internationalization (i18n) mapping of the on-disk 67748c5129fSDevin Teske# scriptname ($pgm) into the localized language (given language-specific 67848c5129fSDevin Teske# $indexfile). If $LANG or $LC_ALL (in orderder of preference, respectively) is 67948c5129fSDevin Teske# set, ".encoding" will automatically be appended as a suffix to the provided 68048c5129fSDevin Teske# $indexfile pathname. 68148c5129fSDevin Teske# 68248c5129fSDevin Teske# If, within $indexfile, multiple $menu_selection values map to $pgm, only the 68348c5129fSDevin Teske# first one will be returned. If no mapping can be made, the NULL string is 68448c5129fSDevin Teske# returned. 68548c5129fSDevin Teske# 68648c5129fSDevin Teske# If $indexfile does not exist, error status is returned with NULL. 68748c5129fSDevin Teske# 688d4ae33f0SDevin Teske# If $var_to_set is NULL or missing, output is printed to stdout (which is less 689d4ae33f0SDevin Teske# recommended due to performance degradation; in a loop for example). 690d4ae33f0SDevin Teske# 69148c5129fSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 69248c5129fSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 69348c5129fSDevin Teske# 69448c5129fSDevin Teskef_index_menusel_keyword_awk=' 69548c5129fSDevin Teske# Variables that should be defined on the invocation line: 69648c5129fSDevin Teske# -v pgm="program_name" 69748c5129fSDevin Teske# 69848c5129fSDevin TeskeBEGIN { 69948c5129fSDevin Teske prefix = "menu_selection=\"" 70048c5129fSDevin Teske plen = length(prefix) 70148c5129fSDevin Teske found = 0 70248c5129fSDevin Teske} 70348c5129fSDevin Teske{ 70448c5129fSDevin Teske if (!match($0, "^" prefix ".*\\|.*\"")) next 70548c5129fSDevin Teske 70648c5129fSDevin Teske keyword = command = substr($0, plen + 1, RLENGTH - plen - 1) 70748c5129fSDevin Teske sub(/^.*\|/, "", command) 70848c5129fSDevin Teske sub(/\|.*$/, "", keyword) 70948c5129fSDevin Teske 71048c5129fSDevin Teske if ( command == pgm ) 71148c5129fSDevin Teske { 71248c5129fSDevin Teske print keyword 71348c5129fSDevin Teske found++ 71448c5129fSDevin Teske exit 71548c5129fSDevin Teske } 71648c5129fSDevin Teske} 71748c5129fSDevin TeskeEND { exit ! found } 71848c5129fSDevin Teske' 71948c5129fSDevin Teskef_index_menusel_keyword() 72048c5129fSDevin Teske{ 721d4ae33f0SDevin Teske local __indexfile="$1" __pgm="$2" __var_to_set="$3" 722d4ae33f0SDevin Teske local __lang="${LANG:-$LC_ALL}" __file="$__indexfile" 72348c5129fSDevin Teske 724d4ae33f0SDevin Teske [ -f "$__indexfile.$__lang" ] && __file="$__indexfile.$__lang" 725526e1dc1SDevin Teske f_dprintf "f_index_menusel_keyword: index=[%s] pgm=[%s] lang=[%s]" \ 726d4ae33f0SDevin Teske "$__file" "$__pgm" "$__lang" 72748c5129fSDevin Teske 728d4ae33f0SDevin Teske if [ "$__var_to_set" ]; then 729d4ae33f0SDevin Teske setvar "$__var_to_set" "$( awk \ 730d4ae33f0SDevin Teske -v pgm="$__pgm" "$f_index_menusel_keyword_awk" "$__file" 731d4ae33f0SDevin Teske )" 732d4ae33f0SDevin Teske else 733d4ae33f0SDevin Teske awk -v pgm="$__pgm" "$f_index_menusel_keyword_awk" "$__file" 73448c5129fSDevin Teske fi 73548c5129fSDevin Teske} 73648c5129fSDevin Teske 737d4ae33f0SDevin Teske# f_index_menusel_command $indexfile $keyword [$var_to_set] 73848c5129fSDevin Teske# 73948c5129fSDevin Teske# Process $indexfile and return only the command portion of the menu_selection 74048c5129fSDevin Teske# line with a keyword portion matching $keyword. 74148c5129fSDevin Teske# 74248c5129fSDevin Teske# This function is for mapping [possibly international] keywords into the 74348c5129fSDevin Teske# command to be executed. If $LANG or $LC_ALL (order of preference) is set, 74448c5129fSDevin Teske# ".encoding" will automatically be appended as a suffix to the provided 74548c5129fSDevin Teske# $indexfile pathname. 74648c5129fSDevin Teske# 74748c5129fSDevin Teske# If, within $indexfile, multiple $menu_selection values map to $keyword, only 74848c5129fSDevin Teske# the first one will be returned. If no mapping can be made, the NULL string is 74948c5129fSDevin Teske# returned. 75048c5129fSDevin Teske# 75148c5129fSDevin Teske# If $indexfile doesn't exist, error status is returned with NULL. 75248c5129fSDevin Teske# 753d4ae33f0SDevin Teske# If $var_to_set is NULL or missing, output is printed to stdout (which is less 754d4ae33f0SDevin Teske# recommended due to performance degradation; in a loop for example). 755d4ae33f0SDevin Teske# 75648c5129fSDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function, 75748c5129fSDevin Teske# afterward is the sh(1) function which utilizes the below awk script. 75848c5129fSDevin Teske# 75948c5129fSDevin Teskef_index_menusel_command_awk=' 76048c5129fSDevin Teske# Variables that should be defined on the invocation line: 76148c5129fSDevin Teske# -v key="keyword" 76248c5129fSDevin Teske# 76348c5129fSDevin TeskeBEGIN { 76448c5129fSDevin Teske prefix = "menu_selection=\"" 76548c5129fSDevin Teske plen = length(prefix) 76648c5129fSDevin Teske found = 0 76748c5129fSDevin Teske} 76848c5129fSDevin Teske{ 76948c5129fSDevin Teske if (!match($0, "^" prefix ".*\\|.*\"")) next 77048c5129fSDevin Teske 77148c5129fSDevin Teske keyword = command = substr($0, plen + 1, RLENGTH - plen - 1) 77248c5129fSDevin Teske sub(/^.*\|/, "", command) 77348c5129fSDevin Teske sub(/\|.*$/, "", keyword) 77448c5129fSDevin Teske 77548c5129fSDevin Teske if ( keyword == key ) 77648c5129fSDevin Teske { 77748c5129fSDevin Teske print command 77848c5129fSDevin Teske found++ 77948c5129fSDevin Teske exit 78048c5129fSDevin Teske } 78148c5129fSDevin Teske} 78248c5129fSDevin TeskeEND { exit ! found } 78348c5129fSDevin Teske' 78448c5129fSDevin Teskef_index_menusel_command() 78548c5129fSDevin Teske{ 786d4ae33f0SDevin Teske local __indexfile="$1" __keyword="$2" __var_to_set="$3" __command 787d4ae33f0SDevin Teske local __lang="${LANG:-$LC_ALL}" __file="$__indexfile" 78848c5129fSDevin Teske 789d4ae33f0SDevin Teske [ -f "$__indexfile.$__lang" ] && __file="$__indexfile.$__lang" 790526e1dc1SDevin Teske f_dprintf "f_index_menusel_command: index=[%s] key=[%s] lang=[%s]" \ 791d4ae33f0SDevin Teske "$__file" "$__keyword" "$__lang" 79248c5129fSDevin Teske 793d4ae33f0SDevin Teske [ -f "$__file" ] || return $FAILURE 794d4ae33f0SDevin Teske __command=$( awk -v key="$__keyword" \ 795d4ae33f0SDevin Teske "$f_index_menusel_command_awk" "$__file" ) || return $FAILURE 79648c5129fSDevin Teske 79748c5129fSDevin Teske # 79848c5129fSDevin Teske # If the command pathname is not fully qualified fix-up/force to be 79948c5129fSDevin Teske # relative to the $indexfile directory. 80048c5129fSDevin Teske # 801d4ae33f0SDevin Teske case "$__command" in 80248c5129fSDevin Teske /*) : already fully qualified ;; 80348c5129fSDevin Teske *) 804d4ae33f0SDevin Teske local __indexdir="${__indexfile%/*}" 805d4ae33f0SDevin Teske [ "$__indexdir" != "$__indexfile" ] || __indexdir="." 806d4ae33f0SDevin Teske __command="$__indexdir/$__command" 80748c5129fSDevin Teske esac 80848c5129fSDevin Teske 809d4ae33f0SDevin Teske if [ "$__var_to_set" ]; then 810d4ae33f0SDevin Teske setvar "$__var_to_set" "$__command" 811d4ae33f0SDevin Teske else 812d4ae33f0SDevin Teske echo "$__command" 813d4ae33f0SDevin Teske fi 814ab2043b8SDevin Teske} 815ab2043b8SDevin Teske 8167323adacSDevin Teske# f_running_as_init 8177323adacSDevin Teske# 8187323adacSDevin Teske# Returns true if running as init(1). 8197323adacSDevin Teske# 8207323adacSDevin Teskef_running_as_init() 8217323adacSDevin Teske{ 8227323adacSDevin Teske # 8237323adacSDevin Teske # When a custom init(8) performs an exec(3) to invoke a shell script, 8247323adacSDevin Teske # PID 1 becomes sh(1) and $PPID is set to 1 in the executed script. 8257323adacSDevin Teske # 8267323adacSDevin Teske [ ${PPID:-0} -eq 1 ] # Return status 8277323adacSDevin Teske} 8287323adacSDevin Teske 8297323adacSDevin Teske# f_mounted $local_directory 8309ecd54f2SDevin Teske# f_mounted -b $device 8317323adacSDevin Teske# 8329ecd54f2SDevin Teske# Return success if a filesystem is mounted on a particular directory. If `-b' 8339ecd54f2SDevin Teske# is present, instead check that the block device (or a partition thereof) is 8349ecd54f2SDevin Teske# mounted. 8357323adacSDevin Teske# 8367323adacSDevin Teskef_mounted() 8377323adacSDevin Teske{ 8389ecd54f2SDevin Teske local OPTIND OPTARG flag use_device= 8399ecd54f2SDevin Teske while getopts b flag; do 8409ecd54f2SDevin Teske case "$flag" in 8419ecd54f2SDevin Teske b) use_device=1 ;; 8429ecd54f2SDevin Teske esac 8439ecd54f2SDevin Teske done 8449ecd54f2SDevin Teske shift $(( $OPTIND - 1 )) 8459ecd54f2SDevin Teske if [ "$use_device" ]; then 8469ecd54f2SDevin Teske local device="$1" 8479ecd54f2SDevin Teske mount | grep -Eq \ 8489ecd54f2SDevin Teske "^$device([[:space:]]|p[0-9]|s[0-9]|\.nop|\.eli)" 8499ecd54f2SDevin Teske else 8507323adacSDevin Teske [ -d "$dir" ] || return $FAILURE 8517323adacSDevin Teske mount | grep -Eq " on $dir \([^)]+\)$" 8529ecd54f2SDevin Teske fi 8539ecd54f2SDevin Teske # Return status is that of last grep(1) 8547323adacSDevin Teske} 8557323adacSDevin Teske 856d4ae33f0SDevin Teske# f_eval_catch [-de] [-k $var_to_set] $funcname $utility \ 857d4ae33f0SDevin Teske# $format [$arguments ...] 858bdf4b176SDevin Teske# 859bdf4b176SDevin Teske# Silently evaluate a command in a sub-shell and test for error. If debugging 860bdf4b176SDevin Teske# is enabled a copy of the command and its output is sent to debug (either 861bdf4b176SDevin Teske# stdout or file depending on environment). If an error occurs, output of the 862bdf4b176SDevin Teske# command is displayed in a dialog(1) msgbox using the [above] f_show_err() 863d4ae33f0SDevin Teske# function (unless optional `-d' flag is given, then no dialog). 864d4ae33f0SDevin Teske# 865bdf4b176SDevin Teske# The $funcname argument is sent to debugging while the $utility argument is 866d4ae33f0SDevin Teske# used in the title of the dialog box. The command that is executed as well as 867d4ae33f0SDevin Teske# sent to debugging with $funcname is the product of the printf(1) syntax 868d4ae33f0SDevin Teske# produced by $format with optional $arguments. 869d4ae33f0SDevin Teske# 870d4ae33f0SDevin Teske# The following options are supported: 871d4ae33f0SDevin Teske# 872d4ae33f0SDevin Teske# -d Do not use dialog(1). 873d4ae33f0SDevin Teske# -e Produce error text from failed command on stderr. 874d4ae33f0SDevin Teske# -k var Save output from the command in var. 875bdf4b176SDevin Teske# 876bdf4b176SDevin Teske# Example 1: 877bdf4b176SDevin Teske# 878bdf4b176SDevin Teske# debug=1 879bdf4b176SDevin Teske# f_eval_catch myfunc echo 'echo "%s"' "Hello, World!" 880bdf4b176SDevin Teske# 881bdf4b176SDevin Teske# Produces the following debug output: 882bdf4b176SDevin Teske# 883bdf4b176SDevin Teske# DEBUG: myfunc: echo "Hello, World!" 884bdf4b176SDevin Teske# DEBUG: myfunc: retval=0 <output below> 885bdf4b176SDevin Teske# Hello, World! 886bdf4b176SDevin Teske# 887d4ae33f0SDevin Teske# Example 2: 888d4ae33f0SDevin Teske# 889d4ae33f0SDevin Teske# debug=1 890d4ae33f0SDevin Teske# f_eval_catch -k contents myfunc cat 'cat "%s"' /some/file 891d4ae33f0SDevin Teske# # dialog(1) Error ``cat: /some/file: No such file or directory'' 892d4ae33f0SDevin Teske# # contents=[cat: /some/file: No such file or directory] 893d4ae33f0SDevin Teske# 894d4ae33f0SDevin Teske# Produces the following debug output: 895d4ae33f0SDevin Teske# 896d4ae33f0SDevin Teske# DEBUG: myfunc: cat "/some/file" 897d4ae33f0SDevin Teske# DEBUG: myfunc: retval=1 <output below> 898d4ae33f0SDevin Teske# cat: /some/file: No such file or directory 899d4ae33f0SDevin Teske# 900bdf4b176SDevin Teske# Example 3: 901bdf4b176SDevin Teske# 902bdf4b176SDevin Teske# debug=1 903bdf4b176SDevin Teske# echo 123 | f_eval_catch myfunc rev rev 904bdf4b176SDevin Teske# 905bdf4b176SDevin Teske# Produces the following debug output: 906bdf4b176SDevin Teske# 907bdf4b176SDevin Teske# DEBUG: myfunc: rev 908bdf4b176SDevin Teske# DEBUG: myfunc: retval=0 <output below> 909bdf4b176SDevin Teske# 321 910bdf4b176SDevin Teske# 911bdf4b176SDevin Teske# Example 4: 912bdf4b176SDevin Teske# 913bdf4b176SDevin Teske# debug=1 914bdf4b176SDevin Teske# f_eval_catch myfunc true true 915bdf4b176SDevin Teske# 916bdf4b176SDevin Teske# Produces the following debug output: 917bdf4b176SDevin Teske# 918bdf4b176SDevin Teske# DEBUG: myfunc: true 919bdf4b176SDevin Teske# DEBUG: myfunc: retval=0 <no output> 920bdf4b176SDevin Teske# 921d4ae33f0SDevin Teske# Example 5: 922d4ae33f0SDevin Teske# 923d4ae33f0SDevin Teske# f_eval_catch -de myfunc ls 'ls "%s"' /some/dir 924d4ae33f0SDevin Teske# # Output on stderr ``ls: /some/dir: No such file or directory'' 925d4ae33f0SDevin Teske# 926d4ae33f0SDevin Teske# Example 6: 927d4ae33f0SDevin Teske# 928d4ae33f0SDevin Teske# f_eval_catch -dek contents myfunc ls 'ls "%s"' /etc 929d4ae33f0SDevin Teske# # Output from `ls' sent to stderr and also saved in $contents 930d4ae33f0SDevin Teske# 931bdf4b176SDevin Teskef_eval_catch() 932bdf4b176SDevin Teske{ 933d4ae33f0SDevin Teske local __no_dialog= __show_err= __var_to_set= 934d4ae33f0SDevin Teske 935d4ae33f0SDevin Teske # 936d4ae33f0SDevin Teske # Process local function arguments 937d4ae33f0SDevin Teske # 9389ecd54f2SDevin Teske local OPTIND OPTARG __flag 939d4ae33f0SDevin Teske while getopts "dek:" __flag > /dev/null; do 940d4ae33f0SDevin Teske case "$__flag" in 941d4ae33f0SDevin Teske d) __no_dialog=1 ;; 942d4ae33f0SDevin Teske e) __show_err=1 ;; 943d4ae33f0SDevin Teske k) __var_to_set="$OPTARG" ;; 944d4ae33f0SDevin Teske esac 945d4ae33f0SDevin Teske done 946d4ae33f0SDevin Teske shift $(( $OPTIND - 1 )) 947d4ae33f0SDevin Teske 948d4ae33f0SDevin Teske local __funcname="$1" __utility="$2"; shift 2 949d4ae33f0SDevin Teske local __cmd __output __retval 950d4ae33f0SDevin Teske 951d4ae33f0SDevin Teske __cmd=$( printf -- "$@" ) 952d4ae33f0SDevin Teske f_dprintf "%s: %s" "$__funcname" "$__cmd" # Log command *before* eval 953d4ae33f0SDevin Teske __output=$( exec 2>&1; eval "$__cmd" ) 954d4ae33f0SDevin Teske __retval=$? 955d4ae33f0SDevin Teske if [ "$__output" ]; then 956d4ae33f0SDevin Teske [ "$__show_err" ] && echo "$__output" >&2 957d4ae33f0SDevin Teske f_dprintf "%s: retval=%i <output below>\n%s" "$__funcname" \ 958d4ae33f0SDevin Teske $__retval "$__output" 959bdf4b176SDevin Teske else 960d4ae33f0SDevin Teske f_dprintf "%s: retval=%i <no output>" "$__funcname" $__retval 961bdf4b176SDevin Teske fi 962d4ae33f0SDevin Teske 963d4ae33f0SDevin Teske ! [ "$__no_dialog" -o "$nonInteractive" -o $__retval -eq $SUCCESS ] && 964d4ae33f0SDevin Teske msg_error="${msg_error:-Error}${__utility:+: $__utility}" \ 965d4ae33f0SDevin Teske f_show_err "%s" "$__output" 966bdf4b176SDevin Teske # NB: f_show_err will handle NULL output appropriately 967d4ae33f0SDevin Teske 968d4ae33f0SDevin Teske [ "$__var_to_set" ] && setvar "$__var_to_set" "$__output" 969d4ae33f0SDevin Teske 970d4ae33f0SDevin Teske return $__retval 971d4ae33f0SDevin Teske} 972d4ae33f0SDevin Teske 973d4ae33f0SDevin Teske# f_count $var_to_set arguments ... 974d4ae33f0SDevin Teske# 975d4ae33f0SDevin Teske# Sets $var_to_set to the number of arguments minus one (the effective number 976d4ae33f0SDevin Teske# of arguments following $var_to_set). 977d4ae33f0SDevin Teske# 978d4ae33f0SDevin Teske# Example: 979d4ae33f0SDevin Teske# f_count count dog house # count=[2] 980d4ae33f0SDevin Teske# 981d4ae33f0SDevin Teskef_count() 982d4ae33f0SDevin Teske{ 983d4ae33f0SDevin Teske setvar "$1" $(( $# - 1 )) 984d4ae33f0SDevin Teske} 985d4ae33f0SDevin Teske 986d4ae33f0SDevin Teske# f_count_ifs $var_to_set string ... 987d4ae33f0SDevin Teske# 988d4ae33f0SDevin Teske# Sets $var_to_set to the number of words (split by the internal field 989d4ae33f0SDevin Teske# separator, IFS) following $var_to_set. 990d4ae33f0SDevin Teske# 991d4ae33f0SDevin Teske# Example 1: 992d4ae33f0SDevin Teske# 993d4ae33f0SDevin Teske# string="word1 word2 word3" 994d4ae33f0SDevin Teske# f_count_ifs count "$string" # count=[3] 995d4ae33f0SDevin Teske# f_count_ifs count $string # count=[3] 996d4ae33f0SDevin Teske# 997d4ae33f0SDevin Teske# Example 2: 998d4ae33f0SDevin Teske# 999d4ae33f0SDevin Teske# IFS=. f_count_ifs count www.freebsd.org # count=[3] 1000d4ae33f0SDevin Teske# 1001d4ae33f0SDevin Teske# NB: Make sure to use double-quotes if you are using a custom value for IFS 1002d4ae33f0SDevin Teske# and you don't want the current value to effect the result. See example 3. 1003d4ae33f0SDevin Teske# 1004d4ae33f0SDevin Teske# Example 3: 1005d4ae33f0SDevin Teske# 1006d4ae33f0SDevin Teske# string="a-b c-d" 1007d4ae33f0SDevin Teske# IFS=- f_count_ifs count "$string" # count=[3] 1008d4ae33f0SDevin Teske# IFS=- f_count_ifs count $string # count=[4] 1009d4ae33f0SDevin Teske# 1010d4ae33f0SDevin Teskef_count_ifs() 1011d4ae33f0SDevin Teske{ 1012d4ae33f0SDevin Teske local __var_to_set="$1" 1013d4ae33f0SDevin Teske shift 1 1014d4ae33f0SDevin Teske set -- $* 1015d4ae33f0SDevin Teske setvar "$__var_to_set" $# 1016bdf4b176SDevin Teske} 1017bdf4b176SDevin Teske 1018ab2043b8SDevin Teske############################################################ MAIN 1019ab2043b8SDevin Teske 1020ab2043b8SDevin Teske# 1021ab2043b8SDevin Teske# Trap signals so we can recover gracefully 1022ab2043b8SDevin Teske# 1023d1eef61dSDevin Tesketrap 'f_interrupt' INT 1024d1eef61dSDevin Tesketrap 'f_die' TERM PIPE XCPU XFSZ FPE TRAP ABRT SEGV 1025d1eef61dSDevin Tesketrap '' ALRM PROF USR1 USR2 HUP VTALRM 1026ab2043b8SDevin Teske 1027526e1dc1SDevin Teske# 1028526e1dc1SDevin Teske# Clone terminal stdout/stderr so we can redirect to it from within sub-shells 1029526e1dc1SDevin Teske# 1030526e1dc1SDevin Teskeeval exec $TERMINAL_STDOUT_PASSTHRU\>\&1 1031526e1dc1SDevin Teskeeval exec $TERMINAL_STDERR_PASSTHRU\>\&2 1032526e1dc1SDevin Teske 103356961fd7SDevin Teske# 1034e14ddd1fSDevin Teske# Self-initialize unless requested otherwise 103556961fd7SDevin Teske# 1036e14ddd1fSDevin Teskef_dprintf "%s: DEBUG_SELF_INITIALIZE=[%s]" \ 1037e14ddd1fSDevin Teske dialog.subr "$DEBUG_SELF_INITIALIZE" 1038e14ddd1fSDevin Teskecase "$DEBUG_SELF_INITIALIZE" in 1039e14ddd1fSDevin Teske""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;; 1040e14ddd1fSDevin Teske*) f_debug_init 1041e14ddd1fSDevin Teskeesac 10429c83db2dSDevin Teske 10439c83db2dSDevin Teske# 104456961fd7SDevin Teske# Log our operating environment for debugging purposes 104556961fd7SDevin Teske# 104656961fd7SDevin Teskef_dprintf "UNAME_S=[%s] UNAME_P=[%s] UNAME_R=[%s]" \ 104756961fd7SDevin Teske "$UNAME_S" "$UNAME_P" "$UNAME_R" 104856961fd7SDevin Teske 104956961fd7SDevin Teskef_dprintf "%s: Successfully loaded." common.subr 105056961fd7SDevin Teske 1051ab2043b8SDevin Teskefi # ! $_COMMON_SUBR 1052