diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:14:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:14:45 +0000 |
commit | 43e8530e93493bb978c446a2023134bdd4277e50 (patch) | |
tree | e8c0d3c0c394b17381f48fb2d288f166b4f22440 /os_win32/update-smart-drivedb.ps1.in | |
parent | Initial commit. (diff) | |
download | smartmontools-43e8530e93493bb978c446a2023134bdd4277e50.tar.xz smartmontools-43e8530e93493bb978c446a2023134bdd4277e50.zip |
Adding upstream version 7.4.upstream/7.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'os_win32/update-smart-drivedb.ps1.in')
-rw-r--r-- | os_win32/update-smart-drivedb.ps1.in | 841 |
1 files changed, 841 insertions, 0 deletions
diff --git a/os_win32/update-smart-drivedb.ps1.in b/os_win32/update-smart-drivedb.ps1.in new file mode 100644 index 0000000..ffec165 --- /dev/null +++ b/os_win32/update-smart-drivedb.ps1.in @@ -0,0 +1,841 @@ +# +# smartmontools drive database update script for Windows +# +# Home page of code is: https://www.smartmontools.org +# +# Copyright (C) 2022-23 Christian Franke +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# $Id: update-smart-drivedb.ps1.in 5515 2023-07-24 12:58:25Z chrfranke $ +# + +<# + .SYNOPSIS + Update smartmontools @VERSION@ drive database. + + .DESCRIPTION + update-smart-drivedb.ps1 updates SCRIPTDIR/drivedb.h from + branches/@DRIVEDB_BRANCH@ of smartmontools SVN repository. + + The downloaded file is verified with OpenPGP/GPG key ID 721042C5. + The public key block is included in the script. + + .PARAMETER Smartctl + Use this smartctl executable for syntax check ('-Smartctl -' to + disable). The default is smartctl.exe in script directory. + + .PARAMETER UrlOf + Use the URL of one of the following locations for download: + github (GitHub mirror of SVN repository) + sf (Sourceforge code browser) + svn (SVN repository) + svni (SVN repository via HTTP instead of HTTPS) + trac (Trac code browser) + The default is 'svn'. + + .PARAMETER Url + Download from this URL. A valid OpenPGP/GPG signature with '.raw.asc' + extension must also exist unless '-NoVerify' is also specified. + + .PARAMETER File + Copy from local file. A valid OpenPGP/GPG signature 'FILE.raw.asc' + must also exist unless '-NoVerify' is also specified. + + .PARAMETER Trunk + Download from SVN trunk. This requires '-NoVerify' because the trunk + versions are not signed. + + .PARAMETER Branch + If '-Branch X.Y' is specified, download from + branches/RELEASE_X_Y_DRIVEDB. This also selects the OpenPGP/GPG key + for older branches (5.40 to 6.6: Key ID DFD22559). + + .PARAMETER Insecure + Don't abort download if certificate verification fails. This option + is also required if a HTTP URL is selected with '-UrlOf' option. + If a HTTPS URL is selected, PowerShell >= 6.0 is required. + + .PARAMETER NoVerify + Don't verify signature with GnuPG. + + .PARAMETER Force + Allow downgrades. By default, the database is not replaced with an + older version of the same branch. + + .PARAMETER ExportKey + Print the OpenPGP/GPG public key block. + + .PARAMETER DryRun + Print download commands only. + + .PARAMETER Quiet + Suppress info messages. + + .PARAMETER Drivedb + Destination drive database file. + The default is drivedb.h in script directory. + + .EXAMPLE + update-smart-drivedb.ps1 + /INSTALLPATH/drivedb.h 7.2/5225 updated to 7.2/5237 + + (Regular update) + + .EXAMPLE + update-smart-drivedb.ps1 -Force -File /INSTALLPATH/drivedb.h.old + /INSTALLPATH/drivedb.h 7.2/5237 downgraded to 7.2/5225 + + (Revert to previous version) + + .EXAMPLE + update-smart-drivedb -Trunk -NoVerify -Smartctl - drivedb-trunk.h + drivedb-trunk.h 7.3/5254 newly installed (NOT VERIFIED) + + (Download the database from SVN trunk to current directory) + + .LINK + https://www.smartmontools.org/ +#> + +param ( + [string]$Smartctl, + [string]$UrlOf, + [string]$Url, + [string]$File, + [switch]$Trunk, + [string]$Branch, + [switch]$Insecure, + [switch]$NoVerify, + [switch]$Force, + [switch]$ExportKey, + [switch]$DryRun, + [switch]$Quiet, + #[switch]$Verbose, # Common parameter + [Parameter(Position=0)][string]$Drivedb +) + +$ErrorActionPreference = "Stop" + +# Set by config.status +# Default drivedb.h update branch +$default_branch="@DRIVEDB_BRANCH@" + +# GnuPG used to verify signature (disabled if empty) +$gpg = "@gnupg@" + +# Name and Directory of this script +$myname = $MyInvocation.MyCommand.Name +$mydir = Split-Path -Path $MyInvocation.MyCommand.Source +if (!$mydir) { + throw "Unknown script directory" +} + +# Default drivedb location +$default_drivedb = "$mydir\drivedb.h" + +# Default command used for syntax check +$default_smartctl = "$mydir\smartctl" + +function error($message) +{ + # Echo error messages to stdout because 'Write-Error' + # always writes a full 'ErrorRecord' to stderr. + echo "${myname}: $message" + exit 1 +} + +function warning($message) +{ + echo "${myname}: (Warning) $message" +} + +function iecho($message) +{ + if (!$script:Quiet) { + echo $message + } +} + +function vecho($message) +{ + $message | Write-Verbose +} + +function test_f($file) +{ + return Test-Path -PathType Leaf -LiteralPath $file +} + +function touch($file) +{ + if (Test-Path -PathType Leaf -LiteralPath $file) { + (Get-Item $file).LastWriteTime = Get-Date + } else { + New-Item -ItemType File -Path $file | Out-Null + } +} + +function cmp($file1, $file2) +{ + if (!( (Test-Path -PathType Leaf -LiteralPath $file1) ` + -and (Test-Path -PathType Leaf -LiteralPath $file2))) { + return $false + } + return (Get-FileHash $file1).hash -eq (Get-FileHash $file2).hash +} + +function rm_f # FILE... +{ + foreach ($file in $args) { + if (Test-Path -PathType Leaf -LiteralPath $file) { + Remove-Item $file + } + } +} + +function rm_rf($dir) +{ + if (Test-Path -PathType Container -LiteralPath $dir) { + Remove-Item -Recurse $dir + } +} + +function mv_f($oldfile, $newfile) +{ + rm_f $newfile + Rename-Item $oldfile $newfile +} + +function selecturl($url_of, [ref]$url) +{ + switch ($url_of) { + 'github' { + # https://github.com/smartmontools/smartmontools/raw/origin/$branch/smartmontools/drivedb.h + # https://github.com/smartmontools/smartmontools/raw/master/smartmontools/drivedb.h + # redirected to: + $u = 'https://raw.githubusercontent.com/smartmontools/smartmontools/master/smartmontools/drivedb.h' + } + 'sf' { $u = 'https://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/drivedb.h?format=raw' } + 'svn' { $u = 'https://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h' } + 'svni' { $u = 'http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h' } + 'trac' { $u = 'https://www.smartmontools.org/export/HEAD/trunk/smartmontools/drivedb.h' } + default { error "${url_of}: is none of 'github sf svn svni trac'" } + } + $url.Value = $u +} + +function vcopy($src, $dest) +{ + if ($script:DryRun) { + echo "Copy-Item $src $dest" + } else { + vecho "Copy-Item $src $dest" + Copy-Item $src $dest + } +} + +function download($url, $file, [ref]$errmsg) +{ + $req = @{ Uri = $url; OutFile = $file; MaximumRedirection = 0 } + if ($script:Insecure) { + # #Requires -Version 6 + $req += @{ SkipCertificateCheck = $true } + } + + $errmsg.Value = "" + if ($script:DryRun) { + echo "Invoke-WebRequest $(echo @req)" + } else { + try { + Invoke-WebRequest @req + } catch { + if ($_.Exception.Message) { + $errmsg.Value = $_.Exception.Message + } else { + $errmsg.Value = "Unknown error" + } + } + } +} + +function check_file($file, $firstchar, $minsize, $maxsize) +{ + # Check file size + $size = (Get-Item -LiteralPath $file).Length + if ($size -lt $minsize) { + return "too small file size $size bytes" + } + if ($size -gt $maxsize) { + return "too large file size $size bytes" + } + + # Check first chars + switch ((Get-Content -LiteralPath $file -TotalCount 1).ToCharArray()[0]) { + "$firstchar" { } + "<" { return "HTML error message" } + default { return "unknown file contents" } + } + + return "" +} + +function unexpand_svn_id($source, $dest) +{ + # For -NoNewLine: + #Requires -Version 5 + (Get-Content -Raw -Path $source) -replace ` + ('\$'+'Id: drivedb\.h [0-9][0-9]* 2[-0-9]* [012][:0-9]*Z [a-z][a-z0-9]* \$'),('$'+'Id'+'$') ` + | Set-Content -NoNewLine -Path $dest +} + +function selectkey($branch, [ref]$key) +{ + switch -RegEx ($branch) { + '^RELEASE_(5_4[0-3]|6_[0-6])_DRIVEDB$' { +# Smartmontools Signing Key (ext. to 2024) <smartmontools-database@listi.jpberlin.de> +# Smartmontools Signing Key (through 2018) <smartmontools-database@listi.jpberlin.de> +# Smartmontools Signing Key (through 2018) <smartmontools-database@lists.sourceforge.net> +# Key ID DFD22559 + $key.Value = ` +'-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +1TC5jSVOIEqOE4TwzRz1Y/dfqSU= +=3Lcg +-----END PGP PUBLIC KEY BLOCK----- +' + } + + '^RELEASE_7_[023]_DRIVEDB$' { +# Smartmontools Signing Key (through 2025) <smartmontools-database@listi.jpberlin.de> +# Smartmontools Signing Key (through 2020) <smartmontools-database@listi.jpberlin.de> +# Key ID 721042C5 + $key.Value = ` +'-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +90iSgZdt5cZgoH04weXCMwDugn/+Q3rzKvRUTrEfSOivJYg65D/mhbz6HoUTs4JD +SstTYa9qNCwKQGRSeis4PAgu0hCpnDAhZuN3Ja5AFC2Wi2szQ7R+Zx/JucIBm5S4 +U30W66MtsyUHeulSJ3AV3HrbFfnqu6zfQM4XLw7MpAtQUNJceS/lWfGIquAp3tY/ +IjZIHwgZqKB3czWDhM83wBzCWgAmxyzIrpb4MBYJ5PGuCyC7R/YTdtPJXxsPQl2l +znsX/9ssa4kBHAQTAQIABgUCX+CfSAAKCRDzh2PO39IlWVcuB/9UkLaPtGY4sDDV +/A7qjSvSy93mv8gkaIj9dhqoZw+r7cLiEtX04Cz9PqocOFgCYJXKrufHNNkHke2A +jE9EJfRKiPU/bkeWmrACvtrOd/DZbdmXfxTOekOr516D2ip/U8GBPw6zxfCQVot6 +htpBpB6zzMDtzMOeLnkOxoxR4EMu5K6eJ48bHvG/lbGBByyfRzhtqPh6AAA9G1CC +IdhNkaA5W1qums3N1mCXrTBnWyjaFhdnttGQfrMdHvTQ77HeL0c2axT2y5PYfrXY +2ZfZowYLEtFXRSTpDaJfgG+qem3N+pMv6SMOG/4CvlH4/3Hq0aCNvKcY5KUXfIgT +xmc3/n/wtFNTbWFydG1vbnRvb2xzIFNpZ25pbmcgS2V5ICh0aHJvdWdoIDIwMjAp +IDxzbWFydG1vbnRvb2xzLWRhdGFiYXNlQGxpc3RpLmpwYmVybGluLmRlPokCPgQT +AQIAKAIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AFAl/gnzAFCQ0umpsACgkQ +6nSrJXIQQsVK7RAAqbZfT3wZEfJkw8MK2JlvgGWH76fHKn5ZoH5i0mA4AvN4QLbU +5Q20HmqHnO9mfAZQ6u4Tn/aFcYT7nlSsEsEmFX+s5QU2y6m2Tx9ThDbZ03ezREOS +0wNf0FOQunV9ZVPT/7cKIgWJa5mZy+LClor9OHllyGUfs9tKNzwxaHh1zBrCNJow +Fi/1bkWy3iMc7vZhWHASwPSp64KHjB4UdMz2hV4pROiUhWi7BY0exIHyZrkcANMP +Hhl9lP32ZvNbOy8osBdPUgXyK3HePD+ftcwJMkoc4mFQXYi9UY7NQpk7STRO10cx +Kq/CgDDvYxbnViRjQoJ0sfwKCaOfsnY/gea7I0aCx8uNISYpHO9iMidd/tJ7+lgx +NiKZTI0EppHYvkyMY15/NGb0gTJbYjuVYdbqDS9mnLuLQAjAX43+n9ND2NjX1o0q +Z9bBqV2VFioNmnxKqGphhRFX9jEzTklieOjhpRrd8v9ljprT6vLFNpYpeLkel8om +VFXrHxrfzKtVFcto5wqHVOcyZyE2zm1QmsS8qvWOTrNfY6p2q9MA2rysqdfgfvN7 +pNDaXutK6ooQi6YlyyTA2ANnHFKa0ncRH+dg+5OF9rhNvM7RyaBXgxF7+5gnU5Gb +VQRKbJ+LOtSKkj0pApR5AKSwyGslZ2bNVlKsADWhk5xj8QlHVlNWiht+i/6JARwE +EwECAAYFAlwmhpwACgkQL83sC9OvGqsVOggAqLB5eQrUv8E9ikD6kJCito827bzD +WF29yD7PvfhjXaz5in54jOVpwg3o9CsqIjjRW0/1bBVswC8ZL0sAdZ+GDSDMw5F2 +IpkD77gjnFY79M/e6C9xYyxYzHC7emDPSz9IroOvdkkEgrB+OABKkaOCcS18P4Lk +3WNHaPw5c7aI0z1iJP52EmSfvB8r86mtUFJB+f15eD/4vaRfkZLFjF9FQ3kgEK1U ++rV4s1O2bCFfP3WPDcc83NgwRUvtXmcSOSOIoXnemJzyJr+JnqCWVET4XWF6i20m +RFXVEpWtf5AkJYgR3z/jW0djELbBWA/35bAnpXy5pDHv9NbZsTkBZxK/kokBHAQT +AQIABgUCXCaGnQAKCRAY7NpGy/a6xn4lB/90tXTnZsgmoftol9uivfQrPdR88WmO +ZLYmUeQAd1rqSFMxe+KzO/qLuU8s6OF4nznwL2cPfbGZxezM4PiYmAmbbEU/3gTO +NwjVBBA0Gfimy/fITEezFtCigo1thkaJ195g/dqY+zE3Vt4rzC03j1vx8mUHRPU6 +kkvKj8cP0j+XHX2xQDsTXTstfnom29wBmGnvSZ9HgcdL71e1VXJXwikmnO3P4J/1 +C2LeCOlWrGqWZ2c0WBLKdJnsYUx7Dm/OvkkB4lF+zWp98zS8jS/5h+1apVgEzrdT +MvT8ydTkUr7ObKGkIhK+L+Xo5BD+V9Qf6xKGYPwhhdj/E5/kyjULrm10iQEcBBMB +AgAGBQJcJoadAAoJEPOHY87f0iVZfiUH/3yKS5wGvTeRInse8+W1WzKuto3XzqXL +ngb9QXWw7nCwqmNS7PbzDnufQi2ThKrMfcK14WgNYABNZPU75I+6bcb0oCB5tloo +IUEV/2Ut/5Hl/83zFFoNA/kQKVz8kIDqgRcxC+zY2VJ4eTKHyQDvXygVk8wnKTBa +e3gX+CIZqJHPXiiygHlbl31Mi3G1Iaxu57dP6ocV0vX1dytKSwd4Rbviwwb4L76o +/tVT9t3GwFM15uK1SqtnAaiaktEdMi3XI4d01H3VUVz/iR0XQbf13RZoEM6CJWms +Q/qvYlwkbKOdlahjoHrFlkhADSBaO9N1OZp3OYDjziIujMdt2IPKnmM= +=7MQk +-----END PGP PUBLIC KEY BLOCK----- +' + } + + default { + error "No known public key for branches/${branch}" + } + } +} + +function run_join_out_err($cmd) # $arg1, $arg2, ... +{ + $cmdobj = Get-Command -CommandType Application -Name $cmd + # Don't prepend $input with BOM + $enc = [Console]::InputEncoding + [Console]::InputEncoding = [System.Text.UTF8Encoding]::new() + $ErrorActionPreference = "Continue" # Don't abort command on first stderr output + $LASTEXITCODE = 42 + # Run command and convert ErrorRecords from stderr to plain Strings + $($input | & $cmdobj @args 2>&1) | %{ $_.ToString() } + $ErrorActionPreference = "Stop" + [Console]::InputEncoding = $enc +} + +function gpg_verify($ascfile, $file, [ref]$ok) +{ + # Create temp home dir + if (!$env:TEMP) { error "Environment variable TEMP is not set" } + $gnupgtmp = Join-Path $env:TEMP "gnupg.$(New-Guid)" + rm_rf $gnupgtmp + New-Item -Type Directory -Path $gnupgtmp | Out-Null + + # Import public key + $env:LC_MESSAGES = "C" + $out = ($public_key | run_join_out_err $gpg "--batch" "--no-tty" "--homedir=$gnupgtmp" "--import") + if ($LASTEXITCODE -ne 0) { + echo $out + exit 1 + } + vecho $out + + # Verify + $out = run_join_out_err $gpg "--batch" "--no-tty" "--homedir=$gnupgtmp" "--verify" $ascfile $file + if ($LASTEXITCODE -eq 0) { + vecho $out + $ok.Value = $true + } + else { + # print gpg error always + echo $out + $ok.Value = $false + } + + # Stop the gpg-agent possibly started by gpg + if ($gpgconf) { + $out = run_join_out_err $gpgconf "--homedir=$gnupgtmp" "--kill" "gpg-agent" + if ($LASTEXITCODE -ne 0) { + echo $out + } + } + + # Remove temp home dir + try { + rm_rf "$gnupgtmp" + } catch { + warning "$_" + } +} + +function get_db_version($file) +{ + $x = (Select-String -CaseSensitive -Pattern '^[ {]*"VERSION: *[^"]*"' -Path $file).Line ` + -replace '^[ {]*"VERSION: ([1-9][./0-9]* [^"]*)".*$','$1' + $v = $x -replace ' .*$','' + if ($v -match '^[1-9][.0-9]*$') { # trunk: get rev from expanded SVN-Id + $r = $x -replace '^[^$]*\$Id: drivedb\.h ([1-9][0-9]*) .*$','$1' + if (!($r -match '^[1-9][0-9]*$')) { + $r = "?" + } + $v = "$v/$r" + } elseif (!($v -match '^[1-9][./0-9]*$')) { + return "" + } + return $v +} + +function mv_all($prefix, $old, $new) +{ + mv_f "${prefix}${old}" "${prefix}${new}" + mv_f "${prefix}${old}.raw" "${prefix}${new}.raw" + if (test_f "${prefix}${old}.raw.asc") { + mv_f "${prefix}${old}.raw.asc" "${prefix}${new}.raw.asc" + } else { + rm_f "${prefix}${new}.raw.asc" + } +} + +# Set defaults +if (!$Smartctl) { + $Smartctl = $default_smartctl +} + +if ($Branch) { + $brname = $Branch -replace '^([567])\.([0-9][0-9]*)$','RELEASE_$1_$2_DRIVEDB' + if ($brname -eq $Branch) { + error "invalid branch version '${Branch}'" + } +} else { + $brname = $default_branch +} + +if (!$Drivedb) { + $Drivedb = $default_drivedb +} + +if ($ExportKey) { + $key = "" + selectkey $brname ([ref]$key) + echo $key + exit 0 +} + +# Check selected source +if (!$Url -and !$File) { + if (!$UrlOf) { + $UrlOf = "svn" + } + $Url = "" + selecturl $UrlOf ([ref]$Url) + if (!$Trunk) { + $Url = $Url -replace "/trunk/","/branches/$brname/" + $Url = $Url -replace "/master/","/origin/$brname/" + } elseif (!$NoVerify) { + error "'-Trunk' requires '-NoVerify'" + } +} elseif (!$UrlOf -and $Url -and !$File) { + if (!($Url -match '^[a-z][a-z0-9]*:[^ ][^ ]*$')) { + error "${Url}: Invalid URL" + } +} elseif (!$UrlOf -and !$Url -and $File) { +} else { + error "only one of '-UrlOf', '-Url', '-File' is allowed" +} + +# Determine path of signature file +$FileAsc = "" +$UrlAsc = "" +if (!$NoVerify) { + if (!$Url) { + $FileAsc = "${File}.raw.asc" + } elseif ($Url -match '\?') { + $UrlAsc = $Url -replace '\?','.raw.asc?' + } else { + $UrlAsc = "${Url}.raw.asc" + } +} + +# Check option compatibility +if ($UrlOf -eq "svni") { + if ($Insecure) { + $Insecure = $false + } + else { + error "'-UrlOf svni' requires '-Insecure'" + } +} + +# Check for smartctl +if ($Smartctl -ne "-") { + if (!(Get-Command -Type Application -Name $Smartctl -ErrorAction Ignore)) { + error "${Smartctl}: not found ('-Smartctl -' to ignore)" + } +} + +# Check for GnuPG +$gpgconf = "" +if (!$NoVerify) { + $gpgobj = $null + if ($gpg) { + $gpgobj = Get-Command -Type Application -Name $gpg -ErrorAction Ignore + } + if (!$gpgobj) { + error "GnuPG is not available ('-NoVerify' to ignore)" + } + $public_key = "" + selectkey $brname ([ref]$public_key) + # Check for gpgconf in same directory + $gpgconf = "gpgconf" + $gpgconfobj = Get-Command -Type Application -Name $gpgconf -ErrorAction Ignore; + if (!($gpgconfobj -and ((Split-Path $gpgobj.Source) -eq (Split-Path $gpgconfobj.Source)))) { + $gpgconf = "" + } +} + +# Remove possible garbage from last download +if (!$DryRun) { + rm_f "${Drivedb}.new" "${Drivedb}.new.raw" "${Drivedb}.new.raw.asc" +} + +if ($Url) { + # Download + vecho "Download drivedb.h" + $errmsg = "" + download $Url "${Drivedb}.new" ([ref]$errmsg) + if ($errmsg) { + rm_f "${Drivedb}.new" + error "drivedb.h: download failed: $errmsg" + } + + if ($UrlAsc) { + vecho "Download drivedb.h.raw.asc" + download $UrlAsc "${Drivedb}.new.raw.asc" ([ref]$errmsg) + if ($errmsg) { + rm_f "${Drivedb}.new" "${Drivedb}.new.raw.asc" + error "drivedb.h.raw.asc: download failed: $errmsg ('-NoVerify' to ignore)" + } + } +} else { + # Copy from local file + if (!(test_f $File)) { + error "${File}: file not found" + } + if ($FileAsc -and !(test_f $FileAsc)) { + error "${FileAsc}: file not found ('-NoVerify' to ignore)" + } + + vcopy $File "${Drivedb}.new" + if ($FileAsc) { + vcopy $FileAsc "${Drivedb}.new.raw.asc" + } +} + +if ($DryRun) { + exit 0 +} + +# Check files and adjust timestamps +$errmsg = check_file "${Drivedb}.new" '/' 10000 1000000 +if ($errmsg) { + rm_f "${Drivedb}.new.raw.asc" + mv_f "${Drivedb}.new" "${Drivedb}.error" + error "${Drivedb}.error: $errmsg" +} +touch "${Drivedb}.new" + +if (test_f "${Drivedb}.new.raw.asc") { + $errmsg = check_file "${Drivedb}.new.raw.asc" '-' 200 2000 + if ($errmsg) { + rm_f "${Drivedb}.new" + mv_f "${Drivedb}.new.raw.asc" "${Drivedb}.error.raw.asc" + error "${Drivedb}.error.raw.asc: $errmsg" + } + touch "${Drivedb}.new.raw.asc" +} + +# Create raw file with unexpanded SVN Id +# (This assumes newlines are LF and not CR/LF) +unexpand_svn_id "${Drivedb}.new" "${Drivedb}.new.raw" + +# Check whether installed file is identical +$equal = $false +if (test_f $Drivedb) { + if (!(test_f "${Drivedb}.raw")) { + # Create missing raw file + unexpand_svn_id "${Drivedb}" "${Drivedb}.raw" + } + # Ignore missing Id keyword expansion in new file + if ( (cmp "${Drivedb}.raw" "${Drivedb}.new.raw") ` + -and ( (cmp "${Drivedb}" "${Drivedb}.new") ` + -or (cmp "${Drivedb}.raw" "${Drivedb}.new"))) { + $equal = $true + } +} + +if (!$NoVerify) { + # Verify raw file + $ok = $false + gpg_verify "${Drivedb}.new.raw.asc" "${Drivedb}.new.raw" ([ref]$ok) + if (!$ok) { + mv_all $Drivedb ".new" ".error" + if ($equal) { + warning "${Drivedb}: *** installed file is identical to broken new file ***" + } + error "${Drivedb}.error.raw: *** BAD signature or outdated key ***" + } +} + +# Get version +$newver = get_db_version "${Drivedb}.new" +if (!$newver) { + if (!$Force) { + mv_all $Drivedb ".new" ".error" + error "${Drivedb}.error: no VERSION information found ('-Force' to ignore)" + } + $newver = "?/?" +} elseif ($newver -match '/\?$') { + if (!$Trunk) { + mv_all $Drivedb ".new" ".error" + error "${Drivedb}.error: VERSION information is incomplete ('-Trunk' to ignore)" + } +} + +if ($Smartctl -ne "-") { + # Check syntax + run_join_out_err $Smartctl -B "${Drivedb}.new" -P showall | Out-Null + if (!$?) { + mv_all $Drivedb ".new" ".error" + error "${Drivedb}.error: rejected by $Smartctl, probably no longer compatible" + } + vecho "${Smartctl}: syntax OK" +} + +# Always install if missing +rm_f "${Drivedb}.lastcheck" +if (!(Test-Path -PathType Leaf -Path $Drivedb)) { + mv_all $Drivedb ".new" "" + iecho "$Drivedb $newver newly installed$(if ($NoVerify) {" (NOT VERIFIED)"})" + exit 0 +} + +# Keep old file if identical +if ($equal) { + if (test_f "${Drivedb}.new.raw.asc") { + if (!(cmp "${Drivedb}.new.raw.asc" "${Drivedb}.raw.asc")) { + mv_f "${Drivedb}.new.raw.asc" "${Drivedb}.raw.asc" + iecho "${Drivedb}.raw.asc $newver updated" + } + } + rm_f "${Drivedb}.new" "${Drivedb}.new.raw" "${Drivedb}.new.raw.asc" + touch "${Drivedb}.lastcheck" + iecho "$Drivedb $newver is already up to date$(if ($NoVerify) {" (NOT VERIFIED)"})" + exit 0 +} + +# Check branch and file version +$oldver = $(get_db_version "${Drivedb}") +if (!$oldver) { + $oldver = "?/?" +} + +if ( ($newver -match '/\?$') ` + -or ($oldver -match '/\?$') ` + -or (($newver -replace '/.*$','') -ne ($oldver -replace '/.*$',''))) { + # Always install from trunk or other branch + $updmsg = "replaced with" +} elseif ((($newver -replace '^.*/','') - ($oldver -replace '^.*/','')) -lt 0) { + # Install older file only if '-Force' is used + if (!$Force) { + rm_f "${Drivedb}.new" "${Drivedb}.new.raw" "${Drivedb}.new.raw.asc" + iecho "$Drivedb $oldver not downgraded to $newver ('-Force' to override)" + exit 0 + } + $updmsg = "downgraded to" +} else { + $updmsg = "updated to" +} + +mv_all $Drivedb "" ".old" +mv_all $Drivedb ".new" "" +iecho "$Drivedb $oldver $updmsg $newver$(if ($NoVerify) {" (NOT VERIFIED)"})" +exit 0 |