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