contrib/package: remote-update: now expect "openwrt-atheros-combined.img" since we...
[project/luci.git] / contrib / package / remote-update / files / usr / sbin / remote-update
1 #!/bin/sh
2
3 local tempfile=/tmp/remote-upgrade.img
4 local D2='\([0-9]\{2\}\)'
5 local D4='\([0-9]\{4\}\)'
6 local NL='
7 '
8
9 find_architecture()
10 {
11         local ifs="$IFS"; IFS="-"
12         set -- $(opkg list_installed kernel)
13         IFS="$ifs"
14
15         echo "$3"
16 }
17
18 find_image()
19 {
20         case "$1" in
21                 atheros)
22                         echo "openwrt-atheros-combined.img"
23                 ;;
24                 ar71xx)
25                         echo "openwrt-ar71xx-combined.img"
26                 ;;
27                 brcm-2.4)
28                         echo "openwrt-brcm-2.4-squashfs.trx"
29                 ;;
30         esac
31 }
32
33 check_image()
34 {
35         local file; for file in /lib/upgrade/*.sh; do . $file; done
36         if platform_check_image "$1" >/dev/null 2>/dev/null; then
37                 return 0
38         fi
39         return 1
40 }
41
42 find_remote_checksum()
43 {
44         wget -qO- ${1%/*}/md5sums 2>/dev/null | \
45                 sed -ne '/'$2'/ { s/ .*//p }'
46 }
47
48 find_local_checksum()
49 {
50         set -- $(md5sum "$tempfile")
51         echo $1
52 }
53
54 find_remote_info()
55 {
56         wget -qO- "${1%/*}/VERSION.txt" 2>/dev/null
57 }
58
59 find_remote_version()
60 {
61         find_remote_info "$1" | \
62                 sed -ne "s!.*$D4/$D2/$D2 $D2:$D2.*!\\1\\2\\3\\4\\5!p;t"
63 }
64
65 find_local_version()
66 {
67         if [ -f /rom/etc/banner ]; then
68                 sed -ne "s!.*$D4/$D2/$D2 $D2:$D2.*!\\1\\2\\3\\4\\5!p;t" \
69                         /rom/etc/banner
70         else
71                 date +"%Y%m%d%H%M" -r /bin/sh
72         fi
73 }
74
75 stop_service()
76 {
77         [ -x /etc/init.d/$1 ] && {
78                 echo -n "Stopping service $1 ... "
79                 /etc/init.d/$1 stop >/dev/null 2>/dev/null
80                 echo "done"
81         }
82 }
83
84 do_wait()
85 {
86         if [ ${1:-0} -gt 0 ]; then
87                 echo -n "${2:-Waiting} "
88                 for i in $(seq 1 $1); do
89                         printf "%-2dseconds" $(($1-$i))
90                         sleep 1
91                         echo -en "\b\b\b\b\b\b\b\b\b"
92                 done
93                 echo "${NL}"
94         fi
95 }
96
97 version_compare()
98 {
99         local v1="$1"
100         local v2="$2"
101
102         while [ -n "$v1" -o -n "$v2" ]; do
103                 if [ -z "${v2:0:4}" -o "${v1:0:4}" -gt "${v2:0:4}" ]; then
104                         return 1
105                 elif [ -z "${v1:0:4}" -o "${v1:0:4}" -lt "${v2:0:4}" ]; then
106                         return 2
107                 fi
108
109                 v1="${v1:4}"
110                 v2="${v2:4}"
111         done
112
113         return 0
114 }
115
116 usage()
117 {
118         cat <<EOT
119
120 Usage:
121   remote-update -h
122   remote-update [-u <update url>] -c
123   remote-update [-v] [-y] [-u <update url>] -w
124   remote-update [-d] [-n] [-v] [-y] [-s <sleep seconds>] [-u <update url>]
125
126 Actions:
127   -h    Display this help message and exit.
128   -c    Check for firmware update and exit.
129   -w    Fetch image and exit, do not perform flash write.
130
131 Options:
132   -d    Do not detach from terminal.
133   -n    Do not backup configuration.
134   -v    Skip verification of downloaded image.
135   -y    Assume defaults for all questions.
136
137   -s <seconds>
138     Sleep given amount of seconds before starting flash write.
139     If ommitted and '-y' is not used, 5 seconds are assumed.
140
141   -u <url>
142     Fetch firmware image from given url. A file "md5sums" is expected
143     in the same remote directory. If there is no such file, use -v to
144     suppress verification.
145
146 EOT
147
148         exit 1
149 }
150
151
152 while getopts "s:u:cdnvwyh" flag; do
153         case $flag in
154                 s) sleeptime="$OPTARG";;
155                 u) updateurl="$OPTARG";;
156                 c) checkupdate=1;;
157                 d) nodetach=1;;
158                 n) nobackup=1;;
159                 v) noverify=1;;
160                 w) noflash=1;;
161                 y) noquestions=1;;
162                 *) usage;;
163         esac
164 done
165
166
167 local image_url="$updateurl"
168 local image_name="${image_url##*/}"
169
170 [ -z "$image_url" ] && {
171         local arch=$(find_architecture)
172         local image=$(find_image "$arch")
173         local repo=$(uci get freifunk.upgrade.repository 2>/dev/null)
174         repo=${repo:-$(uci get system.upgrade.repository 2>/dev/null)}
175
176         [ -z "$arch" ] && {
177                 echo "Can not determine the current architecture."
178                 exit 1
179         }
180
181         [ -z "$repo" ] && {
182                 echo "No repository configured in 'system.upgrade.repository'."
183                 echo "Use the '-u' flag to specify an image location."
184                 exit 1
185         }
186
187         [ -z "$image" ] && {
188                 echo "No suitable image for the '$arch' architecture."
189                 echo "Your platform is not supported."
190                 exit 1
191         }
192
193         echo "Architecture: $arch"
194         echo "Repository:   $repo"
195
196         image_name="$image"
197         image_url="${repo%/}/$arch/$image"
198 }
199
200
201 if [ "$checkupdate" = 1 ]; then
202         local v1=$(find_local_version)
203         local v2=$(find_remote_version "$image_url")
204
205         [ -n "$v1" -a -n "$v2" ] && {
206                 version_compare "$v1" "$v2"
207                 [ $? == 2 ] && {
208                         echo "Update available!${NL}Local:  $v1${NL}Remote: $v2${NL}--"
209                         find_remote_info "$image_url"
210                         exit 0
211                 } || {
212                         echo "Local version $v1 is up to date"
213                         exit 2
214                 }
215         } || {
216                 echo "No remote time stamp found."
217                 exit 1
218         }
219 else
220         if [ "$noquestions" != 1 ]; then
221                 echo -n "${NL}About to download $image_name. Continue? [y] "
222                 read answer
223                 case "$answer" in
224                         [nN]) exit 1;;
225                 esac
226         fi
227
228         echo -n "Downloading $image_name ... "
229         rm -f $tempfile
230         wget -qO $tempfile "$image_url" 2>/dev/null
231         [ $? == 0 ] && echo done || {
232                 echo failed
233                 rm -f $tempfile
234                 exit 1
235         }
236
237         if [ "$noverify" != 1 ]; then
238                 echo -n "Verifying $image_name ... "
239
240                 local md5_remote=$(find_remote_checksum "$image_url" "$image_name")
241                 local md5_local=$(find_local_checksum)
242
243                 check_image "$tempfile"
244                 local image_ok=$?
245
246                 if [ $image_ok = 0 -a -n "$md5_remote" -a -n "$md5_local" -a "$md5_remote" = "$md5_local" ]; then
247                         echo "done"
248                 else
249                         if [ $image_ok != 0 ]; then
250                                 echo "unsupported image type"
251                         else
252                                 echo "checksum mismatch! (local:${md5_local:-(none)} remote:${md5_remote:-(none)})"
253                         fi
254
255                         local answer=n
256                         if [ "$noquestions" != 1 ]; then
257                                 echo -n "${NL}Verification failed. Continue anyway? [n] "
258                                 read answer
259                         fi
260
261                         case "$answer" in
262                                 [yYjJ]*) : ;;
263                                 *)
264                                         echo "Aborting."
265                                         rm -f $tempfile
266                                         exit 1
267                                 ;;
268                         esac
269                 fi
270         fi
271
272         if [ "$noflash" != 1 ]; then
273                 if [ -f "$tempfile" ]; then
274                         if [ "$noquestions" == 1 ]; then
275                                 do_wait ${sleeptime:-5} "${NL}About to start flashing, hit <Ctrl-C> to abort!${NL}${NL}Starting in"
276                         else
277                                 if [ -z "$nobackup" ]; then
278                                         echo -n "${NL}Keep configuration files? [y] "
279                                         read answer
280                                         case "$answer" in
281                                                 [nN]) nobackup=1;;
282                                         esac
283                                 fi
284
285                                 echo -n "${NL}About to start flashing!${NL}Hit <Enter> to continue or <Ctrl-C> to abort.${NL}"
286                                 read answer
287                         fi
288
289                         for s in lucid collectd; do stop_service $s; done
290
291                         if [ "$nodetach" != 1 ]; then
292                                 echo -n "Starting sysupgrade in background ... "
293                                 /bin/busybox start-stop-daemon -S -b -x /sbin/sysupgrade -- ${nobackup:+-n} "$tempfile"
294                                 echo "done"
295                         else
296                                 echo "Executing sysupgrade ... "
297                                 exec /sbin/sysupgrade ${nobackup:+-n} "$tempfile"
298                         fi
299                 else
300                         echo "No upgrade image found!"
301                         exit 1
302                 fi
303         else
304                 echo "Image saved in '$tempfile'"
305         fi
306 fi