File: [local] / src / distrib / miniroot / install.sub (download)
Revision 1.426, Wed Mar 5 01:09:58 2008 UTC (16 years, 3 months ago) by krw
Branch: MAIN
CVS Tags: OPENBSD_4_3_BASE, OPENBSD_4_3 Changes since 1.425: +2 -2 lines
Tweak regexp replacing 'off' with 'on secure' so we don't end up with
'on secure secure'.
ok deraadt@
|
# $OpenBSD: install.sub,v 1.426 2008/03/05 01:09:58 krw Exp $
# $NetBSD: install.sub,v 1.5.2.8 1996/09/02 23:25:02 pk Exp $
#
# Copyright (c) 1997-2007 Todd Miller, Theo de Raadt, Ken Westerback
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Copyright (c) 1996 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Jason R. Thorpe.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the NetBSD
# Foundation, Inc. and its contributors.
# 4. Neither the name of The NetBSD Foundation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# OpenBSD install/upgrade script common subroutines and initialization code
# Include machine-dependent functions and definitions.
#
# The following functions must be provided:
# md_congrats() - display friendly message
# md_installboot() - install boot-blocks on disk
# md_prep_disklabel() - put an OpenBSD disklabel on the disk
# md_consoleinfo() - set CDEV, CTTY, CSPEED, CPROM
#
# The following variables can be provided if required:
# MDSETS - list of files to add to THESETS
# MDTERM - 'vt220' assumed if not provided
# MDDKDEVS - '/^[sw]d[0-9][0-9]* /s/ .*//p' assumed if not provided
# MDCDDEVS - '/^cd[0-9][0-9]* /s/ .*//p' assumed if not provided
# MDMTDEVS - '/^[cms]t[0-9][0-9]* /s/ .*//p'
# MDXAPERTURE - set machdep.allowaperture=value in sysctl.conf
. install.md
set_term() {
local _tables
TERM=${TERM:-${MDTERM:-vt220}}
ask "Terminal type?" $TERM
export TERM=$resp
[[ -x /sbin/kbd ]] || return
_tables=$(bsort $(kbd -l | egrep -v "^(user|tables|encoding)"))
while :; do
ask "kbd(8) mapping? ('L' for list)" "none"
case $resp in
[Ll?]) echo "Major tables: $_tables" ;;
none) return ;;
*) kbd $resp && { echo $resp >/tmp/kbdtype ; return ; } ;;
esac
done
}
welcome() {
local _q
cat <<__EOT
Welcome to the $OBSD $MODE program.
This program will help you $MODE OpenBSD. At any prompt except password
prompts you can escape to a shell by typing '!'. Default answers are shown
in []'s and are selected by pressing RETURN. At any time you can exit this
program by pressing Control-C, but exiting during an $MODE can leave your
system in an inconsistent state.
__EOT
# Configure the terminal and keyboard.
set_term
cat <<__EOT
IS YOUR DATA BACKED UP? As with anything that modifies disk contents, this
program can cause SIGNIFICANT data loss.
__EOT
case $MODE in
upgrade)
cat <<__EOT
NOTE: once your system has been upgraded, you must manually merge any changes
to files in the 'etc' set into the files already on your system.
__EOT
_q="Proceed with upgrade?"
;;
install)
cat <<__EOT
It is often helpful to have the installation notes handy. For complex disk
configurations, relevant disk hardware manuals and a calculator are useful.
__EOT
if [ -f /etc/fstab ]; then
cat <<__EOT
You seem to be trying to restart an interrupted installation! You can skip
the disk preparation steps and continue, or you can reboot and start over.
__EOT
_q="Skip disk initialization?"
else
_q="Proceed with install?"
fi
;;
esac
ask_yn "$_q"
if [[ $resp == n ]]; then
cat <<__EOT
Enter 'halt' at the prompt to gracefully exit OpenBSD. You can then
power cycle the machine and boot your original OS.
__EOT
exit
fi
echo "Cool! Let's get to it."
}
# Echo the file $1 to standard output, skipping any lines that begin with a
# '#'. i.e. strip comment lines from the file.
stripcom () {
local _l
[[ -f $1 ]] || return
while read _l; do
[[ -n ${_l%%#*} ]] && echo $_l
done <$1
}
scan_dmesg() {
bsort $(sed -ne "$1" /var/run/dmesg.boot)
}
scan_disknames() {
local _n _oifs=$IFS
IFS=","
bsort $(for _n in $(disknames); do echo "$_n "; done | sed -ne "$1")
IFS=$_oifs
}
get_ifdevs() {
ifconfig \
| egrep -v '^[[:space:]]|(bridge|enc|gif|gre|lo|pflog|pfsync|ppp|sl|tun|vlan)[[:digit:]]+:' \
| sed -ne 's/^\(.*\):.*/\1/p'
}
get_drive() {
ask_which "$1" "contains the $MODE media" "$2"
[[ $resp == done ]] && return 1
makedev $resp || return 1
return 0
}
mount_mnt2() {
local _dev=$1 _opts _file=/tmp/parts.$1 _parts
disklabel $_dev 2>/dev/null | grep '^ [a-p]: ' \
| egrep -v "swap|unused" >$_file
_parts=$(sed -e 's/^ \(.\): .*/\1/' $_file)
set -- $_parts
[[ $# == 0 ]] && { echo "No filesystems found on $_dev" ; return 1 ; }
if isin "c" $_parts; then
# Don't ask questions if 'c' contains a filesystem.
resp=c
elif [[ $# == 1 ]]; then
# Don't ask questions if there's only one choice.
resp=$1
else
# Display partitions with filesystems and ask which to use.
cat /tmp/parts.$_dev
ask_which "$_dev partition" "has the $MODE sets" "$_parts"
[[ $resp == done ]] && return 1
fi
# Always mount msdos partitions with -s to get lower case names.
grep -q "^ $resp: .*MSDOS" $_file && _opts="-s"
mount -o ro,$_opts /dev/$_dev$resp /mnt2
}
# Ask for a password, saving the input in $resp.
# Display $1 as the prompt.
# *Don't* allow the '!' options that ask does.
# *Don't* echo input.
askpass() {
set -o noglob
stty -echo
read resp?"$1 "
stty echo
set +o noglob
echo
}
# Ask for user input.
#
# $1 = the question to ask the user
# $2 = the default answer
#
# Save the user input (or the default) in $resp.
#
# Allow the user to escape to shells ('!') or execute commands
# ('!foo') before entering the input.
ask() {
local _question=$1 _default=$2
set -o noglob
while :; do
echo -n "$_question "
[[ -z $_default ]] || echo -n "[$_default] "
read resp
case $resp in
!) echo "Type 'exit' to return to install."
sh
;;
!*) eval ${resp#?}
;;
*) : ${resp:=$_default}
break
;;
esac
done
set +o noglob
}
# Ask for user input until a non-empty reply is entered.
#
# $1 = the question to ask the user
# $2 = the default answer
#
# Save the user input (or the default) in $resp.
ask_until() {
resp=
while [[ -z $resp ]] ; do
ask "$1" "$2"
done
}
# Ask the user for a y or n, and insist on 'y', 'yes', 'n' or 'no'.
#
# $1 = the question to ask the user
# $2 = the default answer (assumed to be 'n' if empty).
#
# Return 'y' or 'n' in $resp.
ask_yn() {
local _q=$1 _a=${2:-no} _resp
typeset -l _resp
while :; do
ask "$_q" "$_a"
_resp=$resp
case $_resp in
y|yes) resp=y ; return ;;
n|no) resp=n ; return ;;
esac
done
}
# Ask for the user to select one value from a list, or 'done'.
#
# $1 = name of the list items (disk, cd, etc.)
# $2 = question to ask
# $3 = list of valid choices
# $4 = default choice, if it is not specified use the first item in $3
# $5 = error message if no items in $3, defaults to 'No $1s found.'
#
# At exit $resp holds selected item, or 'done'
ask_which() {
local _name=$1 _query=$2 _list=$3 _def=$4 _err=$5
set -- $_list
if (( $# < 1 )); then
echo "${_err:=No ${_name}s found}."
resp=done
return
fi
: ${_def:=$1}
# Eliminate extraneous (especially trailing) whitespace in _list.
_list="$*"
while :; do
# Put both lines in ask prompt, rather than use a
# separate 'echo' to ensure the entire question is
# re-ask'ed after a '!' or '!foo' shell escape.
ask "Available ${_name}s are: $_list.\nWhich one $_query? (or 'done')" "$_def"
# Quote $resp to prevent user from confusing isin() by
# entering something like 'a a'.
isin "$resp" $_list done && break
echo "'$resp' is not a valid choice."
done
}
# test the first argument against the remaining ones, return success on a match
isin() {
local _a=$1 _b
shift
for _b; do
[[ $_a == $_b ]] && return 0
done
return 1
}
# add first argument to list formed by the remaining arguments
# adds to the tail if the element does not already exist
addel() {
local _a=$1
shift
echo -n "$*"
isin "$_a" $* || echo -n " $_a"
}
# remove all occurrences of first argument from list formed by
# the remaining arguments
rmel() {
local _a=$1 _b
shift
for _b; do
[[ $_a != $_b ]] && echo -n "$_b "
done
}
bsort() {
local _l _a=$1 _b
[[ $# -gt 0 ]] || return
shift
for _b; do
if [[ $_a != $_b ]] ; then
if [[ $_a > $_b ]] ; then
_l="$_a $_l"; _a=$_b
else
_l="$_b $_l"
fi
fi
done
# Output the smallest value found.
echo -n "$_a "
# Sort remaining values.
bsort $_l
}
# Add interesting/useful comments from mnt/etc/$1 to /tmp/$1.
#
# $1 == file in /tmp and /mnt/etc directories
save_comments() {
local _file=$1
if [[ -f /mnt/etc/$_file ]]; then
grep "^#" /mnt/etc/$_file >/tmp/$_file.new
[[ -f /tmp/$_file ]] && cat /tmp/$_file >>/tmp/$_file.new
mv /tmp/$_file.new /tmp/$_file
fi
}
# Offer to edit a file in /tmp and execute ${EDITOR} to do so if the user
# accepts the offer.
#
# $1 == file in /tmp to edit
edit_tmp_file() {
local _file=$1
ask_yn "Edit $_file with $EDITOR?"
[[ $resp == y ]] && $EDITOR /tmp/$_file
}
# Offer to shell out for manual network configuration, and do so if
# the user accepts the offer.
manual_net_cfg() {
ask_yn "Do you want to do any manual network configuration?"
[[ $resp == y ]] && { echo "Type 'exit' to return to $MODE." ; sh ; }
}
# log in via ftp to host $1 as user $2 with password $3
# and return a list of all files in the directory $4 on stdout
ftp_list_files() {
ftp ${_ftp_active} -V -n "$1" <<__EOT
user "$2" "$3"
cd "$4"
ls
quit
__EOT
}
# Create a device.
#
# $1 = name of the device to create.
makedev() {
local _dev=$1
if [[ ! -r /dev/MAKEDEV ]] ; then
echo "MAKEDEV not found. Can't create device nodes."
return 1
fi
cd /dev ; sh MAKEDEV $_dev || return 1 ; cd - >/dev/null
}
# Create an entry in the hosts file. If an entry with the
# same symbolic name and address family already exists, delete it.
# $1 - IP address (v6 if it contains ':', else v4)
# $2 - symbolic name
addhostent() {
local _addr=$1 _name=$2 _delim="."
[[ $_addr == *:* ]] && _delim=":"
sed "/^[0-9a-fA-F]*[$_delim].* $_name\$/d" /tmp/hosts >/tmp/hosts.new
mv /tmp/hosts.new /tmp/hosts
echo "$_addr $_name" >>/tmp/hosts
}
# Show list of available sets and let the user select which sets to install.
#
# $1 = available sets
# $2 = already selected sets
#
# Set $resp to list of selected sets.
select_sets() {
local _avail=$1 _selected=$2 _next _f _action
cat <<__EOT
Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-' to the set name, file name pattern or 'all'. Selected
sets are labelled '[X]'.
__EOT
while :; do
_action=
_next=
echo
for _f in $_avail; do
if isin $_f $_selected; then
echo " [X] $_f"
else
echo " [ ] $_f"
: ${_next:=$_f}
fi
done
: ${_next:=done}
ask "Set name? (or 'done')" "$_next"
case $resp in
done) break ;;
-*) _action=rmel ;;
esac
: ${_action:=addel}
resp=${resp#+|-}
case $resp in
"") continue ;;
all) resp=* ;;
esac
# Use @($resp) rather than just $resp to protect
# against silly user input that might cause syntax
# errors.
for _f in $_avail; do
eval "case $_f in
@($resp)) _selected=\`$_action $_f \$_selected\` ;;
esac"
done
done
resp=$_selected
}
configure_ifs() {
local _IFDEVS=$IFDEVS _ifs _name _media _hn
while :; do
ask_which "interface" "do you wish to initialize" "$_IFDEVS" \
"" "No more interfaces to initialize"
[[ $resp == done ]] && break
_ifs=$resp
_hn=/tmp/hostname.$_ifs
# Get symbolic name - will be used in DHCP requests.
ask "Symbolic (host) name for $_ifs?" "$(hostname -s)"
_name=$resp
# Get and apply media options.
_media=$(ifconfig -m $_ifs | grep "media ")
if [[ -n $_media ]]; then
cat <<__EOT
The media options for $_ifs are currently
$(ifconfig -m $_ifs | sed -n '/supported/D;/media:/p')
__EOT
ask_yn "Do you want to change the media options?"
case $resp in
y) cat <<__EOT
Supported media options for $_ifs are:
$_media
__EOT
ask "Media options for $_ifs?"
_media=$resp
ifconfig $_ifs $_media || return 1
;;
n) _media=
;;
esac
fi
rm -f $_hn
v4_config "$_ifs" "$_media" "$_name" "$_hn"
v6_config "$_ifs" "$_media" "$_name" "$_hn"
[[ -f $_hn ]] && _IFDEVS=$(rmel "$_ifs" $_IFDEVS)
done
}
# Output '<UP | DOWN> [<addr> <netmask> <rest of inet line>]'.
#
# $1 == interface
v4_info() {
ifconfig $1 inet | sed -n '
1s/.*<UP,.*/UP/p
1s/.*<.*/DOWN/p
/inet/s/netmask//
/inet/s///p'
}
# Obtain and output the inet6 information related to the given
# interface. Should output '<UP/DOWN> <addr> <prefixlen> <rest of inet line> '.
#
# $1 == interface
v6_info() {
ifconfig $1 inet6 | sed -n '
1s/.*<UP,.*/UP/p
1s/.*<.*/DOWN/p
/scopeid/d
/inet6/s///p'
}
# Construct etc/dhclient.conf and issue DHCP request. Return FALSE if
# no IP address assigned to $1.
#
# $1 == interface
# $2 == hostname (optional).
dhcp_request() {
local _ifs=$1 _hn=$2
echo "lookup file bind" >/etc/resolv.conf.tail
if [[ -n $_hn ]]; then
_hn="send host-name \"$_hn\";"
echo "Issuing hostname-associated DHCP request for $_ifs."
else
echo "Issuing free-roaming DHCP request for $_ifs."
fi
cat >/etc/dhclient.conf <<__EOT
initial-interval 1;
$_hn
request subnet-mask, broadcast-address, routers, domain-name,
domain-name-servers, host-name;
__EOT
ifconfig $_ifs group dhcp >/dev/null 2>&1
dhclient $_ifs
set -- $(v4_info $_ifs)
if [[ $1 == UP && -n $2 ]]; then
# Move configuration files to where they will be copied to the
# installed system. Overwrites configuration information from
# last successful dhcp attempt.
mv /etc/dhclient.conf /tmp/dhclient.conf
mv /etc/resolv.conf.tail /tmp/resolv.conf.tail
return 0
fi
ifconfig $_ifs delete down
rm /etc/dhclient.conf /etc/resolv.conf.tail
return 1
}
v4_config() {
local _ifs=$1 _media=$2 _name=$3 _hn=$4 _prompt _addr _mask
if ifconfig $_ifs | grep 'groups:.* dhcp' >/dev/null 2>&1; then
_addr=dhcp
else
set -- $(v4_info $_ifs)
if [[ -n $2 ]]; then
_addr=$2; _mask=$3
ifconfig $_ifs inet $_addr delete
fi
fi
[[ -x /sbin/dhclient ]] && _prompt=" or 'dhcp'"
_prompt="IPv4 address for $_ifs? (or 'none'$_prompt)"
ask_until "$_prompt" "$_addr"
case $resp in
none) ;;
dhcp) if [[ ! -x /sbin/dhclient ]]; then
echo "DHCP not possible - no /sbin/dhclient."
elif dhcp_request $_ifs "$_name" || dhcp_request $_ifs ; then
addhostent "127.0.0.1" "$_name"
echo "dhcp NONE NONE NONE $_media" >>$_hn
fi
;;
*) _addr=$resp
ask_until "Netmask?" "${_mask:=255.255.255.0}"
ifconfig $_ifs -group dhcp >/dev/null 2>&1
if ifconfig $_ifs inet $_addr netmask $resp up ; then
addhostent "$_addr" "$_name"
echo "inet $_addr $resp NONE $_media" >$_hn
fi
;;
esac
}
v6_config() {
local _ifs=$1 _media=$2 _name=$3 _hn=$4 _addr _prefixlen _prompt
ifconfig lo0 inet6 >/dev/null 2>&1 || return
set -- $(v6_info $_ifs)
[[ -n $2 ]] && { _addr=$2; _prefixlen=$3; }
[[ -x /sbin/rtsol ]] && _prompt="or 'rtsol' "
_prompt="IPv6 address for $_ifs? (${_prompt}or 'none')"
ask_until "$_prompt" "${_addr:-none}"
case $resp in
none) return
;;
rtsol) [[ ! -x /sbin/rtsol ]] && { echo "No /sbin/rtsol." ; return ; }
ifconfig $_ifs up
rtsol -F $_ifs
addhostent "::1" "$_name"
echo "up\nrtsol $media" >>$_hn
return
;;
esac
_addr=$resp
ask_until "IPv6 prefix length for $_ifs?" "${_prefixlen:=64}"
ifconfig $_ifs inet6 $_addr prefixlen $resp up || return
echo "inet6 $_addr $resp $media" >>$_hn
addhostent "$_addr" "$_name"
v6_defroute $_ifs
[[ $resp == none ]] && return
route -n add -inet6 -host default "$resp" || return
echo "$resp" >>/tmp/mygate
}
v4_defroute() {
local _dr _prompt=" or 'none'"
[[ -x /sbin/dhclient ]] && _prompt=", 'dhcp'$_prompt"
_prompt="Default IPv4 route? (IPv4 address$_prompt)"
_dr=$(route -n show -inet | sed -ne '/^default */{s///; s/ .*//; p;}')
[[ -f /tmp/dhclient.conf ]] && _dr=dhcp
while :; do
ask_until "$_prompt" "$_dr"
[[ $resp == @(none|dhcp) ]] && break
route delete -inet default >/dev/null 2>&1
route -n add -inet -host default "$resp" && { echo "$resp" >/tmp/mygate ; break ; }
# Put the old default route back. The new one did not work.
route -n add -inet -host default $_dr >/dev/null 2>&1
done
}
v6_defroute() {
local _if=$1 _routers _oifs
if [[ -z $(route -n show -inet6 | sed -ne '/^default */{s///; s/ .*//; p;}') ]]; then
resp=none
return
fi
if [[ -x /sbin/ping6 ]]; then
_routers=$(ping6 -n -c 2 ff02::2%$_if 2>&1 | sed -n \
-e '/bytes from/{s/^.*from //;s/,.*$//;p;}')
fi
_oifs=$IFS
IFS=
PS3="IPv6 default router? (list #, IPv6 address or 'none'): "
select i in $_routers; do
case $i in
"") resp=$REPLY
[[ -n $resp ]] && break
;;
*) resp=$i
break
;;
esac
done
IFS=$_oifs
}
# Much of this is gratuitously stolen from /etc/netstart.
enable_network() {
local _netfile _gw
# Copy any required or optional files found
for _netfile in hosts dhclient.conf resolv.conf resolv.conf.tail protocols services; do
if [ -f /mnt/etc/${_netfile} ]; then
cp /mnt/etc/${_netfile} /etc/${_netfile}
fi
done
# Set the address for the loopback interface. Bringing the
# interface up, automatically invokes the IPv6 address ::1.
ifconfig lo0 inet 127.0.0.1
# configure all of the non-loopback interfaces which we know about.
# refer to hostname.if(5)
for hn in /mnt/etc/hostname.*; do
# Strip off /mnt/etc/hostname. prefix
if=${hn#/mnt/etc/hostname.}
# Check for ifconfig'able interface.
ifconfig $if >/dev/null 2>&1 || continue
# Now parse the hostname.* file
while :; do
if [ "$cmd2" ]; then
# we are carrying over from the 'read dt dtaddr' last time
set -- $cmd2
af=$1 name=$2 mask=$3 bcaddr=$4 ext1=$5 cmd2=
# make sure and get any remaining args in ext2, like the read below
i=1; while [ i -lt 6 -a -n "$1" ]; do shift; let i=i+1; done
ext2="$@"
else
# read the next line or exit the while loop
read af name mask bcaddr ext1 ext2 || break
fi
# $af can be "dhcp", "up", "rtsol", an address family, commands, or
# a comment.
case $af in
"#"*|"!"*|"bridge"|"")
# skip comments, user commands, bridges,
# and empty lines
continue
;;
"dhcp") [ "$name" = "NONE" ] && name=
[ "$mask" = "NONE" ] && mask=
[ "$bcaddr" = "NONE" ] && bcaddr=
dhcpif="$dhcpif $if"
cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 down"
cmd="$cmd; dhclient $if"
;;
"rtsol")
rtsolif="$rtsolif $if"
cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up"
;;
"up")
# The only one of these guaranteed to be set is $if
# the remaining ones exist so that media controls work
cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up"
;;
*) read dt dtaddr
if [ "$name" = "alias" ]; then
# perform a 'shift' of sorts
alias=$name
name=$mask
mask=$bcaddr
bcaddr=$ext1
ext1=$ext2
ext2=
else
alias=
fi
cmd="ifconfig $if $af $alias $name "
case $dt in
dest) cmd="$cmd $dtaddr"
;;
[a-z!]*)
cmd2="$dt $dtaddr"
;;
esac
if [ ! -n "$name" ]; then
echo "/mnt/etc/hostname.$if: invalid network configuration file"
return
fi
case $af in
inet) [ "$mask" ] && cmd="$cmd netmask $mask"
if [ "$bcaddr" -a "$bcaddr" != "NONE" ]; then
cmd="$cmd broadcast $bcaddr"
fi
[ "$alias" ] && rtcmd="; route -qn add -host $name 127.0.0.1"
;;
inet6)
[ "$mask" ] && cmd="$cmd prefixlen $mask"
cmd="$cmd $bcaddr"
;;
*) cmd="$cmd $mask $bcaddr"
esac
cmd="$cmd $ext1 $ext2$rtcmd" rtcmd=
;;
esac
eval "$cmd"
done </mnt/etc/hostname.$if
done
[[ -n $rtsolif ]] && /mnt/sbin/rtsol -F $rtsolif
# /mnt/etc/mygate, if it exists, contains the address(es) of my
# default gateway(s). Use for ipv4 if no interfaces configured via
# dhcp. Use for ipv6 if no interfaces configured via rtsol.
[[ -z $dhcpif ]] && stripcom /mnt/etc/mygate | while read _gw; do
[[ $_gw == @(*:*) ]] && continue
route -qn delete default >/dev/null 2>&1
route -qn add -host default $_gw && break
done
[[ -z $rtsolif ]] && stripcom /mnt/etc/mygate | while read _gw; do
[[ $_gw == !(*:*) ]] && continue
route -qn delete -inet6 default >/dev/null 2>&1
route -qn add -host -inet6 default $_gw && break
done
# Use loopback, not the wire.
route -qn add -host `hostname` 127.0.0.1 >/dev/null
route -qn add -net 127 127.0.0.1 -reject >/dev/null
# Display results...
echo "Network interface configuration:"
ifconfig -am
# enable the resolver if resolv.conf is available
route -n show
if [ -f /etc/resolv.conf ]; then
echo "\nResolver enabled."
else
echo "\nResolver not enabled."
fi
}
# Install a user-selected subset of the files in $2 from the source
# named in $1. Display an error message for failed installs so the
# user will know to try again.
install_files() {
local _src=$1 _files=$2 _f _sets _get_sets
# Initialize _sets to the list of sets found in _src, and initialize
# _get_sets to the intersection of _sets and DEFAULTSETS.
#
# Sets will be installed in the order given in THESETS to ensure proper
# installation. So, to minimize user confusion display the sets in the
# order in which they will be installed.
for _f in $THESETS; do
isin $_f $_files || continue;
_sets=$(addel $_f $_sets)
isin $_f $DEFAULTSETS "site$VERSION-$(hostname -s).tgz" && \
_get_sets=$(addel $_f $_get_sets)
done
if [[ -z $_sets ]]; then
# Show $_src, but delete any ftp password.
cat <<__EOT
No $OBSD sets were found at
$(echo $_src | sed -e 's/\(^ftp:\/\/[^/]*\)\(:[^/]*\)\(@.*\)/\1\3/')
Set names are: $THESETS
__EOT
return
fi
resp=y
isin INSTALL.$ARCH $_files ||
ask_yn "INSTALL.$ARCH not found. Use sets found here anyway?"
[[ $resp = n ]] && return
select_sets "$_sets" "$_get_sets"
[[ -n $resp ]] || return
_get_sets=$resp
ask_yn "Ready to $MODE sets?" yes
[[ $resp = n ]] && return
for _f in $THESETS ; do
isin $_f $_get_sets || continue
echo "Getting $_f ..."
case $_f in
*.tgz) ftp $_ftp_active -o - -V -m "$_src/$_f" | tar zxphf - -C /mnt
;;
*) ftp $_ftp_active -o "/mnt/$_f" -V -m "$_src/$_f"
;;
esac
if [ $? -ne 0 ]; then
echo "'$_f' did not install correctly."
else
DEFAULTSETS=$(rmel $_f $DEFAULTSETS)
fi
done
}
# Encode $1 as specified for usercodes and passwords in RFC 1738
# section 3.1 and section 5.
#
# Escape everything between 0x20 and 0x7e to avoid both illegal url
# characters and characters causing problems during script processing.
#
# *NOTE*
# 1) quotes around $1 are required to preserve trailing or
# embedded blanks in usercodes and passwords.
# 2) substitute '%' FIRST so it doesn't eliminate '%' chars we insert.
encode_for_url() {
echo "$1" | sed -e "
s/%/%25/g
s/ /%20/g
s/!/%21/g
s/\"/"/g
s/#/%23/g
s/\\\$/%24/g
s/&/%26/g
s/'/%27/g
s/(/%28/g
s/)/%29/g
s/\*/%2a/g
s/+/%2b/g
s/,/%2c/g
s/-/%2d/g
s/\./%2e/g
s/\//%2f/g
s/:/%3a/g
s/;/%3b/g
s/</%3c/g
s/=/%3d/g
s/>/%3e/g
s/?/%3f/g
s/@/%40/g
s/\[/%5b/g
s/\\\\/%5c/g
s/]/%5d/g
s/\^/%5e/g
s/_/%5f/g
s/\`/%60/g
s/{/%7b/g
s/|/%7c/g
s/}/%7d/g
s/~/%7e/g
"
}
# Check for the presence of an error message in the output of the ftp commands
# used to get the list of files in a directory.
#
# $1 = error message to look for
# $2 = ftp command output
ftp_error() {
if [[ -n $(echo "$2" | grep "$1") ]]; then
echo $1
return 0
fi
return 1
}
# Get several parameters from the user, and xfer
# files from the server.
# $1 = url type (ftp or http)
# Note: _ftp_server_ip, _ftp_server_dir, _ftp_server_login,
# and _ftp_active must be global.
install_url() {
local _url_type=$1 _file_list _url_base _oifs _prompt _passwd
ask "HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none')" \
"${ftp_proxy:-none}"
unset ftp_proxy http_proxy
[[ $resp == none ]] || export ftp_proxy=$resp http_proxy=$resp
rm -f $SERVERLIST
ask_yn "Display the list of known $_url_type servers?"
if [[ $resp == y ]]; then
# ftp.openbsd.org == 129.128.5.191 and will remain at
# that address for the foreseeable future.
echo -n "Getting the list from 129.128.5.191 (ftp.openbsd.org)..."
ftp $_ftp_active -V -a -o - \
ftp://129.128.5.191/$FTPDIR/ftplist 2>/tmp/ftplisterr \
| sed -ne "/^${_url_type}:\/\//s///p" >$SERVERLIST
if [[ -s $SERVERLIST ]]; then
echo "done."
_prompt="Server? (IP address, hostname, list#, 'done' or '?')"
cat -n $SERVERLIST | less -XE
else
echo "FAILED."
cat /tmp/ftplisterr
fi
fi
# Get server IP address or hostname
: ${_prompt:="Server? (IP address, hostname or 'done')"}
while :; do
eval resp=\$_${_url_type}_server_ip
ask_until "$_prompt" "$resp"
case $resp in
done) return ;;
"?") [[ -s $SERVERLIST ]] || continue
cat -n $SERVERLIST | less -XE
;;
+([0-9]))
# A numeric hostname is ignored. A number is only used
# as a line number in $SERVERLIST.
[[ -s $SERVERLIST ]] || continue
set -- $(sed -ne "${resp}p" $SERVERLIST)
[[ $# -lt 1 ]] && { echo "There is no line $resp." ; continue ; }
echo "Using $*"
eval _${_url_type}_server_ip=${1%%/*}
eval _${_url_type}_server_dir=${1#*/}/$SETDIR
# Repeat loop to get user to confirm server address.
;;
*) eval _${_url_type}_server_ip=$resp
break
;;
esac
done
# Some older servers lie about their support for passive mode ftp, so
# ask the user if it worth trying passive mode to the chosen server.
# Irrelevant if using a proxy.
if [[ $_url_type == ftp && -z $ftp_proxy ]]; then
case $_ftp_active in
-A) resp=no ;;
*) resp=yes ;;
esac
unset _ftp_active
ask_yn "Does the server support passive mode ftp?" $resp
[[ $resp == n ]] && _ftp_active=-A
fi
# Get server directory
eval resp=\$_${_url_type}_server_dir
ask_until "Server directory?" "${resp:-pub/OpenBSD/$SETDIR}"
eval _${_url_type}_server_dir=$resp
if [[ $_url_type == ftp ]]; then
# Get login name, setting IFS to nothing so trailing or
# embedded blanks are preserved!
_oifs=$IFS
IFS=
ask_until "Login?" "${_ftp_server_login:=anonymous}"
_ftp_server_login=$resp
# Get password unless login in 'anonymous' or 'ftp'
if [[ $_ftp_server_login == @(anonymous|ftp) ]]; then
_passwd=root@`hostname`
else
resp=
while [[ -z $resp ]] ; do
askpass "Password? (will not echo)"
done
_passwd=$resp
fi
IFS=$_oifs
fi
# Build up the base url since it is so nasty...
_url_base=$_url_type://
if [[ $_url_type == ftp && $_ftp_server_login != anonymous ]]; then
_url_base=$_url_base$(encode_for_url "$_ftp_server_login"):$(encode_for_url "$_passwd")@
fi
eval _url_base=$_url_base\$_${_url_type}_server_ip/\$_${_url_type}_server_dir
# XXX Workaround for problems ftp'ing out from a v6 only host.
ifconfig lo0 127.0.0.1
# Get list of files from the server.
if [[ $_url_type == ftp && -z $ftp_proxy ]] ; then
_file_list=$(ftp_list_files "$_ftp_server_ip" "$_ftp_server_login" "$_passwd" "$_ftp_server_dir")
ftp_error "Login failed." "$_file_list" && return
ftp_error "No such file or directory." "$_file_list" && return
else
# Assumes index file is "index.txt" for http (or proxy)
# We can't use index.html since the format is server-dependent
_file_list=$(ftp -o - -V "$_url_base/index.txt" | sed 's/
//')
fi
install_files "$_url_base" "$_file_list"
}
install_mounted_fs() {
local _dir
while :; do
ask_until "Pathname to the sets? (or 'done')" "$SETDIR"
[[ $resp == done ]] && return
# Accept a valid /mnt2 or /mnt relative path.
[[ -d /mnt2/$resp ]] && { _dir=/mnt2/$resp ; break ; }
[[ -d /mnt/$resp ]] && { _dir=/mnt/$resp ; break ; }
# Accept a valid absolute path.
[[ -d /$resp ]] && { _dir=/$resp ; break ; }
echo "The directory '$resp' does not exist."
done
install_files "file://$_dir" "$(ls -l $_dir)"
}
install_cdrom() {
get_drive "CD-ROM" "$CDDEVS" || return
mount_mnt2 $resp || return
install_mounted_fs
}
install_disk() {
ask_yn "Is the disk partition already mounted?"
if [[ $resp == n ]]; then
get_drive "disk" "$DKDEVS" || return
mount_mnt2 $resp || return
fi
install_mounted_fs
}
install_nfs() {
local _tcp
# Get the IP address of the server.
ask_until "Server IP address or hostname?" "$NFS_ADDR"
NFS_ADDR=$resp
# Get the server path to mount.
ask_until "Filesystem on server to mount?" "$NFS_PATH"
NFS_PATH=$resp
# Determine use of TCP
ask_yn "Use TCP transport? (requires TCP-capable NFS server)"
[[ $resp == y ]] && _tcp=-T
# Mount the server
mount_nfs $_tcp -o ro $NFS_ADDR:$NFS_PATH /mnt2 || return
install_mounted_fs
}
install_tape() {
local _z _bs
# Get the name of the tape device.
get_drive "tape drive" "$MTDEVS" || return
export TAPE=/dev/nr$resp
if [[ ! -c $TAPE ]]; then
echo "$TAPE is not a character special file."
return
fi
# Rewind the tape device.
echo -n "Rewinding $TAPE (mt rewind)..."
mt rewind || return
echo "done."
# Extract the desired files.
while :; do
ask_until "Skip how many files? (or 'done')" 0
[[ $resp == done ]] && return
[[ $resp == +([0-9]) ]] || continue
(($resp < 0)) && continue
if (($resp > 0)); then
echo -n "Skipping $resp file(s)..."
mt fsf $resp || return
echo "done."
elif [[ -n $_bs ]]; then
# Dance to start of next file.
mt bsf ; mt fsf
fi
unset _z
ask_yn "Is the file gzipped?" yes
[[ $resp == y ]] && _z=z
# Get the blocksize to use. If the file isn't gzipped then
# default to the 20 x 512 = 10,240 byte tar default.
[[ $_z == z ]] || _bs=10240
ask_until "Blocksize for this file?" "${_bs:-8k}"
[[ $resp == done ]] && return
_bs=$resp
dd if=$TAPE bs=$_bs | tar ${_z}xvphf - -C /mnt || return
done
}
set_timezone() {
local _zoneroot=/mnt/usr/share/zoneinfo/ _zonepath
# If the timezone directory structure is not
# available, return immediately.
[[ ! -d $_zoneroot ]] && return
if [[ -L /mnt/etc/localtime ]]; then
TZ=$(ls -l /mnt/etc/localtime 2>/dev/null)
TZ=${TZ#*${_zoneroot#/mnt}}
fi
: ${TZ:=GMT}
while :; do
_zonepath=$_zoneroot
ask "What timezone are you in? ('?' for list)" "$TZ"
if [[ $resp == ? ]]; then
ls -F ${_zonepath}
continue;
fi
_zonepath=${_zonepath}${resp}
while [[ -d $_zonepath ]]; do
ask "What sub-timezone of '${_zonepath#$_zoneroot}' are you in? ('?' for list)"
case $resp in
"") ;;
?) ls -F $_zonepath ;;
*) _zonepath=$_zonepath/$resp ;;
esac
done
if [[ -f $_zonepath ]]; then
TZ=${_zonepath#$_zoneroot}
echo -n "Setting local timezone to '$TZ'..."
ln -sf /usr/share/zoneinfo/$TZ /mnt/etc/localtime
echo "done."
return
fi
echo -n "'${_zonepath#$_zoneroot}'"
echo " is not a valid timezone on this system."
done
}
# Check with the user that missing required sets were deliberately skipped.
sane_install() {
local _s _m
for _s in $SANESETS; do
isin $_s $DEFAULTSETS || continue
ask_yn "'$_s' was not installed.\nAre you *SURE* your $MODE is complete without '$_s'?"
[[ $resp == n ]] && _m="$_m $_s"
done
[[ -n $_m ]] && return 1
return 0
}
# Ask the user for locations of sets, and then install whatever sets the
# user selects from that location. Repeat as many times as the user
# needs to get all desired sets.
install_sets() {
local _d=disk _locs="disk ftp http"
[[ -n $CDDEVS ]] && { _locs="cd $_locs" ; _d=cd ; }
[[ -x /sbin/mount_nfs ]] && _locs="$_locs nfs"
[[ -n $MTDEVS && -x /bin/mt ]] && _locs="$_locs tape"
echo "\nLet's $MODE the sets!"
while :; do
umount -f /mnt2 >/dev/null 2>&1
[[ -z $DEFAULTSETS ]] && _d=done
ask "Location of sets? ($_locs or 'done')" "$_d"
case $resp in
done) sane_install && return ;;
c*|C*) isin "cd" $_locs && install_cdrom ;;
d*|D*) install_disk ;;
f*|F*) isin "ftp" $_locs && install_url ftp ;;
h*|H*) isin "http" $_locs && install_url http ;;
n*|N*) isin "nfs" $_locs && install_nfs ;;
t*|T*) isin "tape" $_locs && install_tape ;;
esac
done
}
# Create a skeletal but useful /etc/fstab from /tmp/fstab by stripping all
# comment lines and dropping all filesystems which
#
# 1) can't be mounted (no mount_* command is found),
# 2) have 'xx' in the option field (usually /altroot),
# 3) have 'noauto' in the option field,
# 4) are nfs (since name resolution may not be present).
#
# In addition,
#
# 1) delete 'softdep' options (no soft updates in ramdisk kernels),
# 2) mount non-ffs filesystems read only,
# 3) prepend '/mnt' to all mount points,
# 4) delete any trailing '/' from the mount point (e.g. root),
# 5) leave out fs_freq and fs_passno fields.
#
# If no /etc/fstab is created, do not proceed with install/upgrade.
munge_fstab() {
local _dev _mp _fstype _opt _rest
while read _dev _mp _fstype _opt _rest; do
# Drop irrelevant lines and filesystems.
[[ $_dev == \#* || \
$_fstype == nfs || \
! -f /sbin/mount_$_fstype || \
$_opt == *noauto* || \
$_opt == *xx* ]] && continue
# Remove any softdep options, as soft updates are not
# available in the ramdisk kernels.
_opt=$(echo $_opt | sed -e 's/softdep//')
# Mount non-ffs filesystems read only.
[[ $_fstype == ffs ]] || _opt=$(echo $_opt | sed -e 's/rw/ro/')
# Write fs entry in fstab.
# 1) prepend '/mnt' to the mount point.
# 2) remove a trailing '/' from the mount point (e.g. root).
# 3) leave out fs_freq and fs_passno fields (i.e. $_rest).
echo $_dev /mnt${_mp%/} $_fstype $_opt
done </tmp/fstab >/etc/fstab
# If no /etc/fstab was created, we have nowhere to $MODE to.
if [ ! -s /etc/fstab ]; then
echo "Unable to create valid /etc/fstab."
exit
fi
}
# Must mount filesystems manually, one at a time, so we can make
# sure the mount points exist.
mount_fs() {
local _async=$1 _dev _mp _fstype _opt _rest
while read _dev _mp _fstype _opt _rest; do
# If not the root filesystem, make sure the mount
# point is present.
[ "$_mp" = "/mnt" ] || mkdir -p $_mp
# Mount the filesystem. If the mount fails, exit.
if ! mount -v -t $_fstype $_async -o $_opt $_dev $_mp ; then
# In addition to the error message displayed by mount ...
cat <<__EOT
FATAL ERROR: Cannot mount filesystems. Double-check your configuration
and restart the $MODE.
__EOT
exit
fi
done </etc/fstab
}
# Preen all filesystems in /etc/fstab that have a /sbin/fsck_XXX,
# showing individual results, but skipping $ROOTDEV. This was already
# fsck'ed successfully.
#
# Exit if any fsck's fail (but do them all before exiting!).
check_fs() {
local _dev _mp _fstype _rest _fail _f
ask_yn "Force checking of non-root filesystems?" yes
[[ $resp == y ]] && _f=f
while read _dev _mp _fstype _rest; do
[ "$_dev" != /dev/"$ROOTDEV" ] || continue
[ -f "/sbin/fsck_$_fstype" ] || continue
# Make sure device exists before fsck'ing it.
_rest=${_dev#/dev/}
makedev ${_rest%[a-p]} || continue
echo -n "fsck -${_f}p $_dev..."
if ! fsck -${_f}p $_dev >/dev/null 2>&1; then
echo "FAILED. You must fsck $_dev manually."
_fail=y
else
echo "OK."
fi
done </etc/fstab
[ "$_fail" ] && exit
}
# Extract fully qualified domain name from current hostname. If none is
# currently set, use 'my.domain'.
get_fqdn() {
local _dn
_dn=$(hostname)
_dn=${_dn#$(hostname -s)}
_dn=${_dn#.}
echo "${_dn:=my.domain}"
}
donetconfig() {
local _dn _ns _n
configure_ifs
# As dhclient will populate /etc/resolv.conf, a symbolic link to
# /tmp/resolv.conf.shadow, mv any such file to /tmp/resolv.conf
# so it will eventually be copied to /mnt/etc/resolv.conf and will
# not in the meantime remove the user's ability to choose to use it
# or not, during the rest of the install.
if [ -f /tmp/resolv.conf.shadow ]; then
mv /tmp/resolv.conf.shadow /tmp/resolv.conf
# Get nameserver address(es). Store as a blank separated list.
for _n in $(grep '^nameserver ' /tmp/resolv.conf); do
[[ $_n == nameserver ]] || _ns="$_ns$_n "
done
# Zap trailing space in _ns.
set -- $_ns
_ns=$*
# Get default fully qualified domain name from *first* domain
# given on *last* search or domain statement.
_dn=$(sed -n \
-e '/^domain[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \
-e '/^search[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \
-e '${g;p;}' /tmp/resolv.conf)
fi
# Get & apply fully qualified domain name to hostname.
ask "DNS domain name? (e.g. 'bar.com')" "${_dn:=$(get_fqdn)}"
hostname "$(hostname -s).$resp"
# Get/Confirm nameservers, and construct appropriate resolv.conf.
ask "DNS nameserver? (IP address or 'none')" "${_ns:=none}"
if [[ $resp != none ]]; then
echo "lookup file bind" >/tmp/resolv.conf
for _ns in $resp; do
echo "nameserver $_ns" >>/tmp/resolv.conf
done
ask_yn "Use the nameserver now?" yes
[[ $resp == y ]] && cp /tmp/resolv.conf /tmp/resolv.conf.shadow
fi
# Get/Confirm an IPv4 default route if an IPv4 address was configured.
[[ -n $(ifconfig -a | sed -ne '/[ ]inet .* broadcast /p') ]] && v4_defroute
edit_tmp_file hosts
manual_net_cfg
}
populateusrlocal() {
if [ -f /mnt/etc/mtree/BSD.local.dist ]; then
/mnt/usr/sbin/chroot /mnt /usr/sbin/mtree -Uedqn -p /usr/local -f /etc/mtree/BSD.local.dist >/dev/null
fi
}
questions() {
local _d
ask_yn "Start sshd(8) by default?" yes
if [[ $resp == n ]]; then
echo "sshd_flags=NO # disabled during install" \
>>/mnt/etc/rc.conf.local
fi
ask "NTP server? (host, 'none' or 'default')" none
if [[ $resp != none ]]; then
echo "ntpd_flags= # enabled during install" \
>>/mnt/etc/rc.conf.local
if [[ $resp != default ]]; then
# Comment out the default 'servers' line, and add a
# 'server' line with the first token in $resp as the
# server.
set -- $resp
sed -e "s/^servers /#&/;/#server /a\\
server $1
" /mnt/etc/ntpd.conf >/tmp/ntpd.conf
fi
fi
if [[ -n $MDXAPERTURE ]]; then
ask_yn "Do you expect to run the X Window System?"
if [[ $resp == y ]]; then
sed -e "/^#\(machdep\.allowaperture=${MDXAPERTURE}\)/s//\1 /" \
/mnt/etc/sysctl.conf >/tmp/sysctl.conf
cp /tmp/sysctl.conf /mnt/etc/sysctl.conf
fi
fi
[[ -n $CDEV ]] || return
_d=${CPROM:-$CDEV}
ask_yn "Change the default console to $_d?"
[[ $resp == n ]] && return
ask_which "speed" "should $_d use" "9600 19200 38400 57600 115200" \
$CSPEED
[[ $resp == done ]] && return
sed -e "/^$CTTY/s/std.9600/std.${resp}/" \
-e "/^$CTTY/s/unknown/vt220 /" \
-e "/$CTTY/s/off.*/on secure/" /mnt/etc/ttys >/tmp/ttys
[[ -n $CPROM ]] && \
echo "stty $CPROM $resp\nset tty $CPROM" >>/mnt/etc/boot.conf
}
finish_up() {
local _dev _mp _fstype _rest
# Mount all known swap partitions. This gives systems with little
# memory a better chance at running 'MAKEDEV all'.
if [[ -x /mnt/sbin/swapctl ]]; then
/mnt/sbin/swapctl -a /dev/$SWAPDEV >/dev/null 2>&1
# Can't do chmod && swapctl -A because devices are not yet
# created on install'ed systems. On upgrade'ed system there
# is a small chance the device does not exist on the ramdisk
# and will thus not get mounted.
while read _dev _mp _fstype _rest; do
[[ $_fstype == swap ]] && \
/mnt/sbin/swapctl -a $_dev >/dev/null 2>&1
done </mnt/etc/fstab
fi
if grep -qs '^rtsol' /mnt/etc/hostname.*; then
sed -e "/^#\(net\.inet6\.ip6\.accept_rtadv\)/s//\1/" \
/mnt/etc/sysctl.conf >/tmp/sysctl.conf
cp /tmp/sysctl.conf /mnt/etc/sysctl.conf
fi
echo -n "Making all device nodes..."
cd /mnt/dev
sh MAKEDEV all
# Make sure any devices we found during probe are created in the
# installed system.
for _dev in $DKDEVS $CDDEVS $MTDEVS; do
sh MAKEDEV $_dev
done
echo "done."
cd /
md_installboot $ROOTDISK
populateusrlocal
[ -x /mnt/$MODE.site ] && /mnt/usr/sbin/chroot /mnt /$MODE.site
# Pat on the back.
cat <<__EOT
CONGRATULATIONS! Your OpenBSD $MODE has been successfully completed!
To boot the new system, enter halt at the command prompt. Once the
system has halted, reset the machine and boot from the disk.
__EOT
md_congrats
}
# #######################################################################
#
# Initial actions common to both installs and upgrades.
#
# Some may require machine dependent routines, which may
# call functions defined above, so it's safest to put this
# code here rather than at the top of the file.
#
# #######################################################################
ROOTDISK=
ROOTDEV=
VERSION=43
VNAME="$(( $VERSION / 10 )).$(( $VERSION % 10 ))"
SETDIR="$VNAME/$ARCH"
FTPDIR="pub/OpenBSD/$VNAME"
OBSD="OpenBSD/$ARCH $VNAME"
SERVERLIST=/tmp/serverlist
# Do not limit ourselves during installs or upgrades.
for _opt in d f l m n p s; do
ulimit -$_opt unlimited
done
# Extract and save one boot's worth of dmesg
dmesg | sed -ne '/^OpenBSD /h;/^OpenBSD /!H;${g;p;}' >/var/run/dmesg.boot
# Scan /var/run/dmesg.boot for interesting devices.
DKDEVS=$(scan_disknames "${MDDKDEVS:-/^[sw]d[0-9][0-9]* /s/ .*//p}")
CDDEVS=$(scan_disknames "${MDCDDEVS:-/^cd[0-9][0-9]* /s/ .*//p}")
MTDEVS=$(scan_dmesg "${MDMTDEVS:-/^[cms]t[0-9][0-9]* /s/ .*//p}")
IFDEVS=$(get_ifdevs)
CONSOLE=$(scan_dmesg '/^\([^ ]*\).*: console$/s//\1/p')
CONSOLE=${CONSOLE% }
[[ -n $CONSOLE ]] && CSPEED=$(stty speed)
# Look for the serial device matching the console. If we are not installing
# from a serial console, just find the first serial device that could be used
# as a console. If a suitable device is found, set CDEV, CTTY, CSPEED, CPROM.
md_consoleinfo
# Selected sets will be installed in the order they are listed in $THESETS.
# Ensure that siteXX.tgz is the *last* set listed so its contents overwrite
# the contents of the other sets, not the other way around.
THESETS="bsd bsd.rd bsd.mp $MDSETS"
DEFAULTSETS="bsd bsd.rd"
for _set in base etc misc comp man game xbase xetc xshare xfont xserv site ; do
[[ $MODE == upgrade && ( $_set == etc || $_set == xetc ) ]] && continue
THESETS="$THESETS ${_set}${VERSION}.tgz"
isin $_set xbase xetc xshare xfont xserv site && continue
DEFAULTSETS="$DEFAULTSETS ${_set}${VERSION}.tgz"
done
# Since etc${VERSION}.tgz is not in DEFAULTSETS for upgrades, it can always be
# in SANESETS.
SANESETS="bsd base${VERSION}.tgz etc${VERSION}.tgz"
# decide upon an editor
: ${EDITOR:=ed}
[[ -x /usr/bin/vi ]] && EDITOR=vi
export EDITOR
# umount all filesystems, just in case we are re-running install or upgrade.
[[ -f /etc/fstab ]] && umount -av 1>/dev/null 2>&1
umount -v /mnt 1>/dev/null 2>&1
# Introduce ourselves.
welcome
# Get ROOTDISK, ROOTDEV and SWAPDEV.
if [[ $MODE == install && ! -f /etc/fstab ]]; then
cat <<__EOT
You will now initialize the disk(s) that OpenBSD will use. To enable all
available security features you should configure the disk(s) to allow the
creation of separate filesystems for /, /tmp, /var, /usr, and /home.
__EOT
fi
set -- $DKDEVS
[[ $# -gt 1 ]] && _defdsk=done
ask_which "disk" "is the root disk" "$DKDEVS" "$_defdsk"
[[ $resp == done ]] && exit
makedev $resp || exit
ROOTDISK=$resp
ROOTDEV=${ROOTDISK}a
SWAPDEV=${ROOTDISK}b