]> git.ozlabs.org Git - yaboot.git/blob - ybin/ybin
ofpath: Handle disk devices with no sd node
[yaboot.git] / ybin / ybin
1 #! /bin/sh
2
3 ###############################################################################
4 ##
5 ## ybin (YaBoot INstaller) installs/updates the yaboot bootloader.
6 ## Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson
7 ##
8 ## This program is free software; you can redistribute it and/or
9 ## modify it under the terms of the GNU General Public License
10 ## as published by the Free Software Foundation; either version 2
11 ## of the License, or (at your option) any later version.
12 ##
13 ## This program is distributed in the hope that it will be useful,
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ## GNU General Public License for more details.
17 ##
18 ## You should have received a copy of the GNU General Public License
19 ## along with this program; if not, write to the Free Software
20 ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 ##
22 ###############################################################################
23
24 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
25 ## allow to run out of /target in boot-floppies
26 if [ -n "$PATH_PREFIX" ] ; then
27     PATH="${PATH}:${PATH_PREFIX}/sbin:${PATH_PREFIX}/bin:${PATH_PREFIX}/usr/sbin:${PATH_PREFIX}/usr/bin:${PATH_PREFIX}/usr/local/sbin:${PATH_PREFIX}/usr/local/bin"
28 fi
29 PRG="${0##*/}"
30 ABSPRG="$0"
31 SIGINT="$PRG: Interrupt caught ... exiting"
32 VERSION=1.3.17
33 DEBUG=0
34 VERBOSE=0
35 TMP="${TMPDIR:-/tmp}"
36 export LC_COLLATE=C
37
38 ## avoid older versions of ofpath shipped in debian boot-floppies etc.
39 if [ -x "${PATH_PREFIX}/usr/sbin/ofpath" ] ; then
40     OFPATH="${PATH_PREFIX}/usr/sbin/ofpath"
41 else
42     OFPATH=ofpath
43 fi
44
45 ## catch signals, clean up junk in /tmp.
46 trap "cleanup" 0
47 trap "exit 129" 1
48 trap "echo 1>&2 $SIGINT ; exit 130" 2
49 trap "exit 131" 3
50 trap "exit 143" 15
51
52 ## allow for non-existent config file, in which case it will be
53 ## generated from command line arguments.
54 if [ -f /etc/yaboot.conf ] ; then
55     CONF=/etc/yaboot.conf
56     bootconf=$CONF
57     ERR=" Error in $CONF:"
58 else
59     CONF=/dev/null
60     bootconf=/dev/null
61 fi
62
63 ## define default configuration
64 boot=unconfigured
65
66 ## allow default to work on packaged and non-packaged yaboot.
67 ## no default for magicboot since it is not required everywhere.
68 if [ -f /usr/local/lib/yaboot/yaboot ] ; then
69     install=/usr/local/lib/yaboot/yaboot
70 elif [ -f /usr/lib/yaboot/yaboot ] ; then
71     install=/usr/lib/yaboot/yaboot
72 fi
73
74 ## defaults
75 usemount=no
76 if (cat /proc/cpuinfo 2> /dev/null | grep ^platform | grep -q 'pSeries') ; then
77     fstype=raw
78 elif (cat /proc/cpuinfo 2> /dev/null | grep ^platform | grep -q 'PowerNV') ; then
79     fstype=raw
80 else
81     fstype=hfs
82 fi
83 hfstype=tbxi
84 hfscreator=UNIX
85 bless=yes
86 protect=no
87 hide=no
88 nonvram=0
89 defaultos=linux
90 brokenosx=no
91 cdrom=no
92 network=no
93 of=no
94 fgcolor=white
95 bgcolor=black
96
97 ## yaboot autoconf defaults
98 label=Linux
99 timeout=40
100 image=/vmlinux
101 partition=3
102 root=/dev/hda3
103 device=hd:
104
105 ## this program behaves differently based on how its called, this
106 ## ensures that nothing nasty happens if someone makes a bogus
107 ## symlink.
108 case "$PRG" in
109     ybin)
110     ;;
111     mkofboot)
112     ;;
113     *)
114     echo 1>&2 "This program must be called as either \`ybin' or \`mkofboot'"
115     exit 1
116     ;;
117 esac
118
119 ## check for printf, use it if possible otherwise fall back on
120 ## unreliable echo -e -n ("SUS" says echo shall support no switches)
121 if [ "$(printf printf_test 2>/dev/null)" = printf_test ] ; then
122     PRINTF=printf
123 else
124     PRINTF="echo -e -n"
125 fi
126
127 ## make fake `id' if its missing, outputs 0 since if its missing we
128 ## are probably running on boot floppies and thus are root.
129 if (command -v id > /dev/null 2>&1) ; then
130     true
131 else
132     id()
133     {
134     echo 0
135     }
136 fi
137
138 ## --version output
139 version()
140 {
141 echo \
142 "$PRG $VERSION
143 Written by Ethan Benson
144
145 Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson
146 This is free software; see the source for copying conditions.  There is NO
147 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
148 }
149
150 ## --help output.
151 usage()
152 {
153 echo \
154 "Usage: $PRG [OPTION]...
155 Update/install bootloader onto a bootstrap partition.
156
157   -b, --boot                 set bootstrap partition device [ -b /dev/hda2 ]
158   -o, --ofboot               set bootstrap partition OpenFirmware device
159                                default: automatically determined [ -o hd:2 ]
160        --bootonce            override default boot label for ONLY next boot
161                                 eg: --bootonce linux-2.6.20-testing
162   -i, --install              pathname to the actual bootloader binary
163                                default: /usr/{local/}lib/yaboot/yaboot same as
164                                install= in config file [ -i bootloader_file ]
165   -C, --config               use alternate configuration file (ybin and yaboot)
166                                [ -C config_file ]
167   -m, --magicboot            pathname to a OpenFirmware magicboot (CHRP) script
168       --filesystem           set the filesystem type of the bootstrap partition
169                                available options are hfs, msdos, and raw
170                                [ --filesystem hfs ] default is hfs
171       --nobless              don't bless the root directory, this should only
172                                be used if you are using a MacOS boot partition
173                                as the bootstrap partition (not recommended)
174   -M, --mount                don't use userspace hfsutils to modify the
175                                bootstrap instead try and mount the filesystem
176                                directly.  Note that attributes cannot be set
177                                this way and you will have to manually modify
178                                OpenFirmware to make your system bootable
179       --protect              set the read-only (locked) bit on all bootstrap
180                                files
181       --hide                 set the invisible bit on all bootstrap files
182                                this is useful of you don't want them to be
183                                visible from MacOS.
184       --nonvram              do not update the boot-device variable in nvram.
185       --force                don't ever ask for confirmation
186   -v, --verbose              make $PRG more verbose
187       --debug                print boring junk only useful for debugging
188   -h, --help                 display this help and exit
189   -V, --version              output version information and exit"
190 }
191
192 ## configuration file parsing. FIXME: need a method which can parse
193 ## image= sections.
194 parseconf()
195 {
196 case "$1" in
197     str)
198        v=`grep "^$2[\ ,=]" "$CONF"` ; echo "${v#*=}"
199        ;;
200     flag)
201        grep "^$2\>" "$CONF" > /dev/null && echo 0 || echo 1
202        ;;
203     ck)
204        grep "^$2[\ ,=]" "$CONF" > /dev/null && echo 0 || echo 1
205        ;;
206 esac
207 }
208
209 ## check for existence of a configuration file, and make sure we have
210 ## read permission.
211 confexist()
212 {
213     if [ ! -e "$CONF" ] ; then
214         echo 1>&2 "$PRG: $CONF: No such file or directory"
215         return 1
216     elif [ ! -f "$CONF" ] ; then
217         echo 1>&2 "$PRG: $CONF: Not a regular file"
218         return 1
219     elif [ ! -r "$CONF" ] ; then
220         echo 1>&2 "$PRG: $CONF: Permission denied"
221         return 1
222     else
223         return 0
224     fi
225 }
226
227 ## check to make sure the configuration file is sane and correct.
228 ## maybe this is an insane ammount of error checking, but I want to
229 ## make sure (hopfully) nothing unexpected ever happens.  and i just
230 ## like useful errors from programs.  every error just marks an error
231 ## variable so we give the user as much info as possible before we
232 ## abandon ship.
233 checkconf()
234 {
235     if [ ! -e "$boot" ] ; then
236         echo 1>&2 "$PRG: $boot: No such file or directory"
237         local CONFERR=1
238     elif [ ! -b "$boot" -a ! -f "$boot" ] ; then
239         echo 1>&2 "$PRG: $boot: Not a regular file or block device"
240         local CONFERR=1
241     elif [ ! -w "$boot" -o ! -r "$boot" ] ; then
242         [ -z "$mntpoint" ] && echo 1>&2 "$PRG: $boot: Permission denied"
243         [ -z "$mntpoint" ] && CONFERR=1
244     fi
245
246     if [ ! -e "$install" ] ; then
247         echo 1>&2 "$PRG: $install: No such file or directory"
248         local CONFERR=1
249     elif [ ! -f "$install" ] ; then
250         echo 1>&2 "$PRG: $bootconf: Not a regular file"
251         local CONFERR=1
252     elif [ ! -r "$install" ] ; then
253         echo 1>&2 "$PRG: $install: Permission denied"
254         local CONFERR=1
255     fi
256
257     if [ "$bootconf" = auto ] ; then
258         true
259     elif [ ! -e "$bootconf" ] ; then
260         echo 1>&2 "$PRG: $bootconf: No such file or directory"
261         local CONFERR=1
262     elif [ ! -f "$bootconf" ] ; then
263         echo 1>&2 "$PRG: $bootconf: Not a regular file"
264         local CONFERR=1
265     elif [ ! -r "$bootconf" ] ; then
266         echo 1>&2 "$PRG: $bootconf: Permission denied"
267         local CONFERR=1
268     fi
269
270     if [ -n "$magicboot" ] ; then
271         if [ ! -e "$magicboot" ] ; then
272             echo 1>&2 "$PRG: $magicboot: No such file or directory"
273             local CONFERR=1
274         elif [ ! -f "$magicboot" ] ; then
275             echo 1>&2 "$PRG: $magicboot: Not a regular file"
276             local CONFERR=1
277         elif [ ! -r "$magicboot" ] ; then
278             echo 1>&2 "$PRG: $magicboot: Permission denied"
279             local CONFERR=1
280         fi
281     fi
282
283     case "$fstype" in
284         hfs|msdos|raw)
285          ;;
286         *)
287          if [ "$ARGFS" = 1 ] ; then
288             echo 1>&2 "$PRG: --filesystem must be either \`hfs', \`msdos', or \`raw'"
289          else
290             echo 1>&2 "$PRG:$ERR \`fstype' must be either \`hfs', \`msdos', or \`raw'"
291          fi
292          local CONFERR=1
293          ;;
294     esac
295
296     ## if we are not using HFS filesystems we don't care about HFS
297     ## specific options.
298     if [ "$fstype" = hfs ] ; then
299         if [ `echo ${#hfstype}` != 4 ] ; then
300             if [ "$ARGTP" = 1 ] ; then
301                 echo 1>&2 "$PRG: --type must be 4 characters"
302             else
303                 echo 1>&2 "$PRG:$ERR \`hfstype' must be 4 characters"
304             fi
305             local CONFERR=1
306         fi
307
308         if [ `echo ${#hfscreator}` != 4 ] ; then
309             if [ "$ARGCT" = 1 ] ; then
310                 echo 1>&2 "$PRG: --creator must be 4 characters"
311             else
312                 echo 1>&2 "$PRG:$ERR \`hfscreator' must be 4 characters"
313             fi
314             local CONFERR=1
315         fi
316     fi
317
318     ## some options are not compatible with fstype=raw
319     if [ "$fstype" = raw ] ; then
320         if [ -n "$mntpoint" ] ; then
321             echo 1>&2 "$PRG:$ERR \`mntpoint' is not compatible with fstype=raw"
322             local CONFERR=1
323         fi
324         if [ "$usemount" = yes ] ; then
325             echo 1>&2 "$PRG:$ERR \`usemount' is not compatible with fstype=raw"
326             local CONFERR=1
327         fi
328         if [ -n "$magicboot" ] ; then
329             echo 1>&2 "$PRG:$ERR \`magicboot' scripts cannot be used with fstype=raw"
330             local CONFERR=1
331         fi
332     fi
333
334     if [ -n "$mntpoint" ] ; then
335         ## standard checks
336         if [ ! -e "$mntpoint" ] ; then
337             echo 1>&2 "$PRG: $mntpoint: No such file or directory"
338             local CONFERR=1
339         elif [ ! -d "$mntpoint" ] ; then
340             echo 1>&2 "$PRG: $mntpoint: Not a directory"
341             local CONFERR=1
342         elif [ ! -w "$mntpoint" -o ! -r "$mntpoint" ] ; then
343             echo 1>&2 "$PRG: $mntpoint: Permission denied"
344             local CONFERR=1
345         elif [ ! -O "$mntpoint" -a `id -u` != 0 ] ; then
346             echo 1>&2 "$PRG: $mntpoint: Permission denied (not owner)"
347             local CONFERR=1
348         fi
349
350         ## make sure no embedded spaces exist
351         echo "$mntpoint" | grep -q [[:space:]]
352         if [ $? = 0 ] ; then
353             echo 1>&2 "$PRG:$ERR \`mntpoint=$mntpoint' contains embedded spaces, don't use lame filenames"
354             local CONFERR=1
355         fi
356
357         ## make sure $mntpoint is on $boot, this matters to nvram updating.
358         if [ "$(v=`df "$mntpoint" 2> /dev/null | grep ^/dev/` ; echo ${v%%[ ]*})" != "$boot" -a -d "$mntpoint" ] ; then
359             echo 1>&2 "$PRG: $mntpoint is not located on $boot"
360             local CONFERR=1
361             ## more then one subdirectory deep is not supported. no sed available on boot floppies ( / -> \ )
362         elif [ "$mntpoint" != "$(v=`df "$mntpoint" 2> /dev/null | grep ^/dev/` ; echo ${v##*[ ]})" ] ; then
363             echo "$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")" | grep -q /
364             if [ $? = 0 ] ; then
365                 echo 1>&2 "$PRG:$ERR $mntpoint is more then one subdirectory deep from root of $boot"
366                 local CONFERR=1
367             else
368                 OFDIR="$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")"
369             fi
370         fi
371
372         if [ "$usemount" = no ] ; then
373             echo 1>&2 "$PRG:$ERR \`mntpoint=' requires \`usemount' be set"
374             local CONFERR=1
375         fi
376     fi
377
378     if [ -n "$magicboot" ] ; then
379         ## check for bsd loader
380         if [ -n "$bsd" ] ; then
381             if [ -f /usr/lib/yaboot/ofwboot -a -r /usr/lib/yaboot/ofwboot ] ; then
382                 BSDLOADER="/usr/lib/yaboot/ofwboot"
383             elif [ -f /usr/local/lib/yaboot/ofwboot -a -r /usr/local/lib/yaboot/ofwboot ] ; then
384                 BSDLOADER="/usr/local/lib/yaboot/ofwboot"
385             else
386                 echo 1>&2 "$PRG: /usr/local/lib/yaboot/ofwboot: No such file or directory"
387                 echo 1>&2 "$PRG: With the bsd= option set you must have the bsd boot loader ofwboot"
388                 CONFERR=1
389             fi
390         fi
391
392         ## convert defaultos variable
393         case "$defaultos" in
394             linux|Linux|GNU|Gnu|gnu)
395                 defaultos=bootyaboot
396                 ;;
397             bootyaboot)
398                 ;;
399             bsd)
400                 defaultos=bootbsd
401                 if [ -z "$bsd" ] ; then
402                     echo 1>&2 "$PRG:$ERR no entry for \`bsd' found, but defaultos is set to \`bsd'"
403                     local CONFERR=1
404                 fi
405                 ;;
406             macos)
407                 defaultos=bootmacos
408                 if [ -z "$macos" ] ; then
409                     echo 1>&2 "$PRG:$ERR no entry for \`macos' found, but defaultos is set to \`macos'"
410                     local CONFERR=1
411                 fi
412                 ;;
413             macosx)
414                 defaultos=bootmacosx
415                 if [ -z "$macosx" ] ; then
416                     echo 1>&2 "$PRG:$ERR no entry for \`macosx' found, but defaultos is set to \`macosx'"
417                     local CONFERR=1
418                 fi
419                 ;;
420             darwin)
421                 defaultos=bootdarwin
422                 if [ -z "$darwin" ] ; then
423                     echo 1>&2 "$PRG:$ERR no entry for \`darwin' found, but defaultos is set to \`darwin'"
424                     local CONFERR=1
425                 fi
426                 ;;
427             *)
428                 echo 1>&2 "$PRG:$ERR \`defaultos' must be either \`linux', \`bsd', \`macos' or \`macosx'"
429                 local CONFERR=1
430                 ;;
431         esac
432     fi
433
434     ## nvsetenv requires /proc
435     if [ ! -f /proc/uptime -a "$nonvram" = 0 ] ; then
436         echo 1>&2 "$PRG: /proc filesystem is not mounted, nvram will not be updated"
437         nonvram=1
438     fi
439
440     if [ "$nonvram" = 0 ] ; then
441         ## see if nvsetenv exists and is executable
442         if (command -v nvsetenv > /dev/null 2>&1) ; then
443             [ -x `command -v nvsetenv` ] || MISSING=1 ; else MISSING=1
444         fi
445
446         if [ "$nonvram" = 0 ] ; then
447             ## if nvsetenv exists see if its the old broken version
448             if [ "$MISSING" != 1 ] ; then
449                 nvsetenv --version > /dev/null 2>&1 || OLD=1
450             else
451                 nonvram=1
452                 echo 1>&2 "$PRG: Warning: \`nvsetenv' could not be found, nvram will not be updated"
453             fi
454
455             if [ "$OLD" = 1 ] ; then
456                 ## i check this myself to avoid misleading error
457                 ## messages. nvsetenv should REALLY support --version.
458                 if [ ! -e /dev/nvram ] ; then
459                     echo 1>&2 "$PRG: /dev/nvram: No such file or directory"
460                     echo 1>&2 "$PRG: Warning: nvram will not be updated"
461                     nonvram=1
462                 elif [ ! -c /dev/nvram ] ; then
463                     echo 1>&2 "$PRG: /dev/nvram: Not a character device"
464                     echo 1>&2 "$PRG: Warning: nvram will not be updated"
465                     nonvram=1
466                 elif [ ! -w /dev/nvram -o ! -r /dev/nvram ] ; then
467                     echo 1>&2 "$PRG: /dev/nvram: Permission denied"
468                     echo 1>&2 "$PRG: Warning: nvram will not be updated"
469                     nonvram=1
470                 elif ! (dd if=/dev/nvram of=/dev/null bs=1 count=10 > /dev/null 2>&1) ; then
471                     echo 1>&2 "$PRG: /dev/nvram: No such device"
472                     echo 1>&2 "$PRG: Warning: nvram will not be updated"
473                     nonvram=1
474                 else
475                     nonvram=1
476                     echo 1>&2 "$PRG: Warning: Incompatible version of \`nvsetenv', nvram will not be updated"
477                 fi
478             fi
479         fi
480
481         if [ -f "$boot" ] ; then
482             echo 1>&2 "$PRG: $boot is a regular file, disabling nvram updating"
483             nonvram=1
484         fi
485     fi
486
487     ## check for newworld mac. use cat hack due to /proc wierdness.
488     ## do not bail if we are on an OldWorld only warn (very loudly).
489     if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:})" = NewWorld ] ; then
490         true
491     elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:})" = OldWorld ] ; then
492         echo 1>&2
493         echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
494         echo 1>&2 "$PRG: Warning: This is an OldWorld PowerMac, $boot will **NOT** be bootable on this machine"
495         echo 1>&2 "$PRG: Oldworld PowerMacs need to use the quik bootloader, not yaboot"
496         echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
497         echo 1>&2
498         [ "$nonvram" = 0 ] && echo 1>&2 "$PRG: OldWorld PowerMac, nvram will not be updated"
499         nonvram=1
500     elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
501         echo 1>&2
502         echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
503         echo 1>&2 "$PRG: Warning: This is an OldWorld PowerMac, $boot will **NOT** be bootable on this machine"
504         echo 1>&2 "$PRG: Oldworld PowerMacs need to use the quik bootloader, not yaboot"
505         echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
506         echo 1>&2
507         [ "$nonvram" = 0 ] && echo 1>&2 "$PRG: OldWorld PowerMac, nvram will not be updated"
508         nonvram=1
509     elif (cat /proc/cpuinfo 2> /dev/null | grep ^platform | grep -q 'pSeries') ; then
510         ## IBM hardware does not need nvram update AFAICT
511         nonvram=1
512         ADDNOTE=yes
513     elif (cat /proc/cpuinfo 2> /dev/null | grep ^platform | grep -q 'PowerNV') ; then
514         ## IBM hardware does not need nvram update AFAICT
515         nonvram=1
516         ADDNOTE=yes
517     else
518         #echo 1>&2 "$PRG: Warning: Unknown archetecture, $boot may not be bootable on this machine"
519         [ "$nonvram" = 0 ] && echo 1>&2 "$PRG: Warning: Unknown architecture, nvram will not be updated"
520         nonvram=1
521     fi
522
523     ## convert human readable color values from config to proper color
524     ## codes
525     case "$fgcolor" in
526         black) fgc=0 ;; blue) fgc=1 ;; green) fgc=2 ;; cyan) fgc=3 ;;
527         red) fgc=4 ;; purple) fgc=5 ;; brown) fgc=6 ;; light-gray) fgc=7 ;;
528         dark-gray) fgc=8 ;; light-blue) fgc=9 ;; light-green) fgc=a ;;
529         light-cyan) fgc=b ;; light-red) fgc=c ;; light-purple) fgc=d ;;
530         yellow) fgc=e ;; white) fgc=f ;;
531         *)
532         echo 1>&2 "$PRG:$ERR Invalid fgcolor: \`$fgcolor'"
533         local CONFERR=1
534         ;;
535     esac
536     case "$bgcolor" in
537         black) bgc=0 ;; blue) bgc=1 ;; green) bgc=2 ;; cyan) bgc=3 ;;
538         red) bgc=4 ;; purple) bgc=5 ;; brown) bgc=6 ;; light-gray) bgc=7 ;;
539         dark-gray) bgc=8 ;; light-blue) bgc=9 ;; light-green) bgc=a ;;
540         light-cyan) bgc=b ;; light-red) bgc=c ;; light-purple) bgc=d ;;
541         yellow) bgc=e ;; white) bgc=f ;;
542         *)
543         echo 1>&2 "$PRG:$ERR Invalid bgcolor: \`$bgcolor'"
544         local CONFERR=1
545         ;;
546     esac
547
548     ## if delay is not set use yaboot's timeout
549     if [ -z "$delay" ] ; then
550         delay="$(($timeout / 10))"
551     fi
552
553     if [ "$CONFERR" = 1 ] ; then
554         return 1
555     else
556         return 0
557     fi
558 }
559
560
561 ## if readlink is missing use a kludge
562 if (command -v readlink > /dev/null 2>&1) ; then
563     true
564 else
565     readlink()
566     {
567         local SYMTARGET="$(v=`ls -l "$2" 2>/dev/null` ; echo ${v##*> })"
568         if [ -n "$SYMTARGET" ] ; then
569             echo "$SYMTARGET"
570             return 0
571         else
572             return 1
573         fi
574     }
575 fi
576
577 ## /etc/yaboot.conf with password should not be world readable.
578 permcheck()
579 {
580 if [ -L "$bootconf" ] ; then
581     local realfile="$(readlink -f "$bootconf")" || return 0
582 else
583     local realfile="$bootconf"
584 fi
585
586 ## don't bother if we could not read the symlink
587 [ -z "$realfile" ] && return 0
588 [ ! -f "$realfile" ] && return 0
589
590 ## get permissions, and don't bother checking if we can't
591 local PERM=`v=$(ls -l "$realfile" 2>/dev/null) ; echo ${v%% *}`
592 [ -z "$PERM" ] && return 0
593 [ `echo ${#PERM}` != 10 ] && return 0
594
595 case "$PERM" in
596     -rw-------|-r--------)
597       if [ ! -O "$realfile" -a `id -u` = 0 ] ; then
598          echo 1>&2 "$PRG: Warning: $bootconf is not owned by root"
599       fi
600       ;;
601     -rw-r-----|-r--r-----)
602       if [ ! -O "$realfile" -a `id -u` = 0 ] ; then
603          echo 1>&2 "$PRG: Warning: $bootconf is not owned by root"
604       fi
605       if [ ! -G "$realfile" -a `id -g` = 0 ] ; then
606          echo 1>&2 "$PRG: Warning: $bootconf is not owned by group root"
607       fi
608       ;;
609     -r--r--r--|-rw-r--r--|-rw-rw-r--|-rw-rw-rw-|-rw-rw----)
610       echo 1>&2 "$PRG: Warning: Insecure permissions on $bootconf: $PERM should be -rw-------"
611       ;;
612     *)
613       echo 1>&2 "$PRG: Warning: Incorrect permissions on $bootconf: $PERM should be -rw-------"
614       ;;
615 esac
616 }
617
618 convertpath()
619 {
620     ## figure out bootstrap device OF pathname if user did not supply it.
621     if [ -z "$ofboot" ] ; then
622         [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$boot'..."
623         ofboot="$($OFPATH $boot)"
624         if [ $? != 0 ] ; then
625             echo 1>&2 "$PRG: Unable to find OpenFirmware path for boot=$boot"
626             echo 1>&2 "$PRG: Please add ofboot=<path> where <path> is the OpenFirmware path to $boot to $CONF"
627             local CONVERR=1
628         fi
629         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: ofboot set to \`$ofboot'"
630     fi
631
632     ## figure out OF device path for macos/macosx if user supplied a unix device node.
633     if [ -n "$bsd" ] ; then
634         case "$bsd" in
635             /dev/*)
636                 [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$bsd'..."
637                 local sbsd="$bsd"
638                 bsd="$($OFPATH $bsd)"
639                 if [ $? != 0 ] ; then
640                     echo 1>&2 "$PRG: Unable to determine OpenFirmware path for bsd=$sbsd"
641                     echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for bsd=$sbsd in $CONF"
642                     local CONVERR=1
643                 fi
644                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: bsd set to \`$bsd' from \`$sbsd'"
645                 ;;
646             *)
647                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: bsd left alone: \`$bsd'"
648                 ;;
649         esac
650     fi
651
652     if [ -n "$macos" ] ; then
653         case "$macos" in
654             /dev/*)
655                 [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$macos'..."
656                 local smacos="$macos"
657                 macos="$($OFPATH $macos)"
658                 if [ $? != 0 ] ; then
659                     echo 1>&2 "$PRG: Unable to determine OpenFirmware path for macos=$smacos"
660                     echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for macos=$smacos in $CONF"
661                     local CONVERR=1
662                 fi
663                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macos set to \`$macos' from \`$smacos'"
664                 ;;
665             *)
666                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macos left alone: \`$macos'"
667                 ;;
668         esac
669     fi
670
671     if [ -n "$macosx" ] ; then
672         case "$macosx" in
673             /dev/*)
674                 [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$macosx'..."
675                 local smacosx="$macosx"
676                 macosx="$($OFPATH $macosx)"
677                 if [ $? != 0 ] ; then
678                     echo 1>&2 "$PRG: Unable to determine OpenFirmware path for macosx=$smacosx"
679                     echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for macosx=$smacosx in $CONF"
680                     local CONVERR=1
681                 fi
682                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macosx set to \`$macosx' from \`$smacosx'"
683                 ;;
684             *)
685                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macosx left alone: \`$macosx'"
686                 ;;
687         esac
688     fi
689
690     if [ -n "$darwin" ] ; then
691         case "$darwin" in
692             /dev/*)
693                 [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$darwin'..."
694                 local sdarwin="$darwin"
695                 darwin="$($OFPATH $darwin)"
696                 if [ $? != 0 ] ; then
697                     echo 1>&2 "$PRG: Unable to determine OpenFirmware path for darwin=$sdarwin"
698                     echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for darwin=$sdarwin in $CONF"
699                     local CONVERR=1
700                 fi
701                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: darwin set to \`$darwin' from \`$sdarwin'"
702                 ;;
703             *)
704                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: darwin left alone: \`$darwin'"
705                 ;;
706         esac
707     fi
708
709     if [ "$CONVERR" = 1 ] ; then
710         return 1
711     else
712         return 0
713     fi
714 }
715
716 ## make sure the hfsutils we need are installed and executable.
717 checkhfsutils()
718 {
719     if (command -v hmount > /dev/null 2>&1) ; then
720         [ -x `command -v hmount` ] || FAIL=1 ; else FAIL=1 ; fi
721     if (command -v humount > /dev/null 2>&1) ; then
722         [ -x `command -v humount` ] || FAIL=1 ; else FAIL=1 ; fi
723     if (command -v hcopy > /dev/null 2>&1) ; then
724         [ -x `command -v hcopy` ] || FAIL=1 ; else FAIL=1 ; fi
725     if (command -v hattrib > /dev/null 2>&1) ; then
726         [ -x `command -v hattrib` ] || FAIL=1 ; else FAIL=1 ; fi
727     if (command -v hformat > /dev/null 2>&1) ; then
728         [ -x `command -v hformat` ] || FAIL=1 ; else FAIL=1 ; fi
729
730     if [ "$FAIL" = 1 ] ; then
731         return 1
732     else
733         return 0
734     fi
735 }
736
737 ## This is gross, IBM CHRP OF needs a .note added to the yaboot
738 ## binary, nobody knows whether this note will affect PowerMac OF or
739 ## not (or could in the future).
740 hack_yaboot()
741 {
742     local YBDIR="${install%/*}"
743     if [ -x "$YBDIR/addnote" ] ; then
744         TMPYABOOT=`mktemp -q "$TMP/yaboot.XXXXXX"`
745         if [ $? != 0 ] ; then
746             echo 1>&2 "$PRG: Could not create temporary file, aborting."
747             return 1
748         else
749             if (cat "$install" > "$TMPYABOOT" 2> /dev/null) ; then
750                 install="$TMPYABOOT"
751             else
752                 echo 1>&2 "$PRG: Could not create temporary file, aborting."
753                 return 1
754             fi
755         fi
756         [ "$DEBUG" = 1 ] && echo "$PRG: Embedding CHRP note section in temp yaboot..."
757         "$YBDIR/addnote" "$install" > /dev/null 2>&1
758         if [ $? != 0 ] ; then
759             echo 1>&2 "$PRG: Could not install note section required by your architecture"
760             return 1
761         fi
762     else
763         echo 1>&2 "$PRG: Your architecture requires $YBDIR/addnote which cannot be found"
764         return 1
765     fi
766     return 0
767 }
768
769 ## install using userspace utilities rather then kernel filesytem
770 ## support.  hfsutils only, mtools not supported.
771 util_install()
772 {
773     ## catch signals, and humount, cleanup done by trap 0.
774     trap "humount $boot ; exit 129" 1
775     trap "echo 1>&2 $SIGINT ; humount $boot ; exit 130" 2
776     trap "humount $boot ; exit 131" 3
777     trap "humount $boot ; exit 143" 15
778
779     ## filenames on bootstrap partition. ofboot hard codes yaboot.
780     local BTFILE=yaboot
781     local CFFILE=yaboot.conf
782
783     ## if there is a magicboot script to install we will give it the
784     ## hfstype (should be "tbxi") and give yaboot type "boot".
785     if [ -n "$magicboot" ] ; then
786         local BTTYPE=boot
787     else
788         local BTTYPE="$hfstype"
789     fi
790
791     if [ -n "$magicboot" ] ; then
792         local WRAP="${magicboot##*/}"
793     fi
794
795     ## set verbose messages here so they don't show temporary file paths
796     local INSTALLFIRST="$PRG: Installing first stage bootstrap $magicboot onto $boot..."
797     local INSTALLPRIMARY="$PRG: Installing primary bootstrap $install onto $boot..."
798
799     ## repoint magicboot as the real first stage loader if using the
800     ## modern automatic generating ofboot.b.
801     if [ -n "$FIRST" ] ; then
802         magicboot="$FIRST"
803         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: set magicboot to $FIRST"
804     fi
805
806     ## gross hack, add note section for IBM CHRP
807     if [ "$ADDNOTE" = yes ] ; then
808         hack_yaboot || return 1
809     fi
810
811     if [ "$fstype" = hfs ] ; then
812         if [ "$protect" = yes ] ; then
813             local LOCK="+l"
814         fi
815
816         if [ "$hide" = yes ] ; then
817             local INVISIBLE="+i"
818         fi
819
820         ## make sure the device is not mounted as a filesystem before
821         ## we start mucking with it directly.
822         mount | grep "^$boot\>" > /dev/null
823         if [ $? = 0 ] ; then
824             echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
825             return 1
826         fi
827
828         ## hmount is really more of a way to make sure we have a valid HFS
829         ## filesystem before proceding, and hcopy requires it...
830         hmount "$boot" > /dev/null
831         if [ $? != 0 ] ; then
832             echo 1>&2 "$PRG: $boot appears to have never had a bootstrap installed, please run mkofboot"
833             return 1
834         fi
835
836         ## must be explicit with target filename to avoid hfsutils
837         ## braindamage ("_" -> " " filename mangling) also avoid
838         ## ambiguity in the bootstrap partition.
839         if [ -n "$magicboot" ] ; then
840             [ "$VERBOSE" = 1 ] && echo "$INSTALLFIRST"
841             hcopy -r "$magicboot" :ofboot.b
842             if [ $? != 0 ] ; then
843                echo 1>&2 "$PRG: An error occured while writing to $boot"
844                return 1
845             fi
846         fi
847
848         [ "$VERBOSE" = 1 ] && echo "$INSTALLPRIMARY"
849         hcopy -r "$install" :"$BTFILE"
850         if [ $? != 0 ] ; then
851             echo 1>&2 "$PRG: An error occured while writing to $boot"
852             return 1
853         fi
854
855         [ "$VERBOSE" = 1 ] && echo "$PRG: Installing $bootconf onto $boot..."
856         hcopy -r "$bootconf" :"$CFFILE"
857         if [ $? != 0 ] ; then
858             echo 1>&2 "$PRG: An error occured while writing to $boot"
859             return 1
860         fi
861
862         if [ -n "$BSDLOADER" ] ; then
863             [ "$VERBOSE" = 1 ] && echo "$PRG: Installing $BSDLOADER onto $boot..."
864             hcopy -r "$BSDLOADER" :ofwboot
865             if [ $? != 0 ] ; then
866                 echo 1>&2 "$PRG: An error occured while writing to $boot"
867                 return 1
868             fi
869         fi
870
871         ## set all file's attributes, if a magicboot script exists it
872         ## gets the configured hfstype instead of yaboot (should be
873         ## "tbxi") so it gets booted by OF.
874         if [ -n "$magicboot" ] ; then
875             [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on $WRAP..."
876             hattrib -t "$hfstype" -c "$hfscreator" $INVISIBLE $LOCK :ofboot.b
877             if [ $? != 0 ] ; then
878                 echo 1>&2 "$PRG: Warning: error setting attributes on $WRAP"
879                 echo 1>&2 "$PRG: This is probably bad but we'll ignore it."
880             fi
881         fi
882
883         [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on $BTFILE..."
884         hattrib -t "$BTTYPE" -c "$hfscreator" $INVISIBLE $LOCK :"$BTFILE"
885         if [ $? != 0 ] ; then
886             echo 1>&2 "$PRG: Warning: error setting attributes on $BTFILE"
887             echo 1>&2 "$PRG: This is probably bad but we'll ignore it"
888         fi
889
890         [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on $CFFILE..."
891         hattrib -t "conf" -c "$hfscreator" $INVISIBLE $LOCK :"$CFFILE"
892         if [ $? != 0 ] ; then
893             echo 1>&2 "$PRG: Warning: error setting attributes on $CFFILE"
894             echo 1>&2 "$PRG: This is probably unimportant so we'll ignore it"
895         fi
896
897         if [ -n "$BSDLOADER" ] ; then
898             [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on ofwboot..."
899             hattrib -t "bsdb" -c "$hfscreator" $INVISIBLE $LOCK :ofwboot
900             if [ $? != 0 ] ; then
901                 echo 1>&2 "$PRG: Warning: error setting attributes on ofwboot"
902                 echo 1>&2 "$PRG: This is probably unimportant so we'll ignore it"
903             fi
904         fi
905
906         ## bless the root directory so OF will find the boot file
907         if [ "$bless" = yes ] ; then
908             [ "$VERBOSE" = 1 ] && echo "$PRG: Blessing $boot with Holy Penguin Pee..."
909             hattrib -b :
910             if [ $? != 0 ] ; then
911                 echo 1>&2 "$PRG: Warning: error blessing $boot"
912                 echo 1>&2 "$PRG: This is probably bad but we'll ignore it"
913             fi
914         fi
915
916         ## clean up the ~/.hcwd file hmount creates
917         humount "$boot" > /dev/null
918         sync ; sync
919
920         ## use explicit filename if we don't bless.
921         if [ "$bless" = yes ] ; then
922             local OFFILE='\\:tbxi'
923         else
924             if [ -n "$magicboot" ] ; then
925                 local OFFILE=ofboot.b
926             else
927                 local OFFILE="$BTFILE"
928             fi
929         fi
930
931         ## update the boot-device variable in OF nvram.
932         if [ "$nonvram" = 0 ] ; then
933             [ "$VERBOSE" = 1 ] && echo "$PRG: Updating OpenFirmware boot-device variable in nvram..."
934             [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: boot-device=${ofboot},${OFFILE}"
935             nvsetenv boot-device "${ofboot},${OFFILE}"
936             if [ $? != 0 ] ; then
937                 echo 1>&2 "$PRG: An error occured while updating nvram, we'll ignore it"
938             fi
939         fi
940
941     else
942         echo 1>&2 "$PRG: mtools support is not implemented"
943         echo 1>&2 "$PRG: Use --mount or add \`usemount' to $CONF"
944         return 1
945     fi
946
947     return 0
948 }
949
950 ## used by mnt_install so mntpoint= can be supported in a cleaner way.
951 mnt()
952 {
953     ## we can even create bootstrap filesystem images directly if you
954     ## ever wanted too.
955     if [ -f "$boot" ] ; then
956         local loop=",loop"
957     fi
958
959     if [ -e "$TMP/bootstrap.$$" ] ; then
960         echo 1>&2 "$PRG: $TMP/bootstrap.$$ exists, aborting."
961         return 1
962     fi
963
964     mkdir -m 700 "$TMP/bootstrap.$$"
965     if [ $? != 0 ] ; then
966         echo 1>&2 "$PRG: Could not create mountpoint directory, aborting."
967         return 1
968     fi
969
970     mount | grep "^$boot\>" > /dev/null
971     if [ $? = 0 ] ; then
972         echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
973         return 1
974     fi
975
976     [ "$VERBOSE" = 1 ] && echo "$PRG: Mounting $boot..."
977     mount -t "$fstype" -o rw,umask=077$loop "$boot" "$TMP/bootstrap.$$"
978     if [ $? != 0 ] ; then
979         echo 1>&2 "$PRG: An error occured mounting $boot"
980         return 1
981     fi
982
983     ## catch signals, set here to avoid umounting something we did not
984     ## mount. cleanup done by trap 0.
985     trap "umount $boot ; exit 129" 1
986     trap "echo 1>&2 $SIGINT ; umount $boot ; exit 130" 2
987     trap "umount $boot ; exit 131" 3
988     trap "umount $boot ; exit 143" 15
989
990     TARGET="$TMP/bootstrap.$$"
991     return 0
992 }
993
994 ## umnt funtion which checks whether we mounted anything or not, for
995 ## mntpoint= this makes the code below cleaner IMO.
996 umnt()
997 {
998     if [ -z "$mntpoint" ] ; then
999         [ "$1" = failure ] && echo 1>&2 "$PRG: Attempting to umount $boot..."
1000         umount "$2"
1001         if [ $? != 0 ] ; then
1002             echo 1>&2 "$PRG: umount of $boot failed!"
1003             return 1
1004         else
1005             [ "$1" = failure ] && echo 1>&2 "$PRG: umount successfull"
1006             return 0
1007         fi
1008     else
1009         return 0
1010     fi
1011 }
1012
1013 ## Use kernel filesytem drivers to mount the bootstrap partition like
1014 ## any other filesystem and copy the files there with standard un*x
1015 ## utilities.
1016 mnt_install()
1017 {
1018     local BTFILE=yaboot
1019
1020     ## msdosfs is broken, yaboot may not support this filename.
1021     if [ "$fstype" = msdos ] ; then
1022         local CFFILE=yaboot.cnf
1023     else
1024         local CFFILE=yaboot.conf
1025     fi
1026
1027     if [ -n "$magicboot" ] ; then
1028         local WRAP="${magicboot##*/}"
1029     fi
1030
1031     ## set verbose messages here so they don't show temporary file paths
1032     local INSTALLFIRST="$PRG: Installing first stage bootstrap $magicboot onto $boot..."
1033     local INSTALLPRIMARY="$PRG: Installing primary bootstrap $install onto $boot..."
1034
1035     ## repoint magicboot as the real first stage loader if using the
1036     ## modern automatic generating ofboot.b.
1037     if [ -n "$FIRST" ] ; then
1038         magicboot="$FIRST"
1039         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: set magicboot to $FIRST"
1040     fi
1041
1042     ## gross hack, add note section for IBM CHRP
1043     if [ "$ADDNOTE" = yes ] ; then
1044         hack_yaboot || return 1
1045     fi
1046
1047     ## call mnt() function to take care of mounting filesystem if needed
1048     if [ -z "$mntpoint" ] ; then
1049         mnt || return 1
1050     else
1051         TARGET="$mntpoint"
1052     fi
1053
1054     ## this is probably insecure on modern filesystems, but i think
1055     ## safe on crippled hfs/dosfs. user should ensure mntpoint= is safe.
1056     if [ -n "$magicboot" ] ; then
1057         [ "$VERBOSE" = 1 ] && echo "$INSTALLFIRST"
1058         cp -f "$magicboot" "$TARGET/ofboot.b"
1059         if [ $? != 0 ] ; then
1060             echo 1>&2 "$PRG: An error occured while writing to $boot"
1061             umnt failure "$TARGET"
1062             return 1
1063         fi
1064     fi
1065
1066     [ "$VERBOSE" = 1 ] && echo "$INSTALLPRIMARY"
1067     cp -f "$install" "$TARGET/$BTFILE"
1068     if [ $? != 0 ] ; then
1069         echo 1>&2 "$PRG: An error occured while writing to $boot"
1070         umnt failure "$TARGET"
1071         return 1
1072     fi
1073
1074     [ "$VERBOSE" = 1 ] && echo "$PRG: Installing $bootconf onto $boot..."
1075     cp -f "$bootconf" "$TARGET/$CFFILE"
1076     if [ $? != 0 ] ; then
1077         echo 1>&2 "$PRG: An error occured while writing to $boot"
1078         umnt failure "$TARGET"
1079         return 1
1080     fi
1081
1082     if [ -n "$BSDLOADER" ] ; then
1083         [ "$VERBOSE" = 1 ] && echo "$PRG: Installing $BSDLOADER onto $boot..."
1084         cp -f "$BSDLOADER" "$TARGET/ofwboot"
1085         if [ $? != 0 ] ; then
1086             echo 1>&2 "$PRG: An error occured while writing to $boot"
1087             umnt failure "$TARGET"
1088             return 1
1089         fi
1090     fi
1091
1092     if [ "$protect" = yes ] ; then
1093         [ "$VERBOSE" = 1 ] && echo "$PRG: Setting read-only attributes..."
1094         chmod a-w "$TARGET/$BTFILE"
1095         chmod a-w "$TARGET/$CFFILE"
1096         if [ -n "$magicboot" ] ; then
1097             chmod a-w "$TARGET/ofboot.b"
1098         fi
1099         if [ -n "$BSDLOADER" ] ; then
1100             chmod a-w "$TARGET/ofwboot"
1101         fi
1102     fi
1103
1104     sync ; sync
1105     umnt success "$TARGET" || return 1
1106
1107     ## make variable with a \ to avoid shell fsckage.  ugly ugly ugly.
1108     local BS='\'
1109     if [ -n "$magicboot" ] ; then
1110         [ -n "$OFDIR" ] && OFDIR="${BS}${OFDIR}${BS}"
1111         local OFFILE="${OFDIR}ofboot.b"
1112     else
1113         [ -n "$OFDIR" ] && OFDIR="${BS}${OFDIR}${BS}"
1114         local OFFILE="${OFDIR}${BTFILE}"
1115     fi
1116
1117     ## update the boot-device variable in OF nvram.
1118     if [ "$nonvram" = 0 ] ; then
1119         [ "$VERBOSE" = 1 ] && echo "$PRG: Updating OpenFirmware boot-device variable in nvram..."
1120         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: boot-device=${ofboot},${OFFILE}"
1121         nvsetenv boot-device "${ofboot},${OFFILE}"
1122         if [ $? != 0 ] ; then
1123             echo 1>&2 "$PRG: An error occured while updating nvram, we'll ignore it"
1124         fi
1125     else
1126         echo 1>&2 "$PRG: Warning: You must manually configure OpenFirmware to boot."
1127     fi
1128
1129     return 0
1130 }
1131
1132 ## raw installation, for IBM RS/6000 hardware, yaboot is dded to the
1133 ## bootstrap partition.
1134 raw_install()
1135 {
1136     ## make sure the device is not mounted as a filesystem before
1137     ## we start mucking with it directly.
1138     mount | grep "^$boot\>" > /dev/null
1139     if [ $? = 0 ] ; then
1140         echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
1141         return 1
1142     fi
1143
1144     ## set verbosity message before munging the yaboot pathname
1145     local INSTALLPRIMARY="$PRG: Installing primary bootstrap $install onto $boot..."
1146
1147     ## gross hack, add note section for IBM CHRP
1148     if [ "$ADDNOTE" = yes ] ; then
1149         hack_yaboot || return 1
1150     fi
1151
1152     [ "$VERBOSE" = 1 ] && echo "$INSTALLPRIMARY"
1153     dd if=/dev/zero of="$boot" bs=512 count=1600 > /dev/null 2>&1
1154     dd if="$install" of="$boot" bs=512 > /dev/null 2>&1
1155     if [ $? != 0 ] ; then
1156         echo 1>&2 "$PRG: Installation failed."
1157         return 1
1158     fi
1159     sync ; sync
1160     [ "$VERBOSE" = 1 ] && echo "$PRG: Installation successful"
1161     return 0
1162 }
1163
1164 ## make sure the first stage ofboot generator is compatible.
1165 checkfirststage()
1166 {
1167     grep -q "^#%ybinscript-" "$magicboot" 2> /dev/null
1168     if [ "$?" = 0 ] ; then
1169         local magic=`grep "^#%ybinscript-" "$magicboot"`
1170         local ver="${magic##*-}"
1171         if [ "$ver" = "1.1" ] ; then
1172             FIRSTSTG=compat
1173             return 0
1174         else
1175             echo 1>&2 "$PRG: Incompatible version of first stage loader $magicboot.  aborting..."
1176             return 1
1177         fi
1178     else
1179         FIRSTSTG=old
1180         return 0
1181     fi
1182 }
1183
1184 ## build the first stage loader.
1185 mkfirststage()
1186 {
1187     ## must have 7 backslashes to == \\ printf + shell = bizarre... or,
1188     ## make special variable to contain a \ (need \\ to make \) to work
1189     ## around echo -e -n brokeness.
1190     local BS='\\'
1191     local OS=1
1192
1193     ## deal with mntpoint=
1194     [ -n "$OFDIR" ] && local OFDIR="${BS}${OFDIR}${BS}"
1195
1196     ## some misguided people insist on installing OSX on
1197     ## HorribleFileSystem+ instead of UFS, as a result MacOS deblesses
1198     ## OSX, making it unbootable. if apple localizes the filesystem hierarchy again screw it.
1199     [ "$brokenosx" = yes ] && local OSXBOOT="${BS}System${BS}Library${BS}CoreServices${BS}BootX"
1200     [ "$brokenosx" = no ] && local OSXBOOT="${BS}${BS}:tbxi"
1201
1202     ## assign variables for configured menu options.
1203     [ "$usemount" = no -a "$bless" = yes ] && local YB="yaboot GNU l $ofboot ,${BS}${BS}yaboot"
1204     [ "$usemount" = yes -o "$bless" = no ] && local YB="yaboot GNU l $ofboot ,${OFDIR}yaboot"
1205     [ -n "$bsd" ] && OS="$(($OS + 1))" && local BSD="ybsd BSD b $ofboot ,${BS}${BS}ofwboot/$bsd"
1206     [ -n "$macos" ] && OS="$(($OS + 1))" && local MAC="macos MacOS m $macos ,${BS}${BS}:tbxi"
1207     [ -n "$macosx" ] && OS="$(($OS + 1))" && local MX="macosx MacOSX x $macosx ,${OSXBOOT}"
1208     [ -n "$darwin" ] && OS="$(($OS + 1))" && local DW="darwin Darwin d $darwin ,${BS}${BS}:tbxi"
1209     [ "$cdrom" = yes ] && OS="$(($OS + 1))" && local CD="cd CDROM c cd: ,${BS}${BS}:tbxi"
1210     [ "$network" = yes ] && OS="$(($OS + 1))" && local NET="net Network n enet: 0"
1211     [ "$of" = yes ] && OS="$(($OS + 1))" && local OF="of OpenFirmware o quit now"
1212     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: OS=$OS"
1213
1214     ## call ofboot,
1215     ## Usage: OS-count defaultos timeout fgc bgc osname oslabel oskey osdev osfile ...
1216     [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: /bin/sh $magicboot $OS $defaultos $delay $fbc $bgc $YB $BSD $MAC $MX $DW $CD $NET $OF\n"
1217     FIRST="$(/bin/sh "$magicboot" "$OS" "$defaultos" "$delay" $fgc $bgc ${YB} ${BSD} ${MAC} ${MX} ${DW} ${CD} ${NET} ${OF})" || return 1
1218
1219     return 0
1220 }
1221
1222 ## mkofboot function.
1223 mkoffs()
1224 {
1225     mount | grep "^$boot\>" > /dev/null
1226     if [ $? = 0 ] ; then
1227         echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
1228         return 1
1229     fi
1230
1231     case "$fstype" in
1232         hfs)
1233             [ "$VERBOSE" = 1 ] && echo "$PRG: Creating HFS filesystem on $boot..."
1234             if (command -v dd > /dev/null 2>&1) ; then
1235                 dd if=/dev/zero of="$boot" bs=512 count=1600 > /dev/null 2>&1
1236             fi
1237             hformat -l bootstrap "$boot" > /dev/null
1238             if [ $? != 0 ] ; then
1239                 echo 1>&2 "$PRG: HFS filesystem creation failed!"
1240                 return 1
1241             fi
1242             humount "$boot" ## otherwise we might get confused.
1243             return 0
1244             ;;
1245         msdos)
1246             if (command -v mkdosfs > /dev/null 2>&1) ; then
1247                 [ -x `command -v mkdosfs` ] || FAIL=1 ; else FAIL=1 ; fi
1248                 if [ "$FAIL" = 1 ] ; then
1249                     echo 1>&2 "$PRG: mkdosfs is not installed or cannot be found"
1250                     return 1
1251                 fi
1252
1253             [ "$VERBOSE" = 1 ] && echo "$PRG: Creating DOS filesystem on $boot..."
1254             if (command -v dd > /dev/null 2>&1) ; then
1255                 dd if=/dev/zero of="$boot" bs=512 count=1600 > /dev/null 2>&1
1256             fi
1257             mkdosfs -n bootstrap "$boot" > /dev/null
1258             if [ $? != 0 ] ; then
1259                 echo 1>&2 "$PRG: DOS filesystem creation failed!"
1260                 return 1
1261             fi
1262             return 0
1263             ;;
1264     esac
1265 }
1266
1267 confirm()
1268 {
1269     if [ "$FORCE" = yes ] ; then
1270         return 0
1271     else
1272         echo 1>&2
1273         [ "$fstype" = raw ] && $PRINTF 1>&2 "$PRG: Overwrite contents of $boot with $install? [y/N] "
1274         [ "$fstype" != raw ] && $PRINTF 1>&2 "$PRG: Create $fstype filesystem on $boot? [y/N] "
1275         read ans
1276         case "$ans" in
1277             y|Y)
1278                 return 0
1279                 ;;
1280             *)
1281                 echo 1>&2 "$PRG: Abort."
1282                 return 2
1283                 ;;
1284         esac
1285     fi
1286 }
1287
1288 ## for fstype=raw check if an ELF binary has already been dded.
1289 luserck()
1290 {
1291     if [ "$(dd if="$boot" bs=1 skip=1 count=3 2>/dev/null)" = ELF ] ; then
1292         return 0
1293     else
1294         echo 1>&2 "$PRG: This partition has never had yaboot installed before, please run mkofboot"
1295         return 1
1296     fi
1297 }
1298
1299 mkconf()
1300 {
1301 ## defaults for this are defined at the beginning of the script with
1302 ## other variables.
1303
1304 echo \
1305 "## yaboot configuration file generated by ybin $VERSION
1306
1307 device=$device
1308 timeout=$timeout
1309
1310 image=$image
1311         label=$label
1312         partition=$partition
1313         root=$root
1314         read-only
1315 " > "$TMPCONF" || return 1
1316
1317 [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "\nDEBUG: autoconf:\n----\n" && cat "$TMPCONF" 1>&2 && echo 1>&2 "----"
1318 return 0
1319 }
1320
1321 ## take out the trash.
1322 cleanup()
1323 {
1324     if [ -n "$TMPCONF" ] ; then rm -f "$TMPCONF" ; fi
1325     if [ -n "$FIRST" ] ; then rm -f "$FIRST" ; fi
1326     if [ -n "$TMPYABOOT" ] ; then rm -f "$TMPYABOOT" ; fi
1327     if [ -d "$TMP/bootstrap.$$" -a "$usemount" = yes ] ; then rmdir "$TMP/bootstrap.$$" ; fi
1328     return 0
1329 }
1330
1331 ##########
1332 ## Main ##
1333 ##########
1334
1335 ## absurdly bloated case statement to parse command line options.
1336 if [ $# != 0 ] ; then
1337     while true ; do
1338         case "$1" in
1339             -V|--version)
1340                 version
1341                 exit 0
1342                 ;;
1343             -h|--help)
1344                 usage
1345                 exit 0
1346                 ;;
1347             --debug)
1348                 DEBUG=1
1349                 ARGS="$ARGS $1"
1350                 shift
1351                 ;;
1352             -v|--verbose)
1353                 VERBOSE=1
1354                 ARGS="$ARGS $1"
1355                 shift
1356                 ;;
1357             -f|--force)
1358                 FORCE=yes
1359                 ARGS="$ARGS $1"
1360                 shift
1361                 ;;
1362             -b|--boot)
1363                 if [ -n "$2" ] ; then
1364                     if [ "$boot" = "unconfigured" ]; then
1365                         boot="$2"
1366                     else
1367                         boot="$boot $2"
1368                     fi
1369                     ARGBT=1
1370                     shift 2
1371                 else
1372                     echo 1>&2 "$PRG: option requires an argument $1"
1373                     echo 1>&2 "Try \`$PRG --help' for more information."
1374                     exit 1
1375                 fi
1376                 ;;
1377             -o|--ofboot)
1378                 if [ -n "$2" ] ; then
1379                     ofboot="$2"
1380                     ARGOB=1
1381                     ARGS="$ARGS $1 $2"
1382                     shift 2
1383                 else
1384                     echo 1>&2 "$PRG: option requires an argument $1"
1385                     echo 1>&2 "Try \`$PRG --help' for more information."
1386                     exit 1
1387                 fi
1388                 ;;
1389             --bootonce)
1390                 if [ -n "$2" ] ; then
1391                     bootonce="$2"
1392                     ARGS="$ARGS $1 $2"
1393                     shift 2
1394                 else
1395                     echo 1>&2 "$PRG: option requires an argument $1"
1396                     echo 1>&2 "Try \`$PRG --help' for more information."
1397                     exit 1
1398                 fi
1399                 ;;
1400             -i|--install)
1401                 if [ -n "$2" ] ; then
1402                     install="$2"
1403                     ARGBF=1
1404                     ARGS="$ARGS $1 $2"
1405                     shift 2
1406                 else
1407                     echo 1>&2 "$PRG: option requires an argument $1"
1408                     echo 1>&2 "Try \`$PRG --help' for more information."
1409                     exit 1
1410                 fi
1411                 ;;
1412             -C|--config)
1413                 if [ -n "$2" ] ; then
1414                     CONF="$2"
1415                     bootconf="$2"
1416                     ERR=" Error in $CONF:"
1417                     ARGS="$ARGS $1 $2"
1418                     shift 2
1419                 else
1420                     echo 1>&2 "$PRG: option requires an argument $1"
1421                     echo 1>&2 "Try \`$PRG --help' for more information."
1422                     exit 1
1423                 fi
1424                 ;;
1425             -m|--magicboot)
1426                 if [ -n "$2" ] ; then
1427                     magicboot="$2"
1428                     ARGWP=1
1429                     ARGS="$ARGS $1 $2"
1430                     shift 2
1431                 else
1432                     echo 1>&2 "$PRG: option requires an argument $1"
1433                     echo 1>&2 "Try \`$PRG --help' for more information."
1434                     exit 1
1435                 fi
1436                 ;;
1437             --filesystem)
1438                 if [ -n "$2" ] ; then
1439                     fstype="$2"
1440                     ARGFS=1
1441                     ARGS="$ARGS $1 $2"
1442                     shift 2
1443                 else
1444                     echo 1>&2 "$PRG: option requires an argument $1"
1445                     echo 1>&2 "Try \`$PRG --help' for more information."
1446                     exit 1
1447                 fi
1448                 ;;
1449             --nobless)
1450                 bless=no
1451                 ARGBS=1
1452                 ARGS="$ARGS $1"
1453                 shift
1454                 ;;
1455             -M|--mount)
1456                 usemount=yes
1457                 ARGMT=1
1458                 ARGS="$ARGS $1"
1459                 shift
1460                 ;;
1461             --protect)
1462                 protect=yes
1463                 ARGPT=1
1464                 ARGS="$ARGS $1"
1465                 shift
1466                 ;;
1467             --hide)
1468                 hide=yes
1469                 ARGHD=1
1470                 ARGS="$ARGS $1"
1471                 shift
1472                 ;;
1473             --nonvram)
1474                 nonvram=1
1475                 ARGNV=1
1476                 ARGS="$ARGS $1"
1477                 shift
1478                 ;;
1479             --device)
1480                 if [ -n "$2" ] ; then
1481                     device="$2"
1482                     bootconf=auto
1483                     echo 1>&2 "$PRG: WARNING: Deprecated option --device"
1484                     ARGS="$ARGS $1 $2"
1485                     shift 2
1486                 else
1487                     echo 1>&2 "$PRG: option requires an argument $1"
1488                     echo 1>&2 "Try \`$PRG --help' for more information."
1489                     exit 1
1490                 fi
1491                 ;;
1492             --timeout)
1493                 if [ -n "$2" ] ; then
1494                     timeout="$2"
1495                     bootconf=auto
1496                     echo 1>&2 "$PRG: WARNING: Deprecated option --device"
1497                     ARGS="$ARGS $1 $2"
1498                     shift 2
1499                 else
1500                     echo 1>&2 "$PRG: option requires an argument $1"
1501                     echo 1>&2 "Try \`$PRG --help' for more information."
1502                     exit 1
1503                 fi
1504                 ;;
1505             --image)
1506                 if [ -n "$2" ] ; then
1507                     image="$2"
1508                     bootconf=auto
1509                     echo 1>&2 "$PRG: WARNING: Deprecated option --device"
1510                     ARGS="$ARGS $1 $2"
1511                     shift 2
1512                 else
1513                     echo 1>&2 "$PRG: option requires an argument $1"
1514                     echo 1>&2 "Try \`$PRG --help' for more information."
1515                     exit 1
1516                 fi
1517                 ;;
1518             --label)
1519                 if [ -n "$2" ] ; then
1520                     label="$2"
1521                     bootconf=auto
1522                     echo 1>&2 "$PRG: WARNING: Deprecated option --device"
1523                     ARGS="$ARGS $1 $2"
1524                     shift 2
1525                 else
1526                     echo 1>&2 "$PRG: option requires an argument $1"
1527                     echo 1>&2 "Try \`$PRG --help' for more information."
1528                     exit 1
1529                 fi
1530                 ;;
1531             --partition)
1532                 if [ -n "$2" ] ; then
1533                     partition="$2"
1534                     bootconf=auto
1535                     echo 1>&2 "$PRG: WARNING: Deprecated option --device"
1536                     ARGS="$ARGS $1 $2"
1537                     shift 2
1538                 else
1539                     echo 1>&2 "$PRG: option requires an argument $1"
1540                     echo 1>&2 "Try \`$PRG --help' for more information."
1541                     exit 1
1542                 fi
1543                 ;;
1544             --root)
1545                 if [ -n "$2" ] ; then
1546                     root="$2"
1547                     bootconf=auto
1548                     echo 1>&2 "$PRG: WARNING: Deprecated option --device"
1549                     ARGS="$ARGS $1 $2"
1550                     shift 2
1551                 else
1552                     echo 1>&2 "$PRG: option requires an argument $1"
1553                     echo 1>&2 "Try \`$PRG --help' for more information."
1554                     exit 1
1555                 fi
1556                 ;;
1557             "")
1558                 break
1559                 ;;
1560             *)
1561                 echo 1>&2 "$PRG: unrecognized option \`$1'"
1562                 echo 1>&2 "Try \`$PRG --help' for more information."
1563                 exit 1
1564                 ;;
1565         esac
1566     done
1567 fi
1568
1569 ## check that specified config file exists, unless its /dev/null in
1570 ## which case we assume all options are done on the command line.
1571 if [ "$CONF" = /dev/null ] ; then
1572     true
1573 else
1574     confexist || exit 1
1575 fi
1576
1577 ## if there is no config file use the automatic generation to make a
1578 ## generic yaboot.conf. do this before the confcheck to avoid wierd errors.
1579 if [ "$bootconf" = /dev/null ] ; then
1580     if (command -v yabootconfig > /dev/null 2>&1) ; then
1581         echo 1>&2 "$PRG: Warning: no /etc/yaboot.conf, running yabootconfig to make one"
1582         yabootconfig --noinstall --quiet
1583         if [ $? != 0 ] ; then
1584             echo 1>&2 "$PRG: yabootconfig failed, please supply a valid /etc/yaboot.conf"
1585             echo 1>&2 "$PRG: You may also use $PRG's --boot, --image, --partition, and --device switches"
1586             echo 1>&2 "$PRG: These switches will cause $PRG to generate a basic yaboot.conf on the fly"
1587             exit 1
1588         else
1589             CONF=/etc/yaboot.conf
1590             bootconf=$CONF
1591             ERR=" Error in $CONF:"
1592             confexist || exit 1
1593         fi
1594     fi
1595 fi
1596
1597 ## Checks if each option was defined on the command line, and if so
1598 ## don't read it from the configuration file. this avoids
1599 ## configuration options from being set null, as well as command line
1600 ## options from being clobbered.
1601 [ "$ARGBT" != 1 -a $(parseconf ck boot) = 0 ] && boot=`parseconf str boot`
1602 [ "$ARGOB" != 1 -a $(parseconf ck ofboot) = 0 ] && ofboot=`parseconf str ofboot`
1603 [ "$ARGBF" != 1 -a $(parseconf ck install) = 0 ] && install=`parseconf str install`
1604 [ "$ARGWP" != 1 -a $(parseconf ck magicboot) = 0 ] && magicboot=`parseconf str magicboot`
1605 [ "$ARGMT" != 1 -a $(parseconf flag usemount) = 0 ] && usemount=yes
1606 [ "$ARGFS" != 1 -a $(parseconf ck fstype) = 0 ] && fstype=`parseconf str fstype`
1607 [ "$ARGBS" != 1 -a $(parseconf flag nobless) = 0 ] && bless=no
1608 [ "$ARGPT" != 1 -a $(parseconf flag protect) = 0 ] && protect=yes
1609 [ "$ARGHD" != 1 -a $(parseconf flag hide) = 0 ] && hide=yes
1610 [ "$ARGNV" != 1 -a $(parseconf flag nonvram) = 0 ] && nonvram=1
1611 [ $(parseconf ck hfstype) = 0 ] && hfstype=`parseconf str hfstype`
1612 [ $(parseconf ck hfscreator) = 0 ] && hfscreator=`parseconf str hfscreator`
1613 [ $(parseconf ck mntpoint) = 0 ] && mntpoint=`parseconf str mntpoint`
1614 [ $(parseconf ck delay) = 0 ] && delay=`parseconf str delay`
1615 [ $(parseconf ck timeout) = 0 ] && timeout=`parseconf str timeout`
1616 [ $(parseconf ck bsd) = 0 ] && bsd=`parseconf str bsd`
1617 [ $(parseconf ck macos) = 0 ] && macos=`parseconf str macos`
1618 [ $(parseconf ck macosx) = 0 ] && macosx=`parseconf str macosx`
1619 [ $(parseconf ck darwin) = 0 ] && darwin=`parseconf str darwin`
1620 [ $(parseconf ck defaultos) = 0 ] && defaultos=`parseconf str defaultos`
1621 [ $(parseconf ck fgcolor) = 0 ] && fgcolor=`parseconf str fgcolor`
1622 [ $(parseconf ck bgcolor) = 0 ] && bgcolor=`parseconf str bgcolor`
1623 [ $(parseconf ck icon) = 0 ] && export YBINOFICON=`parseconf str icon`
1624 [ $(parseconf flag enablecdboot) = 0 ] && cdrom=yes
1625 [ $(parseconf flag enablenetboot) = 0 ] && network=yes
1626 [ $(parseconf flag enableofboot) = 0 ] && of=yes
1627 [ $(parseconf flag brokenosx) = 0 ] && brokenosx=yes
1628
1629 bootparts=0
1630 for i in $boot; do
1631     bootparts=$(($bootparts + 1))
1632 done
1633 if [ "$bootparts" -gt 1 ]; then
1634     [ "$VERBOSE" = 1 ] && echo "$PRG: Iterating through list of boot partitions..."
1635     rc=0
1636     for i in $boot; do
1637         [ "$VERBOSE" = 1 ] && echo "$ABSPRG $ARGS -b $i"
1638         $ABSPRG $ARGS -b $i || rc=$?
1639     done
1640     exit $rc
1641 fi
1642
1643 ## ffs!! rtfm! foad!
1644 if [ "$boot" = unconfigured ] ; then
1645     echo 1>&2 "$PRG: You must specify the device for the bootstrap partition. (ie: boot=/dev/hdaX)"
1646     echo 1>&2 "$PRG: Try \`$PRG --help' for more information."
1647     exit 1
1648 fi
1649
1650 ## if there is still no config file use the automatic generation to make a
1651 ## generic yaboot.conf. do this before the confcheck to avoid wierd errors.
1652 if [ "$bootconf" = /dev/null ] ; then
1653     echo 1>&2 "$PRG: Warning: no yaboot.conf, using generic configuration."
1654     bootconf=auto
1655 fi
1656
1657 ## mntpoint is incompatible with mkofboot.
1658 if [ "$PRG" = mkofboot -a -n "$mntpoint" ] ; then
1659     echo 1>&2 "$PRG: Cannot be used with \`mntpoint='"
1660     exit 1
1661 fi
1662
1663 ## validate configuration for sanity.
1664 checkconf || exit 1
1665
1666 if [ "x$bootonce" != "x" ]; then
1667     foundlabel=`sed s/\#.*// $bootconf | grep "label=$bootonce$" | wc -l`
1668     if [ "$nonvram" = 1 ]; then
1669         echo 1>&2 "$PRG: --bootonce specified, but nvsetenv not available."
1670         exit 1
1671     fi
1672     if [ "$foundlabel" = 1 ]; then
1673         nvsetenv boot-once "$bootonce"
1674         foundlabel=`nvsetenv boot-once`
1675         if [ "$foundlabel" != "boot-once=$bootonce" -a \
1676              "$foundlabel" != "$bootonce" ]; then
1677             echo 1>&2 "$PRG: Could not nvsetenv boot-once $bootonce"
1678             exit 1
1679         fi
1680         [ "$VERBOSE" = 1 ] && echo "$PRG: nvsetenv boot-once $bootonce"
1681     else
1682         echo 1>&2 "$PRG: Could not find bootonce label [$bootonce] in $bootconf"
1683         exit 1
1684     fi
1685 fi
1686
1687 bootparts=0
1688
1689 ## check that we can use ofpath, its only needed for magicboot script
1690 ## building and nvram updates.
1691 if [ -n "$magicboot" -o "$nonvram" = 0 ] ; then
1692     if [ -z "$ofboot" -o -n "$macos" -o -n "$macosx" -o -n "$darwin" ] ; then
1693         if (command -v ofpath > /dev/null 2>&1) ; then
1694             [ -x `command -v ofpath` ]
1695             if [ $? != 0 ] ; then
1696                 echo 1>&2 "$PRG: ofpath could not be found, aborting."
1697                 exit 1
1698             fi
1699         else
1700             echo 1>&2 "$PRG: ofpath could not be found, aborting."
1701             exit 1
1702         fi
1703     fi
1704 fi
1705
1706 ## if password is set in yaboot.conf make sure permissions on that
1707 ## file are safe, warn if not.
1708 if (grep -q '^[[:space:]]*password[[:space:]]*=' "$bootconf" > /dev/null 2>&1) ; then
1709     permcheck
1710 fi
1711
1712 ## check if we are root if needed.
1713 if [ "$usemount" = yes -a -z "$mntpoint" ] ; then
1714     if [ `id -u` != 0 ] ; then
1715         echo 1>&2 "$PRG: \`usemount' requires root privileges, go away."
1716         exit 1
1717     fi
1718 fi
1719
1720 if [ "$fstype" = hfs ] ; then
1721     checkhfsutils
1722     if [ $? != 0 ] ; then
1723         echo 1>&2 "$PRG: hfsutils is not installed or cannot be found"
1724         echo 1>&2 "$PRG: Try --mount if `uname -sr` supports HFS"
1725         exit 1
1726     fi
1727 fi
1728
1729 ## convert unix device nodes to OpenFirmware pathnames
1730 if [ -n "$magicboot" -o "$nonvram" = 0 ] ; then
1731     convertpath || exit 1
1732 fi
1733
1734 ## yaboot.conf autogeneration. MUST have secure mktemp to
1735 ## avoid race conditions. Debian's mktemp qualifies.
1736 if [ "$bootconf" = auto ] ; then
1737     TMPCONF=`mktemp -q "$TMP/$PRG.XXXXXX"`
1738     if [ $? != 0 ] ; then
1739         echo 1>&2 "$PRG: Could not create temporary file, aborting."
1740         exit 1
1741     fi
1742
1743     mkconf
1744     if [ $? != 0 ] ; then
1745         echo 1>&2 "$PRG: An error occured generating yaboot.conf, aborting."
1746         exit 1
1747     fi
1748
1749     bootconf="$TMPCONF"
1750 fi
1751
1752 if [ -n "$magicboot" ] ; then
1753     checkfirststage || exit 1
1754     if [ "$FIRSTSTG" = compat ] ; then
1755         mkfirststage
1756         if [ $? != 0 ] ; then
1757             echo 1>&2 "$PRG: An error occured while building first stage loader.  aborting..."
1758             exit 1
1759         fi
1760     fi
1761 fi
1762
1763 case "$PRG" in
1764     ybin)
1765         case "$usemount" in
1766             no)
1767                 if [ "$fstype" = raw ] ; then
1768                     luserck || exit 1
1769                     raw_install || exit 1
1770                 else
1771                     util_install || exit 1
1772                 fi
1773                 exit 0
1774                 ;;
1775             yes)
1776                 mnt_install || exit 1
1777                 exit 0
1778                 ;;
1779         esac
1780         ;;
1781     mkofboot)
1782         case "$usemount" in
1783             no)
1784                 ## its not nice to erase the partition and then bail!
1785                 if [ "$fstype" = msdos ] ; then
1786                     echo 1>&2 "$PRG: mtools support is not implemented"
1787                     echo 1>&2 "$PRG: Use --mount or add \`usemount' to $CONF"
1788                     exit 1
1789                 fi
1790                 confirm || exit 2
1791                 if [ "$fstype" = raw ] ; then
1792                     raw_install || exit 1
1793                 else
1794                     mkoffs || exit 1
1795                     util_install || exit 1
1796                 fi
1797                 [ "$VERBOSE" = 1 ] && echo "$PRG: Installation complete."
1798                 exit 0
1799                 ;;
1800             yes)
1801                 confirm || exit 2
1802                 mkoffs || exit 1
1803                 mnt_install || exit 1
1804                 [ "$VERBOSE" = 1 ] && echo "$PRG: Installation complete."
1805                 exit 0
1806                 ;;
1807         esac
1808         ;;
1809 esac
1810
1811 exit 0