Home | History | Annotate | Line # | Download | only in miniroot
install.sub revision 1.33
      1 #!/bin/sh
      2 #	$NetBSD: install.sub,v 1.33 2000/02/20 00:23:10 mrg Exp $
      3 #
      4 # Copyright (c) 1996 The NetBSD Foundation, Inc.
      5 # All rights reserved.
      6 #
      7 # This code is derived from software contributed to The NetBSD Foundation
      8 # by Jason R. Thorpe.
      9 #
     10 # Redistribution and use in source and binary forms, with or without
     11 # modification, are permitted provided that the following conditions
     12 # are met:
     13 # 1. Redistributions of source code must retain the above copyright
     14 #    notice, this list of conditions and the following disclaimer.
     15 # 2. Redistributions in binary form must reproduce the above copyright
     16 #    notice, this list of conditions and the following disclaimer in the
     17 #    documentation and/or other materials provided with the distribution.
     18 # 3. All advertising materials mentioning features or use of this software
     19 #    must display the following acknowledgement:
     20 #        This product includes software developed by the NetBSD
     21 #        Foundation, Inc. and its contributors.
     22 # 4. Neither the name of The NetBSD Foundation nor the names of its
     23 #    contributors may be used to endorse or promote products derived
     24 #    from this software without specific prior written permission.
     25 #
     26 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36 # POSSIBILITY OF SUCH DAMAGE.
     37 #
     38 
     39 #	NetBSD installation/upgrade script - common subroutines.
     40 
     41 ROOTDISK=""				# filled in below
     42 VERSION=				# filled in automatically (see list)
     43 export VERSION
     44 
     45 ALLSETS="base comp etc games man misc text"	# default install sets
     46 UPGRSETS="base comp games man misc text"	# default upgrade sets
     47 THESETS=					# one of the above
     48 
     49 local_sets_dir=""			# Path searched for sets by install_sets
     50 					# on the local filesystems
     51 
     52 # decide upon an editor
     53 if [ X$EDITOR = X ]; then
     54 	if [ -x /usr/bin/vi ]; then
     55 		EDITOR=vi
     56 	else
     57 		EDITOR=ed
     58 	fi
     59 fi
     60 
     61 getresp() {
     62 	read resp
     63 	if [ "X$resp" = "X" ]; then
     64 		resp=$1
     65 	fi
     66 }
     67 
     68 isin() {
     69 # test the first argument against the remaining ones, return succes on a match
     70 	_a=$1; shift
     71 	while [ $# != 0 ]; do
     72 		if [ "$_a" = "$1" ]; then return 0; fi
     73 		shift
     74 	done
     75 	return 1
     76 }
     77 
     78 rmel() {
     79 # remove first argument from list formed by the remaining arguments
     80 	local	_a
     81 
     82 	_a=$1; shift
     83 	while [ $# != 0 ]; do
     84 		if [ "$_a" != "$1" ]; then
     85 			echo "$1";
     86 		fi
     87 		shift
     88 	done
     89 }
     90 
     91 cutword () {
     92 # read a line of data, return Nth element.
     93 	local _a
     94 	local _n
     95 	local _oifs
     96 
     97 	# optional field separator
     98 	_oifs="$IFS"
     99 	case "$1" in
    100 		-t?*) IFS=${1#-t}; shift;;
    101 	esac
    102 
    103 	_n=$1
    104 	read _a; set -- $_a
    105 	IFS="$_oifs"
    106 	if [ "$1" = "" ]; then return; fi
    107 	eval echo \$$_n
    108 }
    109 
    110 cutlast () {
    111 # read a line of data, return last element. Equiv. of awk '{print $NF}'.
    112 	local _a
    113 	local _oifs
    114 
    115 	# optional field separator
    116 	_oifs="$IFS"
    117 	case "$1" in
    118 		-t?*) IFS=${1#-t}; shift;;
    119 	esac
    120 
    121 	read _a; set -- $_a
    122 	IFS="$_oifs"
    123 	if [ "$1" = "" ]; then return; fi
    124 	while [ "$#" -gt 10 ]; do shift 10; done
    125 	eval echo \$$#
    126 }
    127 
    128 firstchar () {
    129 # return first character of argument
    130 	local _a
    131 	_a=$1
    132 	while [ ${#_a} != 1 ]; do
    133 		_a=${_a%?}
    134 	done
    135 	echo $_a
    136 }
    137 
    138 basename () {
    139 	local _oifs
    140 	if [ "$1" = "" ]; then return; fi
    141 	_oifs="$IFS"
    142 	IFS="/"
    143 	set -- $1
    144 	IFS="$_oifs"
    145 	while [ "$#" -gt 10 ]; do shift 10; done
    146 	eval echo \$$#
    147 }
    148 
    149 dir_has_sets() {
    150 	# return true when the directory $1 contains a set for $2...$n
    151 	local _dir
    152 	local _file
    153 
    154 	_dir=$1; shift
    155 	for _file in $*
    156 	do
    157 		if [ -f $_dir/${_file}.tar.gz ]; then
    158 			return 0
    159 		fi
    160 		# Try for stupid msdos convention
    161 		if [ -f $_dir/${_file}.tgz ]; then
    162 			return 0
    163 		fi
    164 		# Try for split files
    165 		if [ -f $_dir/${_file}${VERSION}.aa ]; then
    166 			return 0
    167 		fi
    168 	done
    169 	return 1
    170 }
    171 
    172 twiddle() {
    173 # spin the propeller so we don't get bored
    174 	while : ; do  
    175 		sleep 1; echo -n "/";
    176 		sleep 1; echo -n "-";
    177 		sleep 1; echo -n "\\";
    178 		sleep 1; echo -n "|";
    179 	done > /dev/tty & echo $!
    180 }
    181 
    182 get_localdir() {
    183 	# $1 is relative mountpoint
    184 	local _mp
    185 	local _dir
    186 
    187 	_mp=$1
    188 	_dir=
    189 	while : ; do
    190 	    if [ X$_mp != X ]; then
    191 		cat << __get_localdir_1
    192 Note: your filesystems are mounted under the temporary mount point \"$_mp\".
    193 The pathname you are requested to enter below should NOT include the \"$_mp\"
    194 prefix.
    195 __get_localdir_1
    196 	    fi
    197 	    echo -n "Enter the pathname where the sets are stored [$_dir] "
    198 	    getresp "$_dir"
    199 	    _dir=$resp
    200 
    201 	    # Allow break-out with empty response
    202 	    if [ -z "$_dir" ]; then
    203 		echo -n "Are you sure you don't want to set the pathname? [n] "
    204 		getresp "n"
    205 		case "$resp" in
    206 			y*|Y*)
    207 				break
    208 				;;
    209 			*)
    210 				continue
    211 				;;
    212 		esac
    213 	    fi
    214 
    215 	    if dir_has_sets "$_mp/$_dir" $THESETS
    216 	    then
    217 		local_sets_dir="$_mp/$_dir"
    218 		break
    219 	    else
    220 		cat << __get_localdir_2
    221 The directory \"$_mp/$_dir\" does not exist, or does not hold any of the
    222 upgrade sets.
    223 __get_localdir_2
    224 		echo -n "Re-enter pathname? [y] "
    225 		getresp "y"
    226 		case "$resp" in
    227 			y*|Y*)
    228 				;;
    229 			*)
    230 				local_sets_dir=""
    231 				break
    232 				;;
    233 		esac
    234 	    fi
    235 	done
    236 }
    237 
    238 getrootdisk() {
    239 	cat << \__getrootdisk_1
    240 
    241 The installation program needs to know which disk to consider
    242 the root disk.  Note the unit number may be different than
    243 the unit number you used in the standalone installation
    244 program.
    245 
    246 Available disks are:
    247 
    248 __getrootdisk_1
    249 	_DKDEVS=`md_get_diskdevs`
    250 	echo	"$_DKDEVS"
    251 	echo	""
    252 	echo -n	"Which disk is the root disk? "
    253 	getresp ""
    254 	if isin $resp $_DKDEVS ; then
    255 		ROOTDISK="$resp"
    256 	else
    257 		echo ""
    258 		echo "The disk $resp does not exist."
    259 		ROOTDISK=""
    260 	fi
    261 }
    262 
    263 labelmoredisks() {
    264 	cat << \__labelmoredisks_1
    265 
    266 You may label the following disks:
    267 
    268 __labelmoredisks_1
    269 	echo "$_DKDEVS"
    270 	echo	""
    271 	echo -n	"Label which disk? [done] "
    272 	getresp "done"
    273 	case "$resp" in
    274 		"done")
    275 			;;
    276 
    277 		*)
    278 			if isin $resp $_DKDEVS ; then
    279 				md_labeldisk $resp
    280 			else
    281 				echo ""
    282 				echo "The disk $resp does not exist."
    283 			fi
    284 			;;
    285 	esac
    286 }
    287 
    288 addhostent() {
    289 	# $1 - IP address
    290 	# $2 - symbolic name
    291 
    292 	# Create an entry in the hosts table.  If no host table
    293 	# exists, create one.  If the IP address already exists,
    294 	# replace it's entry.
    295 	if [ ! -f /tmp/hosts ]; then
    296 		echo "127.0.0.1 localhost" > /tmp/hosts
    297 	fi
    298 
    299 	sed "/^$1 /d" < /tmp/hosts > /tmp/hosts.new
    300 	mv /tmp/hosts.new /tmp/hosts
    301 
    302 	echo "$1 $2 $2.$FQDN" >> /tmp/hosts
    303 }
    304 
    305 addifconfig() {
    306 	# $1 - interface name
    307 	# $2 - interface symbolic name
    308 	# $3 - interface IP address
    309 	# $4 - interface netmask
    310 	# $5 - (optional) interface link-layer medium
    311 	# $6 - (optional) interface link-layer directives
    312 	local _m
    313 
    314 	_m=""
    315 	if [ "$5" != "" ]; then
    316 		_m="media $5"
    317 	fi
    318 	# Create a ifconfig.* file for the interface.
    319 	echo "inet $2 netmask $4 $_m $6" > /tmp/ifconfig.$1
    320 
    321 	addhostent $3 $2
    322 }
    323 
    324 configurenetwork() {
    325 	local _ifsdone
    326 	local _ifs
    327 
    328 #	_IFS=`md_get_ifdevs`
    329 	_IFS=`ifconfig -l | sed '
    330 		s/lo0//
    331 		s/ppp[0-9]//g
    332 		s/sl[0-9]//g
    333 		s/tun[0-9]//g'`
    334 
    335 	_ifsdone=""
    336 	resp=""		# force at least one iteration
    337 	while [ "X${resp}" != X"done" ]; do
    338 	cat << \__configurenetwork_1
    339 
    340 You may configure the following network interfaces (the interfaces
    341 marked with [X] have been succesfully configured):
    342 
    343 __configurenetwork_1
    344 
    345 		for _ifs in $_IFS; do
    346 			if isin $_ifs $_ifsdone ; then
    347 				echo -n "[X] "
    348 			else
    349 				echo -n "    "
    350 			fi
    351 			echo $_ifs
    352 		done
    353 		echo	""
    354 		echo -n	"Configure which interface? [done] "
    355 		getresp "done"
    356 		case "$resp" in
    357 		"done")
    358 			;;
    359 		*)
    360 			_ifs=$resp
    361 			if isin $_ifs $_IFS ; then
    362 				if configure_ifs $_ifs ; then
    363 					_ifsdone="$_ifs $_ifsdone"
    364 				fi
    365 			else
    366 				echo "Invalid response: \"$resp\" is not in list"
    367 			fi
    368 			;;
    369 		esac
    370 	done
    371 }
    372 
    373 configure_ifs() {
    374 
    375 	local _up
    376 	local _interface_name
    377 	local _interface_ip
    378 	local _interface_mask
    379 	local _interface_symname
    380 	local _interface_extra
    381 	local _interface_mediumtype
    382 	local _interface_supported_media
    383 	local _m
    384 	local _t
    385 
    386 	_interface_name=$1
    387 	_up=DOWN
    388 	if isin $_interface_name `ifconfig -l -u` ; then
    389 		_up=UP
    390 	fi
    391 
    392 	_interface_supported_media=`ifconfig -m $_interface_name | sed -n '
    393 		/^[ 	]*media autoselect/d
    394 		4,$s/[ 	]*media //p'`
    395 
    396 	# get current "media" "ip" and "netmask" ("broadcast")
    397 	_t=`ifconfig $_interface_name | sed -n '
    398 		s/^[ 	]*media: [^ 	]* \([^ ][^ ]*\).*/\1/p'`
    399 
    400 	if [ "$_t" != "manual" -a "$_t" != "media:" -a "$_t" != "autoselect" ];
    401 	then
    402 		_interface_mediumtype=$1
    403 	fi
    404 
    405 	set -- `ifconfig $_interface_name | sed -n '
    406 		/^[ 	]*inet/{
    407 		s/inet//
    408 		s/--> [0-9.][0-9.]*//
    409 		s/netmask//
    410 		s/broadcast//
    411 		p;}'`
    412 
    413 	_interface_ip=$1
    414 	_interface_mask=$2
    415 
    416 	# Get IP address
    417 	resp=""		# force one iteration
    418 	while [ "X${resp}" = X"" ]; do
    419 		echo -n "IP address? [$_interface_ip] "
    420 		getresp "$_interface_ip"
    421 		_interface_ip=$resp
    422 	done
    423 
    424 	# Get symbolic name
    425 	resp=""		# force one iteration
    426 	while [ "X${resp}" = X"" ]; do
    427 		echo -n "Symbolic (host) name? "
    428 		getresp ""
    429 		_interface_symname=$resp
    430 	done
    431 
    432 	# Get netmask
    433 	resp=""		# force one iteration
    434 	while [ "X${resp}" = X"" ]; do
    435 		echo -n "Netmask? [$_interface_mask] "
    436 		getresp "$_interface_mask"
    437 		_interface_mask=$resp
    438 	done
    439 
    440 	echo "Your network interface might require explicit selection"
    441 	echo "of the type of network medium attached. Supported media:"
    442 	echo "$_interface_supported_media"
    443 	echo -n "Additional media type arguments (none)? [$_interface_mediumtype] "
    444 	getresp "$_interface_mediumtype"
    445 	_m=""
    446 	if [ "X${resp}" != X"" -a "X${resp}" != Xnone ]; then
    447 		_interface_mediumtype=$resp
    448 		_m="media ${resp}"
    449 	fi
    450 
    451 
    452 	echo "Your network interface might require additional link-layer"
    453 	echo "directives (like \`link0'). If this is the case you can enter"
    454 	echo "these at the next prompt."
    455 	echo ""
    456 	echo -n "Additional link-layer arguments (none)? [$_interface_extra] "
    457 	getresp "$_interface_extra"
    458 	if [ "X${resp}" != X"" -a "X${resp}" != Xnone ]; then
    459 		_interface_extra=$resp
    460 	fi
    461 
    462 	# Configure the interface.  If it
    463 	# succeeds, add it to the permanent
    464 	# network configuration info.
    465 	if [ $_up != "UP" ]; then
    466 		ifconfig ${_interface_name} down
    467 		if ifconfig ${_interface_name} inet \
    468 		    ${_interface_ip} \
    469 		    netmask ${_interface_mask} \
    470 		    ${_interface_extra} ${_m} up ; then
    471 			addifconfig \
    472 			    "${_interface_name}" \
    473 			    "${_interface_symname}" \
    474 			    "${_interface_ip}" \
    475 			    "${_interface_mask}" \
    476 			    "${_interface_mediumtype}" \
    477 			    "${_interface_extra}"
    478 			return 0
    479 		fi
    480 	else
    481 		echo "Interface ${_interface_name} is already active."
    482 		echo "Just saving configuration on new root filesystem."
    483 		addifconfig \
    484 		    "${_interface_name}" \
    485 		    "${_interface_symname}" \
    486 		    "${_interface_ip}" \
    487 		    "${_interface_mask}" \
    488 		    "${_interface_mediumtype}" \
    489 		    "${_interface_extra}"
    490 	fi
    491 	return 1
    492 }
    493 
    494 # Much of this is gratuitously stolen from /etc/netstart.
    495 enable_network() {
    496 
    497 	# Set up the hostname.
    498 	if [ ! -f /mnt/etc/myname ]; then
    499 		echo "ERROR: no /etc/myname!"
    500 		return 1
    501 	fi
    502 	hostname=`cat /mnt/etc/myname`
    503 	hostname $hostname
    504 
    505 	# configure all the interfaces which we know about.
    506 if [ -f /mnt/etc/rc.conf ]; then
    507 (
    508 	# assume network interface configuration style 1.2D and up
    509 	. /mnt/etc/rc.conf
    510 
    511 	if [ "$net_interfaces" != NO ]; then
    512 		if [ "$auto_ifconfig" = YES ]; then
    513 			tmp="`ifconfig -l`"
    514 		else
    515 			tmp="$net_interfaces"
    516 		fi
    517 		echo -n "configuring network interfaces:"
    518 		for i in $tmp; do
    519 			eval `echo 'args=$ifconfig_'$i`
    520 			if [ ! -z "$args" ]; then
    521 				echo -n " $i"
    522 				ifconfig $i $args
    523 			elif [ -f /mnt/etc/ifconfig.$i ]; then
    524 				echo -n " $i"
    525 				(while read args; do
    526 					ifconfig $i $args
    527 				done) < /mnt/etc/ifconfig.$i
    528 			elif [ "$auto_ifconfig" != YES ]; then
    529 				echo
    530 				echo -n "/mnt/etc/ifconfig.$i missing"
    531 				echo -n "& ifconfig_$i not set"
    532 				echo "; interface $i can't be configured"
    533 			fi
    534 		done
    535 		echo "."
    536 	fi
    537 )
    538 else
    539 (
    540 	tmp="$IFS"
    541 	IFS="$IFS."
    542 	set -- `echo /mnt/etc/hostname*`
    543 	IFS=$tmp
    544 	unset tmp
    545 
    546 	while [ $# -ge 2 ] ; do
    547 		shift		# get rid of "hostname"
    548 		(
    549 			read af name mask bcaddr extras
    550 			read dt dtaddr
    551 
    552 			if [ ! -n "$name" ]; then
    553 		    echo "/etc/hostname.$1: invalid network configuration file"
    554 				exit
    555 			fi
    556 
    557 			cmd="ifconfig $1 $af $name "
    558 			if [ "${dt}" = "dest" ]; then cmd="$cmd $dtaddr"; fi
    559 			if [ -n "$mask" ]; then cmd="$cmd netmask $mask"; fi
    560 			if [ -n "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then
    561 				cmd="$cmd broadcast $bcaddr";
    562 			fi
    563 			cmd="$cmd $extras"
    564 
    565 			$cmd
    566 		) < /mnt/etc/hostname.$1
    567 		shift
    568 	done
    569 )
    570 fi
    571 
    572 	# set the address for the loopback interface
    573 	ifconfig lo0 inet localhost
    574 
    575 	# use loopback, not the wire
    576 	route add $hostname localhost
    577 
    578 	# /etc/mygate, if it exists, contains the name of my gateway host
    579 	# that name must be in /etc/hosts.
    580 	if [ -f /mnt/etc/mygate ]; then
    581 		route delete default > /dev/null 2>&1
    582 		route add default `cat /mnt/etc/mygate`
    583 	fi
    584 
    585 	# enable the resolver, if appropriate.
    586 	if [ -f /mnt/etc/resolv.conf ]; then
    587 		_resolver_enabled="TRUE"
    588 		cp /mnt/etc/resolv.conf /tmp/resolv.conf.shadow
    589 	fi
    590 
    591 	# Display results...
    592 	echo	"Network interface configuration:"
    593 	ifconfig -a
    594 
    595 	echo	""
    596 
    597 	if [ "X${_resolver_enabled}" = X"TRUE" ]; then
    598 		netstat -r
    599 		echo	""
    600 		echo	"Resolver enabled."
    601 	else
    602 		netstat -rn
    603 		echo	""
    604 		echo	"Resolver not enabled."
    605 	fi
    606 
    607 	return 0
    608 }
    609 
    610 install_ftp() {
    611 	local	_f
    612 	local	_sets
    613 	local	_next
    614 
    615 	# Build a script to extract valid files from a list
    616 	# of filenames on stdin.
    617 	# XXX : Can we use this on more places? Leo.
    618 
    619 	echo "#!/bin/sh" > /tmp/fname_filter.sh
    620 	echo "while read line; do"	>> /tmp/fname_filter.sh
    621 	echo "    case \$line in"	>> /tmp/fname_filter.sh
    622 	for _f in $THESETS; do
    623 		echo "    $_f.tar.gz|$_f.tgz|$_f.${VERSION}.aa)" \
    624 					>> /tmp/fname_filter.sh
    625 		echo '        echo -n "$line ";;' \
    626 					>> /tmp/fname_filter.sh
    627 	done
    628 	echo "        *) ;;"		>> /tmp/fname_filter.sh
    629 	echo "    esac"			>> /tmp/fname_filter.sh
    630 	echo "done"			>> /tmp/fname_filter.sh
    631 
    632 	# Get several parameters from the user, and create
    633 	# a shell script that directs the appropriate
    634 	# commands into ftp.
    635 	cat << \__install_ftp_1
    636 
    637 This is an automated ftp-based installation process.  You will be asked
    638 several questions.  The correct set of commands will be placed in a script
    639 that will be fed to ftp(1).
    640 
    641 __install_ftp_1
    642 	# Get server IP address
    643 	resp=""		# force one iteration
    644 	while [ "X${resp}" = X"" ]; do
    645 		echo -n "Server IP? [${_ftp_server_ip}] "
    646 		getresp "${_ftp_server_ip}"
    647 		_ftp_server_ip=$resp
    648 	done
    649 
    650 	# Get login name
    651 	resp=""		# force one iteration
    652 	while [ "X${resp}" = X"" ]; do
    653 		echo -n "Login? [${_ftp_server_login}] "
    654 		getresp "${_ftp_server_login}"
    655 		_ftp_server_login=$resp 
    656 	done
    657 
    658 	# Get password
    659 	resp=""		# force one iteration
    660 	while [ "X${resp}" = X"" ]; do
    661 		echo -n "Password? "
    662 		stty -echo
    663 		getresp ""
    664 		echo ""
    665 		stty echo
    666 		_ftp_server_password=$resp
    667 	done
    668 
    669 	cat << \__install_ftp_2
    670 
    671 You will be asked to enter the name of the directory that contains the
    672 installation sets. When you enter a '?' you will see a listing of the
    673 current directory on the server.
    674 __install_ftp_2
    675 	_sets=""
    676 	while [ -z "$_sets" ]
    677 	do
    678 		resp=""		# force one iteration
    679 		while [ "X${resp}" = X"" ]; do
    680 			echo -n "Server directory? [${_ftp_server_dir}] "
    681 		    getresp "${_ftp_server_dir}"
    682 		    if [ "X$resp" = 'X?' -a -z "$_ftp_server_dir" ]; then
    683 			resp=""
    684 		    fi
    685 		done
    686 		if [ $resp != '?' ]; then
    687 			_ftp_server_dir=$resp
    688 		fi
    689 
    690 		# Build the basics of an ftp-script...
    691 		echo "#!/bin/sh" > /tmp/ftp-script.sh
    692 		echo "cd /mnt" >> /tmp/ftp-script.sh
    693 		echo "ftp -e -i -n $_ftp_server_ip << \__end_commands" >> \
    694 		    /tmp/ftp-script.sh
    695 		echo "user $_ftp_server_login $_ftp_server_password" >> \
    696 		    /tmp/ftp-script.sh
    697 		echo "bin" >> /tmp/ftp-script.sh
    698 		echo "cd $_ftp_server_dir" >> /tmp/ftp-script.sh
    699 
    700 		# Make a copy of this script that lists the directory
    701 		# contents, and use that to determine the files to get.
    702 		cat /tmp/ftp-script.sh	>  /tmp/ftp-dir.sh
    703 		echo "ls"		>> /tmp/ftp-dir.sh
    704 		echo "quit"		>> /tmp/ftp-dir.sh
    705 		echo "__end_commands"	>> /tmp/ftp-dir.sh
    706 
    707 		if [ $resp = '?' ]; then
    708 			sh /tmp/ftp-dir.sh
    709 		else
    710 			_sets=`sh /tmp/ftp-dir.sh | sh /tmp/fname_filter.sh`
    711 		fi
    712 	done
    713 	rm -f /tmp/ftp-dir.sh /tmp/fname_filter.sh
    714 
    715 	while : ; do
    716 		echo "The following sets are available for extraction:"
    717 		echo "(marked sets are already on the extraction list)"
    718 		echo ""
    719 
    720 		_next=""
    721 		for _f in $_sets ; do
    722 			if isin $_f $_setsdone; then
    723 				echo -n "[X] "
    724 				_next=""
    725 			else
    726 				echo -n "    "
    727 				if [ -z "$_next" ]; then _next=$_f; fi
    728 			fi
    729 			echo $_f
    730 		done
    731 		echo ""
    732 
    733 		# Get name of the file and add extraction command
    734 		# to the ftp-script.
    735 		if [ "X$_next" = "X" ]; then resp=n; else resp=y; fi
    736 		echo -n "Continue to add filenames [$resp]? "
    737 		getresp "$resp"
    738 		if [ "$resp" = "n" ]; then
    739 			break
    740 		fi
    741 
    742 		echo -n "File name [$_next]? "
    743 		getresp "$_next"
    744 		if isin $resp $_sets; then
    745 			echo "get $resp |\"pax -zr${verbose_flag}pe\"" >> \
    746 					/tmp/ftp-script.sh
    747 			_setsdone="$resp $_setsdone"
    748 		else
    749 			echo "You entered an invalid filename."
    750 			echo ""
    751 		fi
    752 	done
    753 
    754 	echo "quit" >> /tmp/ftp-script.sh
    755 	echo "__end_commands" >> /tmp/ftp-script.sh
    756 
    757 	sh /tmp/ftp-script.sh
    758 	rm -f /tmp/ftp-script.sh
    759 	echo "Extraction complete."
    760 }
    761 
    762 install_from_mounted_fs() {
    763 	# $1 - directory containing installation sets
    764 	local _filename
    765 	local _sets
    766 	local _next
    767 	local _all
    768 	local _f
    769 	local _dirname
    770 
    771 	_dirname=$1
    772 	_sets=""
    773 
    774 	if ! dir_has_sets ${_dirname} $THESETS
    775 	then
    776 
    777 		echo ""
    778 		echo "The directory at the mount point, \"${_dirname}\", contains: "
    779 		echo ""
    780 		ls -F ${_dirname}
    781 		echo ""
    782 		echo    "Enter the subdirectory relative to the mountpoint, that"
    783 		echo -n "contains the savesets: [try this directory] "
    784 		getresp ""
    785 		if [ "X${resp}" != "X" ]; then
    786 			_dirname=${_dirname}/$resp
    787 		fi
    788 
    789 		while ! dir_has_sets ${_dirname} $THESETS; do
    790 			echo ""
    791 			echo -n "There are no NetBSD install sets available in "
    792 			echo "\"${_dirname}\"."
    793 			echo "\"${_dirname}\" contains: "
    794 			echo ""
    795 			ls -F ${_dirname}
    796 			echo ""
    797 			echo -n "Enter subdirectory: [try other install media] "
    798 			getresp ""
    799 			if [ "X${resp}" = "X" ]; then
    800 				return
    801 			fi
    802 			if [ ! -d ${_dirname}/${resp} ]; then
    803 				echo "\"${resp}\" is no directory; try again."
    804 			else
    805 				_dirname=${_dirname}/$resp
    806 			fi
    807 		done
    808 	fi
    809 
    810 	for _f in $THESETS ; do
    811 		if [ -f ${_dirname}/${_f}.tar.gz ]; then
    812 			_sets="$_sets ${_f}.tar.gz"
    813 		elif [ -f ${_dirname}/${_f}.tgz ]; then
    814 			_sets="$_sets ${_f}.tgz"
    815 		elif [ -f ${_dirname}/${_f}${VERSION}.aa ]; then
    816 			_sets="$_sets ${_f}${VERSION}"
    817 		fi
    818 	done
    819 
    820 	while : ; do
    821 		echo "The following sets are available for extraction:"
    822 		echo "(marked sets have already been extracted)"
    823 		echo ""
    824 
    825 		_next=""
    826 		_all=""
    827 		for _f in $_sets ; do
    828 			if isin $_f $_setsdone; then
    829 				echo -n "[X] "
    830 				_next=""
    831 			else
    832 				echo -n "    "
    833 				if [ -z "$_next" ]; then
    834 					_next=$_f;
    835 				fi
    836 				_all="$_all $_f"
    837 			fi
    838 			echo $_f
    839 		done
    840 		echo ""
    841 
    842 		# Get the name of the file.
    843 		if [ "X$_next" = "X" ]; then
    844 			resp=n
    845 		else
    846 			resp=y
    847 		fi
    848 		echo -n "Continue extraction [$resp]?"
    849 		getresp "$resp"
    850 		if [ "$resp" = "n" ]; then
    851 			break
    852 		fi
    853 
    854 		echo -n "File name(s) (or "all") [$_next]? "
    855 		getresp "$_next"
    856 		if [ "x$resp" = xall ]; then
    857 			resp="$_all"
    858 		fi
    859 
    860 		for _f in $resp; do
    861 			_filename="/${_dirname}/$_f"
    862 
    863 			# Ensure file exists
    864 			if [ ! -f $_filename ]; then
    865 				if [ -f ${_filename}.aa ]; then
    866 					_filename=${_filename}.\?\?
    867 				else
    868 			 echo "File $_filename does not exist.  Check to make"
    869 			 echo "sure you entered the information properly."
    870 			 continue 2
    871 				fi
    872 			fi
    873 
    874 			# Extract file
    875 			echo "Extracting the $_f set:"
    876 			cat $_filename | (cd /mnt; pax -zr${verbose_flag}pe)
    877 			echo "Extraction complete."
    878 			_setsdone="$_f $_setsdone"
    879 		done
    880 
    881 	done
    882 }
    883 
    884 install_cdrom() {
    885 	local _drive
    886 	local _partition_range
    887 	local _partition
    888 	local _fstype
    889 	local _directory
    890 
    891 	# Get the cdrom device info
    892 	cat << \__install_cdrom_1
    893 
    894 The following CD-ROM devices are installed on your system; please select
    895 the CD-ROM device containing the partition with the installation sets:
    896 
    897 __install_cdrom_1
    898 	_CDDEVS=`md_get_cddevs`
    899 	echo    "$_CDDEVS"
    900 	echo	""
    901 	echo -n	"Which is the CD-ROM with the installation media? [abort] "
    902 	getresp "abort"
    903 	case "$resp" in
    904 		abort)
    905 			echo "Aborting."
    906 			return
    907 			;;
    908 
    909 		*)
    910 			if isin $resp $_CDDEVS ; then
    911 				_drive=$resp
    912 			else
    913 				echo ""
    914 				echo "The CD-ROM $resp does not exist."
    915 				echo "Aborting."
    916 				return
    917 			fi
    918 			;;
    919 	esac
    920 
    921 	# Get partition
    922 	_partition_range=`md_get_partition_range`
    923 	resp=""		# force one iteration
    924 	while [ "X${resp}" = X"" ]; do
    925 		echo -n "Partition? [a] "
    926 		getresp "a"
    927 		case "$resp" in
    928 			$_partition_range)
    929 				_partition=$resp
    930 				;;
    931 
    932 			*)
    933 				echo "Invalid response: $resp"
    934 				resp=""		# force loop to repeat
    935 				;;
    936 		esac
    937 	done
    938 
    939 	# Ask for filesystem type
    940 	cat << \__install_cdrom_2
    941 
    942 There are two CD-ROM filesystem types currently supported by this program:
    943 	1) ISO-9660 (cd9660)
    944 	2) Berkeley Fast Filesystem (ffs)
    945 
    946 __install_cdrom_2
    947 	resp=""		# force one iteration
    948 	while [ "X${resp}" = X"" ]; do
    949 		echo -n "Which filesystem type? [cd9660] "
    950 		getresp "cd9660"
    951 		case "$resp" in
    952 			cd9660|ffs)
    953 				_fstype=$resp
    954 				;;
    955 
    956 			*)
    957 				echo "Invalid response: $resp"
    958 				resp=""		# force loop to repeat
    959 				;;
    960 		esac
    961 	done
    962 
    963 	# Mount the CD-ROM
    964 	if ! mount -t ${_fstype} -o ro \
    965 	    /dev/${_drive}${_partition} /mnt2 ; then
    966 		echo "Cannot mount CD-ROM drive.  Aborting."
    967 		return
    968 	fi
    969 
    970 	install_from_mounted_fs /mnt2
    971 	umount -f /mnt2 > /dev/null 2>&1
    972 }
    973 
    974 mount_a_disk() {
    975 	# Mount a disk on /mnt2. The set of disk devices to choose from
    976 	# is $_DKDEVS.
    977 	# returns 0 on failure.
    978 
    979 	local _drive
    980 	local _partition_range
    981 	local _partition
    982 	local _fstype
    983 	local _fsopts
    984 	local _directory
    985 	local _md_fstype
    986 	local _md_fsopts
    987 
    988 	getresp "abort"
    989 	case "$resp" in
    990 		abort)
    991 			echo "Aborting."
    992 			return 0
    993 			;;
    994 
    995 		*)
    996 			if isin $resp $_DKDEVS ; then
    997 				_drive=$resp
    998 			else
    999 				echo ""
   1000 				echo "The disk $resp does not exist."
   1001 				echo "Aborting."
   1002 				return 0
   1003 			fi
   1004 			;;
   1005 	esac
   1006 
   1007 	# Get partition
   1008 	_partition_range=`md_get_partition_range`
   1009 	resp=""		# force one iteration
   1010 	while [ "X${resp}" = X"" ]; do
   1011 		echo -n "Partition? [d] "
   1012 		getresp "d"
   1013 		case "$resp" in
   1014 			$_partition_range)
   1015 				_partition=$resp
   1016 				;;
   1017 
   1018 			*)
   1019 				echo "Invalid response: $resp"
   1020 				resp=""		# force loop to repeat
   1021 				;;
   1022 		esac
   1023 	done
   1024 
   1025 	# Ask for filesystem type
   1026 	cat << \__mount_a_disk_2
   1027 
   1028 The following filesystem types are supported:
   1029 	1) ffs
   1030 __mount_a_disk_2
   1031 	_md_fstype=`md_native_fstype`
   1032 	_md_fsopts=`md_native_fsopts`
   1033 	if [ ! -z "$_md_fstype" ]; then
   1034 		echo "	2) $_md_fstype"
   1035 	else
   1036 		_md_fstype="_undefined_"
   1037 	fi
   1038 	resp=""		# force one iteration
   1039 	while [ "X${resp}" = X"" ]; do
   1040 		echo -n "Which filesystem type? [ffs] "
   1041 		getresp "ffs"
   1042 		case "$resp" in
   1043 			ffs)
   1044 				_fstype=$resp
   1045 				_fsopts="ro"
   1046 				;;
   1047 			$_md_fstype)
   1048 				_fstype=$resp
   1049 				_fsopts=$_md_fsopts
   1050 				;;
   1051 			*)
   1052 				echo "Invalid response: $resp"
   1053 				resp=""		# force loop to repeat
   1054 				;;
   1055 		esac
   1056 	done
   1057 
   1058 	# Mount the disk
   1059 	if ! mount -t ${_fstype} -o $_fsopts \
   1060 	    /dev/${_drive}${_partition} /mnt2 ; then
   1061 		echo "Cannot mount disk.  Aborting."
   1062 		return 0
   1063 	fi
   1064 	return 1
   1065 }
   1066 
   1067 install_disk() {
   1068 	local _directory
   1069 
   1070 	cat << \__install_disk_1
   1071 
   1072 Ok, lets install from a disk.  The file-system the install sets on may
   1073 already mounted, or we might have to mount the filesystem to get to it.
   1074 
   1075 __install_disk_1
   1076 
   1077 	echo -n "Is the file-system with the install sets already mounted? [n] "
   1078 	getresp "n"
   1079 	case $resp in
   1080 	y*|Y*)
   1081 		echo "What mount point are the sets located in? [] "
   1082 		getresp ""
   1083 		if [ -d "$resp" ]; then
   1084 			install_from_mounted_fs $resp
   1085 		else
   1086 			echo "$resp: Not a directory, aborting..."
   1087 		fi
   1088 		return
   1089 		;;
   1090 	*)
   1091 		;;
   1092 	esac
   1093 
   1094 	cat << \__install_disk_2
   1095 
   1096 The following disk devices are installed on your system; please select
   1097 the disk device containing the partition with the installation sets:
   1098 
   1099 __install_disk_2
   1100 	_DKDEVS=`md_get_diskdevs`
   1101 	echo    "$_DKDEVS"
   1102 	echo	""
   1103 	echo -n	"Which is the disk with the installation sets? [abort] "
   1104 
   1105 	if mount_a_disk ; then
   1106 		return
   1107 	fi
   1108 
   1109 	install_from_mounted_fs /mnt2
   1110 	umount -f /mnt2 > /dev/null 2>&1
   1111 }
   1112 
   1113 install_nfs() {
   1114 	# Get the IP address of the server
   1115 	resp=""		# force one iteration
   1116 	while [ "X${resp}" = X"" ]; do
   1117 		echo -n "Server IP address? [${_nfs_server_ip}] "
   1118 		getresp "${_nfs_server_ip}"
   1119 	done
   1120 	_nfs_server_ip=$resp
   1121 
   1122 	# Get server path to mount
   1123 	resp=""		# force one iteration
   1124 	while [ "X${resp}" = X"" ]; do
   1125 		echo -n "Filesystem on server to mount? [${_nfs_server_path}] "
   1126 		getresp "${_nfs_server_path}"
   1127 	done
   1128 	_nfs_server_path=$resp
   1129 
   1130 	# Determine use of TCP
   1131 	echo -n "Use TCP transport (only works with capable NFS server)? [n] "
   1132 	getresp "n"
   1133 	case "$resp" in
   1134 		y*|Y*)
   1135 			_nfs_tcp="-T"
   1136 			;;
   1137 
   1138 		*)
   1139 			_nfs_tcp=""
   1140 			;;
   1141 	esac
   1142 
   1143 	# Mount the server
   1144 	mkdir /mnt2 > /dev/null 2>&1
   1145 	if ! mount_nfs $_nfs_tcp ${_nfs_server_ip}:${_nfs_server_path} \
   1146 	    /mnt2 ; then
   1147 		echo "Cannot mount NFS server.  Aborting."
   1148 		return
   1149 	fi
   1150 
   1151 	install_from_mounted_fs /mnt2
   1152 	umount -f /mnt2 > /dev/null 2>&1
   1153 }
   1154 
   1155 install_tape() {
   1156 	local _xcmd
   1157 
   1158 	# Get the name of the tape from the user.
   1159 	cat << \__install_tape_1
   1160 
   1161 The installation program needs to know which tape device to use.  Make
   1162 sure you use a "no rewind on close" device.
   1163 
   1164 __install_tape_1
   1165 	_tape=`basename $TAPE`
   1166 	resp=""		# force one iteration
   1167 	while [ "X${resp}" = X"" ]; do
   1168 		echo -n "Name of tape device? [${_tape}]"
   1169 		getresp "${_tape}"
   1170 	done
   1171 	_tape=`basename $resp`
   1172 	TAPE="/dev/${_tape}"
   1173 	if [ ! -c $TAPE ]; then
   1174 		echo "$TAPE does not exist or is not a character special file."
   1175 		echo "Aborting."
   1176 		return
   1177 	fi
   1178 	export TAPE
   1179 
   1180 	# Rewind the tape device
   1181 	echo -n "Rewinding tape..."
   1182 	if ! mt rewind ; then
   1183 		echo "$TAPE may not be attached to the system or may not be"
   1184 		echo "a tape device.  Aborting."
   1185 		return
   1186 	fi
   1187 	echo "done."
   1188 
   1189 	# Get the file number
   1190 	resp=""		# force one iteration
   1191 	while [ "X${resp}" = X"" ]; do
   1192 		echo -n "File number? "
   1193 		getresp ""
   1194 		case "$resp" in
   1195 			[1-9]*)
   1196 				_nskip=`expr $resp - 1`
   1197 				;;
   1198 
   1199 			*)
   1200 				echo "Invalid file number ${resp}."
   1201 				resp=""		# fore loop to repeat
   1202 				;;
   1203 		esac
   1204 	done
   1205 
   1206 	# Skip to correct file.
   1207 	echo -n "Skipping to source file..."
   1208 	if [ "X${_nskip}" != X"0" ]; then
   1209 		if ! mt fsf $_nskip ; then
   1210 			echo "Could not skip $_nskip files.  Aborting."
   1211 			return
   1212 		fi
   1213 	fi
   1214 	echo "done."
   1215 
   1216 	cat << \__install_tape_2
   1217 
   1218 There are 2 different ways the file can be stored on tape:
   1219 
   1220 	1) an image of a gzipped tar file
   1221 	2) a standard tar image
   1222 
   1223 __install_tape_2
   1224 	resp=""		# force one iteration
   1225 	while [ "X${resp}" = X"" ]; do
   1226 		echo -n "Which way is it? [1] "
   1227 		getresp "1"
   1228 		case "$resp" in
   1229 		1)
   1230 			_xcmd="pax -zr${verbose_flag}pe"
   1231 			;;
   1232 
   1233 		2)
   1234 			_xcmd="pax -r${verbose_flag}pe"
   1235 			;;
   1236 
   1237 		*)
   1238 			echo "Invalid response: $resp."
   1239 			resp=""		# force loop to repeat
   1240 			;;
   1241 		esac
   1242 		( cd /mnt; dd if=$TAPE | $_xcmd )
   1243 	done
   1244 	echo "Extraction complete."
   1245 }
   1246 
   1247 get_timezone() {
   1248 	local _a
   1249 	local _zonepath
   1250 
   1251 	#
   1252 	# If the zoneinfo is not on the installation medium or on the
   1253 	# installed filesystem, set TZ to GMT and return immediatly.
   1254 	#
   1255 	if [ ! -e /usr/share/zoneinfo -a ! -e /mnt/usr/share/zoneinfo ]; then
   1256 		TZ=GMT
   1257 		return
   1258 	fi
   1259 	if [ ! -d /usr/share/zoneinfo ]; then
   1260 		_zonepath=/mnt
   1261 	else
   1262 		_zonepath=""
   1263 	fi
   1264 		
   1265 cat << \__get_timezone_1
   1266 
   1267 Select a time zone for your location. Timezones are represented on the
   1268 system by a directory structure rooted in "/usr/share/timezone". Most
   1269 timezones can be selected by entering a token like "MET" or "GMT-6".
   1270 Other zones are grouped by continent, with detailed zone information
   1271 separated by a slash ("/"), e.g. "US/Pacific".
   1272 
   1273 To get a listing of what's available in /usr/share/zoneinfo, enter "?"
   1274 at the prompts below.
   1275 
   1276 __get_timezone_1
   1277 	if [ X$TZ = X ]; then
   1278 		TZ=`ls -l /mnt/etc/localtime 2>/dev/null | cutlast`
   1279 		TZ=${TZ#/usr/share/zoneinfo/}
   1280 	fi
   1281 	while :; do
   1282 		echo -n	"What timezone are you in [\`?' for list] [$TZ]? "
   1283 		getresp "$TZ"
   1284 		case "$resp" in
   1285 		"")
   1286 			echo "Timezone defaults to GMT"
   1287 			TZ="GMT"
   1288 			break;
   1289 			;;
   1290 		"?")
   1291 			ls ${_zonepath}/usr/share/zoneinfo
   1292 			;;
   1293 		*)
   1294 			_a=$resp
   1295 			while [ -d ${_zonepath}/usr/share/zoneinfo/$_a ]; do
   1296 				echo -n "There are several timezones available"
   1297 				echo " within zone '$_a'"
   1298 				echo -n "Select a sub-timezone [\`?' for list]: "
   1299 				getresp ""
   1300 				case "$resp" in
   1301 				"?") ls ${_zonepath}/usr/share/zoneinfo/$_a ;;
   1302 				*)	_a=${_a}/${resp}
   1303 					if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
   1304 						break;
   1305 					fi
   1306 					;;
   1307 				esac
   1308 			done
   1309 			if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
   1310 				TZ="$_a"
   1311 				echo "You have selected timezone \"$_a\"".
   1312 				break 2
   1313 			fi
   1314 			echo "'/usr/share/zoneinfo/$_a' is not a valid timezone on this system."
   1315 			;;
   1316 		esac
   1317 	done
   1318 }
   1319 
   1320 install_sets()
   1321 {
   1322 	local _yup
   1323 	_yup="FALSE"
   1324 
   1325 	# Ask the user which media to load the distribution from.
   1326 	# Ask the user if they want verbose extraction.  They might not want
   1327 	# it on, eg, SPARC frame buffer console.
   1328 	cat << \__install_sets_1
   1329 
   1330 It is now time to extract the installation sets onto the hard disk.
   1331 Make sure the sets are either on a local device (i.e. tape, CD-ROM) or on a
   1332 network server.
   1333 
   1334 Would you like to see each file listed during extraction (verbose) mode?
   1335 On some console hardware, such as serial consoles and Sun frame buffers,
   1336 this can extend the total extraction time.
   1337 __install_sets_1
   1338 	echo -n "Use verbose listing for extractions? [y] "
   1339 	getresp "y"
   1340 	case "$resp" in
   1341 	y*|Y*)
   1342 		verbose_flag=v
   1343 		;;
   1344 	*)
   1345 		echo "Not using verbose listing.."
   1346 		verbose_flag=""
   1347 		;;
   1348 	esac
   1349 
   1350 	if [ -d ${Default_sets_dir:-/dev/null} ]; then
   1351 		if dir_has_sets $Default_sets_dir $THESETS; then
   1352 			local_sets_dir=$Default_sets_dir
   1353 		fi
   1354 	fi
   1355 	if [ "X$local_sets_dir" != "X" ]; then
   1356 		install_from_mounted_fs ${local_sets_dir}
   1357 		if [ X"$_setsdone" != X ]; then
   1358 			_yup="TRUE"
   1359 		fi
   1360 	fi
   1361 
   1362 	# Go on prodding for alternate locations
   1363 	resp=""		# force at least one iteration
   1364 	while [ X"${resp}" = X ]; do
   1365 		# If _yup is not FALSE, it means that we extracted sets above.
   1366 		# If that's the case, bypass the menu the first time.
   1367 		if [ X"$_yup" = X"FALSE" ]; then
   1368 			echo -n	"Install from (f)tp, (t)ape, (C)D-ROM, (N)FS"
   1369 			echo -n " or local (d)isk? "
   1370 			getresp ""
   1371 			case "$resp" in
   1372 			d*|D*)
   1373 				install_disk
   1374 				;;
   1375 			f*|F*)
   1376 				install_ftp
   1377 				;;
   1378 			t*|T*)
   1379 				install_tape
   1380 				;;
   1381 			c*|C*)
   1382 				install_cdrom
   1383 				;;
   1384 			n*|N*)
   1385 				install_nfs
   1386 				;;
   1387 			*)
   1388 				echo "Invalid response: $resp"
   1389 				resp=""
   1390 				;;
   1391 			esac
   1392 		else
   1393 			_yup="FALSE"	# So we'll ask next time
   1394 		fi
   1395 
   1396 		# Give the user the opportunity to extract more sets. They
   1397 		# don't necessarily have to come from the same media.
   1398 		echo	""
   1399 		echo -n	"Extract more sets? [n] "
   1400 		getresp "n"
   1401 		case "$resp" in
   1402 		y*|Y*)
   1403 			# Force loop to repeat
   1404 			resp=""
   1405 			;;
   1406 
   1407 		*)
   1408 			;;
   1409 		esac
   1410 	done
   1411 }
   1412 
   1413 munge_fstab()
   1414 {
   1415 	local _fstab
   1416 	local _fstab_shadow
   1417 	local _dev
   1418 	local _mp
   1419 	local _fstype
   1420 	local _rest
   1421 
   1422 	# Now that the 'real' fstab is configured, we munge it into a 'shadow'
   1423 	# fstab which we'll use for mounting and unmounting all of the target
   1424 	# filesystems relative to /mnt.  Mount all filesystems.
   1425 	_fstab=$1
   1426 	_fstab_shadow=$2
   1427 	( while read _dev _mp _fstype _rest; do
   1428 		# Skip comment lines
   1429 		case "$_dev" in
   1430 			\#*)	continue;;
   1431 			*)	;;
   1432 		esac
   1433 		# and some filesystem types (like there are swap,kernfs,...)
   1434 		case "$_fstype" in
   1435 			ffs|ufs|nfs)	;;
   1436 			*)	continue;;
   1437 		esac
   1438 		if [ "$_mp" = "/" ]; then
   1439 			echo $_dev /mnt $_fstype $_rest
   1440 		else
   1441 			echo $_dev /mnt$_mp $_fstype $_rest
   1442 		fi
   1443 	    done ) < $_fstab > $_fstab_shadow
   1444 }
   1445 
   1446 mount_fs()
   1447 {
   1448 	# Must mount filesystems manually, one at a time, so we can make
   1449 	# sure the mount points exist.
   1450 	# $1 is a file in fstab format
   1451 	local _fstab
   1452 
   1453 	_fstab=$1
   1454 
   1455 	( while read line; do
   1456 		set -- $line
   1457 		_dev=$1
   1458 		_mp=$2
   1459 		_fstype=$3
   1460 		_opt=$4
   1461 
   1462 		# If not the root filesystem, make sure the mount
   1463 		# point is present.
   1464 		if [ "X{$_mp}" != X"/mnt" ]; then
   1465 			mkdir -p $_mp
   1466 		fi
   1467 
   1468 		# Mount the filesystem.  If the mount fails, exit
   1469 		# with an error condition to tell the outer
   1470 		# later to bail.
   1471 		if ! mount -v -t $_fstype -o async -o $_opt $_dev $_mp ; then
   1472 			# error message displated by mount
   1473 			exit 1
   1474 		fi
   1475 	done ) < $_fstab
   1476 
   1477 	if [ "X${?}" != X"0" ]; then
   1478 		cat << \__mount_filesystems_1
   1479 
   1480 FATAL ERROR:  Cannot mount filesystems.  Double-check your configuration
   1481 and restart the installation process.
   1482 __mount_filesystems_1
   1483 		exit
   1484 	fi
   1485 }
   1486 
   1487 unmount_fs()
   1488 {
   1489 	# Unmount all filesystems and check their integrity.
   1490 	# Usage: [-fast] <fstab file>
   1491 	local _fast
   1492 	local _fstab
   1493 	local _pid
   1494 
   1495 	if [ "$1" = "-fast" ]; then
   1496 		_fast=1
   1497 		_fstab=$2
   1498 	else
   1499 		_fast=0
   1500 		_fstab=$1
   1501 	fi
   1502 
   1503 	if [ ! \( -f $_fstab -a -s $_fstab \) ]; then
   1504 		echo "fstab empty" > /dev/tty
   1505 		return
   1506 	fi
   1507 
   1508 	if [ $_fast = 0 ]; then
   1509 		echo -n	"Syncing disks..."
   1510 		_pid=`twiddle`
   1511 		sync; sleep 4; sync; sleep 2; sync; sleep 2
   1512 		kill $_pid
   1513 		echo	"done."
   1514 	fi
   1515 
   1516 	(
   1517 		_devs=""
   1518 		_mps=""
   1519 		# maintain reverse order
   1520 		while read line; do
   1521 			set -- $line
   1522 			_devs="$1 ${_devs}"
   1523 			_mps="$2 ${_mps}"
   1524 		done
   1525 		echo -n "Umounting filesystems... "
   1526 		for _mp in ${_mps}; do
   1527 			echo -n "${_mp} "
   1528 			umount ${_mp}
   1529 		done
   1530 		echo "Done."
   1531 
   1532 		if [ $_fast = 0 ]; then
   1533 			exit
   1534 		fi
   1535 		echo "Checking filesystem integrity..."
   1536 		for _dev in ${_devs}; do
   1537 			echo  "${_dev}"
   1538 			fsck -f ${_dev}
   1539 		done
   1540 		echo "Done."
   1541 	) < $_fstab
   1542 }
   1543 
   1544 check_fs()
   1545 {
   1546 	# Check filesystem integrity.
   1547 	# $1 is a file in fstab format
   1548 	local _fstab
   1549 
   1550 	_fstab=$1
   1551 
   1552 	(
   1553 		_devs=""
   1554 		_mps=""
   1555 		while read line; do
   1556 			set -- $line
   1557 			_devs="$1 ${_devs}"
   1558 			_mps="$2 ${_mps}"
   1559 		done
   1560 
   1561 		echo "Checking filesystem integrity..."
   1562 		for _dev in ${_devs}; do
   1563 			echo  "${_dev}"
   1564 			fsck -f ${_dev}
   1565 		done
   1566 		echo "Done."
   1567 	) < $_fstab
   1568 }
   1569