install.sub revision 1.59 1 1.1 pk #!/bin/sh
2 1.59 tsutsui # $NetBSD: install.sub,v 1.59 2020/12/12 05:23:21 tsutsui 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.49 maya UPGRSETS="base comp games man misc 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.29 mrg /^[ ]*inet/{
407 1.29 mrg s/inet//
408 1.29 mrg s/--> [0-9.][0-9.]*//
409 1.29 mrg s/netmask//
410 1.29 mrg s/broadcast//
411 1.47 christos p;}')
412 1.29 mrg
413 1.29 mrg _interface_ip=$1
414 1.29 mrg _interface_mask=$2
415 1.8 pk
416 1.1 pk # Get IP address
417 1.1 pk resp="" # force one iteration
418 1.47 christos while [ -z "${resp}" ]; do
419 1.8 pk echo -n "IP address? [$_interface_ip] "
420 1.8 pk getresp "$_interface_ip"
421 1.1 pk _interface_ip=$resp
422 1.1 pk done
423 1.1 pk
424 1.1 pk # Get symbolic name
425 1.1 pk resp="" # force one iteration
426 1.47 christos while [ -z "${resp}" ]; do
427 1.1 pk echo -n "Symbolic (host) name? "
428 1.1 pk getresp ""
429 1.1 pk _interface_symname=$resp
430 1.1 pk done
431 1.1 pk
432 1.1 pk # Get netmask
433 1.1 pk resp="" # force one iteration
434 1.50 tsutsui while [ -z "${resp}" ]; do
435 1.8 pk echo -n "Netmask? [$_interface_mask] "
436 1.8 pk getresp "$_interface_mask"
437 1.1 pk _interface_mask=$resp
438 1.1 pk done
439 1.1 pk
440 1.16 pk echo "Your network interface might require explicit selection"
441 1.16 pk echo "of the type of network medium attached. Supported media:"
442 1.29 mrg echo "$_interface_supported_media"
443 1.29 mrg echo -n "Additional media type arguments (none)? [$_interface_mediumtype] "
444 1.16 pk getresp "$_interface_mediumtype"
445 1.28 is _m=""
446 1.47 christos if [ "${resp:-none}" != "none" ]; then
447 1.16 pk _interface_mediumtype=$resp
448 1.28 is _m="media ${resp}"
449 1.16 pk fi
450 1.16 pk
451 1.16 pk
452 1.15 gwr echo "Your network interface might require additional link-layer"
453 1.47 christos echo "directives (like 'link0'). If this is the case you can enter"
454 1.15 gwr echo "these at the next prompt."
455 1.15 gwr echo ""
456 1.29 mrg echo -n "Additional link-layer arguments (none)? [$_interface_extra] "
457 1.15 gwr getresp "$_interface_extra"
458 1.47 christos if [ "${resp:-none}" != "none" ]; then
459 1.15 gwr _interface_extra=$resp
460 1.15 gwr fi
461 1.15 gwr
462 1.1 pk # Configure the interface. If it
463 1.1 pk # succeeds, add it to the permanent
464 1.1 pk # network configuration info.
465 1.8 pk if [ $_up != "UP" ]; then
466 1.8 pk ifconfig ${_interface_name} down
467 1.8 pk if ifconfig ${_interface_name} inet \
468 1.8 pk ${_interface_ip} \
469 1.28 is netmask ${_interface_mask} \
470 1.28 is ${_interface_extra} ${_m} up ; then
471 1.8 pk addifconfig \
472 1.28 is "${_interface_name}" \
473 1.28 is "${_interface_symname}" \
474 1.28 is "${_interface_ip}" \
475 1.28 is "${_interface_mask}" \
476 1.38 is "${_m}" \
477 1.28 is "${_interface_extra}"
478 1.8 pk return 0
479 1.8 pk fi
480 1.8 pk else
481 1.8 pk echo "Interface ${_interface_name} is already active."
482 1.8 pk echo "Just saving configuration on new root filesystem."
483 1.1 pk addifconfig \
484 1.28 is "${_interface_name}" \
485 1.28 is "${_interface_symname}" \
486 1.28 is "${_interface_ip}" \
487 1.28 is "${_interface_mask}" \
488 1.38 is "${_m}" \
489 1.28 is "${_interface_extra}"
490 1.1 pk fi
491 1.1 pk return 1
492 1.1 pk }
493 1.1 pk
494 1.35 lukem # Much of this is gratuitously stolen from /etc/rc.d/network.
495 1.1 pk enable_network() {
496 1.1 pk
497 1.1 pk # Set up the hostname.
498 1.39 abs if [ -f /mnt/etc/myname ]; then
499 1.47 christos hostname=$(cat /mnt/etc/myname)
500 1.39 abs elif [ -f /mnt/etc/rc.conf ];then
501 1.47 christos hostname=$(sh -c '. /mnt/etc/rc.conf ; echo $hostname')
502 1.39 abs else
503 1.1 pk echo "ERROR: no /etc/myname!"
504 1.1 pk return 1
505 1.1 pk fi
506 1.39 abs if [ -z "$hostname" ];then
507 1.39 abs echo "ERROR: hostname not set in /etc/myname or /etc/rc.conf!"
508 1.39 abs return 1
509 1.39 abs fi
510 1.1 pk hostname $hostname
511 1.1 pk
512 1.1 pk # configure all the interfaces which we know about.
513 1.16 pk if [ -f /mnt/etc/rc.conf ]; then
514 1.16 pk (
515 1.16 pk # assume network interface configuration style 1.2D and up
516 1.43 bouyer if [ -f /mnt/etc/defaults/rc.conf ]; then
517 1.43 bouyer . /mnt/etc/defaults/rc.conf
518 1.43 bouyer fi
519 1.16 pk . /mnt/etc/rc.conf
520 1.16 pk
521 1.16 pk if [ "$net_interfaces" != NO ]; then
522 1.24 pk if [ "$auto_ifconfig" = YES ]; then
523 1.47 christos tmp="$(ifconfig -l)"
524 1.16 pk else
525 1.16 pk tmp="$net_interfaces"
526 1.16 pk fi
527 1.16 pk echo -n "configuring network interfaces:"
528 1.16 pk for i in $tmp; do
529 1.47 christos eval $(echo 'args=$ifconfig_'$i)
530 1.53 kre if [ -n "$args" ]; then
531 1.16 pk echo -n " $i"
532 1.16 pk ifconfig $i $args
533 1.16 pk elif [ -f /mnt/etc/ifconfig.$i ]; then
534 1.16 pk echo -n " $i"
535 1.16 pk (while read args; do
536 1.16 pk ifconfig $i $args
537 1.16 pk done) < /mnt/etc/ifconfig.$i
538 1.24 pk elif [ "$auto_ifconfig" != YES ]; then
539 1.16 pk echo
540 1.16 pk echo -n "/mnt/etc/ifconfig.$i missing"
541 1.16 pk echo -n "& ifconfig_$i not set"
542 1.16 pk echo "; interface $i can't be configured"
543 1.16 pk fi
544 1.16 pk done
545 1.16 pk echo "."
546 1.16 pk fi
547 1.16 pk )
548 1.16 pk else
549 1.1 pk (
550 1.1 pk tmp="$IFS"
551 1.1 pk IFS="$IFS."
552 1.47 christos set -- $(echo /mnt/etc/hostname*)
553 1.1 pk IFS=$tmp
554 1.1 pk unset tmp
555 1.1 pk
556 1.1 pk while [ $# -ge 2 ] ; do
557 1.1 pk shift # get rid of "hostname"
558 1.1 pk (
559 1.1 pk read af name mask bcaddr extras
560 1.1 pk read dt dtaddr
561 1.1 pk
562 1.53 kre if [ -z "$name" ]; then
563 1.1 pk echo "/etc/hostname.$1: invalid network configuration file"
564 1.1 pk exit
565 1.1 pk fi
566 1.1 pk
567 1.1 pk cmd="ifconfig $1 $af $name "
568 1.1 pk if [ "${dt}" = "dest" ]; then cmd="$cmd $dtaddr"; fi
569 1.1 pk if [ -n "$mask" ]; then cmd="$cmd netmask $mask"; fi
570 1.47 christos if [ "${bcaddr:-NONE}" != "NONE" ]; then
571 1.1 pk cmd="$cmd broadcast $bcaddr";
572 1.1 pk fi
573 1.1 pk cmd="$cmd $extras"
574 1.1 pk
575 1.1 pk $cmd
576 1.1 pk ) < /mnt/etc/hostname.$1
577 1.1 pk shift
578 1.1 pk done
579 1.1 pk )
580 1.16 pk fi
581 1.1 pk
582 1.1 pk # set the address for the loopback interface
583 1.1 pk ifconfig lo0 inet localhost
584 1.1 pk
585 1.1 pk # use loopback, not the wire
586 1.1 pk route add $hostname localhost
587 1.1 pk
588 1.1 pk # /etc/mygate, if it exists, contains the name of my gateway host
589 1.1 pk # that name must be in /etc/hosts.
590 1.1 pk if [ -f /mnt/etc/mygate ]; then
591 1.1 pk route delete default > /dev/null 2>&1
592 1.47 christos route add default $(cat /mnt/etc/mygate)
593 1.1 pk fi
594 1.1 pk
595 1.1 pk # enable the resolver, if appropriate.
596 1.1 pk if [ -f /mnt/etc/resolv.conf ]; then
597 1.1 pk _resolver_enabled="TRUE"
598 1.1 pk cp /mnt/etc/resolv.conf /tmp/resolv.conf.shadow
599 1.1 pk fi
600 1.1 pk
601 1.1 pk # Display results...
602 1.1 pk echo "Network interface configuration:"
603 1.1 pk ifconfig -a
604 1.1 pk
605 1.1 pk echo ""
606 1.1 pk
607 1.47 christos if [ "${_resolver_enabled:-FALSE}" = "TRUE" ]; then
608 1.1 pk netstat -r
609 1.1 pk echo ""
610 1.1 pk echo "Resolver enabled."
611 1.1 pk else
612 1.1 pk netstat -rn
613 1.1 pk echo ""
614 1.1 pk echo "Resolver not enabled."
615 1.1 pk fi
616 1.1 pk
617 1.1 pk return 0
618 1.1 pk }
619 1.1 pk
620 1.1 pk install_ftp() {
621 1.21 leo local _f
622 1.21 leo local _sets
623 1.21 leo local _next
624 1.21 leo
625 1.21 leo # Build a script to extract valid files from a list
626 1.21 leo # of filenames on stdin.
627 1.21 leo # XXX : Can we use this on more places? Leo.
628 1.21 leo
629 1.21 leo echo "#!/bin/sh" > /tmp/fname_filter.sh
630 1.21 leo echo "while read line; do" >> /tmp/fname_filter.sh
631 1.21 leo echo " case \$line in" >> /tmp/fname_filter.sh
632 1.21 leo for _f in $THESETS; do
633 1.40 fredette echo " $_f.tar.gz|$_f.tgz|$_f.tar|$_f.${VERSION}.aa)" \
634 1.21 leo >> /tmp/fname_filter.sh
635 1.21 leo echo ' echo -n "$line ";;' \
636 1.21 leo >> /tmp/fname_filter.sh
637 1.21 leo done
638 1.21 leo echo " *) ;;" >> /tmp/fname_filter.sh
639 1.21 leo echo " esac" >> /tmp/fname_filter.sh
640 1.21 leo echo "done" >> /tmp/fname_filter.sh
641 1.21 leo
642 1.1 pk # Get several parameters from the user, and create
643 1.1 pk # a shell script that directs the appropriate
644 1.1 pk # commands into ftp.
645 1.1 pk cat << \__install_ftp_1
646 1.1 pk
647 1.1 pk This is an automated ftp-based installation process. You will be asked
648 1.1 pk several questions. The correct set of commands will be placed in a script
649 1.1 pk that will be fed to ftp(1).
650 1.1 pk
651 1.1 pk __install_ftp_1
652 1.1 pk # Get server IP address
653 1.1 pk resp="" # force one iteration
654 1.47 christos while [ -z "${resp}" ]; do
655 1.1 pk echo -n "Server IP? [${_ftp_server_ip}] "
656 1.1 pk getresp "${_ftp_server_ip}"
657 1.1 pk _ftp_server_ip=$resp
658 1.1 pk done
659 1.1 pk
660 1.1 pk # Get login name
661 1.1 pk resp="" # force one iteration
662 1.47 christos while [ -z "${resp}" ]; do
663 1.1 pk echo -n "Login? [${_ftp_server_login}] "
664 1.1 pk getresp "${_ftp_server_login}"
665 1.1 pk _ftp_server_login=$resp
666 1.1 pk done
667 1.1 pk
668 1.1 pk # Get password
669 1.1 pk resp="" # force one iteration
670 1.47 christos while [ -z "${resp}" ]; do
671 1.16 pk echo -n "Password? "
672 1.16 pk stty -echo
673 1.16 pk getresp ""
674 1.16 pk echo ""
675 1.16 pk stty echo
676 1.1 pk _ftp_server_password=$resp
677 1.1 pk done
678 1.1 pk
679 1.1 pk cat << \__install_ftp_2
680 1.1 pk
681 1.21 leo You will be asked to enter the name of the directory that contains the
682 1.21 leo installation sets. When you enter a '?' you will see a listing of the
683 1.21 leo current directory on the server.
684 1.21 leo __install_ftp_2
685 1.58 tsutsui echo ""
686 1.58 tsutsui echo "The default installation directory in the official ftp server is:"
687 1.58 tsutsui echo "/pub/NetBSD/NetBSD-${RELEASE}/${MACHINE}/binary/sets"
688 1.58 tsutsui
689 1.21 leo _sets=""
690 1.21 leo while [ -z "$_sets" ]
691 1.21 leo do
692 1.21 leo resp="" # force one iteration
693 1.47 christos while [ -z "${resp}" ]; do
694 1.21 leo echo -n "Server directory? [${_ftp_server_dir}] "
695 1.21 leo getresp "${_ftp_server_dir}"
696 1.47 christos if [ -z "$resp" ] && [ -z "$_ftp_server_dir" ]; then
697 1.21 leo resp=""
698 1.21 leo fi
699 1.21 leo done
700 1.21 leo if [ $resp != '?' ]; then
701 1.21 leo _ftp_server_dir=$resp
702 1.21 leo fi
703 1.21 leo
704 1.21 leo # Build the basics of an ftp-script...
705 1.21 leo echo "#!/bin/sh" > /tmp/ftp-script.sh
706 1.21 leo echo "cd /mnt" >> /tmp/ftp-script.sh
707 1.26 is echo "ftp -e -i -n $_ftp_server_ip << \__end_commands" >> \
708 1.21 leo /tmp/ftp-script.sh
709 1.21 leo echo "user $_ftp_server_login $_ftp_server_password" >> \
710 1.21 leo /tmp/ftp-script.sh
711 1.21 leo echo "bin" >> /tmp/ftp-script.sh
712 1.21 leo echo "cd $_ftp_server_dir" >> /tmp/ftp-script.sh
713 1.21 leo
714 1.21 leo # Make a copy of this script that lists the directory
715 1.21 leo # contents, and use that to determine the files to get.
716 1.21 leo cat /tmp/ftp-script.sh > /tmp/ftp-dir.sh
717 1.36 pk echo "nlist" >> /tmp/ftp-dir.sh
718 1.21 leo echo "quit" >> /tmp/ftp-dir.sh
719 1.21 leo echo "__end_commands" >> /tmp/ftp-dir.sh
720 1.21 leo
721 1.21 leo if [ $resp = '?' ]; then
722 1.21 leo sh /tmp/ftp-dir.sh
723 1.21 leo else
724 1.56 tsutsui _sets=$(sh /tmp/ftp-dir.sh | sort -u | sh /tmp/fname_filter.sh)
725 1.21 leo fi
726 1.21 leo done
727 1.21 leo rm -f /tmp/ftp-dir.sh /tmp/fname_filter.sh
728 1.59 tsutsui rm -f /tmp/ftp-script.sh
729 1.59 tsutsui
730 1.59 tsutsui # Prepare ftp-fetch script to fetch binary sets
731 1.59 tsutsui _download_dir=INSTALL
732 1.59 tsutsui _ftp_opts=""
733 1.59 tsutsui _ftp_url="ftp://$_ftp_server_login:$_ftp_server_password@$_ftp_server_ip$_ftp_server_dir/"
734 1.59 tsutsui echo "#!/bin/sh" > /tmp/ftp-fetch.sh
735 1.59 tsutsui echo "cd /mnt" >> /tmp/ftp-fetch.sh
736 1.59 tsutsui echo "mkdir -p $_download_dir" >> /tmp/ftp-fetch.sh
737 1.21 leo
738 1.21 leo while : ; do
739 1.21 leo echo "The following sets are available for extraction:"
740 1.27 is echo "(marked sets are already on the extraction list)"
741 1.21 leo echo ""
742 1.1 pk
743 1.21 leo _next=""
744 1.21 leo for _f in $_sets ; do
745 1.21 leo if isin $_f $_setsdone; then
746 1.21 leo echo -n "[X] "
747 1.21 leo _next=""
748 1.21 leo else
749 1.21 leo echo -n " "
750 1.21 leo if [ -z "$_next" ]; then _next=$_f; fi
751 1.21 leo fi
752 1.21 leo echo $_f
753 1.21 leo done
754 1.21 leo echo ""
755 1.1 pk
756 1.21 leo # Get name of the file and add extraction command
757 1.59 tsutsui # to the ftp-fetch script.
758 1.47 christos if [ -z "$_next" ]; then resp=n; else resp=y; fi
759 1.21 leo echo -n "Continue to add filenames [$resp]? "
760 1.21 leo getresp "$resp"
761 1.21 leo if [ "$resp" = "n" ]; then
762 1.1 pk break
763 1.1 pk fi
764 1.1 pk
765 1.21 leo echo -n "File name [$_next]? "
766 1.21 leo getresp "$_next"
767 1.21 leo if isin $resp $_sets; then
768 1.59 tsutsui echo "echo Fetching $resp:" >> \
769 1.59 tsutsui /tmp/ftp-fetch.sh
770 1.59 tsutsui echo "ftp ${_ftp_opts} -o $_download_dir/$resp ${_ftp_url}$resp" >> \
771 1.59 tsutsui /tmp/ftp-fetch.sh
772 1.59 tsutsui echo "echo Extracting $resp:" >> \
773 1.59 tsutsui /tmp/ftp-fetch.sh
774 1.59 tsutsui echo "pax -zr${verbose_flag}pe -f $_download_dir/$resp" >> \
775 1.59 tsutsui /tmp/ftp-fetch.sh
776 1.59 tsutsui echo "rm -f $_download_dir/$resp" >> \
777 1.59 tsutsui /tmp/ftp-fetch.sh
778 1.21 leo _setsdone="$resp $_setsdone"
779 1.21 leo else
780 1.21 leo echo "You entered an invalid filename."
781 1.21 leo echo ""
782 1.21 leo fi
783 1.1 pk done
784 1.1 pk
785 1.59 tsutsui sh /tmp/ftp-fetch.sh
786 1.59 tsutsui rm -f /tmp/ftp-fetch.sh
787 1.1 pk echo "Extraction complete."
788 1.1 pk }
789 1.1 pk
790 1.11 pk install_from_mounted_fs() {
791 1.13 pk # $1 - directory containing installation sets
792 1.1 pk local _filename
793 1.13 pk local _sets
794 1.12 pk local _next
795 1.29 mrg local _all
796 1.1 pk local _f
797 1.18 is local _dirname
798 1.1 pk
799 1.18 is _dirname=$1
800 1.13 pk _sets=""
801 1.20 is
802 1.31 sjg if ! dir_has_sets ${_dirname} $THESETS
803 1.31 sjg then
804 1.20 is
805 1.18 is echo ""
806 1.31 sjg echo "The directory at the mount point, \"${_dirname}\", contains: "
807 1.18 is echo ""
808 1.18 is ls -F ${_dirname}
809 1.18 is echo ""
810 1.31 sjg echo "Enter the subdirectory relative to the mountpoint, that"
811 1.31 sjg echo -n "contains the savesets: [try this directory] "
812 1.18 is getresp ""
813 1.47 christos if [ -n "${resp}" ]; then
814 1.18 is _dirname=${_dirname}/$resp
815 1.18 is fi
816 1.31 sjg
817 1.31 sjg while ! dir_has_sets ${_dirname} $THESETS; do
818 1.31 sjg echo ""
819 1.31 sjg echo -n "There are no NetBSD install sets available in "
820 1.31 sjg echo "\"${_dirname}\"."
821 1.31 sjg echo "\"${_dirname}\" contains: "
822 1.31 sjg echo ""
823 1.31 sjg ls -F ${_dirname}
824 1.31 sjg echo ""
825 1.31 sjg echo -n "Enter subdirectory: [try other install media] "
826 1.31 sjg getresp ""
827 1.47 christos if [ -z "${resp}" ]; then
828 1.31 sjg return
829 1.31 sjg fi
830 1.31 sjg if [ ! -d ${_dirname}/${resp} ]; then
831 1.31 sjg echo "\"${resp}\" is no directory; try again."
832 1.31 sjg else
833 1.31 sjg _dirname=${_dirname}/$resp
834 1.31 sjg fi
835 1.31 sjg done
836 1.31 sjg fi
837 1.18 is
838 1.18 is for _f in $THESETS ; do
839 1.18 is if [ -f ${_dirname}/${_f}.tar.gz ]; then
840 1.18 is _sets="$_sets ${_f}.tar.gz"
841 1.18 is elif [ -f ${_dirname}/${_f}.tgz ]; then
842 1.18 is _sets="$_sets ${_f}.tgz"
843 1.40 fredette elif [ -f ${_dirname}/${_f}.tar ]; then
844 1.40 fredette _sets="$_sets ${_f}.tar"
845 1.18 is elif [ -f ${_dirname}/${_f}${VERSION}.aa ]; then
846 1.18 is _sets="$_sets ${_f}${VERSION}"
847 1.18 is fi
848 1.18 is done
849 1.1 pk
850 1.1 pk while : ; do
851 1.1 pk echo "The following sets are available for extraction:"
852 1.1 pk echo "(marked sets have already been extracted)"
853 1.1 pk echo ""
854 1.1 pk
855 1.12 pk _next=""
856 1.29 mrg _all=""
857 1.1 pk for _f in $_sets ; do
858 1.1 pk if isin $_f $_setsdone; then
859 1.1 pk echo -n "[X] "
860 1.12 pk _next=""
861 1.1 pk else
862 1.1 pk echo -n " "
863 1.29 mrg if [ -z "$_next" ]; then
864 1.29 mrg _next=$_f;
865 1.29 mrg fi
866 1.29 mrg _all="$_all $_f"
867 1.1 pk fi
868 1.1 pk echo $_f
869 1.1 pk done
870 1.1 pk echo ""
871 1.1 pk
872 1.1 pk # Get the name of the file.
873 1.47 christos if [ -z "$_next" ]; then
874 1.33 mrg resp=n
875 1.33 mrg else
876 1.33 mrg resp=y
877 1.33 mrg fi
878 1.1 pk echo -n "Continue extraction [$resp]?"
879 1.1 pk getresp "$resp"
880 1.1 pk if [ "$resp" = "n" ]; then
881 1.1 pk break
882 1.1 pk fi
883 1.1 pk
884 1.29 mrg echo -n "File name(s) (or "all") [$_next]? "
885 1.12 pk getresp "$_next"
886 1.29 mrg if [ "x$resp" = xall ]; then
887 1.29 mrg resp="$_all"
888 1.29 mrg fi
889 1.29 mrg
890 1.29 mrg for _f in $resp; do
891 1.29 mrg _filename="/${_dirname}/$_f"
892 1.1 pk
893 1.29 mrg # Ensure file exists
894 1.29 mrg if [ ! -f $_filename ]; then
895 1.29 mrg if [ -f ${_filename}.aa ]; then
896 1.29 mrg _filename=${_filename}.\?\?
897 1.29 mrg else
898 1.18 is echo "File $_filename does not exist. Check to make"
899 1.18 is echo "sure you entered the information properly."
900 1.29 mrg continue 2
901 1.29 mrg fi
902 1.18 is fi
903 1.1 pk
904 1.29 mrg # Extract file
905 1.29 mrg echo "Extracting the $_f set:"
906 1.40 fredette case "$_filename" in
907 1.40 fredette *.tar)
908 1.40 fredette (cd /mnt; pax -r${verbose_flag}pe < $_filename)
909 1.40 fredette ;;
910 1.40 fredette *)
911 1.40 fredette cat $_filename | \
912 1.40 fredette (cd /mnt; pax -zr${verbose_flag}pe)
913 1.40 fredette ;;
914 1.40 fredette esac
915 1.29 mrg echo "Extraction complete."
916 1.29 mrg _setsdone="$_f $_setsdone"
917 1.29 mrg done
918 1.1 pk
919 1.1 pk done
920 1.1 pk }
921 1.1 pk
922 1.1 pk install_cdrom() {
923 1.5 pk local _drive
924 1.6 leo local _partition_range
925 1.5 pk local _partition
926 1.5 pk local _fstype
927 1.5 pk local _directory
928 1.5 pk
929 1.1 pk # Get the cdrom device info
930 1.1 pk cat << \__install_cdrom_1
931 1.1 pk
932 1.1 pk The following CD-ROM devices are installed on your system; please select
933 1.6 leo the CD-ROM device containing the partition with the installation sets:
934 1.1 pk
935 1.1 pk __install_cdrom_1
936 1.47 christos _CDDEVS=$(md_get_cddevs)
937 1.1 pk echo "$_CDDEVS"
938 1.1 pk echo ""
939 1.1 pk echo -n "Which is the CD-ROM with the installation media? [abort] "
940 1.1 pk getresp "abort"
941 1.1 pk case "$resp" in
942 1.1 pk abort)
943 1.1 pk echo "Aborting."
944 1.1 pk return
945 1.1 pk ;;
946 1.1 pk
947 1.1 pk *)
948 1.1 pk if isin $resp $_CDDEVS ; then
949 1.5 pk _drive=$resp
950 1.1 pk else
951 1.1 pk echo ""
952 1.1 pk echo "The CD-ROM $resp does not exist."
953 1.1 pk echo "Aborting."
954 1.1 pk return
955 1.1 pk fi
956 1.1 pk ;;
957 1.1 pk esac
958 1.1 pk
959 1.1 pk # Get partition
960 1.47 christos _partition_range=$(md_get_partition_range)
961 1.1 pk resp="" # force one iteration
962 1.47 christos while [ -z "${resp}" ]; do
963 1.17 is echo -n "Partition? [a] "
964 1.17 is getresp "a"
965 1.1 pk case "$resp" in
966 1.6 leo $_partition_range)
967 1.5 pk _partition=$resp
968 1.1 pk ;;
969 1.1 pk
970 1.1 pk *)
971 1.1 pk echo "Invalid response: $resp"
972 1.1 pk resp="" # force loop to repeat
973 1.1 pk ;;
974 1.1 pk esac
975 1.1 pk done
976 1.1 pk
977 1.1 pk # Ask for filesystem type
978 1.1 pk cat << \__install_cdrom_2
979 1.1 pk
980 1.1 pk There are two CD-ROM filesystem types currently supported by this program:
981 1.1 pk 1) ISO-9660 (cd9660)
982 1.1 pk 2) Berkeley Fast Filesystem (ffs)
983 1.1 pk
984 1.1 pk __install_cdrom_2
985 1.1 pk resp="" # force one iteration
986 1.47 christos while [ -z "${resp}" ]; do
987 1.1 pk echo -n "Which filesystem type? [cd9660] "
988 1.1 pk getresp "cd9660"
989 1.1 pk case "$resp" in
990 1.1 pk cd9660|ffs)
991 1.5 pk _fstype=$resp
992 1.1 pk ;;
993 1.1 pk
994 1.1 pk *)
995 1.1 pk echo "Invalid response: $resp"
996 1.1 pk resp="" # force loop to repeat
997 1.1 pk ;;
998 1.1 pk esac
999 1.1 pk done
1000 1.1 pk
1001 1.1 pk # Mount the CD-ROM
1002 1.17 is if ! mount -t ${_fstype} -o ro \
1003 1.5 pk /dev/${_drive}${_partition} /mnt2 ; then
1004 1.1 pk echo "Cannot mount CD-ROM drive. Aborting."
1005 1.1 pk return
1006 1.1 pk fi
1007 1.1 pk
1008 1.20 is install_from_mounted_fs /mnt2
1009 1.5 pk umount -f /mnt2 > /dev/null 2>&1
1010 1.5 pk }
1011 1.5 pk
1012 1.14 leo mount_a_disk() {
1013 1.14 leo # Mount a disk on /mnt2. The set of disk devices to choose from
1014 1.14 leo # is $_DKDEVS.
1015 1.14 leo # returns 0 on failure.
1016 1.14 leo
1017 1.5 pk local _drive
1018 1.6 leo local _partition_range
1019 1.5 pk local _partition
1020 1.5 pk local _fstype
1021 1.5 pk local _fsopts
1022 1.5 pk local _directory
1023 1.5 pk local _md_fstype
1024 1.5 pk local _md_fsopts
1025 1.5 pk
1026 1.5 pk getresp "abort"
1027 1.5 pk case "$resp" in
1028 1.5 pk abort)
1029 1.5 pk echo "Aborting."
1030 1.14 leo return 0
1031 1.5 pk ;;
1032 1.5 pk
1033 1.5 pk *)
1034 1.5 pk if isin $resp $_DKDEVS ; then
1035 1.5 pk _drive=$resp
1036 1.5 pk else
1037 1.5 pk echo ""
1038 1.5 pk echo "The disk $resp does not exist."
1039 1.5 pk echo "Aborting."
1040 1.14 leo return 0
1041 1.5 pk fi
1042 1.5 pk ;;
1043 1.5 pk esac
1044 1.5 pk
1045 1.5 pk # Get partition
1046 1.47 christos _partition_range=$(md_get_partition_range)
1047 1.5 pk resp="" # force one iteration
1048 1.47 christos while [ -z "${resp}" ]; do
1049 1.5 pk echo -n "Partition? [d] "
1050 1.5 pk getresp "d"
1051 1.5 pk case "$resp" in
1052 1.6 leo $_partition_range)
1053 1.5 pk _partition=$resp
1054 1.5 pk ;;
1055 1.5 pk
1056 1.5 pk *)
1057 1.5 pk echo "Invalid response: $resp"
1058 1.5 pk resp="" # force loop to repeat
1059 1.5 pk ;;
1060 1.5 pk esac
1061 1.5 pk done
1062 1.5 pk
1063 1.5 pk # Ask for filesystem type
1064 1.14 leo cat << \__mount_a_disk_2
1065 1.5 pk
1066 1.5 pk The following filesystem types are supported:
1067 1.5 pk 1) ffs
1068 1.46 mlelstv 2) cd9660
1069 1.14 leo __mount_a_disk_2
1070 1.47 christos _md_fstype=$(md_native_fstype)
1071 1.47 christos _md_fsopts=$(md_native_fsopts)
1072 1.53 kre if [ -n "$_md_fstype" ]; then
1073 1.46 mlelstv echo " 3) $_md_fstype"
1074 1.5 pk else
1075 1.5 pk _md_fstype="_undefined_"
1076 1.5 pk fi
1077 1.5 pk resp="" # force one iteration
1078 1.47 christos while [ -z "${resp}" ]; do
1079 1.5 pk echo -n "Which filesystem type? [ffs] "
1080 1.5 pk getresp "ffs"
1081 1.5 pk case "$resp" in
1082 1.46 mlelstv ffs|cd9660)
1083 1.5 pk _fstype=$resp
1084 1.5 pk _fsopts="ro"
1085 1.5 pk ;;
1086 1.5 pk $_md_fstype)
1087 1.5 pk _fstype=$resp
1088 1.5 pk _fsopts=$_md_fsopts
1089 1.5 pk ;;
1090 1.5 pk *)
1091 1.5 pk echo "Invalid response: $resp"
1092 1.5 pk resp="" # force loop to repeat
1093 1.5 pk ;;
1094 1.5 pk esac
1095 1.5 pk done
1096 1.5 pk
1097 1.5 pk # Mount the disk
1098 1.5 pk if ! mount -t ${_fstype} -o $_fsopts \
1099 1.5 pk /dev/${_drive}${_partition} /mnt2 ; then
1100 1.5 pk echo "Cannot mount disk. Aborting."
1101 1.14 leo return 0
1102 1.14 leo fi
1103 1.14 leo return 1
1104 1.14 leo }
1105 1.14 leo
1106 1.14 leo install_disk() {
1107 1.14 leo local _directory
1108 1.14 leo
1109 1.14 leo cat << \__install_disk_1
1110 1.14 leo
1111 1.30 mrg Ok, lets install from a disk. The file-system the install sets on may
1112 1.30 mrg already mounted, or we might have to mount the filesystem to get to it.
1113 1.30 mrg
1114 1.30 mrg __install_disk_1
1115 1.30 mrg
1116 1.30 mrg echo -n "Is the file-system with the install sets already mounted? [n] "
1117 1.30 mrg getresp "n"
1118 1.30 mrg case $resp in
1119 1.30 mrg y*|Y*)
1120 1.30 mrg echo "What mount point are the sets located in? [] "
1121 1.30 mrg getresp ""
1122 1.30 mrg if [ -d "$resp" ]; then
1123 1.30 mrg install_from_mounted_fs $resp
1124 1.30 mrg else
1125 1.30 mrg echo "$resp: Not a directory, aborting..."
1126 1.30 mrg fi
1127 1.30 mrg return
1128 1.30 mrg ;;
1129 1.30 mrg *)
1130 1.30 mrg ;;
1131 1.30 mrg esac
1132 1.30 mrg
1133 1.30 mrg cat << \__install_disk_2
1134 1.30 mrg
1135 1.14 leo The following disk devices are installed on your system; please select
1136 1.14 leo the disk device containing the partition with the installation sets:
1137 1.14 leo
1138 1.30 mrg __install_disk_2
1139 1.47 christos _DKDEVS=$(md_get_diskdevs)
1140 1.14 leo echo "$_DKDEVS"
1141 1.14 leo echo ""
1142 1.14 leo echo -n "Which is the disk with the installation sets? [abort] "
1143 1.14 leo
1144 1.14 leo if mount_a_disk ; then
1145 1.5 pk return
1146 1.5 pk fi
1147 1.5 pk
1148 1.20 is install_from_mounted_fs /mnt2
1149 1.1 pk umount -f /mnt2 > /dev/null 2>&1
1150 1.1 pk }
1151 1.1 pk
1152 1.1 pk install_nfs() {
1153 1.1 pk # Get the IP address of the server
1154 1.1 pk resp="" # force one iteration
1155 1.47 christos while [ -z "${resp}" ]; do
1156 1.1 pk echo -n "Server IP address? [${_nfs_server_ip}] "
1157 1.1 pk getresp "${_nfs_server_ip}"
1158 1.1 pk done
1159 1.1 pk _nfs_server_ip=$resp
1160 1.1 pk
1161 1.1 pk # Get server path to mount
1162 1.1 pk resp="" # force one iteration
1163 1.47 christos while [ -z "${resp}" ]; do
1164 1.1 pk echo -n "Filesystem on server to mount? [${_nfs_server_path}] "
1165 1.1 pk getresp "${_nfs_server_path}"
1166 1.1 pk done
1167 1.1 pk _nfs_server_path=$resp
1168 1.1 pk
1169 1.1 pk # Determine use of TCP
1170 1.1 pk echo -n "Use TCP transport (only works with capable NFS server)? [n] "
1171 1.1 pk getresp "n"
1172 1.1 pk case "$resp" in
1173 1.1 pk y*|Y*)
1174 1.1 pk _nfs_tcp="-T"
1175 1.1 pk ;;
1176 1.1 pk
1177 1.1 pk *)
1178 1.40 fredette echo -n "Use small NFS transfers (needed when server "
1179 1.40 fredette echo "or client"
1180 1.40 fredette echo -n "has a slow network card)? [n] "
1181 1.40 fredette getresp "n"
1182 1.40 fredette case "$resp" in
1183 1.40 fredette y*|Y*)
1184 1.40 fredette _nfs_tcp="-r 1024 -w 1024"
1185 1.40 fredette ;;
1186 1.40 fredette
1187 1.40 fredette *)
1188 1.40 fredette _nfs_tcp=""
1189 1.40 fredette ;;
1190 1.40 fredette esac
1191 1.1 pk ;;
1192 1.1 pk esac
1193 1.1 pk
1194 1.1 pk # Mount the server
1195 1.1 pk mkdir /mnt2 > /dev/null 2>&1
1196 1.1 pk if ! mount_nfs $_nfs_tcp ${_nfs_server_ip}:${_nfs_server_path} \
1197 1.1 pk /mnt2 ; then
1198 1.1 pk echo "Cannot mount NFS server. Aborting."
1199 1.1 pk return
1200 1.1 pk fi
1201 1.1 pk
1202 1.20 is install_from_mounted_fs /mnt2
1203 1.1 pk umount -f /mnt2 > /dev/null 2>&1
1204 1.1 pk }
1205 1.1 pk
1206 1.1 pk install_tape() {
1207 1.11 pk local _xcmd
1208 1.11 pk
1209 1.1 pk # Get the name of the tape from the user.
1210 1.1 pk cat << \__install_tape_1
1211 1.1 pk
1212 1.1 pk The installation program needs to know which tape device to use. Make
1213 1.1 pk sure you use a "no rewind on close" device.
1214 1.1 pk
1215 1.1 pk __install_tape_1
1216 1.47 christos _tape=$(basename $TAPE)
1217 1.1 pk resp="" # force one iteration
1218 1.47 christos while [ -z "${resp}" ]; do
1219 1.1 pk echo -n "Name of tape device? [${_tape}]"
1220 1.1 pk getresp "${_tape}"
1221 1.1 pk done
1222 1.47 christos _tape=$(basename $resp)
1223 1.1 pk TAPE="/dev/${_tape}"
1224 1.1 pk if [ ! -c $TAPE ]; then
1225 1.1 pk echo "$TAPE does not exist or is not a character special file."
1226 1.1 pk echo "Aborting."
1227 1.1 pk return
1228 1.1 pk fi
1229 1.1 pk export TAPE
1230 1.1 pk
1231 1.1 pk # Rewind the tape device
1232 1.1 pk echo -n "Rewinding tape..."
1233 1.1 pk if ! mt rewind ; then
1234 1.1 pk echo "$TAPE may not be attached to the system or may not be"
1235 1.1 pk echo "a tape device. Aborting."
1236 1.1 pk return
1237 1.1 pk fi
1238 1.1 pk echo "done."
1239 1.1 pk
1240 1.1 pk # Get the file number
1241 1.1 pk resp="" # force one iteration
1242 1.47 christos while [ -z "${resp}" ]; do
1243 1.1 pk echo -n "File number? "
1244 1.1 pk getresp ""
1245 1.1 pk case "$resp" in
1246 1.1 pk [1-9]*)
1247 1.47 christos _nskip=$(expr $resp - 1)
1248 1.1 pk ;;
1249 1.1 pk
1250 1.1 pk *)
1251 1.1 pk echo "Invalid file number ${resp}."
1252 1.1 pk resp="" # fore loop to repeat
1253 1.1 pk ;;
1254 1.1 pk esac
1255 1.1 pk done
1256 1.1 pk
1257 1.1 pk # Skip to correct file.
1258 1.1 pk echo -n "Skipping to source file..."
1259 1.47 christos if [ "${_nskip}" != "0" ]; then
1260 1.1 pk if ! mt fsf $_nskip ; then
1261 1.1 pk echo "Could not skip $_nskip files. Aborting."
1262 1.1 pk return
1263 1.1 pk fi
1264 1.1 pk fi
1265 1.1 pk echo "done."
1266 1.1 pk
1267 1.1 pk cat << \__install_tape_2
1268 1.1 pk
1269 1.1 pk There are 2 different ways the file can be stored on tape:
1270 1.1 pk
1271 1.1 pk 1) an image of a gzipped tar file
1272 1.1 pk 2) a standard tar image
1273 1.1 pk
1274 1.1 pk __install_tape_2
1275 1.1 pk resp="" # force one iteration
1276 1.47 christos while [ -z "${resp}" ]; do
1277 1.1 pk echo -n "Which way is it? [1] "
1278 1.1 pk getresp "1"
1279 1.1 pk case "$resp" in
1280 1.11 pk 1)
1281 1.33 mrg _xcmd="pax -zr${verbose_flag}pe"
1282 1.11 pk ;;
1283 1.1 pk
1284 1.11 pk 2)
1285 1.33 mrg _xcmd="pax -r${verbose_flag}pe"
1286 1.11 pk ;;
1287 1.1 pk
1288 1.11 pk *)
1289 1.11 pk echo "Invalid response: $resp."
1290 1.11 pk resp="" # force loop to repeat
1291 1.11 pk ;;
1292 1.1 pk esac
1293 1.11 pk ( cd /mnt; dd if=$TAPE | $_xcmd )
1294 1.1 pk done
1295 1.1 pk echo "Extraction complete."
1296 1.1 pk }
1297 1.1 pk
1298 1.1 pk get_timezone() {
1299 1.1 pk local _a
1300 1.6 leo local _zonepath
1301 1.6 leo
1302 1.6 leo #
1303 1.6 leo # If the zoneinfo is not on the installation medium or on the
1304 1.6 leo # installed filesystem, set TZ to GMT and return immediatly.
1305 1.6 leo #
1306 1.47 christos if [ ! -e /usr/share/zoneinfo ] && [ ! -e /mnt/usr/share/zoneinfo ]; then
1307 1.6 leo TZ=GMT
1308 1.6 leo return
1309 1.6 leo fi
1310 1.6 leo if [ ! -d /usr/share/zoneinfo ]; then
1311 1.6 leo _zonepath=/mnt
1312 1.6 leo else
1313 1.6 leo _zonepath=""
1314 1.6 leo fi
1315 1.6 leo
1316 1.1 pk cat << \__get_timezone_1
1317 1.1 pk
1318 1.1 pk Select a time zone for your location. Timezones are represented on the
1319 1.42 nathanw system by a directory structure rooted in "/usr/share/zoneinfo". Most
1320 1.1 pk timezones can be selected by entering a token like "MET" or "GMT-6".
1321 1.1 pk Other zones are grouped by continent, with detailed zone information
1322 1.1 pk separated by a slash ("/"), e.g. "US/Pacific".
1323 1.1 pk
1324 1.1 pk To get a listing of what's available in /usr/share/zoneinfo, enter "?"
1325 1.1 pk at the prompts below.
1326 1.1 pk
1327 1.1 pk __get_timezone_1
1328 1.48 christos if [ -z "$TZ" ]; then
1329 1.47 christos TZ=$(ls -l /mnt/etc/localtime 2>/dev/null | cutlast)
1330 1.3 pk TZ=${TZ#/usr/share/zoneinfo/}
1331 1.1 pk fi
1332 1.1 pk while :; do
1333 1.47 christos echo -n "What timezone are you in ['?' for list] [$TZ]? "
1334 1.1 pk getresp "$TZ"
1335 1.1 pk case "$resp" in
1336 1.1 pk "")
1337 1.1 pk echo "Timezone defaults to GMT"
1338 1.1 pk TZ="GMT"
1339 1.1 pk break;
1340 1.1 pk ;;
1341 1.1 pk "?")
1342 1.6 leo ls ${_zonepath}/usr/share/zoneinfo
1343 1.1 pk ;;
1344 1.1 pk *)
1345 1.1 pk _a=$resp
1346 1.6 leo while [ -d ${_zonepath}/usr/share/zoneinfo/$_a ]; do
1347 1.1 pk echo -n "There are several timezones available"
1348 1.1 pk echo " within zone '$_a'"
1349 1.47 christos echo -n "Select a sub-timezone ['?' for list]: "
1350 1.1 pk getresp ""
1351 1.1 pk case "$resp" in
1352 1.6 leo "?") ls ${_zonepath}/usr/share/zoneinfo/$_a ;;
1353 1.1 pk *) _a=${_a}/${resp}
1354 1.6 leo if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
1355 1.1 pk break;
1356 1.1 pk fi
1357 1.1 pk ;;
1358 1.1 pk esac
1359 1.1 pk done
1360 1.6 leo if [ -f ${_zonepath}/usr/share/zoneinfo/$_a ]; then
1361 1.1 pk TZ="$_a"
1362 1.1 pk echo "You have selected timezone \"$_a\"".
1363 1.1 pk break 2
1364 1.1 pk fi
1365 1.1 pk echo "'/usr/share/zoneinfo/$_a' is not a valid timezone on this system."
1366 1.1 pk ;;
1367 1.1 pk esac
1368 1.1 pk done
1369 1.1 pk }
1370 1.1 pk
1371 1.1 pk install_sets()
1372 1.1 pk {
1373 1.13 pk local _yup
1374 1.13 pk _yup="FALSE"
1375 1.13 pk
1376 1.13 pk # Ask the user which media to load the distribution from.
1377 1.33 mrg # Ask the user if they want verbose extraction. They might not want
1378 1.33 mrg # it on, eg, SPARC frame buffer console.
1379 1.13 pk cat << \__install_sets_1
1380 1.1 pk
1381 1.1 pk It is now time to extract the installation sets onto the hard disk.
1382 1.10 thorpej Make sure the sets are either on a local device (i.e. tape, CD-ROM) or on a
1383 1.1 pk network server.
1384 1.1 pk
1385 1.33 mrg Would you like to see each file listed during extraction (verbose) mode?
1386 1.33 mrg On some console hardware, such as serial consoles and Sun frame buffers,
1387 1.33 mrg this can extend the total extraction time.
1388 1.1 pk __install_sets_1
1389 1.33 mrg echo -n "Use verbose listing for extractions? [y] "
1390 1.33 mrg getresp "y"
1391 1.33 mrg case "$resp" in
1392 1.33 mrg y*|Y*)
1393 1.33 mrg verbose_flag=v
1394 1.33 mrg ;;
1395 1.33 mrg *)
1396 1.37 is echo "Not using verbose listing."
1397 1.33 mrg verbose_flag=""
1398 1.33 mrg ;;
1399 1.33 mrg esac
1400 1.13 pk
1401 1.31 sjg if [ -d ${Default_sets_dir:-/dev/null} ]; then
1402 1.31 sjg if dir_has_sets $Default_sets_dir $THESETS; then
1403 1.31 sjg local_sets_dir=$Default_sets_dir
1404 1.31 sjg fi
1405 1.31 sjg fi
1406 1.47 christos if [ -n "${local_sets_dir}" ]; then
1407 1.13 pk install_from_mounted_fs ${local_sets_dir}
1408 1.48 christos if [ -n "$_setsdone" ]; then
1409 1.13 pk _yup="TRUE"
1410 1.13 pk fi
1411 1.13 pk fi
1412 1.13 pk
1413 1.13 pk # Go on prodding for alternate locations
1414 1.13 pk resp="" # force at least one iteration
1415 1.48 christos while [ -z "${resp}" ]; do
1416 1.13 pk # If _yup is not FALSE, it means that we extracted sets above.
1417 1.13 pk # If that's the case, bypass the menu the first time.
1418 1.48 christos if [ "${_yup}" = "FALSE" ]; then
1419 1.13 pk echo -n "Install from (f)tp, (t)ape, (C)D-ROM, (N)FS"
1420 1.13 pk echo -n " or local (d)isk? "
1421 1.13 pk getresp ""
1422 1.1 pk case "$resp" in
1423 1.13 pk d*|D*)
1424 1.13 pk install_disk
1425 1.13 pk ;;
1426 1.13 pk f*|F*)
1427 1.13 pk install_ftp
1428 1.13 pk ;;
1429 1.13 pk t*|T*)
1430 1.13 pk install_tape
1431 1.13 pk ;;
1432 1.13 pk c*|C*)
1433 1.13 pk install_cdrom
1434 1.13 pk ;;
1435 1.13 pk n*|N*)
1436 1.13 pk install_nfs
1437 1.1 pk ;;
1438 1.1 pk *)
1439 1.13 pk echo "Invalid response: $resp"
1440 1.13 pk resp=""
1441 1.1 pk ;;
1442 1.1 pk esac
1443 1.13 pk else
1444 1.13 pk _yup="FALSE" # So we'll ask next time
1445 1.13 pk fi
1446 1.1 pk
1447 1.13 pk # Give the user the opportunity to extract more sets. They
1448 1.13 pk # don't necessarily have to come from the same media.
1449 1.13 pk echo ""
1450 1.13 pk echo -n "Extract more sets? [n] "
1451 1.13 pk getresp "n"
1452 1.1 pk case "$resp" in
1453 1.13 pk y*|Y*)
1454 1.13 pk # Force loop to repeat
1455 1.13 pk resp=""
1456 1.1 pk ;;
1457 1.1 pk
1458 1.1 pk *)
1459 1.1 pk ;;
1460 1.1 pk esac
1461 1.13 pk done
1462 1.1 pk }
1463 1.1 pk
1464 1.1 pk munge_fstab()
1465 1.1 pk {
1466 1.1 pk local _fstab
1467 1.1 pk local _fstab_shadow
1468 1.5 pk local _dev
1469 1.5 pk local _mp
1470 1.7 leo local _fstype
1471 1.5 pk local _rest
1472 1.6 leo
1473 1.1 pk # Now that the 'real' fstab is configured, we munge it into a 'shadow'
1474 1.1 pk # fstab which we'll use for mounting and unmounting all of the target
1475 1.1 pk # filesystems relative to /mnt. Mount all filesystems.
1476 1.1 pk _fstab=$1
1477 1.1 pk _fstab_shadow=$2
1478 1.7 leo ( while read _dev _mp _fstype _rest; do
1479 1.7 leo # Skip comment lines
1480 1.7 leo case "$_dev" in
1481 1.7 leo \#*) continue;;
1482 1.7 leo *) ;;
1483 1.7 leo esac
1484 1.7 leo # and some filesystem types (like there are swap,kernfs,...)
1485 1.7 leo case "$_fstype" in
1486 1.7 leo ffs|ufs|nfs) ;;
1487 1.7 leo *) continue;;
1488 1.7 leo esac
1489 1.3 pk if [ "$_mp" = "/" ]; then
1490 1.8 pk echo $_dev /mnt $_fstype $_rest
1491 1.1 pk else
1492 1.8 pk echo $_dev /mnt$_mp $_fstype $_rest
1493 1.3 pk fi
1494 1.6 leo done ) < $_fstab > $_fstab_shadow
1495 1.1 pk }
1496 1.1 pk
1497 1.1 pk mount_fs()
1498 1.1 pk {
1499 1.1 pk # Must mount filesystems manually, one at a time, so we can make
1500 1.1 pk # sure the mount points exist.
1501 1.1 pk # $1 is a file in fstab format
1502 1.1 pk local _fstab
1503 1.1 pk
1504 1.1 pk _fstab=$1
1505 1.1 pk
1506 1.1 pk ( while read line; do
1507 1.4 pk set -- $line
1508 1.4 pk _dev=$1
1509 1.4 pk _mp=$2
1510 1.4 pk _fstype=$3
1511 1.4 pk _opt=$4
1512 1.1 pk
1513 1.1 pk # If not the root filesystem, make sure the mount
1514 1.1 pk # point is present.
1515 1.47 christos if [ "$_mp" != "/mnt" ]; then
1516 1.1 pk mkdir -p $_mp
1517 1.1 pk fi
1518 1.1 pk
1519 1.1 pk # Mount the filesystem. If the mount fails, exit
1520 1.1 pk # with an error condition to tell the outer
1521 1.1 pk # later to bail.
1522 1.29 mrg if ! mount -v -t $_fstype -o async -o $_opt $_dev $_mp ; then
1523 1.1 pk # error message displated by mount
1524 1.1 pk exit 1
1525 1.1 pk fi
1526 1.1 pk done ) < $_fstab
1527 1.1 pk
1528 1.47 christos if [ "$?" != "0" ]; then
1529 1.1 pk cat << \__mount_filesystems_1
1530 1.1 pk
1531 1.1 pk FATAL ERROR: Cannot mount filesystems. Double-check your configuration
1532 1.1 pk and restart the installation process.
1533 1.1 pk __mount_filesystems_1
1534 1.1 pk exit
1535 1.1 pk fi
1536 1.1 pk }
1537 1.1 pk
1538 1.1 pk unmount_fs()
1539 1.1 pk {
1540 1.1 pk # Unmount all filesystems and check their integrity.
1541 1.13 pk # Usage: [-fast] <fstab file>
1542 1.13 pk local _fast
1543 1.1 pk local _fstab
1544 1.13 pk local _pid
1545 1.13 pk
1546 1.13 pk if [ "$1" = "-fast" ]; then
1547 1.13 pk _fast=1
1548 1.13 pk _fstab=$2
1549 1.13 pk else
1550 1.13 pk _fast=0
1551 1.13 pk _fstab=$1
1552 1.13 pk fi
1553 1.1 pk
1554 1.51 tsutsui if ! [ -f "${_fstab}" ] || ! [ -s "${_fstab}" ]; then
1555 1.13 pk echo "fstab empty" > /dev/tty
1556 1.13 pk return
1557 1.13 pk fi
1558 1.1 pk
1559 1.13 pk if [ $_fast = 0 ]; then
1560 1.13 pk echo -n "Syncing disks..."
1561 1.47 christos _pid=$(twiddle)
1562 1.13 pk sync; sleep 4; sync; sleep 2; sync; sleep 2
1563 1.13 pk kill $_pid
1564 1.13 pk echo "done."
1565 1.13 pk fi
1566 1.1 pk
1567 1.1 pk (
1568 1.1 pk _devs=""
1569 1.1 pk _mps=""
1570 1.1 pk # maintain reverse order
1571 1.1 pk while read line; do
1572 1.3 pk set -- $line
1573 1.3 pk _devs="$1 ${_devs}"
1574 1.3 pk _mps="$2 ${_mps}"
1575 1.1 pk done
1576 1.1 pk echo -n "Umounting filesystems... "
1577 1.1 pk for _mp in ${_mps}; do
1578 1.1 pk echo -n "${_mp} "
1579 1.1 pk umount ${_mp}
1580 1.1 pk done
1581 1.1 pk echo "Done."
1582 1.1 pk
1583 1.13 pk if [ $_fast = 0 ]; then
1584 1.13 pk exit
1585 1.13 pk fi
1586 1.1 pk echo "Checking filesystem integrity..."
1587 1.1 pk for _dev in ${_devs}; do
1588 1.1 pk echo "${_dev}"
1589 1.1 pk fsck -f ${_dev}
1590 1.1 pk done
1591 1.1 pk echo "Done."
1592 1.1 pk ) < $_fstab
1593 1.1 pk }
1594 1.1 pk
1595 1.1 pk check_fs()
1596 1.1 pk {
1597 1.1 pk # Check filesystem integrity.
1598 1.1 pk # $1 is a file in fstab format
1599 1.1 pk local _fstab
1600 1.1 pk
1601 1.1 pk _fstab=$1
1602 1.1 pk
1603 1.1 pk (
1604 1.1 pk _devs=""
1605 1.1 pk _mps=""
1606 1.1 pk while read line; do
1607 1.3 pk set -- $line
1608 1.3 pk _devs="$1 ${_devs}"
1609 1.3 pk _mps="$2 ${_mps}"
1610 1.1 pk done
1611 1.1 pk
1612 1.1 pk echo "Checking filesystem integrity..."
1613 1.1 pk for _dev in ${_devs}; do
1614 1.1 pk echo "${_dev}"
1615 1.1 pk fsck -f ${_dev}
1616 1.1 pk done
1617 1.1 pk echo "Done."
1618 1.1 pk ) < $_fstab
1619 1.1 pk }
1620 1.48 christos
1621 1.48 christos mi_mount_kernfs() {
1622 1.48 christos # Make sure kernfs is mounted.
1623 1.48 christos if [ ! -d /kern ] || [ ! -e /kern/msgbuf ]; then
1624 1.48 christos mkdir /kern > /dev/null 2>&1
1625 1.48 christos /sbin/mount_kernfs /kern /kern
1626 1.48 christos fi
1627 1.48 christos }
1628 1.48 christos
1629 1.48 christos mi_filter_msgbuf() {
1630 1.48 christos # Remove timestemps, sort.
1631 1.48 christos sed -e 's/^\[[0-9. ]*\] //' < /kern/msgbuf | sort -u
1632 1.48 christos }
1633 1.48 christos
1634 1.48 christos mi_filter_dmesg() {
1635 1.48 christos # Remove timestemps, sort.
1636 1.55 tsutsui dmesg | awk '{ h=$0; gsub("^[[0-9. ]*] ", "", h); print h; }' \
1637 1.48 christos | sort -u
1638 1.48 christos }
1639