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