]>
Commit | Line | Data |
---|---|---|
7f0798ef GI |
1 | #! /bin/sh |
2 | # | |
3 | # smartmontools drive database update script | |
4 | # | |
6b80b4d2 | 5 | # Copyright (C) 2010-15 Christian Franke |
7f0798ef GI |
6 | # |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2, or (at your option) | |
10 | # any later version. | |
11 | # | |
12 | # You should have received a copy of the GNU General Public License | |
13 | # (for example COPYING); If not, see <http://www.gnu.org/licenses/>. | |
14 | # | |
6b80b4d2 | 15 | # $Id: update-smart-drivedb.in 4184 2015-12-14 19:20:44Z chrfranke $ |
7f0798ef GI |
16 | # |
17 | ||
18 | set -e | |
19 | ||
20 | # Set by config.status | |
21 | PACKAGE="@PACKAGE@" | |
22 | VERSION="@VERSION@" | |
23 | prefix="@prefix@" | |
24 | exec_prefix="@exec_prefix@" | |
25 | sbindir="@sbindir@" | |
26 | datarootdir="@datarootdir@" | |
27 | datadir="@datadir@" | |
28 | drivedbdir="@drivedbdir@" | |
29 | ||
cfbba5b9 GI |
30 | # Download tools |
31 | os_dltools="@os_dltools@" | |
32 | ||
33 | # drivedb.h update branch | |
34 | BRANCH="@DRIVEDB_BRANCH@" | |
35 | ||
7f0798ef | 36 | # Default drivedb location |
6b80b4d2 | 37 | DRIVEDB="$drivedbdir/drivedb.h" |
7f0798ef GI |
38 | |
39 | # Smartctl used for syntax check | |
40 | SMARTCTL="$sbindir/smartctl" | |
41 | ||
6b80b4d2 | 42 | myname=$0 |
7f0798ef | 43 | |
6b80b4d2 JD |
44 | usage() |
45 | { | |
46 | cat <<EOF | |
7f0798ef GI |
47 | smartmontools $VERSION drive database update script |
48 | ||
6b80b4d2 | 49 | Usage: $myname [OPTIONS] [DESTFILE] |
7f0798ef | 50 | |
6b80b4d2 JD |
51 | -s SMARTCTL Use SMARTCTL for syntax check ('-s -' to disable) |
52 | [default: $SMARTCTL] | |
53 | -t TOOL Use TOOL for download: $os_dltools | |
54 | [default: first one found in PATH] | |
55 | -u LOCATION Use URL of LOCATION for download: | |
56 | sf (Sourceforge code browser via HTTP) | |
57 | svn (SVN repository via HTTPS) [default] | |
58 | svni (SVN repository via HTTP) | |
59 | trac (Trac code browser via HTTPS) | |
60 | --cacert FILE Use CA certificates from FILE to verify the peer | |
61 | --capath DIR Use CA certificate files from DIR to verify the peer | |
62 | --insecure Don't abort download if certificate verification fails | |
63 | --dryrun Print download commands only | |
64 | -v Verbose output | |
7f0798ef | 65 | |
6b80b4d2 | 66 | Updates $DRIVEDB |
7f0798ef GI |
67 | or DESTFILE from smartmontools SVN repository. |
68 | Tries to download first from branch $BRANCH | |
69 | and then from trunk. | |
70 | EOF | |
6b80b4d2 JD |
71 | exit 1 |
72 | } | |
7f0798ef | 73 | |
6b80b4d2 JD |
74 | error() |
75 | { | |
76 | echo "$myname: $*" >&2 | |
77 | exit 1 | |
78 | } | |
7f0798ef | 79 | |
6b80b4d2 JD |
80 | warning() |
81 | { | |
82 | echo "$myname: (Warning) $*" >&2 | |
83 | } | |
84 | ||
85 | selecturl() | |
86 | { | |
87 | case $1 in | |
88 | sf) url='http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/drivedb.h?format=raw' ;; | |
89 | svn) url='https://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h' ;; | |
90 | svni) url='http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h' ;; | |
91 | trac) url='https://www.smartmontools.org/export/HEAD/trunk/smartmontools/drivedb.h' ;; | |
92 | *) usage ;; | |
93 | esac | |
94 | } | |
95 | ||
96 | inpath() | |
97 | { | |
98 | local d rc save | |
99 | rc=1 | |
100 | save=$IFS | |
101 | IFS=':' | |
102 | for d in $PATH; do | |
103 | test -f "$d/$1" || continue | |
104 | test -x "$d/$1" || continue | |
105 | rc=0 | |
cfbba5b9 | 106 | break |
6b80b4d2 JD |
107 | done |
108 | IFS=$save | |
109 | return $rc | |
110 | } | |
111 | ||
112 | vecho() | |
113 | { | |
114 | test -n "$q" || echo "$*" | |
115 | } | |
116 | ||
117 | # vrun COMMAND ARGS... | |
118 | vrun() | |
119 | { | |
120 | if [ -n "$dryrun" ]; then | |
121 | echo "$*" | |
122 | elif [ -n "$q" ]; then | |
123 | "$@" 2>/dev/null | |
124 | else | |
125 | echo "$*" | |
126 | "$@" | |
cfbba5b9 | 127 | fi |
6b80b4d2 JD |
128 | } |
129 | ||
130 | # vrun2 OUTFILE COMMAND ARGS... | |
131 | vrun2() | |
132 | { | |
133 | local f err rc | |
134 | f=$1; shift | |
135 | rc=0 | |
136 | if [ -n "$dryrun" ]; then | |
137 | echo "$* > $f" | |
138 | else | |
139 | vecho "$* > $f" | |
140 | err=`"$@" 2>&1 > $f` || rc=$? | |
141 | if [ -n "$err" ]; then | |
142 | vecho "$err" >&2 | |
143 | test $rc != 0 || rc=42 | |
144 | fi | |
145 | fi | |
146 | return $rc | |
147 | } | |
148 | ||
149 | # download URL FILE | |
150 | download() | |
151 | { | |
152 | local f u se rc | |
153 | u=$1; f=$2 | |
154 | rc=0 | |
155 | ||
156 | case $tool in | |
157 | curl) | |
158 | vrun curl ${q:+-s} -f --max-redirs 0 \ | |
159 | ${cacert:+--cacert "$cacert"} \ | |
160 | ${capath:+--capath "$capath"} \ | |
161 | ${insecure:+--insecure} \ | |
162 | -o "$f" "$u" || rc=$? | |
163 | ;; | |
164 | ||
165 | wget) | |
166 | vrun wget $q --max-redirect=0 \ | |
167 | ${cacert:+--ca-certificate="$cacert"} \ | |
168 | ${capath:+--ca-directory="$capath"} \ | |
169 | ${insecure:+--no-check-certificate} \ | |
170 | -O "$f" "$u" || rc=$? | |
171 | ;; | |
172 | ||
173 | lynx) | |
174 | test -z "$cacert" || vrun export SSL_CERT_FILE="$cacert" | |
175 | test -z "$capath" || vrun export SSL_CERT_DIR="$capath" | |
176 | # Check also stderr as lynx does not return != 0 on HTTP error | |
177 | vrun2 "$f" lynx -stderr -noredir -source "$u" || rc=$? | |
178 | ;; | |
179 | ||
180 | svn) | |
181 | vrun svn $q export \ | |
182 | --non-interactive --no-auth-cache \ | |
183 | ${cacert:+--config-option "servers:global:ssl-trust-default-ca=no"} \ | |
184 | ${cacert:+--config-option "servers:global:ssl-authority-files=$cacert"} \ | |
185 | ${insecure:+--trust-server-cert} \ | |
186 | "$u" "$f" || rc=$? | |
187 | ;; | |
188 | ||
189 | fetch) # FreeBSD | |
190 | vrun fetch $q --no-redirect \ | |
191 | ${cacert:+--ca-cert "$cacert"} \ | |
192 | ${capath:+--ca-path "$capath"} \ | |
193 | ${insecure:+--no-verify-hostname} \ | |
194 | -o "$f" "$u" || rc=$? | |
195 | ;; | |
196 | ||
197 | ftp) # OpenBSD | |
198 | vrun ftp \ | |
199 | ${cacert:+-S cafile="$cacert"} \ | |
200 | ${capath:+-S capath="$capath"} \ | |
201 | ${insecure:+-S dont} \ | |
202 | -o "$f" "$u" || rc=$? | |
203 | ;; | |
204 | ||
205 | *) error "$tool: unknown (internal error)" ;; | |
206 | esac | |
207 | return $rc | |
208 | } | |
209 | ||
210 | # Parse options | |
211 | smtctl=$SMARTCTL | |
212 | tool= | |
213 | url= | |
214 | q="-q" | |
215 | dryrun= | |
216 | cacert= | |
217 | capath= | |
218 | insecure= | |
219 | ||
220 | while true; do case $1 in | |
221 | -s) | |
222 | shift; test -n "$1" || usage | |
223 | smtctl=$1 ;; | |
224 | ||
225 | -t) | |
226 | shift | |
227 | case $1 in *\ *) usage ;; esac | |
228 | case " $os_dltools " in *\ $1\ *) ;; *) usage ;; esac | |
229 | tool=$1 ;; | |
230 | ||
231 | -u) | |
232 | shift; selecturl "$1" ;; | |
233 | ||
234 | -v) | |
235 | q= ;; | |
236 | ||
237 | --dryrun) | |
238 | dryrun=t ;; | |
239 | ||
240 | --cacert) | |
241 | shift; test -n "$1" || usage | |
242 | cacert=$1 ;; | |
243 | ||
244 | --capath) | |
245 | shift; test -n "$1" || usage | |
246 | capath=$1 ;; | |
247 | ||
248 | --insecure) | |
249 | insecure=t ;; | |
250 | ||
251 | -*) | |
252 | usage ;; | |
253 | ||
254 | *) | |
255 | break ;; | |
256 | esac; shift; done | |
257 | ||
258 | case $# in | |
259 | 0) DEST=$DRIVEDB ;; | |
260 | 1) DEST=$1 ;; | |
261 | *) usage ;; | |
262 | esac | |
263 | ||
264 | if [ -z "$tool" ]; then | |
265 | # Find download tool in PATH | |
266 | for t in $os_dltools; do | |
267 | if inpath "$t"; then | |
268 | tool=$t | |
269 | break | |
270 | fi | |
271 | done | |
272 | test -n "$tool" || error "found none of: $os_dltools" | |
7f0798ef GI |
273 | fi |
274 | ||
6b80b4d2 JD |
275 | test -n "$url" || selecturl "svn" |
276 | ||
277 | # Check option compatibility | |
278 | case "$tool:$url" in | |
279 | svn:http*://svn.code.sf.net*) ;; | |
280 | svn:*) error "'-t svn' requires '-u svn' or '-u svni'" ;; | |
281 | esac | |
282 | case "$tool:${capath:+set}" in | |
283 | svn:set) warning "'--capath' is ignored if '-t svn' is used" ;; | |
284 | esac | |
285 | case "${insecure:-f}:$url" in | |
286 | t:http:*) insecure= ;; | |
287 | ?:https:*) ;; | |
288 | *) error "'-u sf' and '-u svni' require '--insecure'" ;; | |
289 | esac | |
290 | case "$tool:$insecure" in | |
291 | lynx:t) warning "'--insecure' is ignored if '-t lynx' is used" ;; | |
292 | esac | |
293 | ||
7f0798ef | 294 | # Try possible branch first, then trunk |
6b80b4d2 JD |
295 | errmsg= |
296 | errmsg2= | |
7f0798ef | 297 | for location in "branches/$BRANCH" "trunk"; do |
6b80b4d2 JD |
298 | test -z "$errmsg" || errmsg2=$errmsg |
299 | vecho "Download from $location with $tool" | |
7f0798ef | 300 | |
6b80b4d2 JD |
301 | # Adjust URL |
302 | case $location in | |
303 | trunk) src=$url ;; | |
304 | *) src=`echo "$url" | sed "s,/trunk/,/$location/,"` ;; | |
305 | esac | |
306 | ||
307 | # Download | |
308 | test -n "$dryrun" || rm -f "$DEST.new" || exit 1 | |
309 | rc=0 | |
310 | download "$src" "$DEST.new" || rc=$? | |
311 | test -z "$dryrun" || continue | |
7f0798ef | 312 | |
6b80b4d2 JD |
313 | errmsg= |
314 | if [ $rc != 0 ]; then | |
315 | errmsg="download from $location failed ($tool: exit $rc)" | |
7f0798ef GI |
316 | continue |
317 | fi | |
6b80b4d2 JD |
318 | |
319 | # Check file contents | |
320 | case `sed 1q "$DEST.new"` in | |
321 | /*) ;; | |
322 | \<*) | |
323 | errmsg="download from $location failed (HTML error message)" | |
324 | continue ;; | |
325 | *) | |
326 | errmsg="download from $location failed (Unknown file contents)" | |
327 | continue ;; | |
328 | esac | |
329 | ||
330 | # Check file size | |
331 | size=`wc -c < "$DEST.new"` | |
332 | if [ "$size" -lt 10000 ]; then | |
333 | errmsg="download from $location failed (too small file size $size bytes)" | |
7f0798ef GI |
334 | continue |
335 | fi | |
6b80b4d2 JD |
336 | if [ "$size" -gt 1000000 ]; then |
337 | errmsg="download from $location failed (too large file size $size bytes)" | |
338 | break | |
339 | fi | |
7f0798ef GI |
340 | |
341 | break | |
342 | done | |
343 | ||
6b80b4d2 JD |
344 | test -z "$dryrun" || exit 0 |
345 | ||
7f0798ef GI |
346 | if [ -n "$errmsg" ]; then |
347 | rm -f "$DEST.new" | |
6b80b4d2 JD |
348 | test -z "$errmsg2" || echo "$myname: $errmsg2" >&2 |
349 | error "$errmsg" | |
7f0798ef GI |
350 | fi |
351 | ||
352 | # Adjust timestamp and permissions | |
353 | touch "$DEST.new" | |
354 | chmod 0644 "$DEST.new" | |
355 | ||
6b80b4d2 JD |
356 | if [ "$smtctl" != "-" ]; then |
357 | # Check syntax | |
358 | rm -f "$DEST.error" | |
359 | if "$smtctl" -B "$DEST.new" -P showall >/dev/null; then | |
360 | test -n "$q" || echo "$smtctl: syntax OK" | |
361 | else | |
362 | mv "$DEST.new" "$DEST.error" | |
363 | echo "$DEST.error: rejected by $smtctl, probably no longer compatible" >&2 | |
364 | exit 1 | |
365 | fi | |
7f0798ef GI |
366 | fi |
367 | ||
6b80b4d2 | 368 | # Keep old file if identical, ignore differences in Id string |
7f0798ef GI |
369 | rm -f "$DEST.lastcheck" |
370 | if [ -f "$DEST" ]; then | |
6b80b4d2 JD |
371 | if cat "$DEST" | sed 's|\$''Id''[^$]*\$|$''Id''$|' \ |
372 | | cmp - "$DEST.new" >/dev/null 2>/dev/null; then | |
7f0798ef GI |
373 | rm -f "$DEST.new" |
374 | touch "$DEST.lastcheck" | |
375 | echo "$DEST is already up to date" | |
376 | exit 0 | |
377 | fi | |
378 | mv "$DEST" "$DEST.old" | |
379 | fi | |
380 | ||
381 | mv "$DEST.new" "$DEST" | |
382 | ||
383 | echo "$DEST updated from $location" | |
384 |