File: update-smart-drivedb.in

package info (click to toggle)
smartmontools 6.5%2Bsvn4324-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 3,772 kB
  • ctags: 7,352
  • sloc: cpp: 41,134; ansic: 9,556; sh: 1,339; makefile: 894
file content (385 lines) | stat: -rw-r--r-- 8,443 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#! /bin/sh
#
# smartmontools drive database update script
#
# Copyright (C) 2010-16 Christian Franke
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# You should have received a copy of the GNU General Public License
# (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
#
# $Id: update-smart-drivedb.in 4224 2016-02-26 20:29:24Z chrfranke $
#

set -e

# Set by config.status
PACKAGE="@PACKAGE@"
VERSION="@VERSION@"
prefix="@prefix@"
exec_prefix="@exec_prefix@"
sbindir="@sbindir@"
datarootdir="@datarootdir@"
datadir="@datadir@"
drivedbdir="@drivedbdir@"

# Download tools
os_dltools="@os_dltools@"

# drivedb.h update branch
BRANCH="@DRIVEDB_BRANCH@"

# Default drivedb location
DRIVEDB="$drivedbdir/drivedb.h"

# Smartctl used for syntax check
SMARTCTL="$sbindir/smartctl"

myname=$0

usage()
{
  cat <<EOF
smartmontools $VERSION drive database update script

Usage: $myname [OPTIONS] [DESTFILE]

  -s SMARTCTL     Use SMARTCTL for syntax check ('-s -' to disable)
                  [default: $SMARTCTL]
  -t TOOL         Use TOOL for download: $os_dltools
                  [default: first one found in PATH]
  -u LOCATION     Use URL of LOCATION for download:
                    sf (Sourceforge code browser via HTTPS)
                    svn (SVN repository via HTTPS) [default]
                    svni (SVN repository via HTTP)
                    trac (Trac code browser via HTTPS)
  --cacert FILE   Use CA certificates from FILE to verify the peer
  --capath DIR    Use CA certificate files from DIR to verify the peer
  --insecure      Don't abort download if certificate verification fails
  --dryrun        Print download commands only
  -v              Verbose output

Updates $DRIVEDB
or DESTFILE from smartmontools SVN repository.
Tries to download first from branch $BRANCH
and then from trunk.
EOF
  exit 1
}

error()
{
  echo "$myname: $*" >&2
  exit 1
}

warning()
{
  echo "$myname: (Warning) $*" >&2
}

selecturl()
{
  case $1 in
    sf)   url='https://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/drivedb.h?format=raw' ;;
    svn)  url='https://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h' ;;
    svni) url='http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h' ;;
    trac) url='https://www.smartmontools.org/export/HEAD/trunk/smartmontools/drivedb.h' ;;
    *) usage ;;
  esac
}

inpath()
{
  local d rc save
  rc=1
  save=$IFS
  IFS=':'
  for d in $PATH; do
    test -f "$d/$1" || continue
    test -x "$d/$1" || continue
    rc=0
    break
  done
  IFS=$save
  return $rc
}

vecho()
{
  test -n "$q" || echo "$*"
}

# vrun COMMAND ARGS...
vrun()
{
  if [ -n "$dryrun" ]; then
    echo "$*"
  elif [ -n "$q" ]; then
    "$@" 2>/dev/null
  else
    echo "$*"
    "$@"
  fi
}

# vrun2 OUTFILE COMMAND ARGS...
vrun2()
{
  local f err rc
  f=$1; shift
  rc=0
  if [ -n "$dryrun" ]; then
    echo "$* > $f"
  else
    vecho "$* > $f"
    err=`"$@" 2>&1 > $f` || rc=$?
    if [ -n "$err" ]; then
      vecho "$err" >&2
      test $rc != 0 || rc=42
    fi
  fi
  return $rc
}

# download URL FILE
download()
{
  local f u se rc
  u=$1; f=$2
  rc=0

  case $tool in
    curl)
      vrun curl ${q:+-s} -f --max-redirs 0 \
        ${cacert:+--cacert "$cacert"} \
        ${capath:+--capath "$capath"} \
        ${insecure:+--insecure} \
        -o "$f" "$u" || rc=$?
      ;;

    wget)
      vrun wget $q --max-redirect=0 \
        ${cacert:+--ca-certificate="$cacert"} \
        ${capath:+--ca-directory="$capath"} \
        ${insecure:+--no-check-certificate} \
        -O "$f" "$u" || rc=$?
      ;;

    lynx)
      test -z "$cacert" || vrun export SSL_CERT_FILE="$cacert"
      test -z "$capath" || vrun export SSL_CERT_DIR="$capath"
      # Check also stderr as lynx does not return != 0 on HTTP error
      vrun2 "$f" lynx -stderr -noredir -source "$u" || rc=$?
      ;;

    svn)
      vrun svn $q export \
        --non-interactive --no-auth-cache \
        ${cacert:+--config-option "servers:global:ssl-trust-default-ca=no"} \
        ${cacert:+--config-option "servers:global:ssl-authority-files=$cacert"} \
        ${insecure:+--trust-server-cert} \
        "$u" "$f" || rc=$?
      ;;

    fetch) # FreeBSD
      vrun fetch $q --no-redirect \
        ${cacert:+--ca-cert "$cacert"} \
        ${capath:+--ca-path "$capath"} \
        ${insecure:+--no-verify-hostname} \
        -o "$f" "$u" || rc=$?
      ;;

    ftp) # OpenBSD
      vrun ftp \
        ${cacert:+-S cafile="$cacert"} \
        ${capath:+-S capath="$capath"} \
        ${insecure:+-S dont} \
        -o "$f" "$u" || rc=$?
      ;;

    *) error "$tool: unknown (internal error)" ;;
  esac
  return $rc
}

# Parse options
smtctl=$SMARTCTL
tool=
url=
q="-q"
dryrun=
cacert=
capath=
insecure=

while true; do case $1 in
  -s)
    shift; test -n "$1" || usage
    smtctl=$1 ;;

  -t)
    shift
    case $1 in *\ *) usage ;; esac
    case " $os_dltools " in *\ $1\ *) ;; *) usage ;; esac
    tool=$1 ;;

  -u)
    shift; selecturl "$1" ;;

  -v)
    q= ;;

  --dryrun)
    dryrun=t ;;

  --cacert)
    shift; test -n "$1" || usage
    cacert=$1 ;;

  --capath)
    shift; test -n "$1" || usage
    capath=$1 ;;

  --insecure)
    insecure=t ;;

  -*)
    usage ;;

  *)
    break ;;
esac; shift; done

case $# in
  0) DEST=$DRIVEDB ;;
  1) DEST=$1 ;;
  *) usage ;;
esac

if [ -z "$tool" ]; then
  # Find download tool in PATH
  for t in $os_dltools; do
    if inpath "$t"; then
      tool=$t
      break
    fi
  done
  test -n "$tool" || error "found none of: $os_dltools"
fi

test -n "$url" || selecturl "svn"

# Check option compatibility
case "$tool:$url" in
  svn:http*://svn.code.sf.net*) ;;
  svn:*) error "'-t svn' requires '-u svn' or '-u svni'" ;;
esac
case "$tool:${capath:+set}" in
  svn:set) warning "'--capath' is ignored if '-t svn' is used" ;;
esac
case "${insecure:-f}:$url" in
  t:http:*) insecure= ;;
  ?:https:*) ;;
  *) error "'-u svni' requires '--insecure'" ;;
esac
case "$tool:$insecure" in
  lynx:t) warning "'--insecure' is ignored if '-t lynx' is used" ;;
esac

# Try possible branch first, then trunk
errmsg=
errmsg2=
for location in "branches/$BRANCH" "trunk"; do
  test -z "$errmsg" || errmsg2=$errmsg
  vecho "Download from $location with $tool"

  # Adjust URL
  case $location in
    trunk) src=$url ;;
    *)     src=`echo "$url" | sed "s,/trunk/,/$location/,"` ;;
  esac

  # Download
  test -n "$dryrun" || rm -f "$DEST.new" || exit 1
  rc=0
  download "$src" "$DEST.new" || rc=$?
  test -z "$dryrun" || continue

  errmsg=
  if [ $rc != 0 ]; then
    errmsg="download from $location failed ($tool: exit $rc)"
    continue
  fi

  # Check file contents
  case `sed 1q "$DEST.new"` in
    /*) ;;
    \<*)
      errmsg="download from $location failed (HTML error message)"
      continue ;;
    *)
      errmsg="download from $location failed (Unknown file contents)"
      continue ;;
  esac

  # Check file size
  size=`wc -c < "$DEST.new"`
  if [ "$size" -lt 10000 ]; then
    errmsg="download from $location failed (too small file size $size bytes)"
    continue
  fi
  if [ "$size" -gt 1000000 ]; then
    errmsg="download from $location failed (too large file size $size bytes)"
    break
  fi

  break
done

test -z "$dryrun" || exit 0

if [ -n "$errmsg" ]; then
  rm -f "$DEST.new"
  test -z "$errmsg2" || echo "$myname: $errmsg2" >&2
  error "$errmsg"
fi

# Adjust timestamp and permissions
touch "$DEST.new"
chmod 0644 "$DEST.new"

if [ "$smtctl" != "-" ]; then
  # Check syntax
  rm -f "$DEST.error"
  if "$smtctl" -B "$DEST.new" -P showall >/dev/null; then
    test -n "$q" || echo "$smtctl: syntax OK"
  else
    mv "$DEST.new" "$DEST.error"
    echo "$DEST.error: rejected by $smtctl, probably no longer compatible" >&2
    exit 1
  fi
fi

# Keep old file if identical, ignore missing Id keyword expansion in new file
rm -f "$DEST.lastcheck"
if [ -f "$DEST" ]; then
  if    cmp "$DEST" "$DEST.new" >/dev/null 2>/dev/null \
     || cat "$DEST" | sed 's|\$''Id''[^$]*\$|$''Id''$|' \
        | cmp - "$DEST.new" >/dev/null 2>/dev/null; then
    rm -f "$DEST.new"
    touch "$DEST.lastcheck"
    echo "$DEST is already up to date"
    exit 0
  fi
  mv "$DEST" "$DEST.old"
fi

mv "$DEST.new" "$DEST"

echo "$DEST updated from $location"