From ce73cafcd4cf4fe1e637d9636780c3d3609998ca Mon Sep 17 00:00:00 2001 From: John Bowler Date: Sun, 29 Jan 2006 10:33:38 +0000 Subject: slugos-init: update for new LEDs, turnup save/restore suppport in 0.10 - /sbin/leds is now a script which uses /sys/class/leds All scripts are not in /sbin /sbin/sysconf does SysConf reading and now implements save/restore of the system configuration. turnup, reflash and sysconfsetup use /sbin/sysconf as appropriate Unused files removed --- packages/slugos-init/files/boot/disk | 4 +- packages/slugos-init/files/boot/flash | 18 +- packages/slugos-init/files/boot/network | 11 +- packages/slugos-init/files/boot/nfs | 3 +- packages/slugos-init/files/boot/ram | 5 +- packages/slugos-init/files/conffiles | 2 +- packages/slugos-init/files/functions | 202 +++--- .../slugos-init/files/initscripts/sysconfsetup | 239 +------ .../slugos-init/files/initscripts/umountinitrd.sh | 30 +- packages/slugos-init/files/initscripts/zleds | 77 +- packages/slugos-init/files/kern_header.c | 47 -- packages/slugos-init/files/leds | 214 ++++++ packages/slugos-init/files/leds.c | 190 ----- packages/slugos-init/files/leds.h | 21 - packages/slugos-init/files/linuxrc | 146 ---- packages/slugos-init/files/reflash | 204 ++---- packages/slugos-init/files/sysconf | 780 +++++++++++++++++++++ packages/slugos-init/files/turnup | 161 ++--- packages/slugos-init/files/update-kernel | 82 --- packages/slugos-init/slugos-init_0.10.bb | 16 +- 20 files changed, 1290 insertions(+), 1162 deletions(-) delete mode 100644 packages/slugos-init/files/kern_header.c create mode 100644 packages/slugos-init/files/leds delete mode 100644 packages/slugos-init/files/leds.c delete mode 100644 packages/slugos-init/files/leds.h delete mode 100755 packages/slugos-init/files/linuxrc create mode 100644 packages/slugos-init/files/sysconf delete mode 100755 packages/slugos-init/files/update-kernel (limited to 'packages') diff --git a/packages/slugos-init/files/boot/disk b/packages/slugos-init/files/boot/disk index ede33a3ee6..e8d1f5245b 100755 --- a/packages/slugos-init/files/boot/disk +++ b/packages/slugos-init/files/boot/disk @@ -3,14 +3,14 @@ # must be given) using options from the rest of # the command line. # -/sbin/leds -A '!gr' -# # Use the standard init path (see /etc/init.d/rcS) export PATH=/sbin:/bin:/usr/sbin:/usr/bin # # Load the helper functions . /etc/default/functions # +leds boot system +# if test -n "$1" then device="$1" diff --git a/packages/slugos-init/files/boot/flash b/packages/slugos-init/files/boot/flash index e0bcebc9b8..12729d7b5d 100755 --- a/packages/slugos-init/files/boot/flash +++ b/packages/slugos-init/files/boot/flash @@ -1,14 +1,14 @@ #!/bin/sh # boot from the current (flash) root partition -# nothing need be done, make the power led flash -# amber to indicate runlevel S -/sbin/leds -A '!gr' -exec /sbin/init +# nothing need be done apart from setting the +# system LED status correctly +. /etc/default/functions +leds beep +leds boot system +test -x /sbin/init && exec /sbin/init # fallback if /sbin/init has been deleted (bad!) -# flashing amber/red - failed early boot -# disk lights flashing: failed in flash boot! -/sbin/leds +A '!g12' +leds boot system panic exec <>/dev/console >&0 2>&0 -exec /sbin/sulogin -exec /bin/sh +test -x /sbin/sulogin && exec /sbin/sulogin +test -x /bin/sh && exec /bin/sh exit 1 diff --git a/packages/slugos-init/files/boot/network b/packages/slugos-init/files/boot/network index 02b226d1f3..599250e744 100755 --- a/packages/slugos-init/files/boot/network +++ b/packages/slugos-init/files/boot/network @@ -11,15 +11,6 @@ # Now all the information for booting should be in the configuration # file. Config the loopback and network interfaces. ifconfig lo 127.0.0.1 up -mac="$(config mac)" iface="$(config iface)" -if test -n "$mac" -a -n "$iface" -a "$mac" != "00:00:00:00:00:00" -a "$mac" != "FF:FF:FF:FF:FF:FF" -then - if ifconfig "$iface" hw ether "$mac" && - ifup "$iface" - then - exit 0 - fi -fi +test -n "$iface" && ifup "$iface" # exit code is true only if the interface config has succeeded -exit 1 diff --git a/packages/slugos-init/files/boot/nfs b/packages/slugos-init/files/boot/nfs index 534d8b7cb0..5f1cbbe323 100755 --- a/packages/slugos-init/files/boot/nfs +++ b/packages/slugos-init/files/boot/nfs @@ -3,7 +3,8 @@ # must be given) using options from the rest of # the command line. # -/sbin/leds -A '!gr' +. /etc/default/functions +leds boot system # # Use the standard init path (see /etc/init.d/rcS) export PATH=/sbin:/bin:/usr/sbin:/usr/bin diff --git a/packages/slugos-init/files/boot/ram b/packages/slugos-init/files/boot/ram index 66d46a7089..42ff8329f9 100755 --- a/packages/slugos-init/files/boot/ram +++ b/packages/slugos-init/files/boot/ram @@ -3,14 +3,15 @@ # must be given) using options from the rest of # the command line. # -/sbin/leds -A '!gr' -# # Use the standard init path (see /etc/init.d/rcS) export PATH=/sbin:/bin:/usr/sbin:/usr/bin # # Load the helper functions . /etc/default/functions # +leds beep double +leds boot system +# if test -n "$1" then device="$1" diff --git a/packages/slugos-init/files/conffiles b/packages/slugos-init/files/conffiles index 51a8091b1e..68dd26d897 100644 --- a/packages/slugos-init/files/conffiles +++ b/packages/slugos-init/files/conffiles @@ -25,7 +25,7 @@ preserve etc/.configured preserve etc/TZ diff etc/default/conffiles diff etc/default/devpts -diff etc/default/rcS +preserve etc/default/rcS preserve etc/default/sysconf diff etc/default/usbd preserve etc/defaultdomain diff --git a/packages/slugos-init/files/functions b/packages/slugos-init/files/functions index e90f03aead..d7e5c9905a 100755 --- a/packages/slugos-init/files/functions +++ b/packages/slugos-init/files/functions @@ -1,5 +1,41 @@ +#!/bin/sh # . this file to load the following utility functions # +# hardware +# the 'Hardware' string from cpuinfo +hardware(){ + sed -n 's!^Hardware *: !!p' /proc/cpuinfo +} +# +# machine +# outputs an identifier of the current machine - i.e. the board +# slugos is running on. +machine(){ + case "$(hardware)" in + *Coyote*) echo coyote;; + *IXDPG425*) echo ixdpg425;; + *WRV54G*) echo wrv54g;; + *IXDP425*) echo ixdp425;; + *IXDP465*) echo ixdp465;; + *IXCDP1100*) echo ixcdp1100*;; + *Avila*) echo avila;; + *Loft*) echo loft;; + *NAS?100d*) echo nas100d;; + *NSLU2*) echo nslu2;; + *) echo unknown;; + esac +} +# +# load_functions "source" +# load the functions in '/sbin/source' - relies on /sbin/source being +# a shell script and having support for this function. +load_functions(){ + test -n "$1" -a -x "/sbin/$1" && . "/sbin/$1" || { + echo "$0: /sbin/$1: script not found" >&2 + return 1 + } +} +# # mtdev "name" # return (output) the character device name for flash parition "name" # /proc/mtd has the general form: @@ -27,90 +63,81 @@ mtsize(){ # 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. +# if there are multiple definitions only the last is output # 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! +# below if necessary. This is because 'config' does the defaulting. 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 + test -r "$config_root/etc/default/sysconf" && + sysvalof "$1" "$2" "$config_root/etc/default/sysconf" +} +# +# syssection "section" +# outputs all the values from the given section changed to the format "name value" +# (i.e. the '=' is dropped). +syssection(){ + test -r "$config_root/etc/default/sysconf" && + sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^\([^=]*\)=\(.*\)$/\1 \2/p' "$config_root/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. +# NOTE: this function does the defaulting, 'sysval' does not! +# config_root: if set this will override the root where config/sysval +# looks for /etc/default/sysconf 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 + mac="$(test -r /proc/net/maclist && + sed -n '/^[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]$/p' /proc/net/maclist | + sed -n 1p)" + # + case "$1" in + mac) test -n "$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 + elif test -n "$mac" + then + echo "$mac" | sed -n 's/^\(..\):\(..\):\(..\):\(..\):\(..\):\(..\)$/slug\1\2\3\4\5\6/p' + else + # because we want the name to remain constant: + echo "brokenslug" + 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) test -r "$config_root/etc/default/sysconf" -a -n "$mac";; + *) return 1;; + esac } # # checkif "iface" @@ -130,11 +157,13 @@ 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 \ + \( -d "$1/mnt" \) -a \ \( -x "$1/bin/sh" -o -h "$1/bin/sh" \) -a \ + \( -x "$1/usr/sbin/chroot" -o -h "$1/usr/sbin/chroot" -o \ + -x "$1/sbin/chroot" -o -h "$1/sbin/chroot" \) -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" \) + -x "$1/etc/init" -o -h "$1/etc/init" -o \ + -x "$1/bin/init" -o -h "$1/bin/init" \) } # # swivel "new root" "old root" @@ -147,7 +176,7 @@ checkmount(){ # Normally this function never returns! # On return 0,1,2 are connected to /dev/console - this may not # have been true before! -swivel() { +swivel(){ cd "$1" exec <&- >&- 2>&- # This is just-in-case the called mounted /proc and was @@ -169,11 +198,26 @@ swivel() { # linux / is already . when the command is executed # therefore it is essential to use the local (new root) # chroot to ensure it gets the correct shared libraries. - exec usr/sbin/chroot . bin/sh -c "\ + if test -x usr/sbin/chroot -o -h usr/sbin/chroot + then + chroot=usr/sbin/chroot + elif test -x sbin/chroot -o -h sbin/chroot + then + chroot=sbin/chroot + else + chroot=chroot + fi + # + exec "$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' + mount -t sysfs sysfs /mnt + echo -n timer >/mnt/class/leds/ready/trigger + echo -n timer >/mnt/class/leds/status/trigger + echo -n 80 >/mnt/class/leds/ready/frequency + echo -n 80 >/mnt/class/leds/status/frequency + umount /mnt sleep 10 >/.recovery sync;sync;sync exit 1" @@ -245,7 +289,7 @@ ifdown(){ # # mountflash "flash device" "flash root directory" {mount options} # Finds and mounts the flash file system on the given directory -mountflash() { +mountflash(){ local ffsdev ffsdir ffsdev="$1" @@ -272,7 +316,7 @@ mountflash() { # umountflash [-r] "flash device" # unmount any instance of the given flash device, if -r is specified a mount on # root is an error, otherwise a mount on root is ignored (and remains). -umountflash() { +umountflash(){ local rootok ffsno ffsdev rootok=1 case "$1" in @@ -324,7 +368,7 @@ umountflash() { } # ffs_umount &2 + echo "$0: umount $ffsdev from all mount points then re-run $0" >&2 return 1 } diff --git a/packages/slugos-init/files/initscripts/sysconfsetup b/packages/slugos-init/files/initscripts/sysconfsetup index 4111633a2b..a4f9074d9c 100644 --- a/packages/slugos-init/files/initscripts/sysconfsetup +++ b/packages/slugos-init/files/initscripts/sysconfsetup @@ -7,225 +7,40 @@ # 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: +# rm or mv the file (/etc/default/sysconf) to recreate it, run this +# script with the reload option to overwrite the system files. The +# configuration files described in sysconf_reload (in +# /sbin/sysconf) will be overwritten on reload. # -# /etc/default/sysconf -# /etc/hostname -# /etc/defaultdomain -# /etc/network/interfaces -# /etc/resolv.conf +# start: standard startup, do a complete (auto) restore if necessary +# reinit: always do a complete auto restore +# reload: just reload sysconf (no config files!) # # /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 +load_functions sysconf || exit 1 # -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 '</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 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 +case "$1" in +start) test -s /etc/default/sysconf || { + if sysconf_read 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 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 slugos 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= + if sysconf_valid + then + sysconf_restore auto + else + sysconf_reload + fi 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='' + sysconf_default + sysconf_reload 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 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 + };; + +reload) test -s /etc/default/sysconf || sysconf_read || sysconf_default + sysconf_reload;; + +reinit) sysconf_restore auto;; -exit 0 +*) ;; +esac diff --git a/packages/slugos-init/files/initscripts/umountinitrd.sh b/packages/slugos-init/files/initscripts/umountinitrd.sh index da39b425f8..9cb1f7a25d 100644 --- a/packages/slugos-init/files/initscripts/umountinitrd.sh +++ b/packages/slugos-init/files/initscripts/umountinitrd.sh @@ -4,15 +4,21 @@ # if the directory /initrd is not present, if this fails # then the /initrd is mounted and we want to remount that # ro - this works round the shutdown -r hang problem -umount /mnt 2>/dev/null || { - # need the device for a remount - . /etc/default/functions - ffspart=Flashdisk - ffsdev="$(mtblockdev $ffspart)" - if test -n "$ffsdev" -a -b "$ffsdev" - then - mount -o remount,ro "$ffsdev" /initrd - else - echo "Flashdisk: $ffsdev: flash device not found" >&2 - fi -} +. /etc/default/functions +while read device directory remainder +do + case "$directory" in + /mnt) echo "InitRD: unmount initrd on /mnt" >&2 + umount /mnt;; + /initrd)# need the device for a remount + ffspart=Flashdisk + ffsdev="$(mtblockdev $ffspart)" + echo "InitRD: remount $ffdev read-only on /initrd" >&2 + if test -n "$ffsdev" -a -b "$ffsdev" + then + mount -o remount,ro "$ffsdev" /initrd + else + echo "Flashdisk: $ffsdev: flash device not found" >&2 + fi;; + esac +done &2 - echo s;; + echo system;; esac } -# Make the named LED do something -flash(){ - echo timer >/sys/class/leds/"$1"/trigger - echo 200 >/sys/class/leds/"$1"/frequency -} -on(){ - echo none >/sys/class/leds/"$1"/trigger - echo 100 >/sys/class/leds/"$1"/brightness -} -off(){ - echo none >/sys/class/leds/"$1"/trigger - echo 0 >/sys/class/leds/"$1"/brightness -} - -test -d /sys/class/leds/ready && case "$1" in -start) if test -d /sys/class/leds/status - then - case "$(state "$runlevel")" in - s) on status - on ready;; - u) off status - on ready;; - esac - else - on ready - fi;; -stop) if test -d /sys/class/leds/status - then - case "$(state "$previous")$(state "$runlevel")" in - ss) flash status - flash ready;; - su|us) flash status - on ready;; - uu) off status - flash ready;; - esac - else - flash ready - fi;; +case "$1" in +start) leds "$(state "$runlevel")";; +stop) leds boot "$(state "$runlevel")";; *) echo "led change: $1: command ignored" >&2;; esac - -exit 0 diff --git a/packages/slugos-init/files/kern_header.c b/packages/slugos-init/files/kern_header.c deleted file mode 100644 index 73b46eec0c..0000000000 --- a/packages/slugos-init/files/kern_header.c +++ /dev/null @@ -1,47 +0,0 @@ - -#include -#include -#include -#include - - -int main(int argc, char **argv) -{ - struct stat sbuf; - char *devtype; - FILE *headerfile; - unsigned int header[4]; - - - if (argc != 3) { - fprintf(stderr, "usage: %s NSLU2_kernel_file_name prepend_header_filename\nThis program builds a 16 byte header which can be prepended to a NSLU2 Kernel for reflashing\n", argv[0]); - exit (1); - } - - if (stat(argv[1], &sbuf) < 0) { - fprintf(stderr, "%s: stat: %s\n", argv[1], strerror(errno)); - exit (1); - } - - /* printf ("File %s is %d bytes long\n", argv[1], sbuf.st_size); */ - if ((headerfile=fopen(argv[2],"wb"))==NULL) - { - fprintf(stderr,"Error opening file\n"); - exit (1); - } - - if ((sbuf.st_size + 16) > 0x100000) { - fprintf(stderr,"Error Kernel + Header is > 1 MB\n"); - exit (1); - } - - header[0] = (unsigned int)sbuf.st_size + 16; - header[1] = 0; - header[2] = 0; - header[3] = 0; - if (!fwrite(&header, sizeof(unsigned int), 4, headerfile)) - fprintf(stderr,"Error write to headerfile: %s\n", strerror(errno)); - - fclose(headerfile); -} - diff --git a/packages/slugos-init/files/leds b/packages/slugos-init/files/leds new file mode 100644 index 0000000000..8132a22046 --- /dev/null +++ b/packages/slugos-init/files/leds @@ -0,0 +1,214 @@ +#!/bin/sh +# leds +# +# utilities to manipulate the settings of the system leds +# +# load the utility functions unless this script is being called +# just to load its own functions. +test "$1" != leds && { + . /etc/default/rcS + . /etc/default/functions +} + +# +# led_set led-dir off|on|slow|fast|panic|blink|flash|user|* +# set the given LED (expressed as a directory) to the +# given status. USER_LED may be set to indicate how to +# handle the 'user' setting. +led_user_default(){ + case "$(machine)" in + nslu2) echo -n "cpu-idle";; + *) echo -n "cpu-activity";; + esac +} +# +led_set(){ + local setting + # expect led-dir state + if test -d "$1" + then + setting="$2" + case "$setting" in + user) if test -n "$USER_LED" + then + setting="$USER_LED" + else + setting="$(led_user_default)" + fi;; + esac + + case "$setting" in + off|on) echo -n none + + case "$setting" in + on) echo -n 100;; + off) echo -n 0;; + esac >"$1/brightness";; + + slow|fast|panic|blink|flash) + echo -n timer + + case "$setting" in + flash) echo -n 727;; + blink) echo -n 72;; + slow) echo -n 400;; + fast) echo -n 100;; + panic) echo -n 50;; + esac >"$1/frequency" + + case "$setting" in + flash) echo -n 10;; + blink) echo -n 1000;; + *) echo -n 100;; + esac >"$1/duty_cycle";; + + cpu-idle) echo -n cpu-idle + # these settings work well on NSLU2 + echo -n 80 >"$1/frequency" + echo -n 10 >"$1/duty_cycle";; + + *) echo -n "$setting";; + esac >"$1/trigger" + else + echo "leds: $1: no such directory" >&2 + return 1 + fi +} + +# +# sysled [boot] system|user|singleuser|shutdown [error|panic|*] +# set the system LEDs to indicate the given boot state, the function +# will temporarily mount sysfs is necessary (using /mnt) +# +# the cases for two LEDs (ready+status) +sysled_readystatus(){ + local ready status + # expect dir [boot](system|user) [error|panic] + case "$3" in + error) ready=fast; status=off;; + panic) ready=fast; status=fast;; + *) case "$2" in + bootsystem) ready=slow; status=slow;; + system) ready=on; status=on;; + bootuser) ready=on; status=slow;; + user) ready=user; status=off;; + bootsingleuser) ready=on; status=slow;; + singleuser) ready=user; status=user;; + bootshutdown) ready=on; status=slow;; + shutdown) ready=slow; status=on;; + esac;; + esac + + led_set "$1/ready" "$ready" + led_set "$1/status" "$status" +} +# +# the cases for one LED (just ready) +sysled_ready(){ + local ready + # expect dir [boot](system|user) [error|panic] + case "$3" in + error) ready=fast;; + panic) ready=panic;; + *) case "$2" in + bootsystem) ready=flash;; + system) ready=blink;; + bootuser) ready=slow;; + user) ready=user;; + bootsingleuser) ready=flash;; + singleuser) ready=blink;; + bootshutdown) ready=slow;; + shutdown) ready=blink;; + esac;; + esac + + led_set "$1/ready" "$ready" +} +# +sysled(){ + local mp st boot isst + mp=/sys + st=1 + boot= + + # validate arguments + if test "$1" = boot + then + shift + boot=boot + fi + case "$1" in + system|user|singleuser|shutdown) :;; + *) echo "sysled: unknown option '$1'" >&2 + echo " usage: sysled [boot] system|user|singleuser|shutdown [error|panic|*]" >&2 + return 1;; + esac + + if test ! -d "$mp/class/leds" && mount -t sysfs sysfs /mnt + then + mp=/mnt + fi + # + # check for the 'ready' LED - otherwise do nothing + if test -d "$mp/class/leds/ready" + then + if test -d "$mp/class/leds/status" + then + sysled_readystatus "$mp/class/leds" $boot"$@" + else + sysled_ready "$mp/class/leds" $boot"$@" + fi + fi + # + # clean up + test "$mp" = /mnt && umount /mnt + return "$st" +} + +# +# beep [double] +# emit a beep, or a double beep +# dummy - at present does nothing +beep(){ + return 0 +} + +# +# leds_help +# be helpful +# leds off|on|slow|fast|panic|blink|flash|user|* +# leds [boot] system|user|singleuser|shutdown [error|panic|*] +leds_help(){ + echo "leds: change the setting of the LEDs" >&2 + echo " usage:" >&2 + echo " leds [boot] system|user|singleuser|shutdown [error|panic|*]" >&2 + echo " set leds during system boot to indicate a particular boot" >&2 + echo " state. 'boot' means that the system is transitioning to" >&2 + echo " the new state. 'error' or 'panic' means a (potentially)" >&2 + echo " recoverable error or an unrecoverable error ('panic') has" >&2 + echo " occured." >&2 + echo " off|on|slow|fast|panic|blink|flash|user|*" >&2 + echo " set the named led to the given display, an arbitrary led" >&2 + echo " trigger may be given. 'user' will use the default specified" >&2 + echo " in USER_LED from /etc/default/rcS, if not specified a cpu" >&2 + echo " activity setting appropriate to the machine is selected" >&2 + echo " beep [double]" >&2 + echo " if possible cause the machine to emit a beep" >&2 +} + +# +# the real command, if required +case "$1" in +boot|system|user|singleuser|shutdown) + sysled "$@";; + +beep) beep "$@";; + +"") leds_help;; +help) leds_help;; + +leds) # just load the functions + ;; + +*) led_set /sys/class/leds/"$@" +esac diff --git a/packages/slugos-init/files/leds.c b/packages/slugos-init/files/leds.c deleted file mode 100644 index e2120ae5d6..0000000000 --- a/packages/slugos-init/files/leds.c +++ /dev/null @@ -1,190 +0,0 @@ - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include "leds.h" - - static int leds; - static int reset; - static int verbose = 0; - enum { - off=0, on=1, blink, unknown, transition=unknown - }; - - - void init_leds(void) - { - int i; - if ((leds = open("/dev/leds", O_RDWR)) < 0) { - int e1 = errno; - if (e1 != ENOENT) { - - fprintf(stderr,"Error: Could not open LEDS device file '/dev/leds' : %s\n", - strerror(e1)); - if(e1 == EACCES) - fprintf(stderr,"Run as root\n"); - exit(1); - } - } - - if (verbose) - printf("leds: initialized.\n"); - } - - void led_ioctl( int cmd, int num ) - { - int i, st; - - if (ioctl(leds, cmd, num) < 0) { - int e1 = errno; - fprintf(stderr, "leds: ioctl(%d,%d): failed to set leds: %s\n", - cmd, num, strerror(e1)); - exit(1); - } - } - - void led_set( int led, int state ) - { - switch (state) { - case off: if (!reset) led_ioctl(N2_LM_OFF, led); break; - case on: led_ioctl(N2_LM_ON, led); break; - case blink: /* Ensure any previous timer gets deleted first and that - * the LED is in a well known state. - */ - if (!reset) led_ioctl(N2_LM_OFF, led); - led_ioctl(N2_LM_BLINK, led); break; - } - } - - int led( int ch ) { - switch (ch) { - case 'r': return LED_RS_RED; - case 'g': return LED_RS_GRN; - case '1': return LED_DISK1; - case '2': return LED_DISK2; - case 'A': reset = 1; return LED_ALL; - default: fprintf(stderr, "leds: %c: unknown LED (use r,g,0,1 or A)\n", ch); - exit(1); - } - } - - int main( int argc, char **argv ) - { - /* Default: switch green on, red off (-A +g). */ - if (argc == 1) { - verbose = 1; - init_leds(); - led_ioctl(N2_LM_ALL_OFF, 0); - led_ioctl(N2_LM_ON, LED_RS_GRN); - } else { - int i, alt=0, state[PHYS_LEDS]; - for(i=0; i 0) { - char *arg = *++argv; - int st; - if (strcmp(arg, "-v") == 0) { - ++verbose; - continue; - } - - switch (*arg) { - case '+': st = on; break; - case '-': st = off; break; - case '!': st = blink; break; - case '/': st = transition; break; - default: fprintf(stderr, "leds: %c: unknown option\n", *arg); - exit(1); - } - - if (st != transition) { - while (*++arg) { - i = led(*arg); - if (i == LED_ALL) - for (i=0; i/dev/null - /usr/bin/mke2fs -m 0 /dev/ram0 12288 - /bin/mount -t ext2 /dev/ram0 /mnt - ( /usr/bin/find . -print0 -mount | /usr/bin/cpio -p -0 -d -m -u /mnt ) - /bin/rm -f /mnt/linuxrc - /bin/cp /mnt/home/httpd/html/Management/upgrade.cgi /mnt/home/httpd/html/Management/upgrade-real.cgi - /bin/echo "#!/bin/sh" > /mnt/home/httpd/html/Management/upgrade.cgi - /bin/echo >> /mnt/home/httpd/html/Management/upgrade.cgi - /bin/echo "/bin/mount -t ramfs none /upload -o size=8196 2>/dev/null" \ - >> /mnt/home/httpd/html/Management/upgrade.cgi - /bin/echo "/bin/dd if=/dev/zero of=/upload/free-ram bs=1k count=8k 2>/dev/null" \ - >> /mnt/home/httpd/html/Management/upgrade.cgi - /bin/echo "/bin/umount /upload 2>/dev/null" \ - >> /mnt/home/httpd/html/Management/upgrade.cgi - /bin/echo "exec /home/httpd/html/Management/upgrade-real.cgi" \ - >> /mnt/home/httpd/html/Management/upgrade.cgi - /bin/echo "Root filesystem will be mounted from /dev/ram0 (a copy of /dev/mtdblock4) ..." -fi - -if [ $prefroot = "nfsroot" ] ; then - - sysconflen=`/bin/dd if=/dev/mtd1 bs=4 count=1 2>/dev/null | /usr/bin/hexdump -n 6 -e '"%02d"'` - ipaddr=`/bin/dd if=/dev/mtd1 bs=1 count=$sysconflen skip=4 2>/dev/null | grep ip_addr | sed -e s/ip_addr=//` - netmask=`/bin/dd if=/dev/mtd1 bs=1 count=$sysconflen skip=4 2>/dev/null | grep netmask | sed -e s/netmask=//` - gateway=`/bin/dd if=/dev/mtd1 bs=1 count=$sysconflen skip=4 2>/dev/null | grep gateway | sed -e s/gateway=//` - - /sbin/insmod ixp400 - /sbin/insmod ixp425_eth - /sbin/ifconfig ixp0 up $ipaddr netmask $netmask - /sbin/route add default gw $gateway - - /sbin/ifconfig lo up 127.0.0.1 - - # The nfsrootloc and nfsrootopts vars can be overridden here. - . /.nfsroot - - /bin/mount $nfsrootopts $nfsrootloc /mnt - - if [ -L /mnt/sbin/init -o -x /mnt/sbin/init -o \ - -L /mnt/bin/init -o -x /mnt/bin/init ] ; then - /bin/echo "Root filesystem will be mounted from an NFS root ..." - mounted=/mnt - else - /bin/umount /mnt - /bin/echo "Can't find valid NFS rootfs, using jffs2 ..." - mounted= - prefroot=jffs2 - fi -fi - -if [ $prefroot = "jffs2" ] ; then - /bin/echo "Root filesystem will be mounted from /dev/mtdblock4 ..." - mounted= -fi - - -/bin/umount /proc - -# Pivot to the desired rootfs and run the initial executable. - -if [ -n "$mounted" ] ; then - - cd $mounted - - if [ -x ./sbin/init -o -L ./sbin/init ] ; then - runboot=/sbin/init - elif [ -x ./bin/init -o -L ./bin/init ] ; then - runboot=/bin/init - else - runboot=/bin/sh - fi - - /sbin/pivot_root . initrd - - exec /usr/sbin/chroot . $runboot < /dev/console 1> /dev/console 2> /dev/console - -else - - exec /sbin/init - -fi - -/bin/echo "Can't chroot to $prefroot, using jffs2 ..." -exec /sbin/init - -# Last-resort fall-back - this should never be reached. -/bin/sh diff --git a/packages/slugos-init/files/reflash b/packages/slugos-init/files/reflash index bcf51fc606..ad1c4c26ad 100644 --- a/packages/slugos-init/files/reflash +++ b/packages/slugos-init/files/reflash @@ -10,6 +10,13 @@ # # /etc/default/functions contains useful utility functions . /etc/default/functions +load_functions sysconf +# +# NSLU2 flash layout is non-standard. +case "$(machine)" in +nslu2) isnslu2=1;; +*) isnslu2=;; +esac # # CHECKING FOR INPUT (ARGUMENTS ETC) # ---------------------------------- @@ -37,31 +44,43 @@ do ffsfile="$1" shift;; -i) shift + test -n "$isnslu2" || { + echo "reflash: -i: only supported on the LinkSys NSLU2" >&2 + echo " use -k and -j to specify the kernel and root file system" >&2 + exit 1 + } test $# -gt 0 || { echo "reflash: -i: give the file containing the complete flash image" >&2 exit 1 } imgfile="$1" shift;; - *) echo "reflash: usage: $0 [-k kernel] [-j rootfs] [-i image]" >&2 + *) if test -n "$isnslu2" + then + echo "reflash: usage: $0 [-k kernel] [-j rootfs] [-i image]" >&2 + else + echo "reflash: usage: $0 [-k kernel] [-j rootfs]" >&2 + fi echo " -k file: the new compressed kernel image ('zImage')" >&2 echo " -j file: the new root file system (jffs2)" >&2 - echo " -i file: a complete flash image (gives both kernel and jffs2)" >&2 + test -n "$isnslu2" && + echo " -i file: a complete flash image (gives both kernel and jffs2)" >&2 echo " The current jffs2 will be umounted if mounted." >&2 exit 1;; esac done # -# Sanity check on the arguments +# Sanity check on the arguments (note that the first case can only fire +# on NSLU2 because of the check for -i above.) if test -n "$imgfile" -a -n "$ffsfile" -a -n "$kfile" then - echo "reflash: -k,-j,-i: specify at most two files" >&2 + echo "reflash: specify at most two files" >&2 echo " -i has both a kernel and rootfs, the kernel from -k and" >&2 echo " the rootfs from -j override the one in the image (if given)" >&2 exit 1 elif test -z "$imgfile" -a -z "$ffsfile" -a -z "$kfile" then - echo "reflash: -k,-j,-i: specify at least one file to flash" >&2 + echo "reflash: specify at least one file to flash" >&2 exit 1 fi # @@ -270,20 +289,8 @@ then errorexit } # - ( cd "$ffsdir" - find etc/*.conf $(sed 's!^/!!' usr/lib/ipkg/info/*.conffiles) ! -type d -newer etc/.configured -print | - sed 's/^/diff /' - exec sed 's/#.*$//;/^[ ]*$/d' etc/default/conffiles - ) | sed 's!^/*!!' | awk '{ op=$1; $1=""; file[$0]=op } - END{ for (f in file) if (file[f] != "ignore") print file[f] f }' | - while read op file - do - if test -e "$ffsdir/$file" - then - echo "$op $file" >&3 - echo "$file" - fi - done 3>"$list" | (cd "$ffsdir"; exec cpio -p -d -m -u "$saved") || { + # sysconf_save_conffiles + sysconf_save_conffiles "$ffsdir" "$saved" "$list" || { echo "reflash: $saved: copy of saved configuration files failed" >&2 rm -rf "$saved" rm "$list" @@ -311,21 +318,22 @@ echo "reflash: about to flash new image" >&2 # steps is a problem, but then so is a failure in a partial write. # Write the flashdisk first because this is larger (most likely to # fail). -# Temporarily check for devio progress indicator capability this way... -if devio -p '' 2>/dev/null -then - progress=-p -else - progress= -fi +# +# -p causes the progress indicator to be displayed +progress=-p do_kernel() { + local cmd + if test -n "$isnslu2" + then + # NSLU2: write length,0,0,0 header, then fill + cmd="wb L,4; fb 12,0; cpL" + else + # Other: just write the kernel bytes + cmd="cpL" + fi devio $progress "$@" "<<$kfile" ">>$kdev" ' # kernel is at imgkoffset[imgksize] - ' "<= $imgkoffset" "L=$imgksize" ' - # kernel write length,0,0,0 header, then fill - wb L,4 - fb 12,0 - cp L + ' "<= $imgkoffset" "L=$imgksize" "$cmd" ' # fill with 255 fb #t-,255' } @@ -445,135 +453,13 @@ mountflash "$ffsdev" "$ffsdir" && :>"$ffsdir/etc/.configured" || { exit 1 } # -# verify file -# this is called with the name of a 'diff' file which is, indeed, -# different and with all the std streams connected to the tty. It -# returns a status code to say whether (0) or not (1) to copy the -# file over. -# -verify_help() { - echo "Please specify how to handle this file or link, the options are as follows," - echo "two character abbreviations may be used:" - echo - echo " keep: retain the old file, overwrite the new flash image file" - echo " upgrade: retain the new file, the old (saved) file is not used" - echo " diff: display the differences between the old and the new using diff -u" - echo " shell: temporarily start an interactive shell (sh -i), exit to continue" - echo " skip: ignore this file for the moment. The file is left in the directory" - echo " $saved and many be handled after this script has completed" -} -# -verify() { - local command file - - file="$1" - echo "reflash: $file: configuration file changed." - verify_help "$file" - while : - do - echo -n "option: " - read command - case "$command" in - ke*) return 0;; - up*) rm "$saved/$file" - return 1;; - di*) echo "DIFF OLD($saved) NEW($ffsdir)" - diff -u "$saved/$file" "$ffsdir/$file";; - sh*) PS1="$file: " sh -i;; - sk*) return 1;; - *) verify_help "$file";; - esac - done -} -# the same, but for a link -verify_link() { - local command link - - link="$1" - echo "reflash: $link: configuration link changed." - verify_help "$link" - while : - do - echo -n "option: " - read command - case "$command" in - ke*) return 0;; - up*) rm "$saved/$link" - return 1;; - di*) echo "DIFF:" - echo "OLD($saved): $link -> $(readlink "$saved/$link")" - echo "NEW($ffsdir): $link -> $(readlink "$ffsdir/$link")";; - sh*) PS1="$link: " sh -i;; - sk*) return 1;; - *) verify_help "$link";; - esac - done -} -# -while read op file -do - # handle .configured specially (to preserve the original datestamp) - if test "$file" = "etc/.configured" - then - # this should definately not fail because of the test above! - if cp -a "$saved/$file" "$ffsdir/$file" - then - echo "$file" >&3 - else - echo "reflash: $file: timestamp copy failed (ignored)" >&2 - fi - elif test -h "$saved/file" -o -h "$ffsdir/$file" - then - # new or old symbolic link - if test -h "$saved/$file" -a -h "$ffsdir/$file" && - test "$(readlink "$saved/$file")" = "$(readlink "$ffsdir/$file")" - then - # no change - echo "$file" >&3 - else - # assume a change regardless - case "$op" in - preserve) - echo "$file" - echo "$file" >&3;; - diff) # need user input - if verify_link "$file" <>/dev/tty >&0 2>&0 - then - echo "$file" - echo "$file" >&3 - fi;; - esac - fi - else - # only overwrite if necessary - if test -e "$ffsdir/$file" && cmp -s "$saved/$file" "$ffsdir/$file" - then - # do not overwrite - echo "$file" >&3 - elif test ! -e "$ffsdir/$file" - then - # always preserve - echo "$file" - echo "$file" >&3 - else - case "$op" in - preserve) - echo "$file" - echo "$file" >&3;; - diff) # the files are different, get user input - if verify "$file" <>/dev/tty >&0 2>&0 - then - echo "$file" - echo "$file" >&3 - fi;; - esac - fi - fi -done <"$list" 3>/tmp/restore.$$ | (cd "$saved"; exec cpio -p -d -u "$ffsdir") || { +# sysconf_restore_conffiles +restore="/tmp/restore.$$" +sysconf_restore_conffiles "$ffsdir" "$saved" "$restore" <"$list" || { echo "reflash: $saved: restore of saved configuration files failed" >&2 echo " The new flash file system is mounted on $ffsdir" >&2 echo " The saved files are in $saved and the list in $list, the list of" >&2 - echo " files selected for restore is in /tmp/restore.$$" >&2 + echo " files selected for restore is in $restore" >&2 echo " You should restore any required configuration from $saved," >&2 echo " then umount $ffsdir and reboot." >&2 exit 1 @@ -581,9 +467,9 @@ done <"$list" 3>/tmp/restore.$$ | (cd "$saved"; exec cpio -p -d -u "$ffsdir") || # # remove the copied files (i.e. the ones which were preserved) ( cd "$saved" - exec rm $(cat /tmp/restore.$$) + exec rm $(cat "$restore") ) -rm /tmp/restore.$$ +rm "$restore" # # clean up, files left in $saved need to be handled by the user files="$(find "$saved" ! -type d -print)" diff --git a/packages/slugos-init/files/sysconf b/packages/slugos-init/files/sysconf new file mode 100644 index 0000000000..1a9cdf0005 --- /dev/null +++ b/packages/slugos-init/files/sysconf @@ -0,0 +1,780 @@ +#!/bin/sh +# sysconf +# +# utility to manipulate system configuration information help +# in a RedBoot SysConf partition +# +# load the utility functions (unless this is being called just +# to load these functions!) +test "$1" != sysconf && . /etc/default/functions + +# +# sysconf_valid +# return true if the SysConf partition exists and seems to be +# potentially valid (it starts with a reasonable length). +sysconf_valid(){ + local sysdev + sysdev="$(mtblockdev SysConf)" + test -n "$sysdev" -a -b "$sysdev" && + devio "<<$sysdev" '!! b.10>s32768<&!' +} + +# +# sysconf_read [prefix] +# read the SysConf partition (if present) writing the result into +# /etc/default/sysconf, if the result is empty it will be removed. +sysconf_read(){ + local sysdev sedcmd mac config_root + config_root="$1" + rm -f /tmp/sysconf.new + sysdev="$(mtblockdev SysConf)" + if sysconf_valid + 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 '</tmp/sysconf.new + fi + # + # test the result - sysconf must be non-empty + if test -s /tmp/sysconf.new + then + mv /tmp/sysconf.new "$config_root/etc/default/sysconf" + else + rm -f /tmp/sysconf.new + return 1 + fi +} + +# +# sysconf_default [prefix] +# Provde a default /etc/default/sysconf when there is no SysConf partition, +# or when it is invalid, this function will read from an existing sysconf, +# copying the values into the new one. +# sysconf_line tag config-tag +# write an appropriate line if the config value is non-empty +sysconf_line(){ + config "$2" | { + local value + read value + test -n "$value" && echo "$1"="$value" + } +} +# +sysconf_default(){ + local config_root + config_root="$1" + { echo '[network]' + sysconf_line hw_addr mac + sysconf_line disk_server_name host + sysconf_line w_d_name domain + sysconf_line lan_interface iface + sysconf_line ip_addr ip + sysconf_line netmask netmask + sysconf_line gateway gateway + sysconf_line dns_server1 dns + sysconf_line dns_server2 dns2 + sysconf_line dns_server3 dns3 + sysconf_line bootproto boot + } >/tmp/sysconf.new + mv /tmp/sysconf.new "$config_root/etc/default/sysconf" +} + +# +# sysconf_reload [prefix] +# read the values from /etc/default/sysconf and use these values to set +# up the following system files: +# +# /etc/hostname +# /etc/defaultdomain +# /etc/resolv.conf +# /etc/network/interfaces +# /etc/motd +# +sysconf_reload(){ + local config_root host domain iface boot ip netmask gateway ifname iftype + config_root="$1" + host="$(config host)" + test -n "$host" && echo "$host" >"$config_root/etc/hostname" + domain="$(config domain)" + test -n "$domain" && echo "$domain" >"$config_root/etc/defaultdomain" + # + # The DNS server information gives up to three nameservers, + # but this currently only binds in the first. + { + test -n "$domain" && echo "search $domain" + test -n "$(config dns)" && echo "nameserver $(config dns)" + test -n "$(config dns2)" && echo "nameserver $(config dns2)" + test -n "$(config dns3)" && echo "nameserver $(config dns3)" + } >"$config_root/etc/resolv.conf" + # + # 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 slugos udhcp script, + # /etc/udhcpc.d/50default, loads the values from sysconf. + iface="$(config iface)" + 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 + # + 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 interface used by default during boot" + echo "auto $iface" + echo "# Automatically generated from /etc/default/sysconf" + echo "# address, netmask and gateway are ignored for 'dhcp'" + echo "# but required for 'static'" + echo "iface $iface inet $boot" + # 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" + # + # Now read all the other ARPHRD_ETHER (type=1) interfaces + # and add an entry for each. + for ifname in $(test -d /sys/class/net && ls /sys/class/net) + do + if test -r "/sys/class/net/$ifname/type" -a "$ifname" != "$iface" + then + read iftype <"/sys/class/net/$ifname/type" + case "$iftype" in + 1) echo "#" + echo "# /sys/class/net/$ifname:" + echo "auto $ifname" + echo "iface $ifname inet dhcp";; + esac + fi + done + } >"$config_root/etc/network/interfaces" + # + # Finally rewrite /etc/motd + { echo "Host name: $host" + echo "Domain name: $domain" + echo "Host MAC: $(config 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 preserve' to save the configuration permanently" + echo "Use 'turnup restore' to restore a previously saved configuration" + echo "Use 'turnup disk|nfs -i options to initialise a non-flash root" + echo "Use 'turnup help' for more information" + } >"$config_root/etc/motd" +} + +# +# sysconf_save_conffiles +# preserve the configuration files in a directory or in a CPIO archive +# (which is *not* compressed). If is a directory the files are +# copied, otherwise a CPIO archive is made with that name. is +# the listing file giving the preserved files and the processing option. +sysconf_save_conffiles(){ + local ffsdir dest list file + ffsdir="$1" + saved="$2" + list="$3" + test -n "$ffsdir" -a -r "$ffsdir/etc/default/conffiles" -a -n "$saved" -a -n "$list" || { + echo "sysconf_save_conffiles: invalid arguments: '$*'" >&2 + echo " usage sysconf_save_conffiles " >&2 + return 1 + } + # + ( cd "$ffsdir" + find etc/*.conf $(sed 's!^/!!' usr/lib/ipkg/info/*.conffiles) ! -type d -newer etc/.configured -print | + sed 's/^/diff /' + exec sed 's/#.*$//;/^[ ]*$/d' etc/default/conffiles + ) | sed 's!^/*!!' | + awk '{ op=$1; $1=""; file[$0]=op } + END{ for (f in file) if (file[f] != "ignore") print file[f] f }' | + while read op file + do + if test -e "$ffsdir/$file" + then + echo "$op $file" >&3 + echo "$file" + fi + done 3>"$list" | ( + cd "$ffsdir" + if test -d "$saved" + then + exec cpio -p -d -m -u "$saved" + else + exec cpio -o -H crc >"$saved" + fi + ) +} + +# +# sysconf_verify file +# this is called with the name of a 'diff' file which is, indeed, +# different and with all the std streams connected to the tty. It +# returns a status code to say whether (0) or not (1) to copy the +# file over. +# +# globals: the following must be defined in the calling context! +# saved: the directory containing the unpacked saved files +# ffsdir: the flash directory to which the files are being restored (/) +# +sysconf_verify_help() { + echo "Please specify how to handle this file or link, the options are as follows," + echo "two character abbreviations may be used:" + echo + echo " keep: retain the old file, overwrite the new flash image file" + echo " upgrade: retain the new file, the old (saved) file is not used" + echo " diff: display the differences between the old and the new using diff -u" + echo " shell: temporarily start an interactive shell (sh -i), exit to continue" + echo " skip: ignore this file for the moment. The file is left in the directory" + echo " $saved and many be handled after this script has completed" +} +# +sysconf_verify() { + local command file + + # return 1 here causes the file not to be overwritten, + # control should never get here! + test -n "$sysconf_noninteractive" && { + echo "$0: $*: changed file cannot be handled non-interactively" >&2 + return 1 + } + + file="$1" + echo "$0: $file: configuration file changed." + sysconf_verify_help "$file" + while : + do + echo -n "option: " + read command + case "$command" in + ke*) return 0;; + up*) rm "$saved/$file" + return 1;; + di*) echo "DIFF OLD($saved) NEW($ffsdir)" + diff -u "$saved/$file" "$ffsdir/$file";; + sh*) PS1="$file: " sh -i;; + sk*) return 1;; + *) sysconf_verify_help "$file";; + esac + done +} +# the same, but for a link +sysconf_verify_link() { + local command link + + # return 1 here causes the file not to be overwritten, + # control should never get here! + test -n "$sysconf_noninteractive" && { + echo "$0: $*: changed link cannot be handled non-interactively" >&2 + return 1 + } + + link="$1" + echo "reflash: $link: configuration link changed." + sysconf_verify_help "$link" + while : + do + echo -n "option: " + read command + case "$command" in + ke*) return 0;; + up*) rm "$saved/$link" + return 1;; + di*) echo "DIFF:" + echo "OLD($saved): $link -> $(readlink "$saved/$link")" + echo "NEW($ffsdir): $link -> $(readlink "$ffsdir/$link")";; + sh*) PS1="$link: " sh -i;; + sk*) return 1;; + *) sysconf_verify_help "$link";; + esac + done +} + +# +# sysconf_restore_conffiles +# restore the configuration files from a directory. 'source-dir' +# If is a directory of files from sysconf_save_conffiles. The +# list of files restored is written to the third argument (restore), +# but is not required (/dev/null would be ok). +# +# the list of files to restore is read from stdin, along with the +# processing option fo