Implementation of reflash without RedBoot/upslug.
authorJohn Bowler <jbowler@nslu2-linux.org>
Sat, 11 Jun 2005 00:06:10 +0000 (00:06 +0000)
committerJohn Bowler <jbowler@nslu2-linux.org>
Sat, 11 Jun 2005 00:06:10 +0000 (00:06 +0000)
Very limited testing.
To try it run 'reflash help'.

BKrev: 42aa2af2mr4JkjqtkaV8hSbfxSC9bw

packages/openslug-init/openslug-init-0.10/conffiles [new file with mode: 0644]
packages/openslug-init/openslug-init-0.10/functions
packages/openslug-init/openslug-init-0.10/initscripts/sysconfsetup
packages/openslug-init/openslug-init-0.10/reflash [new file with mode: 0644]
packages/openslug-init/openslug-init-0.10/turnup
packages/openslug-init/openslug-init_0.10.bb

diff --git a/packages/openslug-init/openslug-init-0.10/conffiles b/packages/openslug-init/openslug-init-0.10/conffiles
new file mode 100644 (file)
index 0000000..e69de29
index e69de29..ac8e195 100644 (file)
@@ -0,0 +1,261 @@
+# . this file to load the following utility functions
+#
+# mtdev "name"
+#  return (output) the character device name for flash parition "name"
+#  /proc/mtd has the general form:
+#    dev:    size   erasesize  name
+#    mtd5: 00020000 00020000 "FIS directory"
+#  use this rather than hard-wiring the device because the partition
+#  table can change - looking in /proc/mtd is more reliable.
+mtdev(){
+       sed -n 's!^\(mtd[0-9][0-9]*\):[^"]*"'"$1"'"$!/dev/\1!p' /proc/mtd
+}
+#
+# mtblockdev "name"
+#  as mtdev but output the name of the block (not character) device
+mtblockdev(){
+       sed -n 's!^mtd\([0-9][0-9]*\):[^"]*"'"$1"'"$!/dev/mtdblock\1!p' /proc/mtd
+}
+#
+# mtsize "name"
+#  the size of the partition as a hexadecimal value (with 0x at the front)
+mtsize(){
+       sed -n 's!^mtd[0-9][0-9]*: \([^ ]*\)[^"]*"'"$1"'"$!0x\1!p' /proc/mtd
+}
+#
+# sysvalmatch "section" "name" 'pattern' "configuration file"
+# sysvalof "section" "name" "configuration file"
+# sysval "section" "name"
+#  outputs the value of the SysConf variable 'name' from section 'section',
+#  this is a bit gross, when it gets a match it copies the value to the
+#  hold space, if no match it jumps over the copy, at the end ($) it copies
+#  the hold space to the pattern space and prints the result, thus it only
+#  ever prints the last match
+# BUG FIX: busybox sed doesn't initialise the hold space and crashes if it
+#  is used before initialisation, so temporarily this script does it's own
+#  tail by hand.
+# NOTE: these functions should only be used internally, add entries to 'config'
+#  below if necessary.  This is because 'config' does the defaulting and in the
+#  recovering case (zero or absent SysConf) /etc/default/sysconf only contains
+#  the hw_addr entry!
+sysvalmatch(){
+       # sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^'"$2"'=\('"$3"'\)$/\1/;tH;bE;:H;h;:E;$g;$p' "$4"
+       sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^'"$2"'=\('"$3"'\)$/\1/p' "$4" | sed -n '$p'
+}
+sysvalof(){
+       sysvalmatch "$1" "$2" '.*' "$3"
+}
+sysval(){
+       sysvalof "$1" "$2" /etc/default/sysconf
+}
+#
+# config "value"
+#  convenience callers for specific values to avoid mis-typing in scripts
+#  NOTE: this function does the defaulting, 'sysval' does not!  Validity
+#  of the sysconf file is determined by the presence of the all important
+#  hw_addr.
+config(){
+       local mac
+       mac=
+       test -r /etc/default/sysconf &&
+               mac="$(sysvalmatch network hw_addr '[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]' /etc/default/sysconf)"
+       if test -n "$mac"
+       then
+               case "$1" in
+               mac)    echo "$mac";;
+               host)   if test -n "$(sysval network disk_server_name)"
+                       then
+                               sysval network disk_server_name
+                       elif test -n "$(sysval network default_server_name)"
+                       then
+                               sysval network default_server_name
+                       else
+                               echo "$mac" | sed -n 's/^..:..:..:\(..\):\(..\):\(..\)$/LKG\1\2\3/p'
+                       fi;;
+               domain) sysval network w_d_name;;
+               iface)  if test -n "$(sysval network lan_interface)"
+                       then
+                               sysval network lan_interface
+                       else
+                               echo eth0
+                       fi;;
+               ip)     if test -n "$(sysval network ip_addr)"
+                       then
+                               sysval network ip_addr
+                       else
+                               echo 192.168.1.77
+                       fi;;
+               netmask)sysval network netmask;;
+               gateway)sysval network gateway;;
+               dns)    sysval network dns_server1;;
+               dns2)   sysval network dns_server2;;
+               dns3)   sysval network dns_server3;;
+               boot)   if test -n "$(sysval network bootproto)"
+                       then
+                               sysval network bootproto
+                       else
+                               echo dhcp
+                       fi;;
+               valid)  return 0;;
+               *)      return 1;;
+               esac
+       else
+               # These are the defaults for an invalid mac address, use the compiled
+               # in hardware address.
+               case "$1" in
+               mac)    echo "00:02:B3:02:02:01";;
+               host)   echo "brokenslug";;
+               iface)  echo eth0;;
+               ip)     echo 192.168.1.77;;
+               boot)   echo dhcp;;
+               *)      return 1;;
+               esac
+       fi
+}
+#
+# checkif "iface"
+#  Validate an interface name by making sure that it exists
+#  in /proc/net/dev (and is not lo).  The listing outputs the
+#  interface followed by a :, the check function looks for
+#  something of the form '$1[a-zA-Z0-9]*:' and outputs the
+#  part preceding the ':'
+checkif(){
+       sed -n '/^[     ]*lo:/d;s/^[    ]*\('"$1"'[a-zA-Z0-9]*\):.*$/\1/p;tE;d;:E;q' /proc/net/dev
+}
+#
+# checkmount "mountpoint"
+#  tests an already mounted mountpoint to see whether to attempt to
+#  boot with this as root.  Returns success if it appears ok.
+checkmount(){
+       # basic test for init (the kernel will try to load this)
+       # but require a shell in bin/sh and no .recovery too
+       test    \( ! -f "$1/.recovery" \) -a \
+               \( -d "$1/initrd" -o -d "$1/mnt" \) -a \
+               \( -x "$1/bin/sh" -o -h "$1/bin/sh" \) -a \
+               \( -x "$1/sbin/init" -o -h "$1/sbin/init" -o \
+               -x "$1/etc/init" -o -h "$1/etc/init" -o \
+               -x "$1/bin/init" -o -h "$1/bin/init" \)
+}
+#
+# swivel "new root" "old root"
+#  NOTE: the arguments must be paths relative to /, bad things
+#  will happen if the arguments themselves start with /
+#  Pivot to a new root.  This does all the fancy pivot_root stuff
+#  including closing streams and does a umount /proc - it doesn't
+#  matter if this fails (failure codes are ignored), but if /proc
+#  was mounted it must be restored by the caller on return.
+#  Normally this function never returns!
+#  On return 0,1,2 are connected to /dev/console - this may not
+#  have been true before!
+swivel() {
+       cd "$1"
+       exec <&- >&- 2>&-
+       # This is just-in-case the called mounted /proc and was
+       # unable to close it because of the streams
+       umount /proc 2>/dev/null
+       if pivot_root . "$2"
+       then
+               # everything must move out of the old root, this process
+               # is $2/bin/sh so it must die, IO is redirected
+               # just in case - typically it will be to a device so it
+               # won't hold the old root open.
+               # the exec here is the first point at which the old root
+               # is unused - before the exec regardless of the close of
+               # 0,1,2 above ash still has *this* shell script open!
+               # (it's on fd 10).
+               # init closes all file descriptors, there's no point
+               # supplying it with fds.
+               exec "$2/usr/sbin/chroot" . bin/sh -c "\
+                       test -x sbin/init && exec sbin/init
+                       test -x etc/init && exec etc/init
+                       test -x bin/init && exec bin/init
+                       leds -A +gr1 '!g1'
+                       sleep 10 >/.recovery
+                       sync;sync;sync
+                       exit 1"
+       fi
+       #
+       # recovery - must restore the old root
+       cd "$2"
+       sbin/pivot_root . "$1"
+       # cd is back to $1 - either pivot_root doesn't change it and the
+       # chroot above was not executed, or pivot_root does change it and
+       # has just changed it back!
+       exec <>/dev/console >&0 2>&0
+}
+#
+# ifup "interface"
+#  bring that interface up with the configured ip and other
+#  information
+ifup(){
+       local ip hostname router subnet iface HOSTNAME NETMASK BROADCAST
+
+       iface="$1"
+       ip="$(config ip)"
+       hostname="$(config host)"
+       router="$(config gateway)"
+       broadcast=
+
+       if test -n "$ip"
+       then
+               # only if an ip was specified
+               subnet="$(config netmask)"
+       else
+               ip=192.168.1.77
+       fi
+
+       # First try udhcpc - note that the /boot/udhcpc.script
+       # simply records the values returned and the udhcpc
+       # is not left running so this will only work for
+       # the lease length time!
+       ifconfig "$iface" up
+       test -n "$hostname" && HOSTNAME="-H $hostname"
+       # The script writes the required shell variable assignments
+       # to file descriptor 9
+       eval $(udhcpc -i "$iface" -n -q -r "$ip" $HOSTNAME -s /boot/udhcpc.script 9>&1 >/dev/null)
+
+       test -n "$broadcast" && BROADCAST="broadcast $broadcast"
+       test -n "$subnet" && NETMASK="netmask $subnet"
+
+       if ifconfig "$iface" "$ip" $NETMASK $BROADCAST
+       then
+               for route in $router
+               do
+                       route add default gw "$route" dev "$iface"
+               done
+               return 0
+       else
+               ifconfig "$iface" down
+               return 1
+       fi
+}
+#
+# ifdown "interface"
+#  take the interface down
+ifdown(){
+       ifconfig "$1" down
+}
+#
+# mountflash "flash root directory" {mount options}
+#  Finds and mounts the flash file system on the given directory
+mountflash() {
+       local ffsdev ffsdir
+
+       ffsdir="$1"
+       test -n "$ffsdir" -a -d "$ffsdir" || {
+               echo "$0: mountflash $ffsdir: not a directory (internal error)" >&2
+               return 1
+       }
+       shift
+
+       ffsdev="$(mtblockdev Flashdisk)"
+       test -n "$ffsdev" -a -b "$ffsdev" || {
+               echo "$0: unable to find flash file system to copy ($ffsdev)" >&2
+               return 1
+       }
+       mount -t jffs2 "$@" "$ffsdev" "$ffsdir" || {
+               echo "$0: $ffsdev: unable to mount flash file system on $ffsdir" >&2
+               return 1
+       }
+       return 0
+}
index e69de29..1940b00 100644 (file)
@@ -0,0 +1,229 @@
+#!/bin/sh
+# This script is run once when the system first boots.  Its sole
+# purpose is to create /etc/default/sysconf (the overall system
+# configuration file) and other files derived from this.
+#
+# The script runs immediately after S10checkroot.sh - this is the
+# point at which the rootfs will be mounted rw even if the kernel
+# booted with it ro.
+#
+# rm or mv the file to run this again.  If this is done the
+# following configuration files will be rewritten:
+#
+# /etc/default/sysconf
+# /etc/hostname
+# /etc/defaultdomain
+# /etc/network/interfaces
+# /etc/resolv.conf
+#
+# /etc/default/functions contains useful utility functions - it's
+# in a separate file so that it can be loaded by any script
+. /etc/default/functions
+#
+config valid && test "$1" != reload && exit 0
+#
+# Utility to deal with absence of DNS configuration
+echodns(){
+       local dns
+       if test $# -gt 0
+       then
+               for dns in "$@"
+               do
+                       echo "nameserver $dns"
+               done
+       fi
+}
+#
+# The SysConf device must exist in /dev at this point for this script
+# to work.
+#
+# It is important not to hard-wire the name of the device because of
+# the posibility of changing the flash partition layout.
+#
+# The block device is used here because at present udev does not
+# show the character devices
+sysdev=
+config valid || sysdev="$(mtblockdev SysConf)"
+if test -n "$sysdev" -a -b "$sysdev"
+then
+       # Read the defined part of SysConf into /etc/default/sysconf.
+       # SysConf has lines of two forms:
+       #
+       #  [section]
+       #  name=value
+       #
+       # In practice SysConf also contains other stuff, use the command:
+       #
+       #  devio '<</dev/mtd1;cpb'
+       #
+       # to examine the current settings.  The badly formatted stuff
+       # is removed (to be exact, the sed script selects only lines
+       # which match one of the two above).  The lan interface, which
+       # defaults to ixp0, is changed to the correct value for openslug,
+       # eth0
+       devio "<<$sysdev" cpb fb1,10 | sed -n '/^\[[^][]*\]$/p;
+               s/^lan_interface=ixp0$/lan_interface=eth0/;
+               /^[-a-zA-Z0-9_][-a-zA-Z0-9_]*=/p' >/etc/default/sysconf
+       #
+       # The SysConf must have a hardware id, if it doesn't it has
+       # probably been erased or never set in the first place and the
+       # hardware id is retrieved from the RedBoot partition.  This is
+       # the only thing which cannot be defaulted.
+fi
+#
+# Error recovery: no SysConf or invalid SysConf.  Make a new one from the
+# RedBoot hardware ID information.
+# NOTE: this block of code overwrites the shell script arguments.
+config valid || {
+       reddev="$(mtblockdev RedBoot)"
+       initmac=
+       if test -n "$reddev" -a -b "$reddev"
+       then
+               # The hardware id starts 80 bytes before the end of the
+               # block, the block ends (or should end) with the signature
+               # <4 bytes> sErCoMm <bytes> sErCoMm.  Note that devio 'pf'
+               # empties the stack.
+               set -- $(devio "<<$reddev" '
+                       <= $80-
+                       .= @
+                       pf %02X
+                       A= 5
+                       $( 1
+                               A= @,A1-
+                               pf :%02X
+                       $) A
+                       pn
+                       <=f4+;cp7;pn
+                       <=$7-;cp7;pn')
+               if test $# -eq 3 -a "$2" = sErCoMm -a "$3" = sErCoMm
+               then
+                       initmac="$1"
+               fi
+       fi
+       #
+       # APEX: may need extra code to set initmac here.
+       #
+       if test -n "$initmac"
+       then
+               #
+               # Generate a complete /etc/default/sysconf based on just
+               # one number ;-)
+               {       echo '[network]'
+                       echo "hw_addr=$initmac"
+               } >/etc/default/sysconf
+               #
+               # See /etc/default/functions (the config function) for
+               # the derivation of the rest of the information.
+       fi
+}
+#
+# The config function will now return the correct values - even if sysconf
+# is still missing.  'config valid' says if valid configuration information
+# is available.
+#
+# Set up the 'standard' files in the root file system (these couldn't be set
+# up before because they depend on stuff which RedBoot puts into SysConf from
+# the ID info on the specific machine - in particular the hardware address of
+# eth0, which must be the one assigned for *this* box!)
+#
+# HOSTNAME: defaults to LGK<mac> i.e. something derived from
+# the ethernet hardware.  LinkSys documentation explains how
+# to determine this.  Set by the user in linksys setup software.
+# DOMAINNAME: LinkSys puts this in w_d_name.
+test -n "$(config host)" && config host >/etc/hostname
+domain="$(config domain)"
+test -n "$domain" && echo "$domain" >/etc/defaultdomain
+#
+# Ethernet information.  This goes into /etc/network/interfaces,
+# however this is only used for static setup (and this is not
+# the default).  With dhcp the openslug udhcp script,
+# /etc/udhcpc.d/50default, loads the values from sysconf.  The
+# lan_interface config value must exist for the file to be
+# overwritten here.
+iface="$(config iface)"
+if test -n "$iface"
+then
+       boot="$(config boot)"
+       # Only dhcp and static are supported at present - bootp
+       # support requires installation of appropriate packages
+       # dhcp is the fail-safe
+       case "$boot" in
+       dhcp|static) ;;
+       *)    boot=dhcp;;
+       esac
+       #
+       mac="$(config mac)"
+       ip="$(config ip)"
+       netmask="$(config netmask)"
+       gateway="$(config gateway)"
+       {
+               echo "# /etc/network/interfaces"
+               echo "# configuration file for ifup(8), ifdown(8)"
+               echo "#"
+               echo "# The loopback interface"
+               echo "auto lo"
+               echo "iface lo inet loopback"
+               echo "#"
+               echo "# The NSLU2 built-in ethernet"
+               echo "auto $iface"
+               echo "# Automatically generated from /etc/default/sysconf"
+               if config valid
+               then
+                       echo "# The pre-up option must always be supplied, regardless"
+                       echo "# of configuration, to set the hardware correctly."
+                       echo "# Severe network problems may result if this option is"
+                       echo "# removed."
+                       c=
+               else
+                       echo "# WARNING: improperly configured network interface."
+                       echo "# WARNING: the pre-up line must be corrected or severe"
+                       echo "# WARNING: network problems may result."
+                       c='#'
+                       mac='<WARNING: unknown hardware address>'
+               fi
+               echo "iface $iface inet $boot"
+               echo "${c}      pre-up ifconfig $iface hw ether $mac"
+               # The following are ignored for DHCP but are harmless
+               test -n "$ip"      && echo "    address $ip"
+               test -n "$netmask" && echo "    netmask $netmask"
+               test -n "$gateway" && echo "    gateway $gateway"
+       } >/etc/network/interfaces
+fi
+#
+# The DNS server information gives up to three nameservers, but this
+# currently only binds in the first.
+{
+       test -n "$domain" && echo "search $domain"
+       echodns $(config dns) $(config dns1) $(config dns2)
+} >/etc/resolv.conf
+#
+# Invalid config must be handled, do this by hacking /etc/motd.
+if config valid
+then
+       echo "Host name:           $(config host)"
+       echo "Host ID:             $mac"
+       echo "Network boot method: $boot"
+       case "$boot" in
+       static) echo "Host IP address:     $ip";;
+       esac
+       echo "Use 'turnup init' to reset the configuration"
+       echo "Use 'turnup disk|nfs -i <device> options to initialise a non-flash root"
+       echo "Use 'turnup help' for more information"
+else
+       echo "+=====================================================================+"
+       echo "|                   +-----------------------+                         |"
+       echo "|                   | INITIALISATION FAILED |                         |"
+       echo "|                   +-----------------------+                         |"
+       echo "|                                                                     |"
+       echo "| This machine has been booted with a temporary ethernet id           |"
+       echo "| The initialisation failed because the machine id was not available  |"
+       echo "| within the flash memory of the NSLU2.  You must run:                |"
+       echo "|                                                                     |"
+       echo "|       turnup init                                                   |"
+       echo "|                                                                     |"
+       echo "| To correct this problem.  Severe network problems may occur if this |"
+       echo "| is not done.                                                        |"
+       echo "+=====================================================================+"
+fi >/etc/motd
+
+exit 0
diff --git a/packages/openslug-init/openslug-init-0.10/reflash b/packages/openslug-init/openslug-init-0.10/reflash
new file mode 100644 (file)
index 0000000..e69de29
index d22e15c..a33a58a 100644 (file)
@@ -385,24 +385,6 @@ boot_rootfs() {
        return 0
 }
 
-#
-# mountflash <flash root directory>
-#  Finds and mounts the flash file system
-mountflash() {
-       local ffsdev
-
-       ffsdev="$(mtblockdev Flashdisk)"
-       test -n "$ffsdev" -a -b "$ffsdev" || {
-               echo "turnup disk: unable to find flash file system to copy ($ffsdev)" >&2
-               return 1
-       }
-       mount -t jffs2 "$ffsdev" "$1" || {
-               echo "turnup disk: $ffsdev: unable to mount flash file system on $1" >&2
-               return 1
-       }
-       return 0
-}
-
 #
 # disk [-m] [-i] [-s<time>] <device> {options}
 #  Carefully copy the flash file system to the named device.
@@ -653,13 +635,180 @@ nfs() {
        return $status
 }
 
+#
+# fix_hw_addr
+#  Called when the configuration is invalid to reset /etc/default/sysconf
+fix_hw_addr() {
+       # first look on the flash disk (ideally this stuff would only
+       # be called from flash, but there is no way of guaranteeing that).
+       local ffsdev ffs mac name force
+
+       case "$1" in
+       -f)     force="$1";;
+       esac
+
+       ffsdev="$(mtblockdev Flashdisk)"
+       test -n "$ffsdev" -a -b "$ffsdev" || {
+               echo "turnup init: the flash file system device is missing" >&2
+               echo "  The device (typically /dev/mtdblock4) must exist and" >&2
+               echo "  it must identify a flash partition called 'Flashdisk'" >&2
+               echo "  It may be that the /dev directory has not been initialised." >&2
+               echo "  This script cannot correct this problem." >&2
+               return 1
+       }
+
+       test -x /etc/init.d/sysconfsetup || {
+               echo "turnup init: /etc/init.d/sysconfsetup: script not executable" >&2
+               echo "  or script not present.  turnup init requires this script to" >&2
+               echo "  exist to correct the initialisation" >&2
+               return 1
+       }
+
+       # use devio to find out if this *is* the flash disk.
+       ffs=
+       if test "$(devio "<<$ffsdev" prd)" -ne "$(devio '<</etc/init.d/sysconfsetup' prd)"
+       then
+               # this isn't the flash device
+               ffs="/tmp/flashdisk.$$"
+               # make sure we can get to the flash file system first
+               mountflash "$ffs" || {
+                       rmdir "$ffs"
+                       return 1
+               }
+
+               # copy if available
+               if test -r "$ffs/etc/default/sysconf"
+               then
+                       cp "$ffs/etc/default/sysconf"
+                       force=
+               fi
+
+               umount "$ffs"
+               rmdir "$ffs"
+       fi
+
+       # if the config is still not valid generate sysconf from the slug
+       # label.
+       config valid && test -z "$force" || {
+               mac=
+               until test -n "$mac"
+               do
+                       echo "turnup init: please find the 'MAC Address' of your NSLU2" >&2
+                       echo "  The required number is on a label on the bottom of the NSLU2" >&2
+                       echo "  It will be something like 'LKG1A2B3C'" >&2
+                       echo -n "Enter the mac address: " >/dev/tty
+                       read name </dev/tty
+                       case "$name" in
+                       [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])
+                               mac="$(echo "$name" |
+                                       sed -n 's/^...\(..\)\(..\)\(..\)$/00:0F:66:\1:\2:\3/p')";;
+                       [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])
+                               mac="$name"
+                               name=
+                               ;;
+                       "")     return 1;;
+                       *)      echo "$name: not recognised as a LinkSys mac address" >&2
+                               echo "  Enter the LinkSys value or a full Ethernet MAC addrress" >&2
+                               mac=;;
+                       esac
+
+                       # Now generate the correct sysconf
+                       {       echo '[network]'
+                               echo "hw_addr=$mac"
+                               test -n "$name" && echo "default_server_name=$name"
+                       } >/etc/default/sysconf
+               done
+       }
+
+       # the configuration should be valid now
+       /etc/init.d/sysconfsetup reload
+}
+
+#
+# read_one 'prompt' 'group' 'name'
+#  read a single value
+read_one() {
+       local n o
+       o="$(sysval "$2" "$3")"
+       echo -n "$1 [$o]: " >/dev/tty
+       read n </dev/tty
+       test -z "$n" && n="$o"
+       eval "$3='$n'"
+}
+#
+# init_network
+#  Change the network initialisation
+init_network() {
+       # fix the root password
+       echo "Please enter a new password for 'root'." >/dev/tty
+       echo "The password must be non-empty for ssh login to succeed!" >/dev/tty
+       passwd
+       # now the network configuration
+       read_one "Host name" network disk_server_name
+       read_one "Domain name" network w_d_name
+       read_one "Boot protocol (dhcp|static)" network bootproto
+       case "$bootproto" in
+       static) read_one "IP address" network ip_addr
+               read_one "IP netmask" network netmask
+               read_one "IP gateway" network gateway
+               read_one "First DNS server" network dns_server1
+               read_one "Second DNS server" network dns_server2
+               read_one "Third DNS server" network dns_server3
+               ;;
+       dhcp)   ;;
+       *)      bootproto=dhcp;;
+       esac
+       #
+       # The other stuff which cannot be changed
+       hw_addr="$(config mac)"
+       lan_interface="$(config iface)"
+       #
+       # Write this out to a new sysconf
+       {       echo "[network]"
+               echo "hw_addr=$hw_addr"
+               echo "lan_interface=$lan_interface"
+               test -n "$disk_server_name" && echo "disk_server_name=$disk_server_name"
+               test -n "$w_d_name" && echo "w_d_name=$w_d_name"
+               echo "bootproto=$bootproto"
+               case "$bootproto" in
+               static) echo "ip_addr=$ip_addr"
+                       test -n "$netmask" && echo "netmask=$netmask"
+                       test -n "$gateway" && echo "gateway=$gateway"
+                       test -n "$dns_server1" && echo "dns_server1=$dns_server1"
+                       test -n "$dns_server2" && echo "dns_server2=$dns_server2"
+                       test -n "$dns_server3" && echo "dns_server3=$dns_server3"
+                       ;;
+               esac
+       } >/etc/default/sysconf
+       #
+       # And reload the result
+       /etc/init.d/sysconfsetup reload
+       #
+       # The remove the spurious 'init' motd
+       rm /etc/motd
+}
+
 #
 # Basic command switch (this should be the only thing in this
 # script which actually does anything!)
 case "$1" in
 init)  shift
-       echo "turnup init: NYI" >&2
-       exit 1;;
+       if config valid && test "$1" != -f
+       then
+               if init_network "$@"
+               then
+                       echo "turnup init: you must reboot the NSLU2 for the changes to take effect" >&2
+               else
+                       exit 1
+               fi
+       else
+               if fix_hw_addr "$@"
+               then
+                       echo "turnup init: you must reboot the NSLU2 for the changes to take effect" >&2
+               else
+                       exit 1
+               fi
+       fi;;
 disk)  shift
        disk "$@";;
 memstick)
@@ -675,7 +824,9 @@ usage: turnup command [options]
   help
     output this help
   init
+    correct errors in network information
     initialise network information when DHCP is not available
+    change network information
   disk [-i] [-s<seconds>] <device> [mount options]
     With -i make <device> a bootable file system then (with or
     without -i) arrange for the next reboot to use that device.
index 576fbb5..7b366b2 100644 (file)
@@ -3,7 +3,7 @@ SECTION = "console/network"
 LICENSE = "GPL"
 DEPENDS = "base-files devio"
 RDEPENDS = "busybox devio"
-PR = "r28"
+PR = "r29"
 
 SRC_URI = "file://linuxrc \
           file://boot/flash \
@@ -21,17 +21,18 @@ SRC_URI = "file://linuxrc \
           file://initscripts/sysconfsetup \
           file://initscripts/umountinitrd.sh \
           file://functions \
+          file://conffiles \
           file://turnup \
+          file://reflash \
           file://modprobe.conf \
           file://leds.h \
           file://leds.c \
-          file://kern_header.c \
-          file://update-kernel"
+          "
 
 SBINPROGS = "leds"
-USRSBINPROGS = "kern_header"
+USRSBINPROGS = ""
 CPROGS = "${USRSBINPROGS} ${SBINPROGS}"
-SCRIPTS = "turnup update-kernel"
+SCRIPTS = "turnup reflash"
 BOOTSCRIPTS = "flash disk nfs ram network udhcpc.script"
 INITSCRIPTS = "syslog.buffer syslog.file syslog.network zleds\
        leds_startup rmrecovery sysconfsetup umountinitrd.sh"
@@ -97,6 +98,7 @@ do_install() {
        done
 
        # Configuration files
+       install -m 0644 conffiles ${D}${sysconfdir}/default
        install -m 0644 modprobe.conf ${D}${sysconfdir}/
 
        set +ex
@@ -137,4 +139,4 @@ FILES_${PN} = "/"
 
 # It is bad to overwrite /linuxrc as it puts the system back to
 # a flash boot (and the flash has potentially not been upgraded!)
-CONFFILES_${PN} = "${sysconfdir}/modprobe.conf /linuxrc"
+CONFFILES_${PN} = "${sysconfdir}/modprobe.conf /linuxrc ${sysconfdir}/default/conffiles"