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