diff options
author | dteske <dteske@FreeBSD.org> | 2012-09-18 22:28:42 +0000 |
---|---|---|
committer | dteske <dteske@FreeBSD.org> | 2012-09-18 22:28:42 +0000 |
commit | 282d6b7f2c0f1fb51d911f75ef9989f62e389985 (patch) | |
tree | 3ef909c692976c6a6b0854f8d722182e78ff8915 /usr.sbin/bsdconfig/include | |
parent | 969b25f00f504248a5c234274661472d753475ad (diff) | |
download | FreeBSD-src-282d6b7f2c0f1fb51d911f75ef9989f62e389985.zip FreeBSD-src-282d6b7f2c0f1fb51d911f75ef9989f62e389985.tar.gz |
Move major includes into /usr/share/bsdconfig for easy external access.
Reviewed by: adrian (co-mentor)
Approved by: adrian (co-mentor)
Diffstat (limited to 'usr.sbin/bsdconfig/include')
-rw-r--r-- | usr.sbin/bsdconfig/include/Makefile | 3 | ||||
-rw-r--r-- | usr.sbin/bsdconfig/include/common.subr | 299 | ||||
-rw-r--r-- | usr.sbin/bsdconfig/include/dialog.subr | 1441 | ||||
-rw-r--r-- | usr.sbin/bsdconfig/include/mustberoot.subr | 360 | ||||
-rw-r--r-- | usr.sbin/bsdconfig/include/strings.subr | 104 | ||||
-rw-r--r-- | usr.sbin/bsdconfig/include/sysrc.subr | 616 |
6 files changed, 1 insertions, 2822 deletions
diff --git a/usr.sbin/bsdconfig/include/Makefile b/usr.sbin/bsdconfig/include/Makefile index 898359a..15d1725 100644 --- a/usr.sbin/bsdconfig/include/Makefile +++ b/usr.sbin/bsdconfig/include/Makefile @@ -3,8 +3,7 @@ NO_OBJ= FILESDIR= ${LIBEXECDIR}/bsdconfig/include -FILES= common.subr dialog.subr messages.subr mustberoot.subr \ - strings.subr sysrc.subr +FILES= messages.subr beforeinstall: mkdir -p ${DESTDIR}${FILESDIR} diff --git a/usr.sbin/bsdconfig/include/common.subr b/usr.sbin/bsdconfig/include/common.subr deleted file mode 100644 index c724c62..0000000 --- a/usr.sbin/bsdconfig/include/common.subr +++ /dev/null @@ -1,299 +0,0 @@ -if [ ! "$_COMMON_SUBR" ]; then _COMMON_SUBR=1 -# -# Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012 Devin Teske -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################ GLOBALS - -# -# Program name -# -pgm="${0##*/}" - -# -# Program arguments -# -ARGC="$#" -ARGV="$@" - -# -# Global exit status variables -# -SUCCESS=0 -FAILURE=1 - -############################################################ FUNCTIONS - -# -# This is an empty function by default, to use it, copy -# /usr/share/examples/bsdconfig/bsdconfigrc to $HOME/.bsdconfigrc -# -f_dprintf() -{ - : this page intentionally left blank -} - -# f_err $fmt [ $opts ... ] -# -# Print a message to stderr (fd=2). -# -f_err() -{ - printf "$@" >&2 -} - -# f_quietly $command [ $arguments ... ] -# -# run a command quietly (quell any output to stdout or stderr) -# -f_quietly() -{ - "$@" > /dev/null 2>&1 -} - -# f_have $anything ... -# -# A wrapper to the `type' built-in. Returns true if argument is a valid shell -# built-in, keyword, or externally-tracked binary, otherwise false. -# -f_have() -{ - f_quietly type "$@" -} - -# f_die [ $status [ $fmt [ $opts ... ]]] -# -# Abruptly terminate due to an error optionally displaying a message in a -# dialog box using printf(1) syntax. -# -f_die() -{ - local status=$FAILURE - - # If there is at least one argument, take it as the status - if [ $# -gt 0 ]; then - status=$1 - shift 1 # status - fi - - # If there are still arguments left, pass them to f_show_msg - [ $# -gt 0 ] && f_show_msg "$@" - - # Optionally call f_clean_up() function if it exists - f_have f_clean_up && f_clean_up - - exit $status -} - -# f_interrupt -# -# Interrupt handler. -# -f_interrupt() -{ - exec 2>&1 # fix sh(1) bug where stderr gets lost within async-trap - f_die -} - -# f_show_msg $fmt [ $opts ... ] -# -# Display a message in a dialog box using printf(1) syntax. -# -f_show_msg() -{ - local msg - msg=$( printf "$@" ) - - # - # Use f_dialog_msgbox from dialog.subr if possible, otherwise fall - # back to dialog(1) (without options, making it obvious when using - # un-aided system dialog). - # - if f_have f_dialog_msgbox; then - f_dialog_msgbox "$msg" - else - dialog --msgbox "$msg" 0 0 - fi -} - -# f_include $file -# -# Include a shell subroutine file. -# -# If the subroutine file exists but returns error status during loading, exit -# is called and execution is prematurely terminated with the same error status. -# -f_include() -{ - local file="$1" - . "$file" || exit $? -} - -# f_include_lang $file -# -# Include a language file. Automatically takes $LANG and $LC_ALL into -# considerationg when including $file (suffix ".$LC_ALL" or ".$LANG" will -# automatically by added prior to loading the language file). -# -# No error is produced if (a) a language has been requested (by setting either -# $LANG or $LC_ALL in the environment) and (b) the language file does not -# exist -- in which case we will fall back to loading $file without-suffix. -# -# If the language file exists but returns error status during loading, exit -# is called and execution is prematurely terminated with the same error status. -# -f_include_lang() -{ - local file="$1" - local lang="${LANG:-$LC_ALL}" - - f_dprintf "lang=[$lang]" - if [ -f "$file.$lang" ]; then - . "$file.$lang" || exit $? - else - . "$file" || exit $? - fi -} - -# f_usage $file [ $key1 $value1 ... ] -# -# Display USAGE file with optional pre-processor macro definitions. The first -# argument is the template file containing the usage text to be displayed. If -# $LANG or $LC_ALL (in order of preference, respectively) is set, ".encoding" -# will automatically be appended as a suffix to the provided $file pathname. -# -# When processing $file, output begins at the first line containing that is -# (a) not a comment, (b) not empty, and (c) is not pure-whitespace. All lines -# appearing after this first-line are output, including (a) comments (b) empty -# lines, and (c) lines that are purely whitespace-only. -# -# If additional arguments appear after $file, substitutions are made while -# printing the contents of the USAGE file. The pre-processor macro syntax is in -# the style of autoconf(1), for example: -# -# f_usage $file "FOO" "BAR" -# -# Will cause instances of "@FOO@" appearing in $file to be replaced with the -# text "BAR" before bering printed to the screen. -# -# This function is a two-parter. Below is the awk(1) portion of the function, -# afterward is the sh(1) function which utilizes the below awk script. -# -f_usage_awk=' -BEGIN { found = 0 } -{ - if ( !found && $0 ~ /^[[:space:]]*($|#)/ ) next - found = 1 - print -} -' -f_usage() -{ - local file="$1" - local lang="${LANG:-$LC_ALL}" - - f_dprintf "lang=[$lang]" - - shift 1 # file - - local usage - if [ -f "$file.$lang" ]; then - usage=$( awk "$f_usage_awk" "$file.$lang" ) || exit $FAILURE - else - usage=$( awk "$f_usage_awk" "$file" ) || exit $FAILURE - fi - - while [ $# -gt 0 ]; do - local key="$1" - export value="$2" - usage=$( echo "$usage" | awk \ - "{ gsub(/@$key@/, ENVIRON[\"value\"]); print }" ) - shift 2 - done - - f_err "%s\n" "$usage" - - exit $FAILURE -} - -# f_index_menu_selection $file $pgm -# -# Process $file looking for $menu_selection values that correspond to $pgm. -# This function is for internationalization (i18n) mapping of the on-disk -# scriptname ($pgm) into the localized language (given language-specific -# $file). If $LANG or $LC_ALL (in orderder of preference, respectively) is set, -# ".encoding" will automatically be appended as a suffix to the provided $file -# pathname. -# -# If, within $file, multiple $menu_selection values map to $pgm, only the first -# one will be returned. If no mapping can be made, the NULL string is returned. -# -# If $file does not exist, error status is returned along with the NULL string. -# -# This function is a two-parter. Below is the awk(1) portion of the function, -# afterward is the sh(1) function which utilizes the below awk script. -# -f_index_menusel_awk=' -# Variables that should be defined on the invocation line: -# -v pgm="program_name" -# -( $0 ~ "^menu_selection=.*\\|" pgm "\"" ) { - sub(/\|.*/, "") - sub(/^menu_selection="/, "") - print - exit -} -' -f_index_menu_selection() -{ - local file="$1" pgm="$2" - local lang="${LANG:-$LC_ALL}" - - f_dprintf "lang=[$lang]" - - if [ -f "$file.$lang" ]; then - awk -v pgm="$pgm" "$f_index_menusel_awk" "$file.$lang" || - exit $FAILURE - elif [ -f "$file" ]; then - awk -v pgm="$pgm" "$f_index_menusel_awk" "$file" || - exit $FAILURE - else - return $FAILURE - fi -} - -############################################################ MAIN - -# -# Trap signals so we can recover gracefully -# -trap 'f_interrupt' SIGINT -trap 'f_die' SIGTERM SIGPIPE SIGXCPU SIGXFSZ \ - SIGFPE SIGTRAP SIGABRT SIGSEGV -trap '' SIGALRM SIGPROF SIGUSR1 SIGUSR2 SIGHUP SIGVTALRM - -fi # ! $_COMMON_SUBR diff --git a/usr.sbin/bsdconfig/include/dialog.subr b/usr.sbin/bsdconfig/include/dialog.subr deleted file mode 100644 index 35c71cb..0000000 --- a/usr.sbin/bsdconfig/include/dialog.subr +++ /dev/null @@ -1,1441 +0,0 @@ -if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1 -# -# Copyright (c) 2006-2012 Devin Teske -# All Rights Reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################ INCLUDES - -BSDCFG_LIBE="/usr/libexec/bsdconfig" -. $BSDCFG_LIBE/include/common.subr || exit 1 -f_include $BSDCFG_LIBE/include/strings.subr -f_include_lang $BSDCFG_LIBE/include/messages.subr - -############################################################ CONFIGURATION - -# -# Default directory to store dialog(1) temporary files -# -: ${DIALOG_TMPDIR:="/tmp"} - -############################################################ GLOBALS - -# -# Default name of dialog(1) utility -# NOTE: This is changed to "Xdialog" by the optional `-X' argument -# -DIALOG="dialog" - -# -# Default dialog(1) title and backtitle text -# -DIALOG_TITLE="$pgm" -DIALOG_BACKTITLE="bsdconfig" - -# -# Settings used while interacting with dialog(1) -# -DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyz" - -# -# Declare that we are fully-compliant with Xdialog(1) by unset'ing all -# compatibility settings. -# -unset XDIALOG_HIGH_DIALOG_COMPAT -unset XDIALOG_FORCE_AUTOSIZE -unset XDIALOG_INFOBOX_TIMEOUT - -# -# Default behavior is to call f_dialog_init() automatically if not already -# called manually by the time the first f_dialog_*() function is used. -# -: ${DIALOG_SELF_INITIALIZE=1} - -############################################################ GENERIC FUNCTIONS - -# f_dialog_title [$new_title] -# -# Set the title of future dialog(1) ($DIALOG_TITLE) or backtitle of Xdialog(1) -# ($DIALOG_BACKTITLE) invocations. If no arguments are given or the first -# argument is NULL, the current title is returned. -# -# Each time this function is called, a backup of the current values is made -# allowing a one-time (single-level) restoration of the previous title using the -# f_dialog_title_restore() function (below). -# -f_dialog_title() -{ - local new_title="$1" - - if [ "$new_title" ]; then - if [ "$USE_XDIALOG" ]; then - _DIALOG_BACKTITLE="$DIALOG_BACKTITLE" - DIALOG_BACKTITLE="$new_title" - else - _DIALOG_TITLE="$DIALOG_TITLE" - DIALOG_TITLE="$new_title" - fi - else - if [ "$USE_XDIALOG" ]; then - echo "$DIALOG_BACKTITLE" - else - echo "$DIALOG_TITLE" - fi - fi -} - -# f_dialog_title_restore -# -# Restore the previous title set by the last call to f_dialog_title(). -# Restoration is non-recursive and only works to restore the most-recent title. -# -f_dialog_title_restore() -{ - if [ "$USE_XDIALOG" ]; then - DIALOG_BACKTITLE="$_DIALOG_BACKTITLE" - else - DIALOG_TITLE="$_DIALOG_TITLE" - fi -} - -# f_dialog_backtitle [$new_backtitle] -# -# Set the backtitle of future dialog(1) ($DIALOG_BACKTITLE) or title of -# Xdialog(1) ($DIALOG_TITLE) invocations. If no arguments are given or the -# first argument is NULL, the current backtitle is returned. -# -f_dialog_backtitle() -{ - local new_backtitle="$1" - - if [ "$new_backtitle" ]; then - if [ "$USE_XDIALOG" ]; then - _DIALOG_TITLE="$DIALOG_TITLE" - DIALOG_TITLE="$new_backtitle" - else - _DIALOG_BACKTITLE="$DIALOG_BACKTITLE" - DIALOG_BACKTITLE="$new_backtitle" - fi - else - if [ "$USE_XDIALOG" ]; then - echo "$DIALOG_TITLE" - else - echo "$DIALOG_BACKTITLE" - fi - fi -} - -# f_dialog_backtitle_restore -# -# Restore the previous backtitle set by the last call to f_dialog_backtitle(). -# Restoration is non-recursive and only works to restore the most-recent -# backtitle. -# -f_dialog_backtitle_restore() -{ - if [ "$USE_XDIALOG" ]; then - DIALOG_TITLE="$_DIALOG_TITLE" - else - DIALOG_BACKTITLE="$_DIALOG_BACKTITLE" - fi -} - -############################################################ SIZE FUNCTIONS - -# f_dialog_infobox_size $title $backtitle $prompt [$hline] -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--infobox' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, and [optionally] hline returning -# the optimal width and height for the box (not exceeding the actual terminal -# width or height). -# -# Newline character sequences (``\n'') in $prompt are expanded as-is done by -# dialog(1). -# -# Output is in the format of "height width". -# -f_dialog_infobox_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 - local min_width max_size - - if [ "$USE_XDIALOG" ]; then - min_width=35 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_width=24 - max_size=$( stty size ) # usually "24 80" - fi - - local max_height="${max_size%%[$IFS]*}" - local max_width="${max_size##*[$IFS]}" - local height width=$min_width - - # - # Bump width for long titles (but don't exceed terminal width). - # - n=$(( ${#title} + 4 )) - if [ $n -gt $width -a $n -gt $min_width ]; then - # Add 16.6% width for Xdialog(1) - [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) - - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - - # - # For Xdialog(1), bump width for long backtitles (which appear within - # the window; don't exceed maximum width). - # - if [ "$USE_XDIALOG" ]; then - n=$(( ${#btitle} + 4 )) - n=$(( $n + $n / 6 )) - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # - # Bump width for long prompts (if not already at maximum width). - # - if [ $width -lt $max_width ]; then - n=$( echo "$prompt" | f_longest_line_length ) - n=$(( $n + 4 )) - - # Add 16.6% width for Xdialog(1) - [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) - - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # - # Bump width for long hlines (if not already at maximum width). - # NOTE: Though Xdialog(1) supports `--hline', it's not currently used. - # - if [ ! "$USE_XDIALOG" ]; then - if [ $width -lt $max_width ]; then - n=$(( ${#hline} + 10 )) - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - fi - - # - # Set height based on number of rows in prompt - # - height=$( echo "$prompt" | f_number_of_lines ) - height=$(( $height + 2 )) - - # - # For Xdialog(1) bump height if backtitle is enabled (displayed in the - # X11 window with a separator line between the backtitle and msg text) - # - if [ "$USE_XDIALOG" -a "$btitle" ]; then - n=$( echo "$btitle" | f_number_of_lines ) - height=$(( $height + $n + 2 )) - fi - - # Make sure height is less than maximum screen size - [ $height -le $max_height ] || height=$max_height - - # Return both - echo "$height $width" -} - -# f_dialog_buttonbox_size $title $backtitle $prompt [$hline] -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--msgbox' and `--yesno' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, and [optionally] hline returning -# the optimal width and height for the box (not exceeding the actual terminal -# width or height). -# -# Newline character sequences (``\n'') in $prompt are expanded as-is done by -# dialog(1). -# -# Output is in the format of "height width". -# -f_dialog_buttonbox_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" - local size="$( f_dialog_infobox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local height="${size%%[$IFS]*}" - local width="${size##*[$IFS]}" - - # Add height to accomodate the buttons - height=$(( $height + 2 )) - - # Adjust for clipping with Xdialog(1) on Linux/GTK2 - [ "$USE_XDIALOG" ] && height=$(( $height + 3 )) - - # - # Enforce maximum height regardless - # - local max_size - if [ "$USE_XDIALOG" ]; then - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - max_size=$( stty size ) # usually "24 80" - fi - local max_height="${max_size%%[$IFS]*}" - [ $height -le $max_height ] || height=$max_height - - # Return both - echo "$height $width" -} - -# f_dialog_inputbox_size $title $backtitle $prompt $init [$hline] -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--inputbox' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, initial text, and [optionally] -# hline returning the optimal width and height for the box (not exceeding the -# actual terminal width and height). -# -# Newline character sequences (``\n'') in $prompt are expanded as-is done by -# dialog(1). -# -# Output is in the format of "height width". -# -f_dialog_inputbox_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" init="$4" hline="$5" n - local size="$( f_dialog_buttonbox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local height="${size%%[$IFS]*}" - local width="${size##*[$IFS]}" - - local min_width max_size - if [ "$USE_XDIALOG" ]; then - min_width=35 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_width=24 - max_size=$( stty size ) # usually "24 80" - fi - local max_height="${max_size%%[$IFS]*}" - local max_width="${max_size##*[$IFS]}" - - # - # Add height to accomodate the input box - # - [ ! "$USE_XDIALOG" ] && height=$(( $height + 3 )) - [ $height -le $max_height ] || height=$max_height - - # - # Bump width for initial text (if not already at maximum width). - # NOTE: Something neither dialog(1)/Xdialog(1) do, but worth it! - # - if [ $width -lt $max_width ]; then - n=$(( ${#init} + 7 )) - - # Add 16.6% width for Xdialog(1) - [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) - - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # Return both - echo "$height $width" -} - -# f_xdialog_2inputsbox_size $title $backtitle $prompt \ -# $label1 $init1 $label2 $init2 -# -# Xdialog(1) does not perform auto-sizing of the width and height of -# `--2inputsbox' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, label for the first field, initial -# text for said field, label for the second field, and initial text for said -# field returning the optimal width and height for the box (not exceeding the -# actual terminal width and height). -# -# Newline character sequences (``\n'') in $prompt are expanded as-is done by -# Xdialog(1). -# -# Output is in the format of "height width". -# -f_xdialog_2inputsbox_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" - local label1="$4" init1="$5" label2="$6" init2="$7" n - local size="$( f_dialog_inputbox_size \ - "$title" "$btitle" "$prompt" "$init1" )" - local height="${size%%[$IFS]*}" - local width="${size##*[$IFS]}" - - local min_width=35 - local max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - local max_height="${max_size%%[$IFS]*}" - local max_width="${max_size##*[$IFS]}" - - # Add height for first label - height=$(( $height + 2 )) - - # - # Bump width for first label text (if not already at maximum width). - # - if [ $width -lt $max_width ]; then - n=$(( ${#label1} + 7 )) - - # Add 16.6% width for Xdialog(1) - n=$(( $n + $n / 6 )) - - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # Add height for second label - height=$(( $height + 2 )) - - # - # Bump width for second label text (if not already at maximum width). - # - if [ $width -lt $max_width ]; then - n=$(( ${#label2} + 7 )) - - # Add 16.6% width for Xdialog(1) - n=$(( $n + $n / 6 )) - - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # Add height for a second inputbox - height=$(( $height + 2 )) - - # - # Bump width for second initial text (if not already at maximum width). - # NOTE: Something neither dialog(1)/Xdialog(1) do, but worth it! - # - if [ $width -lt $max_width ]; then - n=$(( ${#init2} + 7 )) - - # Add 16.6% width for Xdialog(1) - n=$(( $n + $n / 6 )) - - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # Return both - echo "$height $width" -} - -# f_dialog_menu_size $title $backtitle $prompt $hline \ -# $tag1 $item1 $tag2 $item2 ... -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--menu' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, hline and list of tag/item pairs, -# returning the optimal width and height for the menu (not exceeding the actual -# terminal width or height). -# -# Output is in the format of "height width rows". -# -f_dialog_menu_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 - local min_width min_rows max_size - - if [ "$USE_XDIALOG" ]; then - min_width=35 - min_rows=1 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_width=24 - min_rows=0 - max_size=$( stty size ) # usually "24 80" - fi - - local max_width="${max_size##*[$IFS]}" - local max_height="${max_size%%[$IFS]*}" - local box_size="$( f_dialog_infobox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local box_height="${box_size%%[$IFS]*}" - local box_width="${box_size##*[$IFS]}" - local max_rows=$(( $max_height - 8 )) - local height width=$box_width rows=$min_rows - - shift 4 # title/btitle/prompt/hline - - # If there's no prompt, bump the max-rows by 1 - [ "$prompt" ] || max_rows=$(( $max_rows + 1 )) - - # - # The sum total between the longest tag-length and longest item-length - # should be used for the menu width (not to exceed terminal width). - # - # Also, calculate the number of rows (not to exceed terminal height). - # - local longest_tag=0 longest_item=0 - while [ $# -ge 2 ]; do - local tag="$1" item="$2" - shift 2 # tag/item - - [ ${#tag} -gt $longest_tag ] && longest_tag=${#tag} - [ ${#item} -gt $longest_item ] && longest_item=${#item} - [ $rows -lt $max_rows ] && rows=$(( $rows + 1 )) - done - - # Update width - n=$(( $longest_tag + $longest_item + 10 )) - [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1) - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - - # Fix rows and set height - [ $rows -gt 0 ] || rows=1 - if [ "$USE_XDIALOG" ]; then - height=$(( $rows + $box_height + 7 )) - else - height=$(( $rows + $box_height + 4 )) - fi - [ $height -le $max_height ] || height=$max_height - - # Return all three - echo "$height $width $rows" -} - -# f_dialog_menu_with_help_size $title $backtitle $prompt $hline \ -# $tag1 $item1 $help1 $tag2 $item2 $help2 ... -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--menu' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, hline and list of tag/item/help -# triplets, returning the optimal width and height for the menu (not exceeding -# the actual terminal width or height). -# -# Output is in the format of "height width rows". -# -f_dialog_menu_with_help_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 - local min_width min_rows max_size - - if [ "$USE_XDIALOG" ]; then - min_width=35 - min_rows=1 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_width=24 - min_rows=0 - max_size=$( stty size ) # usually "24 80" - fi - - local max_width="${max_size##*[$IFS]}" - local max_height="${max_size%%[$IFS]*}" - local box_size="$( f_dialog_infobox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local box_height="${box_size%%[$IFS]*}" - local box_width="${box_size##*[$IFS]}" - local max_rows=$(( $max_height - 8 )) - local height width=$box_width rows=$min_rows - - shift 4 # title/btitle/prompt/hline - - # If there's no prompt, bump the max-rows by 1 - [ "$prompt" ] || max_rows=$(( $max_rows + 1 )) - - # - # The sum total between the longest tag-length and longest item-length - # should be used for the menu width (not to exceed terminal width). - # - # Also, calculate the number of rows (not to exceed terminal height). - # - # Also, calculate the longest help while we're here. This will be used - # to influence the width of the menu if (and only-if) using Xdialog(1). - # - local longest_tag=0 longest_item=0 longest_help=0 - while [ $# -ge 3 ]; do - local tag="$1" item="$2" help="$3" - shift 3 # tag/item/help - - [ ${#tag} -gt $longest_tag ] && longest_tag=${#tag} - [ ${#item} -gt $longest_item ] && longest_item=${#item} - [ ${#help} -gt $longest_help ] && longest_help=${#help} - [ $rows -lt $max_rows ] && rows=$(( $rows + 1 )) - done - - # Update width - n=$(( $longest_tag + $longest_item + 10 )) - [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1) - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - - # Update width for help text if using Xdialog(1) - if [ "$USE_XDIALOG" ]; then - n=$(( $longest_help + 10 )) - n=$(( $n + $n / 6 )) # +16.6% - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - fi - - # Fix rows and set height - [ $rows -gt 0 ] || rows=1 - if [ "$USE_XDIALOG" ]; then - height=$(( $rows + $box_height + 8 )) - else - height=$(( $rows + $box_height + 4 )) - fi - [ $height -le $max_height ] || height=$max_height - - # Return all three - echo "$height $width $rows" -} - -# f_dialog_radiolist_size $title $backtitle $prompt $hline \ -# $tag1 $item1 $status1 $tag2 $item2 $status2 ... -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--radiolist' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, hline and list of tag/item/status -# triplets, returning the optimal width and height for the radiolist (not -# exceeding the actual terminal width or height). -# -# Output is in the format of "height width rows". -# -f_dialog_radiolist_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" n=0 - local min_width min_rows max_size - - if [ "$USE_XDIALOG" ]; then - min_width=35 - min_rows=1 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_width=24 - min_rows=0 - max_size=$( stty size ) # usually "24 80" - fi - - local max_width="${max_size##*[$IFS]}" - local max_height="${max_size%%[$IFS]*}" - local box_size="$( f_dialog_infobox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local box_height="${box_size%%[$IFS]*}" - local box_width="${box_size##*[$IFS]}" - local max_rows=$(( $max_height - 8 )) - local height width=$box_width rows=$min_rows - - shift 4 # title/btitle/prompt/hline - - # - # The sum total between the longest tag-length, longest item-length, - # and radio-button width should be used for the menu width (not to - # exceed terminal width). - # - # Also, calculate the number of rows (not to exceed terminal height). - # - local longest_tag=0 longest_item=0 - while [ $# -ge 2 ]; do - local tag="$1" item="$2" help="$3" - shift 3 # tag/item/status - - [ ${#tag} -gt $longest_tag ] && longest_tag=${#tag} - [ ${#item} -gt $longest_item ] && longest_item=${#item} - [ $rows -lt $max_rows ] && rows=$(( $rows + 1 )) - done - - # Update width - n=$(( $longest_tag + $longest_item + 13 )) - [ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1) - if [ $n -gt $width -a $n -gt $min_width ]; then - if [ $n -lt $max_width ]; then - width=$n - else - width=$max_width - fi - fi - - # Fix rows and set height - [ $rows -gt 0 ] || rows=1 - if [ "$USE_XDIALOG" ]; then - height=$(( $rows + $box_height + 7 )) - else - height=$(( $rows + $box_height + 4 )) - fi - [ $height -le $max_height ] || height=$max_height - - # Return all three - echo "$height $width $rows" -} - -# f_dialog_calendar_size $title $backtitle $prompt [$hline] -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--calendar' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, and [optionally] hline returning -# the optimal width and height for the box (not exceeding the actual terminal -# width and height). -# -# Newline character sequences (``\n'') in $prompt are expanded as-is done by -# dialog(1). -# -# Output is in the format of "height width". -# -f_dialog_calendar_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" n - local size="$( f_dialog_infobox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local height="${size%%[$IFS]*}" - local width="${size##*[$IFS]}" - - local min_width min_height max_size - if [ "$USE_XDIALOG" ]; then - min_height=15 - min_width=55 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_height=0 - min_width=40 - max_size=$( stty size ) # usually "24 80" - fi - local max_height="${max_size%%[$IFS]*}" - local max_width="${max_size##*[$IFS]}" - - # - # Enforce the minimum width for displaying the calendar - # - [ $width -ge $min_width ] || width=$min_width - - # - # When using dialog(1), the calendar box is unique from other dialog(1) - # boxes in-that the height passed should not accomodate the 15-lines - # required to display the calendar. This does not apply to Xdialog(1). - # - # When using Xdialog(1), the height must accomodate the 15-lines - # required to display the calendar. - # - # NOTE: Also under dialog(1), because we can't predict whether the user - # has disabled shadow's in their `$HOME/.dialogrc' file, we'll subtract - # 16 rather than 15. This does not apply to Xdialog(1). - # - max_height=$(( $max_height - 16 )) - height=$( echo "$prompt" | f_number_of_lines ) - if [ "$USE_XDIALOG" ]; then - # Add height to accomodate for the embedded calendar widget - height=$(( $height + $min_height - 1 )) - - # Also, bump height if backtitle is enabled - if [ "$btitle" ]; then - local n="$( echo "$btitle" | f_number_of_lines )" - height=$(( $height + $n + 2 )) - fi - else - [ "$prompt" ] && height=$(( $height + 1 )) - fi - [ $height -le $max_height ] || height=$max_height - - # - # The calendar box refuses to display if too large. - # - max_width=$(( $max_width - 2 )) - [ $width -le $max_width ] || width=$max_width - - # Return both - echo "$height $width" -} - -# f_dialog_timebox_size $title $backtitle $prompt [$hline] -# -# Not all versions of dialog(1) perform auto-sizing of the width and height of -# `--timebox' boxes sensibly. -# -# This function helps solve this issue by taking as arguments (in order of -# appearance) the title, backtitle, prompt, and [optionally] hline returning -# the optimal width and height for the box (not exceeding the actual terminal -# width and height). -# -# Newline character sequences (``\n'') in $prompt are expanded as-is done by -# dialog(1). -# -# Output is in the format of "height width". -# -f_dialog_timebox_size() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local title="$1" btitle="$2" prompt="$3" hline="$4" n - local size="$( f_dialog_infobox_size \ - "$title" "$btitle" "$prompt" "$hline" )" - local height="${size%%[$IFS]*}" - local width="${size##*[$IFS]}" - - local min_width min_height max_size - if [ "$USE_XDIALOG" ]; then - min_width=40 - max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION - else - min_height=0 - min_width=20 - max_size=$( stty size ) # usually "24 80" - fi - local max_height="${max_size%%[$IFS]*}" - local max_width="${max_size##*[$IFS]}" - - # - # Enforce the minimum width for displaying the timebox - # - [ $width -ge $min_width ] || width=$min_width - - # - # When using dialog(1), the timebox box is unique from other dialog(1) - # boxes in-that the height passed should not accomodate the 6-lines - # required to display the timebox. This does not apply to Xdialog(1). - # - # When using Xdialog(1), the height seems to have no effect. All values - # provide the same results. - # - # NOTE: Also under dialog(1), because we can't predict whether the user - # has disabled shadow's in their `$HOME/.dialogrc' file, we'll subtract - # 7 rather than 6. This does not apply to Xdialog(1). - # - if [ "$USE_XDIALOG" ]; then - height=0 # Autosize; all values produce same results - else - max_height=$(( $max_height - 7 )) - height=$( echo "$prompt" | f_number_of_lines ) - height=$(( $height + 1 )) - [ $height -le $max_height ] || height=$max_height - [ "$prompt" ] && height=$(( $height + 1 )) - fi - - # - # The timebox box refuses to display if too large. - # - max_width=$(( $max_width - 2 )) - [ $width -le $max_width ] || width=$max_width - - # Return both - echo "$height $width" -} - -############################################################ CLEAR FUNCTIONS - -# f_dialog_clear -# -# Clears any/all previous dialog(1) displays. -# -f_dialog_clear() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - $DIALOG --clear -} - -############################################################ INFO FUNCTIONS - -# f_dialog_info $info_text ... -# -# Throw up a dialog(1) infobox. The infobox remains until another dialog is -# displayed or `dialog --clear' (or dialog_clear) is called. -# -f_dialog_info() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local info_text="$*" - local size="$( f_dialog_infobox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$info_text" )" - - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - ${USE_XDIALOG:+--ignore-eof} \ - ${USE_XDIALOG:+--no-buttons} \ - --infobox \"\$info_text\" $size -} - -# f_xdialog_info $info_text ... -# -# Throw up an Xdialog(1) infobox and do not dismiss it until stdin produces -# EOF. This implies that you must execute this either as an rvalue to a pipe, -# lvalue to indirection or in a sub-shell that provides data on stdin. -# -f_xdialog_info() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local info_text="$*" - local size="$( f_dialog_infobox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$info_text" )" - - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --no-close --no-buttons \ - --infobox \"\$info_text\" $size \ - -1 # timeout of -1 means abort when EOF on stdin -} - -############################################################ MSGBOX FUNCTIONS - -# f_dialog_msgbox $msg_text ... -# -# Throw up a dialog(1) msgbox. The msgbox remains until the user presses ENTER -# or ESC, acknowledging the modal dialog. -# -# If the user presses ENTER, the exit status is zero (success), otherwise if -# the user presses ESC the exit status is 255. -# -f_dialog_msgbox() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local msg_text="$*" - local size="$( f_dialog_buttonbox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$msg_text" )" - - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --ok-label \"\$msg_ok\" \ - --msgbox \"\$msg_text\" $size -} - -############################################################ YESNO FUNCTIONS - -# f_dialog_yesno $msg_text ... -# -# Display a dialog(1) Yes/No prompt to allow the user to make some decision. -# The yesno prompt remains until the user presses ENTER or ESC, acknowledging -# the modal dialog. -# -# If the user chooses YES the exit status is zero, or chooses NO the exit -# status is one, or presses ESC the exit status is 255. -# -f_dialog_yesno() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local msg_text="$*" - local hline="$hline_arrows_tab_enter" - local size="$( f_dialog_buttonbox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$msg_text" \ - "$hline" )" - - if [ "$USE_XDIALOG" ]; then - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --ok-label \"\$msg_yes\" \ - --cancel-label \"\$msg_no\" \ - --yesno \"\$msg_text\" $size - else - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --yes-label \"\$msg_yes\" \ - --no-label \"\$msg_no\" \ - --yesno \"\$msg_text\" $size - fi -} - -# f_dialog_noyes $msg_text ... -# -# Display a dialog(1) No/Yes prompt to allow the user to make some decision. -# The noyes prompt remains until the user presses ENTER or ESC, acknowledging -# the modal dialog. -# -# If the user chooses YES the exit status is zero, or chooses NO the exit -# status is one, or presses ESC the exit status is 255. -# -# NOTE: This is just like the f_dialog_yesno function except "No" is default. -# -f_dialog_noyes() -{ - [ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init - - local msg_text="$*" - local hline="$hline_arrows_tab_enter" - local size="$( f_dialog_buttonbox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$msg_text" \ - "$hline" )" - - if [ "$USE_XDIALOG" ]; then - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --default-no \ - --ok-label \"\$msg_yes\" \ - --cancel-label \"\$msg_no\" \ - --yesno \"\$msg_text\" $size - else - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --defaultno \ - --yes-label \"\$msg_yes\" \ - --no-label \"\$msg_no\" \ - --yesno \"\$msg_text\" $size - fi -} - -############################################################ INPUT FUNCTIONS - -# f_dialog_inputstr -# -# Obtain the inputstr entered by the user from the most recently displayed -# dialog(1) inputbox and clean up any temporary files. -# -f_dialog_inputstr() -{ - local tmpfile="$DIALOG_TMPDIR/dialog.inputbox.$$" - - [ -f "$tmpfile" ] || return $FAILURE - - # Skip warnings and trim leading/trailing whitespace from user input - awk ' - BEGIN { found = 0 } - { - if ( ! found ) - { - if ( $0 ~ /^$/ ) next - if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next - found = 1 - } - sub(/^[[:space:]]*/, "") - sub(/[[:space:]]*$/, "") - print - } - ' "$tmpfile" 2> /dev/null - f_quietly rm -f "$tmpfile" - - return $SUCCESS -} - -############################################################ MENU FUNCTIONS - -# f_dialog_menutag -# -# Obtain the menutag chosen by the user from the most recently displayed -# dialog(1) menu and clean up any temporary files. -# -f_dialog_menutag() -{ - local tmpfile="$DIALOG_TMPDIR/dialog.menu.$$" - - [ -f "$tmpfile" ] || return $FAILURE - - awk ' - BEGIN { found = 0 } - { - if ( found ) # ... just spew - { - print - next - } - if ( $0 ~ /^$/ ) next - if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next - found = 1 - print - } - ' "$tmpfile" 2> /dev/null - f_quietly rm -f "$tmpfile" - - return $SUCCESS -} - -# f_dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ... -# -# To use the `--menu' option of dialog(1) you must pass an ordered list of -# tag/item pairs on the command-line. When the user selects a menu option the -# tag for that item is printed to stderr. -# -# This function allows you to dereference the tag chosen by the user back into -# the item associated with said tag. -# -# Pass the tag chosen by the user as the first argument, followed by the -# ordered list of tag/item pairs (HINT: use the same tag/item list as was -# passed to dialog(1) for consistency). -# -# If the tag cannot be found, NULL is returned. -# -f_dialog_menutag2item() -{ - local tag="$1" tagn item - shift 1 # tag - - while [ $# -gt 0 ]; do - tagn="$1" - item="$2" - shift 2 # tagn/item - - if [ "$tag" = "$tagn" ]; then - echo "$item" - return $SUCCESS - fi - done - return $FAILURE -} - -# f_dialog_menutag2item_with_help $tag_chosen $tag1 $item1 $help1 \ -# $tag2 $item2 $help2 ... -# -# To use the `--menu' option of dialog(1) with the `--item-help' option, you -# must pass an ordered list of tag/item/help triplets on the command-line. When -# the user selects a menu option the tag for that item is printed to stderr. -# -# This function allows you to dereference the tag chosen by the user back into -# the item associated with said tag (help is discarded/ignored). -# -# Pass the tag chosen by the user as the first argument, followed by the -# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list -# as was passed to dialog(1) for consistency). -# -# If the tag cannot be found, NULL is returned. -# -f_dialog_menutag2item_with_help() -{ - local tag="$1" tagn item - shift 1 # tag - - while [ $# -gt 0 ]; do - tagn="$1" - item="$2" - shift 3 # tagn/item/help - - if [ "$tag" = "$tagn" ]; then - echo "$item" - return $SUCCESS - fi - done - return $FAILURE -} - -# f_dialog_menutag2index $tag_chosen $tag1 $item1 $tag2 $item2 ... -# -# To use the `--menu' option of dialog(1) you must pass an ordered list of -# tag/item pairs on the command-line. When the user selects a menu option the -# tag for that item is printed to stderr. -# -# This function allows you to dereference the tag chosen by the user back into -# the index associated with said tag. The index is the one-based tag/item pair -# array position within the ordered list of tag/item pairs passed to dialog(1). -# -# Pass the tag chosen by the user as the first argument, followed by the -# ordered list of tag/item pairs (HINT: use the same tag/item list as was -# passed to dialog(1) for consistency). -# -# If the tag cannot be found, NULL is returned. -# -f_dialog_menutag2index() -{ - local tag="$1" tagn n=1 - shift 1 # tag - - while [ $# -gt 0 ]; do - tagn="$1" - shift 2 # tagn/item - - if [ "$tag" = "$tagn" ]; then - echo $n - return $SUCCESS - fi - n=$(( $n + 1 )) - done - return $FAILURE -} - -# f_dialog_menutag2index_with_help $tag_chosen $tag1 $item1 $help1 \ -# $tag2 $item2 $help2 ... -# -# To use the `--menu' option of dialog(1) with the `--item-help' option, you -# must pass an ordered list of tag/item/help triplets on the command-line. When -# the user selects a menu option the tag for that item is printed to stderr. -# -# This function allows you to dereference the tag chosen by the user back into -# the index associated with said tag. The index is the one-based tag/item/help -# triplet array position within the ordered list of tag/item/help triplets -# passed to dialog(1). -# -# Pass the tag chosen by the user as the first argument, followed by the -# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list -# as was passed to dialog(1) for consistency). -# -# If the tag cannot be found, NULL is returned. -# -f_dialog_menutag2index_with_help() -{ - local tag="$1" tagn n=1 - shift 1 # tag - - while [ $# -gt 0 ]; do - tagn="$1" - shift 3 # tagn/item/help - - if [ "$tag" = "$tagn" ]; then - echo $n - return $SUCCESS - fi - n=$(( $n + 1 )) - done - return $FAILURE -} - -############################################################ INIT FUNCTIONS - -# f_dialog_init -# -# Initialize (or re-initialize) the dialog module after setting/changing any -# of the following environment variables: -# -# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate -# that Xdialog(1) should be used instead of dialog(1). -# -# SECURE Either NULL or Non-NULL. If given a value will indicate -# that (while running as root) sudo(8) authentication is -# required to proceed. -# -f_dialog_init() -{ - DIALOG_SELF_INITIALIZE= - - # - # Process stored command-line arguments - # - SECURE=$( set -- "$ARGV" - while getopts S flag > /dev/null; do - case "$flag" in - S) echo 1;; - \?) continue;; - esac - done - ) - USE_XDIALOG=$( set -- "$ARGV" - while getopts SX flag > /dev/null; do - case "$flag" in - S|X) echo 1;; - \?) continue;; - esac - done - ) - - # - # Process `-X' command-line option - # - [ "$USE_XDIALOG" ] && DIALOG=Xdialog - - # - # Sanity check, or die gracefully - # - if ! f_have $DIALOG; then - unset USE_XDIALOG - failed_dialog="$DIALOG" - DIALOG=dialog - f_die 1 "$msg_no_such_file_or_directory" "$pgm" "$failed_dialog" - fi - - # - # If we're already running as root but we got there by way of sudo(8) - # and we have X11, we should merge the xauth(1) credentials from our - # original user. - # - if [ "$USE_XDIALOG" ] && - [ "$( id -u )" = "0" ] && - [ "$SUDO_USER" -a "$DISPLAY" ] - then - if ! f_have xauth; then - # Die gracefully, as we [likely] can't use Xdialog(1) - unset USE_XDIALOG - DIALOG=dialog - f_die 1 "$msg_no_such_file_or_directory" "$pgm" "xauth" - fi - HOSTNAME=$(hostname) - displaynum="${DISPLAY#*:}" - eval xauth -if \~$SUDO_USER/.Xauthority extract - \ - \"\$HOSTNAME/unix:\$displaynum\" \ - \"\$HOSTNAME:\$displaynum\" | sudo sh -c 'xauth -ivf \ - ~root/.Xauthority merge - > /dev/null 2>&1' - fi - - # - # Probe Xdialog(1) for maximum height/width constraints, or die - # gracefully - # - if [ "$USE_XDIALOG" ]; then - if ! maxsize=$( LANG= LC_ALL= $DIALOG --print-maxsize 2>&1 ) - then - # Xdialog(1) failed, fall back to dialog(1) - unset USE_XDIALOG - size=$( f_dialog_buttonbox_size "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$maxsize" "" ) - eval dialog \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --ok-label \"\$msg_ok\" \ - --msgbox \"\$maxsize\" $size - exit $FAILURE - fi - - XDIALOG_MAXSIZE=$( - set -- ${maxsize##*:} - - height=${1%,} - width=$2 - - echo $height $width - ) - unset maxsize - fi - - # - # If using Xdialog(1), swap DIALOG_TITLE with DIALOG_BACKTITLE. - # The reason for this is because many dialog(1) applications use - # --backtitle for the program name (which is better suited as - # --title with Xdialog(1)). - # - if [ "$USE_XDIALOG" ]; then - _DIALOG_TITLE="$DIALOG_TITLE" - DIALOG_TITLE="$DIALOG_BACKTITLE" - DIALOG_BACKTITLE="$_DIALOG_TITLE" - unset _DIALOG_TITLE - fi -} - -############################################################ CLEAN-UP FUNCTIONS - -# f_clean_up -# -# Clean-up routines (run when script exits or is killed). -# -f_clean_up() -{ - f_quietly rm -f "$DIALOG_TMPDIR"/dialog.*.$$ -} - -############################################################ MAIN - -# -# Trap signals so we can recover gracefully -# -trap 'f_clean_up' EXIT - -fi # ! $_DIALOG_SUBR diff --git a/usr.sbin/bsdconfig/include/mustberoot.subr b/usr.sbin/bsdconfig/include/mustberoot.subr deleted file mode 100644 index c646530..0000000 --- a/usr.sbin/bsdconfig/include/mustberoot.subr +++ /dev/null @@ -1,360 +0,0 @@ -if [ ! "$_MUSTBEROOT_SUBR" ]; then _MUSTBEROOT_SUBR=1 -# -# Copyright (c) 2006-2012 Devin Teske -# All Rights Reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################ INCLUDES - -BSDCFG_LIBE="/usr/libexec/bsdconfig" -. $BSDCFG_LIBE/include/common.subr || exit 1 -f_include $BSDCFG_LIBE/include/dialog.subr -f_include_lang $BSDCFG_LIBE/include/messages.subr - -############################################################ CONFIGURATION -# NOTE: These are not able to be overridden/inherited for security purposes. - -# -# Number of tries a user gets to enter his/her password before we log the -# sudo(8) failure and exit. -# -PASSWD_TRIES=3 - -# -# While in SECURE mode, should authentication as `root' be allowed? Set to -# non-NULL to enable authentication as `root', otherwise disabled. -# -# WARNING: -# Unless using a custom sudo(8) configuration, user `root' should not be -# allowed because no password is required to become `root' when already `root' -# and therefore, any value entered as password will work. -# -SECURE_ALLOW_ROOT= - -# -# While in SECURE mode, should we divulge (through error message) when the -# requested authentication user does not exist? Set to non-NULL to enable, -# otherwise a non-existent user is treated like an invalid password. -# -SECURE_DIVULGE_UNKNOWN_USER= - -############################################################ FUNCTIONS - -# f_become_root_via_sudo -# -# If not running as root, prompt for sudo(8) credentials to become root. -# Re-execution of the current program via sudo is automatically handled. -# -# The following environment variables effect functionality: -# -# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate -# that Xdialog(1) should be used instead of dialog(1). -# -f_become_root_via_sudo() -{ - local msg hline size - - [ "$( id -u )" = "0" ] && return $SUCCESS - - f_have sudo || f_die 1 "$msg_must_be_root_to_execute" "$pgm" - - # - # Check sudo(8) access before prompting for password. - # - :| sudo -S -v 2> /dev/null - if [ $? -ne $SUCCESS ]; then - # - # sudo(8) access denied. Prompt for their password. - # - msg="$msg_please_enter_password" - hline="$hline_alnum_punc_tab_enter" - size=$( f_dialog_inputbox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$msg" \ - "$hline" ) - - # - # Continue prompting until they either Cancel, succeed - # or exceed the number of allowed failures. - # - local password nfailures=0 retval - while [ $nfailures -lt $PASSWD_TRIES ]; do - if [ "$USE_XDIALOG" ]; then - password=$( $DIALOG \ - --title "$DIALOG_TITLE" \ - --backtitle "$DIALOG_BACKTITLE" \ - --hline "$hline" \ - --ok-label "$msg_ok" \ - --cancel-label "$msg_cancel" \ - --password --inputbox "$msg" $size \ - 2>&1 > /dev/null ) - retval=$? - - # Catch X11-related errors - [ $retval -eq 255 ] && - f_die $retval "$password" - else - $DIALOG \ - --title "$DIALOG_TITLE" \ - --backtitle "$DIALOG_BACKTITLE" \ - --hline "$hline" \ - --ok-label "$msg_ok" \ - --cancel-label "$msg_cancel" \ - --insecure \ - --passwordbox "$msg" $size \ - 2> "$DIALOG_TMPDIR/dialog.inputbox.$$" - retval=$? - password=$( f_dialog_inputstr ) - fi - - # Exit if the user cancelled. - [ $retval -eq $SUCCESS ] || exit $retval - - # - # Validate sudo(8) credentials - # - sudo -S -v 2> /dev/null <<-EOF - $password - EOF - retval=$? - unset password # scrub memory - if [ $retval -eq $SUCCESS ]; then - # Access granted... - break - else - # Access denied... - nfailures=$(( $nfailures + 1 )) - - # introduce a short delay - if [ $nfailures -lt $PASSWD_TRIES ]; then - f_dialog_info "$msg_sorry_try_again" - sleep 1 - fi - fi - done - - # - # If user exhausted number of allowed password tries, log - # the security event and exit immediately. - # - if [ $nfailures -ge $PASSWD_TRIES ]; then - msg=$( printf "$msg_nfailed_attempts" "$nfailures" ) - logger -p auth.notice -t sudo " " \ - "$USER : $msg" \ - "; TTY=$(tty)" \ - "; PWD=$PWD" \ - "; USER=root" \ - "; COMMAND=$0" - f_die 1 "sudo: $msg" - fi - fi - - # Use xauth(1) to grant root the ability to use this X11/SSH session - if [ "$USE_XDIALOG" -a "$SSH_CONNECTION" -a "$DISPLAY" ]; then - f_have xauth || f_die 1 \ - "$msg_no_such_file_or_directory" "$pgm" "xauth" - local HOSTNAME displaynum - HOSTNAME=$(hostname) - displaynum="${DISPLAY#*:}" - xauth -f ~/.Xauthority extract - $HOSTNAME/unix:$displaynum \ - $HOSTNAME:$displaynum | sudo sh -c 'xauth -ivf \ - ~root/.Xauthority merge - > /dev/null 2>&1' - fi - - # Re-execute ourselves with sudo(8) - if [ $ARGC -gt 0 ]; then - exec sudo "$0" $ARGV - else - exec sudo "$0" - fi - exit $? # Never reached unless error -} - -# f_authenticate_some_user -# -# Only used if running as root and requires X11 (see USE_XDIALOG below). -# Prompts the user to enter a username and password to be authenticated via -# sudo(8) to proceed. -# -# The following environment variables effect functionality: -# -# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate -# that Xdialog(1) should be used instead of dialog(1). -# -f_authenticate_some_user() -{ - local msg hline size width height - - f_have sudo || f_die 1 "$msg_must_be_root_to_execute" "$pgm" - - # - # Secure-mode has been requested. - # - - [ "$USE_XDIALOG" ] || f_die 1 "$msg_secure_mode_requires_x11" - [ "$(id -u)" = "0" ] || f_die 1 "$msg_secure_mode_requires_root" - - # - # Prompt for sudo(8) credentials. - # - - msg="$msg_please_enter_username_password" - hline="$hline_alnum_punc_tab_enter" - size=$( f_xdialog_2inputsbox_size \ - "$DIALOG_TITLE" \ - "$DIALOG_BACKTITLE" \ - "$msg" \ - "$field_username" "" \ - "$field_password" "" ) - width="${size##*[$IFS]}" - height="${size%%[$IFS]*}" - height=$(( $height + 2 )) # Add height for --password - - # - # Continue prompting until they either Cancel, succeed or exceed the - # number of allowed failures. - # - local user_pass nfailures=0 retval - while [ $nfailures -lt $PASSWD_TRIES ]; do - user_pass=$( $DIALOG \ - --title "$DIALOG_TITLE" \ - --backtitle "$DIALOG_BACKTITLE" \ - --hline "$hline" \ - --ok-label "$msg_ok" \ - --cancel-label "$msg_cancel" \ - --password --2inputsbox "$msg" \ - $height $width \ - "$field_username" "" \ - "$field_password" "" \ - 2>&1 > /dev/null ) - retval=$? - - # Catch X11-related errors - [ $retval -eq 255 ] && f_die $retval "$user_pass" - - # Exit if the user cancelled. - [ $retval -eq $SUCCESS ] || exit $retval - - # - # Make sure the user exists and is non-root - # - local user password - user="${user_pass%%/*}" - password="${user_pass#*/}" - unset user_pass # scrub memory - if [ ! "$user" ]; then - nfailures=$(( $nfailures + 1 )) - f_dialog_msgbox "$msg_no_username" - continue - fi - if [ ! "$SECURE_ALLOW_ROOT" ]; then - case "$user" in - root|toor) - nfailures=$(( $nfailures + 1 )) - f_dialog_msgbox "$( printf \ - "$msg_user_disallowed" "$user" )" - continue - esac - fi - if ! f_quietly id "$user"; then - nfailures=$(( $nfailures + 1 )) - if [ "$SECURE_DIVULGE_UNKNOWN_USER" ]; then - f_dialog_msgbox "$( printf \ - "$msg_unknown_user" "$user" )" - elif [ $nfailures -lt $PASSWD_TRIES ]; then - f_dialog_info "$msg_sorry_try_again" - sleep 1 - fi - continue - fi - - # - # Validate sudo(8) credentials for given user - # - su -m "$user" <<-EOF - sh <<EOS - sudo -k - sudo -S -v 2> /dev/null <<EOP - $password - EOP - EOS - EOF - retval=$? - unset user - unset password # scrub memory - - if [ $retval -eq $SUCCESS ]; then - # Access granted... - break - else - # Access denied... - nfailures=$(( $nfailures + 1 )) - - # introduce a short delay - if [ $nfailures -lt $PASSWD_TRIES ]; then - f_dialog_info "$msg_sorry_try_again" - sleep 1 - fi - fi - done - - # - # If user exhausted number of allowed password tries, log - # the security event and exit immediately. - # - if [ $nfailures -ge $PASSWD_TRIES ]; then - msg=$( printf "$msg_nfailed_attempts" "$nfailures" ) - logger -p auth.notice -t sudo " " \ - "${SUDO_USER:-$USER} : $msg" \ - "; TTY=$(tty)" \ - "; PWD=$PWD" \ - "; USER=root" \ - "; COMMAND=$0" - f_die 1 "sudo: $message" - fi -} - -# f_mustberoot_init -# -# If not already root, make the switch to root by re-executing ourselves via -# sudo(8) using user-supplied credentials. -# -# The following environment variables effect functionality: -# -# SECURE Either NULL or Non-NULL. If given a value will indicate -# that (while running as root) sudo(8) authentication is -# required to proceed. -# -f_mustberoot_init() -{ - if [ "$(id -u)" != "0" -a ! "$SECURE" ]; then - f_become_root_via_sudo - elif [ "$SECURE" ]; then - f_authenticate_some_user - fi -} - -fi # ! $_MUSTBEROOT_SUBR diff --git a/usr.sbin/bsdconfig/include/strings.subr b/usr.sbin/bsdconfig/include/strings.subr deleted file mode 100644 index 1a330ad..0000000 --- a/usr.sbin/bsdconfig/include/strings.subr +++ /dev/null @@ -1,104 +0,0 @@ -if [ ! "$_STRINGS_SUBR" ]; then _STRINGS_SUBR=1 -# -# Copyright (c) 2006-2012 Devin Teske -# All Rights Reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ - -# f_substr "$string" $start [ $length ] -# -# Simple wrapper to awk(1)'s `substr' function. -# -f_substr() -{ - local string="$1" start="${2:-0}" len="${3:-0}" - echo "$string" | awk "{ print substr(\$0, $start, $len) }" -} - -# f_longest_line_length -# -# Simple wrapper to an awk(1) script to print the length of the longest line of -# input (read from stdin). Supports the newline escape-sequence `\n' for -# splitting a single line into multiple lines. -# -f_longest_line_length_awk=' -BEGIN { longest = 0 } -{ - if (split($0, lines, /\\n/) > 1) - { - for (n in lines) - { - len = length(lines[n]) - longest = ( len > longest ? len : longest ) - } - } - else - { - len = length($0) - longest = ( len > longest ? len : longest ) - } -} -END { print longest } -' -f_longest_line_length() -{ - awk "$f_longest_line_length_awk" -} - -# f_number_of_lines -# -# Simple wrapper to an awk(1) script to print the number of lines read from -# stdin. Supports newline escape-sequence `\n' for splitting a single line into -# multiple lines. -# -f_number_of_lines_awk=' -BEGIN { num_lines = 0 } -{ - num_lines += split($0, unused, /\\n/) -} -END { print num_lines } -' -f_number_of_lines() -{ - awk "$f_number_of_lines_awk" -} - -# f_isinteger $arg -# -# Returns true if argument is a positive/negative whole integer. -# -f_isinteger() -{ - local arg="$1" - - # Prevent division-by-zero - [ "$arg" = "0" ] && return $SUCCESS - - # Attempt to perform arithmetic divison (an operation which will exit - # with error unless arg is a valid positive/negative whole integer). - # - ( : $((0/$arg)) ) > /dev/null 2>&1 -} - -fi # ! $_STRINGS_SUBR diff --git a/usr.sbin/bsdconfig/include/sysrc.subr b/usr.sbin/bsdconfig/include/sysrc.subr deleted file mode 100644 index 52e57bc..0000000 --- a/usr.sbin/bsdconfig/include/sysrc.subr +++ /dev/null @@ -1,616 +0,0 @@ -if [ ! "$_SYSRC_SUBR" ]; then _SYSRC_SUBR=1 -# -# Copyright (c) 2006-2012 Devin Teske -# All Rights Reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################ INCLUDES - -BSDCFG_LIBE="/usr/libexec/bsdconfig" -. $BSDCFG_LIBE/include/common.subr || exit 1 -f_include_lang $BSDCFG_LIBE/include/messages.subr - -############################################################ CONFIGURATION - -# -# Standard pathnames (inherit values from shell if available) -# -: ${RC_DEFAULTS:="/etc/defaults/rc.conf"} - -############################################################ GLOBALS - -# -# Global exit status variables -# -SUCCESS=0 -FAILURE=1 - -############################################################ FUNCTIONS - -# f_clean_env [ --except $varname ... ] -# -# Unset all environment variables in the current scope. An optional list of -# arguments can be passed, indicating which variables to avoid unsetting; the -# `--except' is required to enable the exclusion-list as the remainder of -# positional arguments. -# -# Be careful not to call this in a shell that you still expect to perform -# $PATH expansion in, because this will blow $PATH away. This is best used -# within a sub-shell block "(...)" or "$(...)" or "`...`". -# -f_clean_env() -{ - local var arg except= - - # - # Should we process an exclusion-list? - # - if [ "$1" = "--except" ]; then - except=1 - shift 1 - fi - - # - # Loop over a list of variable names from set(1) built-in. - # - for var in $( set | awk -F= \ - '/^[[:alpha:]_][[:alnum:]_]*=/ {print $1}' \ - | grep -v '^except$' - ); do - # - # In POSIX bourne-shell, attempting to unset(1) OPTIND results - # in "unset: Illegal number:" and causes abrupt termination. - # - [ "$var" = OPTIND ] && continue - - # - # Process the exclusion-list? - # - if [ "$except" ]; then - for arg in "$@" ""; do - [ "$var" = "$arg" ] && break - done - [ "$arg" ] && continue - fi - - unset "$var" - done -} - -# f_sysrc_get $varname -# -# Get a system configuration setting from the collection of system- -# configuration files (in order: /etc/defaults/rc.conf /etc/rc.conf -# and /etc/rc.conf). -# -# NOTE: Additional shell parameter-expansion formats are supported. For -# example, passing an argument of "hostname%%.*" (properly quoted) will -# return the hostname up to (but not including) the first `.' (see sh(1), -# "Parameter Expansion" for more information on additional formats). -# -f_sysrc_get() -{ - # Sanity check - [ -f "$RC_DEFAULTS" -a -r "$RC_DEFAULTS" ] || return $FAILURE - - # Taint-check variable name - case "$1" in - [0-9]*) - # Don't expand possible positional parameters - return $FAILURE;; - *) - [ "$1" ] || return $FAILURE - esac - - ( # Execute within sub-shell to protect parent environment - - # - # Clear the environment of all variables, preventing the - # expansion of normals such as `PS1', `TERM', etc. - # - f_clean_env --except RC_CONFS RC_DEFAULTS SUCCESS - - . "$RC_DEFAULTS" > /dev/null 2>&1 - - unset RC_DEFAULTS - # no longer needed - - # - # If the query is for `rc_conf_files' then store the value that - # we inherited from sourcing RC_DEFAULTS (above) so that we may - # conditionally restore this value after source_rc_confs in the - # event that RC_CONFS does not customize the value. - # - if [ "$1" = "rc_conf_files" ]; then - _rc_conf_files="$rc_conf_files" - fi - - # - # If RC_CONFS is defined, set $rc_conf_files to an explicit - # value, modifying the default behavior of source_rc_confs(). - # - ( : ${RC_CONFS?} ) > /dev/null 2>&1 - if [ $? -eq ${SUCCESS:-0} ]; then - rc_conf_files="$RC_CONFS" - _rc_confs_set=1 - fi - - unset SUCCESS - # no longer needed - - source_rc_confs > /dev/null 2>&1 - - # - # If the query was for `rc_conf_files' AND after calling - # source_rc_confs the vaue has not changed, then we should - # restore the value to the one inherited from RC_DEFAULTS - # before performing the final query (preventing us from - # returning what was set via RC_CONFS when the intent was - # instead to query the value from the file(s) specified). - # - if [ "$1" = "rc_conf_files" -a \ - "$_rc_confs_set" -a \ - "$rc_conf_files" = "$RC_CONFS" \ - ]; then - rc_conf_files="$_rc_conf_files" - unset _rc_conf_files - unset _rc_confs_set - fi - - unset RC_CONFS - # no longer needed - - # - # This must be the last functional line for both the sub-shell - # and the function to preserve the return status from formats - # such as "${varname?}" and "${varname:?}" (see "Parameter - # Expansion" in sh(1) for more information). - # - eval echo '"${'"$1"'}"' 2> /dev/null - ) -} - -# f_sysrc_get_default $varname -# -# Get a system configuration default setting from the default rc.conf(5) file -# (or whatever RC_DEFAULTS points at). -# -f_sysrc_get_default() -{ - # Sanity check - [ -f "$RC_DEFAULTS" -a -r "$RC_DEFAULTS" ] || return $FAILURE - - # Taint-check variable name - case "$1" in - [0-9]*) - # Don't expand possible positional parameters - return $FAILURE;; - *) - [ "$1" ] || return $FAILURE - esac - - ( # Execute within sub-shell to protect parent environment - - # - # Clear the environment of all variables, preventing the - # expansion of normals such as `PS1', `TERM', etc. - # - f_clean_env --except RC_DEFAULTS - - . "$RC_DEFAULTS" > /dev/null 2>&1 - - unset RC_DEFAULTS - # no longer needed - - # - # This must be the last functional line for both the sub-shell - # and the function to preserve the return status from formats - # such as "${varname?}" and "${varname:?}" (see "Parameter - # Expansion" in sh(1) for more information). - # - eval echo '"${'"$1"'}"' 2> /dev/null - ) -} - -# f_sysrc_find $varname -# -# Find which file holds the effective last-assignment to a given variable -# within the rc.conf(5) file(s). -# -# If the variable is found in any of the rc.conf(5) files, the function prints -# the filename it was found in and then returns success. Otherwise output is -# NULL and the function returns with error status. -# -f_sysrc_find() -{ - local varname="$1" - local regex="^[[:space:]]*$varname=" - local rc_conf_files="$( f_sysrc_get rc_conf_files )" - local conf_files= - local file - - # Check parameters - [ "$varname" ] || return $FAILURE - - # - # If RC_CONFS is defined, set $rc_conf_files to an explicit - # value, modifying the default behavior of source_rc_confs(). - # - [ "$RC_CONFS" ] && rc_conf_files="$RC_CONFS" - - # - # Reverse the order of files in rc_conf_files (the boot process sources - # these in order, so we will search them in reverse-order to find the - # last-assignment -- the one that ultimately effects the environment). - # - for file in $rc_conf_files; do - conf_files="$file${conf_files:+ }$conf_files" - done - - # - # Append the defaults file (since directives in the defaults file - # indeed affect the boot process, we'll want to know when a directive - # is found there). - # - conf_files="$conf_files${conf_files:+ }$RC_DEFAULTS" - - # - # Find which file matches assignment to the given variable name. - # - for file in $conf_files; do - [ -f "$file" -a -r "$file" ] || continue - if grep -Eq "$regex" $file; then - echo $file - return $SUCCESS - fi - done - - return $FAILURE # Not found -} - -# f_sysrc_desc $varname -# -# Attempts to return the comments associated with varname from the rc.conf(5) -# defaults file `/etc/defaults/rc.conf' (or whatever RC_DEFAULTS points to). -# -# Multi-line comments are joined together. Results are NULL if no description -# could be found. -# -# This function is a two-parter. Below is the awk(1) portion of the function, -# afterward is the sh(1) function which utilizes the below awk script. -# -f_sysrc_desc_awk=' -# Variables that should be defined on the invocation line: -# -v varname="varname" -# -BEGIN { - regex = "^[[:space:]]*"varname"=" - found = 0 - buffer = "" -} -{ - if ( ! found ) - { - if ( ! match($0, regex) ) next - - found = 1 - sub(/^[^#]*(#[[:space:]]*)?/, "") - buffer = $0 - next - } - - if ( !/^[[:space:]]*#/ || - /^[[:space:]]*[[:alpha:]_][[:alnum:]_]*=/ || - /^[[:space:]]*#[[:alpha:]_][[:alnum:]_]*=/ || - /^[[:space:]]*$/ ) exit - - sub(/(.*#)*[[:space:]]*/, "") - buffer = buffer" "$0 -} -END { - # Clean up the buffer - sub(/^[[:space:]]*/, "", buffer) - sub(/[[:space:]]*$/, "", buffer) - - print buffer - exit ! found -} -' -f_sysrc_desc() -{ - awk -v varname="$1" "$f_sysrc_desc_awk" < "$RC_DEFAULTS" -} - -# f_sysrc_set $varname $new_value -# -# Change a setting in the system configuration files (edits the files in-place -# to change the value in the last assignment to the variable). If the variable -# does not appear in the source file, it is appended to the end of the primary -# system configuration file `/etc/rc.conf'. -# -# This function is a two-parter. Below is the awk(1) portion of the function, -# afterward is the sh(1) function which utilizes the below awk script. -# -f_sysrc_set_awk=' -# Variables that should be defined on the invocation line: -# -v varname="varname" -# -v new_value="new_value" -# -BEGIN { - regex = "^[[:space:]]*"varname"=" - found = retval = 0 -} -{ - # If already found... just spew - if ( found ) { print; next } - - # Does this line match an assignment to our variable? - if ( ! match($0, regex) ) { print; next } - - # Save important match information - found = 1 - matchlen = RSTART + RLENGTH - 1 - - # Store the value text for later munging - value = substr($0, matchlen + 1, length($0) - matchlen) - - # Store the first character of the value - t1 = t2 = substr(value, 0, 1) - - # Assignment w/ back-ticks, expression, or misc. - # We ignore these since we did not generate them - # - if ( t1 ~ /[`$\\]/ ) { retval = 1; print; next } - - # Assignment w/ single-quoted value - else if ( t1 == "'\''" ) { - sub(/^'\''[^'\'']*/, "", value) - if ( length(value) == 0 ) t2 = "" - sub(/^'\''/, "", value) - } - - # Assignment w/ double-quoted value - else if ( t1 == "\"" ) { - sub(/^"(.*\\\\+")*[^"]*/, "", value) - if ( length(value) == 0 ) t2 = "" - sub(/^"/, "", value) - } - - # Assignment w/ non-quoted value - else if ( t1 ~ /[^[:space:];]/ ) { - t1 = t2 = "\"" - sub(/^[^[:space:]]*/, "", value) - } - - # Null-assignment - else if ( t1 ~ /[[:space:];]/ ) { t1 = t2 = "\"" } - - printf "%s%c%s%c%s\n", substr($0, 0, matchlen), \ - t1, new_value, t2, value -} -END { exit retval } -' -f_sysrc_set() -{ - local varname="$1" new_value="$2" - - # Check arguments - [ "$varname" ] || return $FAILURE - - # - # Find which rc.conf(5) file contains the last-assignment - # - local not_found= - local file="$( f_sysrc_find "$varname" )" - if [ "$file" = "$RC_DEFAULTS" -o ! "$file" ]; then - # - # We either got a null response (not found) or the variable - # was only found in the rc.conf(5) defaults. In either case, - # let's instead modify the first file from $rc_conf_files. - # - - not_found=1 - - # - # If RC_CONFS is defined, use $RC_CONFS - # rather than $rc_conf_files. - # - if [ "$RC_CONFS" ]; then - file="${RC_CONFS%%[$IFS]*}" - else - file=$( f_sysrc_get rc_conf_files ) - file="${file%%[$IFS]*}" - fi - fi - - # - # If not found, append new value to last file and return. - # - if [ "$not_found" ]; then - echo "$varname=\"$new_value\"" >> "$file" - return $? - fi - - # - # Perform sanity checks. - # - if [ ! -w "$file" ]; then - f_err "$msg_cannot_create_permission_denied\n" \ - "$pgm" "$file" - return $FAILURE - fi - - # - # Create a new temporary file to write to. - # - local tmpfile="$( mktemp -t "$pgm" )" - [ "$tmpfile" ] || return $FAILURE - - # - # Fixup permissions (else we're in for a surprise, as mktemp(1) creates - # the temporary file with 0600 permissions, and if we simply mv(1) the - # temporary file over the destination, the destination will inherit the - # permissions from the temporary file). - # - local mode - mode=$( stat -f '%#Lp' "$file" 2> /dev/null ) - f_quietly chmod "${mode:-0644}" "$tmpfile" - - # - # Fixup ownership. The destination file _is_ writable (we tested - # earlier above). However, this will fail if we don't have sufficient - # permissions (so we throw stderr into the bit-bucket). - # - local owner - owner=$( stat -f '%u:%g' "$file" 2> /dev/null ) - f_quietly chown "${owner:-root:wheel}" "$tmpfile" - - # - # Operate on the matching file, replacing only the last occurrence. - # - local new_contents retval - new_contents=$( tail -r $file 2> /dev/null ) - new_contents=$( echo "$new_contents" | awk -v varname="$varname" \ - -v new_value="$new_value" "$f_sysrc_set_awk" ) - retval=$? - - # - # Write the temporary file contents. - # - echo "$new_contents" | tail -r > "$tmpfile" || return $FAILURE - if [ $retval -ne $SUCCESS ]; then - echo "$varname=\"$new_value\"" >> "$tmpfile" - fi - - # - # Taint-check our results. - # - if ! /bin/sh -n "$tmpfile"; then - f_err "$msg_previous_syntax_errors\n" "$pgm" "$file" - rm -f "$tmpfile" - return $FAILURE - fi - - # - # Finally, move the temporary file into place. - # - mv "$tmpfile" "$file" -} - -# f_sysrc_delete $varname -# -# Remove a setting from the system configuration files (edits files in-place). -# Deletes all assignments to the given variable in all config files. If the -# `-f file' option is passed, the removal is restricted to only those files -# specified, otherwise the system collection of rc_conf_files is used. -# -# This function is a two-parter. Below is the awk(1) portion of the function, -# afterward is the sh(1) function which utilizes the below awk script. -# -f_sysrc_delete_awk=' -# Variables that should be defined on the invocation line: -# -v varname="varname" -# -BEGIN { - regex = "^[[:space:]]*"varname"=" - found = 0 -} -{ - if ( $0 ~ regex ) - found = 1 - else - print -} -END { exit ! found } -' -f_sysrc_delete() -{ - local varname="$1" - local file - - # Check arguments - [ "$varname" ] || return $FAILURE - - # - # Operate on each of the specified files - # - for file in ${RC_CONFS:-$( f_sysrc_get rc_conf_files )}; do - [ -e "$file" ] || continue - - # - # Create a new temporary file to write to. - # - local tmpfile="$( mktemp -t "$pgm" )" - [ "$tmpfile" ] || return $FAILURE - - # - # Fixup permissions and ownership (mktemp(1) defaults to 0600 - # permissions) to instead match the destination file. - # - local mode owner - mode=$( stat -f '%#Lp' "$file" 2> /dev/null ) - owner=$( stat -f '%u:%g' "$file" 2> /dev/null ) - f_quietly chmod "${mode:-0644}" "$tmpfile" - f_quietly chown "${owner:-root:wheel}" "$tmpfile" - - # - # Operate on the file, removing all occurrences, saving the - # output in our temporary file. - # - awk -v varname="$varname" "$f_sysrc_delete_awk" "$file" \ - > "$tmpfile" - if [ $? -ne $SUCCESS ]; then - # The file didn't contain any assignments - rm -f "$tmpfile" - continue - fi - - # - # Taint-check our results. - # - if ! /bin/sh -n "$tmpfile"; then - f_err "$msg_previous_syntax_errors\n" \ - "$pgm" "$file" - rm -f "$tmpfile" - return $FAILURE - fi - - # - # Perform sanity checks - # - if [ ! -w "$file" ]; then - f_err "$msg_permission_denied\n" "$pgm" "$file" - rm -f "$tmpfile" - return $FAILURE - fi - - # - # Finally, move the temporary file into place. - # - mv "$tmpfile" "$file" - done -} - -fi # ! $_SYSRC_SUBR |