a bug in which certain combinations of arguments produced unexpected results such as `-dX' (now properly produces debugging and X11), `-XS' (now properly produces X11 in secure mode), `-df-' (enables debugging when reading a script from standard-input, etc. Multi-word variations such as `-d -X', `-X -S', `-d -f-', `-d -f -', etc. also work as expected. Also tested were variations in argument order, which are now working as expected.
336 lines
8.6 KiB
Bash
Executable File
336 lines
8.6 KiB
Bash
Executable File
#!/bin/sh
|
|
#-
|
|
# Copyright (c) 2012 Ron McDowell
|
|
# Copyright (c) 2012-2013 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$
|
|
#
|
|
############################################################ INCLUDES
|
|
|
|
BSDCFG_SHARE="/usr/share/bsdconfig"
|
|
. $BSDCFG_SHARE/common.subr || exit 1
|
|
f_dprintf "%s: loading includes..." "$0"
|
|
f_include $BSDCFG_SHARE/dialog.subr
|
|
f_include $BSDCFG_SHARE/mustberoot.subr
|
|
f_include $BSDCFG_SHARE/strings.subr
|
|
|
|
BSDCFG_LIBE="/usr/libexec/bsdconfig"
|
|
f_include_lang $BSDCFG_LIBE/include/messages.subr
|
|
|
|
BSDCONFIG_HELPFILE=$BSDCFG_LIBE/include/bsdconfig.hlp
|
|
USAGE_HELPFILE=$BSDCFG_LIBE/include/usage.hlp
|
|
|
|
############################################################ FUNCTIONS
|
|
|
|
# usage
|
|
#
|
|
# display usage and exit
|
|
#
|
|
usage()
|
|
{
|
|
local index="INDEX" cmd_list=""
|
|
|
|
cd $BSDCFG_LIBE
|
|
# No need to preserve CWD (headed toward exit)
|
|
|
|
# Test for language-specific indices
|
|
f_quietly ls */"$index.${LANG:-$LC_ALL}" &&
|
|
index="$index.${LANG:-$LC_ALL}"
|
|
|
|
cmd_list=$(
|
|
awk '/^menu_selection="/ {
|
|
sub(/\|.*/, "")
|
|
sub(/^menu_selection="/, "")
|
|
print
|
|
}' */$index | sort
|
|
)
|
|
|
|
#
|
|
# Determine the longest command-length (in characters)
|
|
#
|
|
local longest_cmd
|
|
longest_cmd=$( echo "$cmd_list" | f_longest_line_length )
|
|
f_dprintf "longest_cmd=[%s]" "$longest_cmd"
|
|
|
|
#
|
|
# Determine the maximum width of terminal/console
|
|
#
|
|
local max_size max_width
|
|
max_size=$( stty size 2> /dev/null )
|
|
: ${max_size:="24 80"}
|
|
max_width="${max_size#*[$IFS]}"
|
|
f_dprintf "max_width=[%s]" "$max_width"
|
|
|
|
#
|
|
# Using the longest command-length as the width of a single column,
|
|
# determine if we can use more than one column to display commands.
|
|
#
|
|
local x=$longest_cmd ncols=1
|
|
x=$(( $x + 8 )) # Accomodate leading tab character
|
|
x=$(( $x + 3 + $longest_cmd )) # Preload end of next column
|
|
while [ $x -lt $max_width ]; do
|
|
ncols=$(( $ncols + 1 ))
|
|
x=$(( $x + 3 + $longest_cmd ))
|
|
done
|
|
f_dprintf "ncols=[%u] x=[%u]" $ncols $x
|
|
|
|
#
|
|
# Re-format the command-list into multiple columns
|
|
#
|
|
cmd_list=$( eval "$( echo "$cmd_list" |
|
|
awk -v ncols=$ncols -v size=$longest_cmd '
|
|
BEGIN {
|
|
n = 0
|
|
row_item[1] = ""
|
|
}
|
|
function print_row()
|
|
{
|
|
fmt = "printf \"\\t%-" size "s"
|
|
for (i = 1; i < cur_col; i++)
|
|
fmt = fmt " %-" size "s"
|
|
fmt = fmt "\\n\""
|
|
printf "%s", fmt
|
|
for (i = 1; i <= cur_col; i++)
|
|
printf " \"%s\"", row_item[i]
|
|
print ""
|
|
}
|
|
{
|
|
n++
|
|
cur_col = (( n - 1 ) % ncols ) + 1
|
|
printf "f_dprintf \"row_item[%u]=[%%s]\" \"%s\"\n",
|
|
cur_col, $0
|
|
row_item[cur_col] = $0
|
|
if ( cur_col == ncols ) print_row()
|
|
}
|
|
END {
|
|
if ( cur_col < ncols ) print_row()
|
|
}' )"
|
|
)
|
|
|
|
f_usage $BSDCFG_LIBE/USAGE \
|
|
"PROGRAM_NAME" "$pgm" \
|
|
"COMMAND_LIST" "$cmd_list"
|
|
|
|
# Never reached
|
|
}
|
|
|
|
# dialog_menu_main
|
|
#
|
|
# Display the dialog(1)-based application main menu.
|
|
#
|
|
dialog_menu_main()
|
|
{
|
|
local title="$DIALOG_TITLE"
|
|
local btitle="$DIALOG_BACKTITLE"
|
|
local prompt="$msg_menu_text"
|
|
local menu_list size
|
|
|
|
menu_list="
|
|
'X' '$msg_exit' '$msg_exit_bsdconfig'
|
|
'1' '$msg_usage' '$msg_quick_start_how_to_use_this_menu_system'
|
|
" # END-QUOTE
|
|
|
|
local sanitize_awk="{ gsub(/'/, \"'\\\\''\"); print }"
|
|
|
|
local menuitem menu_title menu_help menu_selection index=2
|
|
for menuitem in $( cd $BSDCFG_LIBE && ls -d [0-9][0-9][0-9].* ); do
|
|
[ $index -lt ${#DIALOG_MENU_TAGS} ] || break
|
|
tag=$( f_substr "$DIALOG_MENU_TAGS" $index 1 )
|
|
|
|
menu_program=
|
|
menu_title=
|
|
menu_help=
|
|
f_include_lang $BSDCFG_LIBE/$menuitem/INDEX
|
|
[ "$menu_program" ] || continue
|
|
|
|
case "$menu_program" in
|
|
/*) : already fully qualified ;;
|
|
*)
|
|
menu_program="$menuitem/$menu_program"
|
|
esac
|
|
|
|
menu_title=$( echo "$menu_title" | awk "$sanitize_awk" )
|
|
menu_help=$( echo "$menu_help" | awk "$sanitize_awk" )
|
|
setvar "menu_program$tag" "$menu_program"
|
|
menu_list="$menu_list '$tag' '$menu_title' '$menu_help'"
|
|
|
|
index=$(( $index + 1 ))
|
|
done
|
|
|
|
size=$( eval f_dialog_menu_with_help_size \
|
|
\"\$title\" \
|
|
\"\$btitle\" \
|
|
\"\$prompt\" \
|
|
\"\" \
|
|
$menu_list )
|
|
|
|
local dialog_menu
|
|
dialog_menu=$( eval $DIALOG \
|
|
--clear \
|
|
--title \"\$title\" \
|
|
--backtitle \"\$btitle\" \
|
|
--item-help \
|
|
--ok-label \"\$msg_ok\" \
|
|
--cancel-label \"\$msg_exit_bsdconfig\" \
|
|
--help-button \
|
|
--help-label \"\$msg_help\" \
|
|
${USE_XDIALOG:+--help \"\"} \
|
|
--default-item \"\$DEFAULTITEM_$$\" \
|
|
--menu \"\$prompt\" $size $menu_list \
|
|
2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
|
|
)
|
|
local retval=$?
|
|
setvar DIALOG_MENU_$$ "$dialog_menu"
|
|
|
|
# Only update default-item on success
|
|
[ $retval -eq 0 ] && setvar DEFAULTITEM_$$ "$dialog_menu"
|
|
|
|
return $retval
|
|
}
|
|
|
|
############################################################ MAIN
|
|
|
|
#
|
|
# If $0 is not "bsdconfig", interpret it either as a keyword to a menuitem or
|
|
# as a valid resword (see script.subr for additional details about reswords).
|
|
#
|
|
if [ "$pgm" != "bsdconfig" ]; then
|
|
if indexfile=$( f_index_file "$pgm" ) &&
|
|
cmd=$( f_index_menusel_command "$indexfile" "$pgm" )
|
|
then
|
|
f_dprintf "pgm=[%s] indexfile=[%s] cmd=[%s]" \
|
|
"$pgm" "$indexfile" "$cmd"
|
|
exec "$cmd" "$@" || exit 1
|
|
else
|
|
f_include $BSDCFG_SHARE/script.subr
|
|
for resword in $RESWORDS; do
|
|
[ "$pgm" = "$resword" ] || continue
|
|
# Found a match
|
|
f_dprintf "pgm=[%s] A valid resWord!" "$pgm"
|
|
f_dispatch $resword
|
|
exit $?
|
|
done
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Process command-line arguments
|
|
#
|
|
scripts_loaded=0
|
|
while getopts f:h$GETOPTS_STDARGS flag; do
|
|
case "$flag" in
|
|
f) [ $scripts_loaded -eq 0 ] && f_include $BSDCFG_SHARE/script.subr
|
|
f_script_load "$OPTARG"
|
|
scripts_loaded=$(( $scripts_loaded + 1 ));;
|
|
h|\?) usage;;
|
|
esac
|
|
done
|
|
shift $(( $OPTIND -1 ))
|
|
|
|
# If we've loaded any scripts, do not continue any further
|
|
[ $scripts_loaded -gt 0 ] && exit
|
|
|
|
#
|
|
# Initialize
|
|
#
|
|
f_dialog_title "$msg_main_menu"
|
|
|
|
[ "$SECURE" ] && f_mustberoot_init
|
|
|
|
# Incorporate rc-file if it exists
|
|
[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
|
|
|
|
#
|
|
# If a non-option argument was passed, process it as a menuitem selection...
|
|
#
|
|
if [ "$1" ]; then
|
|
#
|
|
# ...unless it's a long-option for usage.
|
|
#
|
|
case "$1" in
|
|
-help|--help|-\?) usage;;
|
|
esac
|
|
|
|
#
|
|
# Find the INDEX (possibly i18n) claiming this keyword and get the
|
|
# command to execute from the menu_selection line.
|
|
#
|
|
if ! { indexfile=$( f_index_file "$1" ) &&
|
|
cmd=$( f_index_menusel_command "$indexfile" "$1" )
|
|
}; then
|
|
# no matches, display usage (which shows valid keywords)
|
|
f_err "%s: %s: $msg_not_found\n" "$pgm" "$1"
|
|
usage
|
|
fi
|
|
|
|
shift
|
|
exec $cmd ${USE_XDIALOG:+-X} "$@" || exit 1
|
|
fi
|
|
|
|
#
|
|
# Launch application main menu
|
|
#
|
|
while :; do
|
|
dialog_menu_main
|
|
retval=$?
|
|
mtag=$( f_dialog_menutag )
|
|
f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
|
|
|
|
if [ $retval -eq 2 ]; then
|
|
# The Help button was pressed
|
|
f_show_help "$BSDCONFIG_HELPFILE"
|
|
continue
|
|
elif [ $retval -ne 0 ]; then
|
|
f_die
|
|
fi
|
|
|
|
case "$mtag" in
|
|
X) # Exit
|
|
break
|
|
;;
|
|
|
|
1) # Usage
|
|
f_show_help "$USAGE_HELPFILE"
|
|
continue
|
|
;;
|
|
|
|
*) # Dynamically loaded menuitem
|
|
f_getvar menu_program$mtag menu_program
|
|
case "$menu_program" in
|
|
/*) cmd="$menu_program";;
|
|
*) cmd="$BSDCFG_LIBE/$menu_program"
|
|
esac
|
|
f_dprintf "cmd=[%s]" "$cmd"
|
|
$cmd ${USE_XDIALOG:+-X}
|
|
|
|
esac
|
|
done
|
|
|
|
exit $SUCCESS
|
|
|
|
################################################################################
|
|
# END
|
|
################################################################################
|