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