1#!/bin/sh 2# $OpenBSD: install.sub,v 1.171 2001/10/31 01:33:24 krw Exp $ 3# $NetBSD: install.sub,v 1.5.2.8 1996/09/02 23:25:02 pk Exp $ 4# 5# Copyright (c) 1997,1998 Todd Miller, Theo de Raadt 6# All rights reserved. 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 3. All advertising materials mentioning features or use of this software 17# must display the following acknowledgement: 18# This product includes software developed by Todd Miller and 19# Theo de Raadt 20# 4. The name of the author may not be used to endorse or promote products 21# derived from this software without specific prior written permission. 22# 23# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33# 34# Copyright (c) 1996 The NetBSD Foundation, Inc. 35# All rights reserved. 36# 37# This code is derived from software contributed to The NetBSD Foundation 38# by Jason R. Thorpe. 39# 40# Redistribution and use in source and binary forms, with or without 41# modification, are permitted provided that the following conditions 42# are met: 43# 1. Redistributions of source code must retain the above copyright 44# notice, this list of conditions and the following disclaimer. 45# 2. Redistributions in binary form must reproduce the above copyright 46# notice, this list of conditions and the following disclaimer in the 47# documentation and/or other materials provided with the distribution. 48# 3. All advertising materials mentioning features or use of this software 49# must display the following acknowledgement: 50# This product includes software developed by the NetBSD 51# Foundation, Inc. and its contributors. 52# 4. Neither the name of The NetBSD Foundation nor the names of its 53# contributors may be used to endorse or promote products derived 54# from this software without specific prior written permission. 55# 56# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 57# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 58# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 59# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 60# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66# POSSIBILITY OF SUCH DAMAGE. 67# 68 69# OpenBSD installation/upgrade script - common subroutines. 70 71ROOTDISK= # filled in below 72VERSION=30 73VERSION_MAJOR=$(( $VERSION / 10 )) 74VERSION_MINOR=$(( $VERSION % 10 )) 75export VERSION VERSION_MAJOR VERSION_MINOR 76 77# extra "site" set can be provided by person doing install 78ALLSETS="base etc misc comp man game xbase xshare xfont xserv site" # install 79UPGRSETS="base misc comp man game xbase xshare xfont xserv site" # upgrade 80SNAPSETS="bin dev etc games man misc sbin \ 81 usr.bin usr.binutils usr.games usr.include \ 82 usr.lib usr.libexec usr.misc usr.sbin usr.share var" 83THESETS= # one of the above 84 85# Path searched for sets by install_sets on the local filesystems 86local_sets_dir= 87 88# decide upon an editor 89if [ "X$EDITOR" = X ]; then 90 if [ -x /usr/bin/vi ]; then 91 EDITOR=vi 92 else 93 EDITOR=ed 94 fi 95 export EDITOR 96fi 97 98# Please don't use the 1 of n form below, good idea, wrong implementation! 99# get a reponse with default[s] 100getresp() { 101 local _shell_aware=0 102 local _no_shell=0 103 104 # -s option means exit after a shell (caller is shell-aware) 105 if [ "$1" = "-s" ]; then 106 _shell_aware=1 107 shift 108 fi 109 # -n option means don't try to run shell commands 110 if [ "$1" = "-n" ]; then 111 _no_shell=1 112 shift 113 fi 114 115 set -o noglob 116 valid="false" 117 while [ "X$valid" = "Xfalse" ]; do 118 read resp 119 if [ ${_no_shell} -eq 1 ]; then 120 test -z "$resp" && resp=$1 121 else 122 case "$resp" in 123 "") resp=$1 124 ;; 125 !) echo "Type 'exit' to return to install." 126 sh 127 test $_shell_aware -eq 0 && continue 128 ;; 129 !*) 130 eval ${resp#?} 131 test $_shell_aware -eq 0 && continue 132 ;; 133 esac 134 fi 135 if [ $# -gt 1 ]; then 136 for i in $@; do 137 if [ "X$resp" = "X$i" ]; then 138 valid="true" 139 fi 140 done 141 else 142 valid="true" 143 fi 144 if [ "X$valid" = "Xfalse" ]; then 145 echo "Try again: Enter one of [$@]" 146 fi 147 done 148 set +o noglob 149} 150 151isin() { 152# test the first argument against the remaining ones, return succes on a match 153 local _a=$1 154 155 shift 156 while [ $# != 0 ]; do 157 if [ "$_a" = "$1" ]; then return 0; fi 158 shift 159 done 160 return 1 161} 162 163addel() { 164# add first argument to list formed by the remaining arguments 165# adds to the tail if the element does not already exist 166 local _a=$1 _seen= 167 168 shift 169 while [ $# != 0 ]; do 170 echo "$1" 171 if [ "$_a" = "$1" ]; then 172 _seen="yes" 173 fi 174 shift 175 done 176 if [ "X$_seen" = "X" ]; then 177 echo "$_a" 178 fi 179} 180 181rmel() { 182# remove first argument from list formed by the remaining arguments 183 local _a=$1 184 185 shift 186 while [ $# != 0 ]; do 187 if [ "$_a" != "$1" ]; then 188 echo "$1" 189 fi 190 shift 191 done 192} 193 194cutword () { 195# read lines on stdin, return Nth element of each line, like cut(1) 196 local _a _n _oifs="$IFS" 197 198 # optional field separator 199 case "$1" in 200 -t?*) IFS=${1#-t}; shift;; 201 esac 202 203 _n=$1 204 while read _a; do 205 set -- $_a 206 test "$1" = "" && break 207 eval echo \$$_n 208 done 209 IFS="$_oifs" 210} 211 212cutlast () { 213# read a line of data, return last element. Equiv. of awk '{print $NF}'. 214 local _a _oifs="$IFS" 215 216 # optional field separator 217 case "$1" in 218 -t?*) IFS=${1#-t}; shift;; 219 esac 220 221 read _a; set -- $_a 222 IFS="$_oifs" 223 if [ "$1" = "" ]; then return; fi 224 while [ "$#" -gt 10 ]; do shift 10; done 225 eval echo \$$# 226} 227 228firstchar () { 229# return first character of argument 230 local _a=$1 231 232 while [ ${#_a} != 1 ]; do 233 _a=${_a%?} 234 done 235 echo $_a 236} 237 238basename () { 239 local _oifs 240 241 if [ "$1" = "" ]; then return; fi 242 _oifs="$IFS" 243 IFS="/" 244 set -- $1 245 IFS="$_oifs" 246 while [ "$#" -gt 10 ]; do shift 10; done 247 eval echo \$$# 248} 249 250isnumeric() { 251 local _a=$1 252 253 while [ ${#_a} != 0 ]; do 254 case $_a in 255 [0-9]*) ;; 256 *) echo 0; return;; 257 esac 258 _a=${_a#?} 259 done 260 echo 1; return 261} 262 263get_ifdevs() { 264 # return available network devices 265 /sbin/ifconfig -a | egrep -v '^([[:space:]]|(lo|enc|gre|ppp|sl|tun|bridge)[[:digit:]])' | cutword -t: 1 266} 267 268bsort() { 269 local _l _a=$1 270 271 if [ $# == 0 ]; then 272 return 273 fi 274 275 if [ $# == 1 ]; then 276 echo $1; return 277 fi 278 279 shift 280 while [ $# != 0 ]; do 281 local _b=$1 282 if [[ "$_a" != "$_b" ]] ; then 283 if [[ "$_a" > "$_b" ]] ; then 284 _l="$_a $_l"; _a=$_b 285 else 286 _l="$_b $_l" 287 fi 288 fi 289 shift 290 done 291 292 echo -n "$_a "; bsort $_l 293} 294 295dir_has_sets() { 296 # return true when the directory $1 contains a set for $2...$n 297 local _dir=$1 _file 298 299 shift 300 for _file in $* 301 do 302 if [ -f $_dir/${_file}${VERSION}.tar.gz ]; then 303 return 0 304 fi 305 # Try for stupid msdos convention 306 if [ -f $_dir/${_file}${VERSION}.tgz ]; then 307 return 0 308 fi 309 # Special check for kernel 310 if [ $_file = "kernel" -a -f $_dir/bsd ]; then 311 return 0 312 fi 313 done 314 return 1 315} 316 317list_has_sets() { 318 # return true when the list $1 contains a set, given dir $2 for $3...$n 319 local _list=$1 _file 320 321 shift 322 for _file in $* 323 do 324 if isin ${_file}${VERSION}.tar.gz $_list; then 325 return 0 326 fi 327 # Try for stupid msdos convention 328 if isin ${_file}${VERSION}.tgz $_list; then 329 return 0 330 fi 331 # Special check for kernel 332 if test $_file = "kernel" && isin bsd $_list; then 333 return 0 334 fi 335 done 336 return 1 337} 338 339ftp_list_files() { 340 # log in via ftp to host $1 as user $2 with password $3 341 # and return a list of all files in the directory $4 on stdout 342 local _host=$1 _user=$2 _pass=$3 _dir=$4 343 344 shift; shift; shift; shift 345 346 ftp ${_ftp_active} -V -n $_host << __ptf 347user $_user $_pass 348cd $_dir 349ls 350quit 351__ptf 352} 353 354get_localdir() { 355 # $1 is relative mountpoint 356 local _mp=$1 _dir= 357 358 while : ; do 359 echo -n "Enter the pathname where the sets are stored [$_dir] " 360 getresp "$_dir" 361 _dir=$resp 362 363 # Allow break-out with empty response 364 if [ -z "$_dir" ]; then 365 echo -n "Are you sure you don't want to set the pathname? [n] " 366 getresp "n" 367 case "$resp" in 368 y*|Y*) 369 break 370 ;; 371 *) 372 continue 373 ;; 374 esac 375 fi 376 377 if dir_has_sets "$_mp/$_dir" $THESETS 378 then 379 local_sets_dir="$_mp/$_dir" 380 break 381 else 382 cat << __EOT 383The directory \"$local_sets_dir\" does not exist, or does not hold any of the 384upgrade sets. 385__EOT 386 echo -n "Re-enter pathname? [y] " 387 getresp "y" 388 case "$resp" in 389 y*|Y*) 390 ;; 391 *) 392 local_sets_dir= 393 break 394 ;; 395 esac 396 fi 397 done 398} 399 400getanotherdisk() { 401 cat << __EOT 402 403Now you can select another disk to initialize. (Do not re-select a disk 404you have already entered information for). Available disks are: 405 406__EOT 407 _DKDEVS=`md_get_diskdevs` 408 echo "$_DKDEVS" 409 echo 410 echo -n "Which one? [done] " 411 getresp "" 412 if [ "X${resp}" = "X" ]; then 413 DISK=done 414 elif [ "X${resp}" = "Xdone" ]; then 415 DISK=done 416 elif isin $resp $_DKDEVS ; then 417 DISK="$resp" 418 else 419 echo 420 echo "The disk $resp does not exist." 421 DISK= 422 fi 423} 424 425getrootdisk() { 426 cat << __EOT 427 428The installation program needs to know which disk to consider the root disk. 429Note the unit number may be different than the unit number you used in the 430boot program (especially on a PC with multiple disk controllers). 431Available disks are: 432 433__EOT 434 local _defdsk; 435 436 _DKDEVS=`md_get_diskdevs` 437 _defdsk=`echo $_DKDEVS | cutlast` 438 if [ "${_defdsk}" != "${_DKDEVS}" ]; then 439 _defdsk= 440 fi 441 echo "$_DKDEVS" 442 echo 443 echo -n "Which disk is the root disk? [${_defdsk}] " 444 getresp "${_defdsk}" 445 if isin $resp $_DKDEVS ; then 446 ROOTDISK="$resp" 447 else 448 echo 449 echo "The disk $resp does not exist." 450 ROOTDISK= 451 fi 452} 453 454addhostent() { 455 # $1 - IP address 456 # $2 - symbolic name 457 458 # Create an entry in the hosts table. If no host table 459 # exists, create one. If the symbolic name already exists, 460 # replace its entry. 461 if [ ! -f /tmp/hosts ]; then 462 echo "127.0.0.1 localhost" > /tmp/hosts 463 fi 464 465 sed "/ $2.$FQDN $2\$/d" < /tmp/hosts > /tmp/hosts.new 466 mv /tmp/hosts.new /tmp/hosts 467 468 echo "$1 $2.$FQDN $2" >> /tmp/hosts 469} 470 471addifconfig() { 472 # $1 - interface name 473 # $2 - interface symbolic name 474 # $3 - interface IP address 475 # $4 - interface netmask 476 # $5 - (optional) interface media directives 477 478 # Create a hostname.* file for the interface. 479 if [ "$3" = "dhcp" ]; then 480 echo "dhcp NONE NONE NONE $5" > /tmp/hostname.$1 481 addhostent 127.0.0.1 $2 482 else 483 echo "inet $3 $4 NONE $5" > /tmp/hostname.$1 484 addhostent $3 $2 485 fi 486} 487 488configurenetwork() { 489 local _ifsdone= _ifs _ouranswer= _reprompt=1 490 491 _IFS=`get_ifdevs` 492 resp= # force at least one iteration 493 while [ "X${resp}" != X"done" ]; do 494 if [ $_reprompt = 1 ]; then 495 cat << __EOT 496 497You may configure the following network interfaces (the interfaces 498marked with [X] have been successfully configured): 499 500__EOT 501 502 for _ifs in $_IFS; do 503 if [ "X${_ouranswer}" = "X" ]; then 504 _ouranswer=$_ifs 505 fi 506 if isin $_ifs $_ifsdone ; then 507 echo -n " [X] " 508 else 509 echo -n " [ ] " 510 fi 511 echo $_ifs 512 done 513 echo 514 fi 515 echo -n "Configure which interface? (or, enter 'done') [$_ouranswer] " 516 getresp "$_ouranswer" 517 case "$resp" in 518 "done") 519 ;; 520 "") 521 _reprompt=0 522 ;; 523 *) 524 _ifs=$resp 525 _ouranswer="done" 526 if isin $_ifs $_IFS ; then 527 if configure_ifs $_ifs ; then 528 _ifsdone="$_ifs $_ifsdone" 529 else 530 _ouranswer= 531 fi 532 else 533 echo "Invalid response: \"$resp\" is not in list" 534 fi 535 _reprompt=1 536 ;; 537 esac 538 539 done 540} 541 542configure_ifs() { 543 local _up _if_name=$1 _if_ip _if_mask 544 local _if_symname _if_extra _hostname 545 local _dhcp_prompt 546 547 set -- `ifconfig $_if_name | sed -n ' 548 1s/.*<UP,.*$/UP/p 549 1s/.*<.*>*$/DOWN/p 550 /media:/s/^.*$// 551 /status:/s/^.*$// 552 /inet/s/--> [0-9.][0-9.]*// 553 /inet/s/netmask// 554 /inet/s/broadcast// 555 /inet/s/inet// p'` 556 557 _up=$1 558 _if_ip=$2 559 _if_mask=$3 560 561 if [ $_up = "UP" ]; then 562 ifconfig $_if_name delete down 563 fi 564 565 if [ ! -x /sbin/dhclient ]; then 566 echo "DHCP install not supported" 567 echo 568 else 569 _dhcp_prompt=" (or 'dhcp')" 570 fi 571 572 # Get IP address 573 resp= # force one iteration 574 while [ "X${resp}" = X"" ]; do 575 echo -n "IP address${_dhcp_prompt} ? [$_if_ip] " 576 getresp "$_if_ip" 577 if [ ! -x /sbin/dhclient -a "X$resp" == "Xdhcp" ]; then 578 resp= 579 fi 580 _if_ip=$resp 581 done 582 583 # Get symbolic name 584 _hostname=`hostname` 585 resp= # force one iteration 586 while [ "X${resp}" = X"" ]; do 587 echo -n "Symbolic (host) name? [$_hostname] " 588 getresp "$_hostname" 589 _if_symname=$resp 590 done 591 592 # Get netmask 593 if [ "$_if_ip" != "dhcp" ]; then 594 resp= 595 if [ "X${_if_mask}" = X"" ]; then 596 _if_mask=255.255.255.0 597 fi 598 while [ "X${resp}" = X"" ]; do 599 echo -n "Netmask ? [$_if_mask] " 600 getresp "$_if_mask" 601 _if_mask=$resp 602 done 603 fi 604 605 if [ -n "`ifconfig -m ${_if_name} | sed -n '/media/p'`" ]; then 606 echo "Your use of the network interface may require non-default" 607 echo "media directives. The default media is:" 608 ifconfig -m ${_if_name} | sed -n ' 609 /supported/D 610 /media:/p' 611 echo "This is a list of supported media:" 612 ifconfig -m ${_if_name} | sed -n ' 613 /media:/D 614 s/^ // 615 /media/p' 616 echo "If the default is not satisfactory, and you wish to use another" 617 echo "media, copy that line from above (e.g. \"media 100baseTX\")" 618 echo -n "Media directives? [$_if_extra] " 619 getresp "$_if_extra" 620 if [ "X${resp}" != X"" ]; then 621 _if_extra=$resp 622 fi 623 fi 624 625 # Configure the interface. If it 626 # succeeds, add it to the permanent 627 # network configuration info. 628 if [ "$_if_ip" = "dhcp" ]; then 629 ifconfig ${_if_name} down ${_if_extra} 630cat > /etc/dhclient.conf << __EOT 631initial-interval 1; 632send host-name "$_hostname"; 633request subnet-mask, broadcast-address, routers, 634 domain-name, domain-name-servers, host-name; 635__EOT 636 dhclient -1 ${_if_name} 637 638 set -- `ifconfig $_if_name | sed -n ' 639 1s/.*<UP,.*$/UP/p 640 1s/.*<.*>*$/DOWN/p 641 /media:/s/^.*$// 642 /status:/s/^.*$// 643 /inet/s/--> [0-9.][0-9.]*// 644 /inet/s/netmask// 645 /inet/s/broadcast// 646 /inet/s/inet// p'` 647 648 if [ $1 = "UP" -a $2 = "0.0.0.0" ]; then 649 echo "hostname-associated DHCP attempt for $_if_name failed..." 650 ifconfig $_if_name delete down 651 652 cat > /etc/dhclient.conf << __EOT 653initial-interval 1; 654request subnet-mask, broadcast-address, routers, 655 domain-name, domain-name-servers, host-name; 656__EOT 657 dhclient -1 ${_if_name} 658 set -- `ifconfig $_if_name | sed -n ' 659 1s/.*<UP,.*$/UP/p 660 1s/.*<.*>*$/DOWN/p 661 /media:/s/^.*$// 662 /status:/s/^.*$// 663 /inet/s/--> [0-9.][0-9.]*// 664 /inet/s/netmask// 665 /inet/s/broadcast// 666 /inet/s/inet// p'` 667 668 if [ $1 = "UP" -a $2 = "0.0.0.0" ]; then 669 echo "free-roaming DHCP attempt for $_if_name failed." 670 ifconfig $_if_name delete down 671 return 1 672 else 673 echo "DHCP attempt for $_if_name successful." 674 addifconfig ${_if_name} ${_if_symname} ${_if_ip} 675 return 0 676 fi 677 else 678 echo "DHCP configuration of $_if_name successful." 679 addifconfig ${_if_name} ${_if_symname} ${_if_ip} 680 return 0 681 fi 682 else 683 ifconfig ${_if_name} down 684 if ifconfig ${_if_name} inet \ 685 ${_if_ip} \ 686 netmask ${_if_mask} ${_if_extra} up ; then 687 addifconfig ${_if_name} ${_if_symname} ${_if_ip} ${_if_mask} "${_if_extra}" 688 return 0 689 fi 690 fi 691 return 1 692} 693 694# Returns true if $1 contains only alphanumerics 695isalphanumeric() { 696 local _n 697 _n=$1 698 while [ ${#_n} != 0 ]; do 699 case $_n in 700 [A-Za-z0-9]*) ;; 701 *) return 1;; 702 esac 703 _n=${_n#?} 704 done 705 return 0 706} 707 708# Much of this is gratuitously stolen from /etc/netstart. 709enable_network() { 710 # Check for required network related files 711 for _netfile in hosts myname; do 712 if [ ! -f /mnt/etc/${_netfile} ]; then 713 echo "ERROR: no /mnt/etc/${_netfile}!" 714 return 1 715 fi 716 done 717 718 # Copy any required or optional files found 719 for _netfile in hosts myname dhclient.conf resolv.conf resolv.conf.tail; do 720 if [ -f /mnt/etc/${_netfile} ]; then 721 cp /mnt/etc/${_netfile} /etc/${_netfile} 722 fi 723 done 724 725 hostname=`cat /etc/myname` 726 hostname $hostname 727 728 _didnet=1 729 730 # set the address for the loopback interface 731 ifconfig lo0 inet localhost 732 733 # use loopback, not the wire 734 route -n add -host $hostname localhost > /dev/null 735 route -n add -net 127 127.0.0.1 -reject > /dev/null 736 737 # configure all of the non-loopback interfaces which we know about. 738 # refer to hostname.if(5) 739 for hn in /mnt/etc/hostname.*; do 740 # Strip off /mnt/etc/hostname. prefix 741 if=${hn#/mnt/etc/hostname.} 742 743 # Interface names must be alphanumeric only. We check to avoid 744 # configuring backup or temp files, and to catch the "*" case. 745 if ! isalphanumeric "$if"; then 746 continue 747 fi 748 ifconfig $if > /dev/null 2>&1 749 if [ "$?" != "0" ]; then 750 continue 751 fi 752 753 # Now parse the hostname.* file 754 while :; do 755 if [ "$cmd2" ]; then 756 # we are carrying over from the 'read dt dtaddr' last time 757 set -- $cmd2 758 af="$1" name="$2" mask="$3" bcaddr="$4" ext1="$5" cmd2= 759 # make sure and get any remaining args in ext2, like the read below 760 i=1; while [ i -lt 6 -a -n "$1" ]; do shift; let i=i+1; done 761 ext2="$@" 762 else 763 # read the next line or exit the while loop 764 read af name mask bcaddr ext1 ext2 || break 765 fi 766 # $af can be "dhcp", "up", "rtsol", an address family, commands, or 767 # a comment. 768 case "$af" in 769 "#"*|"!"*|"bridge"|""|"rtsol") 770 # skip comments, user commands, bridges, 771 # IPv6 rtsol and empty lines 772 continue 773 ;; 774 "dhcp") 775 [ "$name" = "NONE" ] && name= 776 [ "$mask" = "NONE" ] && mask= 777 [ "$bcaddr" = "NONE" ] && bcaddr= 778 ifconfig $if $name $mask $bcaddr $ext1 $ext2 down 779 cmd="dhclient $if" 780 ;; 781 "up") 782 # The only one of these guaranteed to be set is $if 783 # the remaining ones exist so that media controls work 784 cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up" 785 ;; 786 *) 787 read dt dtaddr 788 if [ "$name" = "alias" ]; then 789 # perform a 'shift' of sorts 790 alias=$name 791 name=$mask 792 mask=$bcaddr 793 bcaddr=$ext1 794 ext1=$ext2 795 ext2= 796 else 797 alias= 798 fi 799 cmd="ifconfig $if $af $alias $name " 800 case "$dt" in 801 dest) 802 cmd="$cmd $dtaddr" 803 ;; 804 [a-z!]*) 805 cmd2="$dt $dtaddr" 806 ;; 807 esac 808 if [ ! -n "$name" ]; then 809 echo "/mnt/etc/hostname.$if: invalid network configuration file" 810 return 811 fi 812 case $af in 813 inet) 814 [ "$mask" ] && cmd="$cmd netmask $mask" 815 if [ "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then 816 cmd="$cmd broadcast $bcaddr" 817 fi 818 [ "$alias" ] && rtcmd="; route -n add -host $name 127.0.0.1" 819 ;; 820 inet6) 821 # Ignore IPv6 setup 822 continue 823 ;; 824 *) cmd="$cmd $mask $bcaddr" 825 esac 826 cmd="$cmd $ext1 $ext2$rtcmd" rtcmd= 827 ;; 828 esac 829 eval "$cmd" 830 done < /mnt/etc/hostname.$if 831 done 832 833 # /mnt/etc/mygate, if it exists, contains the name of my gateway host 834 # that name must be in /etc/hosts. 835 if [ -f /mnt/etc/mygate ]; then 836 route delete default > /dev/null 2>&1 837 route -n add -host default `cat /mnt/etc/mygate` 838 fi 839 840 # Get FQDN after any DHCP manipulation of resolv.conf is done 841 get_fqdn /etc/resolv.conf 842 843 # Display results... 844 echo "Network interface configuration:" 845 ifconfig -am 846 847 # enable the resolver if resolv.conf is available 848 if [ -f /etc/resolv.conf ]; then 849 route show 850 echo "\nResolver enabled." 851 else 852 route -n show 853 echo "\nResolver not enabled." 854 fi 855 856 return 0 857} 858 859 860# Print the selector and get a response 861# The list of sets is passed in as $1, sets $resp 862get_selection() { 863 local _next= _f _sets=$1 864 865 for _f in $_sets ; do 866 if isin $_f $_setsdone ; then 867 echo -n " [X] " 868 _next= 869 else 870 echo -n " [ ] " 871 if [ -z "$_next" ]; then 872 _next=$_f 873 fi 874 fi 875 echo $_f 876 done 877 878 # Get the name of the file. 879 echo -n "File name? [$_next] " 880 getresp "$_next" 881} 882 883# Do globbing on the selection and parse +/-, sets _get_files and _setsdone 884# (which must exist in the local namespace) as side effects. 885glob_selection() { 886 local _selection="$1" _parent_dir="$2" _sets="$3" 887 local _action _matched _tfile _f 888 889 if [ "X${_selection}" = X"" ]; then 890 return 891 fi 892 893 # Change +/- into add/remove 894 _action=add 895 case "$_selection" in 896 +*) _selection="${_selection#?}" 897 ;; 898 -*) _selection="${_selection#?}" 899 _action=remove 900 ;; 901 esac 902 903 # Major hack to allow the user to select globbing patterns 904 set -o noglob 905 if [ X"$_selection" = X"all" ]; then 906 _selection=* 907 fi 908 _tfile=/tmp/install_case.$$ # safe in single user mode 909 cat >$_tfile << OOF 910 case \$_f in 911 $_selection) # Add/remove file to extraction list 912 if [ "\$_action" = "add" ]; then 913 _get_files=\`addel \${_f} \${_get_files}\` 914 _setsdone=\`addel \${_f} \${_setsdone}\` 915 elif [ "\$_action" = "remove" ]; then 916 _get_files=\`rmel \${_f} \${_get_files}\` 917 _setsdone=\`rmel \${_f} \${_setsdone}\` 918 else 919 echo "Unknown action: \$_action" 920 fi 921 _matched=\$(( \$_matched + 1 )) 922 ;; 923 esac 924OOF 925 set +o noglob 926 927 # Eww. 928 _matched=0 929 for _f in $_sets; do 930 . $_tfile 931 done 932 rm -f $_tfile 933 934 if [ $_matched -eq 0 ]; then 935 echo "File $_parent_dir/$_selection does not exist. Check to make" 936 echo "sure you entered the information properly or enter 'list' for a file list." 937 fi 938} 939 940install_url() { 941# Get several parameters from the user, and xfer 942# files from the server. 943# Note: _ftp_server_ip, _ftp_server_dir, _ftp_server_login, 944# _ftp_server_password, and _ftp_active must be global. 945 946local _sets _kernel _f _file_list _get_files _failed_files _osetsdone 947local _url_type _url_base _reuse _minpat 948 949# Parse arguments, shell style 950while test $# != 0; do 951 case "$1" in 952 -ftp) _url_type=ftp ;; 953 -http) _url_type=http ;; 954 -reuse) _reuse=1 ;; 955 -minpat) shift; _minpat="$1" ;; 956 esac 957 shift 958done 959if [ X"${_minpat}" = X ]; then 960 _minpat='base*.tar.gz|base*.tgz|man*.tar.gz|man*.tgz|etc*.tar.gz|etc*.tgz|bsd' 961fi 962 963echo 964echo "This is an automated ${_url_type}-based installation process. You will be asked" 965echo "questions and then the files will be retrieved iteratively via ${_url_type}." 966echo 967 968# Reuse old values w/o prompting for anything? 969if [ X"$_reuse" = X"1" ]; then 970 _reuse= 971 if eval test X"\$_installed_via_${_url_type}" = X"1"; then 972 echo -n "Use values from previous ${_url_type} install? [y] " 973 getresp y 974 case "$resp" in 975 y*|Y*) 976 _reuse=1;; 977 esac 978 fi 979fi 980if [ X"$_reuse" = X ]; then 981 # Proxy the connections? 982 if [ "X${_proxy_host}" = X"" ]; then 983 _proxy_host=none 984 fi 985 echo -n "HTTP/FTP proxy URL? (e.g. \"http://proxy:8080\", or \"none\") [${_proxy_host}] " 986 getresp "${_proxy_host}" 987 if [ "X${resp}" = X"none" ]; then 988 unset _proxy_host ftp_proxy http_proxy 989 else 990 _proxy_host=$resp 991 export ftp_proxy=${_proxy_host} 992 export http_proxy=${_proxy_host} 993 fi 994 if [ "${_url_type}" = "ftp" -a "X$ftp_proxy" = "X" ]; then 995 # Use active mode ftp? (irrelevant if using a proxy) 996 case "${_ftp_active}" in 997 -A) resp=y ;; 998 *) resp=n ;; 999 esac 1000 echo "By default, ftp will attempt a passive connection and fall back to a normal" 1001 echo "(active) connection if that doesn't work. However, there are some very" 1002 echo "old ftp servers that claim to support passive mode, but really do not." 1003 echo "In this case, you should explicitly request an active session." 1004 echo -n "Do you want to use active ftp? [${resp}] " 1005 getresp "${resp}" 1006 case "$resp" in 1007 y*|Y*) _ftp_active=-A ;; 1008 *) unset _ftp_active ;; 1009 esac 1010 fi 1011 1012 # Provide a list of possible servers 1013 test -z "$_ftp_getlist" && _ftp_getlist=y 1014 echo -n "Do you want a list of potential ${_url_type} servers? [${_ftp_getlist}] " 1015 getresp $_ftp_getlist 1016 case "$resp" in 1017 n*|N*) _ftp_getlist=n 1018 ;; 1019 *) 1020 _ftp_getlist=y 1021 ftphost=129.128.5.191 1022 if [ "X${_resolver_enabled}" = X"TRUE" ]; then 1023 ftphost=ftp.openbsd.org 1024 fi 1025 ftp ${_ftp_active} -V -a -o /tmp/ftplist ftp://${ftphost}/pub/OpenBSD/${VERSION_MAJOR}.${VERSION_MINOR}/ftplist > /dev/null 1026 cat /tmp/ftplist | grep "^${_url_type}:" | cat -n | less -XE 1027 ;; 1028 esac 1029 1030 # Get server IP address 1031 resp= # force one iteration 1032 while [ "X${resp}" = X"" ]; do 1033 if [ -f /tmp/ftplist ]; then 1034 eval echo -n "Server IP address, hostname, or list#? [\$_${_url_type}_server_ip]\ " 1035 else 1036 eval echo -n "Server IP address, or hostname? [\$_${_url_type}_server_ip]\ " 1037 fi 1038 eval getresp "\$_${_url_type}_server_ip" 1039 if [ "X$resp" = "X?" -a -f /tmp/ftplist ]; then 1040 cat /tmp/ftplist | grep "^${_url_type}:" | cat -n | less -XE 1041 resp= 1042 elif [ -n "$resp" -a `isnumeric $resp` -eq 1 -a ${resp:-0} -ge 1 \ 1043 -a -f /tmp/ftplist ]; then 1044 maxlines=`grep "^${_url_type}:" /tmp/ftplist | cat -n | 1045 sed -n -e '$p' | cutword 1` 1046 if [ $maxlines -lt $resp ]; then 1047 echo "There is no ${resp}th line in the list." 1048 resp= 1049 continue 1050 fi 1051 tline=`grep "^${_url_type}:" /tmp/ftplist | sed -n -e "${resp}p"` 1052 url=`echo $tline | sed -e "s/^${_url_type}:\/\///" | 1053 cutword -t' ' 1 | cutword -t' ' 1` 1054 host=`echo $url | cutword -t/ 1` 1055 path=`echo $url | sed -e "s/^${host}\///"` 1056 path="${path}/${VERSION_MAJOR}.${VERSION_MINOR}/${ARCH}" 1057 eval _${_url_type}_server_ip=$host 1058 eval _${_url_type}_server_dir=$path 1059 resp= # do it again, just to double check 1060 echo "Using $tline" 1061 else 1062 eval _${_url_type}_server_ip="$resp" 1063 fi 1064 done 1065 1066 # Get server directory 1067 if [ "${_url_type}" = "ftp" -a "X${_ftp_server_dir}" = X"" ]; then 1068 # Default ftp dir 1069 _ftp_server_dir="pub/OpenBSD/${VERSION_MAJOR}.${VERSION_MINOR}/${ARCH}" 1070 fi 1071 resp= # force one iteration 1072 while [ "X${resp}" = X"" ]; do 1073 eval echo -n "Server directory? [\$_${_url_type}_server_dir]\ " 1074 eval getresp "\$_${_url_type}_server_dir" 1075 eval _${_url_type}_server_dir=$resp 1076 done 1077 1078 if [ "${_url_type}" = "ftp" ]; then 1079 # Need default values even if we proxy ftp... 1080 if [ "X${_ftp_server_login}" = X"" ]; then 1081 _ftp_server_login=anonymous 1082 fi 1083 if [ "X${_ftp_server_password}" = X"" ]; then 1084 _ftp_server_password=root@`hostname`.${FQDN} 1085 fi 1086 1087 # Get login name 1088 resp= # force one iteration 1089 while [ "X${resp}" = X"" ]; do 1090 echo -n "Login? [${_ftp_server_login}] " 1091 getresp "${_ftp_server_login}" 1092 _ftp_server_login=$resp 1093 done 1094 1095 # Get password unless anonymous 1096 if [ ${_ftp_server_login} != "anonymous" ]; then 1097 resp= # force one iteration 1098 while [ "X${resp}" = X"" ]; do 1099 echo -n "Password (will not echo): " 1100 stty -echo 1101 getresp -n "${_ftp_server_password}" 1102 stty echo 1103 echo 1104 _ftp_server_password=$resp 1105 done 1106 else 1107 # only used by ftp_list_files() 1108 _ftp_server_password=root@`hostname`.${FQDN} 1109 fi 1110 fi 1111fi 1112 1113# Build up the base url since it is so nasty... 1114if [ "${_url_type}" = "ftp" -a "${_ftp_server_login}" != "anonymous" ]; then 1115 _url_base=ftp://${_ftp_server_login}:${_ftp_server_password}@${_ftp_server_ip}/${_ftp_server_dir} 1116else 1117 eval _url_base=${_url_type}://\$_${_url_type}_server_ip/\$_${_url_type}_server_dir 1118fi 1119 1120# Get list of files from the server. 1121# XXX - check for nil $_file_list and deal 1122if [ "${_url_type}" = "ftp" -a "X${ftp_proxy}" = X"" ]; then 1123 _file_list=`ftp_list_files "$_ftp_server_ip" "$_ftp_server_login" "$_ftp_server_password" "$_ftp_server_dir"` 1124else 1125 # Assumes index file is "index.txt" for http (or proxy) 1126 # We can't use index.html since the format is server-dependent 1127 _file_list=`ftp -o - -V ${_url_base}/index.txt | sed 's/ 1128//'` 1129fi 1130 1131_sets= 1132if list_has_sets "$_file_list" $THESETS; then 1133 for _f in $THESETS ; do 1134 if [ "X${_f}" = "Xkernel" ]; then 1135 if isin bsd $_file_list; then 1136 _kernel=bsd 1137 fi 1138 elif isin ${_f}${VERSION}.tar.gz $_file_list; then 1139 _sets="$_sets ${_f}${VERSION}.tar.gz" 1140 elif isin ${_f}${VERSION}.tgz $_file_list; then 1141 _sets="$_sets ${_f}${VERSION}.tgz" 1142 fi 1143 done 1144else 1145 eval echo "There are no OpenBSD install sets available in \"\$_${_url_type}_server_dir\"." 1146 echo -n "Search for *.tar.gz and *.tgz files? [y] " 1147 getresp "y" 1148 case "$resp" in 1149 n*|N*) return ;; 1150 *) ;; 1151 esac 1152 # *.tar.gz and *.tgz are possible sets 1153 _sets= 1154 _kernel= 1155 for _f in ${_file_list} ; do 1156 case "$_f" in 1157 *.tar.gz|*.tgz) _sets="$_sets ${_f}" 1158 esac 1159 done 1160 if [ "X${_sets}" = X"" ]; then 1161 echo "There are no *.tar.gz or *.tgz files in that dir." 1162 echo -n "See a directory listing? [y] " 1163 getresp "y" 1164 case "$resp" in 1165 n*|N*) return ;; 1166 *) ;; 1167 esac 1168 echo 1169 echo "${_file_list}" 1170 echo 1171 return 1172 else 1173 echo "Adding *.tar.gz and *.tgz files to selector." 1174 fi 1175fi 1176 1177# Yes, all those blackslashes really are necesary... 1178eval echo "\\\\n"\ 1179"You will now be asked for files to extract. In addition to the files listed,\\\\n"\ 1180"you may select any file located at\\\\n"\ 1181" \$_${_url_type}_server_ip:\$_${_url_type}_server_dir\\\\n"\ 1182"You can also enter \'all\' to install all the standard sets, or \'list\' to list\\\\n"\ 1183"the files available. When you are done selecting files, enter \'done\'. Some of\\\\n"\ 1184"these sets are required for your ${MODE} and some are optional -- you will want\\\\n"\ 1185"at least the base and bsd sets. Consult the installation notes if you are not\\\\n"\ 1186"sure which sets are required!" 1187_osetsdone="$_setsdone" 1188# Set the minimal default 1189for _f in $_sets $_kernel; do 1190 eval "case $_f in \ 1191 ${_minpat}) \ 1192 if ! isin \${_f} \${_setsdone}; then \ 1193 _get_files=\`addel \${_f} \${_get_files}\` ; \ 1194 _setsdone=\`addel \${_f} \${_setsdone}\` ; \ 1195 fi ;; \ 1196 esac" 1197done 1198 1199# Allow the user to select/de-select additional sets 1200while : ; do 1201 echo 1202 echo "The following sets are available for extraction." 1203 echo "Enter filename, \`list', \`all', or \`done'." 1204 echo "You may de-select a set by prepending a '-' to its name." 1205 echo 1206 get_selection "$_sets $_kernel" 1207 1208 if [ "X${resp}" = X"done" ]; then 1209 break 1210 elif [ "X${resp}" = X"list" ]; then 1211 echo 1212 eval echo "\$_${_url_type}_server_dir:" 1213 echo "${_file_list}" 1214 continue 1215 fi 1216 1217 eval glob_selection \"$resp\" \$_${_url_type}_server_dir \"$_sets $_kernel\" 1218done 1219 1220# User may have said "done" without selecting any files 1221if [ "X${_get_files}" = X"" ]; then 1222 return 1223fi 1224 1225# Stash the fact that we configured and downloaded via this url method 1226eval _installed_via_${_url_type}=1 1227 1228echo 1229echo "Fetching files via ${_url_type} may take a long time, especially over a slow network" 1230echo -n "connection. Ready to download files? [y] " 1231getresp "y" 1232case "$resp" in 1233 y*|Y*) 1234 ;; 1235 *) 1236 _setsdone="$_osetsdone" 1237 return 1238 ;; 1239esac 1240 1241# Download the files one at a time and keep track of which ones failed 1242while test -n "${_get_files}" ; do 1243 _failed_files= 1244 echo 1245 for _f in $_get_files ; do 1246 echo "Getting ${_f} ..." 1247 if [ "X${_f}" = "X${_kernel}" ]; then 1248 ( cd /mnt ; ftp ${_ftp_active} -V -m ${_url_base}/${_f} ) 1249 else 1250 ( cd /mnt ; ftp ${_ftp_active} -o - -V -m ${_url_base}/${_f} | tar zxpf - ) 1251 fi 1252 if [ $? -ne 0 ]; then 1253 # Mark xfer as having failed,. 1254 _setsdone=`rmel $_f $_setsdone` 1255 _failed_files="${_failed_files} ${_f}" 1256 fi 1257 done 1258 1259 # Give them the option of refetching failed files. 1260 _get_files= 1261 while test -n "${_failed_files}" ; do 1262 echo 1263 echo "The following files failed to transfer and extract correctly:" 1264 echo "Choose which one(s) to refetch or 'done' to exit selector." 1265 echo "You may de-select a file by prepending a '-' to its name." 1266 echo 1267 get_selection "$_failed_files" 1268 1269 if [ "X${resp}" = X"done" ]; then 1270 break 1271 elif [ "X${resp}" = X"list" ]; then 1272 echo 1273 eval echo "\$_${_url_type}_server_dir:" 1274 echo "${_file_list}" 1275 echo 1276 continue 1277 fi 1278 1279 eval glob_selection \"$resp\" \$_${_url_type}_server_dir \"$_failed_files\" 1280 done 1281done 1282} 1283 1284install_from_mounted_fs() { 1285# $1 - directory containing installation sets 1286local _sets= _kernel _f _get_files _failed_files _osetsdone 1287 1288if [ ! -d $1 ]; then 1289 echo "No such directory: $1" 1290 return 1291fi 1292 1293if dir_has_sets $1 $THESETS; then 1294 for _f in $THESETS ; do 1295 if [ "X${_f}" = "Xkernel" ]; then 1296 if [ -f $1/bsd ]; then 1297 _kernel=bsd 1298 fi 1299 elif [ -f $1/${_f}${VERSION}.tar.gz ]; then 1300 _sets="$_sets ${_f}${VERSION}.tar.gz" 1301 elif [ -f $1/${_f}${VERSION}.tgz ]; then 1302 _sets="$_sets ${_f}${VERSION}.tgz" 1303 fi 1304 done 1305else 1306 echo "There are no OpenBSD install sets available in \"$1\"." 1307 echo -n "Search for *.tar.gz and *.tgz files? [y] " 1308 getresp "y" 1309 case "$resp" in 1310 n*|N*) return ;; 1311 *) ;; 1312 esac 1313 # *.tar.gz and *.tgz are possible sets 1314 _sets= 1315 _kernel= 1316 _sets=`cd $1 ; echo *.tar.gz *.tgz` 1317 if [ "X${_sets}" = X'*.tar.gz *.tgz' ]; then 1318 echo "There are no *.tar.gz or *.tgz files in that dir." 1319 echo -n "See a directory listing? [y] " 1320 getresp "y" 1321 case "$resp" in 1322 n*|N*) return ;; 1323 *) ;; 1324 esac 1325 echo 1326 ( cd $1 && ls ) 1327 echo 1328 return 1329 else 1330 echo "Adding *.tar.gz and *.tgz files to selector." 1331 fi 1332fi 1333 1334echo "\n"\ 1335"You will now be asked for files to extract. In addition to the\n"\ 1336"files listed in the selector you may enter any file located in\n"\ 1337"$1. You can also enter 'all' to install all the standard\n"\ 1338"sets, or 'list' to list the files avilable in $1.\n"\ 1339"When you are done selecting files, enter 'done'.\n"\ 1340"Some of these sets are required for your ${MODE} and some are optional --\n"\ 1341"You will want at least the base and bsd sets.\n"\ 1342"Consult the installation notes if you are not sure which sets are required!" 1343_osetsdone="$_setsdone" 1344# Set a minimal default 1345for _f in $_sets $_kernel; do 1346 case "$_f" in 1347 base*.tar.gz|base*.tgz|man*.tar.gz|man*.tgz|etc*.tar.gz|etc*.tgz|bsd) 1348 if ! isin ${_f} ${_setsdone}; then 1349 _get_files=`addel ${_f} ${_get_files}` 1350 _setsdone=`addel ${_f} ${_setsdone}` 1351 fi 1352 ;; 1353 esac 1354done 1355 1356# Allow the user to select/de-select additional sets 1357while : ; do 1358 echo 1359 echo "The following sets are available for extraction." 1360 echo "Enter filename, \`list', \`all', or \`done'." 1361 echo "You may de-select a set by prepending a '-' to its name." 1362 echo 1363 get_selection "$_sets $_kernel" 1364 1365 if [ "X${resp}" = X"done" ]; then 1366 break 1367 elif [ "X${resp}" = X"list" ]; then 1368 echo 1369 echo "${1}:" 1370 ( cd $1 && ls ) 1371 continue 1372 fi 1373 1374 glob_selection "$resp" "$1" "$_sets $_kernel" 1375done 1376 1377# User may have said "done" without selecting any files 1378if [ "X${_get_files}" = X"" ]; then 1379 return 1380fi 1381 1382echo 1383echo -n "Ready to extract selected file sets? [y] " 1384getresp "y" 1385case "$resp" in 1386 y*|Y*) 1387 ;; 1388 *) 1389 _setsdone="$_osetsdone" 1390 return 1391 ;; 1392esac 1393 1394# Extract the files one at a time and keep track of which ones failed 1395while test -n "${_get_files}" ; do 1396 _failed_files= 1397 echo 1398 for _f in $_get_files ; do 1399 echo "$1/${_f}:" 1400 if [ "X${_f}" = "X${_kernel}" ]; then 1401 ftp -V -m -o /mnt/$_f file:$1/$_f 1402 else 1403 ftp -V -m -o - file:$1/$_f | (cd /mnt; tar -zxpf -) 1404 fi 1405 if [ $? -ne 0 ]; then 1406 # Mark xfer as having failed,. 1407 _setsdone=`rmel $_f $_setsdone` 1408 _failed_files="${_failed_files} ${_f}" 1409 fi 1410 done 1411 1412 # Give them the option of retrying failed files. 1413 _get_files= 1414 while test -n "${_failed_files}" ; do 1415 echo 1416 echo "The following files failed to extract correctly:" 1417 echo "Choose which one(s) to retry or 'done' to exit selector." 1418 echo "You may de-select a file by prepending a '-' to its name." 1419 echo 1420 get_selection "$_failed_files" 1421 1422 if [ "X${resp}" = X"done" ]; then 1423 break 1424 elif [ "X${resp}" = X"list" ]; then 1425 echo 1426 echo "${1}:" 1427 ( cd $1 && ls ) 1428 echo 1429 continue 1430 fi 1431 1432 glob_selection "$resp" "$1" "$_failed_files" 1433 done 1434done 1435} 1436 1437install_cdrom() { 1438local _drive _range _part _fstype _directory _n 1439 1440# Get the cdrom device info 1441_CDDEVS=`md_get_cddevs` 1442if [ "X${_CDDEVS}" = X"" ]; then 1443 echo "No CD-ROM devices were found. Aborting." 1444 return 1445fi 1446 1447cat << __EOT 1448 1449The following CD-ROM devices are installed on your system. 1450Please make sure the CD is in the CD-ROM drive and select 1451the device containing the CD with the installation sets: 1452 1453$_CDDEVS 1454 1455__EOT 1456_drive=`echo $_CDDEVS | cutword 1` 1457echo -n "Which CD-ROM contains the installation media? [$_drive] " 1458getresp "$_drive" 1459case "$resp" in 1460 abort) 1461 echo "Aborting." 1462 return 1463 ;; 1464 1465 *) 1466 if isin $resp $_CDDEVS ; then 1467 _drive=$resp 1468 else 1469 echo 1470 echo "The CD-ROM $resp does not exist." 1471 echo "Aborting." 1472 return 1473 fi 1474 ;; 1475esac 1476 1477# If it is an ISO9660 CD-ROM, we don't need to ask any other questions 1478_n=0 1479until disklabel $_drive >/tmp/label.$_drive 2>&1; do 1480 # Try up to 6 times to access the CD 1481 if egrep -q '(Input/output error)|(sector size 0)' /tmp/label.$_drive; then 1482 _n=$(( $_n + 1 )) 1483 if [ _n -le 5 ]; then 1484 echo "I/O error accessing $_drive; retrying" 1485 sleep 10 1486 else 1487 echo "Cannot access $_drive. Aborting." 1488 return 1489 fi 1490 else 1491 break 1492 fi 1493done 1494echo 1495if grep -q '^ *c: .*ISO9660' /tmp/label.$_drive; then 1496 _fstype=cd9660 1497 _part=c 1498else 1499 # Get partition from user 1500 _range=`md_get_partition_range` 1501 resp= # force one iteration 1502 while [ "X${resp}" = X"" ]; do 1503 echo -n 'CD-ROM partition to mount (normally "c")? [c] ' 1504 getresp c 1505 case "$resp" in 1506 $_range) 1507 _part=$resp 1508 ;; 1509 1510 *) 1511 echo "Invalid response: $resp" 1512 resp= # force loop to repeat 1513 ;; 1514 esac 1515 done 1516 1517 # Ask for filesystem type 1518 cat << __EOT 1519 1520There are two CD-ROM filesystem types currently supported by this program: 1521cd9660 ISO-9660 1522ffs Berkeley Fast Filesystem 1523 1524__EOT 1525 resp= # force one iteration 1526 while [ "X${resp}" = X"" ]; do 1527 echo -n "Which filesystem type? [cd9660] " 1528 getresp "cd9660" 1529 case "$resp" in 1530 cd9660|ffs) 1531 _fstype=$resp 1532 ;; 1533 1534 *) 1535 echo "Invalid response: $resp" 1536 resp= # force loop to repeat 1537 ;; 1538 esac 1539 done 1540fi 1541rm -f /tmp/label.$_drive 1542 1543# Mount the CD-ROM 1544if ! mount -t ${_fstype} -o ro \ 1545 /dev/${_drive}${_part} /mnt2 ; then 1546 echo "Cannot mount CD-ROM drive. Aborting." 1547 return 1548fi 1549 1550# Get the directory where the file lives 1551if [ "X${_directory}" = X"" ]; then 1552 _directory="/${VERSION_MAJOR}.${VERSION_MINOR}/${ARCH}" 1553fi 1554resp= # force one iteration 1555while [ "X${resp}" = X"" ]; do 1556 echo "Enter the directory relative to the mount point that" 1557 echo -n "contains the file. [${_directory}] " 1558 getresp "${_directory}" 1559done 1560_directory=$resp 1561 1562install_from_mounted_fs /mnt2/${_directory} 1563umount -f /mnt2 > /dev/null 2>&1 1564} 1565 1566mount_a_disk() { 1567# Mount a disk on /mnt2. The set of disk devices to choose from 1568# is $_DKDEVS. 1569# returns 0 on failure. 1570 1571local _drive _def_partition _partition_range _partition _fstype 1572local _fsopts _directory _md_fstype _md_fsopts 1573 1574getresp "abort" 1575case "$resp" in 1576 abort) 1577 echo "Aborting." 1578 return 0 1579 ;; 1580 1581 *) 1582 if isin $resp $_DKDEVS ; then 1583 _drive=$resp 1584 else 1585 echo 1586 echo "The disk $resp does not exist." 1587 echo "Aborting." 1588 return 0 1589 fi 1590 ;; 1591esac 1592 1593# Get partition 1594cat << __EOT 1595 1596The following partitions have been found on $_drive: 1597 1598__EOT 1599disklabel $_drive 2>/dev/null | grep '^ .:' 1600echo 1601_likely_partition_range=`disklabel $_drive 2>/dev/null | \ 1602 sed -n -e '/swap/s/.*//' -e '/unused/s/.*//' \ 1603 -e '/^ .:/{s/^ \(.\).*/\1/;H;}' \ 1604 -e '${g;s/\n//g;s/^/[/;s/$/]/p;}'` 1605_partition_range=`disklabel $_drive 2>/dev/null | \ 1606 sed -n -e '/^ .:/{s/^ \(.\).*/\1/;H;}' \ 1607 -e '${g;s/\n//g;s/^/[/;s/$/]/p;}'` 1608_def_partition=`echo $_likely_partition_range | \ 1609 sed -n 's/^\[\(.\).*\]/\1/p'` 1610if [ -z "$_def_partition" ]; then 1611 _def_partition=`echo $_partition_range | \ 1612 sed -n 's/^\[\(.\).*\]/\1/p'` 1613 if [ -z "$_def_partition" ]; then 1614 echo "There are no usable partitions on that disk" 1615 return 0 1616 fi 1617fi 1618resp= # force one iteration 1619while [ "X${resp}" = X"" ]; do 1620 echo -n "Partition? [$_def_partition] " 1621 getresp "$_def_partition" 1622 case "$resp" in 1623 $_partition_range) 1624 _partition=$resp 1625 ;; 1626 1627 *) 1628 echo "Invalid response: $resp" 1629 resp= # force loop to repeat 1630 ;; 1631 esac 1632done 1633 1634# Ask for filesystem type 1635cat << __EOT 1636 1637The following filesystem types are supported: 1638default (deduced from the disklabel) 1639ffs 1640__EOT 1641_md_fstype=`md_native_fstype` 1642_md_fsopts=`md_native_fsopts` 1643if [ ! -z "$_md_fstype" ]; then 1644 echo " $_md_fstype" 1645else 1646 _md_fstype="_undefined_" 1647fi 1648resp= # force one iteration 1649while [ "X${resp}" = X"" ]; do 1650 echo -n "Which filesystem type? [default] " 1651 getresp "default" 1652 case "$resp" in 1653 default) 1654 _fstype= 1655 _fsopts="ro" 1656 ;; 1657 ffs) 1658 _fstype="-t $resp" 1659 _fsopts="async,ro" 1660 ;; 1661 $_md_fstype) 1662 _fstype="-t $resp" 1663 _fsopts=$_md_fsopts 1664 ;; 1665 *) 1666 echo "Invalid response: $resp" 1667 resp= # force loop to repeat 1668 ;; 1669 esac 1670done 1671 1672# Mount the disk 1673if ! mount $_fstype -o $_fsopts /dev/${_drive}${_partition} /mnt2; then 1674 echo "Cannot mount disk. Aborting." 1675 return 0 1676fi 1677return 1 1678} 1679 1680install_disk() { 1681local _directory 1682 1683cat << __EOT 1684 1685The following disk devices are installed on your system; please select 1686the disk device containing the partition with the installation sets: 1687 1688__EOT 1689_DKDEVS=`md_get_diskdevs` 1690echo "$_DKDEVS" 1691echo 1692echo -n "Which is the disk with the installation sets? [abort] " 1693 1694if mount_a_disk ; then 1695 return 1696fi 1697 1698# Get the directory where the file lives 1699resp= # force one iteration 1700while [ "X${resp}" = X"" ]; do 1701 echo "Enter the directory relative to the mount point that" 1702 echo -n "contains the file. [${_directory}] " 1703 getresp "${_directory}" 1704done 1705_directory=$resp 1706 1707install_from_mounted_fs /mnt2/${_directory} 1708umount -f /mnt2 > /dev/null 2>&1 1709} 1710 1711install_nfs() { 1712# Get the IP address of the server 1713resp= # force one iteration 1714while [ "X${resp}" = X"" ]; do 1715 echo -n "Server IP address or hostname? [${_nfs_server_ip}] " 1716 getresp "${_nfs_server_ip}" 1717done 1718_nfs_server_ip=$resp 1719 1720# Get server path to mount 1721resp= # force one iteration 1722while [ "X${resp}" = X"" ]; do 1723 echo -n "Filesystem on server to mount? [${_nfs_server_path}] " 1724 getresp "${_nfs_server_path}" 1725done 1726_nfs_server_path=$resp 1727 1728# Determine use of TCP 1729echo -n "Use TCP transport (only works with capable NFS server)? [n] " 1730getresp "n" 1731case "$resp" in 1732 y*|Y*) 1733 _nfs_tcp="-T" 1734 ;; 1735 1736 *) 1737 _nfs_tcp= 1738 ;; 1739esac 1740 1741# Mount the server 1742mkdir /mnt2 > /dev/null 2>&1 1743if ! mount_nfs $_nfs_tcp ${_nfs_server_ip}:${_nfs_server_path} \ 1744 /mnt2 ; then 1745 echo "Cannot mount NFS server. Aborting." 1746 return 1747fi 1748 1749# Get the directory where the file lives 1750resp= # force one iteration 1751while [ "X${resp}" = X"" ]; do 1752 echo "Enter the directory relative to the mount point that" 1753 echo -n "contains the file. [${_nfs_directory}] " 1754 getresp "${_nfs_directory}" 1755done 1756_nfs_directory=$resp 1757 1758install_from_mounted_fs /mnt2/${_nfs_directory} 1759umount -f /mnt2 > /dev/null 2>&1 1760} 1761 1762install_tape() { 1763local _xcmd 1764 1765# Get the name of the tape from the user. 1766cat << __EOT 1767 1768The installation program needs to know which tape device to use. Make 1769sure you use a "no rewind on close" device. 1770 1771__EOT 1772_tape=`basename $TAPE` 1773resp= # force one iteration 1774while [ "X${resp}" = X"" ]; do 1775 echo -n "Name of tape device? [${_tape}]" 1776 getresp "${_tape}" 1777done 1778_tape=`basename $resp` 1779TAPE="/dev/${_tape}" 1780if [ ! -c $TAPE ]; then 1781 echo "$TAPE does not exist or is not a character special file." 1782 echo "Aborting." 1783 return 1784fi 1785export TAPE 1786 1787# Rewind the tape device 1788echo -n "Rewinding tape..." 1789if ! mt rewind ; then 1790 echo "$TAPE may not be attached to the system or may not be" 1791 echo "a tape device. Aborting." 1792 return 1793fi 1794echo "done." 1795 1796# Get the file number 1797resp= # force one iteration 1798while [ "X${resp}" = X"" ]; do 1799 echo -n "File number? " 1800 getresp "" 1801 case "$resp" in 1802 [1-9]*) 1803 _nskip=$(( $resp - 1 )) 1804 ;; 1805 1806 *) 1807 echo "Invalid file number ${resp}." 1808 resp= # force loop to repeat 1809 ;; 1810 esac 1811done 1812 1813# Skip to correct file. 1814echo -n "Skipping to source file..." 1815if [ "X${_nskip}" != X"0" ]; then 1816 if ! mt fsf $_nskip ; then 1817 echo "Could not skip $_nskip files. Aborting." 1818 return 1819 fi 1820fi 1821echo "done." 1822 1823cat << __EOT 1824 1825There are 2 different ways the file can be stored on tape: 1826 18271) an image of a gzipped tar file 18282) a standard tar image 1829 1830__EOT 1831resp= # force one iteration 1832while [ "X${resp}" = X"" ]; do 1833 echo -n "Which way is it? [1] " 1834 getresp "1" 1835 case "$resp" in 1836 1) 1837 _xcmd="tar -zxvpf -" 1838 ;; 1839 1840 2) 1841 _xcmd="tar -xvpf -" 1842 ;; 1843 1844 *) 1845 echo "Invalid response: $resp." 1846 resp= # force loop to repeat 1847 ;; 1848 esac 1849 ( cd /mnt; dd if=$TAPE | $_xcmd ) 1850done 1851echo "Extraction complete." 1852} 1853 1854get_timezone() { 1855local _a _zonepath 1856 1857# 1858# If the zoneinfo is not on the installation medium or on the 1859# installed filesystem, set TZ to GMT and return immediatly. 1860# 1861if [ ! -e /usr/share/zoneinfo -a ! -e /mnt/usr/share/zoneinfo ]; then 1862 TZ=GMT 1863 return 1864fi 1865if [ ! -d /usr/share/zoneinfo ]; then 1866 _zonepath=/mnt 1867else 1868 _zonepath= 1869fi 1870 1871cat << __EOT 1872 1873Select a time zone for your location. Timezones are represented on the system 1874by a directory structure rooted in "/usr/share/timezone". Most timezones can 1875be selected by entering a token like "CET" or "GMT-6". Other zones are 1876grouped by continent or country, with detailed zone information separated by 1877a slash ("/"), e.g. "US/Pacific" or "Canada/Mountain". 1878 1879To get a listing of what's available in /usr/share/zoneinfo, enter "?" 1880at the prompts below. 1881 1882__EOT 1883if [ X$TZ = X ]; then 1884 TZ=`ls -l /mnt/etc/localtime 2>/dev/null | cutlast` 1885 TZ=${TZ#/usr/share/zoneinfo/} 1886fi 1887while : ; do 1888 echo -n "What timezone are you in? [\`?' for list] [$TZ] " 1889 getresp "$TZ" 1890 case "$resp" in 1891 "") 1892 echo "Timezone defaults to GMT" 1893 TZ="GMT" 1894 break; 1895 ;; 1896 "?") 1897 ls -F ${_zonepath}/usr/share/zoneinfo 1898 ;; 1899 *) 1900 _a=$resp 1901 while [ -d ${_zonepath}/usr/share/zoneinfo/$_a ]; do 1902 echo -n "There are several timezones available" 1903 echo " within zone '$_a'" 1904 echo -n "Select a sub-timezone [\`?' for list]: " 1905 getresp "" 1906 case "$resp" in 1907 "?") ls -F ${_zonepath}/usr/share/zoneinfo/$_a ;; 1908 *) _a=${_a}/${resp} 1909 if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then 1910 break; 1911 fi 1912 ;; 1913 esac 1914 done 1915 if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then 1916 TZ="$_a" 1917 echo "You have selected timezone \"$_a\"". 1918 return 1919 fi 1920 echo "'/usr/share/zoneinfo/$_a' is not a valid timezone on this system." 1921 ;; 1922 esac 1923done 1924} 1925 1926sane_install() { 1927 if [ ! -s /mnt/bsd ]; then 1928 cat << __EOT 1929 1930Warning, no kernel (/mnt/bsd) installed! You did not unpack a file set 1931containing a kernel--this is needed to boot. Please note that the install 1932kernel is *not* suitable for general use. 1933__EOT 1934 elif [ ! -f /mnt/bin/cat ]; then 1935 cat << __EOT 1936 1937You still do not have a /bin/cat in your filesystem (i.e. a sample random file 1938which you probably want). This seems to indicate that you are still missing 1939important distribution files. 1940__EOT 1941 elif [ ! -d /mnt/etc -o ! -d /mnt/usr/share/zoneinfo -o ! -d /mnt/dev ]; then 1942 cat << __EOT 1943 1944Something needed to complete the installation seems to be missing, did you 1945forget to extract a required set? 1946__EOT 1947 else 1948 return 0; 1949 fi 1950 1951 cat << __EOT 1952 1953You will now be given the chance to install the missing set(s). You can 1954enter '!' at the prompt to escape to a shell and fix things by hand if you wish. 1955 1956__EOT 1957 1958 return 1 1959} 1960 1961install_sets() { 1962local _yup="FALSE" _have_nfs 1963 1964# Can we do an NFS install? 1965test -f /sbin/mount_nfs && _have_nfs=true 1966 1967# Ask the user which media to load the distribution from. 1968cat << __EOT 1969It is now time to extract the installation sets onto the hard disk. Make sure 1970the sets are either on a local device (i.e. tape, CD-ROM) or on a network 1971server. You will have the chance to repeat this step or to extract sets from 1972several places, so you don't have to try to load all the sets in one try and 1973can recover from some errors. 1974 1975__EOT 1976 1977if [ "X$local_sets_dir" != "X" ]; then 1978 install_from_mounted_fs ${local_sets_dir} 1979 if [ X"$_setsdone" != X ]; then 1980 _yup="TRUE" 1981 fi 1982fi 1983 1984# Go on prodding for alternate locations 1985resp= # force at least one iteration 1986while [ X"${resp}" = X ]; do 1987 # If _yup is not FALSE, it means that we extracted sets above. 1988 # If that's the case, bypass the menu the first time. 1989 if [ X"$_yup" = X"FALSE" ]; then 1990 echo -n "Install from (f)tp, (h)ttp, (t)ape, (C)D-ROM" 1991 test -n "$_have_nfs" && echo -n ", (N)FS" 1992 echo -n " or local (d)isk? " 1993 getresp "" 1994 case "$resp" in 1995 d*|D*) 1996 install_disk 1997 resp=d 1998 ;; 1999 f*|F*) 2000 test -n "$_didnet" || donetconfig 2001 install_url -ftp 2002 resp=f 2003 ;; 2004 h*|H*) 2005 test -n "$_didnet" || donetconfig 2006 install_url -http 2007 resp=h 2008 ;; 2009 t*|T*) 2010 install_tape 2011 resp=t 2012 ;; 2013 c*|C*) 2014 install_cdrom 2015 resp=c 2016 ;; 2017 n*|N*) 2018 test -n "$_didnet" || donetconfig 2019 if [ -n "$_have_nfs" ]; then 2020 install_nfs 2021 resp=n 2022 else 2023 echo "Invalid response: $resp" 2024 resp= 2025 fi 2026 ;; 2027 *) 2028 echo "Invalid response: $resp" 2029 resp= 2030 ;; 2031 esac 2032 else 2033 _yup="FALSE" # So we'll ask next time 2034 fi 2035 2036 # Perform sanity checks... 2037 if sane_install; then 2038 # Give the user the opportunity to extract more sets. They 2039 # don't necessarily have to come from the same media. 2040 echo 2041 echo -n "Extract more sets? [n] " 2042 getresp "n" 2043 case "$resp" in 2044 y*|Y*) 2045 # Force loop to repeat 2046 resp= 2047 ;; 2048 2049 *) 2050 ;; 2051 esac 2052 else 2053 # Not sane, don't exit loop. 2054 resp= 2055 fi 2056done 2057} 2058 2059munge_fstab() { 2060local _fstab _fstab_shadow _dev _mp _fstype _dev _options 2061 2062# Create a 'shadow' fstab to use for mounting and unmounting all 2063# of the target filesystems relative to /mnt. 2064_fstab=$1 2065_fstab_shadow=$2 2066( while read _dev _mp _fstype _options _rest; do 2067 # Skip comment lines, non-ffs filesystems and 2068 # 'noauto' filesystems. 2069 case "$_dev" in 2070 \#*) continue;; 2071 *) ;; 2072 esac 2073 case "$_fstype" in 2074 ffs) ;; 2075 *) continue;; 2076 esac 2077 case "$_options" in 2078 *noauto*) continue;; 2079 *) ;; 2080 esac 2081 # Don't use soft updates 2082 _options="$(echo ${_options} | sed 's/,softdep,/,/; s/,softdep//; s/softdep,//')" 2083 if [ "$_mp" = "/" ]; then 2084 _mp="" 2085 fi 2086 echo $_dev /mnt$_mp $_fstype $_options $_rest 2087 done ) < $_fstab > $_fstab_shadow 2088} 2089 2090mount_fs() { 2091# Must mount filesystems manually, one at a time, so we can make 2092# sure the mount points exist. 2093# $1 is a file in fstab format 2094local _fstab=$1 2095local _async=$2 2096 2097( while read line; do 2098 set -- $line 2099 _dev=$1 2100 _mp=$2 2101 _fstype=$3 2102 _opt=$4 2103 2104 # If not the root filesystem, make sure the mount 2105 # point is present. 2106 if [ "X{$_mp}" != X"/mnt" ]; then 2107 mkdir -p $_mp 2108 fi 2109 2110 # Mount the filesystem. If the mount fails, exit 2111 # with an error condition to tell the outer 2112 # later to bail. 2113 if ! mount -v -t $_fstype $_async -o $_opt $_dev $_mp ; then 2114 # error message displayed by mount 2115 exit 1 2116 fi 2117done ) < $_fstab 2118 2119if [ "X${?}" != X"0" ]; then 2120 cat << __EOT 2121 2122FATAL ERROR: Cannot mount filesystems. Double-check your configuration 2123and restart the installation process. 2124__EOT 2125 exit 2126fi 2127} 2128 2129unmount_fs() { 2130# Unmount all filesystems and check their integrity. 2131# Usage: [-check] <fstab file> 2132local _check _fstab _pid 2133 2134if [ "$1" = "-check" ]; then 2135 _check=1 2136 _fstab=$2 2137else 2138 _check=0 2139 _fstab=$1 2140fi 2141 2142if [ ! \( -f $_fstab -a -s $_fstab \) ]; then 2143 echo "fstab empty" > /dev/tty 2144 return 2145fi 2146 2147( 2148 _devs= 2149 _mps= 2150 # maintain reverse order 2151 while read line; do 2152 set -- $line 2153 _devs="$1 ${_devs}" 2154 _mps="$2 ${_mps}" 2155 done 2156 echo -n "Unmounting filesystems... " 2157 for _mp in ${_mps}; do 2158 echo -n "${_mp} " 2159 umount ${_mp} 2160 done 2161 echo "... Done." 2162 2163 if [ $_check = 1 ]; then 2164 echo "Checking filesystem integrity..." 2165 for _dev in ${_devs}; do 2166 echo "${_dev}" 2167 fsck -f ${_dev} 2168 done 2169 echo "... Done." 2170 fi 2171) < $_fstab 2172} 2173 2174remount_fs() { 2175( while read line; do 2176 set -- $line 2177 _dev=$1 2178 _mp=$2 2179 _fstype=$3 2180 _opt=$4 2181 2182 if ! mount -u -o $_opt $_dev $_mp ; then 2183 # error message displayed by mount 2184 exit 1 2185 fi 2186done ) < $1 2187} 2188 2189check_fs() { 2190# Check filesystem integrity. 2191# $1 is a file in fstab format 2192local _fstab=$1 2193 2194( 2195 _devs= 2196 _mps= 2197 while read line; do 2198 set -- $line 2199 _devs="$1 ${_devs}" 2200 _mps="$2 ${_mps}" 2201 done 2202 2203 echo "Checking filesystem integrity..." 2204 for _dev in ${_devs}; do 2205 echo "${_dev}" 2206 fsck -f ${_dev} 2207 done 2208 echo "Done." 2209) < $_fstab 2210} 2211 2212get_fqdn() { 2213 # Find LAST instance of DOMAIN or SEARCH and extract first domain name 2214 # on that line as FQDN. Then ask user, just to be sure. 2215 2216 if [ -f "$1" ]; then 2217 FQDN=`sed -n \ 2218 -e '/^domain[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \ 2219 -e '/^search[[:space:]][[:space:]]*/{s///;s/\([^[:space:]]*\).*$/\1/;h;}' \ 2220 -e '${g;p;}' $1` 2221 fi 2222 2223 resp= # force at least one iteration 2224 while [ "X${resp}" = X"" ]; do 2225 echo -n "Enter DNS domain name (e.g. \"bar.com\"): [$FQDN] " 2226 getresp "$FQDN" 2227 done 2228 2229 FQDN=$resp 2230} 2231 2232donetconfig() { 2233 _didnet=1 2234 resp= # force at least one iteration 2235 _nam= 2236 if [ -f /tmp/myname ]; then 2237 _nam=`cat /tmp/myname` 2238 fi 2239 while [ "X${resp}" = X"" ]; do 2240 echo -n "Enter system hostname (short form, e.g. \"foo\"): [$_nam] " 2241 getresp "$_nam" 2242 done 2243 hostname $resp 2244 echo $resp > /tmp/myname 2245 2246 echo 2247 echo "If you have any devices being configured by a DHCP server" 2248 echo "it is recommended that you do not enter a default route or" 2249 echo "any name servers." 2250 echo 2251 2252 # Get FQDN before creation of hosts file entries in addhostent() 2253 if [ -f /tmp/resolv.conf.shadow ]; then 2254 get_fqdn /tmp/resolv.conf.shadow 2255 else 2256 # If install is being re-run, save a few keystrokes 2257 get_fqdn /tmp/resolv.conf 2258 fi 2259 2260 configurenetwork 2261 2262 resp=`route -n show | 2263 grep '^default' | 2264 sed -e 's/^default //' -e 's/ .*//'` 2265 if [ "X${resp}" = "X" ]; then 2266 resp=none 2267 if [ -f /tmp/mygate ]; then 2268 resp=`cat /etc/mygate` 2269 if [ "X${resp}" = "X" ]; then 2270 resp="none"; 2271 fi 2272 fi 2273 fi 2274 echo -n "Enter IP address of default route: [$resp] " 2275 getresp "$resp" 2276 if [ "X${resp}" != X"none" ]; then 2277 route delete default > /dev/null 2>&1 2278 if route add default $resp > /dev/null ; then 2279 echo $resp > /tmp/mygate 2280 fi 2281 fi 2282 2283 resp="none" 2284 if [ -f /etc/resolv.conf ]; then 2285 resp= 2286 for n in `grep '^nameserver ' /etc/resolv.conf | \ 2287 sed -e 's/^nameserver //'`; do 2288 if [ "X${resp}" = "X" ]; then 2289 resp="$n" 2290 else 2291 resp="$resp $n" 2292 fi 2293 done 2294 elif [ -f /tmp/resolv.conf ]; then 2295 resp= 2296 for n in `grep '^nameserver ' /tmp/resolv.conf | \ 2297 sed -e 's/^nameserver //'`; do 2298 if [ "X${resp}" = "X" ]; then 2299 resp="$n" 2300 else 2301 resp="$resp $n" 2302 fi 2303 done 2304 fi 2305 echo -n "Enter IP address of primary nameserver: [$resp] " 2306 getresp "$resp" 2307 if [ "X${resp}" != X"none" ]; then 2308 echo "search $FQDN" > /tmp/resolv.conf 2309 for n in `echo ${resp}`; do 2310 echo "nameserver $n" >> /tmp/resolv.conf 2311 done 2312 echo "lookup file bind" >> /tmp/resolv.conf 2313 2314 echo -n "Would you like to use the nameserver now? [y] " 2315 getresp "y" 2316 case "$resp" in 2317 y*|Y*) 2318 cp /tmp/resolv.conf \ 2319 /tmp/resolv.conf.shadow 2320 ;; 2321 2322 *) 2323 ;; 2324 esac 2325 fi 2326 2327 if [ ! -f /tmp/resolv.conf.shadow ]; then 2328 echo 2329 echo "The host table is as follows:" 2330 echo 2331 cat /tmp/hosts 2332 cat << __hosts_table_1 2333 2334You may want to edit the host table in the event that you are doing an 2335NFS installation or an FTP installation without a name server and want 2336to refer to the server by name rather than by its numeric ip address. 2337__hosts_table_1 2338 echo -n "Would you like to edit the host table with ${EDITOR}? [n] " 2339 getresp "n" 2340 case "$resp" in 2341 y*|Y*) 2342 ${EDITOR} /tmp/hosts 2343 ;; 2344 2345 *) 2346 ;; 2347 esac 2348 fi 2349 2350 cat << \__network_config_2 2351 2352You will now be given the opportunity to escape to the command shell to do 2353any additional network configuration you may need. This may include adding 2354additional routes, if needed. In addition, you might take this opportunity 2355to redo the default route in the event that it failed above. 2356__network_config_2 2357 echo -n "Escape to shell? [n] " 2358 getresp "n" 2359 case "$resp" in 2360 y*|Y*) 2361 echo "Type 'exit' to return to install." 2362 sh 2363 ;; 2364 2365 *) 2366 ;; 2367 esac 2368} 2369 2370populateusrlocal() { 2371 if [ -f /mnt/etc/mtree/BSD.local.dist ]; then 2372 /mnt/usr/sbin/chroot /mnt /usr/sbin/mtree -Uedqn -p /usr/local -f /etc/mtree/BSD.local.dist >/dev/null 2373 fi 2374} 2375