194 lines
5.8 KiB
Bash
Executable File
194 lines
5.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# author jjm2473
|
|
if [ -f /lib/upgrade/ota.sh ]; then
|
|
. /lib/upgrade/ota.sh
|
|
export_ota_url
|
|
fi
|
|
|
|
if [ -z "$OTA_URL_BASE" ]; then
|
|
echo "Unsupported device." >&2
|
|
exit 255
|
|
fi
|
|
|
|
WRLOCK=/var/lock/ota_background.lock
|
|
|
|
action=${1}
|
|
shift
|
|
|
|
sha256() {
|
|
sha256sum $1 | cut -d' ' -f1
|
|
}
|
|
|
|
fcurl() {
|
|
curl --fail --show-error "$@"
|
|
}
|
|
|
|
download() {
|
|
local img=$1
|
|
local sum=$2
|
|
touch /tmp/firmware.img.part
|
|
echo >/tmp/firmware.img.progress
|
|
rm -f /tmp/firmware.img.sha256sum
|
|
if [ -f /tmp/firmware.img ]; then
|
|
echo "Checking existed firmware.img..." >> /tmp/firmware.img.progress
|
|
if [ "`sha256 /tmp/firmware.img`" = "$sum" ]; then
|
|
echo $sum > /tmp/firmware.img.sha256sum;
|
|
rm -f /tmp/firmware.img.part
|
|
rm -f /tmp/firmware.img.progress
|
|
return 0;
|
|
else
|
|
echo "Check failed, redownload" >> /tmp/firmware.img.progress
|
|
rm -f /tmp/firmware.img
|
|
fi
|
|
fi
|
|
curl --fail --show-error --connect-timeout 5 --progress-bar -o /tmp/firmware.img.part "$OTA_URL_BASE/$img" 2>/tmp/firmware.img.progress &
|
|
echo "$!" > /var/run/ota/download.pid
|
|
if wait $!; then
|
|
rm -f /var/run/ota/download.pid
|
|
echo "Checking new firmware.img.part..." > /tmp/firmware.img.progress
|
|
if [ "`sha256 /tmp/firmware.img.part`" = "$sum" ]; then
|
|
mv /tmp/firmware.img.part /tmp/firmware.img && echo $sum > /tmp/firmware.img.sha256sum
|
|
rm -f /tmp/firmware.img.progress
|
|
return 0
|
|
else
|
|
echo "Checksum failed!" >>/tmp/firmware.img.progress
|
|
fi
|
|
fi
|
|
rm -f /var/run/ota/download.pid
|
|
rm -f /tmp/firmware.img.part
|
|
return 1
|
|
}
|
|
|
|
lock_download() {
|
|
local lock="$WRLOCK"
|
|
exec 200>$lock
|
|
flock -n 200 || return
|
|
download $1 $2
|
|
flock -u 200
|
|
}
|
|
|
|
prepare_check() {
|
|
local line
|
|
local release=`grep 'DISTRIB_RELEASE=' /etc/openwrt_release | sed -E "s/.*'(.+)'.*/\1/"`
|
|
local revision=`grep 'DISTRIB_REVISION=' /etc/openwrt_release | sed -E "s/.*'(.+)'.*/\1/" | cut -d'-' -f1`
|
|
local current="$release-$revision"
|
|
local latest=0
|
|
cat /dev/null > /var/run/ota/ota.log
|
|
fcurl --connect-timeout 5 -o /var/run/ota/ota.latest "$OTA_URL_BASE/version.latest" || { rm -f /var/run/ota/ota.latest ; return 255; }
|
|
if grep -Fq "$current" /var/run/ota/ota.latest; then
|
|
latest=1
|
|
current=""
|
|
fi
|
|
fcurl --connect-timeout 5 -o /var/run/ota/ota.index "$OTA_URL_BASE/version.index" || return 255;
|
|
head -5 /var/run/ota/ota.index | while read line; do
|
|
if [ -z "$line" -o "$line" = "$current" ]; then
|
|
break
|
|
fi
|
|
echo "<h3>`echo $line | sed 's/-/ /'`</h3><pre>" >> /var/run/ota/ota.log
|
|
fcurl --connect-timeout 1 "$OTA_URL_BASE/log/$line.log" >> /var/run/ota/ota.log
|
|
echo "</pre>" >> /var/run/ota/ota.log
|
|
done
|
|
[ "`wc -l /var/run/ota/ota.log | cut -d' ' -f1`" -eq 0 ] && return 1
|
|
[ "`wc -l /var/run/ota/ota.index | cut -d' ' -f1`" -gt 5 ] && echo "<a href=\"$OTA_URL_BASE/\" onclick=\"void(0)\" target=\"_blank\">More</a>" >> /var/run/ota/ota.log
|
|
|
|
return $latest
|
|
}
|
|
|
|
# 0: found newer fw, 1: already newest fw, 2: found running task, *: err
|
|
do_check() {
|
|
local ret=0
|
|
local lock="$WRLOCK"
|
|
exec 200>$lock
|
|
if flock -n 200; then
|
|
prepare_check
|
|
ret=$?
|
|
flock -u 200 >/dev/null 2>&1
|
|
elif [ -f /tmp/firmware.img.progress -o -f /tmp/firmware.img.sha256sum ]; then
|
|
ret=2
|
|
else
|
|
echo "lock failed!" >&2
|
|
return 255
|
|
fi
|
|
|
|
if [ "$ret" -eq 0 -o "$ret" -eq 2 ]; then
|
|
# output
|
|
echo "<pre>"
|
|
sed -E 's/.*\((.+)\).*/\1/' /var/run/ota/ota.latest
|
|
echo "</pre>"
|
|
echo "<br><h2>ChangeLog:</h2>"
|
|
fi
|
|
[ "$ret" -eq 0 -o "$ret" -eq 1 -o "$ret" -eq 2 ] && cat /var/run/ota/ota.log
|
|
return $ret
|
|
}
|
|
|
|
# async download
|
|
do_download(){
|
|
local img=`head -1 /var/run/ota/ota.latest | sed -E 's/.*\((.+)\).*/\1/'`
|
|
local sum=`grep 'SHA256: ' /var/run/ota/ota.latest | cut -d' ' -f2`
|
|
[ -z "$img" -o -z "$sum" ] && { echo "do check first" >&2 ; return 254; }
|
|
lock_download $img $sum &
|
|
return 0
|
|
}
|
|
|
|
# 0: done, 1: downloading, 2: failed, 254: wrong state, *: err
|
|
do_progress() {
|
|
local sum=`grep 'SHA256: ' /var/run/ota/ota.latest | cut -d' ' -f2`
|
|
[ -z "$sum" ] && { echo "do check first" >&2 ; return 254; }
|
|
[ -f /tmp/firmware.img.sha256sum ] && [ "`cat /tmp/firmware.img.sha256sum`" = "$sum" ] && return 0
|
|
[ -f /tmp/firmware.img.progress ] || { echo "download not in progress" >&2 ; return 254; }
|
|
[ -f /tmp/firmware.img.part ] && { cat /tmp/firmware.img.progress | tr '\r' '\n' | tail -n1; return 1; }
|
|
tail -1 /tmp/firmware.img.progress | grep -Fq 'Canceled!' && { echo "Canceled"; return 2; }
|
|
grep -v '\r' /tmp/firmware.img.progress >&2
|
|
return 3
|
|
}
|
|
|
|
do_cancel() {
|
|
if [ -f /var/run/ota/download.pid ]; then
|
|
local pid=`cat /var/run/ota/download.pid`
|
|
if [ -n "$pid" ]; then
|
|
kill -TERM $pid;
|
|
while kill -0 $pid >/dev/null 2>&1; do
|
|
if ! sleep 1; then
|
|
break
|
|
fi
|
|
done
|
|
echo "" >> /tmp/firmware.img.progress
|
|
echo "Canceled!" >> /tmp/firmware.img.progress
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
ota_init(){
|
|
mkdir -p /var/run/ota >/dev/null 2>&1 || true
|
|
}
|
|
|
|
usage() {
|
|
echo "usage: ota sub-command"
|
|
echo "where sub-command is one of:"
|
|
echo " check Check firmware upgrade"
|
|
echo " download Download latest firmware"
|
|
echo " progress Download progress"
|
|
echo " cancel Cancel download"
|
|
}
|
|
|
|
ota_init || exit 255
|
|
|
|
case $action in
|
|
"check")
|
|
do_check
|
|
;;
|
|
"download")
|
|
do_download
|
|
;;
|
|
"progress")
|
|
do_progress
|
|
;;
|
|
"cancel")
|
|
do_cancel
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|