#!/bin/sh local tempfile=/tmp/remote-upgrade.img local D2='\([0-9]\{2\}\)' local D4='\([0-9]\{4\}\)' local NL=' ' find_architecture() { opkg list_installed 'base-files-*' | \ sed -ne 's/base-files-\([^ ]\+\).*/\1/p' } find_image() { case "$1" in atheros) if grep -q '"vmlinux.bin.l7"' /proc/mtd; then echo "openwrt-fonera-combined.img" else echo "openwrt-ubiquity-combined.img" fi ;; brcm-2.4) echo "openwrt-brcm-2.4-squashfs.trx" ;; esac } check_image() { local file; for file in /lib/upgrade/*.sh; do . $file; done if platform_check_image "$1" >/dev/null 2>/dev/null; then return 0 fi return 1 } find_remote_checksum() { wget -qO- ${1%/*}/md5sums 2>/dev/null | \ sed -ne '/'$2'/ { s/ .*//p }' } find_local_checksum() { set -- $(md5sum "$tempfile") echo $1 } find_remote_info() { wget -qO- "${1%/*}/VERSION.txt" 2>/dev/null } find_remote_version() { find_remote_info "$1" | \ sed -ne "s!.*$D4/$D2/$D2 $D2:$D2.*!\\1\\2\\3\\4\\5!p;t" } find_local_version() { if [ -f /rom/etc/banner ]; then sed -ne "s!.*$D4/$D2/$D2 $D2:$D2.*!\\1\\2\\3\\4\\5!p;t" \ /rom/etc/banner else date +"%Y%m%d%H%M" -r /bin/sh fi } stop_service() { [ -x /etc/init.d/$1 ] && { echo -n "Stopping service $1 ... " /etc/init.d/$1 stop >/dev/null 2>/dev/null echo "done" } } do_wait() { if [ ${1:-0} -gt 0 ]; then echo -n "${2:-Waiting} " for i in $(seq 1 $1); do printf "%-2dseconds" $(($1-$i)) sleep 1 echo -en "\b\b\b\b\b\b\b\b\b" done echo "${NL}" fi } version_compare() { local v1="$1" local v2="$2" while [ -n "$v1" -o -n "$v2" ]; do if [ -z "${v2:0:4}" -o "${v1:0:4}" -gt "${v2:0:4}" ]; then return 1 elif [ -z "${v1:0:4}" -o "${v1:0:4}" -lt "${v2:0:4}" ]; then return 2 fi v1="${v1:4}" v2="${v2:4}" done return 0 } usage() { cat <] -c remote-update [-v] [-y] [-u ] -w remote-update [-d] [-n] [-v] [-y] [-s ] [-u ] Actions: -h Display this help message and exit. -c Check for firmware update and exit. -w Fetch image and exit, do not perform flash write. Options: -d Do not detach from terminal. -n Do not backup configuration. -v Skip verification of downloaded image. -y Assume defaults for all questions. -s Sleep given amount of seconds before starting flash write. If ommitted and '-y' is not used, 5 seconds are assumed. -u Fetch firmware image from given url. A file "md5sums" is expected in the same remote directory. If there is no such file, use -v to suppress verification. EOT exit 1 } while getopts "s:u:cdnvwyh" flag; do case $flag in s) sleeptime="$OPTARG";; u) updateurl="$OPTARG";; c) checkupdate=1;; d) nodetach=1;; n) nobackup=1;; v) noverify=1;; w) noflash=1;; y) noquestions=1;; *) usage;; esac done local image_url="$updateurl" local image_name="${image_url##*/}" [ -z "$image_url" ] && { local arch=$(find_architecture) local image=$(find_image "$arch") local repo=$(uci get freifunk.upgrade.repository 2>/dev/null) [ -z "$arch" ] && { echo "Can not determine the current architecture." exit 1 } [ -z "$repo" ] && { echo "No repository configured in 'freifunk.upgrade.repository'." echo "Use the '-u' flag to specify an image location." exit 1 } [ -z "$image" ] && { echo "No suitable image for the '$arch' architecture." echo "Your platform is not supported." exit 1 } echo "Architecture: $arch" echo "Repository: $repo" image_name="$image" image_url="${repo%/}/$arch/$image" } if [ "$checkupdate" = 1 ]; then local v1=$(find_local_version) local v2=$(find_remote_version "$image_url") [ -n "$v1" -a -n "$v2" ] && { version_compare "$v1" "$v2" [ $? == 2 ] && { echo "Update available!${NL}Local: $v1${NL}Remote: $v2${NL}--" find_remote_info "$image_url" exit 0 } || { echo "Local version $v1 is up to date" exit 2 } } || { echo "No remote time stamp found." exit 1 } else if [ "$noquestions" != 1 ]; then echo -n "${NL}About to download $image_name. Continue? [y] " read answer case "$answer" in [nN]) exit 1;; esac fi echo -n "Downloading $image_name ... " rm -f $tempfile wget -qO $tempfile "$image_url" 2>/dev/null [ $? == 0 ] && echo done || { echo failed rm -f $tempfile exit 1 } if [ "$noverify" != 1 ]; then echo -n "Verifying $image_name ... " local md5_remote=$(find_remote_checksum "$image_url" "$image_name") local md5_local=$(find_local_checksum) check_image "$tempfile" local image_ok=$? if [ $image_ok = 0 -a -n "$md5_remote" -a -n "$md5_local" -a "$md5_remote" = "$md5_local" ]; then echo "done" else if [ $image_ok != 0 ]; then echo "unsupported image type" else echo "checksum mismatch! (local:${md5_local:-(none)} remote:${md5_remote:-(none)})" fi local answer=n if [ "$noquestions" != 1 ]; then echo -n "${NL}Verification failed. Continue anyway? [n] " read answer fi case "$answer" in [yYjJ]*) : ;; *) echo "Aborting." rm -f $tempfile exit 1 ;; esac fi fi if [ "$noflash" != 1 ]; then if [ -f "$tempfile" ]; then if [ "$noquestions" == 1 ]; then do_wait ${sleeptime:-5} "${NL}About to start flashing, hit to abort!${NL}${NL}Starting in" else if [ -z "$nobackup" ]; then echo -n "${NL}Keep configuration files? [y] " read answer case "$answer" in [nN]) nobackup=1;; esac fi echo -n "${NL}About to start flashing!${NL}Hit to continue or to abort.${NL}" read answer fi for s in lucid collectd; do stop_service $s; done if [ "$nodetach" != 1 ]; then echo -n "Starting sysupgrade in background ... " /bin/busybox start-stop-daemon -S -b -x /sbin/sysupgrade -- ${nobackup:+-n} "$tempfile" echo "done" else echo "Executing sysupgrade ... " exec /sbin/sysupgrade ${nobackup:+-n} "$tempfile" fi else echo "No upgrade image found!" exit 1 fi else echo "Image saved in '$tempfile'" fi fi