install.sub revision 1.3 1 1.1 pk #!/bin/sh
2 1.3 pk # $NetBSD: install.sub,v 1.3 1996/05/20 00:32:25 pk 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 # 3. All advertising materials mentioning features or use of this software
19 1.1 pk # must display the following acknowledgement:
20 1.2 thorpej # This product includes software developed by the NetBSD
21 1.2 thorpej # Foundation, Inc. and its contributors.
22 1.2 thorpej # 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.2 thorpej # contributors may be used to endorse or promote products derived
24 1.2 thorpej # from this software without specific prior written permission.
25 1.1 pk #
26 1.2 thorpej # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.2 thorpej # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.2 thorpej # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.2 thorpej # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
30 1.2 thorpej # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.2 thorpej # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.2 thorpej # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.2 thorpej # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.2 thorpej # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.2 thorpej # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.2 thorpej # POSSIBILITY OF SUCH DAMAGE.
37 1.1 pk #
38 1.1 pk
39 1.1 pk # NetBSD installation/upgrade script - common subroutines.
40 1.1 pk
41 1.1 pk VERSION=1.1A
42 1.1 pk export VERSION # XXX needed in subshell
43 1.1 pk ROOTDISK="" # filled in below
44 1.1 pk
45 1.1 pk ALLSETS="base comp etc games man misc text" # default install sets
46 1.1 pk UPGRSETS="base comp games man misc text" # default upgrade sets
47 1.1 pk
48 1.1 pk getresp() {
49 1.1 pk read resp
50 1.1 pk if [ "X$resp" = "X" ]; then
51 1.1 pk resp=$1
52 1.1 pk fi
53 1.1 pk }
54 1.1 pk
55 1.1 pk isin() {
56 1.1 pk # test the first argument against the remaining ones, return succes on a match
57 1.1 pk _a=$1; shift
58 1.1 pk while [ $# != 0 ]; do
59 1.1 pk if [ "$_a" = "$1" ]; then return 0; fi
60 1.1 pk shift
61 1.1 pk done
62 1.1 pk return 1
63 1.1 pk }
64 1.1 pk
65 1.1 pk rmel() {
66 1.1 pk # remove first argument from list formed by the remaining arguments
67 1.3 pk local _a
68 1.1 pk _a=$1; shift
69 1.1 pk while [ $# != 0 ]; do
70 1.1 pk if [ "$_a" != "$1" ]; then
71 1.1 pk echo "$1";
72 1.1 pk fi
73 1.1 pk shift
74 1.1 pk done
75 1.1 pk }
76 1.1 pk
77 1.3 pk cutword () {
78 1.3 pk # read a line of data, return Nth element.
79 1.3 pk local _a
80 1.3 pk local _n
81 1.3 pk _n=$1
82 1.3 pk read _a; set -- $_a
83 1.3 pk if [ "$1" = "" ]; then return; fi
84 1.3 pk eval echo \$$_n
85 1.3 pk }
86 1.3 pk
87 1.3 pk cutlast () {
88 1.3 pk # read a line of data, return last element. Equiv. of awk '{print $NF}'.
89 1.3 pk local _a
90 1.3 pk read _a; set -- $_a
91 1.3 pk if [ "$1" = "" ]; then return; fi
92 1.3 pk if [ "$#" -gt 10 ]; then shift 10; fi
93 1.3 pk eval echo \$$#
94 1.3 pk }
95 1.3 pk
96 1.3 pk firstchar () {
97 1.3 pk # return first character of argument
98 1.3 pk local _a
99 1.3 pk _a=$1
100 1.3 pk while [ ${#_a} != 1 ]; do
101 1.3 pk _a=${_a%?}
102 1.3 pk done
103 1.3 pk echo $_a
104 1.3 pk }
105 1.3 pk
106 1.1 pk twiddle() {
107 1.1 pk # spin the propeller so we don't get bored
108 1.1 pk while : ; do
109 1.1 pk sleep 1; echo -n "/";
110 1.1 pk sleep 1; echo -n "-";
111 1.1 pk sleep 1; echo -n "\\";
112 1.1 pk sleep 1; echo -n "|";
113 1.1 pk done > /dev/tty & echo $!
114 1.1 pk }
115 1.1 pk
116 1.1 pk do_mfs_mount() {
117 1.1 pk # $1 is the mount point
118 1.1 pk # $2 is the size in DEV_BIZE blocks
119 1.1 pk
120 1.1 pk umount $1 > /dev/null 2>&1
121 1.1 pk if ! mount_mfs -s $2 swap $1 ; then
122 1.1 pk cat << \__mfs_failed_1
123 1.1 pk
124 1.1 pk FATAL ERROR: Can't mount the memory filesystem.
125 1.1 pk
126 1.1 pk __mfs_failed_1
127 1.1 pk exit
128 1.1 pk fi
129 1.1 pk
130 1.1 pk # Bleh. Give mount_mfs a chance to DTRT.
131 1.1 pk sleep 2
132 1.1 pk }
133 1.1 pk
134 1.1 pk getrootdisk() {
135 1.1 pk cat << \__getrootdisk_1
136 1.1 pk
137 1.1 pk The installation program needs to know which disk to consider
138 1.1 pk the root disk. Note the unit number may be different than
139 1.1 pk the unit number you used in the standalone installation
140 1.1 pk program.
141 1.1 pk
142 1.1 pk Available disks are:
143 1.1 pk
144 1.1 pk __getrootdisk_1
145 1.1 pk _DKDEVS=`md_get_diskdevs`
146 1.1 pk echo "$_DKDEVS"
147 1.1 pk echo ""
148 1.1 pk echo -n "Which disk is the root disk? "
149 1.1 pk getresp ""
150 1.1 pk if isin $resp $_DKDEVS ; then
151 1.1 pk ROOTDISK="$resp"
152 1.1 pk else
153 1.1 pk echo ""
154 1.1 pk echo "The disk $resp does not exist."
155 1.1 pk ROOTDISK=""
156 1.1 pk fi
157 1.1 pk }
158 1.1 pk
159 1.1 pk labelmoredisks() {
160 1.1 pk cat << \__labelmoredisks_1
161 1.1 pk
162 1.1 pk You may label the following disks:
163 1.1 pk
164 1.1 pk __labelmoredisks_1
165 1.1 pk echo "$_DKDEVS"
166 1.1 pk echo ""
167 1.1 pk echo -n "Label which disk? [done] "
168 1.1 pk getresp "done"
169 1.1 pk case "$resp" in
170 1.1 pk done)
171 1.1 pk ;;
172 1.1 pk
173 1.1 pk *)
174 1.3 pk if isin $resp $_DKDEVS > /dev/null ; then
175 1.1 pk md_labeldisk $resp
176 1.1 pk else
177 1.1 pk echo ""
178 1.1 pk echo "The disk $resp does not exist."
179 1.1 pk fi
180 1.1 pk ;;
181 1.1 pk esac
182 1.1 pk }
183 1.1 pk
184 1.1 pk addhostent() {
185 1.1 pk # $1 - IP address
186 1.1 pk # $2 - symbolic name
187 1.1 pk
188 1.1 pk # Create an entry in the hosts table. If no host table
189 1.1 pk # exists, create one. If the IP address already exists,
190 1.1 pk # replace it's entry.
191 1.1 pk if [ ! -f /tmp/hosts ]; then
192 1.1 pk echo "127.0.0.1 localhost" > /tmp/hosts
193 1.1 pk fi
194 1.1 pk
195 1.3 pk sed "/^$1 /d" < /tmp/hosts > /tmp/hosts.new
196 1.3 pk mv /tmp/hosts.new /tmp/hosts
197 1.1 pk
198 1.1 pk echo "$1 $2 $2.$FQDN" >> /tmp/hosts
199 1.1 pk }
200 1.1 pk
201 1.1 pk addifconfig() {
202 1.1 pk # $1 - interface name
203 1.1 pk # $2 - interface symbolic name
204 1.1 pk # $3 - interface IP address
205 1.1 pk # $4 - interface netmask
206 1.1 pk
207 1.1 pk # Create a hostname.* file for the interface.
208 1.1 pk echo "inet $2 $4" > /tmp/hostname.$1
209 1.1 pk
210 1.1 pk addhostent $3 $2
211 1.1 pk }
212 1.1 pk
213 1.1 pk configurenetwork() {
214 1.1 pk local _ifsdone
215 1.1 pk local _ifs
216 1.1 pk
217 1.1 pk _IFS=`md_get_ifdevs`
218 1.1 pk _ifsdone=""
219 1.1 pk resp="" # force at least one iteration
220 1.1 pk while [ "X${resp}" != X"done" ]; do
221 1.1 pk cat << \__configurenetwork_1
222 1.1 pk
223 1.1 pk You may configure the following network interfaces (the interfaces
224 1.1 pk marked with [X] have been succesfully configured):
225 1.1 pk
226 1.1 pk __configurenetwork_1
227 1.1 pk
228 1.1 pk for _ifs in $_IFS; do
229 1.1 pk if isin $_ifs $_ifsdone ; then
230 1.1 pk echo -n "[X] "
231 1.1 pk else
232 1.1 pk echo -n " "
233 1.1 pk fi
234 1.1 pk echo $_ifs
235 1.1 pk done
236 1.1 pk echo ""
237 1.1 pk echo -n "Configure which interface? [done] "
238 1.1 pk getresp "done"
239 1.1 pk case "$resp" in
240 1.1 pk "done")
241 1.1 pk ;;
242 1.1 pk *)
243 1.1 pk _ifs=$resp
244 1.1 pk if isin $_ifs $_IFS ; then
245 1.1 pk if configure_ifs $_ifs ; then
246 1.1 pk _ifsdone="$_ifs $_ifsdone"
247 1.1 pk fi
248 1.1 pk else
249 1.1 pk echo "Invalid response: \"$resp\" is not in list"
250 1.1 pk fi
251 1.1 pk ;;
252 1.1 pk esac
253 1.1 pk done
254 1.1 pk }
255 1.1 pk
256 1.1 pk configure_ifs() {
257 1.1 pk
258 1.1 pk _interface_name=$1
259 1.1 pk
260 1.1 pk # Get IP address
261 1.1 pk resp="" # force one iteration
262 1.1 pk while [ "X${resp}" = X"" ]; do
263 1.1 pk echo -n "IP address? "
264 1.1 pk getresp ""
265 1.1 pk _interface_ip=$resp
266 1.1 pk done
267 1.1 pk
268 1.1 pk # Get symbolic name
269 1.1 pk resp="" # force one iteration
270 1.1 pk while [ "X${resp}" = X"" ]; do
271 1.1 pk echo -n "Symbolic (host) name? "
272 1.1 pk getresp ""
273 1.1 pk _interface_symname=$resp
274 1.1 pk done
275 1.1 pk
276 1.1 pk # Get netmask
277 1.1 pk resp="" # force one iteration
278 1.1 pk while [ "X${resp}" = X"" ]; do
279 1.1 pk echo -n "Netmask? "
280 1.1 pk getresp ""
281 1.1 pk _interface_mask=$resp
282 1.1 pk done
283 1.1 pk
284 1.1 pk # Configure the interface. If it
285 1.1 pk # succeeds, add it to the permanent
286 1.1 pk # network configuration info.
287 1.1 pk ifconfig ${_interface_name} down
288 1.1 pk if ifconfig ${_interface_name} inet \
289 1.1 pk ${_interface_ip} \
290 1.1 pk netmask ${_interface_mask} up ; then
291 1.1 pk addifconfig \
292 1.1 pk ${_interface_name} \
293 1.1 pk ${_interface_symname} \
294 1.1 pk ${_interface_ip} \
295 1.1 pk ${_interface_mask}
296 1.1 pk return 0
297 1.1 pk fi
298 1.1 pk return 1
299 1.1 pk }
300 1.1 pk
301 1.1 pk # Much of this is gratuitously stolen from /etc/netstart.
302 1.1 pk enable_network() {
303 1.1 pk
304 1.1 pk # Set up the hostname.
305 1.1 pk if [ ! -f /mnt/etc/myname ]; then
306 1.1 pk echo "ERROR: no /etc/myname!"
307 1.1 pk return 1
308 1.1 pk fi
309 1.1 pk hostname=`cat /mnt/etc/myname`
310 1.1 pk hostname $hostname
311 1.1 pk
312 1.1 pk # configure all the interfaces which we know about.
313 1.1 pk (
314 1.1 pk tmp="$IFS"
315 1.1 pk IFS="$IFS."
316 1.1 pk set -- `echo /mnt/etc/hostname*`
317 1.1 pk IFS=$tmp
318 1.1 pk unset tmp
319 1.1 pk
320 1.1 pk while [ $# -ge 2 ] ; do
321 1.1 pk shift # get rid of "hostname"
322 1.1 pk (
323 1.1 pk read af name mask bcaddr extras
324 1.1 pk read dt dtaddr
325 1.1 pk
326 1.1 pk if [ ! -n "$name" ]; then
327 1.1 pk echo "/etc/hostname.$1: invalid network configuration file"
328 1.1 pk exit
329 1.1 pk fi
330 1.1 pk
331 1.1 pk cmd="ifconfig $1 $af $name "
332 1.1 pk if [ "${dt}" = "dest" ]; then cmd="$cmd $dtaddr"; fi
333 1.1 pk if [ -n "$mask" ]; then cmd="$cmd netmask $mask"; fi
334 1.1 pk if [ -n "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then
335 1.1 pk cmd="$cmd broadcast $bcaddr";
336 1.1 pk fi
337 1.1 pk cmd="$cmd $extras"
338 1.1 pk
339 1.1 pk $cmd
340 1.1 pk ) < /mnt/etc/hostname.$1
341 1.1 pk shift
342 1.1 pk done
343 1.1 pk )
344 1.1 pk
345 1.1 pk # set the address for the loopback interface
346 1.1 pk ifconfig lo0 inet localhost
347 1.1 pk
348 1.1 pk # use loopback, not the wire
349 1.1 pk route add $hostname localhost
350 1.1 pk
351 1.1 pk # /etc/mygate, if it exists, contains the name of my gateway host
352 1.1 pk # that name must be in /etc/hosts.
353 1.1 pk if [ -f /mnt/etc/mygate ]; then
354 1.1 pk route delete default > /dev/null 2>&1
355 1.1 pk route add default `cat /mnt/etc/mygate`
356 1.1 pk fi
357 1.1 pk
358 1.1 pk # enable the resolver, if appropriate.
359 1.1 pk if [ -f /mnt/etc/resolv.conf ]; then
360 1.1 pk _resolver_enabled="TRUE"
361 1.1 pk cp /mnt/etc/resolv.conf /tmp/resolv.conf.shadow
362 1.1 pk fi
363 1.1 pk
364 1.1 pk # Display results...
365 1.1 pk echo "Network interface configuration:"
366 1.1 pk ifconfig -a
367 1.1 pk
368 1.1 pk echo ""
369 1.1 pk
370 1.1 pk if [ "X${_resolver_enabled}" = X"TRUE" ]; then
371 1.1 pk netstat -r
372 1.1 pk echo ""
373 1.1 pk echo "Resolver enabled."
374 1.1 pk else
375 1.1 pk netstat -rn
376 1.1 pk echo ""
377 1.1 pk echo "Resolver not enabled."
378 1.1 pk fi
379 1.1 pk
380 1.1 pk return 0
381 1.1 pk }
382 1.1 pk
383 1.1 pk install_ftp() {
384 1.1 pk # Get several parameters from the user, and create
385 1.1 pk # a shell script that directs the appropriate
386 1.1 pk # commands into ftp.
387 1.1 pk cat << \__install_ftp_1
388 1.1 pk
389 1.1 pk This is an automated ftp-based installation process. You will be asked
390 1.1 pk several questions. The correct set of commands will be placed in a script
391 1.1 pk that will be fed to ftp(1).
392 1.1 pk
393 1.1 pk __install_ftp_1
394 1.1 pk # Get server IP address
395 1.1 pk resp="" # force one iteration
396 1.1 pk while [ "X${resp}" = X"" ]; do
397 1.1 pk echo -n "Server IP? [${_ftp_server_ip}] "
398 1.1 pk getresp "${_ftp_server_ip}"
399 1.1 pk _ftp_server_ip=$resp
400 1.1 pk done
401 1.1 pk
402 1.1 pk # Get server directory
403 1.1 pk resp="" # force one iteration
404 1.1 pk while [ "X${resp}" = X"" ]; do
405 1.1 pk echo -n "Server directory? [${_ftp_server_dir}] "
406 1.1 pk getresp "${_ftp_server_dir}"
407 1.1 pk _ftp_server_dir=$resp
408 1.1 pk done
409 1.1 pk
410 1.1 pk # Get login name
411 1.1 pk resp="" # force one iteration
412 1.1 pk while [ "X${resp}" = X"" ]; do
413 1.1 pk echo -n "Login? [${_ftp_server_login}] "
414 1.1 pk getresp "${_ftp_server_login}"
415 1.1 pk _ftp_server_login=$resp
416 1.1 pk done
417 1.1 pk
418 1.1 pk # Get password
419 1.1 pk resp="" # force one iteration
420 1.1 pk while [ "X${resp}" = X"" ]; do
421 1.1 pk echo -n "Password? [${_ftp_server_password}] "
422 1.1 pk getresp "${_ftp_server_password}"
423 1.1 pk _ftp_server_password=$resp
424 1.1 pk done
425 1.1 pk
426 1.1 pk # Get list of files for mget.
427 1.1 pk cat << \__install_ftp_2
428 1.1 pk
429 1.1 pk You will now be asked for files to extract. Enter one file at a time.
430 1.1 pk When you are done entering files, enter 'done'.
431 1.1 pk
432 1.1 pk __install_ftp_2
433 1.1 pk echo "#!/bin/sh" > /tmp/ftp-script.sh
434 1.1 pk echo "cd /mnt" >> /tmp/ftp-script.sh
435 1.1 pk echo "ftp -i -n $_ftp_server_ip << \__end_commands" >> \
436 1.1 pk /tmp/ftp-script.sh
437 1.1 pk echo "user $_ftp_server_login $_ftp_server_password" >> \
438 1.1 pk /tmp/ftp-script.sh
439 1.1 pk echo "bin" >> /tmp/ftp-script.sh
440 1.1 pk echo "cd $_ftp_server_dir" >> /tmp/ftp-script.sh
441 1.1 pk
442 1.1 pk resp="" # force one interation
443 1.1 pk while [ "X${resp}" != X"done" ]; do
444 1.1 pk echo -n "File? [done] "
445 1.1 pk getresp "done"
446 1.1 pk if [ "X${resp}" = X"done" ]; then
447 1.1 pk break
448 1.1 pk fi
449 1.1 pk
450 1.3 pk _ftp_file=`echo ${resp} | cutword 1'`
451 1.1 pk echo "get ${_ftp_file} |\"tar --unlink -zxvpf -\"" >> \
452 1.1 pk /tmp/ftp-script.sh
453 1.1 pk done
454 1.1 pk
455 1.1 pk echo "quit" >> /tmp/ftp-script.sh
456 1.1 pk echo "__end_commands" >> /tmp/ftp-script.sh
457 1.1 pk
458 1.1 pk sh /tmp/ftp-script.sh
459 1.1 pk rm -f /tmp/ftp-script.sh
460 1.1 pk echo "Extraction complete."
461 1.1 pk }
462 1.1 pk
463 1.1 pk install_common_nfs_cdrom() {
464 1.1 pk # $1 - directory containing file
465 1.1 pk local _filename
466 1.1 pk local _setsdone
467 1.1 pk local _prev
468 1.1 pk local _f
469 1.1 pk
470 1.1 pk _sets=`(cd /mnt2/$1; ls *.tar.gz)`
471 1.1 pk if [ -z "$_sets" ]; then
472 1.1 pk echo "There are no NetBSD install sets available in \"$1\""
473 1.1 pk return
474 1.1 pk fi
475 1.1 pk
476 1.1 pk _setsdone=""
477 1.1 pk while : ; do
478 1.1 pk echo "The following sets are available for extraction:"
479 1.1 pk echo "(marked sets have already been extracted)"
480 1.1 pk echo ""
481 1.1 pk
482 1.1 pk _prev=""
483 1.1 pk for _f in $_sets ; do
484 1.1 pk if isin $_f $_setsdone; then
485 1.1 pk echo -n "[X] "
486 1.1 pk else
487 1.1 pk echo -n " "
488 1.1 pk if [ -z "$_prev" ]; then _prev=$_f; fi
489 1.1 pk fi
490 1.1 pk echo $_f
491 1.1 pk done
492 1.1 pk echo ""
493 1.1 pk
494 1.1 pk # Get the name of the file.
495 1.1 pk if [ "X$_prev" = "X" ]; then resp=n; else resp=y; fi
496 1.1 pk echo -n "Continue extraction [$resp]?"
497 1.1 pk getresp "$resp"
498 1.1 pk if [ "$resp" = "n" ]; then
499 1.1 pk break
500 1.1 pk fi
501 1.1 pk
502 1.1 pk echo -n "File name [$_prev]? "
503 1.1 pk getresp "$_prev"
504 1.1 pk _f=$resp
505 1.1 pk _filename="/mnt2/$1/$_f"
506 1.1 pk
507 1.1 pk # Ensure file exists
508 1.1 pk if [ ! -f $_filename ]; then
509 1.1 pk echo "File $_filename does not exist. Check to make"
510 1.1 pk echo "sure you entered the information properly."
511 1.1 pk continue
512 1.1 pk fi
513 1.1 pk
514 1.1 pk # Extract file
515 1.1 pk cat $_filename | (cd /mnt; tar -zxvpf -)
516 1.1 pk echo "Extraction complete."
517 1.1 pk _setsdone="$_f $_setsdone"
518 1.1 pk
519 1.1 pk done
520 1.1 pk }
521 1.1 pk
522 1.1 pk install_cdrom() {
523 1.1 pk # Get the cdrom device info
524 1.1 pk cat << \__install_cdrom_1
525 1.1 pk
526 1.1 pk The following CD-ROM devices are installed on your system; please select
527 1.1 pk the CD-ROM device containing the installation media:
528 1.1 pk
529 1.1 pk __install_cdrom_1
530 1.1 pk _CDDEVS=`md_get_cddevs`
531 1.1 pk echo "$_CDDEVS"
532 1.1 pk echo ""
533 1.1 pk echo -n "Which is the CD-ROM with the installation media? [abort] "
534 1.1 pk getresp "abort"
535 1.1 pk case "$resp" in
536 1.1 pk abort)
537 1.1 pk echo "Aborting."
538 1.1 pk return
539 1.1 pk ;;
540 1.1 pk
541 1.1 pk *)
542 1.1 pk if isin $resp $_CDDEVS ; then
543 1.1 pk _cdrom_drive=$resp
544 1.1 pk else
545 1.1 pk echo ""
546 1.1 pk echo "The CD-ROM $resp does not exist."
547 1.1 pk echo "Aborting."
548 1.1 pk return
549 1.1 pk fi
550 1.1 pk ;;
551 1.1 pk esac
552 1.1 pk
553 1.1 pk # Get partition
554 1.1 pk resp="" # force one iteration
555 1.1 pk while [ "X${resp}" = X"" ]; do
556 1.1 pk echo -n "Partition? [c] "
557 1.1 pk getresp "c"
558 1.1 pk case "$resp" in
559 1.1 pk [a-h])
560 1.1 pk _cdrom_partition=$resp
561 1.1 pk ;;
562 1.1 pk
563 1.1 pk *)
564 1.1 pk echo "Invalid response: $resp"
565 1.1 pk resp="" # force loop to repeat
566 1.1 pk ;;
567 1.1 pk esac
568 1.1 pk done
569 1.1 pk
570 1.1 pk # Ask for filesystem type
571 1.1 pk cat << \__install_cdrom_2
572 1.1 pk
573 1.1 pk There are two CD-ROM filesystem types currently supported by this program:
574 1.1 pk 1) ISO-9660 (cd9660)
575 1.1 pk 2) Berkeley Fast Filesystem (ffs)
576 1.1 pk
577 1.1 pk __install_cdrom_2
578 1.1 pk resp="" # force one iteration
579 1.1 pk while [ "X${resp}" = X"" ]; do
580 1.1 pk echo -n "Which filesystem type? [cd9660] "
581 1.1 pk getresp "cd9660"
582 1.1 pk case "$resp" in
583 1.1 pk cd9660|ffs)
584 1.1 pk _cdrom_filesystem=$resp
585 1.1 pk ;;
586 1.1 pk
587 1.1 pk *)
588 1.1 pk echo "Invalid response: $resp"
589 1.1 pk resp="" # force loop to repeat
590 1.1 pk ;;
591 1.1 pk esac
592 1.1 pk done
593 1.1 pk
594 1.1 pk # Mount the CD-ROM
595 1.1 pk if ! mount -t ${_cdrom_filesystem} -o ro \
596 1.1 pk /dev/${_cdrom_drive}${_cdrom_partition} /mnt2 ; then
597 1.1 pk echo "Cannot mount CD-ROM drive. Aborting."
598 1.1 pk return
599 1.1 pk fi
600 1.1 pk
601 1.1 pk # Get the directory where the file lives
602 1.1 pk resp="" # force one iteration
603 1.1 pk while [ "X${resp}" = X"" ]; do
604 1.1 pk echo "Enter the directory relative to the mount point that"
605 1.1 pk echo -n "contains the file. [${_cdrom_directory}] "
606 1.1 pk getresp "${_cdrom_directory}"
607 1.1 pk done
608 1.1 pk _cdrom_directory=$resp
609 1.1 pk
610 1.1 pk install_common_nfs_cdrom ${_cdrom_directory}
611 1.1 pk umount -f /mnt2 > /dev/null 2>&1
612 1.1 pk }
613 1.1 pk
614 1.1 pk install_nfs() {
615 1.1 pk # Get the IP address of the server
616 1.1 pk resp="" # force one iteration
617 1.1 pk while [ "X${resp}" = X"" ]; do
618 1.1 pk echo -n "Server IP address? [${_nfs_server_ip}] "
619 1.1 pk getresp "${_nfs_server_ip}"
620 1.1 pk done
621 1.1 pk _nfs_server_ip=$resp
622 1.1 pk
623 1.1 pk # Get server path to mount
624 1.1 pk resp="" # force one iteration
625 1.1 pk while [ "X${resp}" = X"" ]; do
626 1.1 pk echo -n "Filesystem on server to mount? [${_nfs_server_path}] "
627 1.1 pk getresp "${_nfs_server_path}"
628 1.1 pk done
629 1.1 pk _nfs_server_path=$resp
630 1.1 pk
631 1.1 pk # Determine use of TCP
632 1.1 pk echo -n "Use TCP transport (only works with capable NFS server)? [n] "
633 1.1 pk getresp "n"
634 1.1 pk case "$resp" in
635 1.1 pk y*|Y*)
636 1.1 pk _nfs_tcp="-T"
637 1.1 pk ;;
638 1.1 pk
639 1.1 pk *)
640 1.1 pk _nfs_tcp=""
641 1.1 pk ;;
642 1.1 pk esac
643 1.1 pk
644 1.1 pk # Mount the server
645 1.1 pk mkdir /mnt2 > /dev/null 2>&1
646 1.1 pk if ! mount_nfs $_nfs_tcp ${_nfs_server_ip}:${_nfs_server_path} \
647 1.1 pk /mnt2 ; then
648 1.1 pk echo "Cannot mount NFS server. Aborting."
649 1.1 pk return
650 1.1 pk fi
651 1.1 pk
652 1.1 pk # Get the directory where the file lives
653 1.1 pk resp="" # force one iteration
654 1.1 pk while [ "X${resp}" = X"" ]; do
655 1.1 pk echo "Enter the directory relative to the mount point that"
656 1.1 pk echo -n "contains the file. [${_nfs_directory}] "
657 1.1 pk getresp "${_nfs_directory}"
658 1.1 pk done
659 1.1 pk _nfs_directory=$resp
660 1.1 pk
661 1.1 pk install_common_nfs_cdrom ${_nfs_directory}
662 1.1 pk umount -f /mnt2 > /dev/null 2>&1
663 1.1 pk }
664 1.1 pk
665 1.1 pk install_tape() {
666 1.1 pk # Get the name of the tape from the user.
667 1.1 pk cat << \__install_tape_1
668 1.1 pk
669 1.1 pk The installation program needs to know which tape device to use. Make
670 1.1 pk sure you use a "no rewind on close" device.
671 1.1 pk
672 1.1 pk __install_tape_1
673 1.1 pk _tape=`basename $TAPE`
674 1.1 pk resp="" # force one iteration
675 1.1 pk while [ "X${resp}" = X"" ]; do
676 1.1 pk echo -n "Name of tape device? [${_tape}]"
677 1.1 pk getresp "${_tape}"
678 1.1 pk done
679 1.1 pk _tape=`basename $resp`
680 1.1 pk TAPE="/dev/${_tape}"
681 1.1 pk if [ ! -c $TAPE ]; then
682 1.1 pk echo "$TAPE does not exist or is not a character special file."
683 1.1 pk echo "Aborting."
684 1.1 pk return
685 1.1 pk fi
686 1.1 pk export TAPE
687 1.1 pk
688 1.1 pk # Rewind the tape device
689 1.1 pk echo -n "Rewinding tape..."
690 1.1 pk if ! mt rewind ; then
691 1.1 pk echo "$TAPE may not be attached to the system or may not be"
692 1.1 pk echo "a tape device. Aborting."
693 1.1 pk return
694 1.1 pk fi
695 1.1 pk echo "done."
696 1.1 pk
697 1.1 pk # Get the file number
698 1.1 pk resp="" # force one iteration
699 1.1 pk while [ "X${resp}" = X"" ]; do
700 1.1 pk echo -n "File number? "
701 1.1 pk getresp ""
702 1.1 pk case "$resp" in
703 1.1 pk [1-9]*)
704 1.1 pk _nskip=`expr $resp - 1`
705 1.1 pk ;;
706 1.1 pk
707 1.1 pk *)
708 1.1 pk echo "Invalid file number ${resp}."
709 1.1 pk resp="" # fore loop to repeat
710 1.1 pk ;;
711 1.1 pk esac
712 1.1 pk done
713 1.1 pk
714 1.1 pk # Skip to correct file.
715 1.1 pk echo -n "Skipping to source file..."
716 1.1 pk if [ "X${_nskip}" != X"0" ]; then
717 1.1 pk if ! mt fsf $_nskip ; then
718 1.1 pk echo "Could not skip $_nskip files. Aborting."
719 1.1 pk return
720 1.1 pk fi
721 1.1 pk fi
722 1.1 pk echo "done."
723 1.1 pk
724 1.1 pk cat << \__install_tape_2
725 1.1 pk
726 1.1 pk There are 2 different ways the file can be stored on tape:
727 1.1 pk
728 1.1 pk 1) an image of a gzipped tar file
729 1.1 pk 2) a standard tar image
730 1.1 pk
731 1.1 pk __install_tape_2
732 1.1 pk resp="" # force one iteration
733 1.1 pk while [ "X${resp}" = X"" ]; do
734 1.1 pk echo -n "Which way is it? [1] "
735 1.1 pk getresp "1"
736 1.1 pk case "$resp" in
737 1.1 pk 1)
738 1.1 pk (
739 1.1 pk cd /mnt
740 1.1 pk dd if=$TAPE | tar --unlink -zxvpf -
741 1.1 pk )
742 1.1 pk ;;
743 1.1 pk
744 1.1 pk 2)
745 1.1 pk (
746 1.1 pk cd /mnt
747 1.1 pk dd if=$TAPE | tar --unlink -xvpf -
748 1.1 pk )
749 1.1 pk ;;
750 1.1 pk
751 1.1 pk *)
752 1.1 pk echo "Invalid response: $resp."
753 1.1 pk resp="" # force loop to repeat
754 1.1 pk ;;
755 1.1 pk esac
756 1.1 pk done
757 1.1 pk echo "Extraction complete."
758 1.1 pk }
759 1.1 pk
760 1.1 pk get_timezone() {
761 1.1 pk local _a
762 1.1 pk cat << \__get_timezone_1
763 1.1 pk
764 1.1 pk Select a time zone for your location. Timezones are represented on the
765 1.1 pk system by a directory structure rooted in "/usr/share/timezone". Most
766 1.1 pk timezones can be selected by entering a token like "MET" or "GMT-6".
767 1.1 pk Other zones are grouped by continent, with detailed zone information
768 1.1 pk separated by a slash ("/"), e.g. "US/Pacific".
769 1.1 pk
770 1.1 pk To get a listing of what's available in /usr/share/zoneinfo, enter "?"
771 1.1 pk at the prompts below.
772 1.1 pk
773 1.1 pk __get_timezone_1
774 1.1 pk if [ X$TZ = X ]; then
775 1.3 pk TZ=`ls -l /etc/localtime 2>/dev/null | cutlast`
776 1.3 pk TZ=${TZ#/usr/share/zoneinfo/}
777 1.1 pk fi
778 1.1 pk while :; do
779 1.1 pk echo -n "What timezone are you in [\`?' for list] [$TZ]? "
780 1.1 pk getresp "$TZ"
781 1.1 pk case "$resp" in
782 1.1 pk "")
783 1.1 pk echo "Timezone defaults to GMT"
784 1.1 pk TZ="GMT"
785 1.1 pk break;
786 1.1 pk ;;
787 1.1 pk "?")
788 1.1 pk ls /usr/share/zoneinfo
789 1.1 pk ;;
790 1.1 pk *)
791 1.1 pk _a=$resp
792 1.1 pk while [ -d /usr/share/zoneinfo/$_a ]; do
793 1.1 pk echo -n "There are several timezones available"
794 1.1 pk echo " within zone '$_a'"
795 1.1 pk echo -n "Select a sub-timezone [\`?' for list]: "
796 1.1 pk getresp ""
797 1.1 pk case "$resp" in
798 1.1 pk "?") ls /usr/share/zoneinfo/$_a ;;
799 1.1 pk *) _a=${_a}/${resp}
800 1.1 pk if [ -f /usr/share/zoneinfo/$_a ]; then
801 1.1 pk break;
802 1.1 pk fi
803 1.1 pk ;;
804 1.1 pk esac
805 1.1 pk done
806 1.1 pk if [ -f /usr/share/zoneinfo/$_a ]; then
807 1.1 pk TZ="$_a"
808 1.1 pk echo "You have selected timezone \"$_a\"".
809 1.1 pk break 2
810 1.1 pk fi
811 1.1 pk echo "'/usr/share/zoneinfo/$_a' is not a valid timezone on this system."
812 1.1 pk ;;
813 1.1 pk esac
814 1.1 pk done
815 1.1 pk }
816 1.1 pk
817 1.1 pk install_sets()
818 1.1 pk {
819 1.1 pk # arguments: the base names of the distribution sets to consider
820 1.1 pk # Ask the user which media to load the distribution from.
821 1.1 pk cat << \__install_sets_1
822 1.1 pk
823 1.1 pk It is now time to extract the installation sets onto the hard disk.
824 1.1 pk Make sure The sets are either on a local device (i.e. tape, CD-ROM) or on a
825 1.1 pk network server.
826 1.1 pk
827 1.1 pk __install_sets_1
828 1.1 pk if [ -f $RELDIR/$1.tar.gz ]; then
829 1.1 pk echo -n "Install from sets in the current root filesystem? [y] "
830 1.1 pk getresp "y"
831 1.1 pk case "$resp" in
832 1.1 pk y*|Y*)
833 1.1 pk for _f do
834 1.1 pk if [ ! -f $RELDIR/${_f}.tar.gz ]; then
835 1.1 pk continue
836 1.1 pk fi
837 1.1 pk echo -n "Install \"$_f\" ? [y]"
838 1.1 pk getresp "y"
839 1.1 pk case "$resp" in
840 1.1 pk y*|Y*)
841 1.1 pk cat $RELDIR/${_f}.tar.gz |
842 1.1 pk (cd /mnt; tar --unlink -zxvpf -)
843 1.1 pk _yup="TRUE"
844 1.1 pk echo "Extraction complete."
845 1.1 pk ;;
846 1.1 pk *)
847 1.1 pk echo "Skipping \"$_f\"."
848 1.1 pk ;;
849 1.1 pk esac
850 1.1 pk done
851 1.1 pk ;;
852 1.1 pk *)
853 1.1 pk _yup="FALSE"
854 1.1 pk ;;
855 1.1 pk esac
856 1.1 pk else
857 1.1 pk _yup="FALSE"
858 1.1 pk fi
859 1.1 pk
860 1.1 pk # Go on prodding for alternate locations
861 1.1 pk resp="" # force at least one iteration
862 1.1 pk while [ "X${resp}" = X"" ]; do
863 1.1 pk # If _yup is not FALSE, it means that we extracted sets above.
864 1.1 pk # If that's the case, bypass the menu the first time.
865 1.1 pk if [ X"$_yup" = X"FALSE" ]; then
866 1.1 pk echo -n "Install from (f)tp, (t)ape, (C)D-ROM, or (N)FS? [f] "
867 1.1 pk getresp "f"
868 1.1 pk case "$resp" in
869 1.1 pk f*|F*)
870 1.1 pk install_ftp
871 1.1 pk ;;
872 1.1 pk
873 1.1 pk t*|T*)
874 1.1 pk install_tape
875 1.1 pk ;;
876 1.1 pk
877 1.1 pk c*|C*)
878 1.1 pk install_cdrom
879 1.1 pk ;;
880 1.1 pk
881 1.1 pk n*|N*)
882 1.1 pk install_nfs
883 1.1 pk ;;
884 1.1 pk
885 1.1 pk *)
886 1.1 pk echo "Invalid response: $resp"
887 1.1 pk resp=""
888 1.1 pk ;;
889 1.1 pk esac
890 1.1 pk else
891 1.1 pk _yup="FALSE" # So we'll ask next time
892 1.1 pk fi
893 1.1 pk
894 1.1 pk # Give the user the opportunity to extract more sets. They don't
895 1.1 pk # necessarily have to come from the same media.
896 1.1 pk echo ""
897 1.1 pk echo -n "Extract more sets? [n] "
898 1.1 pk getresp "n"
899 1.1 pk case "$resp" in
900 1.1 pk y*|Y*)
901 1.1 pk # Force loop to repeat
902 1.1 pk resp=""
903 1.1 pk ;;
904 1.1 pk
905 1.1 pk *)
906 1.1 pk ;;
907 1.1 pk esac
908 1.1 pk done
909 1.1 pk }
910 1.1 pk
911 1.1 pk munge_fstab()
912 1.1 pk {
913 1.1 pk local _fstab
914 1.1 pk local _fstab_shadow
915 1.3 pk local _dev, _mp, _rest
916 1.1 pk # Now that the 'real' fstab is configured, we munge it into a 'shadow'
917 1.1 pk # fstab which we'll use for mounting and unmounting all of the target
918 1.1 pk # filesystems relative to /mnt. Mount all filesystems.
919 1.1 pk _fstab=$1
920 1.1 pk _fstab_shadow=$2
921 1.3 pk ( while read _dev _mp _rest; do
922 1.3 pk if [ "$_mp" = "/" ]; then
923 1.3 pk echo $_dev /mnt $_rest
924 1.1 pk else
925 1.3 pk echo $_dev /mnt$_mp $_rest
926 1.3 pk fi
927 1.3 pk done ) < $_fstab > $_fstab_shadow
928 1.1 pk }
929 1.1 pk
930 1.1 pk mount_fs()
931 1.1 pk {
932 1.1 pk # Must mount filesystems manually, one at a time, so we can make
933 1.1 pk # sure the mount points exist.
934 1.1 pk # $1 is a file in fstab format
935 1.1 pk local _fstab
936 1.1 pk
937 1.1 pk _fstab=$1
938 1.1 pk
939 1.1 pk ( while read line; do
940 1.3 pk _dev=`echo $line | cutword 1`
941 1.3 pk _mp=`echo $line | cutword 2`
942 1.3 pk _fstype=`echo $line | cutword 3`
943 1.3 pk _opt=`echo $line | cutword 4`
944 1.1 pk
945 1.1 pk # If not the root filesystem, make sure the mount
946 1.1 pk # point is present.
947 1.1 pk if [ "X{$_mp}" != X"/mnt" ]; then
948 1.1 pk mkdir -p $_mp
949 1.1 pk fi
950 1.1 pk
951 1.1 pk # Mount the filesystem. If the mount fails, exit
952 1.1 pk # with an error condition to tell the outer
953 1.1 pk # later to bail.
954 1.1 pk if ! mount -v -t $_fstype -o $_opt $_dev $_mp ; then
955 1.1 pk # error message displated by mount
956 1.1 pk exit 1
957 1.1 pk fi
958 1.1 pk done ) < $_fstab
959 1.1 pk
960 1.1 pk if [ "X${?}" != X"0" ]; then
961 1.1 pk cat << \__mount_filesystems_1
962 1.1 pk
963 1.1 pk FATAL ERROR: Cannot mount filesystems. Double-check your configuration
964 1.1 pk and restart the installation process.
965 1.1 pk __mount_filesystems_1
966 1.1 pk exit
967 1.1 pk fi
968 1.1 pk }
969 1.1 pk
970 1.1 pk unmount_fs()
971 1.1 pk {
972 1.1 pk # Unmount all filesystems and check their integrity.
973 1.1 pk # $1 is a file in fstab format
974 1.1 pk local _fstab
975 1.1 pk
976 1.1 pk _fstab=$1
977 1.1 pk
978 1.1 pk echo -n "Syncing disks..."
979 1.1 pk pid=`twiddle`
980 1.1 pk sync; sleep 4; sync; sleep 2; sync; sleep 2
981 1.1 pk kill $pid
982 1.1 pk echo "done."
983 1.1 pk
984 1.1 pk (
985 1.1 pk _devs=""
986 1.1 pk _mps=""
987 1.1 pk # maintain reverse order
988 1.1 pk while read line; do
989 1.3 pk set -- $line
990 1.3 pk _devs="$1 ${_devs}"
991 1.3 pk _mps="$2 ${_mps}"
992 1.1 pk done
993 1.1 pk echo -n "Umounting filesystems... "
994 1.1 pk for _mp in ${_mps}; do
995 1.1 pk echo -n "${_mp} "
996 1.1 pk umount ${_mp}
997 1.1 pk done
998 1.1 pk echo "Done."
999 1.1 pk
1000 1.1 pk echo "Checking filesystem integrity..."
1001 1.1 pk for _dev in ${_devs}; do
1002 1.1 pk echo "${_dev}"
1003 1.1 pk fsck -f ${_dev}
1004 1.1 pk done
1005 1.1 pk echo "Done."
1006 1.1 pk ) < $_fstab
1007 1.1 pk }
1008 1.1 pk
1009 1.1 pk check_fs()
1010 1.1 pk {
1011 1.1 pk # Check filesystem integrity.
1012 1.1 pk # $1 is a file in fstab format
1013 1.1 pk local _fstab
1014 1.1 pk
1015 1.1 pk _fstab=$1
1016 1.1 pk
1017 1.1 pk (
1018 1.1 pk _devs=""
1019 1.1 pk _mps=""
1020 1.1 pk while read line; do
1021 1.3 pk set -- $line
1022 1.3 pk _devs="$1 ${_devs}"
1023 1.3 pk _mps="$2 ${_mps}"
1024 1.1 pk done
1025 1.1 pk
1026 1.1 pk echo "Checking filesystem integrity..."
1027 1.1 pk for _dev in ${_devs}; do
1028 1.1 pk echo "${_dev}"
1029 1.1 pk fsck -f ${_dev}
1030 1.1 pk done
1031 1.1 pk echo "Done."
1032 1.1 pk ) < $_fstab
1033 1.1 pk }
1034