xref: /freebsd/usr.sbin/bsdconfig/startup/rcdelete (revision c243e4902be8df1e643c76b5f18b68bb77cc5268)
1#!/bin/sh
2#-
3# Copyright (c) 2012 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 (INLUDING, 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_LIBE="/usr/libexec/bsdconfig"
32. $BSDCFG_LIBE/include/common.subr || exit 1
33f_include $BSDCFG_LIBE/include/dialog.subr
34f_include $BSDCFG_LIBE/include/mustberoot.subr
35f_include $BSDCFG_LIBE/include/sysrc.subr
36
37APP_DIR="140.startup"
38f_include $BSDCFG_LIBE/$APP_DIR/include/rcconf.subr
39f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
40
41ipgm=$( f_index_menu_selection $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" )
42[ $? -eq $SUCCESS -a "$ipgm" ] && pgm="$ipgm"
43
44############################################################ GLOBALS
45
46#
47# Global map/menu-list for the main menu
48#
49RCCONF_MAP=
50_RCCONF_MAP=
51RCCONF_MENU_LIST=
52
53#
54# Options
55#
56# Inherit SHOW_DESC value if set, otherwise default to 1
57( : ${SHOW_DESC?} ) > /dev/null 2>&1 || 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 size
82	local hline="$hline_arrows_tab_enter"
83	local prompt=""
84
85	RCCONF_MENU_LIST="
86		'X $msg_exit_cancel'     '$msg_exit_cancel_desc'
87		            ${SHOW_DESC:+'$msg_exit_cancel_help'}
88		'> $msg_delete_selected' '$msg_delete_selected_desc'
89		            ${SHOW_DESC:+'$msg_delete_selected_help'}
90		'> $msg_all'             '$msg_all_desc'
91		            ${SHOW_DESC:+'$msg_all_help'}
92		'> $msg_none'            '$msg_none_desc'
93		            ${SHOW_DESC:+'$msg_none_help'}
94	${USE_XDIALOG:+
95		'> $msg_view_details' '$msg_view_details_desc'
96		                       ${SHOW_DESC:+'$msg_view_details_help'}
97	}
98	" # END-QUOTE
99
100	if [ ! "$_RCCONF_MAP" ]; then
101		# Genreate RCCONF_MAP of `var desc ...' per-line
102		f_dialog_info "$msg_creating_rcconf_map"
103		RCCONF_MAP=$( f_startup_rcconf_map )
104		export RCCONF_MAP
105		# Generate _${var}_desc variables from $RCCONF_MAP
106		f_startup_rcconf_map_expand
107		export _RCCONF_MAP=1
108	fi
109
110	# Show infobox for modes that take a while to calculate/display
111	[ "$SHOW_DEFAULT_VALUE" -o "$SHOW_CONFIGURED" ] &&
112		f_dialog_info "$msg_creating_menu_list"
113
114	RCCONF_MENU_LIST="$RCCONF_MENU_LIST $(
115		. "$RC_DEFAULTS" > /dev/null
116		source_rc_confs > /dev/null
117		var_list=$( f_startup_rcconf_list )
118		for var in $var_list; do
119			eval export $var
120			[ "$SHOW_DEFAULT_VALUE" ] && export \
121				_${var}_default="$( f_sysrc_get_default $var )"
122			[ "$SHOW_CONFIGURED" ] && export \
123				_${var}_file="$( f_sysrc_find $var )"
124		done
125		export SHOW_VALUE SHOW_DESC SHOW_DEFAULT_VALUE SHOW_CONFIGURED
126		export msg_default_value
127		echo "$var_list" | awk '
128		BEGIN {
129			prefix = ""
130		}
131		{
132			cur_prefix = tolower(substr($1, 1, 1))
133			printf "'\''"
134			if ( prefix != cur_prefix )
135				prefix = cur_prefix
136			else
137				printf " "
138			var = $1
139			printf "%s'\'' '\''[", var
140			if ( ENVIRON["_" var "_delete"] )
141				printf "X"
142			else
143				printf " "
144			printf "] "
145			if ( ENVIRON["SHOW_DEFAULT_VALUE"] ) {
146				default = ENVIRON["_" var "_default"]
147				gsub(/'\''/, "'\''\\'\'\''", default)
148				value = ENVIRON[var]
149				gsub(/'\''/, "'\''\\'\'\''", value)
150				printf ENVIRON["msg_default_value"] "; %s",
151				       default, value
152			} else if ( ENVIRON["SHOW_CONFIGURED"] ) {
153				printf "%s", ENVIRON["_" var "_file"]
154			} else { # SHOW_VALUE (default behavior)
155				value = ENVIRON[var]
156				gsub(/'\''/, "'\''\\'\'\''", value)
157				printf "%s", value
158			}
159			printf "'\''"
160			if ( ENVIRON["SHOW_DESC"] ) {
161				desc = ENVIRON["_" var "_desc"]
162				gsub(/'\''/, "'\''\\'\'\''", desc)
163				printf " '\''%s'\''", desc
164			}
165			printf "\n"
166		}'
167	)"
168
169	set -f # noglob
170
171	size=$( eval f_dialog_menu_${SHOW_DESC:+with_help_}size \
172	        	\"\$DIALOG_TITLE\"     \
173	        	\"\$DIALOG_BACKTITLE\" \
174	                \"\$prompt\"           \
175	        	\"\$hline\"            \
176	        	$RCCONF_MENU_LIST      )
177
178	eval $DIALOG \
179		--clear --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		--menu \"\$prompt\" $size          \
188		$RCCONF_MENU_LIST                  \
189		2> "$DIALOG_TMPDIR/dialog.menu.$$"
190}
191
192# dialog_menu_delete $var1 [$var2 ...]
193#
194# Get the user's blessing to delete one or more variables.
195# if (and only-if) the user confirms (does not press ESC or Cancel/NO).
196#
197dialog_menu_delete()
198{
199	local size
200	local hline="$hline_arrows_tab_enter"
201	local prompt="$msg_are_you_sure_you_want_delete_the_following"
202	local var_list menu_list
203
204	[ $# -ge 1 ] || return $FAILURE
205
206	if [ $# -eq 1 ]; then
207		msg=$( printf "$msg_are_you_sure_you_want_to_delete" \
208		              "$delete_vars" )
209		f_dialog_noyes "$msg"
210		return $?
211	fi
212
213	var_list=$( for var in $*; do echo "$var"; done | sort -u )
214	menu_list=$(
215		. "$RC_DEFAULTS"
216		source_rc_confs
217		echo "$var_list" | awk '
218		BEGIN {
219			prefix = ""
220		}
221		{
222			cur_prefix = tolower(substr($1, 1, 1))
223			printf "'\''"
224			if ( prefix != cur_prefix )
225				prefix = cur_prefix
226			else
227				printf " "
228			var = $1
229			printf "%s'\'' '\'\''\n", var
230		}'
231	)
232
233	size=$( eval f_dialog_menu_size \
234	        	\"\$DIALOG_TITLE\"     \
235	        	\"\$DIALOG_BACKTITLE\" \
236	                \"\$prompt\"           \
237	        	\"\$hline\"            \
238	        	$menu_list             )
239
240	local defaultno="defaultno"
241	[ "$USE_XDIALOG" ] && defaultno="default-no"
242
243	eval $DIALOG \
244		--clear --title \"\$DIALOG_TITLE\" \
245		--backtitle \"\$DIALOG_BACKTITLE\" \
246		--hline \"\$hline\"                \
247		--$defaultno                       \
248		--ok-label \"\$msg_ok\"            \
249		--cancel-label \"\$msg_cancel\"    \
250		--menu \"\$prompt\" $size          \
251		$menu_list                         \
252		2> "$DIALOG_TMPDIR/dialog.menu.$$"
253}
254
255############################################################ MAIN
256
257# Incorporate rc-file if it exists
258[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
259
260#
261# Process command-line arguments
262#
263while getopts hSX flag; do
264	case "$flag" in
265	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm";;
266	esac
267done
268shift $(( $OPTIND - 1 ))
269
270#
271# Initialize
272#
273f_dialog_init
274f_dialog_title "$msg_delete_startup_directives"
275f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
276f_mustberoot_init
277
278while :; do
279	dialog_menu_main
280	retval=$?
281	mtag=$( f_dialog_menutag )
282
283	if [ "$USE_XDIALOG" ]; then
284		case "$mtag" in
285		"> $msg_view_details")
286			f_dialog_input_view_details
287			continue
288		esac
289	elif [ $retval -eq 2 ]; then
290		# The ``Help'' button (labeled "Details") was pressed
291		f_dialog_input_view_details
292		continue
293	fi
294
295	[ $retval -eq 0 ] || f_die
296
297	case "$mtag" in
298	"X $msg_exit_cancel") break ;;
299	"> $msg_delete_selected")
300		delete_vars=
301		for var in $( f_startup_rcconf_list ); do
302			[ "$( eval echo \$_${var}_delete )" ] || continue
303			delete_vars="$delete_vars${delete_vars:+ }$var"
304		done
305		unset var # no longer needed
306		if dialog_menu_delete $delete_vars; then
307			f_dialog_title "$msg_info"
308			f_dialog_info "$msg_deleting_selected_directives"
309			f_dialog_title_restore
310			for var in $delete_vars; do
311				err=$( f_sysrc_delete $var 2>&1 )
312				if [ $? -ne $SUCCESS ]; then
313					f_show_msg "%s\n" "$err"
314					break
315				fi
316			done
317			unset var # no longer needed
318		fi
319		;;
320	"> $msg_all")
321		for var in $( f_startup_rcconf_list ); do
322			setvar _${var}_delete 1
323			export _${var}_delete
324		done
325		unset var # no longer needed
326		;;
327	"> $msg_none")
328		var_list=$( set | awk -F= "
329			/$STARTUP_RCCONF_REGEX/ {
330				if (\$1 ~ /^_[[:alpha:]_][[:alnum:]_]*_delete/)
331					print \$1
332			}"
333		)
334		[ "$var_list" ] && unset $var_list
335		unset var_list # no longer needed
336		;;
337	*) # Anything else is a variable to edit
338		var="${mtag# }"
339
340		# Toggle the state-variable and loop back to menu
341		if ( eval : \${_${var}_delete?} ) > /dev/null 2>&1; then
342			unset _${var}_delete
343		else
344			setvar _${var}_delete 1
345			export _${var}_delete
346		fi
347		unset var # no longer needed
348	esac
349done
350
351exit $SUCCESS
352
353################################################################################
354# END
355################################################################################
356