1#!/bin/sh
2#-
3# Copyright (c) 2012-2013 Devin Teske
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD$
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." "$0"
34f_include $BSDCFG_SHARE/dialog.subr
35f_include $BSDCFG_SHARE/mustberoot.subr
36f_include $BSDCFG_SHARE/sysrc.subr
37f_include $BSDCFG_SHARE/startup/rcconf.subr
38
39BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="140.startup"
40f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
41
42f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
43	pgm="${ipgm:-$pgm}"
44
45############################################################ GLOBALS
46
47#
48# Global map/menu-list for the main menu
49#
50RCCONF_MAP=
51_RCCONF_MAP=
52
53#
54# Options
55#
56# Inherit SHOW_DESC value if set, otherwise default to 1
57[ "${SHOW_DESC+set}" ] || SHOW_DESC=1
58# Selectively inherit SHOW_* value (in order of preference)
59if [ "$SHOW_DEFAULT_VALUE" ]; then
60	SHOW_DEFAULT_VALUE=1
61	SHOW_CONFIGURED=
62	SHOW_VALUE=
63elif [ "$SHOW_CONFIGURED" ]; then
64	SHOW_DEFAULT_VALUE=
65	SHOW_CONFIGURED=1
66	SHOW_VALUE=
67else
68	SHOW_DEFAULT_VALUE=
69	SHOW_CONFIGURED=
70	SHOW_VALUE=1
71fi
72
73############################################################ FUNCTIONS
74
75# dialog_menu_main
76#
77# Display the dialog(1)-based application main menu.
78#
79dialog_menu_main()
80{
81	local prompt=
82	local menu_list="
83		'X $msg_exit'    '$msg_exit_desc'
84		                  ${SHOW_DESC:+'$msg_exit_this_menu'}
85		'> $msg_add_new' '$msg_add_new_desc'
86		                  ${SHOW_DESC:+'$msg_add_new_help'}
87		'> $msg_delete'  '$msg_delete_desc'
88		                  ${SHOW_DESC:+'$msg_delete_help'}
89	${USE_XDIALOG:+
90		'> $msg_view_details' '$msg_view_details_desc'
91		                       ${SHOW_DESC:+'$msg_view_details_help'}
92	}
93	" # END-QUOTE
94	local defaultitem= # Calculated below
95	local hline="$hline_arrows_tab_enter"
96
97	if [ ! "$_RCCONF_MAP" ]; then
98		# Genreate RCCONF_MAP of `var desc ...' per-line
99		f_dialog_info "$msg_creating_rcconf_map"
100		f_startup_rcconf_map RCCONF_MAP
101		export RCCONF_MAP
102		# Generate _${var}_desc variables from $RCCONF_MAP
103		f_startup_rcconf_map_expand RCCONF_MAP
104		export _RCCONF_MAP=1
105	fi
106
107	# Show infobox for modes that take a while to calculate/display
108	[ "$SHOW_DEFAULT_VALUE" -o "$SHOW_CONFIGURED" ] &&
109		f_dialog_info "$msg_creating_menu_list"
110
111	menu_list="$menu_list $(
112		. "$RC_DEFAULTS" > /dev/null
113		source_rc_confs > /dev/null
114		var_list=$( f_startup_rcconf_list )
115		for var in $var_list; do
116			eval export $var
117			[ "$SHOW_DEFAULT_VALUE" ] && export \
118				_${var}_default="$( f_sysrc_get_default $var )"
119			[ "$SHOW_CONFIGURED" ] && export \
120				_${var}_file="$( f_sysrc_find $var )"
121		done
122		export SHOW_VALUE SHOW_DESC SHOW_DEFAULT_VALUE SHOW_CONFIGURED
123		export msg_default_value
124		echo "$var_list" | awk '
125		BEGIN {
126			prefix = ""
127		}
128		{
129			cur_prefix = tolower(substr($1, 1, 1))
130			printf "'\''"
131			if ( prefix != cur_prefix )
132				prefix = cur_prefix
133			else
134				printf " "
135			var = $1
136			printf "%s'\'' '\''", var
137			if ( ENVIRON["SHOW_DEFAULT_VALUE"] ) {
138				default = ENVIRON["_" var "_default"]
139				gsub(/'\''/, "'\''\\'\'\''", default)
140				value = ENVIRON[var]
141				gsub(/'\''/, "'\''\\'\'\''", value)
142				printf ENVIRON["msg_default_value"] "; %s",
143				       default, value
144			} else if ( ENVIRON["SHOW_CONFIGURED"] ) {
145				printf "%s", ENVIRON["_" var "_file"]
146			} else { # SHOW_VALUE (default behavior)
147				value = ENVIRON[var]
148				gsub(/'\''/, "'\''\\'\'\''", value)
149				printf "%s", value
150			}
151			printf "'\''"
152			if ( ENVIRON["SHOW_DESC"] ) {
153				desc = ENVIRON["_" var "_desc"]
154				gsub(/'\''/, "'\''\\'\'\''", desc)
155				printf " '\''%s'\''", desc
156			}
157			printf "\n"
158		}'
159	)"
160
161	set -f # set noglob because descriptions in the $menu_list may contain
162	       # `*' and get expanded by dialog(1) (doesn't affect Xdialog(1)).
163	       # This prevents dialog(1) from expanding wildcards in help line.
164
165	local height width rows
166	eval f_dialog_menu${SHOW_DESC:+_with_help}_size \
167		height width rows      \
168		\"\$DIALOG_TITLE\"     \
169		\"\$DIALOG_BACKTITLE\" \
170		\"\$prompt\"           \
171		\"\$hline\"            \
172		$menu_list
173
174	# Obtain default-item from previously stored selection
175	f_dialog_default_fetch defaultitem
176
177	local menu_choice
178	menu_choice=$( eval $DIALOG \
179		--title \"\$DIALOG_TITLE\"         \
180		--backtitle \"\$DIALOG_BACKTITLE\" \
181		--hline \"\$hline\"                \
182		--ok-label \"\$msg_ok\"            \
183		--cancel-label \"\$msg_cancel\"    \
184		--help-button                      \
185		--help-label \"\$msg_details\"     \
186		${SHOW_DESC:+--item-help}          \
187		--default-item \"\$defaultitem\"   \
188		--menu \"\$prompt\"                \
189		$height $width $rows               \
190		$menu_list                         \
191		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
192	)
193	local retval=$?
194	f_dialog_data_sanitize menu_choice
195	f_dialog_menutag_store "$menu_choice"
196
197	# Only update default-item on success
198	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
199
200	return $retval
201}
202
203############################################################ MAIN
204
205# Incorporate rc-file if it exists
206[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
207
208#
209# Process command-line arguments
210#
211while getopts h$GETOPTS_STDARGS flag; do
212	case "$flag" in
213	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
214	esac
215done
216shift $(( $OPTIND - 1 ))
217
218#
219# Initialize
220#
221f_dialog_title "$msg_view_edit_startup_configuration"
222f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
223f_mustberoot_init
224
225#
226# Launch application main menu
227#
228while :; do
229	dialog_menu_main
230	retval=$?
231	f_dialog_menutag_fetch mtag
232
233	if [ "$USE_XDIALOG" ]; then
234		case "$mtag" in
235		"> $msg_view_details")
236			f_dialog_input_view_details
237			continue
238		esac
239	elif [ $retval -eq $DIALOG_HELP ]; then
240		# The ``Help'' button (labeled "Details") was pressed
241		f_dialog_input_view_details
242		continue
243	fi
244
245	[ $retval -eq $DIALOG_OK ] || f_die
246
247	case "$mtag" in
248	"X $msg_exit") break ;;
249	"> $msg_add_new") $BSDCFG_LIBE/$APP_DIR/rcadd ${USE_XDIALOG:+-X} ;;
250	"> $msg_delete")
251		# rcdelete has a similar interface that can inherit the below:
252		export SHOW_VALUE SHOW_DESC SHOW_DEFAULT_VALUE SHOW_CONFIGURED
253		$BSDCFG_LIBE/$APP_DIR/rcdelete ${USE_XDIALOG:+-X}
254		;;
255	*) # Anything else is a variable to edit
256		$BSDCFG_LIBE/$APP_DIR/rcedit ${USE_XDIALOG:+-X} "${mtag# }"
257	esac
258done
259
260exit $SUCCESS
261
262################################################################################
263# END
264################################################################################
265