Expand PMF_FN_* macros.
[netbsd-mini2440.git] / distrib / miniroot / install.sub
blob7b8de452f674e43b90658b767338c54c764ddf8a
1 #!/bin/sh
2 # $NetBSD: install.sub,v 1.44 2006/04/24 19:00:30 snj Exp $
4 # Copyright (c) 1996 The NetBSD Foundation, Inc.
5 # All rights reserved.
7 # This code is derived from software contributed to The NetBSD Foundation
8 # by Jason R. Thorpe.
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted provided that the following conditions
12 # are met:
13 # 1. Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 # 2. Redistributions in binary form must reproduce the above copyright
16 # notice, this list of conditions and the following disclaimer in the
17 # documentation and/or other materials provided with the distribution.
19 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
32 # NetBSD installation/upgrade script - common subroutines.
34 ROOTDISK="" # filled in below
35 VERSION= # filled in automatically (see list)
36 export VERSION
38 ALLSETS="base comp etc games man misc text" # default install sets
39 UPGRSETS="base comp games man misc text" # default upgrade sets
40 THESETS= # one of the above
42 local_sets_dir="" # Path searched for sets by install_sets
43 # on the local filesystems
45 # decide upon an editor
46 if [ X$EDITOR = X ]; then
47 if [ -x /usr/bin/vi ]; then
48 EDITOR=vi
49 else
50 EDITOR=ed
54 getresp() {
55 read resp
56 if [ "X$resp" = "X" ]; then
57 resp=$1
61 isin() {
62 # test the first argument against the remaining ones, return succes on a match
63 _a=$1; shift
64 while [ $# != 0 ]; do
65 if [ "$_a" = "$1" ]; then return 0; fi
66 shift
67 done
68 return 1
71 rmel() {
72 # remove first argument from list formed by the remaining arguments
73 local _a
75 _a=$1; shift
76 while [ $# != 0 ]; do
77 if [ "$_a" != "$1" ]; then
78 echo "$1";
80 shift
81 done
84 cutword () {
85 # read a line of data, return Nth element.
86 local _a
87 local _n
88 local _oifs
90 # optional field separator
91 _oifs="$IFS"
92 case "$1" in
93 -t?*) IFS=${1#-t}; shift;;
94 esac
96 _n=$1
97 read _a; set -- $_a
98 IFS="$_oifs"
99 if [ "$1" = "" ]; then return; fi
100 eval echo \$$_n
103 cutlast () {
104 # read a line of data, return last element. Equiv. of awk '{print $NF}'.
105 local _a
106 local _oifs
108 # optional field separator
109 _oifs="$IFS"
110 case "$1" in
111 -t?*) IFS=${1#-t}; shift;;
112 esac
114 read _a; set -- $_a
115 IFS="$_oifs"
116 if [ "$1" = "" ]; then return; fi
117 while [ "$#" -gt 10 ]; do shift 10; done
118 eval echo \$$#
121 firstchar () {
122 # return first character of argument
123 local _a
124 _a=$1
125 while [ ${#_a} != 1 ]; do
126 _a=${_a%?}
127 done
128 echo $_a
131 basename () {
132 local _oifs
133 if [ "$1" = "" ]; then return; fi
134 _oifs="$IFS"
135 IFS="/"
136 set -- $1
137 IFS="$_oifs"
138 while [ "$#" -gt 10 ]; do shift 10; done
139 eval echo \$$#
142 dir_has_sets() {
143 # return true when the directory $1 contains a set for $2...$n
144 local _dir
145 local _file
147 _dir=$1; shift
148 for _file in $*
150 if [ -f $_dir/${_file}.tar.gz ]; then
151 return 0
153 # Try for stupid msdos convention
154 if [ -f $_dir/${_file}.tgz ]; then
155 return 0
157 # Try for uncompressed files
158 if [ -f $_dir/${_file}.tar ]; then
159 return 0
161 # Try for split files
162 if [ -f $_dir/${_file}${VERSION}.aa ]; then
163 return 0
165 done
166 return 1
169 twiddle() {
170 # spin the propeller so we don't get bored
171 while : ; do
172 sleep 1; echo -n "/\b";
173 sleep 1; echo -n "-\b";
174 sleep 1; echo -n "\\\b";
175 sleep 1; echo -n "|\b";
176 done > /dev/tty & echo $!
179 get_localdir() {
180 # $1 is relative mountpoint
181 local _mp
182 local _dir
184 _mp=$1
185 _dir=
186 while : ; do
187 if [ X$_mp != X ]; then
188 cat << __get_localdir_1
189 Note: your filesystems are mounted under the temporary mount point \"$_mp\".
190 The pathname you are requested to enter below should NOT include the \"$_mp\"
191 prefix.
192 __get_localdir_1
194 echo -n "Enter the pathname where the sets are stored [$_dir] "
195 getresp "$_dir"
196 _dir=$resp
198 # Allow break-out with empty response
199 if [ -z "$_dir" ]; then
200 echo -n "Are you sure you don't want to set the pathname? [n] "
201 getresp "n"
202 case "$resp" in
203 y*|Y*)
204 break
207 continue
209 esac
212 if dir_has_sets "$_mp/$_dir" $THESETS
213 then
214 local_sets_dir="$_mp/$_dir"
215 break
216 else
217 cat << __get_localdir_2
218 The directory \"$_mp/$_dir\" does not exist, or does not hold any of the
219 upgrade sets.
220 __get_localdir_2
221 echo -n "Re-enter pathname? [y] "
222 getresp "y"
223 case "$resp" in
224 y*|Y*)
227 local_sets_dir=""
228 break
230 esac
232 done
235 getrootdisk() {
236 cat << \__getrootdisk_1
238 The installation program needs to know which disk to consider
239 the root disk. Note the unit number may be different than
240 the unit number you used in the standalone installation
241 program.
243 Available disks are:
245 __getrootdisk_1
246 _DKDEVS=`md_get_diskdevs`
247 echo "$_DKDEVS"
248 echo ""
249 echo -n "Which disk is the root disk? "
250 getresp ""
251 if isin $resp $_DKDEVS ; then
252 ROOTDISK="$resp"
253 else
254 echo ""
255 echo "The disk $resp does not exist."
256 ROOTDISK=""
260 labelmoredisks() {
261 cat << \__labelmoredisks_1
263 You may label the following disks:
265 __labelmoredisks_1
266 echo "$_DKDEVS"
267 echo ""
268 echo -n "Label which disk? [done] "
269 getresp "done"
270 case "$resp" in
271 "done")
275 if isin $resp $_DKDEVS ; then
276 md_labeldisk $resp
277 else
278 echo ""
279 echo "The disk $resp does not exist."
282 esac
285 addhostent() {
286 # $1 - IP address
287 # $2 - symbolic name
289 local fqdn
291 # Create an entry in the hosts table. If no host table
292 # exists, create one. If the IP address already exists,
293 # replace its entry.
294 if [ ! -f /tmp/hosts ]; then
295 echo "127.0.0.1 localhost" > /tmp/hosts
298 sed "/^$1 /d" < /tmp/hosts > /tmp/hosts.new
299 mv /tmp/hosts.new /tmp/hosts
301 if [ X${FQDN} != X ]; then
302 fqdn=$2.$FQDN
304 echo "$1 $2 $fqdn" >> /tmp/hosts
307 addifconfig() {
308 # $1 - interface name
309 # $2 - interface symbolic name
310 # $3 - interface IP address
311 # $4 - interface netmask
312 # $5 - (optional) interface link-layer medium, preceded by "media ", else ""
313 # $6 - (optional) interface link-layer directives
314 local _m
316 # Create a ifconfig.* file for the interface.
317 echo "inet $2 netmask $4 $5 $6" > /tmp/ifconfig.$1
319 addhostent $3 $2
322 configurenetwork() {
323 local _ifsdone
324 local _ifs
326 # _IFS=`md_get_ifdevs`
327 _IFS=`ifconfig -l | sed '
328 s/lo0//
329 s/ppp[0-9]//g
330 s/sl[0-9]//g
331 s/tun[0-9]//g'`
333 _ifsdone=""
334 resp="" # force at least one iteration
335 while [ "X${resp}" != X"done" ]; do
336 cat << \__configurenetwork_1
338 You may configure the following network interfaces (the interfaces
339 marked with [X] have been successfully configured):
341 __configurenetwork_1
343 for _ifs in $_IFS; do
344 if isin $_ifs $_ifsdone ; then
345 echo -n "[X] "
346 else
347 echo -n " "
349 echo $_ifs
350 done
351 echo ""
352 echo -n "Configure which interface? [done] "
353 getresp "done"
354 case "$resp" in
355 "done")
358 _ifs=$resp
359 if isin $_ifs $_IFS ; then
360 if configure_ifs $_ifs ; then
361 _ifsdone="$_ifs $_ifsdone"
363 else
364 echo "Invalid response: \"$resp\" is not in list"
367 esac
368 done
371 configure_ifs() {
373 local _up
374 local _interface_name
375 local _interface_ip
376 local _interface_mask
377 local _interface_symname
378 local _interface_extra
379 local _interface_mediumtype
380 local _interface_supported_media
381 local _m
382 local _t
384 _interface_name=$1
385 _up=DOWN
386 if isin $_interface_name `ifconfig -l -u` ; then
387 _up=UP
390 _interface_supported_media=`ifconfig -m $_interface_name | sed -n '
391 /^[ ]*media autoselect/d
392 4,$s/[ ]*media //p'`
394 # get current "media" "ip" and "netmask" ("broadcast")
395 _t=`ifconfig $_interface_name | sed -n '
396 s/^[ ]*media: [^ ]* \([^ ][^ ]*\).*/\1/p'`
398 if [ "$_t" != "manual" -a "$_t" != "media:" -a "$_t" != "autoselect" ];
399 then
400 _interface_mediumtype=$1
403 set -- `ifconfig $_interface_name | sed -n '
404 /^[ ]*inet/{
405 s/inet//
406 s/--> [0-9.][0-9.]*//
407 s/netmask//
408 s/broadcast//
409 p;}'`
411 _interface_ip=$1
412 _interface_mask=$2
414 # Get IP address
415 resp="" # force one iteration
416 while [ "X${resp}" = X"" ]; do
417 echo -n "IP address? [$_interface_ip] "
418 getresp "$_interface_ip"
419 _interface_ip=$resp
420 done
422 # Get symbolic name
423 resp="" # force one iteration
424 while [ "X${resp}" = X"" ]; do
425 echo -n "Symbolic (host) name? "
426 getresp ""
427 _interface_symname=$resp
428 done
430 # Get netmask
431 resp="" # force one iteration
432 while [ "X${resp}" = X"" ]; do
433 echo -n "Netmask? [$_interface_mask] "
434 getresp "$_interface_mask"
435 _interface_mask=$resp
436 done
438 echo "Your network interface might require explicit selection"
439 echo "of the type of network medium attached. Supported media:"
440 echo "$_interface_supported_media"
441 echo -n "Additional media type arguments (none)? [$_interface_mediumtype] "
442 getresp "$_interface_mediumtype"
443 _m=""
444 if [ "X${resp}" != X"" -a "X${resp}" != Xnone ]; then
445 _interface_mediumtype=$resp
446 _m="media ${resp}"
450 echo "Your network interface might require additional link-layer"
451 echo "directives (like \`link0'). If this is the case you can enter"
452 echo "these at the next prompt."
453 echo ""
454 echo -n "Additional link-layer arguments (none)? [$_interface_extra] "
455 getresp "$_interface_extra"
456 if [ "X${resp}" != X"" -a "X${resp}" != Xnone ]; then
457 _interface_extra=$resp
460 # Configure the interface. If it
461 # succeeds, add it to the permanent
462 # network configuration info.
463 if [ $_up != "UP" ]; then
464 ifconfig ${_interface_name} down
465 if ifconfig ${_interface_name} inet \
466 ${_interface_ip} \
467 netmask ${_interface_mask} \
468 ${_interface_extra} ${_m} up ; then
469 addifconfig \
470 "${_interface_name}" \
471 "${_interface_symname}" \
472 "${_interface_ip}" \
473 "${_interface_mask}" \
474 "${_m}" \
475 "${_interface_extra}"
476 return 0
478 else
479 echo "Interface ${_interface_name} is already active."
480 echo "Just saving configuration on new root filesystem."
481 addifconfig \
482 "${_interface_name}" \
483 "${_interface_symname}" \
484 "${_interface_ip}" \
485 "${_interface_mask}" \
486 "${_m}" \
487 "${_interface_extra}"
489 return 1
492 # Much of this is gratuitously stolen from /etc/rc.d/network.
493 enable_network() {
495 # Set up the hostname.
496 if [ -f /mnt/etc/myname ]; then
497 hostname=`cat /mnt/etc/myname`
498 elif [ -f /mnt/etc/rc.conf ];then
499 hostname=`sh -c '. /mnt/etc/rc.conf ; echo $hostname'`
500 else
501 echo "ERROR: no /etc/myname!"
502 return 1
504 if [ -z "$hostname" ];then
505 echo "ERROR: hostname not set in /etc/myname or /etc/rc.conf!"
506 return 1
508 hostname $hostname
510 # configure all the interfaces which we know about.
511 if [ -f /mnt/etc/rc.conf ]; then
513 # assume network interface configuration style 1.2D and up
514 if [ -f /mnt/etc/defaults/rc.conf ]; then
515 . /mnt/etc/defaults/rc.conf
517 . /mnt/etc/rc.conf
519 if [ "$net_interfaces" != NO ]; then
520 if [ "$auto_ifconfig" = YES ]; then
521 tmp="`ifconfig -l`"
522 else
523 tmp="$net_interfaces"
525 echo -n "configuring network interfaces:"
526 for i in $tmp; do
527 eval `echo 'args=$ifconfig_'$i`
528 if [ ! -z "$args" ]; then
529 echo -n " $i"
530 ifconfig $i $args
531 elif [ -f /mnt/etc/ifconfig.$i ]; then
532 echo -n " $i"
533 (while read args; do
534 ifconfig $i $args
535 done) < /mnt/etc/ifconfig.$i
536 elif [ "$auto_ifconfig" != YES ]; then
537 echo
538 echo -n "/mnt/etc/ifconfig.$i missing"
539 echo -n "& ifconfig_$i not set"
540 echo "; interface $i can't be configured"
542 done
543 echo "."
546 else
548 tmp="$IFS"
549 IFS="$IFS."
550 set -- `echo /mnt/etc/hostname*`
551 IFS=$tmp
552 unset tmp
554 while [ $# -ge 2 ] ; do
555 shift # get rid of "hostname"
557 read af name mask bcaddr extras
558 read dt dtaddr
560 if [ ! -n "$name" ]; then
561 echo "/etc/hostname.$1: invalid network configuration file"
562 exit
565 cmd="ifconfig $1 $af $name "
566 if [ "${dt}" = "dest" ]; then cmd="$cmd $dtaddr"; fi
567 if [ -n "$mask" ]; then cmd="$cmd netmask $mask"; fi
568 if [ -n "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then
569 cmd="$cmd broadcast $bcaddr";
571 cmd="$cmd $extras"
573 $cmd
574 ) < /mnt/etc/hostname.$1
575 shift
576 done
580 # set the address for the loopback interface
581 ifconfig lo0 inet localhost
583 # use loopback, not the wire
584 route add $hostname localhost
586 # /etc/mygate, if it exists, contains the name of my gateway host
587 # that name must be in /etc/hosts.
588 if [ -f /mnt/etc/mygate ]; then
589 route delete default > /dev/null 2>&1
590 route add default `cat /mnt/etc/mygate`
593 # enable the resolver, if appropriate.
594 if [ -f /mnt/etc/resolv.conf ]; then
595 _resolver_enabled="TRUE"
596 cp /mnt/etc/resolv.conf /tmp/resolv.conf.shadow
599 # Display results...
600 echo "Network interface configuration:"
601 ifconfig -a
603 echo ""
605 if [ "X${_resolver_enabled}" = X"TRUE" ]; then
606 netstat -r
607 echo ""
608 echo "Resolver enabled."
609 else
610 netstat -rn
611 echo ""
612 echo "Resolver not enabled."
615 return 0
618 install_ftp() {
619 local _f
620 local _sets
621 local _next
623 # Build a script to extract valid files from a list
624 # of filenames on stdin.
625 # XXX : Can we use this on more places? Leo.
627 echo "#!/bin/sh" > /tmp/fname_filter.sh
628 echo "while read line; do" >> /tmp/fname_filter.sh
629 echo " case \$line in" >> /tmp/fname_filter.sh
630 for _f in $THESETS; do
631 echo " $_f.tar.gz|$_f.tgz|$_f.tar|$_f.${VERSION}.aa)" \
632 >> /tmp/fname_filter.sh
633 echo ' echo -n "$line ";;' \
634 >> /tmp/fname_filter.sh
635 done
636 echo " *) ;;" >> /tmp/fname_filter.sh
637 echo " esac" >> /tmp/fname_filter.sh
638 echo "done" >> /tmp/fname_filter.sh
640 # Get several parameters from the user, and create
641 # a shell script that directs the appropriate
642 # commands into ftp.
643 cat << \__install_ftp_1
645 This is an automated ftp-based installation process. You will be asked
646 several questions. The correct set of commands will be placed in a script
647 that will be fed to ftp(1).
649 __install_ftp_1
650 # Get server IP address
651 resp="" # force one iteration
652 while [ "X${resp}" = X"" ]; do
653 echo -n "Server IP? [${_ftp_server_ip}] "
654 getresp "${_ftp_server_ip}"
655 _ftp_server_ip=$resp
656 done
658 # Get login name
659 resp="" # force one iteration
660 while [ "X${resp}" = X"" ]; do
661 echo -n "Login? [${_ftp_server_login}] "
662 getresp "${_ftp_server_login}"
663 _ftp_server_login=$resp
664 done
666 # Get password
667 resp="" # force one iteration
668 while [ "X${resp}" = X"" ]; do
669 echo -n "Password? "
670 stty -echo
671 getresp ""
672 echo ""
673 stty echo
674 _ftp_server_password=$resp
675 done
677 cat << \__install_ftp_2
679 You will be asked to enter the name of the directory that contains the
680 installation sets. When you enter a '?' you will see a listing of the
681 current directory on the server.
682 __install_ftp_2
683 _sets=""
684 while [ -z "$_sets" ]
686 resp="" # force one iteration
687 while [ "X${resp}" = X"" ]; do
688 echo -n "Server directory? [${_ftp_server_dir}] "
689 getresp "${_ftp_server_dir}"
690 if [ "X$resp" = 'X?' -a -z "$_ftp_server_dir" ]; then
691 resp=""
693 done
694 if [ $resp != '?' ]; then
695 _ftp_server_dir=$resp
698 # Build the basics of an ftp-script...
699 echo "#!/bin/sh" > /tmp/ftp-script.sh
700 echo "cd /mnt" >> /tmp/ftp-script.sh
701 echo "ftp -e -i -n $_ftp_server_ip << \__end_commands" >> \
702 /tmp/ftp-script.sh
703 echo "user $_ftp_server_login $_ftp_server_password" >> \
704 /tmp/ftp-script.sh
705 echo "bin" >> /tmp/ftp-script.sh
706 echo "cd $_ftp_server_dir" >> /tmp/ftp-script.sh
708 # Make a copy of this script that lists the directory
709 # contents, and use that to determine the files to get.
710 cat /tmp/ftp-script.sh > /tmp/ftp-dir.sh
711 echo "nlist" >> /tmp/ftp-dir.sh
712 echo "quit" >> /tmp/ftp-dir.sh
713 echo "__end_commands" >> /tmp/ftp-dir.sh
715 if [ $resp = '?' ]; then
716 sh /tmp/ftp-dir.sh
717 else
718 _sets=`sh /tmp/ftp-dir.sh | sh /tmp/fname_filter.sh`
720 done
721 rm -f /tmp/ftp-dir.sh /tmp/fname_filter.sh
723 while : ; do
724 echo "The following sets are available for extraction:"
725 echo "(marked sets are already on the extraction list)"
726 echo ""
728 _next=""
729 for _f in $_sets ; do
730 if isin $_f $_setsdone; then
731 echo -n "[X] "
732 _next=""
733 else
734 echo -n " "
735 if [ -z "$_next" ]; then _next=$_f; fi
737 echo $_f
738 done
739 echo ""
741 # Get name of the file and add extraction command
742 # to the ftp-script.
743 if [ "X$_next" = "X" ]; then resp=n; else resp=y; fi
744 echo -n "Continue to add filenames [$resp]? "
745 getresp "$resp"
746 if [ "$resp" = "n" ]; then
747 break
750 echo -n "File name [$_next]? "
751 getresp "$_next"
752 if isin $resp $_sets; then
753 echo "get $resp |\"pax -zr${verbose_flag}pe\"" >> \
754 /tmp/ftp-script.sh
755 _setsdone="$resp $_setsdone"
756 else
757 echo "You entered an invalid filename."
758 echo ""
760 done
762 echo "quit" >> /tmp/ftp-script.sh
763 echo "__end_commands" >> /tmp/ftp-script.sh
765 sh /tmp/ftp-script.sh
766 rm -f /tmp/ftp-script.sh
767 echo "Extraction complete."
770 install_from_mounted_fs() {
771 # $1 - directory containing installation sets
772 local _filename
773 local _sets
774 local _next
775 local _all
776 local _f
777 local _dirname
779 _dirname=$1
780 _sets=""
782 if ! dir_has_sets ${_dirname} $THESETS
783 then
785 echo ""
786 echo "The directory at the mount point, \"${_dirname}\", contains: "
787 echo ""
788 ls -F ${_dirname}
789 echo ""
790 echo "Enter the subdirectory relative to the mountpoint, that"
791 echo -n "contains the savesets: [try this directory] "
792 getresp ""
793 if [ "X${resp}" != "X" ]; then
794 _dirname=${_dirname}/$resp
797 while ! dir_has_sets ${_dirname} $THESETS; do
798 echo ""
799 echo -n "There are no NetBSD install sets available in "
800 echo "\"${_dirname}\"."
801 echo "\"${_dirname}\" contains: "
802 echo ""
803 ls -F ${_dirname}
804 echo ""
805 echo -n "Enter subdirectory: [try other install media] "
806 getresp ""
807 if [ "X${resp}" = "X" ]; then
808 return
810 if [ ! -d ${_dirname}/${resp} ]; then
811 echo "\"${resp}\" is no directory; try again."
812 else
813 _dirname=${_dirname}/$resp
815 done
818 for _f in $THESETS ; do
819 if [ -f ${_dirname}/${_f}.tar.gz ]; then
820 _sets="$_sets ${_f}.tar.gz"
821 elif [ -f ${_dirname}/${_f}.tgz ]; then
822 _sets="$_sets ${_f}.tgz"
823 elif [ -f ${_dirname}/${_f}.tar ]; then
824 _sets="$_sets ${_f}.tar"
825 elif [ -f ${_dirname}/${_f}${VERSION}.aa ]; then
826 _sets="$_sets ${_f}${VERSION}"
828 done
830 while : ; do
831 echo "The following sets are available for extraction:"
832 echo "(marked sets have already been extracted)"
833 echo ""
835 _next=""
836 _all=""
837 for _f in $_sets ; do
838 if isin $_f $_setsdone; then
839 echo -n "[X] "
840 _next=""
841 else
842 echo -n " "
843 if [ -z "$_next" ]; then
844 _next=$_f;
846 _all="$_all $_f"
848 echo $_f
849 done
850 echo ""
852 # Get the name of the file.
853 if [ "X$_next" = "X" ]; then
854 resp=n
855 else
856 resp=y
858 echo -n "Continue extraction [$resp]?"
859 getresp "$resp"
860 if [ "$resp" = "n" ]; then
861 break
864 echo -n "File name(s) (or "all") [$_next]? "
865 getresp "$_next"
866 if [ "x$resp" = xall ]; then
867 resp="$_all"
870 for _f in $resp; do
871 _filename="/${_dirname}/$_f"
873 # Ensure file exists
874 if [ ! -f $_filename ]; then
875 if [ -f ${_filename}.aa ]; then
876 _filename=${_filename}.\?\?
877 else
878 echo "File $_filename does not exist. Check to make"
879 echo "sure you entered the information properly."
880 continue 2
884 # Extract file
885 echo "Extracting the $_f set:"
886 case "$_filename" in
887 *.tar)
888 (cd /mnt; pax -r${verbose_flag}pe < $_filename)
891 cat $_filename | \
892 (cd /mnt; pax -zr${verbose_flag}pe)
894 esac
895 echo "Extraction complete."
896 _setsdone="$_f $_setsdone"
897 done
899 done
902 install_cdrom() {
903 local _drive
904 local _partition_range
905 local _partition
906 local _fstype
907 local _directory
909 # Get the cdrom device info
910 cat << \__install_cdrom_1
912 The following CD-ROM devices are installed on your system; please select
913 the CD-ROM device containing the partition with the installation sets:
915 __install_cdrom_1
916 _CDDEVS=`md_get_cddevs`
917 echo "$_CDDEVS"
918 echo ""
919 echo -n "Which is the CD-ROM with the installation media? [abort] "
920 getresp "abort"
921 case "$resp" in
922 abort)
923 echo "Aborting."
924 return
928 if isin $resp $_CDDEVS ; then
929 _drive=$resp
930 else
931 echo ""
932 echo "The CD-ROM $resp does not exist."
933 echo "Aborting."
934 return
937 esac
939 # Get partition
940 _partition_range=`md_get_partition_range`
941 resp="" # force one iteration
942 while [ "X${resp}" = X"" ]; do
943 echo -n "Partition? [a] "
944 getresp "a"
945 case "$resp" in
946 $_partition_range)
947 _partition=$resp
951 echo "Invalid response: $resp"
952 resp="" # force loop to repeat
954 esac
955 done
957 # Ask for filesystem type
958 cat << \__install_cdrom_2
960 There are two CD-ROM filesystem types currently supported by this program:
961 1) ISO-9660 (cd9660)
962 2) Berkeley Fast Filesystem (ffs)
964 __install_cdrom_2
965 resp="" # force one iteration
966 while [ "X${resp}" = X"" ]; do
967 echo -n "Which filesystem type? [cd9660] "
968 getresp "cd9660"
969 case "$resp" in
970 cd9660|ffs)
971 _fstype=$resp
975 echo "Invalid response: $resp"
976 resp="" # force loop to repeat
978 esac
979 done
981 # Mount the CD-ROM
982 if ! mount -t ${_fstype} -o ro \
983 /dev/${_drive}${_partition} /mnt2 ; then
984 echo "Cannot mount CD-ROM drive. Aborting."
985 return
988 install_from_mounted_fs /mnt2
989 umount -f /mnt2 > /dev/null 2>&1
992 mount_a_disk() {
993 # Mount a disk on /mnt2. The set of disk devices to choose from
994 # is $_DKDEVS.
995 # returns 0 on failure.
997 local _drive
998 local _partition_range
999 local _partition
1000 local _fstype
1001 local _fsopts
1002 local _directory
1003 local _md_fstype
1004 local _md_fsopts
1006 getresp "abort"
1007 case "$resp" in
1008 abort)
1009 echo "Aborting."
1010 return 0
1014 if isin $resp $_DKDEVS ; then
1015 _drive=$resp
1016 else
1017 echo ""
1018 echo "The disk $resp does not exist."
1019 echo "Aborting."
1020 return 0
1023 esac
1025 # Get partition
1026 _partition_range=`md_get_partition_range`
1027 resp="" # force one iteration
1028 while [ "X${resp}" = X"" ]; do
1029 echo -n "Partition? [d] "
1030 getresp "d"
1031 case "$resp" in
1032 $_partition_range)
1033 _partition=$resp
1037 echo "Invalid response: $resp"
1038 resp="" # force loop to repeat
1040 esac
1041 done
1043 # Ask for filesystem type
1044 cat << \__mount_a_disk_2
1046 The following filesystem types are supported:
1047 1) ffs
1048 __mount_a_disk_2
1049 _md_fstype=`md_native_fstype`
1050 _md_fsopts=`md_native_fsopts`
1051 if [ ! -z "$_md_fstype" ]; then
1052 echo " 2) $_md_fstype"
1053 else
1054 _md_fstype="_undefined_"
1056 resp="" # force one iteration
1057 while [ "X${resp}" = X"" ]; do
1058 echo -n "Which filesystem type? [ffs] "
1059 getresp "ffs"
1060 case "$resp" in
1061 ffs)
1062 _fstype=$resp
1063 _fsopts="ro"
1065 $_md_fstype)
1066 _fstype=$resp
1067 _fsopts=$_md_fsopts
1070 echo "Invalid response: $resp"
1071 resp="" # force loop to repeat
1073 esac
1074 done
1076 # Mount the disk
1077 if ! mount -t ${_fstype} -o $_fsopts \
1078 /dev/${_drive}${_partition} /mnt2 ; then
1079 echo "Cannot mount disk. Aborting."
1080 return 0
1082 return 1
1085 install_disk() {
1086 local _directory
1088 cat << \__install_disk_1
1090 Ok, lets install from a disk. The file-system the install sets on may
1091 already mounted, or we might have to mount the filesystem to get to it.
1093 __install_disk_1
1095 echo -n "Is the file-system with the install sets already mounted? [n] "
1096 getresp "n"
1097 case $resp in
1098 y*|Y*)
1099 echo "What mount point are the sets located in? [] "
1100 getresp ""
1101 if [ -d "$resp" ]; then
1102 install_from_mounted_fs $resp
1103 else
1104 echo "$resp: Not a directory, aborting..."
1106 return
1110 esac
1112 cat << \__install_disk_2
1114 The following disk devices are installed on your system; please select
1115 the disk device containing the partition with the installation sets:
1117 __install_disk_2
1118 _DKDEVS=`md_get_diskdevs`
1119 echo "$_DKDEVS"
1120 echo ""
1121 echo -n "Which is the disk with the installation sets? [abort] "
1123 if mount_a_disk ; then
1124 return
1127 install_from_mounted_fs /mnt2
1128 umount -f /mnt2 > /dev/null 2>&1
1131 install_nfs() {
1132 # Get the IP address of the server
1133 resp="" # force one iteration
1134 while [ "X${resp}" = X"" ]; do
1135 echo -n "Server IP address? [${_nfs_server_ip}] "
1136 getresp "${_nfs_server_ip}"
1137 done
1138 _nfs_server_ip=$resp
1140 # Get server path to mount
1141 resp="" # force one iteration
1142 while [ "X${resp}" = X"" ]; do
1143 echo -n "Filesystem on server to mount? [${_nfs_server_path}] "
1144 getresp "${_nfs_server_path}"
1145 done
1146 _nfs_server_path=$resp
1148 # Determine use of TCP
1149 echo -n "Use TCP transport (only works with capable NFS server)? [n] "
1150 getresp "n"
1151 case "$resp" in
1152 y*|Y*)
1153 _nfs_tcp="-T"
1157 echo -n "Use small NFS transfers (needed when server "
1158 echo "or client"
1159 echo -n "has a slow network card)? [n] "
1160 getresp "n"
1161 case "$resp" in
1162 y*|Y*)
1163 _nfs_tcp="-r 1024 -w 1024"
1167 _nfs_tcp=""
1169 esac
1171 esac
1173 # Mount the server
1174 mkdir /mnt2 > /dev/null 2>&1
1175 if ! mount_nfs $_nfs_tcp ${_nfs_server_ip}:${_nfs_server_path} \
1176 /mnt2 ; then
1177 echo "Cannot mount NFS server. Aborting."
1178 return
1181 install_from_mounted_fs /mnt2
1182 umount -f /mnt2 > /dev/null 2>&1
1185 install_tape() {
1186 local _xcmd
1188 # Get the name of the tape from the user.
1189 cat << \__install_tape_1
1191 The installation program needs to know which tape device to use. Make
1192 sure you use a "no rewind on close" device.
1194 __install_tape_1
1195 _tape=`basename $TAPE`
1196 resp="" # force one iteration
1197 while [ "X${resp}" = X"" ]; do
1198 echo -n "Name of tape device? [${_tape}]"
1199 getresp "${_tape}"
1200 done
1201 _tape=`basename $resp`
1202 TAPE="/dev/${_tape}"
1203 if [ ! -c $TAPE ]; then
1204 echo "$TAPE does not exist or is not a character special file."
1205 echo "Aborting."
1206 return
1208 export TAPE
1210 # Rewind the tape device
1211 echo -n "Rewinding tape..."
1212 if ! mt rewind ; then
1213 echo "$TAPE may not be attached to the system or may not be"
1214 echo "a tape device. Aborting."
1215 return
1217 echo "done."
1219 # Get the file number
1220 resp="" # force one iteration
1221 while [ "X${resp}" = X"" ]; do
1222 echo -n "File number? "
1223 getresp ""
1224 case "$resp" in
1225 [1-9]*)
1226 _nskip=`expr $resp - 1`
1230 echo "Invalid file number ${resp}."
1231 resp="" # fore loop to repeat
1233 esac
1234 done
1236 # Skip to correct file.
1237 echo -n "Skipping to source file..."
1238 if [ "X${_nskip}" != X"0" ]; then
1239 if ! mt fsf $_nskip ; then
1240 echo "Could not skip $_nskip files. Aborting."
1241 return
1244 echo "done."
1246 cat << \__install_tape_2
1248 There are 2 different ways the file can be stored on tape:
1250 1) an image of a gzipped tar file
1251 2) a standard tar image
1253 __install_tape_2
1254 resp="" # force one iteration
1255 while [ "X${resp}" = X"" ]; do
1256 echo -n "Which way is it? [1] "
1257 getresp "1"
1258 case "$resp" in
1260 _xcmd="pax -zr${verbose_flag}pe"
1264 _xcmd="pax -r${verbose_flag}pe"
1268 echo "Invalid response: $resp."
1269 resp="" # force loop to repeat
1271 esac
1272 ( cd /mnt; dd if=$TAPE | $_xcmd )
1273 done
1274 echo "Extraction complete."
1277 get_timezone() {
1278 local _a
1279 local _zonepath
1282 # If the zoneinfo is not on the installation medium or on the
1283 # installed filesystem, set TZ to GMT and return immediatly.
1285 if [ ! -e /usr/share/zoneinfo -a ! -e /mnt/usr/share/zoneinfo ]; then
1286 TZ=GMT
1287 return
1289 if [ ! -d /usr/share/zoneinfo ]; then
1290 _zonepath=/mnt
1291 else
1292 _zonepath=""
1295 cat << \__get_timezone_1
1297 Select a time zone for your location. Timezones are represented on the
1298 system by a directory structure rooted in "/usr/share/zoneinfo". Most
1299 timezones can be selected by entering a token like "MET" or "GMT-6".
1300 Other zones are grouped by continent, with detailed zone information
1301 separated by a slash ("/"), e.g. "US/Pacific".
1303 To get a listing of what's available in /usr/share/zoneinfo, enter "?"
1304 at the prompts below.
1306 __get_timezone_1
1307 if [ X$TZ = X ]; then
1308 TZ=`ls -l /mnt/etc/localtime 2>/dev/null | cutlast`
1309 TZ=${TZ#/usr/share/zoneinfo/}
1311 while :; do
1312 echo -n "What timezone are you in [\`?' for list] [$TZ]? "
1313 getresp "$TZ"
1314 case "$resp" in
1316 echo "Timezone defaults to GMT"
1317 TZ="GMT"
1318 break;
1320 "?")
1321 ls ${_zonepath}/usr/share/zoneinfo
1324 _a=$resp
1325 while [ -d ${_zonepath}/usr/share/zoneinfo/$_a ]; do
1326 echo -n "There are several timezones available"
1327 echo " within zone '$_a'"
1328 echo -n "Select a sub-timezone [\`?' for list]: "
1329 getresp ""
1330 case "$resp" in
1331 "?") ls ${_zonepath}/usr/share/zoneinfo/$_a ;;
1332 *) _a=${_a}/${resp}
1333 if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
1334 break;
1337 esac
1338 done
1339 if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
1340 TZ="$_a"
1341 echo "You have selected timezone \"$_a\"".
1342 break 2
1344 echo "'/usr/share/zoneinfo/$_a' is not a valid timezone on this system."
1346 esac
1347 done
1350 install_sets()
1352 local _yup
1353 _yup="FALSE"
1355 # Ask the user which media to load the distribution from.
1356 # Ask the user if they want verbose extraction. They might not want
1357 # it on, eg, SPARC frame buffer console.
1358 cat << \__install_sets_1
1360 It is now time to extract the installation sets onto the hard disk.
1361 Make sure the sets are either on a local device (i.e. tape, CD-ROM) or on a
1362 network server.
1364 Would you like to see each file listed during extraction (verbose) mode?
1365 On some console hardware, such as serial consoles and Sun frame buffers,
1366 this can extend the total extraction time.
1367 __install_sets_1
1368 echo -n "Use verbose listing for extractions? [y] "
1369 getresp "y"
1370 case "$resp" in
1371 y*|Y*)
1372 verbose_flag=v
1375 echo "Not using verbose listing."
1376 verbose_flag=""
1378 esac
1380 if [ -d ${Default_sets_dir:-/dev/null} ]; then
1381 if dir_has_sets $Default_sets_dir $THESETS; then
1382 local_sets_dir=$Default_sets_dir
1385 if [ "X$local_sets_dir" != "X" ]; then
1386 install_from_mounted_fs ${local_sets_dir}
1387 if [ X"$_setsdone" != X ]; then
1388 _yup="TRUE"
1392 # Go on prodding for alternate locations
1393 resp="" # force at least one iteration
1394 while [ X"${resp}" = X ]; do
1395 # If _yup is not FALSE, it means that we extracted sets above.
1396 # If that's the case, bypass the menu the first time.
1397 if [ X"$_yup" = X"FALSE" ]; then
1398 echo -n "Install from (f)tp, (t)ape, (C)D-ROM, (N)FS"
1399 echo -n " or local (d)isk? "
1400 getresp ""
1401 case "$resp" in
1402 d*|D*)
1403 install_disk
1405 f*|F*)
1406 install_ftp
1408 t*|T*)
1409 install_tape
1411 c*|C*)
1412 install_cdrom
1414 n*|N*)
1415 install_nfs
1418 echo "Invalid response: $resp"
1419 resp=""
1421 esac
1422 else
1423 _yup="FALSE" # So we'll ask next time
1426 # Give the user the opportunity to extract more sets. They
1427 # don't necessarily have to come from the same media.
1428 echo ""
1429 echo -n "Extract more sets? [n] "
1430 getresp "n"
1431 case "$resp" in
1432 y*|Y*)
1433 # Force loop to repeat
1434 resp=""
1439 esac
1440 done
1443 munge_fstab()
1445 local _fstab
1446 local _fstab_shadow
1447 local _dev
1448 local _mp
1449 local _fstype
1450 local _rest
1452 # Now that the 'real' fstab is configured, we munge it into a 'shadow'
1453 # fstab which we'll use for mounting and unmounting all of the target
1454 # filesystems relative to /mnt. Mount all filesystems.
1455 _fstab=$1
1456 _fstab_shadow=$2
1457 ( while read _dev _mp _fstype _rest; do
1458 # Skip comment lines
1459 case "$_dev" in
1460 \#*) continue;;
1461 *) ;;
1462 esac
1463 # and some filesystem types (like there are swap,kernfs,...)
1464 case "$_fstype" in
1465 ffs|ufs|nfs) ;;
1466 *) continue;;
1467 esac
1468 if [ "$_mp" = "/" ]; then
1469 echo $_dev /mnt $_fstype $_rest
1470 else
1471 echo $_dev /mnt$_mp $_fstype $_rest
1473 done ) < $_fstab > $_fstab_shadow
1476 mount_fs()
1478 # Must mount filesystems manually, one at a time, so we can make
1479 # sure the mount points exist.
1480 # $1 is a file in fstab format
1481 local _fstab
1483 _fstab=$1
1485 ( while read line; do
1486 set -- $line
1487 _dev=$1
1488 _mp=$2
1489 _fstype=$3
1490 _opt=$4
1492 # If not the root filesystem, make sure the mount
1493 # point is present.
1494 if [ "X{$_mp}" != X"/mnt" ]; then
1495 mkdir -p $_mp
1498 # Mount the filesystem. If the mount fails, exit
1499 # with an error condition to tell the outer
1500 # later to bail.
1501 if ! mount -v -t $_fstype -o async -o $_opt $_dev $_mp ; then
1502 # error message displated by mount
1503 exit 1
1505 done ) < $_fstab
1507 if [ "X${?}" != X"0" ]; then
1508 cat << \__mount_filesystems_1
1510 FATAL ERROR: Cannot mount filesystems. Double-check your configuration
1511 and restart the installation process.
1512 __mount_filesystems_1
1513 exit
1517 unmount_fs()
1519 # Unmount all filesystems and check their integrity.
1520 # Usage: [-fast] <fstab file>
1521 local _fast
1522 local _fstab
1523 local _pid
1525 if [ "$1" = "-fast" ]; then
1526 _fast=1
1527 _fstab=$2
1528 else
1529 _fast=0
1530 _fstab=$1
1533 if [ ! \( -f $_fstab -a -s $_fstab \) ]; then
1534 echo "fstab empty" > /dev/tty
1535 return
1538 if [ $_fast = 0 ]; then
1539 echo -n "Syncing disks..."
1540 _pid=`twiddle`
1541 sync; sleep 4; sync; sleep 2; sync; sleep 2
1542 kill $_pid
1543 echo "done."
1547 _devs=""
1548 _mps=""
1549 # maintain reverse order
1550 while read line; do
1551 set -- $line
1552 _devs="$1 ${_devs}"
1553 _mps="$2 ${_mps}"
1554 done
1555 echo -n "Umounting filesystems... "
1556 for _mp in ${_mps}; do
1557 echo -n "${_mp} "
1558 umount ${_mp}
1559 done
1560 echo "Done."
1562 if [ $_fast = 0 ]; then
1563 exit
1565 echo "Checking filesystem integrity..."
1566 for _dev in ${_devs}; do
1567 echo "${_dev}"
1568 fsck -f ${_dev}
1569 done
1570 echo "Done."
1571 ) < $_fstab
1574 check_fs()
1576 # Check filesystem integrity.
1577 # $1 is a file in fstab format
1578 local _fstab
1580 _fstab=$1
1583 _devs=""
1584 _mps=""
1585 while read line; do
1586 set -- $line
1587 _devs="$1 ${_devs}"
1588 _mps="$2 ${_mps}"
1589 done
1591 echo "Checking filesystem integrity..."
1592 for _dev in ${_devs}; do
1593 echo "${_dev}"
1594 fsck -f ${_dev}
1595 done
1596 echo "Done."
1597 ) < $_fstab