#!/bin/sh . /etc/os-release . /lib/functions/uci-defaults.sh API=$(uci -q get ota.config.api_url) WRLOCK=/var/lock/ota_background.lock # armsr/armv8 [ "$OPENWRT_BOARD" = "armsr/armv8" ] && alias board_name="echo armsr,armv8" # x86_64 [ $(uname -m) = "x86_64" ] && alias board_name="echo x86_64" action=${1} shift sha256() { sha256sum $1 | cut -d' ' -f1 } download() { read_json if [ -f /tmp/firmware.img ]; then echo "Checking existed firmware.img..." >> /tmp/firmware.img.progress if [ "`sha256 /tmp/firmware.img`" = "$FW_SHA256SUM" ]; then return 0; else echo "Check failed, redownload" >> /tmp/firmware.img.progress rm -f /tmp/firmware.img fi fi touch /tmp/firmware.img.progress fw_download_tool "$FW_URL" -o /tmp/firmware.img.part -k -L -4 > /tmp/firmware.img.progress 2>&1 & echo "$! $PPID" > /var/run/ota/download.pid while true; do progress=$(grep -c "100.00%" /tmp/firmware.img.progress) if [ "$progress" -ge "1" ]; then echo "Checking new firmware.img.part..." > /tmp/firmware.img.progress break fi sleep 1 done if [ "`sha256 /tmp/firmware.img.part`" = "$FW_SHA256SUM" ]; then mv /tmp/firmware.img.part /tmp/firmware.img && echo $FW_SHA256SUM > /tmp/firmware.img.sha256sum rm -f /tmp/firmware.img.progress return 0 else echo "Checksum failed!" >>/tmp/firmware.img.progress sleep 1 rm -rf /tmp/firmware.img.part return 1 fi } lock_download() { local lock="$WRLOCK" exec 200>$lock flock -n 200 || return download flock -u 200 } # 0: found newer fw, 1: already newest fw, *: err do_check() { url_check=$(curl -I -o /dev/null -s -w %{http_code} "$API") [ $url_check -ne 200 ] && exit 255 curl -s "$API" > /var/run/ota/fw.json read_json NEW_VERSION=$(basename $FW_URL | awk -F- '{if (NF >= 3 && $3 ~ /^rc/) {print $2 "-" $3} else {print $2}}') if [ "$BUILD_DATE" -lt "$FW_BUILD_DATE" ]; then echo "

Model:  $(board_name)
Current Version:  $PRETTY_NAME
Build Date:  $(date "+%Y-%m-%d %H:%M:%S" -d "@$BUILD_DATE")

" echo "

New Version:  OpenWrt $NEW_VERSION
Build Date:  $(date "+%Y-%m-%d %H:%M:%S" -d "@$FW_BUILD_DATE")

" return 0 elif [ "$BUILD_DATE" -ge "$FW_BUILD_DATE" ]; then return 1 else return 255 fi } # async download do_download(){ [ ! -f "/var/run/ota/fw.json" ] && { echo "do check first" >&2 ; return 254; } lock_download & return 0 } # 0: done, 1: downloading, 2: failed, *: err do_progress() { read_json [ -f /tmp/firmware.img.sha256sum ] && [ "`cat /tmp/firmware.img.sha256sum`" = "$FW_SHA256SUM" ] && 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; } tail -1 /tmp/firmware.img.progress | grep -Fq 'Checksum failed!' && { echo "Checksum failed!"; return 254; } grep -v '\r' /tmp/firmware.img.progress >&2 return 1 } 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 -9 $pid >/dev/null 2>&1; do if ! sleep 1; then break fi done rm -rf /tmp/firmware.img* /var/lock/ota_background.lock /var/lock/ota_api.lock /var/run/ota/download.pid echo "" >> /tmp/firmware.img.progress echo "Canceled!" >> /tmp/firmware.img.progress fi fi return 0 } read_json(){ FW_BUILD_DATE=$(jsonfilter -i /var/run/ota/fw.json -e "@['$(board_name)'][0]['build_date']") FW_SHA256SUM=$(jsonfilter -i /var/run/ota/fw.json -e "@['$(board_name)'][0]['sha256sum']") FW_URL=$(jsonfilter -i /var/run/ota/fw.json -e "@['$(board_name)'][0]['url']") } 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