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