Index: etc/rc.d/bootconf.sh
===================================================================
RCS file: /cvsroot/src/etc/rc.d/bootconf.sh,v
retrieving revision 1.9
diff -u -p -r1.9 bootconf.sh
--- etc/rc.d/bootconf.sh	23 Apr 2006 23:26:26 -0000	1.9
+++ etc/rc.d/bootconf.sh	3 May 2010 15:35:00 -0000
@@ -1,71 +1,48 @@
 #!/bin/sh
 #
-# $NetBSD: bootconf.sh,v 1.9 2006/04/23 23:26:26 hubertf Exp $
+# $NetBSD: bootconf.sh,v 1.12 2009/09/11 18:17:43 apb Exp $
 #
 
 # PROVIDE: bootconf
 # REQUIRE: mountcritlocal
+# KEYWORD: interactive
+
+$_rc_subr_loaded . /etc/rc.subr
+
+name="bootconf"
+start_cmd="bootconf_start"
+stop_cmd=":"
+
+# Refer to newbtconf(8) for more information.
 
 bootconf_start()
 {
-		# Refer to newbtconf(8) for more information
-		#
+	local def= default='current'
 
-	if [ ! -e /etc/etc.current ]; then
-		return 0
-	fi
+	[ -h /etc/etc.current ] || return 0
+
+	# check for default boot-up configuration
 	if [ -h /etc/etc.default ]; then
-		def=$(ls -ld /etc/etc.default 2>&1)
-		default="${def##*-> *etc.}"
-	else
-		default=current
+		def=$(/bin/ls -ld /etc/etc.default 2>&1)
+		default="${def#*-> *etc.}"
 	fi
-	if [ "$default" = "current" ]; then
-		def=$(ls -ld /etc/etc.current 2>&1)
-		default="${def##*-> *etc.}"
+
+	if [ "$default" = 'current' ]; then
+		# use most recently used boot-up configuration
+		def=$(/bin/ls -ld /etc/etc.current 2>&1)
+		default="${def#*-> *etc.}"
 	fi
+	conf="$default"
 
-	spc=""
-	for i in /etc/etc.*; do
-		name="${i##/etc/etc.}"
-		case $name in
-		current|default|\*)
-			continue
-			;;	
-		*)
-			if [ "$name" = "$default" ]; then
-				echo -n "${spc}[${name}]"
-			else
-				echo -n "${spc}${name}"
-			fi
-			spc=" "
-			;;
-		esac
-	done
-	echo
-	master=$$
-	_DUMMY=/etc/passwd
-	conf=${_DUMMY}
-	while [ ! -d /etc/etc.$conf/. ]; do
-		trap "conf=$default; echo; echo Using default of $default" ALRM
-		echo -n "Which configuration [$default] ? "
-		(sleep 30 && kill -ALRM $master) >/dev/null 2>&1 &
-		read conf
-		trap : ALRM
-		if [ -z $conf ] ; then
-			conf=$default
-		fi
-		if [ ! -d /etc/etc.$conf/. ]; then
-			conf=${_DUMMY}
-		fi
-	done
+	bootconf
 
-	case  $conf in
+	case "$conf" in
 	current|default)
+		# nothing to do
 		;;
 	*)
-		rm -f /etc/etc.current
-		ln -s etc.$conf /etc/etc.current
+		/bin/rm -f /etc/etc.current
+		/bin/ln -s etc."$conf" /etc/etc.current
 		;;
 	esac
 
@@ -74,8 +51,159 @@ bootconf_start()
 	fi
 }
 
-case "$1" in
-*start)
-	bootconf_start
-	;;
-esac
+# print basic instructions, start countdown timer and wait for user to interact
+# or for timer to expire
+bootconf()
+{
+	local bc_opt= bc_opt_str=
+	local pid= line=
+
+	bc_opt="$(get_bc_opt)" && bc_opt_str=", $bc_opt"
+
+	echo 'bootconf: Ctrl-C to select configuration, enter for default'
+	countdown "$conf$bc_opt_str" ${bootconf_delay:-30} &
+	pid=$!
+
+	# set up self-resetting traps:
+	#  SIGCHLD: countdown elapsed
+	#  SIGINT:  user typed ^C
+	trap 'trap - CHLD; echo; return' CHLD
+	trap "trap - CHLD; trap : INT; quiet_kill $pid; select_conf; return" INT
+
+	# if this read returns, the user must have hit enter while the
+	# countdown was running -> reset traps and and kill countdown
+	read line
+	trap - CHLD
+	trap : INT
+
+	# if `kill $pid' is used here or from the INT trap, shell prints
+	# [1]   Terminated             countdown "${con...
+	# after boot-up continues...
+	quiet_kill $pid
+}
+
+# print currently selected boot-up configuration and number of seconds
+# remaining until it will be used if user does not interact
+countdown()
+{
+	local bc="$1"
+	local delay=$2
+	local i=$delay
+
+	while [ $i -gt 0 ]; do
+		printf "\rUsing boot-up configuration \`%s' in %*d seconds" \
+		    "$bc" ${#delay} $i
+		i=$(($i-1))
+		/bin/sleep 1
+	done
+	printf "\rUsing boot-up configuration \`%s'    %*s        " \
+	    "$bc" ${#delay} ' '
+}
+
+# suppress SIGTERM message from shell when killing process running in the
+# background (thanks to the anonymous poster!)
+quiet_kill()
+{
+	exec 3>&2	# Duplicate stderr.
+	exec 2>&-	# Close stderr (redirection to /dev/null works, too).
+	kill $1
+	/bin/sleep 0	# This allows the terminate message to flush.
+			# XXX - There must be a better way to flush this!
+	exec 2>&3	# Restore stderr.
+	exec 3>&-	# Close copy of stderr.
+}
+
+#
+# Prompt for boot-up configuration name.  If the chosen configuration has
+# options, i.e. the file `/etc/etc.$conf/bootconf.options' sets the
+# `bootconf_options' variable to contain option names, additionally prompt for
+# desired option.
+#
+select_conf()
+{
+	local default="$conf"
+	local dir= name=
+	local bootconf_options= bc_opt= bc_opt_def=
+
+	echo
+	while : ; do
+		echo -n 'Boot-up configurations:'
+		for dir in /etc/etc.*; do
+			name="${dir##/etc/etc.}"
+			case "$name" in
+			current|default|\*)
+				continue
+				;;	
+			*)
+				[ "$name" = "$default" ] && name="[$name]"
+				echo -n " $name"
+				;;
+			esac
+		done
+		echo
+
+		echo -n "Configuration [$default]: "
+		read conf
+		[ -z "$conf" ] && conf="$default"
+
+		if [ ! -d /etc/etc."$conf"/. ]; then
+			echo "Invalid configuration \`$conf'"
+			conf=
+			continue
+		fi
+
+		# if there are no config options, we're done
+		[ -f /etc/etc."$conf"/bootconf.options ] || break
+		bootconf_options=
+		. /etc/etc."$conf"/bootconf.options
+		[ -z "$bootconf_options" ] && break
+
+		bc_opt=
+		bc_opt_def="$(get_bc_opt)"
+
+		# read until we get a valid option
+		while :; do
+			echo -n "Configuration options for \`$conf':"
+			for name in $bootconf_options; do
+				[ "$name" = "$bc_opt_def" ] && name="[$name]"
+				echo -n " $name"
+			done
+			echo
+
+			echo -n "Option${bc_opt_def:+ [$bc_opt_def]}: "
+			read bc_opt
+			[ -z "$bc_opt" ] && bc_opt="$bc_opt_def"
+
+			# undocumented feature:
+			# c: choose different configuration
+			[ "$bc_opt" = 'c' ] && break
+
+			# check if desired option is valid
+			for name in $bootconf_options; do
+				[ "$bc_opt" != "$name" ] && continue
+				# remember choice
+				echo "bootconf_option='$bc_opt'" \
+				    >/var/db/bootconf_option."$conf"
+				break 3
+			done
+			[ -z "$bc_opt" ] || echo "Invalid option \`$bc_opt'"
+		done
+	done
+
+	echo "Using boot-up configuration \`$conf${bc_opt:+, $bc_opt}'"
+}
+
+# print currently selected bootconf option, or return 1 if none is set
+get_bc_opt()
+{
+	local bootconf_option=
+
+	[ -f /var/db/bootconf_option."$conf" ] && \
+	   . /var/db/bootconf_option."$conf"
+
+	[ -z "$bootconf_option" ] && return 1
+	echo "$bootconf_option"
+}
+
+load_rc_config $name
+run_rc_command "$1"
Index: sbin/newbtconf/newbtconf.8
===================================================================
RCS file: /cvsroot/src/sbin/newbtconf/newbtconf.8,v
retrieving revision 1.19
diff -u -p -r1.19 newbtconf.8
--- sbin/newbtconf/newbtconf.8	30 Sep 2005 20:18:12 -0000	1.19
+++ sbin/newbtconf/newbtconf.8	3 May 2010 15:35:00 -0000
@@ -44,8 +44,8 @@
 .Nm
 is used to set up the system in such a way that the user is offered a
 selection of environments in which to boot the system up into.
-The most obvious application being for laptops to provide a network
-and non-network environment after a successful boot into multi-user mode.
+A typical example is for laptops to provide a home and a work environment
+after a successful boot into multi-user mode.
 .Ss Background
 In order to accomplish this task, the files usually associated with
 establishing the current system's running configuration are replaced with
@@ -76,6 +76,9 @@ As opposed to
 with every boot),
 .Pa /etc/etc.default
 is not automatically updated.
+If
+.Pa /etc/etc.default
+does not exist, the default boot-up configuration is the last one used.
 .Ss Getting Started
 By default,
 .Nx
@@ -92,7 +95,7 @@ This will create two symbolic links
 and
 .Pa /etc/etc.default
 to the directory
-.Pa /etc/etc.network .
+.Pa /etc/etc.home .
 The following files are all moved into
 that directory and symbolic links put in their place, in
 .Pa /etc ,
@@ -118,18 +121,24 @@ To test that this has been performed cor
 .Nx .
 After the kernel has autoconfigured and tty flags have been set,
 a prompt should appear, preceded by the following like, looking like this:
-.Bd -literal
-[network]
-Which configuration [network] ?
+.Bd -literal -offset indent
+bootconf: Ctrl-C to select configuration, enter for default
+Using boot-up configuration `home' in 30 seconds
 .Ed
 .Pp
-The []'s are used to indicate the default configuration, which can be
-selected by just pressing return.
-If there were other configurations available at this stage, you would
-have 30 seconds to enter that name and press
+If you do not interact by hitting Ctrl-C within 30 seconds (or whatever you set
+.Sy bootconf_delay
+to in
+.Xr rc.conf 5 )
+the default configuration is selected; just pressing
+.Sy RETURN
+yields the same.
+If there were other configurations available at this stage, hitting Ctrl-C
+would print their names and let you choose one of them by entering its name
+and pressing
 .Sy RETURN .
 .Ss Multiple Configurations
-Once an initial configuration has been set up, we can proceed to set up further
+Once an initial configuration has been set up, you can proceed to set up further
 run time environments.
 This is done by invoking
 .Nm
@@ -142,62 +151,132 @@ Upon completion, a new directory,
 .Pa /etc/etc.\*[Lt]newname\*[Gt] ,
 will have been created,
 priming the directory with the appropriate files for editing.
-For example, if we do
+For example, if you do
 .Nm
-.Ar nonet network
+.Ar work home
 it would create a directory named
-.Pa /etc/etc.nonet
+.Pa /etc/etc.work
 and copy all the files from
-.Pa /etc/etc.network
+.Pa /etc/etc.home
 into that directory.
-Upon rebooting, we should see:
-.Bd -literal
-[network] nonet
-Which configuration [network] ?
+Upon rebooting, you should be able to interrupt the count down timer by
+hitting Ctrl-C, enter
+.Dq work
+and press
+.Sy RETURN
+to select that configuration:
+.Bd -literal -offset indent
+bootconf: Ctrl-C to select configuration, enter for default
+Using boot-up configuration `home' in 28 seconds^C
+Boot-up configurations: [home] work
+Configuration [home]: work
+Using boot-up configuration `work'
 .Ed
 .Pp
 To set up the system for booting into the
-.Dq nonet
+.Dq work
 configuration, the files in
-.Pa /etc/etc.nonet
+.Pa /etc/etc.work
 need be edited.
 .Pp
 If you wanted to make
-.Dq nonet
+.Dq work
 the default configuration when booting, you
-would need delete the symbolic link
+would need to delete the symbolic link
 .Pa /etc/etc.default
 and create a new symbolic link (with the same name) to
-.Pa /etc/etc.nonet .
+.Pa /etc/etc.work .
 Booting up after having made such a change would
 result in the following being displayed:
-.Bd -literal
-network [nonet]
-Which configuration [nonet] ?
-.Ed
-.Ss \&No Network
-Assuming that we performed the above command successfully, in order to
-successfully configure
-.Nx
-to not configure interfaces (or generate no
-errors from attempting to do so), the following settings (at least) should
-be used in
-.Pa /etc/etc.nonet/rc.conf :
-.Bd -literal
-auto_ifconfig=NO
-net_interfaces=NO
-.Ed
-.Pp
-Of course other networking services, such as NTP, routed, etc, are all
-expected to be
-.Dq NO .
-In general, the only setting that should be
-.Dq YES
-is syslogd, and perhaps cron (if your cron scripts don't
-need the network) or screenblank/wscons (if applicable).
-Other actions such as deleting any NFS mounts from
-.Pa /etc/etc.nonet/fstab
-would also need to be undertaken.
+.Bd -literal -offset indent
+bootconf: Ctrl-C to select configuration, enter for default
+Using boot-up configuration `work' in 29 seconds^C
+Boot-up configurations: home [work]
+Configuration [work]: 
+Using boot-up configuration `work'
+.Ed
+.Pp
+If you prefer the default configuration to be whatever you've used last,
+then just delete
+.Pa /etc/etc.default .
+.Ss Configuration Options
+Each boot-up configuration may have two or more options.
+Such options can be used for boot-up configurations which are similar but
+differ in a few details.
+For example, your
+.Dq home
+configuration could have options
+.Dq nonet ,
+.Dq lan
+and
+.Dq wlan 
+while your
+.Dq work
+configuration has options
+.Dq lan
+and
+.Dq customerX .
+.Pp
+Options for an existing boot-up configuration can be configured by
+creating a file named
+.Pa /etc/etc.\*[Lt]name\*[Gt]/bootconf.options .
+That file needs to define the variable
+.Sy bootconf_options
+to contain your option names, concatenated by whitespace.
+To implement the aforementioned example, you would create the file
+.Pa /etc/etc.home/bootconf.options
+containing
+.Bd -literal -offset indent
+bootconf_options='nonet lan wlan'
+.Ed
+.Pp
+and the file
+.Pa /etc/etc.work/bootconf.options
+containing
+.Bd -literal -offset indent
+bootconf_options='lan customerX'
+.Ed
+.Pp
+Such options can then be selected at boot time.
+Furthermore they are remembered across reboots.
+This means that the next time the system is started, the most recently used
+option is chosen unless another option is explicitly specified:
+.Bd -literal -offset indent
+bootconf: Ctrl-C to select configuration, enter for default
+Using boot-up configuration `home, wlan' in 28 seconds^C
+Boot-up configurations: [home] work
+Configuration [home]: 
+Configuration options for `home': nonet lan [wlan]
+Option [wlan]: nonet
+Using boot-up configuration `home, nonet'
+.Ed
+.Pp
+The selected option's name is available to the system startup configuration
+files as
+.Sy bootconf_option
+after
+.Pa /var/db/bootconf_option.\*[Lt]name\*[Gt]
+has been sourced.
+For example, in
+.Pa /etc/etc.home/rc.conf
+you could use something like this
+.Bd -literal -offset indent
+[ -r /var/db/bootconf_option.home ] && \\
+   . /var/db/bootconf_option.home
+
+case "$bootconf_option" in
+	lan|wlan)
+		sshd=YES
+		;;
+	nonet)
+		auto_ifconfig=NO
+		net_interfaces=NO
+		inetd=NO
+		;;
+esac
+.Ed
+.Pp
+to configure your system depending on what option has been selected.
 .Ss Reverting multiple boot configurations
 Multiple boot configurations can be deactivated by running
 .Nm
@@ -222,6 +301,8 @@ are not removed.
 Symbolic link to current config directory.
 .It Pa /etc/etc.default
 Symbolic link to default config directory.
+.It Pa /etc/etc.\*[Lt]name\*[Gt]/bootconf.options
+Available configuration options (see above).
 .Pp
 .It Pa /etc/defaultdomain
 These files all become symbolic links.
@@ -256,10 +337,6 @@ with initial input from
 .Aq mrg@NetBSD.org
 on how to approach this problem.
 .Sh BUGS
-It presently does not display a count down timer whilst waiting for input
-to select which configuration and nor does it abort said timer when a key
-is first pressed.
-.Pp
 The management of the overall collection of multiple configurations is much
 more manual than it ought to be.
 A general system configuration tool needs to be written to ease their
Index: sbin/newbtconf/newbtconf.sh
===================================================================
RCS file: /cvsroot/src/sbin/newbtconf/newbtconf.sh,v
retrieving revision 1.8
diff -u -p -r1.8 newbtconf.sh
--- sbin/newbtconf/newbtconf.sh	5 Jan 2004 23:23:33 -0000	1.8
+++ sbin/newbtconf/newbtconf.sh	3 May 2010 15:35:01 -0000
@@ -15,11 +15,11 @@ FILES="defaultdomain fstab ifconfig.* in
 	rc.conf rc.conf.d resolv.conf"
 
 if [ $dir = init ] ; then
-	if [ -d /etc/etc.network -o -e /etc/etc.current ] ; then
+	if [ -d /etc/etc.home -o -e /etc/etc.current ] ; then
 		echo "Error: multi-configuration already initialized"
 		exit 1
 	fi
-	dir=etc.network
+	dir=etc.home
 	cd /etc
 	mkdir -m 755 $dir
 	ln -s $dir etc.current
