]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/openslug-init/openslug-init-0.10/turnup
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / openslug-init / openslug-init-0.10 / turnup
1 #!/bin/sh
2 # turnup
3 # See the help block at the end for documentation.
4 #
5 . /etc/default/functions
6
7 #
8 # configuration
9 #  The following variables control which directories in /var end up on the rootfs
10 #  and which end up in a temporary file system.
11 INRAM_MEMSTICK="/var/cache /var/lock /var/log /var/run /var/tmp /var/lib/ipkg"
12 INRAM_NFS="/var/cache /var/lock /var/run /var/tmp"
13 INRAM_DISK=""
14 #
15 # force: override certain checks
16 force=
17 #
18 # fstype new
19 #  The type of the file system mounted on "new"  Outputs the last
20 #  piece of information found, which should be the one for the
21 #  currently visible mount!
22 fstype() {
23         local cwd dev mp type options pass freq result
24         cwd="$(cd "$1"; /bin/pwd)"
25         result=
26         while read dev mp type options pass freq
27         do
28                 case "$mp" in
29                 "$cwd") result="$type";;
30                 esac
31         done </proc/mounts
32         echo "$result"
33 }
34 #
35 # fsoptions arguments
36 #  Collapses the mount (-o) options into a single list which is
37 #  printed on stdout.  Accepts an arbitrary list of options and
38 #  just joins them together.
39 fsoptions() {
40         local options
41         options=
42         while test $# -gt 1
43         do
44                 case "$1" in
45                 -t)     shift;;
46                 -o)     if test -n "$2"
47                         then
48                                 if test -n "$options"
49                                 then
50                                         options="$options,$2"
51                                 else
52                                         options="$2"
53                                 fi
54                         fi
55                         shift;;
56                 esac
57                 shift
58         done
59         if test -n "$options"
60         then
61                 echo "$options"
62         else
63                 echo defaults
64         fi
65 }
66 #
67 # get_flash <directory> {mount options}
68 #  mount the flash device, writeable, on the given directory
69 get_flash() {
70         local ffsdir ffsdev
71
72         ffsdir="$1"
73         shift
74         test -n "$ffsdir" -a -d "$ffsdir" || {
75                 echo "$0: $ffsdir: internal error, flash mount point not a directory" >&2
76                 return 1
77         }
78
79         ffsdev="$(mtblockdev Flashdisk)"
80         umountflash "$ffsdev" &&
81         mountflash "$ffsdev" "$ffsdir" "$@"
82 }
83 #
84 # check_rootfs [-i] <root fs directory>
85 #  Make sure the candidate rootfs is empty
86 check_rootfs() {
87         local fcount
88
89         case "$1" in
90         -i)     shift
91                 case "$force" in
92                 -f) return 0;;
93                 esac
94
95                 fcount="$(find "$1" ! -type d -print | wc -l)"
96                 test "$fcount" -eq 0 && return 0
97
98                 echo "turnup: $1: partition contains existing files, specify -f to overwrite" >&2
99                 return 1;;
100         *)      checkmount "$1" && return 0
101
102                 echo "turnup: $1: partition does not seem to be a valid root partition" >&2
103                 if test -f "$1"/.recovery
104                 then
105                         echo "  $1/.recovery exists: fix the partition then remove it" >&2
106                 fi
107                 return 1;;
108         esac
109 }
110 #
111 # copy_rootfs old new
112 #  Make a copy of the given root file system, copying only the
113 #  directories needed.  The root must be the flash file system
114 copy_rootfs() {
115         local old new
116         old="$1"
117         new="$2"
118         test -d "$old" -a -d "$new" || {
119                 echo "turnup: rootfs: copy $old $new: not a directory" >&2
120                 return 1
121         }
122         #
123         # There are no problem file names in the flash file system, so
124         # it is possible to use -print, not -print0.  The following
125         # files and directories are not copied:
126         #
127         #   /dev/*
128         #   /boot, /boot/*
129         #   /linuxrc*
130         #   /var/*
131         echo "turnup: copying root file system" >&2
132         (       cd "$1"
133                 find . -mount -print |
134                 sed '\@^./dev/@d;\@^./boot/@d;\@^./boot$@d;\@^./linuxrc@d;\@^./var/@d' |
135                 cpio -p -d -m -u "$2"
136         ) || {
137                 echo "turnup: rootfs: cpio $old $new failed" >&2
138                 return 1
139         }
140         echo "done" >&2
141 }
142
143 #
144 # setup_dev new device_table
145 #  In flash file systems /dev is in ramfs, in disk systems /dev
146 #  can be populated permanently.  This is done by creating a
147 #  single entry '.noram' in /dev - the devices init script will
148 #  then populate the directory without overmounting it.  The
149 #  devices in the passed in device table are also created, but
150 #  note that this is insufficient, /etc/init.d/devices must
151 #  also run.
152 setup_dev() {
153         test -n "$1" -a -d "$1"/dev -a -r "$2" || {
154                 echo "turnup: setup_dev($1,$2): expected a directory and a file" >&2
155                 return 1
156         }
157         echo "turnup: initialising dev file system" >&2
158         # init tries to open the following devices:
159         #       /dev/console
160         #       /dev/tty0
161         #       /dev/null
162         # syslog, and maybe other things, only work if fd 1 is valid, therefore
163         # we must create these devices here...
164         makedevs --root="$1" --devtable="$2"
165         :>"$1"/dev/.noram
166         return 0
167 }
168
169 #
170 # setup_bootdev new device_table
171 #  As above but actually uses the supplied device table - this is possible if
172 #  the table is just used for boot because the extra setup is not required.
173 setup_bootdev() {
174         test -n "$1" -a -d "$1"/dev -a -r "$2" || {
175                 echo "turnup: setup_bootdev($1,$2): expected a directory and a file" >&2
176                 return 1
177         }
178         # NOTE: this fails silently with 0 return code(!) when a directory
179         # does not exist yet things are created within it.
180         makedevs -r "$1" -D "$2"
181 }
182
183 #
184 # setup_var new type
185 #  Populates /var.
186 #  Removes the /var tmpfs entry from /etc/fstab.
187 #  Creates links from /var into /media/ram for NFS and Memstick.
188
189 setup_var() {
190         test -n "$1" -a -d "$1"/var || {
191                 echo "turnup: setup_var($1,$2): expected a directory" >&2
192                 return 1
193         }
194         case "$2" in
195         disk|nfs|memstick);;
196         *)      echo "turnup: setup_var($1,$2): expected 'disk', 'nfs' or 'memstick'" >&2
197                 return 1;;
198         esac
199         #
200         # populate /var, there is a shell script to do this, but it uses
201         # absolute path names
202         chroot "$1" /bin/busybox sh /etc/init.d/populate-volatile.sh || {
203                 echo "turnup: /var: could not populate directory" >&2
204                 return 1
205         }
206
207         case "$2" in
208         disk) RAMTARGETS=${INRAM_DISK};;
209         nfs) RAMTARGETS=${INRAM_NFS};;
210         memstick) RAMTARGETS=${INRAM_MEMSTICK};;
211         esac
212
213         for d in ${RAMTARGETS}; do
214           RAMDIR="/media/ram${d}"
215           REALDIR="${d}"
216           rm -rf "${1}${REALDIR}"
217           ln -s "${RAMDIR}" "${1}${REALDIR}"
218           done
219         # the startup link is left for the moment, this seems safer
220         #rm "$1"/etc/rc?.d/[KS]??populate-var.sh
221         # remove the /var tmpfs entry from the new /etc/fstab
222         sed -i '\@[     ]/var[  ][      ]*tmpfs[        ]@d' "$1"/etc/fstab
223         echo "turnup: tmpfs will no longer be mounted on /var" >&2
224         #
225         # Previous versions of turnup removed populate-var.sh from the
226         # startup links, this one doesn't, so /var can be made back into
227         # a tmpfs just by a change to /etc/fstab.
228         return 0
229 }
230
231 #
232 # setup_syslog new
233 #  Moves the syslog to a file - appropriate for disk and nfs types, not
234 #  otherwise.
235 setup_syslog() {
236         test -n "$1" -a -d "$1"/etc || {
237                 echo "turnup: setup_syslog($1): expected a directory" >&2
238                 return 1
239         }
240         #
241         # if the syslog is to the buffer redirect it to a file
242         if egrep -q '^DESTINATION="buffer"' "$1"/etc/syslog.conf
243         then
244                 if cp "$1"/etc/syslog.conf "$1"/etc/syslog.conf.sav
245                 then
246                         # the busybox syslog will fail with ROTATESIZE and ROTATEGENS
247                         sed -i 's!DESTINATION="buffer"!DESTINATION="file"!
248                                 /^ROTATESIZE=/d
249                                 /^ROTATEGENS=/d' "$1"/etc/syslog.conf
250                         echo "turnup: /etc/syslog.conf: changed to file buffering" >&2
251                         echo " Old (buffer) version in /etc/syslog.conf.sav" >&2
252                         echo " Log messages will be in /var/log/messages" >&2
253                 else
254                         echo "turnup: /etc/syslog.conf: failed to make a copy" >&2
255                         echo " syslog will log to a buffer" >&2
256                 fi
257         fi
258         return 0
259 }
260
261 #
262 # setup_rootfs type new device_table
263 #  Populates the /dev and /var directories, alters the startup to
264 #  not mount or populate them further.  Does the right thing according
265 #  to the given $type
266 setup_rootfs() {
267         local type new table
268         type="$1"
269         new="$2"
270         table="$3"
271
272         test -n "$new" -a -d "$new" -a -f "$table" || {
273                 echo "turnup: setup_rootfs($type,$new,$table): expected a directory and a file" >&2
274                 return 1
275         }
276
277         case "$type" in
278         flash)  return 0;;
279         disk)   setup_dev "$new" "$table" &&
280                 setup_var "$new" "$type" &&
281                 setup_syslog "$new";;
282         memstick)
283                 setup_bootdev "$new" "$table" &&
284                 setup_var "$new" "$type" ;;
285         nfs)    setup_dev "$new" "$table" &&
286                 setup_var "$new" "$type" &&
287                 setup_syslog "$new";;
288         *)      echo "turnup: setup_rootfs: $type: unknown rootfs type" >&2
289                 return 1;;
290         esac
291         # return code of last setup function
292 }
293
294 #
295 # setup_fstab new fsdev fstype fsoptions
296 #  Alters the /etc/fstab entry for / to refer to the correct device and
297 #  have the correct type and options.  Essential for checkroot to remount
298 #  / with the correct options.
299 #  bad, since sed won't fail even if it changes nothing.
300 setup_fstab() {
301         sed -i '\@^[^   ]*[     ][      ]*/[    ]@s@^.*$@'"$2   /       $3      $4      1  1"'@' "$1"/etc/fstab
302         egrep -q "^$2   /       $3      $4      1  1\$" "$1"/etc/fstab || {
303                 echo "turnup: /etc/fstab: root(/) entry not changed" >&2
304                 echo "  you probably need to check the options in /etc/fstab" >&2
305                 echo "  to ensure that the root partition is mounted correctly" >&2
306                 return 1
307         }
308 }
309
310
311 #
312 # boot_rootfs <boot type> <flash file system> <sleep time> <device> [options]
313 #  Change the flash partition (not the current root!) to boot off
314 #  the new root file system
315 boot_rootfs() {
316         local type ffs sleep device opt
317
318         type="$1"
319         ffs="$2"
320         sleep="$3"
321         device="$4"
322
323         # test this first as the test does not depend on the correctness
324         # of the other arguments
325         test -n "$ffs" -a -d "$ffs" || {
326                 echo "turnup: boot_rootfs($type, $ffs, $device): expected directory" >&2
327                 return 1
328         }
329         test -x "$ffs"/boot/"$type" || {
330                 echo "turnup: boot_rootfs($type, $ffs, $device): invalid boot type $type" >&2
331                 return 1
332         }
333         shift
334         shift
335
336         case "$type" in
337         disk)   test -n "$device" -a -b "$device" || {
338                         echo "turnup: boot_rootfs($ffs, $type, $device): expected block device" >&2
339                         return 1
340                 }
341                 shift 2;;
342         nfs)    shift 2;;
343         flash)  ;;
344         ram)    ;;
345         *)      echo "turnup: boot_rootfs($type, $ffs, $device): unknown type" >&2
346                 return 1;;
347         esac
348
349         #
350         # The /linuxrc records the correct options to mount the device,
351         # since we have already mounted if correctly with these options
352         # we can be sure (maybe) that the boot will work.  If not /boot/disk
353         # falls back to flash.
354         #
355         # This modifies the boot process, until this point no harm has been
356         # done to the system, but at this point the boot rootfs will change
357         rm -f "$ffs"/linuxrc.new || {
358                 echo "turnup: boot_rootfs: failed to remove $ffs/linuxrc.new" >&2
359                 return 1
360         }
361         case "$type" in
362         flash)  ln -s "boot/flash" "$ffs"/linuxrc.new || {
363                         echo "turnup: boot_rootfs: failed to create $ffs/linuxrc.new" >&2
364                         return 1
365                 };;
366         ram)    {       echo '#!/bin/sh'
367                         echo 'rm -f /linuxrc.new'
368                         echo 'ln -s boot/flash /linuxrc.new'
369                         echo 'mv /linuxrc.new /linuxrc'
370                         echo 'exec /boot/ram /dev/ram0'
371                         echo 'exec /boot/flash'
372                 } >"$ffs"/linuxrc.new &&
373                 chmod 744 "$ffs"/linuxrc.new || {
374                         echo "turnup: boot_rootfs: failed to write $ffs/linuxrc.new" >&2
375                         return 1
376                 };;
377         *)      {       echo '#!/bin/sh'
378                         test "$sleep" -gt 0 && echo -n "sleep='$sleep' "
379                         echo -n "exec '/boot/$type' '$device'"
380                         for opt in "$@"
381                         do
382                                 echo -n " '$opt'"
383                         done
384                         echo
385                         echo 'exec /boot/flash'
386                 } >"$ffs"/linuxrc.new &&
387                 chmod 744 "$ffs"/linuxrc.new || {
388                         echo "turnup: boot_rootfs: failed to write $ffs/linuxrc.new" >&2
389                         return 1
390                 };;
391         esac
392         rm -f "$ffs"/linuxrc.sav || {
393                 echo "turnup: boot_rootfs: failed to remove $ffs/linuxrc.sav" >&2
394                 return 1
395         }
396         ln "$ffs"/linuxrc "$ffs"/linuxrc.sav || {
397                 echo "turnup: boot_rootfs: failed to save /linuxrc.sav" >&2
398                 return 1
399         }
400         mv -f "$ffs"/linuxrc.new "$ffs"/linuxrc || {
401                 echo "turnup: boot_rootfs: failed to install new /linuxrc" >&2
402                 return 1
403         }
404         return 0
405 }
406
407 #
408 # disk [-m] [-i] [-s<time>] <device> {options}
409 #  Carefully copy the flash file system to the named device.
410 disk() {
411         local setup_type sleep init device new ffs fst fso
412
413         setup_type=disk
414         sleep=0
415         init=
416         while test $# -gt 0
417         do
418                 case "$1" in
419                 -f)     force="$1"
420                         shift;;
421                 -m)     setup_type=memstick
422                         shift;;
423                 -i)     init="$1"
424                         shift;;
425                 -s*)    sleep="${1#-s}"
426                         sleep="${sleep:-10}"
427                         shift;;
428                 *)      break;;
429                 esac
430         done
431
432         device="$1"
433         test -n "$device" -a -b "$device" || {
434                 echo "turnup disk: $device: block device required" >&2
435                 return 1
436         }
437         shift
438
439         # make temporary directories for the mount points
440         new="/tmp/rootfs.$$"
441         ffs="/tmp/flashdisk.$$"
442         mkdir "$new" "$ffs" || {
443                 echo "turnup: disk: failed to create temporary directories" >&2
444                 return 1
445         }
446
447         # make sure we can get to the flash file system first
448         get_flash "$ffs" || {
449                 rmdir "$new" "$ffs"
450                 return 1
451         }
452
453         # Now mount the device with the given options, note that specifying
454         # read only is *not* an option, this is important because the boot/disk
455         # script needs a rw file system
456         status=1
457         fst=
458         fso="$(fsoptions "$@")"
459         if mount "$@" "$device" "$new"
460         then
461                 fst="$(fstype "$new")"
462                 umount "$new" ||
463                         echo "turnup disk: $device($new): umount does not seem to work" >&2
464         fi
465
466         if test -n "$fst" && mount -t "$fst" -o "$fso" "$device" "$new"
467         then
468                 if check_rootfs $init "$new" && {
469                         test -z "$init" || {
470                                 copy_rootfs "$ffs" "$new" &&
471                                 setup_rootfs "$setup_type" "$new" "$ffs"/etc/device_table
472                         }
473                    }
474                 then
475                         setup_fstab "$new" "$device" "$fst" "$fso"
476                         status=0
477                 fi
478
479                 # clean up the disk.  It is worrying if this umount fails!
480                 umount "$new" || test "$force" = "-f" || {
481                         echo "turnup disk: $device: umount failed" >&2
482                         echo "  you must unmount this device cleanly yourself, then use" >&2
483                         if test -z "$init"
484                         then
485                                 echo "  turnup with the -f option to boot from the device" >&2
486                         else
487                                 echo "  turnup without the -i option to boot from the device" >&2
488                         fi
489                         status=1
490                 }
491
492                 # if everything went ok boot from this disk
493                 if test $status -eq 0
494                 then
495                         # memsticks boot like disks, so ignore the -m
496                         boot_rootfs disk "$ffs" "$sleep" "$device" -t "$fst" -o "$fso"
497                 fi
498         else
499                 echo "turnup disk: $device($*): unable to mount device on $new" >&2
500                 # If it worked first time
501                 if test -n "$fst"
502                 then
503                         echo "  options used: -t $fst -o $fso [error in this script]" >&2
504                 fi
505         fi
506
507         # clean up the flash file system
508         umount "$ffs"
509         rmdir "$new" "$ffs"
510         return $status
511 }
512
513 #
514 # boot_reset <type>
515 #  Resets the boot type to flash or ram, as appropriate
516 boot_reset() {
517         local ffs typ status
518
519         case "$1" in
520         flash|ram)type="$1"
521                 shift;;
522         *)      echo "turnup: boot_reset($1): invalid type" >&2
523                 return 1;;
524         esac
525
526         ffs="/tmp/flashdisk.$$"
527         mkdir "$ffs" || {
528                 echo "turnup: $1: failed to create temporary directory" >&2
529                 return 1
530         }
531
532         get_flash "$ffs" || {
533                 rmdir "$ffs"
534                 return 1
535         }
536
537         # now try to set the /linuxrc appropriately
538         boot_rootfs "$type" "$ffs"
539         status=$?
540
541         # clean up
542         umount "$ffs"
543         rmdir "$ffs"
544         return $status
545 }
546
547 #
548 # nfs [-i] <root partition> {options}
549 #  Copy the flash file system to the given NFS root partition.
550 nfs() {
551         local init nfsroot new ffs
552
553         init=
554         while test $# -gt 0
555         do
556                 case "$1" in
557                 -i)     init="$1"
558                         shift;;
559                 -f)     force="$1"
560                         shift;;
561                 *)      break;;
562                 esac
563         done
564
565         nfsroot="$1"
566         test -n "$nfsroot" || {
567                 echo "turnup nfs: $nfsroot: NFS root file system required" >&2
568                 return 1
569         }
570         shift
571
572         # make temporary directories for the mount points
573         new="/tmp/rootfs.$$"
574         ffs="/tmp/flashdisk.$$"
575         mkdir "$new" "$ffs" || {
576                 echo "turnup nfs: failed to create temporary directories" >&2
577                 return 1
578         }
579
580         # make sure we can get to the flash file system first
581         get_flash "$ffs" || {
582                 rmdir "$new" "$ffs"
583                 return 1
584         }
585
586         # Now mount the device with the given options, note that specifying
587         # read only is *not* an option, this is important because the boot/disk
588         # script needs a rw file system
589         status=1
590         fst=
591         # These settings for for NFS, something better will probably have to
592         # be done to support other network file systems.
593         nfsopt="nolock,noatime,hard,intr,rsize=1024,wsize=1024"
594         fso="$(fsoptions -o "$nfsopt" "$@")"
595         if mount -o "$nfsopt" "$@" "$nfsroot" "$new"
596         then
597                 fst="$(fstype "$new")"
598                 umount "$new" ||
599                         echo "turnup nfs: $nfsroot($new): umount does not seem to work" >&2
600         fi
601
602         if test -n "$fst" && mount -t "$fst" -o "$fso" "$nfsroot" "$new"
603         then
604                 if :>"$new"/ttt && test -O "$new"/ttt && rm "$new"/ttt
605                 then
606                         if check_rootfs $init "$new" && {
607                                 test -z "$init" || {
608                                         copy_rootfs "$ffs" "$new" &&
609                                         setup_rootfs nfs "$new" "$ffs"/etc/device_table
610                                 }
611                            }
612                         then
613                                 setup_fstab "$new" "$nfsroot" "$fst" "$fso"
614                                 status=0
615                         fi
616                 else
617                         echo "turnup nfs: $nfsroot: partition must be exported no_root_squash" >&2
618                 fi
619
620                 # clean up the disk.  It is worrying if this umount fails!
621                 umount "$new" || test "$force" = "-f" || {
622                         echo "turnup nfs: $nfsroot: umount failed" >&2
623                         if test $status -eq 0
624                         then
625                                 echo "  you must unmount this partition cleanly yourself, then use" >&2
626                                 if test -z "$init"
627                                 then
628                                         echo "  turnup with the -f option to boot from the NFS root" >&2
629                                 else
630                                         echo "  turnup without the -i option to boot from the NFS root" >&2
631                                 fi
632                                 status=1
633                         fi
634                 }
635
636                 # if everything went ok boot from this disk
637                 if test $status -eq 0
638                 then
639                         # the options used are exactly those which worked before.
640                         boot_rootfs nfs "$ffs" 0 "$nfsroot" -t nfs -o "$fso"
641                 fi
642         else
643                 echo "turnup nfs: $nfsroot($*): unable to mount device on $new" >&2
644                 # If it worked first time
645                 if test -n "$fst"
646                 then
647                         echo "  options obtained: -t $fst -o $fso" >&2
648                 fi
649         fi
650
651         # clean up the flash file system
652         umount "$ffs"
653         rmdir "$new" "$ffs"
654         return $status
655 }
656
657 #
658 # fix_hw_addr
659 #  Called when the configuration is invalid to reset /etc/default/sysconf
660 fix_hw_addr() {
661         # first look on the flash disk (ideally this stuff would only
662         # be called from flash, but there is no way of guaranteeing that).
663         local ffsdev ffs mac name force
664
665         case "$1" in
666         -f)     force="$1";;
667         esac
668
669         ffsdev="$(mtblockdev Flashdisk)"
670         test -n "$ffsdev" -a -b "$ffsdev" || {
671                 echo "turnup init: the flash file system device is missing" >&2
672                 echo "  The device (typically /dev/mtdblock4) must exist and" >&2
673                 echo "  it must identify a flash partition called 'Flashdisk'" >&2
674                 echo "  It may be that the /dev directory has not been initialised." >&2
675                 echo "  This script cannot correct this problem." >&2
676                 return 1
677         }
678
679         test -x /etc/init.d/sysconfsetup || {
680                 echo "turnup init: /etc/init.d/sysconfsetup: script not executable" >&2
681                 echo "  or script not present.  turnup init requires this script to" >&2
682                 echo "  exist to correct the initialisation" >&2
683                 return 1
684         }
685
686         # use devio to find out if this *is* the flash disk.
687         ffs=
688         if test "$(devio "<<$ffsdev" prd)" -ne "$(devio '<</etc/init.d/sysconfsetup' prd)"
689         then
690                 # this isn't the flash device
691                 ffs="/tmp/flashdisk.$$"
692                 # make sure we can get to the flash file system first
693                 get_flash "$ffs" || {
694                         rmdir "$ffs"
695                         return 1
696                 }
697
698                 # copy if available
699                 if test -r "$ffs/etc/default/sysconf"
700                 then
701                         cp "$ffs/etc/default/sysconf"
702                         force=
703                 fi
704
705                 umount "$ffs"
706                 rmdir "$ffs"
707         fi
708
709         # if the config is still not valid generate sysconf from the slug
710         # label.
711         config valid && test -z "$force" || {
712                 mac=
713                 until test -n "$mac"
714                 do
715                         echo "turnup init: please find the 'MAC Address' of your NSLU2" >&2
716                         echo "  The required number is on a label on the bottom of the NSLU2" >&2
717                         echo "  It will be something like 'LKG1A2B3C'" >&2
718                         echo -n "Enter the mac address: " >/dev/tty
719                         read name </dev/tty
720                         case "$name" in
721                         [Ll][Kk][Gg][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])
722                                 mac="$(echo "$name" |
723                                         sed -n 's/^...\(..\)\(..\)\(..\)$/00:0F:66:\1:\2:\3/p')";;
724                         [0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f])
725                                 mac="$name"
726                                 name=
727                                 ;;
728                         "")     return 1;;
729                         *)      echo "$name: not recognised as a LinkSys mac address" >&2
730                                 echo "  Enter the LinkSys value or a full Ethernet MAC addrress" >&2
731                                 mac=;;
732                         esac
733
734                         # Now generate the correct sysconf
735                         {       echo '[network]'
736                                 echo "hw_addr=$mac"
737                                 test -n "$name" && echo "default_server_name=$name"
738                         } >/etc/default/sysconf
739                 done
740         }
741
742         # the configuration should be valid now
743         /etc/init.d/sysconfsetup reload
744 }
745
746 #
747 # read_one 'prompt' 'group' 'name'
748 #  read a single value
749 read_one() {
750         local n o
751         o="$(sysval "$2" "$3")"
752         echo -n "$1 [$o]: " >/dev/tty
753         read n </dev/tty
754         test -z "$n" && n="$o"
755         eval "$3='$n'"
756 }
757 #
758 # init_network
759 #  Change the network initialisation
760 init_network() {
761         # fix the root password
762         echo "Please enter a new password for 'root'." >/dev/tty
763         echo "The password must be non-empty for ssh login to succeed!" >/dev/tty
764         passwd
765         # now the network configuration
766         read_one "Host name" network disk_server_name
767         read_one "Domain name" network w_d_name
768         read_one "Boot protocol (dhcp|static)" network bootproto
769         case "$bootproto" in
770         static) read_one "IP address" network ip_addr
771                 read_one "IP netmask" network netmask
772                 read_one "IP gateway" network gateway
773                 read_one "First DNS server" network dns_server1
774                 read_one "Second DNS server" network dns_server2
775                 read_one "Third DNS server" network dns_server3
776                 echo "$ip_addr       $disk_server_name" >> /etc/hosts
777                 ;;
778         dhcp)   sed -i -e "s/localhost\$/localhost $disk_server_name/" /etc/hosts
779                 ;;
780         *)      bootproto=dhcp;;
781         esac
782         #
783         # The other stuff which cannot be changed
784         hw_addr="$(config mac)"
785         lan_interface="$(config iface)"
786         #
787         # Write this out to a new sysconf
788         {       echo "[network]"
789                 echo "hw_addr=$hw_addr"
790                 echo "lan_interface=$lan_interface"
791                 test -n "$disk_server_name" && echo "disk_server_name=$disk_server_name"
792                 test -n "$w_d_name" && echo "w_d_name=$w_d_name"
793                 echo "bootproto=$bootproto"
794                 case "$bootproto" in
795                 static) echo "ip_addr=$ip_addr"
796                         test -n "$netmask" && echo "netmask=$netmask"
797                         test -n "$gateway" && echo "gateway=$gateway"
798                         test -n "$dns_server1" && echo "dns_server1=$dns_server1"
799                         test -n "$dns_server2" && echo "dns_server2=$dns_server2"
800                         test -n "$dns_server3" && echo "dns_server3=$dns_server3"
801                         ;;
802                 esac
803         } >/etc/default/sysconf
804         #
805         # And reload the result
806         /etc/init.d/sysconfsetup reload
807         #
808         # The remove the spurious 'init' motd
809         rm /etc/motd
810 }
811
812 #
813 # Basic command switch (this should be the only thing in this
814 # script which actually does anything!)
815 case "$1" in
816 init)   shift
817         if config valid && test "$1" != -f
818         then
819                 if init_network "$@"
820                 then
821                         echo "turnup init: you must reboot the NSLU2 for the changes to take effect" >&2
822                 else
823                         exit 1
824                 fi
825         else
826                 if fix_hw_addr "$@"
827                 then
828                         echo "turnup init: you must reboot the NSLU2 for the changes to take effect" >&2
829                 else
830                         exit 1
831                 fi
832         fi;;
833 disk)   shift
834         disk "$@";;
835 memstick)
836         shift
837         disk -m "$@" -o noatime;;
838 nfs)    shift
839         nfs "$@";;
840 flash)  boot_reset flash;;
841 ram)    boot_reset ram;;
842 *)      echo "\
843 usage: turnup command [options]
844  commands:
845   help
846     output this help
847   init
848     correct errors in network information
849     initialise network information when DHCP is not available
850     change network information
851   disk [-i] [-s<seconds>] <device> [mount options]
852     With -i make <device> a bootable file system then (with or
853     without -i) arrange for the next reboot to use that device.
854     The device must already be formatted as a file system, with
855     -i it must be completely empty, without it must contain an
856     apparently bootable file system. -s (for example -s5)
857     specifies a delay in seconds to wait at boot time before
858     mounting the device.
859   memstick [-i] <device> [mount options]
860     Behaves as disk however options appropriate to a flash memory
861     stick are automatically added
862   nfs [-i] <nfs mount path> [mount options]
863     <nfs mount path> must be a mountable NFS file system.  With
864     -i the partition must be empty and is initialised with a
865     bootable file system.  Without -i the partition must already
866     contain a bootable file system.  In either case the NFS
867     partition must be available to be mounted without root id
868     sqashing (i.e. root must be root) and it will be selected
869     as the root file system for subsequent reboots.
870     A default set of -o options are provided, additional options
871     may be given on the command line (multiple -o options will
872     be combined into a single -o).
873   flash
874     Revert to booting from the flash disk on next reboot.
875   ram
876     Boot (once) into a ramdisk, subsequent boots will be to
877     the flash file system.
878  disk formatting:
879   The argument to 'nfs' or 'disk' must be an empty partition
880   of sufficient size to hold the root file system (at least
881   16MByte but more is recommended to allow package installation).
882   An appropriate ext3 partition can be made using the command:
883
884     mke2fs -j <device>  # for example: /dev/sda1
885
886   An appropriate NFS partition can be emptied using 'rm', but
887   must be set up (exported) on the NFS server." >&2
888         exit 0;;
889 esac
890 # Exit with return code from command.