install.sub revision 1.63 1 1.1 pk #!/bin/sh
2 1.63 andvar # $NetBSD: install.sub,v 1.63 2022/03/13 14:20:24 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.1 pk # test the first argument against the remaining ones, return succes 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.1 pk # Determine use of TCP
1167 1.1 pk echo -n "Use TCP transport (only works with capable NFS server)? [n] "
1168 1.1 pk getresp "n"
1169 1.1 pk case "$resp" in
1170 1.1 pk y*|Y*)
1171 1.1 pk _nfs_tcp="-T"
1172 1.1 pk ;;
1173 1.1 pk
1174 1.1 pk *)
1175 1.40 fredette echo -n "Use small NFS transfers (needed when server "
1176 1.40 fredette echo "or client"
1177 1.40 fredette echo -n "has a slow network card)? [n] "
1178 1.40 fredette getresp "n"
1179 1.40 fredette case "$resp" in
1180 1.40 fredette y*|Y*)
1181 1.40 fredette _nfs_tcp="-r 1024 -w 1024"
1182 1.40 fredette ;;
1183 1.40 fredette
1184 1.40 fredette *)
1185 1.40 fredette _nfs_tcp=""
1186 1.40 fredette ;;
1187 1.40 fredette esac
1188 1.1 pk ;;
1189 1.1 pk esac
1190 1.1 pk
1191 1.1 pk # Mount the server
1192 1.1 pk mkdir /mnt2 > /dev/null 2>&1
1193 1.1 pk if ! mount_nfs $_nfs_tcp ${_nfs_server_ip}:${_nfs_server_path} \
1194 1.1 pk /mnt2 ; then
1195 1.1 pk echo "Cannot mount NFS server. Aborting."
1196 1.1 pk return
1197 1.1 pk fi
1198 1.1 pk
1199 1.20 is install_from_mounted_fs /mnt2
1200 1.1 pk umount -f /mnt2 > /dev/null 2>&1
1201 1.1 pk }
1202 1.1 pk
1203 1.1 pk install_tape() {
1204 1.11 pk local _xcmd
1205 1.11 pk
1206 1.1 pk # Get the name of the tape from the user.
1207 1.1 pk cat << \__install_tape_1
1208 1.1 pk
1209 1.1 pk The installation program needs to know which tape device to use. Make
1210 1.1 pk sure you use a "no rewind on close" device.
1211 1.1 pk
1212 1.1 pk __install_tape_1
1213 1.47 christos _tape=$(basename $TAPE)
1214 1.1 pk resp="" # force one iteration
1215 1.47 christos while [ -z "${resp}" ]; do
1216 1.1 pk echo -n "Name of tape device? [${_tape}]"
1217 1.1 pk getresp "${_tape}"
1218 1.1 pk done
1219 1.47 christos _tape=$(basename $resp)
1220 1.1 pk TAPE="/dev/${_tape}"
1221 1.1 pk if [ ! -c $TAPE ]; then
1222 1.1 pk echo "$TAPE does not exist or is not a character special file."
1223 1.1 pk echo "Aborting."
1224 1.1 pk return
1225 1.1 pk fi
1226 1.1 pk export TAPE
1227 1.1 pk
1228 1.1 pk # Rewind the tape device
1229 1.1 pk echo -n "Rewinding tape..."
1230 1.1 pk if ! mt rewind ; then
1231 1.1 pk echo "$TAPE may not be attached to the system or may not be"
1232 1.1 pk echo "a tape device. Aborting."
1233 1.1 pk return
1234 1.1 pk fi
1235 1.1 pk echo "done."
1236 1.1 pk
1237 1.1 pk # Get the file number
1238 1.1 pk resp="" # force one iteration
1239 1.47 christos while [ -z "${resp}" ]; do
1240 1.1 pk echo -n "File number? "
1241 1.1 pk getresp ""
1242 1.1 pk case "$resp" in
1243 1.1 pk [1-9]*)
1244 1.47 christos _nskip=$(expr $resp - 1)
1245 1.1 pk ;;
1246 1.1 pk
1247 1.1 pk *)
1248 1.1 pk echo "Invalid file number ${resp}."
1249 1.1 pk resp="" # fore loop to repeat
1250 1.1 pk ;;
1251 1.1 pk esac
1252 1.1 pk done
1253 1.1 pk
1254 1.1 pk # Skip to correct file.
1255 1.1 pk echo -n "Skipping to source file..."
1256 1.47 christos if [ "${_nskip}" != "0" ]; then
1257 1.1 pk if ! mt fsf $_nskip ; then
1258 1.1 pk echo "Could not skip $_nskip files. Aborting."
1259 1.1 pk return
1260 1.1 pk fi
1261 1.1 pk fi
1262 1.1 pk echo "done."
1263 1.1 pk
1264 1.1 pk cat << \__install_tape_2
1265 1.1 pk
1266 1.1 pk There are 2 different ways the file can be stored on tape:
1267 1.1 pk
1268 1.1 pk 1) an image of a gzipped tar file
1269 1.1 pk 2) a standard tar image
1270 1.1 pk
1271 1.1 pk __install_tape_2
1272 1.1 pk resp="" # force one iteration
1273 1.47 christos while [ -z "${resp}" ]; do
1274 1.1 pk echo -n "Which way is it? [1] "
1275 1.1 pk getresp "1"
1276 1.1 pk case "$resp" in
1277 1.11 pk 1)
1278 1.33 mrg _xcmd="pax -zr${verbose_flag}pe"
1279 1.11 pk ;;
1280 1.1 pk
1281 1.11 pk 2)
1282 1.33 mrg _xcmd="pax -r${verbose_flag}pe"
1283 1.11 pk ;;
1284 1.1 pk
1285 1.11 pk *)
1286 1.11 pk echo "Invalid response: $resp."
1287 1.11 pk resp="" # force loop to repeat
1288 1.11 pk ;;
1289 1.1 pk esac
1290 1.11 pk ( cd /mnt; dd if=$TAPE | $_xcmd )
1291 1.1 pk done
1292 1.1 pk echo "Extraction complete."
1293 1.1 pk }
1294 1.1 pk
1295 1.1 pk get_timezone() {
1296 1.1 pk local _a
1297 1.6 leo local _zonepath
1298 1.6 leo
1299 1.6 leo #
1300 1.6 leo # If the zoneinfo is not on the installation medium or on the
1301 1.63 andvar # installed filesystem, set TZ to GMT and return immediately.
1302 1.6 leo #
1303 1.47 christos if [ ! -e /usr/share/zoneinfo ] && [ ! -e /mnt/usr/share/zoneinfo ]; then
1304 1.6 leo TZ=GMT
1305 1.6 leo return
1306 1.6 leo fi
1307 1.6 leo if [ ! -d /usr/share/zoneinfo ]; then
1308 1.6 leo _zonepath=/mnt
1309 1.6 leo else
1310 1.6 leo _zonepath=""
1311 1.6 leo fi
1312 1.6 leo
1313 1.1 pk cat << \__get_timezone_1
1314 1.1 pk
1315 1.1 pk Select a time zone for your location. Timezones are represented on the
1316 1.42 nathanw system by a directory structure rooted in "/usr/share/zoneinfo". Most
1317 1.1 pk timezones can be selected by entering a token like "MET" or "GMT-6".
1318 1.1 pk Other zones are grouped by continent, with detailed zone information
1319 1.1 pk separated by a slash ("/"), e.g. "US/Pacific".
1320 1.1 pk
1321 1.1 pk To get a listing of what's available in /usr/share/zoneinfo, enter "?"
1322 1.1 pk at the prompts below.
1323 1.1 pk
1324 1.1 pk __get_timezone_1
1325 1.48 christos if [ -z "$TZ" ]; then
1326 1.47 christos TZ=$(ls -l /mnt/etc/localtime 2>/dev/null | cutlast)
1327 1.3 pk TZ=${TZ#/usr/share/zoneinfo/}
1328 1.1 pk fi
1329 1.1 pk while :; do
1330 1.47 christos echo -n "What timezone are you in ['?' for list] [$TZ]? "
1331 1.1 pk getresp "$TZ"
1332 1.1 pk case "$resp" in
1333 1.1 pk "")
1334 1.1 pk echo "Timezone defaults to GMT"
1335 1.1 pk TZ="GMT"
1336 1.1 pk break;
1337 1.1 pk ;;
1338 1.1 pk "?")
1339 1.6 leo ls ${_zonepath}/usr/share/zoneinfo
1340 1.1 pk ;;
1341 1.1 pk *)
1342 1.1 pk _a=$resp
1343 1.6 leo while [ -d ${_zonepath}/usr/share/zoneinfo/$_a ]; do
1344 1.1 pk echo -n "There are several timezones available"
1345 1.1 pk echo " within zone '$_a'"
1346 1.47 christos echo -n "Select a sub-timezone ['?' for list]: "
1347 1.1 pk getresp ""
1348 1.1 pk case "$resp" in
1349 1.6 leo "?") ls ${_zonepath}/usr/share/zoneinfo/$_a ;;
1350 1.1 pk *) _a=${_a}/${resp}
1351 1.6 leo if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
1352 1.1 pk break;
1353 1.1 pk fi
1354 1.1 pk ;;
1355 1.1 pk esac
1356 1.1 pk done
1357 1.6 leo if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
1358 1.1 pk TZ="$_a"
1359 1.1 pk echo "You have selected timezone \"$_a\"".
1360 1.1 pk break 2
1361 1.1 pk fi
1362 1.1 pk echo "'/usr/share/zoneinfo/$_a' is not a valid timezone on this system."
1363 1.1 pk ;;
1364 1.1 pk esac
1365 1.1 pk done
1366 1.1 pk }
1367 1.1 pk
1368 1.1 pk install_sets()
1369 1.1 pk {
1370 1.13 pk local _yup
1371 1.13 pk _yup="FALSE"
1372 1.13 pk
1373 1.13 pk # Ask the user which media to load the distribution from.
1374 1.33 mrg # Ask the user if they want verbose extraction. They might not want
1375 1.33 mrg # it on, eg, SPARC frame buffer console.
1376 1.13 pk cat << \__install_sets_1
1377 1.1 pk
1378 1.1 pk It is now time to extract the installation sets onto the hard disk.
1379 1.10 thorpej Make sure the sets are either on a local device (i.e. tape, CD-ROM) or on a
1380 1.1 pk network server.
1381 1.1 pk
1382 1.33 mrg Would you like to see each file listed during extraction (verbose) mode?
1383 1.33 mrg On some console hardware, such as serial consoles and Sun frame buffers,
1384 1.33 mrg this can extend the total extraction time.
1385 1.1 pk __install_sets_1
1386 1.33 mrg echo -n "Use verbose listing for extractions? [y] "
1387 1.33 mrg getresp "y"
1388 1.33 mrg case "$resp" in
1389 1.33 mrg y*|Y*)
1390 1.33 mrg verbose_flag=v
1391 1.33 mrg ;;
1392 1.33 mrg *)
1393 1.37 is echo "Not using verbose listing."
1394 1.33 mrg verbose_flag=""
1395 1.33 mrg ;;
1396 1.33 mrg esac
1397 1.13 pk
1398 1.31 sjg if [ -d ${Default_sets_dir:-/dev/null} ]; then
1399 1.31 sjg if dir_has_sets $Default_sets_dir $THESETS; then
1400 1.31 sjg local_sets_dir=$Default_sets_dir
1401 1.31 sjg fi
1402 1.31 sjg fi
1403 1.47 christos if [ -n "${local_sets_dir}" ]; then
1404 1.13 pk install_from_mounted_fs ${local_sets_dir}
1405 1.48 christos if [ -n "$_setsdone" ]; then
1406 1.13 pk _yup="TRUE"
1407 1.13 pk fi
1408 1.13 pk fi
1409 1.13 pk
1410 1.13 pk # Go on prodding for alternate locations
1411 1.13 pk resp="" # force at least one iteration
1412 1.48 christos while [ -z "${resp}" ]; do
1413 1.13 pk # If _yup is not FALSE, it means that we extracted sets above.
1414 1.13 pk # If that's the case, bypass the menu the first time.
1415 1.48 christos if [ "${_yup}" = "FALSE" ]; then
1416 1.13 pk echo -n "Install from (f)tp, (t)ape, (C)D-ROM, (N)FS"
1417 1.13 pk echo -n " or local (d)isk? "
1418 1.13 pk getresp ""
1419 1.1 pk case "$resp" in
1420 1.13 pk d*|D*)
1421 1.13 pk install_disk
1422 1.13 pk ;;
1423 1.13 pk f*|F*)
1424 1.13 pk install_ftp
1425 1.13 pk ;;
1426 1.13 pk t*|T*)
1427 1.13 pk install_tape
1428 1.13 pk ;;
1429 1.13 pk c*|C*)
1430 1.13 pk install_cdrom
1431 1.13 pk ;;
1432 1.13 pk n*|N*)
1433 1.13 pk install_nfs
1434 1.1 pk ;;
1435 1.1 pk *)
1436 1.13 pk echo "Invalid response: $resp"
1437 1.13 pk resp=""
1438 1.1 pk ;;
1439 1.1 pk esac
1440 1.13 pk else
1441 1.13 pk _yup="FALSE" # So we'll ask next time
1442 1.13 pk fi
1443 1.1 pk
1444 1.13 pk # Give the user the opportunity to extract more sets. They
1445 1.13 pk # don't necessarily have to come from the same media.
1446 1.13 pk echo ""
1447 1.13 pk echo -n "Extract more sets? [n] "
1448 1.13 pk getresp "n"
1449 1.1 pk case "$resp" in
1450 1.13 pk y*|Y*)
1451 1.13 pk # Force loop to repeat
1452 1.13 pk resp=""
1453 1.1 pk ;;
1454 1.1 pk
1455 1.1 pk *)
1456 1.1 pk ;;
1457 1.1 pk esac
1458 1.13 pk done
1459 1.1 pk }
1460 1.1 pk
1461 1.1 pk munge_fstab()
1462 1.1 pk {
1463 1.1 pk local _fstab
1464 1.1 pk local _fstab_shadow
1465 1.5 pk local _dev
1466 1.5 pk local _mp
1467 1.7 leo local _fstype
1468 1.5 pk local _rest
1469 1.6 leo
1470 1.1 pk # Now that the 'real' fstab is configured, we munge it into a 'shadow'
1471 1.1 pk # fstab which we'll use for mounting and unmounting all of the target
1472 1.1 pk # filesystems relative to /mnt. Mount all filesystems.
1473 1.1 pk _fstab=$1
1474 1.1 pk _fstab_shadow=$2
1475 1.7 leo ( while read _dev _mp _fstype _rest; do
1476 1.7 leo # Skip comment lines
1477 1.7 leo case "$_dev" in
1478 1.7 leo \#*) continue;;
1479 1.7 leo *) ;;
1480 1.7 leo esac
1481 1.7 leo # and some filesystem types (like there are swap,kernfs,...)
1482 1.7 leo case "$_fstype" in
1483 1.7 leo ffs|ufs|nfs) ;;
1484 1.7 leo *) continue;;
1485 1.7 leo esac
1486 1.3 pk if [ "$_mp" = "/" ]; then
1487 1.8 pk echo $_dev /mnt $_fstype $_rest
1488 1.1 pk else
1489 1.8 pk echo $_dev /mnt$_mp $_fstype $_rest
1490 1.3 pk fi
1491 1.6 leo done ) < $_fstab > $_fstab_shadow
1492 1.1 pk }
1493 1.1 pk
1494 1.1 pk mount_fs()
1495 1.1 pk {
1496 1.1 pk # Must mount filesystems manually, one at a time, so we can make
1497 1.1 pk # sure the mount points exist.
1498 1.1 pk # $1 is a file in fstab format
1499 1.1 pk local _fstab
1500 1.1 pk
1501 1.1 pk _fstab=$1
1502 1.1 pk
1503 1.1 pk ( while read line; do
1504 1.4 pk set -- $line
1505 1.4 pk _dev=$1
1506 1.4 pk _mp=$2
1507 1.4 pk _fstype=$3
1508 1.4 pk _opt=$4
1509 1.1 pk
1510 1.1 pk # If not the root filesystem, make sure the mount
1511 1.1 pk # point is present.
1512 1.47 christos if [ "$_mp" != "/mnt" ]; then
1513 1.1 pk mkdir -p $_mp
1514 1.1 pk fi
1515 1.1 pk
1516 1.1 pk # Mount the filesystem. If the mount fails, exit
1517 1.1 pk # with an error condition to tell the outer
1518 1.1 pk # later to bail.
1519 1.29 mrg if ! mount -v -t $_fstype -o async -o $_opt $_dev $_mp ; then
1520 1.63 andvar # error message displayed by mount
1521 1.1 pk exit 1
1522 1.1 pk fi
1523 1.1 pk done ) < $_fstab
1524 1.1 pk
1525 1.47 christos if [ "$?" != "0" ]; then
1526 1.1 pk cat << \__mount_filesystems_1
1527 1.1 pk
1528 1.1 pk FATAL ERROR: Cannot mount filesystems. Double-check your configuration
1529 1.1 pk and restart the installation process.
1530 1.1 pk __mount_filesystems_1
1531 1.1 pk exit
1532 1.1 pk fi
1533 1.1 pk }
1534 1.1 pk
1535 1.1 pk unmount_fs()
1536 1.1 pk {
1537 1.1 pk # Unmount all filesystems and check their integrity.
1538 1.13 pk # Usage: [-fast] <fstab file>
1539 1.13 pk local _fast
1540 1.1 pk local _fstab
1541 1.13 pk local _pid
1542 1.13 pk
1543 1.13 pk if [ "$1" = "-fast" ]; then
1544 1.13 pk _fast=1
1545 1.13 pk _fstab=$2
1546 1.13 pk else
1547 1.13 pk _fast=0
1548 1.13 pk _fstab=$1
1549 1.13 pk fi
1550 1.1 pk
1551 1.51 tsutsui if ! [ -f "${_fstab}" ] || ! [ -s "${_fstab}" ]; then
1552 1.13 pk echo "fstab empty" > /dev/tty
1553 1.13 pk return
1554 1.13 pk fi
1555 1.1 pk
1556 1.13 pk if [ $_fast = 0 ]; then
1557 1.13 pk echo -n "Syncing disks..."
1558 1.47 christos _pid=$(twiddle)
1559 1.13 pk sync; sleep 4; sync; sleep 2; sync; sleep 2
1560 1.13 pk kill $_pid
1561 1.13 pk echo "done."
1562 1.13 pk fi
1563 1.1 pk
1564 1.1 pk (
1565 1.1 pk _devs=""
1566 1.1 pk _mps=""
1567 1.1 pk # maintain reverse order
1568 1.1 pk while read line; do
1569 1.3 pk set -- $line
1570 1.3 pk _devs="$1 ${_devs}"
1571 1.3 pk _mps="$2 ${_mps}"
1572 1.1 pk done
1573 1.63 andvar echo -n "Unmounting filesystems... "
1574 1.1 pk for _mp in ${_mps}; do
1575 1.1 pk echo -n "${_mp} "
1576 1.1 pk umount ${_mp}
1577 1.1 pk done
1578 1.1 pk echo "Done."
1579 1.1 pk
1580 1.13 pk if [ $_fast = 0 ]; then
1581 1.13 pk exit
1582 1.13 pk fi
1583 1.1 pk echo "Checking filesystem integrity..."
1584 1.1 pk for _dev in ${_devs}; do
1585 1.1 pk echo "${_dev}"
1586 1.1 pk fsck -f ${_dev}
1587 1.1 pk done
1588 1.1 pk echo "Done."
1589 1.1 pk ) < $_fstab
1590 1.1 pk }
1591 1.1 pk
1592 1.1 pk check_fs()
1593 1.1 pk {
1594 1.1 pk # Check filesystem integrity.
1595 1.1 pk # $1 is a file in fstab format
1596 1.1 pk local _fstab
1597 1.1 pk
1598 1.1 pk _fstab=$1
1599 1.1 pk
1600 1.1 pk (
1601 1.1 pk _devs=""
1602 1.1 pk _mps=""
1603 1.1 pk while read line; do
1604 1.3 pk set -- $line
1605 1.3 pk _devs="$1 ${_devs}"
1606 1.3 pk _mps="$2 ${_mps}"
1607 1.1 pk done
1608 1.1 pk
1609 1.1 pk echo "Checking filesystem integrity..."
1610 1.1 pk for _dev in ${_devs}; do
1611 1.1 pk echo "${_dev}"
1612 1.1 pk fsck -f ${_dev}
1613 1.1 pk done
1614 1.1 pk echo "Done."
1615 1.1 pk ) < $_fstab
1616 1.1 pk }
1617 1.48 christos
1618 1.48 christos mi_mount_kernfs() {
1619 1.48 christos # Make sure kernfs is mounted.
1620 1.48 christos if [ ! -d /kern ] || [ ! -e /kern/msgbuf ]; then
1621 1.48 christos mkdir /kern > /dev/null 2>&1
1622 1.48 christos /sbin/mount_kernfs /kern /kern
1623 1.48 christos fi
1624 1.48 christos }
1625 1.48 christos
1626 1.48 christos mi_filter_msgbuf() {
1627 1.48 christos # Remove timestemps, sort.
1628 1.48 christos sed -e 's/^\[[0-9. ]*\] //' < /kern/msgbuf | sort -u
1629 1.48 christos }
1630 1.48 christos
1631 1.48 christos mi_filter_dmesg() {
1632 1.48 christos # Remove timestemps, sort.
1633 1.55 tsutsui dmesg | awk '{ h=$0; gsub("^[[0-9. ]*] ", "", h); print h; }' \
1634 1.48 christos | sort -u
1635 1.48 christos }
1636