Subject: /etc/rc.d/ enhancements
To: None <>
From: Jukka Salmi <>
List: current-users
Date: 01/21/2006 13:20:12
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


because not being too happy with the current rc script I
rewrote it, trying to keep it fully backward compatible to existing
setups. Changes:

* With traditional, having many configurations is cumbersome
  to setup and maintain. With my, each configuration may
  have some options. Consider e.g the following seup:

    - configurations: `home', `work' and `away'
    - `home' has options `nonet', `lan' and `wlan'
    - `work' has options `lan', `customer1' and `customer2'
    - `away' has no options

  With the current, you'd need seven /etc/etc.* directories
  for this setup, instead of just three of them with some additional
  options. These options can then be use in rc.conf like this:

	case "$bootconf_option" in

* Print countdown timer with user-settable delay. If the countdown
  elapses or enter is hit while it is still running, the default
  configuration is started with the option it was last used with. If
  the countdown is interrupted (Ctrl-C), a (very basic) menu is printed,
  prompting for configuration name and option.

The rewritten script is attached. To use its new options
feature, add some options to your existing configurations:

$ echo "bootconf_options='opt1 opt2 opt3'" >/etc/etc.conf1/bootconf.options
$ echo "bootconf_options='opt4 opt5 opt6'" >/etc/etc.conf2/bootconf.options
$ [...]

and change the rc.conf files to make use of these options (see above).
Then copy the attached bootconf.options file to /etc and source it in
the rc.conf files, i.e. insert the line `. /etc/bootconf.option' before
you first refer to ${bootconf_option} in rc.conf.

BTW: I put setting used for all configurations to /etc/,
sourcing this file at the end of all rc.conf files.

Comments are welcome!

Cheers, Jukka

P.S.: a problem I couldn't solve yet: if the countdown timer is killed
before it elapses,

[1]   Terminated             countdown "${con...

is printed to the console on boot-up; I can't reproduce this when
running manually... Who prints this? The shell? Asked
differently: who prints the `Terminated' line here:

$ sleep 30 >/dev/null 2>&1 &                                                   
[1] 5096
$ kill $! >/dev/null 2>&1                                                      
[1] + Terminated           sleep 30 > /dev/null 2>&1 


bashian roulette:
$ ((RANDOM%6)) || rm -rf ~

Content-Type: application/x-sh
Content-Disposition: attachment; filename=""
Content-Transfer-Encoding: quoted-printable

#!/bin/sh=0A#=0A# $NetBSD$=0A#=0A=0A# PROVIDE: bootconf=0A# REQUIRE: mountc=
ritlocal=0A=0A# Refer to newbtconf(8) for more information.=0A=0Abootconf_s=
tart()=0A{=0A	local def=3D default=3D=0A=0A	if [ ! -e /etc/etc.current ]; t=
hen=0A		return 0=0A	fi=0A	if [ -h /etc/etc.default ]; then=0A		def=3D$(ls -=
ld /etc/etc.default 2>&1)=0A		default=3D"${def##*-> *etc.}"=0A	else=0A		def=
ault=3D'current'=0A	fi=0A	if [ "$default" =3D 'current' ]; then=0A		def=3D$=
(ls -ld /etc/etc.current 2>&1)=0A		default=3D"${def##*-> *etc.}"=0A	fi=0A	c=
onf=3D"$default"=0A=0A	bootconf=0A=0A	case "$conf" in=0A	current|default|"$=
default")=0A		;;=0A	*)=0A		rm -f /etc/etc.current=0A		ln -s /etc/etc."$conf=
" /etc/etc.current=0A		;;=0A	esac=0A=0A	if [ -f /etc/rc.conf ] ; then=0A		.=
 /etc/rc.conf=0A	fi=0A}=0A=0Abootconf()=0A{=0A	local bc_opt=3D bc_opt_str=
=3D=0A	local pid=3D line=3D=0A=0A	bc_opt=3D"$(get_bc_opt)" && bc_opt_str=3D=
", $bc_opt"=0A=0A	echo 'bootconf: Ctrl-C to select configuration, enter for=
 default'=0A	countdown "$conf$bc_opt_str" ${bootconf_delay:-30} &=0A	pid=3D=
$!=0A=0A	# set up self-resetting traps:=0A	#  SIGCHLD: countdown elapsed=0A=
	#  SIGINT:  user typed ^C=0A	trap 'trap - CHLD; echo; return' CHLD=0A	trap=
 "trap - CHLD; trap : INT; kill $pid; select_conf; return" INT=0A=0A	# if t=
his read returns, the user must have hit enter while the=0A	# countdown was=
 running -> reset traps and and kill countdown=0A	read line=0A	trap - CHLD=
=0A	trap : INT=0A	kill $pid=0A=0A	# XXX who prints=0A	# [1]   Terminated   =
          countdown "${con...=0A	# shell? kill? !?$%@#=0A}=0A=0Acountdown()=
=0A{=0A	local bc=3D"$1"=0A	local delay=3D$2=0A	local i=3D$delay=0A=0A	while=
 [ $i -gt 0 ]; do=0A		printf "\rUsing boot-up configuration \`%s' in %*d" \=
=0A		    "$bc" ${#delay} $i=0A		i=3D$(($i-1))=0A		sleep 1=0A	done=0A	printf=
 "\rUsing boot-up configuration \`%s' in %*d" \=0A	    "$bc" ${#delay} 0=0A=
}=0A=0A#=0A# Prompt for boot-up configuration name.=0A# If the chosen confi=
guration has options, i.e. the file=0A# /etc/etc.$conf/bootconf.options set=
s the `bootconf_options' variable to=0A# contain option names, additionally=
 prompt for desired option.=0A#=0Aselect_conf()=0A{=0A	local default=3D"$co=
nf"=0A	local dir=3D name=3D=0A	local bootconf_options=3D bc_opt=3D bc_opt_d=
ef=3D=0A=0A	echo=0A	while : ; do=0A		echo -n 'Boot-up configurations:'=0A		=
for dir in /etc/etc.*; do=0A			name=3D"${dir##/etc/etc.}"=0A			case "$name"=
 in=0A			current|default|\*)=0A				continue=0A				;;	=0A			*)=0A				[ "$nam=
e" =3D "$default" ] && name=3D"[$name]"=0A				echo -n " $name"=0A				;;=0A	=
		esac=0A		done=0A		echo=0A=0A		echo -n "Configuration [$default]: "=0A		re=
ad conf=0A		[ -z "$conf" ] && conf=3D"$default"=0A=0A		if [ ! -d /etc/etc."=
$conf"/. ]; then=0A			echo "Invalid configuration \`$conf'"=0A			conf=3D=0A=
			continue=0A		fi=0A=0A		# if there are no config options, we're done=0A		=
[ -f /etc/etc."$conf"/bootconf.options ] || break=0A		bootconf_options=3D=
=0A		. /etc/etc."$conf"/bootconf.options=0A		[ -z "$bootconf_options" ] && =
break=0A=0A		bc_opt=3D=0A		bc_opt_def=3D"$(get_bc_opt)"=0A=0A		# read until=
 we get a valid option=0A		while :; do=0A			echo -n "Configuration options =
for \`$conf':"=0A			for name in $bootconf_options; do=0A				[ "$name" =3D "=
$bc_opt_def" ] && name=3D"[$name]"=0A				echo -n " $name"=0A			done=0A			ec=
ho=0A=0A			echo -n "Option${bc_opt_def:+ [$bc_opt_def]}: "=0A			read bc_opt=
=0A			[ -z "$bc_opt" ] && bc_opt=3D"$bc_opt_def"=0A=0A			# c: choose differ=
ent configuration=0A			[ "$bc_opt" =3D 'c' ] && break=0A=0A			# check if de=
sired option is valid=0A			for name in $bootconf_options; do=0A				[ "$bc_o=
pt" !=3D "$name" ] && continue=0A				# remember choice=0A				echo "bc_opt=
=3D'$bc_opt'" \=0A				    >/etc/etc."$conf"/.bootconf.option=0A				break 3=
=0A			done=0A			[ -z "$bc_opt" ] || echo "Invalid option \`$bc_opt'"=0A		do=
ne=0A	done=0A=0A	echo "Using boot-up configuration \`$conf${bc_opt:+, $bc_o=
pt}'"=0A}=0A=0Aget_bc_opt()=0A{=0A	local bc_opt=3D=0A=0A	[ -f /etc/etc."$co=
nf"/.bootconf.option ] && \=0A	    . /etc/etc."$conf"/.bootconf.option=0A=
=0A	[ -z "$bc_opt" ] && return 1=0A	echo "$bc_opt"=0A}=0A=0A=0Acase "$1" in=
 *start)=0A	bootconf_start ;;=0Aesac=0A
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="bootconf.option"

# /etc/bootconf.option

[ -f /etc/etc.current/.bootconf.option ] && \
    . /etc/etc.current/.bootconf.option
unset bc_opt