summaryrefslogtreecommitdiffhomepage
path: root/contrib/package/remote-update
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/package/remote-update')
-rw-r--r--contrib/package/remote-update/Makefile43
-rwxr-xr-xcontrib/package/remote-update/files/usr/sbin/remote-update309
2 files changed, 352 insertions, 0 deletions
diff --git a/contrib/package/remote-update/Makefile b/contrib/package/remote-update/Makefile
new file mode 100644
index 000000000..c8adceeaa
--- /dev/null
+++ b/contrib/package/remote-update/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
+#
+# This is free software, licensed under the Apache 2.0 license.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=remote-update
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/remote-update
+ SECTION:=luci
+ CATEGORY:=LuCI
+ SUBMENU:=Freifunk
+ TITLE:=Freifunk remote update utility.
+ DEPENDS:=@TARGET_atheros||@TARGET_ar71xx||@TARGET_brcm-2.4
+endef
+
+define Package/remote-update/description
+ The freifunk remote-update utility uses sysupgrade to reflash the currently
+ running firmware while keeping most of the existing configuratio.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/remote-update/install
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,remote-update))
diff --git a/contrib/package/remote-update/files/usr/sbin/remote-update b/contrib/package/remote-update/files/usr/sbin/remote-update
new file mode 100755
index 000000000..bffc449d0
--- /dev/null
+++ b/contrib/package/remote-update/files/usr/sbin/remote-update
@@ -0,0 +1,309 @@
+#!/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
+ ;;
+ ar71xx)
+ if grep -q '"kernel"' /proc/mtd; then
+ echo "openwrt-ar71xx-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 <<EOT
+
+Usage:
+ remote-update -h
+ remote-update [-u <update url>] -c
+ remote-update [-v] [-y] [-u <update url>] -w
+ remote-update [-d] [-n] [-v] [-y] [-s <sleep seconds>] [-u <update url>]
+
+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 <seconds>
+ Sleep given amount of seconds before starting flash write.
+ If ommitted and '-y' is not used, 5 seconds are assumed.
+
+ -u <url>
+ 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)
+ repo=${repo:-$(uci get system.upgrade.repository 2>/dev/null)}
+
+ [ -z "$arch" ] && {
+ echo "Can not determine the current architecture."
+ exit 1
+ }
+
+ [ -z "$repo" ] && {
+ echo "No repository configured in 'system.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 <Ctrl-C> 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 <Enter> to continue or <Ctrl-C> 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