diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist
deleted file mode 100644
index b04b3501f5efd94313942eb7439457bc82f5a2f5..0000000000000000000000000000000000000000
--- a/CVSROOT/checkoutlist
+++ /dev/null
@@ -1,13 +0,0 @@
-# The "checkoutlist" file is used to support additional version controlled
-# administrative files in $CVSROOT/CVSROOT, such as template files.
-#
-# The first entry on a line is a filename which will be checked out from
-# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
-# The remainder of the line is an error message to use if the file cannot
-# be checked out.
-#
-# File format:
-#
-#	[<whitespace>]<filename><whitespace><error message><end-of-line>
-#
-# comment lines begin with '#'
diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo
deleted file mode 100644
index b19e7b7a63e8e90cdb49c43f02035646c4a76e0a..0000000000000000000000000000000000000000
--- a/CVSROOT/commitinfo
+++ /dev/null
@@ -1,15 +0,0 @@
-# The "commitinfo" file is used to control pre-commit checks.
-# The filter on the right is invoked with the repository and a list 
-# of files to check.  A non-zero exit of the filter program will 
-# cause the commit to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT.  For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/config b/CVSROOT/config
deleted file mode 100644
index ff43ec005ab332bc2aa7e1378754180e75a4b049..0000000000000000000000000000000000000000
--- a/CVSROOT/config
+++ /dev/null
@@ -1,14 +0,0 @@
-# Set this to "no" if pserver shouldn't check system users/passwords
-#SystemAuth=no
-
-# Put CVS lock files in this directory rather than directly in the repository.
-#LockDir=/var/lock/cvs
-
-# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
-# level of the new working directory when using the `cvs checkout'
-# command.
-#TopLevelAdmin=no
-
-# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
-# history file, or a subset as needed (ie `TMAR' logs all write operations)
-#LogHistory=TOFEWGCMAR
diff --git a/CVSROOT/cvswrappers b/CVSROOT/cvswrappers
deleted file mode 100644
index 0accaf1b1532448d633d8a183cd8e3a5dd3b4a75..0000000000000000000000000000000000000000
--- a/CVSROOT/cvswrappers
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file affects handling of files based on their names.
-#
-# The -t/-f options allow one to treat directories of files
-# as a single file, or to transform a file in other ways on
-# its way in and out of CVS.
-#
-# The -m option specifies whether CVS attempts to merge files.
-#
-# The -k option specifies keyword expansion (e.g. -kb for binary).
-#
-# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
-#
-#  wildcard	[option value][option value]...
-#
-#  where option is one of
-#  -f		from cvs filter		value: path to filter
-#  -t		to cvs filter		value: path to filter
-#  -m		update methodology	value: MERGE or COPY
-#  -k		expansion mode		value: b, o, kkv, &c
-#
-#  and value is a single-quote delimited value.
-# For example:
-#*.gif -k 'b'
diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo
deleted file mode 100644
index d78886c1522b6eae3470c13da218c3d8e197cf71..0000000000000000000000000000000000000000
--- a/CVSROOT/editinfo
+++ /dev/null
@@ -1,21 +0,0 @@
-# The "editinfo" file is used to allow verification of logging
-# information.  It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure.  Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-#   Making sure that the entered bug-id number is correct.
-#   Validating that the code that was reviewed is indeed the code being
-#       checked in (using the bug-id number or a seperate review
-#       number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported.  There can be only one entry that matches a given
-# repository.
diff --git a/CVSROOT/loginfo b/CVSROOT/loginfo
deleted file mode 100644
index a6a40e011bf383368e4abf36e585859c22e2f895..0000000000000000000000000000000000000000
--- a/CVSROOT/loginfo
+++ /dev/null
@@ -1,29 +0,0 @@
-# The "loginfo" file controls where "cvs commit" log information
-# is sent.  The first entry on a line is a regular expression which must match
-# the directory that the change is being made to, relative to the
-# $CVSROOT.  If a match is found, then the remainder of the line is a filter
-# program that should expect log information on its standard input.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name ALL appears as a regular expression it is always used
-# in addition to the first matching regex or DEFAULT.
-#
-# You may specify a format string as part of the
-# filter.  The string is composed of a `%' followed
-# by a single format character, or followed by a set of format
-# characters surrounded by `{' and `}' as separators.  The format
-# characters are:
-#
-#   s = file name
-#   V = old version number (pre-checkin)
-#   v = new version number (post-checkin)
-#
-# For example:
-#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
-# or
-#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
-^sm5$ /cvsroot/sitedocs/CVSROOT/cvstools/syncmail -u %{sVv} smartmontools-cvs@lists.sourceforge.net
-^sm5/os_win32$ /cvsroot/sitedocs/CVSROOT/cvstools/syncmail -u %{sVv} smartmontools-cvs@lists.sourceforge.net
-^www$ /cvsroot/sitedocs/CVSROOT/cvstools/syncmail -u %{sVv} ballen4705@users.sourceforge.net
diff --git a/CVSROOT/modules b/CVSROOT/modules
deleted file mode 100644
index cb9e9efc94b342879a5fff24b425473fc11edd01..0000000000000000000000000000000000000000
--- a/CVSROOT/modules
+++ /dev/null
@@ -1,26 +0,0 @@
-# Three different line formats are valid:
-#	key	-a    aliases...
-#	key [options] directory
-#	key [options] directory files...
-#
-# Where "options" are composed of:
-#	-i prog		Run "prog" on "cvs commit" from top-level of module.
-#	-o prog		Run "prog" on "cvs checkout" of module.
-#	-e prog		Run "prog" on "cvs export" of module.
-#	-t prog		Run "prog" on "cvs rtag" of module.
-#	-u prog		Run "prog" on "cvs update" of module.
-#	-d dir		Place module in directory "dir" instead of module name.
-#	-l		Top-level directory only -- do not recurse.
-#
-# NOTE:  If you change any of the "Run" options above, you'll have to
-# release and re-checkout any working directories of these modules.
-#
-# And "directory" is a path to a directory relative to $CVSROOT.
-#
-# The "-a" option specifies an alias.  An alias is interpreted as if
-# everything on the right of the "-a" had been typed on the command line.
-#
-# You can encode a module within a module by using the special '&'
-# character to interpose another module into the current module.  This
-# can be useful for creating a module that consists of many directories
-# spread out over the entire source repository.
diff --git a/CVSROOT/notify b/CVSROOT/notify
deleted file mode 100644
index 34f0bc288808e56e499d0852a9bfc9a3214b02d9..0000000000000000000000000000000000000000
--- a/CVSROOT/notify
+++ /dev/null
@@ -1,12 +0,0 @@
-# The "notify" file controls where notifications from watches set by
-# "cvs watch add" or "cvs edit" are sent.  The first entry on a line is
-# a regular expression which is tested against the directory that the
-# change is being made to, relative to the $CVSROOT.  If it matches,
-# then the remainder of the line is a filter program that should contain
-# one occurrence of %s for the user to notify, and information on its
-# standard input.
-#
-# "ALL" or "DEFAULT" can be used in place of the regular expression.
-#
-# For example:
-#ALL mail %s -s "CVS notification"
diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo
deleted file mode 100644
index 49e59f4d0df9b432c5b99c0b806378a77c9cd870..0000000000000000000000000000000000000000
--- a/CVSROOT/rcsinfo
+++ /dev/null
@@ -1,13 +0,0 @@
-# The "rcsinfo" file is used to control templates with which the editor
-# is invoked on commit and import.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being made to, relative to the
-# $CVSROOT.  For the first match that is found, then the remainder of the
-# line is the name of the file that contains the template.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo
deleted file mode 100644
index 274a46dd5b61069f1cea62395178b09aa3120248..0000000000000000000000000000000000000000
--- a/CVSROOT/taginfo
+++ /dev/null
@@ -1,20 +0,0 @@
-# The "taginfo" file is used to control pre-tag checks.
-# The filter on the right is invoked with the following arguments:
-#
-# $1 -- tagname
-# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
-# $3 -- repository
-# $4->  file revision [file revision ...]
-#
-# A non-zero exit of the filter program will cause the tag to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT.  For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg
deleted file mode 100644
index 86f747ce222390e6aa7a488074e372030d57a479..0000000000000000000000000000000000000000
--- a/CVSROOT/verifymsg
+++ /dev/null
@@ -1,21 +0,0 @@
-# The "verifymsg" file is used to allow verification of logging
-# information.  It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure.  Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-#   Making sure that the entered bug-id number is correct.
-#   Validating that the code that was reviewed is indeed the code being
-#       checked in (using the bug-id number or a seperate review
-#       number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported.  There can be only one entry that matches a given
-# repository.
diff --git a/sm5/.cvsignore b/sm5/.cvsignore
deleted file mode 100644
index 85c60d8adb27e6bc8c0d54b7f511eff2ee64d255..0000000000000000000000000000000000000000
--- a/sm5/.cvsignore
+++ /dev/null
@@ -1,46 +0,0 @@
-*.gz
-*.o
-*.rpm
-*.tar.gz
-*.tar.gz.asc
-*~
-.deps
-.gdb_history
-Makefile
-Makefile.in
-VERSION
-aclocal.m4
-add
-autom4te.cache
-autotools.diff
-build
-config.guess
-config.h
-config.h.in
-config.log
-config.status
-config.sub
-configure
-core
-cvs-script
-depcomp
-install-sh
-missing
-mkinstalldirs
-smartctl
-smartctl.8
-smartctl.1m
-smartctl.exe
-smartd
-smartd.8
-smartd.1m
-smartd.conf.5
-smartd.conf.4
-smartd.conf.sample
-smartd.initd
-smartd.exe
-stamp-h
-stamp-h.in
-stamp-h1
-writelog.c
-SMART
diff --git a/sm5/AUTHORS b/sm5/AUTHORS
deleted file mode 100644
index 6405f856f1a1a1e153949c81c02ae6be6dd07e50..0000000000000000000000000000000000000000
--- a/sm5/AUTHORS
+++ /dev/null
@@ -1,30 +0,0 @@
-$Id: AUTHORS,v 1.13 2004/07/16 01:41:19 geoffk1 Exp $
-
-This code was originally developed as a Senior Thesis by Michael
-Cornwell at the Concurrent Systems Laboratory (now part of the Storage
-Systems Research Center), Jack Baskin School of Engineering, University
-of California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-
-This package is meant to be an up-to-date replacement for the
-ucsc-smartsuite and smartsuite packages, and is derived from that code.
-
-Maintainers / Developers:
-
-Bruce Allen		<smartmontools-support@lists.sourceforge.net>
-Erik Inge Bols�		<knan@mo.himolde.no>
-Stanislav Brabec	<sbrabec@suse.cz>
-Peter Cassidy		<pcassidy@mac.com>
-Casper Dik		<casper@holland.sun.com>
-Christian Franke	<franke@computer.org>
-Guilhem Fr�zou		<guilhem.frezou@catii.fr>
-Douglas Gilbert		<dougg@torque.net>
-Guido Guenther		<agx@sigxcpu.org>
-Geoff Keating		<geoffk@geoffk.org>
-Dr. David Kirkby	<drkirkby@ntlworld.com>
-Kai M�kisara		<kai.makisara@kolumbus.fi>
-Eduard Martinescu	<martines@rochester.rr.com>
-Fr�d�ric L. W. Meunier	<http://www.pervalidus.net/contact.html>
-Keiji Sawada		<card_captor@users.sourceforge.net>
-Sergey Svishchev	<svs@ropnet.ru>
-Phil Williams		<phil@subbacultcha.demon.co.uk>
-Richard Zybert		<richard.zybert@zybert.co.uk>
diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
deleted file mode 100644
index 44b5c6d97458e32ee945b778c71f07fe4a707788..0000000000000000000000000000000000000000
--- a/sm5/CHANGELOG
+++ /dev/null
@@ -1,1857 +0,0 @@
-CHANGELOG for smartmontools
-
-$Id: CHANGELOG,v 1.447 2004/08/16 22:44:15 ballen4705 Exp $
-
-The most recent version of this file is:
-http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?sortby=date&view=markup
-
-Maintainers / Developers Key:
-[BA] Bruce Allen
-[EB] Erik Inge Bols�
-[SB] Stanislav Brabec
-[PC] Peter Cassidy
-[CD] Caper Dik
-[CF] Christian Franke
-[GF] Guilhem Fr�zou
-[DG] Douglas Gilbert
-[GG] Guido Guenther
-[GK] Geoff Keating
-[DK] Dr. David Kirkby
-[KM] Kai M�kisara
-[EM] Eduard Martinescu
-[FM] Fr�d�ric L. W. Meunier
-[KS] Keiji Sawada
-[SS] Sergey Svishchev
-[PW] Phil Williams
-[RZ] Richard Zybert
-
-NOTES FOR FUTURE RELEASES: see TODO file.
-
-<ADDITIONS TO THE CHANGE LOG SHOULD BE ADDED JUST BELOW HERE, PLEASE>
-
-  [BA] Additional modifications of Ed's controller scheme.  Fixed
-       broken 3ware support under linux, problems with scanning
-       devices in smartd, and other small problems.
-
-  [EM] Minor change to FreeBSD inclusion of 'twe' include files.  Add 
-       code to check if they exising in /usr/include/sys to use those
-       in preference to ones added here
-
-  [EM] Very preliminary support attempt for 3Ware controllers under 
-       FreeBSD. Also, switched 'escalade_type/escalade_port' to
-       'controler_type/controller_port' and moved away from 
-       'tryata/tryscsi' to using new 'controller*' variables to 
-       determine which controller type (ATA/SCSI/3Ware) to use.
-
-  [GK] Added initscript support for Darwin.
-
-  [CF] Windows smartd: Added ability to run smartd as a windows service,
-       including new commands "smartd install ..." and "smartd remove"
-       to install and remove the service registry entry.
-
-  [BA] smartd: warn user if -s regexp regular expression contains
-       characters other than 0123456789.*()|+?[-]{}:=SLCO since such
-       characters are 'suspicous' and may indicate a poorly formed
-       regexp.  Extended regular expression gurus: can this list be
-       reduced somewhat?
-
-  [CF] Fixed bug in Windows smartd: Missing close of config file when
-       configuration is reloaded by smartd daemon.
-
-  [CF] Windows smartd: Added mail warning feature using the "Blat"
-       (http://blat.sourceforge.net/) mailer as a default.
-
-  [PW] Added Maxtor DiamondMax Plus 5120 Ultra ATA 33 series and TOSHIBA
-       MK3017GAP to knowndrives table.
-
-  [CF] Added fixes to build smartmontools on old Linux systems
-       (libc < 6, Kernel 2.0.x).
-
-  [BA] Added ATA minor version identity strings for latest ATA specification
-       updates: ATA/ATAPI-7 T13 1532D revision 4a and ATA/ATAPI-6 published,
-       ANSI INCITS 361-2002
-
-  [PW] Added Hitachi Travelstar 5K80 family and Fujitsu MHTxxxxAH family to
-       knowndrives table.
-
-  [EM] Fix up compilation under FreeBSD < 5.x
-
-  [PW] Added QUANTUM FIREBALL EX3.2A and missing Western Digital Caviar SE
-       drives to knowndrives table.
-
-  [BA] Modified Hitachi Travelstar 80GN family regexp in drive database.
-       Thanks to [GK/CF] for problem & solution.
-
-  [GK] Added os_darwin.[ch]
-
-  [PW] Added the following drives to the knowndrives table: IBM Travelstar
-       48GH, 30GN, and 15GN family; IBM Deskstar 37GP and 34GXP family;
-       Western Digital WDC WD272AA; Maxtor DiamondMax D540X-4D family;
-       TOSHIBA MK2016GAP, MK2018GAP, MK2018GAS, MK2023GAS; and
-       QUANTUM FIREBALL ST3.2A
-
-  [BA] smartd/smarctl now print build HOST/OS information as part
-       of startup slogan.  This should make it slightly easier to
-       read bug reports from users.
-
-  [RZ] Fixed the DEVICESCAN to do what it was supposed to do - give
-       error message unless scanning is in progress.  
-
-  [BA] Update documentation to describe 3ware character devices. Better
-       error detection for missing/malfunctioning devices behind 3ware
-       controllers. Now pack 3ware ioctl structures explicitly.
-
-  [BA] For ATA devices that support LBA mode, print capacity as part
-       of smartctl --info
-
-  [RZ] Made DEVICESCAN quiet about non-existing devices unless debug
-       is on.
-
-  [DG] treat "unit attention" SCSI warning as try again in some contexts
-       (test unit ready and mode sense)
-
-  [BA] on drives that store max/min rather than min/max, get order
-       correct in printing temp.
-
-  [BA] fixed typo in 'smartctl -h' output.  Thanks to Gabor Z. Papp.
-
-  [BA] linux: clean-up to 3ware/AMCC support; dynamically create
-       or fix /dev/tw[ae][0-15] device node entries if they don't
-       exist or are incorrect. One can now use the character devices
-       /dev/twe[0-15] OR /dev/sd? for 3ware 6000/7000/8000 series
-       cards.  One must use /dev/twa[0-15] for 3ware 9000 series cards.
-       Note that selective self-tests now work via /dev/tw[ae] devices.
-       Next step: documentation.
-
-  [BA] linux: experimental "support" for 3ware/AMCC 9000 series
-       controllers that use the 3w-9xxx driver.  This will be in a
-       state of flux for a few days.  Note that this requires the
-       character interface /dev/twa[0-15].
-
-  [DG] linux: extend general SCSI OS interface to use the SG_IO ioctl. If
-       not available, use the older SCSI_IOCTL_SEND_COMMAND ioctl.
-
-  [KS] Solaris/x86: fixed system identification problem in configure
-       script.  Thanks to Stuart Swales.
-
-smartmontools 5.32
-
-  [BA] Update link to revised/updated IBM Deskstar Firmware
-
-  [CF] Cygwin & Windows: Added missing ASPI manager initialization
-       with GetASPI32SupportInfo(). Thanks to Nikolai SAOUKH for pointing
-       this out and providing a patch.
-
-  [BA] modified smartd init script to work on whitebox (thanks to
-       Michael Falzon)
-
-  [BA] removed (reverted) additional Attribute definitions from
-       http://smart.friko.pl/attributes.php.  All (or most?) of these
-       appear to be return code values for the WD Digital Life Guard Utility.
-
-  [PW] Added Seagate Medalist 17242, 13032, 10232, 8422, and 4312 to
-       knowndrives table.  Added missing Seagate U Series 5 drives.
-
-  [PW] Added the following QUANTUM models to knowndrives table:
-       FIREBALL EX6.4A, FIREBALLP AS10.2, FIREBALLP AS40.0, FIREBALL CR4.3A,
-       FIREBALLP LM15, FIREBALLP LM30, and FIREBALLlct20 30
-
-  [PW] Added missing Western Digital Protege drives to knowndrives table.
-
-  [PW] Added Maxtor DiamondMax 40 ATA 66 series and DiamondMax 40 VL Ultra
-       ATA 100 series to knowndrives table.
-
-  [PW] Added the following Hitachi/IBM drives to knowndrives table:
-       HITACHI_DK14FA-20B, Travelstar 40GNX series, Travelstar 4LP series,
-       and Travelstar DK23XXB series.  Added the missing Travelstar 80GN
-       drives.
-
-  [PW] Added Fujitsu MPB series and MPG series to knowndrives table.  Added
-       the missing Fujitsu MHSxxxxAT drives.
-
-  [KS] Solaris: added workaround for dynamic change of time-zone.
-
-  [KS] Solaris: fixed problem that autogen.sh cannot detect absence of
-       auto* tools.
-
-  [BA] smartd: added time-zone bug information to man page. 
-       Reverted CF code for _WIN32 case. 
-
-  [CF] Cygwin & Windows: Added better error messages on IDE/ATA device
-       open error.
-
-  [BA] added additional Attribute definitions from
-       http://smart.friko.pl/attributes.php
-
-  [BA] smartd: reworked TimeZone bug workaround so it is only invoked
-       for glibc.  Note: this might not be right -- a similar bug may
-       exist in other platform's libcs.
-
-  [DG] SCSI smartmontools documentation updated [2004/5/6]. See:
-       http://smartmontools.sourceforge.net/smartmontools_scsi.html
-
-  [CF] Windows: Fixed reset of TZ=GMT in glibc timezone bug workaround.
-
-smartmontools 5.31
-
-  [DG] move SCSI device temperature and start-stop log page output
-       (smartctl) into --attributes section (was in --info section).
-
-  [GG] change default installation location to /usr/local
-
-  [CF] Cygwin smartd: Fixed crash on access of SCSI devices after fork().
-
-  [PW] Added TOSHIBA MK4018GAS and the following Maxtor drive families
-       to knowndrives table: DiamondMax D540X-4G, Fireball 541DX,
-       DiamondMax 3400 Ultra ATA, DiamondMax Plus 6800 Ultra ATA 66.
-
-  [PW] Added missing Maxtor DiamondMax 16, DiamondMax D540X-4K, and
-       DiamondMax Plus 45 Ulta ATA 100 drives to knowndrives table.
-
-  [PW] Added ExcelStor J240, Hitachi Travelstar 80GN family, Fujitsu
-       MHTxxxxAT family, and IBM Deskstar 25GP and 22GXP families to
-       knowndrives table.
-
-  [CF] Cygwin smartd: Added workaround for missing SIGQUIT via keyboard:
-       To exit smartd in debug mode, type CONTROL-C twice.
-
-  [BA] smartctl: printing of the selective self-test log is now
-       controlled by a new option: -l selective
-
-  [BA] Added entries for Samsung firmware versions -25 to -39 based
-       on latest info about firmware bug fixes.
-
-  [PW] Added Seagate U Series X family, Seagate U8 family, and Seagate
-       Medalist 8641 family to knowndrives table.
-
-  [CF] smartd: Added exit values 5/6 for missing/unreadable config file.
-
-  [BA] smartd: now monitor the Current Pending Sector count (Attribute 197)
-       and the Offline Pending Sector Count (Attribute 198).  Log a
-       warning (and send an email, if so configured) if the raw count
-       is nonzero.  These are controlled by new Directives: -C and -U.
-       Currently they are enabled by default.
-
-  [CF] Added option -c FILE, --configfile=FILE to smartd to specify
-       an alternate configuration FILE or '-' for standard input.
-
-  [KS] configure.in now searches for -lnsl and -lsocket for Solaris.
-
-  [CF] Win32/native smartd: Added thread to combine several syslog output
-       lines into one single event log entry.
-
-  [CF] Win32 smartd: Added DEVICESCAN for SCSI/ASPI devices.
-
-  [GG] Use gethostbyname() the get the DNS domain since getdomainname() 
-       returns the NIS domain when sending mails from smartd.
-
-  [GG] smartd.init.in: pass smartd_opts to smartd on startup, read distribution
-       specific configuration files if found
-
-  [SS] smartctl: added NetBSD support for Selective Self-tests.
-
-  [BA] smartd.conf example configuration file now has all examples
-       commented out except for 'DEVICESCAN'.
-
-  [CF] Win32/native smartd: Added ability to display warning "emails"
-       as message box by "-m msgbox" directive. With "-m sysmsgbox",
-       a system modal (always on top) message box is shown.
-
-  [BA] smartctl: printing of self-test log for disks that support
-       Selective self-testing now shows the status of the (optional)
-       read-scan after the selective self test.  Also, changed format
-       in printing self-test log to print failing LBA in base 10 not
-       base 16 (more compatible with kernel error messages).  Also,
-       in printing SMART error log, print timestamps in format
-       days+hours+minutes+seconds.
-
-  [CF] Win32 smartd: Added ability to log to stdout/stderr
-       (-l local1/2). Toggling debug console still works
-       if stdout is redirected.
-
-  [BA] smartctl: selective self-test log, print current status
-       in a  more detailed way.  Allow writing of selective self-test
-       log provided that no other self-test is underway.
-
-  [BA] Linux: eliminated dependency on kernel tree hdreg.h.
-
-  [BA] smartctl: -l selftest option now prints Selective self-test
-       log in addition to the normal self-test log.
-       Added additional options (-t pending, -t afterselect) to
-       control remaining Selective Self-test capabilities.  Tested
-       with several Maxtor disks. Modified error message printing
-       so that munged option messages print at the end not the
-       start of output.
-
-  [CF] Added daemon support to Win32 native version of smartd.
-       The daemon can be controlled by commands similar to initd
-       scripts: "smartd status|stop|reload|restart|sigusr1|sigusr2".
-
-  [CF] Added minor support for option "-l local[0-7]" to Win32 native
-       (not Cygwin) version of smartd. If specified, the log output
-       is written to file "./smartd[1-7]?.log" instead of event log.
-
-  [BA] Added Selective Self-test to smartctl (-t selective,M-N).
-       Currently only supported under Linux; Solaris, NetBSD, FreeBSD
-       and Windows developers must add WRITE LOG functionality to
-       os_*.c
-
-  [BA] Added workaround for an annoying glibc bug: if you change
-       timezones, (eg, flying with a laptop from USA to Europe)
-       localtime() does not notice this in a running
-       executable, so time that appears in the system log (syslog!)
-       will be incorrect.  See
-       http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48184
-       for additional examples of this bug.
-
-  [DG] Set explicit timeouts for SCSI commands (most default to 6 seconds).
-       Previously a 0 second timeout was meant to be interpreted as a 
-       default timeout but the FreeBSD port had a problem in this area.
-
-  [CF] Fixed un-thread-safe exit signal handler for Win32
-
-  [BA] Fixed un-thread-safe exit signal handler pointed out
-       by CF.
-
-  [BA] Changed configure script to eliminate warnings under
-       Solaris from sys/int_type.h conflicts with int64.h
-       Added header files for umask to smartd.c.
-
-  [BA] Man page format change from Werner LEMBERG.  " " changed to \&
-
-  [CF] Added os_win32/syslogevt.* event message file tool for Win32
-       smartd (native+cygwin). May also be useful for other cygwin
-       programs writing to syslog().
-
-  [CF] Added Win32 version of smartd
-
-  [CF] Merged RELEASE_5_26_WIN32_BRANCH
-
-  [BA] Made some changes to man page markup suggested by
-       Richard Verhoeven to work around bugs in man2html.
-       Tested not to break anything under Linux and Solaris.
-
-  [CF] Moved PrintOut() from utility.c to smart{ctl,d}.c to avoid
-       syslog() output of smartctl.
-
-  [BA] Grew worried that some time-zone names could be very long (eg,
-       Mitteleuropaische Zeit) and put date string lengths into a
-       single macro in utility.c
-
-  [EM] Updated os_freebsd.c to handle older versions of FreeBSD in a 
-       more appropriate/obvious fashion.
-
-  [EM] Modified autogen.sh as FreeBSD installs automake 1.7 as 
-       'automake17' and NOT 'automake-1.7'
-
-smartmontools 5.30
-
-  [PW] Added QUANTUM FIREBALLlct15 30, QUANTUM FIREBALLlct20 40, and
-       Maxtor 6Y060P0 (DiamondMax Plus 9 60GB) to knowndrives table.
-
-  [PW] Added Maxtor MaXLine II family to knowndrives table (thanks to
-       Brett Russ for submitting the patch).
-
-  [BA] Added remaining read/write commands to detailed list of
-       error log commands that have text descriptions of problem
-       printed.  For commands that support it, print number of failed
-       sectors at problem LBA.
-
-  [BA] Made SuSE section of smartd init script more SuSE 9 compatible.
-       Thanks to Hans-Peter Jansen.
-
-  [CF] Windows smartd: Added IDE/ATA device scan
-       Added windows device names to smartctl.8.in, smartd.8.in
-   
-  [BA] smartctl/smartd: user-provided '-F samsung' and '-F samsung2'
-       command line options/Directives did NOT over-ride preset values
-       unless user specified '-P ignore'.  Now they will always over-ride
-       preset values from the database.
-
-  [BA] Added error decoding for a few more READ and WRITE commands.
-
-  [PW] Added Maxtor MaXLine Plus II, Western Digital Caviar SE (Serial ATA)
-       series, Hitachi Deskstar 7K250 series, and Ultra ATA 66 models of
-       the Maxtor DiamondMax Plus 40 series to knowndrives table.
-
-  [BA] Added Maxtor Diamondmax 250 GB drives to database.  Note that
-       these model numbers are not listed in Maxtor documentation, but
-       they exist.
-
-  [BA] Removed the 'contact developers' phrase from the Samsung disk
-       warning messages.
-
-  [PW] Added TOSHIBA MK2017GAP, IBM Deskstar 14GXP and 16GP series,
-       Fujitsu MPC series, Seagate Barracuda ATA III family, and missing
-       Seagate Barracuda U Series drives to knowndrives table
-
-  [BA] smartd: wrong loglevel for message: Configuration file
-       /etc/smartd.conf parsed.  Changed to LOG_INFO from LOG_CRIT.
-       Thanks to  Emmanuel CHANTREAU for the report.
-
-  [CF] Checked in development version of windows code base.
-
-smartmontools 5.29 (note: there was NO 5.28 release)
-
-  [BA] smartd: configure script did not set correct directory to search for
-       smartd.conf based on --prefix argument to ./configure.  Thanks to
-       GG for identifying the problem and fix.
-
-  [BA] make clean now removes man pages (generated from *.in) files as well
-       as object files.
-
-  [EM] Correct copying of sense data in FreeBSD SCSI implementation. Thanks
-       to Sergey Svishchev for noticing the bug.
-
-  [BA] On solaris, wrong warning message if no ATA support.  Warning message
-       concerns 3ware controller, not ATA.
-
-  [SS] Added SCSI support for NetBSD.
-
-  [BA] on big-endian linux machines, fixed interpretation of HDIO_GET_IDENTITY
-       to correctly identify ATAPI bit (was byte swapped).  This should
-       eliminate some SYSLOG noise if user queries a packet device (eg, CD
-       ROM or DVD reader).
-
-  [PW] Removed warning for IBM Deskstar 40GV & 75GXP series drives with
-       A5AA/A6AA firmware.  Thanks to Gerald Schnabel.
-
-  [PW] Added Toshiba TOS MK3019GAXB SUN30G to knowndrives table
-
-  [PW] Added Western Digital Caviar AC12500, AC24300, AC25100, AC36400,
-       and AC38400 to knowndrives table
-
-  [BA] When printing ATA error log, print the LBA at which READ
-       or WRITE commands failed.
-
-  [BA] Changed syntax of error message in smartctl
-
-  [BA] Added versioning info (-V options to smartd/smartctl) for
-       Solaris ATA module.
-
-smartmontools 5.27
-
-  [KS] Added ATA/IDE support for Solaris/SPARC (ATA/IDE not yet for
-       Solaris/x86).
-
-  [BA] 3ware controllers: documented that one can monitor any of the
-       physical disks from any of the 3ware /dev/sd? logical devices.
-       Better warnings if querying a disk that does not exist.
-
-  [PW] Added Hitachi Travelstar DK23DA series, Maxtor DiamondMax Plus 40
-       series, Western Digital Caviar WDxxxAA, WDxxxBA, and WDxxxAB series
-       to knowndrives table
-
-  [BA] missing 'pragma pack' on ATA IDENTIFY DEVICE structure may have
-       caused odd or incorrect results on 64-bit machines.
-
-  [BA] smartctl/smartd allow inspection of self-test and error logs even
-       if disk firmware claims that these don't exist.  This is needed
-       for some Maxtor disks whose firmware does not indicate log support
-       even though the disk DOES support it.
-
-  [BA] Improved porting instructions and documentation in os_generic.c
-
-  [PW] Add Western Digital Caviar WD136AA and SAMSUNG SP40A2H (RR100-07
-       firmware) to knowndrives table.
-
-  [EM] FreeBSD:	remove extra definition of FreeNonZero
-
-  [BA] smartctl: the -q silent option was printing output for some
-       error conditions.  Fixed.  Will rename relevant variables to help
-       avoid these errors in the future.
-
-  [SS] NetBSD port added.
-
-  [BA] more sensible error messages for devfs and devfs-like systems.
-       Instead of saying that the DIRECTORY does not exist, say that
-       the DEVICE does not exist.
-
-  [BA] smartd: added -n Directive, to prevent disk spin-up depending
-       upon the power mode (SLEEP, STANDBY, or IDLE).
-
-  [PW] Added Maxtor DiamondMax 20 VL series, Fujitsu MPF series,
-       Maxtor DiamondMax 36 series, Maxtor DiamondMax 4320 series, and
-       Maxtor DiamondMax 536DX series to knowndrives table.
-
-  [BA] many warning messages now give the file name AND VERSION
-
-  [BA] smartd: when the user provides multiple address recipients
-       to the '-m' Directive in a comma-delineated list, the commas
-       are stripped out before passing the list of addresses to the
-       mailer program. (Thanks to Calin A. Culianu for pointing this out
-       and providing a patch.)
-
-  [BA] smartd: when the '-M exec path' Directive is used, any stdout OR
-       stderr output from the executable "path" is assumed to indicate a
-       problem, and is echoed to SYSLOG.
-
-  [BA] Added all missing IBM/Hitachi Deskstar 180GXP models to knowndrives
-       table.
-
-  [PW] Added some missing IBM/Hitachi Deskstar 120GXP models to knowndrives
-       table.
-
-  [PW] Added IBM Travelstar 14GS to knowndrives table.
-
-  [PW] Modified knowndrives table to match entire Hitachi Travelstar
-       DK23BA and DK23EA series of drives (thanks to Norikatsu Shigemura
-       for submitting the patch).
-
-  [PW] Added some missing Fujitsu MPE series drives to knowndrives table.
-
-  [PW] Added TOSHIBA MK4019GAX, TOSHIBA MK6409MAV, and QUANTUM
-       FIREBALLlct15 20 to knowndrives table.
-
-  [EM] Fixup example command output for FreeBSD
-
-  [PW] Added Maxtor DiamondMax 80 family to knowndrives table.
-
-  [EM] Catch up FreeBSD code to switch PROJECTHOME to PACKAGE_HOMEPAGE
-       macros.
-
-  [BA] smartd: now watches stdout/stderr when trying to run mail, mailx
-       or mail warning script, and reports any output to SYSLOG.  This
-       gives a clearer error message if something is wrong.
-
-  [BA] smartd: Solaris init script modified to accomodate grep that
-       lacks '-q' quiet option.  Also check for running process to kill
-       on stop.
-
-  [PW] Added some missing Seagate Barracuda 7200.7 and 7200.7 Plus drives
-       to knowndrives table.
-
-  [PW] Added Maxtor DiamondMax Plus 60 family and Seagate U Series 5 20413
-       to knowndrives table.
-
-  [BA] smartd: under Solaris, made default mailer be 'mailx' not
-       'mail', since Solaris 'mail' does not accept a '-s' argument.
-       A workaround for Solaris users of earlier versions is to
-       have '-M exec /bin/mailx' in their smartd.conf config file.
-
-  [DG] some SCSI controllers don't like odd length transfers so make
-       sure LOG SENSE transfers are rounded up to an even number when
-       and odd length is reported (i.e. there is a double fetch, the
-       first to find the length, the second gets the data)
-
-  [BA] smartd man pages: under Solaris, correct section numbers in the
-       'See also' section.
-
-  [KS/BA] smartd man page: describe how to set Solaris syslog.conf
-       file to catch all messages.  Give correct Solaris SYSLOG default
-       path /var/adm/messages in man pages.
-
-  [BA] smartd: incorporated Debian startup script submitted by user.
-
-  [BA] smartctl: modified printing of self-test log entry number.  Seagate
-       firmware can leave 'holes' in the self-test log while a test is
-       actually running.  We now print entry numbers consistently in this
-       case, not assuming that entries are contiguous.
-
-  [PW] Added QUANTUM FIREBALL CX10.2A and Western Digital Caviar AC23200L
-       to knowndrives table.
-
-  [PW] Added QUANTUM FIREBALLlct20 20 to knowndrives table.
-
-  [PW] Added Maxtor DiamondMax Plus D740X family to knowndrives table.
-
-  [PW] Added IBM Travelstar 32GH, 30GT, and 20GN family to knowndrives
-       table.
-
-  [BA] Slackware init script modified to search for /etc/slackware-version
-       rather than /etc/slackware-release.
-
-  [PW] Added Seagate Barracuda ATA II family and TOSHIBA MK4019GAXB to
-       knowndrives table.
-
-  [GG] explain howto use autoreconf in autogen.sh
-
-  [KS] Makefile.am/configure.in: changed manual page sections for
-       Solaris.
-
-  [BA] smartd: reduced number of scheduled self-test messages if
-       test already run in current hour.
-
-  [PW] Added Maxtor DiamondMax Plus 8 family to knowndrives table.
-
-  [BA] linux: check for linux/hdreg.h.  If it's there, use it. If
-       not, provide the necessary definitions ourselves.
-
-  [PW] Removed warning for IBM Deskstar 40GV & 75GXP series drives
-       with TXAOA5AA firmware
-
-  [PW] Added IBM Travelstar 25GS, 18GT, and 12GN family to knowndrives
-       table.
-
-  [PW] Added IBM/Hitachi Travelstar 60GH & 40GN family to knowndrives
-       table.
-
-  [BA] smartd: made '-s' Directive more efficient.  Now store
-       compiled regex, and re-use.  If device lacks certain self-test
-       capabilities, track it and don't try again.
-
-  [BA] smartd: made memory allocation for device lists completely
-       dynamic (eliminating compile-time maximum length constants).
-
-  [PW] Removed warning for SAMSUNG SP0802N with TK100-23 firmware
-
-  [PW] Added Seagate Barracuda ATA IV family to knowndrives table.
-
-  [BA] smartd: reduce per-device memory footprint by making
-       mail-warning info dynamically allocated.  Also remove
-       potential memory leak if use has -m Directive twice and
-       keeps reloading the config file (highly unlikely this would
-       ever be noticed!)  
-
-  [DG] smartd: added SCSI scheduled self-tests (Background
-       short or extended).
-
-  [BA] smartd: can now run scheduled offline immediate and
-       self-tests.  See man page and -s Directive for details.
-
-  [GG] don't include manpages in make-dist-tarball.
-
-  [BA] smartctl: on-line examples given with -h are now correct
-       for solaris and linux, but wrong for freebsd.  Ed?
-
-  [BA] smartd: man page now explains device scanning for solaris as
-       well as linux and freebsd.
-
-  [BA] smartd/smartctl: man pages now report correct CVS tag release
-       date, and executables '-V' options reports more build info.
-
-smartmontools 5.26
-
-  [BA] Improved user messages that appear from 'make install'
-
-  [PW] Removed warning for SAMSUNG SP1213N with firmware TL100-23
-
-  [BA] incorporated SuSE init script from user.
-
-  [DG] if SCSI device is read only, then open it read only.
-
-  [BA] when compiled on non-supported system (NOT linux, freebsd or solaris) then
-       the run-time error messages now clearly say 'your system is not supported'
-       and give clear directions.
-
-  [BA] ./configure script now works correctly on SuSE linux boxes
-
-  [BA] minor improvements to man pages
-
-  [BA] simplified detection of packet (ATAPI, CD) devices.
-
-  [BA] init script (redhat, mandrake, yellowdog) now uses correct
-       strings for translation and is slightly more standard.
-
-  [DG] smartctl: output scsi Seagate vendor pages for disks (not tapes)
-
-smartmontools 5.25
-
-Note: there was no '5.24' release. From this point on, even numbered
-releases will be 'stable' ones and odd numbered releases will be
-unstable/testing/development ones.
-
-  [DG] smartd/smartctl: changed scsiClearControlGLTSD() to
-       scsiSetControlGLTSD() with an 'enabled' argument so '-S on'
-       and '-S off' work for SCSI devices (if changing GLTSD supported).
-
-  [BA] smartd/smartctl: wired in scsiClearControlGLTSD(). Could still
-       use a corresponding Set function.  Left stubs for this purpose.
-
-  [DG] scsicmds: added scsiClearControlGLTSD() [still to be wired in]
-
-  [BA] smartctl: make SCSI -T options behave the same way as the
-       ATA ones.
-
-  [DG] smartctl: output scsi transport protocol if available
-
-  [DG] scsi: stop device scan in smartd and smartctl if badly formed
-       mode response [heuristic to filter out USB devices before we
-       (potentially) lock them up].
-
-  [BA] smartd: deviceclose()->CloseDevice(). Got rid of SCSIDEVELOPMENT
-       macro-enabled code.  Added -W to list of gcc specific options to
-       always enable. Made code clean for -W warnings.
-
-  [PW] Added Maxtor DiamondMax VL 30 family to knowndrives table.
-
-  [DG] scsi: add warning (when '-l error' active) if Control mode page
-       GLTSD bit is set (global disable of saving log counters)
-
-  [DG] scsi: remember mode sense cmd length. Output trip temperature
-       from IE lpage (IBM extension) when unavailable from temp lpage.
-
-  [BA] smartd: for both SCSI and ATA now warns user if either
-       the number of self-test errors OR timestamp of most
-       recent self-test error have increased.
-
-  [DG] smartctl: output Seagate scsi Cache and Factory log pages (if
-       available) when vendor attributes chosen
-
-  [DG] smartd: add scsiCountFailedSelfTests() function.
-
-  [DG] Do more sanity checking of scsi log page responses.
-
-  [BA] smartd: now warns user if number of self-test errors has
-       increased for SCSI devices.
-
-  [BA] smartd: warn user if number of ATA self-test errors increases
-       (as before) OR if hour time stamp of most recent self-test
-       error changes.
-
-  [DG] More checks for well formed mode page responses. This has the side
-       effect of stopping scans on bad SCSI implementations (e.g. some
-       USB disks) prior to sending commands (typically log sense) that
-       locks them up.
-
-  [PW] Added Western Digital Caviar family and Caviar SE family to
-       knowndrives table.
-
-  [BA] smartd: added -l daemon (which is the default value if -l
-       is not used).
-
-  [PW] Added Seagate Barracuda ATA V family to knowndrives table.
-
-  [BA] smartd: added additional command line argument -l FACILITY
-       or --logfacility FACILITY.  This can be used to redirect
-       messages from smartd to a different file than the one used
-       by other system daemons.
-
-  [PW] Added Seagate Barracuda 7200.7, Western Digital Protege WD400EB,
-       and Western Digital Caviar AC38400 to knowndrives table.
-
-  [BA] smartd: scanning should now also work correctly for
-       devfs WITHOUT traditional links /dev/hd[a-t] or /dev/sd[a-z].
-  
-  [PW] Added Maxtor 4W040H3, Seagate Barracuda 7200.7 Plus,
-       IBM Deskstar 120GXP (40GB), Seagate U Series 20410,
-       Fujitsu MHM2100AT, MHL2300AT, MHM2150AT, and IBM-DARA-212000
-       to knowndrives table.
-
-  [PW] Added remaining Maxtor DiamondMax Plus 9 models to knowndrives
-       table.
-
-  [EM] smartd: If no matches found, then return 0, rather than an error
-       indication, as it just means no devices of the given type exist.
-       Adjust FreeBSD scan code to mirror Linux version.
-
-  [BA] smartd: made device scan code simpler and more robust. If
-       too many devices detected, warn user but scan as many
-       as possible.  If error in scanning, warn user but don't
-       die right away.
-
-  [EM] smartd: To keep as consistent as possible, migrate FreeBSD
-       devicescan code to also use glob(3). Also verified clean 
-       compile on a 4.7 FreeBSD system.
-
-  [BA] smartd: Modified device scan code to use glob(3). Previously
-       it appeared to have trouble when scanning devices on an XFS
-       file system, and used non-public interface to directory
-       entries. Problems were also reported when /dev/ was on an
-       ext2/3 file system, but there was a JFS partition on the same
-       disk.
-
-  [BA] Clearer error messages when device scanning finds no suitable
-       devices.
-
-  [EM] FreeBSD:	Fixup code to allow for proper compilation under 
-       -STABLE branch.
-
-smartmontools 5.23
-
-  [BA] smartd: didn't close file descriptors of ATA packet devices
-       that are scanned. Fixed.
-
-  [BA] Added reload/report targets to the smartmontools init script.
-       reload: reloads config file
-       report: send SIGUSR1 to check devices now
-
-smartmontools 5.22
-
-  [EM] Fix compile issues for FreeBSD < 5-CURRENT.
-
-  [PW] Added Fujitsu MHM2200AT to knowndrives table.
-
-  [BA] To help catch bugs, clear ATA error structures before all
-       ioctl calls.  Disable code that attempted to time-out on SCSI
-       devices when they hung (doesn't work).
- 
-  [BA] Documented STATUS/ERROR flags added by [PW] below.
-
-  [BA] Improved algorithm to recognize ATA packet devices. Should
-       no longer generate SYSLOG kernel noise when user tries either
-       smartd or smartctl on packet device (CD-ROM or DVD).  Clearer
-       warning messages from smartd when scanning ATA packet device.
-
-  [PW] Added TOSHIBA MK4025GAS to knowndrives table.
-
-  [PW] Added a textual interpretation of the status and error registers
-       in the SMART error log (ATA).  The interpretation is
-       command-dependent and currently only eight commands are supported
-       (those which produced errors in the error logs that I happen to
-       have seen).
-
-  [BA] added memory allocation tracking to solaris code.
-       Fixed solaris signal handling (reset handler to default
-       after first call to handler) by using sigset. Added
-       HAVE_SIGSET to configure.in
-
-  [CD] solaris port: added SCSI functionality to solaris
-       stubs.
-
-  [BA] smartd: attempt to address bug report about smartd
-       hanging on USB devices when scanning:
-       https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=107615
-       Set a timeout of SCSITIMEOUT (nominally 7 seconds) before
-       giving up.
-
-  [EM] smartd: DEVICESCAN will follow links in a devfs filesystem and
-       make sure the end point is a disc.  Update documentation, added
-       note about FreeBSD scanning
-
-  [BA] smartd: DEVICESCAN also looks for block devices in
-       /dev.  Updated documentation.  Now scans for up to
-       20 ATA devices /dev/hda-t rather than previous 12
-       /dev/hda-l.
-
-  [EM] smartd: mirror the FreeBSD DEVICESCAN logic for Linux,
-       so that smartd now scans only devices found in /dev/. Also,
-       make utility memory functions take a line number and file so
-       that we report errors with the correct location.
- 
-  [GG] add a note about Debian bug #208964 to WARNINGS.
-
-  [BA] smartctl: -T verypermissive option broken.  Use
-       -T verpermissive until the next release, please.
-
-  [BA] Syntax mods so that code also compiles on Solaris using
-       Sun Workshop compiler.  Need -xmemalign 1i -xCC flags
-       for cc.
-
-smartmontools 5.21
-
-  [DK] Changed configure.in so -Wall is only included if gcc
-       is used (this is a gcc specific flag) and -fsignedchar
-       is not used at all (this is a gcc specific compiler 
-       flag).
-
-  [BA] Modifications so that code now compiles under solaris. Now
-       all that's needed (:-) is to fill in os_solaris.[hc].  Added
-       os_generic.[hc] as guide to future ports.  Fixed -D option
-       of smartd (no file name).  Modified -h opt of smartd/smartctl
-       to work properly with solaris getopt().
-
-  [EM] Update MAN pages with notes that 3ware drives are NOT supported
-	under FreeBSD. Cleanup FreeBSD warning message handling.
-
-  [EM] FreeBSD only: Fix first user found bug....I guess I was making
-       the wrong assumption on how to convert ATA devnames to
-       channel/unit numbers.
-  
-  [EM] Allow for option --enable-sample to append '.sample' to installed
-	smartd.conf and rc script files. Also, let rc script shell setting
-	be determined by configure
-
-  [EM] Minor autoconf update to include -lcam for FreeBSD
-
-  [EM] Add conditional logic to allow FreeBSD to compile pre-ATAng.
-	-- note, not tested
-	Add some documentation to INSTALL for FreeBSD.
-
-  [EM] Implement SCSI CAM support for FreeBSD.  NOTE: I am not an expert
-	in the use of CAM.  It seems to work for me, but I may be doing
-	something horribly wrong, so please exercise caution.
-
-  [EM] Switch over to using 'atexit' rather than 'on_exit' routine. This also
-  	meant we needed to save the exit status elsewhere so our 'Goodbye'
-	routine could examine it.
-
-  [EM] Move the DEVICESCAN code to os specific files. Also moved some of the
-	smartd Memory functions to utility.c to make available to smartctl.
-
-  [EM] Code janitor work on os_freebsd.c.
-
-  [EM] Added os_freebsd.[hc] code.  Additional code janitor
-       work.
-
-  [BA] Code janitor working, moving OS dependent code into
-       os_linux.[hc].
-
-  [GG] conditionally compile os_{freebsd,linux}.o depending on
-       host architecture
-
-  [PW] Print estimated completion time for tests
-
-  [BA] Added -F samsung2 flag to correct firmware byte swap.
-       All samsung drives with *-23 firmware revision string.
-
-smartmontools 5.20
-
-  [GG] Fixed broken Makefile.am (zero length smartd.conf.5
-       was being created), fix broken uninstall/distcheck targets
-
-  [FM] Improved Slackware init script added to /etc/smartd.initd
-
-smartmontools 5.19 [NOTE CHANGE OF RELEASE NUMBERING]
-
-  [BA] smartctl: added '-T verypermissive' option which is
-       equivalent to giving '-T permissive' many times.
-
-  [BA] Try harder to identify from IDENTIFY DEVICE structure
-       if SMART supported/enabled.  smartd now does a more
-       thorough job of trying to assess this before sending
-       a SMART status command to find out for sure.
-
-  [BA] smartctl: it's now possible to override the program's
-       guess of the device type (ATA or SCSI) with -d option.
-
-  [BA] try hard to avoid sending IDENTIFY DEVICE to packet
-       devices (CDROMS).  They can't do SMART, and this generates
-       annoying syslog messages. At the same time, identify type
-       of Packet device.
-
-  [BA] smartctl: Can now use permissive option more
-       than once, to control how far to go before giving up.
-
-  [BA] smartd: if user asked to monitor either error or self-test
-       logs (-l error or -l selftest) WITHOUT monitoring any of the
-       Attribute values, code will SEGV.  For 5.1-18 and earlier,
-       a good workaround is to enable Auto offline (-o on).
-
-  [BA] smartctl: If enable auto offline command given, update auto
-       offline status before printing capabilities.
-
-  [GG] Make autotools build the default, remove autotools.diff
-
-  [GG] Add auto{conf,make} support, not enabled by default. 
-
-  [BA] Eliminated #include <linux/hdreg.h> from code. This
-       should simplify porting to solaris, FreeBSD, etc. The
-       only linux-specific code is now isolated to three routines,
-       one for SCSI, one for Escalade, one for ATA.
-
-smartmontools 5.1-18
-
-  [BA] smartd: fixed serious bug - Attributes not monitored unless
-       user told smartd to ignore at least one of them!
-
-smartmontools 5.1-17
-
-  [BA] Default runlevels for smartd changed from 3 and 5 to
-       2, 3, 4, and 5.
-
-  [BA] Removed as much dynamic memory allocation as possible from
-       configuration file parsing. Reloading config file, even in
-       presence of syntax errors etc. should not cause memory leaks.
-
-  [PW] It is no longer permissible for the integer part (if any) of
-       arguments to --report and --device to be followed by non-digits.
-       For example, the "foo" in --report=ioctl,2foo was previously
-       ignored, but now causes an error.
-
-  [BA] smartd: added -q/--quit command line option to specify
-       under what circumstances smartd should exit.  The old
-       -c/--checkonce option is now obsoleted by this more
-       general-purpose option.
-
-  [BA] smartd now responds to a HUP signal by re-reading its
-       configuration file /etc/smartd.conf.  If there are
-       errors in this file, then the configuration file is
-       ignored and smartd continues to monitor the devices that
-       it was monitoring prior to receiving the HUP signal.
-
-  [BA] Now correctly get SMART status from disks behind 3ware
-       controllers, thanks to Adam Radford. Need 3w-xxxx driver
-       version 1.02.00.037 or later. Previously the smartmontools
-       SMART status always returned "OK" for 3ware controllers.
-
-  [BA] Additional work on dynamic memory allocation/deallocation.
-       This should have no effect on smartctl, but clears that way
-       for smartd to dynamically add and remove entries.  It should
-       also now be easier to modify smartd to re-read its config
-       file on HUP (which is easy) without leaking memory (which is
-       harder). The philosophy is that memory for data structures in
-       smartd is now allocated only on demand, the first time it
-       is needed.
-
-  [BA] smartd: finished cleanup.  Now use create/rm functions for
-       cfgentries and dynamic memory allocation almost everywhere.
-       Philosophy: aggresively try and provoke SEGV to help find
-       bad code.
-
-  [BA] Added SAMSUNG SV0412H to knowndrives table.
-
-  [BA] smartd: if DEVICESCAN used then knowndrives table might not set
-       the -v attributes correctly -- may have been the same for all
-       the drives.  Cleaned up some data structures and memory
-       allocation to try and ensure segvs if such problems are 
-       introduced again.
-
-  [BA] Now allow -S on and -o on for the 3ware device type.  For these
-       commands to be passed through, the stock 3ware 3w-xxxx driver
-       must be patched (8 lines).  I'll post a patch on the smartmontools
-       home page after it's been tested by a few other people and 3ware
-       have had a chance to look it over.
-
-smartmontools-5.1-16
-
-  [BA] smartd - can now monitor ATA drives behind 3ware controllers.
-
-  [BA] smartd - changed some FATAL out of memory error messages from
-       syslog level LOG_INFO to LOG_CRIT.
-
-  [BA] smartctl - added code to look at ATA drives behind 3ware RAID
-       controllers using the 3w-xxxx driver.  Note that for technical
-       reasons related to the 3w-xxxx driver, the "Enable Autosave",
-       "Enable Automatic Offline" commands are not implemented.
-       I will add this to smartd shortly.
-
-  [BA] smartd - modified sleep loop, so that smartd no longer comes
-       on the run queue every second.  Instead, unless interrupted,
-       it sleeps until the next polling time, when it wakes up. Now
-       smartd also tries to wake up at exactly the right
-       intervals (nominally 30 min) even if the user has been sending
-       signals to it.
-
-  [GG] add Fujitsu MHN2300AT to vendoropts_9_seconds.
-
-  [EB] Fujitsu change in knowndrives ... match the whole MPD and
-       MPE series for vendoropts_9_seconds.
-
-  [BA] smartd bug, might cause segv if a device can not be opened. Was
-       due to missing comma in char* list.  Consequence is that email
-       failure messages might have had the wrong Subject: heading for
-       errorcount, FAILEDhealthcheck, FAILEDreadsmartdata, FAILEDreadsmarterrorlog,
-       FAILEDreadsmartsefltestlog, FAILEDopendevice were all displaced by
-       one.  And FAILEDopendevice might have caused a segv if -m was being
-       used as a smartd Directive.
-
-smartmontools-5.1-15
-
-  [BA] Cleaned up smartmontools.spec so that upgrading, removing
-       and other such operations correctly preserve running behavior
-       and booting behavior of smartd.
-
-  [BA] Improved formatting of ATA Error Log printout, and added
-       listing of names of commands that caused the error. Added
-       obsolete ATA-4 SMART feature commands to table, along with
-       obsolete SFF-8035i SMART feature command.
-
-  [PW] Added atacmdnames.[hc], which turn command register &
-       feature register pairs into ATA command names.
-
-  [BA] Added conveyance self-test.  Some code added for selective
-       self-tests, but #ifdefed out.
-
-  [BA] Modified smartd exit status and log levels.  If smartd is
-       "cleanly" terminated, for example with SIGTERM, then its
-       exit messages are now logged at LOG_INFO not LOG_CRIT
-
-  [BA] Added Attribute IDs  (Fujitsu) 0xCA - 0xCE.  This is decimal
-       202-206. Added -v switches for interpretation of Attributes
-       192, 198 and 201. 
-
-  [BA] Made smartmontools work with any endian order machine for:
-       - SMART selftest log
-       - SMART ATA error log
-       - SMART Attributes values
-       - SMART Attributes thesholds
-       - IDENTIFY DEVICE information
-       - LOG DIRECTORY
-       Smartmontools is now free of endian bias and works correctly
-       on both little- and big-endian hardware.  This has been tested by
-       three independent PPC users on a variety of ATA and SCSI hardware.
-
-  [DG] Check that certain SCSI command responses are well formed. If
-       IEC mode page response is not well formed exit smartctl. This
-       is to protect aacraid. smartd should ignore a aacraid device.
-
-smartmontools-5.1-14
-
-  [BA] smartctl: added column to -A output to show if Attributes are
-       updated only during off-line testing or also during normal
-       operation.
-
-smartmontools-5.1-13
-
-  [BA] smartd: attempt to enable/disable automatic offline testing even
-       if the disk appears not to support it.  Now the same logic
-       as smartctl.
-
-  [BA] Added definition of Attribute 201, soft read error rate.
-
-  [BA] Added IBM/Hitachi IC35L120AVV207-1 (GXP-180) and corresponding
-       8MB Cache GXP-120 to drive database.
-
-  [BA] smartd: if DEVICESCAN Directive used in smartd.conf, and
-       -I, -R or -r Directives used in conjunction with this, got
-       segv errors.  Fixed by correcting memory allocation calls.
-
-  [BA] smartd: enable automatic offline testing was broken due
-       to cut-and-paste error that disabled it instead of
-       enabling it.  Thanks to Maciej W. Rozycki for pointing
-       out the problem and solution.
-
-  [BA] Fixed "spelling" of some Attribute names to replace spaces
-       in names by underscores. (Fixed field width easier for awk
-       style parsing.)
-
-  [BA,GF] Added mods submitted by [GF] to support Attribute 193 being
-       load/unload cycles. Add -v 193,loadunload option, useful for
-       Hitachi drive DK23EA-30, and add this drive to knowndrive.c
-       Add meaning of attribute 250 : Read error retry rate
-
-smartmontools-5.1-12
-
-  [BA] Added another entry for Samsung drives to knowndrive table.
-
-  [DG] Refine SCSI log sense command to do a double fetch in most cases
-       (but not for the TapeAlert log page). Fix TapeAlert and Self Test
-       log page response truncation.
-
-  [PW] Added 'removable' argument to -d Directive for smartd.  This indicates
-       that smartd should continue (rather than exit) if the device does not 
-       appear to be present.
-
-  [BA] Modified smartmontools.spec [Man pages location] and
-       smartd.initd [Extra space kills chkconfig!] for Redhat 6.x
-       compatibility (thanks to Gerald Schnabel).
-
-smartmontools-5.1-11
-
-  [EB] Add another Fujitsu disk to knowndrives.c
-
-  [GG] match for scsi/ and ide/ in case of devfs to exclude false postives
-
-  [BA] If SCSI device listed in /etc/smartd.conf fails to open or do
-       SMART stuff correctly, or not enough space
-       to list all SCSI devices, fail with error unless
-       -DSCSIDEVELOPMENT set during compile-time.
-
-  [BA] Added automatic recognition of /dev/i* (example: /dev/ide/...)
-       as an ATA device.
-
-  [DG] Add "Device type: [disk | tape | medium changer | ...] line to
-       smartctl -i output for SCSI devices.
-
-  [PW] Fixed bug in smartd where test email would be sent regularly (for
-       example, daily if the user had specified -M daily) instead of just
-       once on startup.
-
-  [KM] More TapeAlert work. Added translations for media changer
-       alerts. TapeAlert support reported according to the log page
-       presence. ModeSense not attempted for non-ready tapes (all
-       drives do not support this after all). Get peripheral type from
-       Inquiry even if drive info is not printed. Add QUIETON()
-       QUIETOFF() to TapeAlert log check.
-
-  [BA] Stupid bug in atacmds.c minor_str[] affected ataVersionInfo().
-       Two missing commas meant that minor_str[] had two few elements,
-       leading to output like this:
-       Device Model:     Maxtor 6Y120L0
-       Serial Number:    Y40BF74E
-       Firmware Version: YAR41VW0
-       Device is:        Not in smartctl database [for details use: -P showall]
-       ATA Version is:   7
-       ATA Standard is:  9,minutes
-                         ^^^^^^^^^
-       Missing commas inserted.
-
-  [BA] Fixed smartd bug.  On device registration, if ATA device did
-       not support SMART error or self-test logs but user had asked to
-       monitor them, an attempt would be made to read them anyway,
-       possibly generating "Drive Seek" errors.  We now check that
-       the self-test and error logs are supported before trying to
-       access them the first time.
-
-  [GG/BA] Fixed bug where if SMART ATA error log not supported,
-       command was tried anyway. Changed some error printing to use
-       print handlers.
-
-  [GG] Makefile modifications to ease packaging
-
-  [DG] Did work for TapeAlerts (SCSI). Now can detect /dev/nst0 as a
-       SCSI device. Also open SCSI devices O_NONBLOCK so they don't
-       hang on open awaiting media. The ATA side should worry about
-       this also: during a DEVICESCAN a cd/dvd device without media
-       will hang. Added some TapeAlert code suggested by Kai Makisara.
-
-smartmontools-5.1-10
-
-  [PW] Extended the -F option/Directive to potentially fix other firmware
-       bugs in addition to the Samsung byte-order bug.  Long option name is
-       now --firmwarebug and the option/Directive accepts an argument
-       indicating the type of firmware bug to fix.
-
-  [BA] Fixed a bug that prevented the enable automatic off-line
-       test feature from enabling.  It also prevented the enable Attribute
-       autosave from working.  See CVS entry for additional details.
-
-  [PW] Modified the -r/--report option (smartctl and smartd) to allow the
-       user to specify the debug level as a positive integer.
-
-  [BA] Added --log directory option to smartctl.  If the disk
-       supports the general-purpose logging feature set (ATA-6/7)
-       then this option enables the Log Directory to be printed.
-       This Log Directory shows which device logs are available, and
-       their lengths in sectors.
-
-  [PW] Added -P/--presets option to smartctl and -P Directive to smartd.
-
-  [GG] Introduce different exit codes indicating the type of problem
-       encountered for smartd.
-
-  [DG] Add non-medium error count to '-l error' and extended self test
-       duration to '-l selftest'. Get scsi IEs and temperature changes
-       working in smartd. Step over various scsi disk problems rather
-       than abort smartd startup.
-
-  [DG] Support -l error for SCSI disks (and tapes). Output error counter
-       log pages.
-
-  [BA] Added -F/--fixbyteorder option to smartctl.  This allows us to read
-       SMART data from some disks that have byte-reversed two- and four-
-       byte quantities in their SMART data structures.
-
-  [BA] Fixed serious bug: the -v options in smartd.conf were all put
-       together and used together, not drive-by-drive.
-
-  [PW] Added knowndrives.h and knowndrives.c.  The knowndrives array
-       supersedes the drivewarnings array.
-
-  [GG] add {-p,--pidfile} option to smartd to write a PID file on
-       startup. Update the manpage accordingly.
-
-  [DG] Fix scsi smartd problem detecting SMART support. More cleaning
-       and fix (and rename) scsiTestUnitReady(). More scsi renaming.
-
-  [BA] Fixed smartd so that if a disk that is explictily listed is not
-       found, then smartd will exit with nonzero status BEFORE forking.
-       If a disk can't be registered, this will also be detected before
-       forking, so that init scripts can react correctly.
-
-  [BA] Replaced all linux-specific ioctl() calls in atacmds.c with
-       a generic handler smartcommandhandler().  Now the only routine
-       that needs to be implemented for a given OS is os_specific_handler().
-       Also implemented the --report ataioctl. This provides 
-       two levels of reporting.  Using the option once gives a summary
-       report of device IOCTL transactions.  Using the option twice give
-       additional info (a printout of ALL device raw 512 byte SMART
-       data structures).  This is useful for debugging.
-
-  [DG] more scsi cleanup. Output scsi device serial number (VPD page
-       0x80) if available as part of '-i'. Implement '-t offline' as
-       default self test (only self test older disks support).
-
-  [BA] Changed crit to info in loglevel of smartd complaint to syslog
-       if DEVICESCAN enabled and device not found.
-
-  [BA] Added -v 194,10xCelsius option/Directive. Raw Attribute number
-       194 is ten times the disk temperature in Celsius.
-
-  [DG] scsicmds.[hc] + scsiprint.c: clean up indentation, remove tabs.
-       Introduce new intermediate interface based on "struct scsi_cmnd_io"
-       to isolate SCSI generic commands + responses from Linux details;
-       should help port to FreeBSD of SCSI part of smartmontools.
-       Make SCSI command builders more parametric.
-
-smartmontools-5.1-9
-  
-  [BA] smartctl: if HDIO_DRIVE_TASK ioctl() is not implemented (no
-       kernel support, then try to assess drive health by examining
-       Attribute values/thresholds directly.
-
-  [BA] smartd/smartctl: added -v 200,writeerrorcount option/Directive
-       for Fujitsu disks.
-
-  [BA] smartd: Now send email if any of the SMART commands fails,
-       or if open()ing the device fails.  This is often noted
-       as a common disk failure mode.
-
-  [BA] smartd/smartctl: Added -v N,raw8 -v N,raw16 and -v N,raw48
-       Directives/Options for printing Raw Attributes in different
-       Formats.
-
-  [BA] smartd: Added -r ID and -R ID for reporting/tracking Raw
-       values of Attributes.
-
-  [BA] smartd/smartctl: Changed printing of spin-up-time attribute
-       raw value to reflect current/average as per IBM standard.
-
-  [BA] smartd/smartctl: Added -v 9,seconds option for disks which
-       use Attribute 9 for power-on lifetime in seconds.
-
-  [BA] smartctl: Added a warning message so that users of some IBM
-       disks are warned to update their firmware.  Note: we may want
-       to add a command-line flag to disable the warning messages.
-       I have done this in a general way, using regexp, so that we
-       can add warnings about any type of disk that we wish...
-
-smartmontools-5.1-7
-
-  [BA] smartd: Created a subdirectory examplescripts/ of source
-       directory that contains executable scripts for the -M exec PATH
-       Directive of smartd.
-
-smartmontools-5.1-5
-
-  [BA] smartd: DEVICESCAN in /etc/smartd.conf
-       can now be followed by all the same Directives as a regular
-       device name like /dev/hda takes.  This allows one to use
-       (for example):
-       DEVICESCAN -m root@example.com
-       in the /etc/smartd.conf file.
-
-  [BA] smartd: Added -c (--checkonce) command-line option. This checks
-       all devices once, then exits.  The exit status can be
-       used to learn if devices were detected, and if smartd is
-       functioning correctly. This is primarily for Distribution
-       scripters.
-
-  [BA] smartd: Implemented -M exec Directive for
-       smartd.conf.  This makes it possible to run an
-       arbitrary script or mailing program with the
-       -m option.
-
-  [PW] smartd: Modified -M Directive so that it can be given
-       multiple times.  Added -M exec Directive.
-
-smartmontools-5.1-4
-
-  [BA] Fixed bug in smartctl pointed out by Pierre Gentile.
-       -d scsi didn't work because tryata and tryscsi were
-       reversed -- now works on /devfs SCSI devices.
-
-  [BA] Fixed bug in smartctl pointed out by Gregory Goddard
-       <ggoddard@ufl.edu>.  Manual says that bit 6 of return
-       value turned on if errors found in smart error log.  But
-       this wasn't implemented.
-
-smartmontools-5.1-3
-
-  [BA] Modified printing format for 9,minutes to read
-       Xh+Ym not X h + Y m, so that fields are fixed width.
-
-  [BA] Added Attribute 240 "head flying hours"
-
-smartmontools-5.1.1
-
-  [BA] As requested, local time/date now printed by smartctl -i
-
-  [PW] Added "help" argument to -v for smartctl
-
-  [PW] Added -D, --showdirectives option to smartd
-
-  [DG] add '-l selftest' capability for SCSI devices (update smartctl.8)
-
-  [BA] smartd,smartctl: added additional Attribute modification option
-       -v 220,temp and -v 9,temp.
-
-  [PW] Renamed smartd option -X to -d
-
-START OF SMARTMONTOOLS 5.1 series
-
-smartmontools-5.0.50
-
-  [PW] Changed smartd.conf Directives -- see man page
-
-  [BA/DG] Fixed uncommented comment in smartd.conf
-
-  [DG] Correct 'Recommended start stop count' for SCSI devices
-
-  [PW] Replaced smartd.conf directive -C with smartd option -i
-
-  [PW] Changed options for smartctl -- see man page.
-
-  [BA] Use strerror() to generate system call error messages.
-
-  [BA] smartd: fflush() all open streams before fork().
-
-  [BA] smartctl, smartd simplified internal handling of checksums
-  for simpler porting and less code.
-
-smartmontools-5.0.49
-
-  [PW] smartd --debugmode changed to --debug
-
-  [BA] smartd/smartctl added attribute 230 Head Amplitude from
-  IBM DPTA-353750.
-
-  [PW] Added list of proposed new options for smartctl to README.
-
-  [PW] smartd: ParseOpts() now uses getopt_long() if HAVE_GETOPT_LONG is
-  defined and uses getopt() otherwise.  This is controlled by CPPFLAGS in
-  the Makefile.
-
-  [BA] smartd: Fixed a couple of error messages done with perror()
-  to redirect them as needed.
-
-smartmontools-5.0.48
-
-  [BA] smartctl: The -O option to enable an Immediate off-line test
-  did not print out the correct time that the test would take to
-  complete.  This is because the test timer is volatile and not
-  fixed.  This has been fixed, and the smartctl.8 man page has been
-  updated to explain how to track the Immediate offline test as it
-  progresses, and to further emphasize the differences between the
-  off-line immediate test and the self-tests.
-
-  [BA] smartd/smartctl: Added new attribute (200) Multi_Zone_Error_Rate
-
-  [BA] smartctl: modified so that arguments could have either a single -
-  as in -ea or multiple ones as in -e -a.  Improved warning message for
-  device not opened, and fixed error in redirection of error output of
-  HD identity command.
-
-  [PW] smartd: added support for long options.  All short options are still
-  supported; see manpage for available long options.
-
-  [BA] smartctl.  When raw Attribute value was 2^31 or larger, did
-  not print correctly.
-
-smartmontools-5.0.46
-
-  [BA] smartd: added smartd.conf Directives -T and -s.  The -T Directive
-  enables/disables Automatic Offline Testing.  The -s Directive
-  enables/disables Attribute Autosave. Documentation and
-  example configuration file updated to agree.
-
-  [BA] smartd: user can make smartd check the disks at any time
-  (ie, interrupt sleep) by sending signal SIGUSR1 to smartd.  This
-  can be done for example with:
-  kill -USR1 <pid>
-  where <pid> is the process ID number of smartd.
-
-  [EB] scsi: don't trust the data we receive from the drive too
-  much. It very well might have errors (like zero response length).
-  Seen on Megaraid logical drive, and verified in the driver source.
-
-  [BA] smartd: added Directive -m for sending test email and
-  for modifying email reminder behavior.  Updated manual, and sample
-  configuration file to illustrate & explain this.
-
-  [BA] smartd: increased size of a continued smartd.conf line to
-  1023 characters.
-
-  [BA] Simplified Directive parsers and improved warning/error
-  messages.
-
-smartmontools-5.0.45
-
-  [EB] Fixed bug in smartd where testunitready logic inverted
-  prevented functioning on scsi devices.
-  The bug in question only affects smartd users with scsi devices.
-  To see if your version of smartd has the testunitready() bug, do
-     smartd -V
-  If the version of the module smartd.c in a line like:
-     Module: smartd.c      revision: 1.66   date: 2002/11/17
-  has a revision greater than or equal to 1.30, and less than or equal to
-  1.64, then your version of the code has this problem.
-  This problem affected releases starting with RELEASE_5_0_16 up to and
-  including RELEASE_5_0_43.
-
-  [BA] Added testunitnotready to smartctl for symmetry with smartd.
-
-  [SB] added Czech descriptions to .spec file
-  [SB]  corrected comment in smartd.conf example
-
-  [BA] Changed way that entries in the ATA error log are printed,
-  to make it clearer which is the most recent error and
-  which is the oldest one.
-
-  NOTE: All changes made prior to this point were done by Bruce Allen
-  [BA] although several of them had been suggested by earlier postings
-  by Stanislav Brabec [SB].
-
-smartmontools-5.0.43
-
-  Changed Temperature_Centigrade to Temperature_Celsius.
-  The term "Centigrade" ceased to exist in 1948.  (c.f
-  http://www.bartleby.com/64/C004/016.html).
-
-smartmontools-5.0.42
-
-  Modified SCSI device check to also send warning emails if
-  requested in directives file.
-
-  Added a new smartd configuration file Directive: -M ADDRESS.
-  This sends a single warning email to ADDRESS for failures or
-  errors detected with the -c, -L, -l, or -f Directives.
-
-smartmontools-5.0.38
-
-  Modified perror() statements in atacmds.c so that printout for SMART
-  commands errors is properly suppressed or queued depending upon users
-  choices for error reporting modes.
-
-  Added Italian descriptions to smartmontools.spec file.
-
-  Started impementing send-mail-on-error for smartd; not yet enabled.
-
-  Added -P (Permissive) Directive to smartd.conf file to allow SMART
-  monitoring of pre-ATA-3 Rev 4 disks that have SMART but do not have
-  a SMART capability bit.
- 
-  Removed charset encodings from smartmontools.spec file for non-English
-  fields.
-
-smartmontools-5.0.32
-
-  Added manual page smartd.conf.5 for configuration file.
-
-  smartctl: Missing ANSI prototype in failuretest(); fixed.
-
-  smartctl: Checksum warnings now printed on stdout, or are silent,
-  depending upon -q and -Q settings.
-
-smartmontools-5.0.31
-
-  Changed Makefile so that the -V option does not reflect file state
-  before commit!
-
-  smartctl: added new options -W, -U, and -P to control if and how the
-  smartctl exits if an error is detected in either a SMART data
-  structure checksum, or a SMART command returns an error.
-
-  modified manual page to break options into slightly more logical
-  categories.
-
-  reformatted 'usage' message order to agree with man page ordering
-
-  modified .spec file so that locale information now contains
-  character set definition.   Changed pt_BR to pt since we do not use any
-  aspect other than language.  See man setlocale.
-
-smartmontools-5.0.30
-  smartctl: added new options -n and -N to force device to be ATA or SCSI
-  smartctl: no longer dies silently if device path does not start/dev/X
-  smartctl: now handles arbitrary device paths
-
-smartmontools-5.0.29
-  Modified .spec file and Makefile to make them more compliant with
-  the "right" way of doing things.
-
-smartmontools-5.0.26
-  Fixed typesetting error in man page smartd.8
-
-  Removed redundant variable (harmless) from smartd.c
-
-smartmontools-5.0.25
-
-  Added a new directive for the configuration file.  If the word
-  DEVICESCAN appears before any non-commented material in the
-  configuration file, then the confi file will be ignored and the
-  devices wil be scanned.
-
-smartmontools-5.0.24
-
-    Note: it has now been confirmed that the code modifications between
-    5.0.23 and 5.0.24 have eliminated the GCC 3.2 problems.  Note that
-    there is a GCC bug howerver, see #848 at
-    http://gcc.gnu.org/cgi-bin/gnatsweb.pl?database=gcc&cmd=query
-
-      Added new Directive for Configuration file:
--C <N> This sets the time in between disk checks to be <N>
-      seconds apart.  Note that  although  you  can  give
-       this Directive multiple times on different lines of
-       the configuration file, only the final  value  that
-       is  given  has  an  effect,  and applies to all the
-       disks.  The default value of <N> is 1800  sec,  and
-       the minimum allowed value is ten seconds.
-
-    Problem wasn't the print format. F.L.W. Meunier <0@pervalidus.net>
-    sent me a gcc 3.2 build and I ran it under a debugger.  The
-    problem seems to be with passing the very large (2x512+4) byte
-    data structures as arguments.  I never liked this anyway; it was
-    inherited from smartsuite.  So I've changed all the heavyweight
-    functions (ATA ones, anyone) to just passing pointers, not hideous
-    kB size structures on the stack.  Hopefully this will now build OK
-    under gcc 3.2 with any sensible compilation options.
-
-smartmontools-5.0.23
-
-    Because of reported problems with GCC 3.2 compile, I have gone
-    thorough the code and explicitly changed all print format
-    parameters to correspond EXACTLY to int unless they have to be
-    promoted to long longs.  To quote from the glibc bible: [From
-    GLIBC Manual: Since the prototype doesn't specify types for
-    optional arguments, in a call to a variadic function the default
-    argument promotions are performed on the optional argument
-    values. This means the objects of type char or short int (whether
-    signed or not) are promoted to either int or unsigned int, as
-    appropriate.]
-
-smartmontools-5.0.22
-
-    smartd, smartctl now warn if they find an attribute whose ID
-    number does not match between Data and Threshold structures.
-
-    Fixed nasty bug which led to wrong number of arguments for a
-    varargs statement, with attendent stack corruption.  Sheesh!
-    Have added script to CVS attic to help find such nasties in the
-    future.
-
-smartmontools-5.0.21
-
-    Eliminated some global variables out of header files and other
-    minor cleanup of smartd.
-
-smartmontools-5.0.20
-
-    Did some revision of the man page for smartd and made the usage
-    messages for Directives 100% consistent.
-
-smartmontools-5.0-19
-
-    smartd: prints warning message when it gets SIGHUP, saying that it
-    is NOT re-reading the config file.
-
-    smartctl: updated man page to say self-test commands -O,x,X,s,S,A
-    appear to be supported in the code.  [I can't test these,  can anyone
-    report?]
-
-smartmontools-5.0-18
-
-    smartctl: smartctl would previously print the LBA of a self-test
-    if it completed, and the LBA was not 0 or 0xff...f However
-    according to the specs this is not correct.  According to the
-    specs, if the self-test completed without error then LBA is
-    undefined.  This version fixes that.  LBA value only printed if
-    self-test encountered an error.
-
-smartmontools-5.0-17
-
-    smartd has changed significantly. This is the first CVS checkin of
-    code that extends the options available for smartd.  The following
-    options can be placed into the /etc/smartd.conf file, and control the
-    behavior of smartd.
-    Configuration file Directives (following device name):
-    -A     Device is an ATA device
-    -S     Device is a SCSI device
-    -c     Monitor SMART Health Status
-    -l     Monitor SMART Error Log for changes
-    -L     Monitor SMART Self-Test Log for new errors
-    -f     Monitor for failure of any 'Usage' Attributes
-    -p     Report changes in 'Prefailure' Attributes
-    -u     Report changes in 'Usage' Attributes
-    -t     Equivalent to -p and -u Directives
-    -a     Equivalent to -c -l -L -f -t Directives
-    -i ID  Ignore Attribute ID for -f Directive
-    -I ID  Ignore Attribute ID for -p, -u or -t Directive
-    #      Comment: text after a hash sign is ignored
-    \      Line continuation character
-
-    cleaned up functions used for printing CVS IDs.  Now use string
-    library, as it should be.
-
-    modified length of device name string in smartd internal structure
-    to accomodate max length device name strings
-
-    removed un-implemented (-e = Email notification) option from
-    command line arg list.  We'll put it back on when implemeneted.
-
-    smartd now logs serious (fatal) conditions in its operation at
-    loglevel LOG_CRIT rather than LOG_INFO before exiting with error.
-
-    smartd used to open a file descriptor for each SMART enabled
-    device, and then keep it open the entire time smartd was running.
-    This meant that some commands, like IOREADBLKPART did not work,
-    since the fd to the device was open.  smartd now opens the device
-    when it needs to read values, then closes it.  Also, if one time
-    around it can't open the device, it simply prints a warning
-    message but does not give up.  Have eliminated the .fd field from
-    data structures -- no longer gets used.
-
-    smartd now opens SCSI devices as well using O_RDONLY rather than
-    O_RDWR.  If someone can no longer monitor a SCSI device that used
-    to be readable, this may well be the reason why.
-
-    smartd never checked if the number of ata or scsi devices detected
-    was greater than the max number it could monitor.  Now it does.
-
-smartmontools-5.0-16
-
-    smartd on startup now looks in the configuration file /etc/smartd.conf for
-    a list of devices which to include in its monitoring list.  See man page
-    (man smartd) for syntax.
-
-    smartd: close file descriptors of SCSI device if not SMART capable
-    Closes ALL file descriptors after forking to daemon.
-
-    added new temperature attribute (231, temperature)
-
-    smartd: now open ATA disks using O_RDONLY
-
-smartmontools-5.0-11
-
-    smartd now prints the name of a failed or changed attribute
-    into logfile, not just ID number
-
-    Changed name of -p (print version) option to -V
-
-    Minor change in philosophy: if a SMART command fails or the device
-    appears incapable of a SMART command that the user has asked for,
-    complain by printing an error message, but go ahead and try
-    anyway.  Since unimplemented SMART commands should just return an
-    error but not cause disk problems, this should't cause any
-    difficulty.
-
-    Added two new flags: q and Q.  q is quiet mode - only print: For
-    the -l option, errors recorded in the SMART error log; For the -L
-    option, errors recorded in the device self-test log; For the -c
-    SMART "disk failing" status or device attributes (pre-failure or
-    usage) which failed either now or in the past; For the -v option
-    device attributes (pre-failure or usage) which failed either now
-    or in the past.  Q is Very Quiet mode: Print no ouput.  The only
-    way to learn about what was found is to use the exit status of
-    smartctl.
-
-    smartctl now returns sensible values (bitmask).  See smartctl.h
-    for the values, and the man page for documentation.
-
-    The SMART status check now uses the correct ATA call.  If failure
-    is detected we search through attributes to list the failed ones.
-    If the SMART status check shows GOOD, we then look to see if their
-    are any usage attributes or prefail attributes have failed at any
-    time.  If so we print them.
-
-    Modified function that prints vendor attributes to say if the
-    attribute has currently failed or has ever failed.
-
-    -p option now prints out license info and CVS strings for all
-    modules in the code, nicely formatted.
-
-    Previous versions of this code (and Smartsuite) only generate
-    SMART failure errors if the value of an attribute is below the
-    threshold and the prefailure bit is set.  However the ATA Spec
-    (ATA4 <=Rev 4) says that it is a SMART failure if the value of an
-    attribute is LESS THAN OR EQUAL to the threshold and the
-    prefailure bit is set.  This is now fixed in both smartctl and
-    smartd.  Note that this is a troubled subject -- the original
-    SFF 8035i specification defining SMART was inconsistent about
-    this.  One section says that Attribute==Threshold is pass,
-    and another section says it is fail.  However the ATA specs are
-    consistent and say Attribute==Threshold is a fail.
-
-    smartd did not print the correct value of any failing SMART attribute.  It
-    printed the index in the attribute table, not the attribute
-    ID. This is fixed.
-
-    when starting self-tests in captive mode ioctl returns EIO because
-    the drive has been busied out.  Detect this and don't return an eror
-    in this case.  Check this this is correct (or how to fix it?)
- 
-    fixed possible error in how to determine ATA standard support
-    for devices with no ATA minor revision number.
-
-    device opened only in read-only not read-write mode.  Don't need R/W 
-    access to get smart data. Check this with Andre.
-
-    smartctl now handles all possible choices of "multiple options"
-    gracefully.  It goes through the following phases of operation,
-    in order: INFORMATION, ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
-    Documentation has bee updated to explain the different phases of
-    operation.  Control flow through ataPrintMain()
-    simplified.
-
-    If reading device identity information fails, try seeing if the info
-    can be accessed using a "DEVICE PACKET" command.  This way we can
-    at least get device info.
-
-    Modified Makefile to automatically tag CVS archive on issuance of
-    a release
-
-    Modified drive detection so minor device ID code showing ATA-3 rev
-    0 (no SMART) is known to not be SMART capable.
-
-    Now verify the checksum of the device ID data structure, and of the
-    attributes threshold structure.  Before neither of these
-    structures had their checksums verified.
-
-    New behavior vis-a-vis checksums.  If they are wrong, we log
-    warning messages to stdout, stderr, and syslog, but carry on
-    anyway.  All functions now call a checksumwarning routine if the
-    checksum doesn't vanish as it should.
-
-    Changed Read Hard Disk Identity function to get fresh info from
-    the disk on each call rather than to use the values that were read
-    upon boot-up into the BIOS.  This is the biggest change in this
-    release.  The ioctl(device, HDIO_GET_IDENTITY, buf ) call should
-    be avoided in such code.  Note that if people get garbled strings
-    for the model, serial no and firmware versions of their drives,
-    then blame goes here (the BIOS does the byte swapping for you,
-    apparently!)
-    
-    Function ataSmartSupport now looks at correct bits in drive
-    identity structure to verify first that these bits are valid,
-    before using them.
-    
-    Function ataIsSmartEnabled() written which uses the Drive ID state
-    information to tell if SMART is enabled or not.  We'll carry this
-    along for the moment without using it.
-
-    Function ataDoesSmartWork() guaranteed to work if the device
-    supports SMART.
-
-    Replace some numbers by #define MACROS
-
-    Wrote Function TestTime to return test time associated with each
-    different type of test.
-
-    Thinking of the future, have added a new function called
-    ataSmartStatus2().  Eventually when I understand how to use the
-    TASKFILE API and am sure that this works correctly, it will
-    replace ataSmartStatus().  This queries the drive directly to
-    see if the SMART status is OK, rather than comparing thresholds to
-    attribute values ourselves. But I need to get some drives that fail
-    their SMART status to check it.
-
-
-smartmontools-5.0-10
-    Removed extraneous space before printing in some error messages
-    Fixed additional typos in documentation
-    Fixed some character buffers that were too short for their contents.
-
-smartmontools-5.0-9
-
-    Put project home path into all source files near the top
-    Corrected typos in the documentation
-    Modified Makefile so that Mandrake Cooker won't increment version number
-    (unless they happen to be working on my machine, which I doubt!)
-
-smartmontools-5.0-8:
-
-    For IBM disks whose raw temp data includes three temps. print all
-    three
-
-    print timestamps for error log to msec precision
-
-    added -m option for Hitachi disks that store power on life in
-    minutes
-
-    added -L option for printing self-test error logs
-
-    in -l option, now print power on lifetime, so that one can see
-    when the error took place
-
-    updated SMART structure definitions to ATA-5 spec
-
-    added -p option
-
-    added -f and -F options to enable/disable autosave threshold
-    parameters
-
-    changed argv parsing to use getops -- elminate buffer overflow
-    vulnerability
-
-    expanded and corrected documentation
-
-    fixed problem with smartd.  It did not actually call
-    ataSmartEnable()!  Since the argument was left out, the test
-    always suceeded because it evaluated to a pointer to the function.
-
-    smartd: closed open file descriptors if device does not support
-    smart. Note: this still needs to be fixed for SCSI devices
-
-
-smartmontools-5.0-0  STARTED with smartsuite-2.1-2
diff --git a/sm5/COPYING b/sm5/COPYING
deleted file mode 100644
index d60c31a97a544b53039088d14fe9114583c0efc3..0000000000000000000000000000000000000000
--- a/sm5/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year  name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/sm5/INSTALL b/sm5/INSTALL
deleted file mode 100644
index 3519156a08c3d057f14f9bb94ae27c84ef3f737a..0000000000000000000000000000000000000000
--- a/sm5/INSTALL
+++ /dev/null
@@ -1,572 +0,0 @@
-Smartmontools installation instructions
-=======================================
-
-$Id: INSTALL,v 1.54 2004/08/14 20:04:38 chrfranke Exp $
-
-Please also see the smartmontools home page:
-http://smartmontools.sourceforge.net/
-
-Table of contents:
-
-[1] System requirements
-[2] Installing from CVS
-[3] Installing from source tarball
-[4] Guidelines for different Linux distributions
-[5] Guidelines for FreeBSD
-[6] Guidelines for Darwin
-[7] Guidelines for NetBSD
-[8] Guidelines for Solaris
-[9] Guidelines for Cygwin
-[10] Guidelines for Windows
-[11] Comments
-[12] Detailed description of ./configure options
-
-[1] System requirements
-=======================
-
-    A) Linux
-
-    Any Linux distribution will support smartmontools if it has a
-    kernel version greater than or equal to 2.2.14. So any recent
-    Linux distribution should support smartmontools.
-
-    There are two parts of smartmontools that may require a patched or
-    nonstandard kernel:
-
-    (1) To get the ATA RETURN SMART STATUS command, the kernel needs
-    to support the HDIO_DRIVE_TASK ioctl().
-
-    (2) To run Selective Self-tests, the kernel needs to support the
-    HDIO_DRIVE_TASKFILE ioctl().
-
-    If your kernel does not support one or both of these ioctls, then
-    smartmontools will "mostly" work.  The things that don't work will
-    give you harmless warning messages.
-
-    For item (1) above, any 2.4 or 2.6 series kernel will provide
-    HDIO_DRIVE_TASK support.  Some 2.2.20 and later kernels also
-    provide this support IF they're properly patched and
-    configured. [Andre Hedrick's IDE patches may be found at
-    http://www.funet.fi/pub/linux/kernel/people/hedrick/ide-2.2.20/ or
-    are available from your local kernel.org mirror.  They are not
-    updated for 2.2.21 or later, and may contain a few bugs.].
-    If the configuration option CONFIG_IDE_TASK_IOCTL
-    exists in your 2.2.X kernel source code tree, then your 2.2.X
-    kernel will probably support this ioctl. [Note that this kernel
-    configuration option does NOT need to be enabled. Its presence
-    merely indicates that the required HDIO_DRIVE_TASK ioctl() is
-    supported.]
-
-    For item (2) above, your kernel must be configured with the kernel
-    configuration option CONFIG_IDE_TASKFILE_IO enabled.  This
-    configuration option is present in all 2.4 and 2.6 series
-    kernels. Some 2.2.20 and later kernels also provide this support
-    IF they're properly patched and configured as described above.
-
-    Please see FAQ section of the URL above for additional details.
-
-    If you are using 3ware controllers, for full functionality you
-    must either use version 1.02.00.037 or greater of the 3w-xxxx
-    driver, or patch earlier 3ware 3w-xxxx drivers.  See
-    http://smartmontools.sourceforge.net/3w-xxxx.txt
-    for the patch.  The version 1.02.00.037 3w-xxxx.c driver was
-    incorporated into kernel 2.4.23-bk2 on 3 December 2003 and into
-    kernel 2.6.0-test5-bk11 on 23 September 2003.
-
-    B) FreeBSD
-
-    For FreeBSD support, a 5-current kernel that includes ATAng is
-    required in order to support ATA drives.  Even current versions of
-    ATAng will not support 100% operation, as the SMART status can not
-    be reliably retrieved.  There is patch pending approval of the
-    ATAng driver maintainer that will address this issue.
-
-    C) Solaris
-
-    The SCSI code has been tested on a variety of Solaris 8 and 9
-    systems.  ATA/IDE code only works on SPARC platform.  All tested
-    kernels worked correctly.
-
-    D) NetBSD
-
-    The code was tested on a 1.6ZG (i.e., 1.6-current) system. It should
-    also function under 1.6.1 and later releases (unverified).  Currently
-    it doesn't support ATA devices on 3ware RAID controllers.
-
-    E) Cygwin
-
-    The code was tested on Cygwin 1.5.7 and should also work on other
-    recent releases.
-
-    Both Cygwin and Windows versions of smartmontools share the same code
-    to access the IDE/ATA or SCSI devices. The information in the "Windows"
-    section below also applies to the Cygwin version.
-
-    F) Windows
-
-    The code was tested on Windows 98SE, NT4, 2000 and XP. It should also
-    work on Windows 95(OSR2), 98, ME and 2003.
-
-    On 9x/ME, only standard (legacy) IDE/ATA devices 0-3 are supported.
-    The driver SMARTVSD.VXD must be present in WINDOWS\SYSTEM\IOSUBSYS
-    to get loaded at Windows startup. The default location in a new
-    installation of some versions of Windows is the WINDOWS\SYSTEM folder.
-    In this case, move SMARTVSD.VXD to WINDOWS\SYSTEM\IOSUBSYS and reboot
-    (http://support.microsoft.com/default.aspx?scid=kb;en-us;265854).
-
-    On NT4/2000/XP, also other ATA or SATA devices are supported if
-    the device driver implements the SMART IOCTL.
-
-    The IDE/ATA read log command (smartctl -l, --log, -a, --all) is
-    not supported on NT4. On 2000/XP, the undocumented and possibly buggy
-    IOCTL_IDE_PASS_THROUGH is used for this purpose (see WARNINGS file).
-
-    SCSI devices are supported on all versions of Windows. An installed
-    ASPI interface (WNASPI32.DLL) is required to access SCSI devices.
-
-    G) MacOS/Darwin
-
-    The code was tested on MacOS 10.3.4.  It should work from 10.3
-    forwards.  It doesn't support 10.2.
-
-    There's an important limitation (see WARNINGS); due to bugs in
-    the libraries used, you cannot run a short test or switch SMART
-    support off on a drive; if you try, you will just run an extended
-    test or switch SMART support on.  So don't panic when your "short"
-    test seems to be taking hours.
-
-    It's also not possible at present to control when the offline
-    routine runs. If your drive doesn't have it running automatically by
-    default, you can't run it at all.
-
-    SCSI devices are not currently supported.  Detecting the power
-    status of a drive is also not currently supported.
-
-    To summarize this, from another point of view, the things that
-    are not supported fall into two categories:
-
-   * Can't be implemented easily without more kernel-level support,
-     so far as I know:
-     - running immediate offline, conveyance, or selective tests
-     - running any test in capture mode
-     - aborting tests
-     - switching on automatic offline testing
-     - support for SCSI
-     - checking the power mode [-n Directive of smartd] (this is not
-       completely impossible, but not by using a documented API)
-
-   * Are implemented, but don't work due to OS bugs:
-     - switching off SMART (switching *on* works fine)
-     - switching off auto-save (but why would you want to?)
-     - running the short test (that leaves you with only the extended test)
-
-The last set have been filed in Apple's bug tracking system and
-hopefully will be fixed.
-
-However, some things do work well.  For ATA devices, all the
-informational output is available, unless you want something that only
-an offline test updates.
-
-
-[2] Installing from CVS
-=======================
-    Get the sources from the CVS repository:
-    cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools login
-    cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co sm5
-    (when prompted for a password, just press Enter)
-
-    Then type:
-    ./autogen.sh
-    and continue with step [3] below, skipping the "unpack the tarball" step.
-
-    Further details of using CVS can be found at the URL above.
-
-    The autogen.sh command is ONLY required when installing from
-    CVS. You need GNU Autoconf (version 2.50 or greater), GNU Automake
-    (version 1.6 or greater) and their dependencies installed in order
-    to run it.  You can get these here:
-    http://www.gnu.org/directory/GNU/autoconf.html
-    http://www.gnu.org/directory/GNU/automake.html
-
-[3] Installing from the source tarball
-======================================
-
-    If you are NOT installing from CVS, then unpack the tarball: 
-    tar zxvf smartmontools-5.VERSION.tar.gz
-
-    Then:
-    ./configure
-    make
-    make install (you may need to be root to do this)
-
-    As shown (with no options to ./configure) this defaults to the
-    following set of installation directories:   
-    --prefix=/usr/local
-    --sbindir=/usr/local/sbin
-    --sysconfdir=/usr/local/etc
-    --mandir=/usr/local/share/man
-    --with-docdir=/usr/local/share/doc/smartmontools-VERSION
-    --with-initscriptdir=/usr/local/etc/rc.d/init.d
-    --disable-sample
-
-    These will usually not overwrite existing "distribution" installations on
-    Linux Systems since the FHS reserves this area for use by the system
-    administrator.
-
-    For different installation locations or distributions, simply add
-    arguments to ./configure as shown in [4] below.
-
-    If you wish to alter the default C compiler flags, set an
-    environment variable CFLAGS='your options' before doing
-    ./configure, or else do:
-    make CFLAGS='your options'
-
-[4] Guidelines for different Linux distributions
-================================================
-
-Note: Please send corrections/additions to:
-smartmontools-support@lists.sourceforge.net
-
-Debian:
-  If you don't want to overwrite any distribution package, use:
-  ./configure
-
-Filesystem Hierarchy Standard (FHS, http://www.pathname.com/fhs/):
-  ./configure --sbindir=/usr/local/sbin                               \
-              --sysconfdir=/usr/local/etc                             \
-              --mandir=/usr/local/man                                 \
-              --with-initscriptdir=/usr/local/etc/rc.d/init.d         \
-              --with-docdir=/usr/local/share/doc/smartmontools-VERSION
-
-Red Hat:
-  ./configure --sbindir=/usr/sbin                               \
-	      --sysconfdir=/etc                                 \
-	      --mandir=/usr/share/man                           \
-	      --with-initscriptdir=/etc/rc.d/init.d             \
-	      --with-docdir=/usr/share/doc/smartmontools-VERSION
-
-Slackware:
-  If you don't want to overwrite any "distribution" package, use:
-  ./configure
-
-  Otherwise use:
-  ./configure --sbindir=/usr/sbin                               \
-              --sysconfdir=/etc                                 \
-              --mandir=/usr/share/man                           \
-              --with-initscriptdir=/etc/rc.d                    \
-              --with-docdir=/usr/share/doc/smartmontools-VERSION
-
-  And
-  removepkg smartmontools smartsuite (only root can do this)
-  before make install
-
-  The init script works on Slackware. You just have to add an entry like
-  the following in /etc/rc.d/rc.M or /etc/rc.d/rc.local:
-
-  if [ -x /etc/rc.d/smartd ]; then
-    . /etc/rc.d/smartd start
-  fi
-
-  To disable it:
-  chmod 644 /etc/rc.d/smartd
-
-  For a list of options:
-  /etc/rc.d/smartd
-
-SuSE:
-  ./configure --sbindir=/usr/sbin                                        \
-              --sysconfdir=/etc                                          \
-              --mandir=/usr/share/man                                    \
-              --with-initscriptdir=/etc/init.d                           \
-              --with-docdir=/usr/share/doc/packages/smartmontools-VERSION
-
-[5] Guidelines for FreeBSD
-==========================
-  To match the way it will installed when it becomes available as a PORT, use
-  the following:
-
-  ./configure --prefix=/usr/local                                      \
-              --with-initscriptdir=/usr/local/etc/rc.d/                \
-              --with-docdir=/usr/local/share/doc/smartmontools-VERSION \
-	      --enable-sample
-
-  Also, it is important that you use GNU make (gmake from /usr/ports/devel/gmake)
-  to build smartmontools, as the default FreeBSD make doesn't know how to build
-  the man pages.
-
-  NOTE: --enable-sample will cause the smartd.conf and smartd RC files to
-  be installed with the string '.sample' append to the name, so you will end
-  up with the following:
-	/usr/local/etc/smartd.conf.sample
-	/usr/local/etc/rc.d/smartd.sample
-
-
-[6] Guidelines for Darwin
-=========================
-  ./configure --with-initscriptdir=/Library/StartupItems
-
-
-[7] Guidelines for NetBSD
-=========================
-  ./configure --prefix=/usr/pkg                                       \
-	      --with-docdir=/usr/pkg/share/doc/smartmontools
-
-[8] Guidelines for Solaris
-==========================
-
-    smartmontools has been partially but not completely ported to
-    Solaris.  It includes complete SCSI support but no ATA or 3ware
-    support.  It can be compiled with either cc or gcc. To compile
-    with gcc:
-
-    ./configure [args]
-    make
-
-    To compile with Sun cc:
-
-    setenv CC cc  [csh syntax], or
-    CC=cc         [sh syntax]
-    ./configure [args]
-    make
-
-    The correct arguments [args] to configure are:
-     --sbindir=/usr/sbin                                \
-     --sysconfdir=/etc                                  \
-     --mandir=/usr/share/man                            \
-     --with-docdir=/usr/share/doc/smartmontools-VERSION \
-     --with-initscriptdir=/etc/init.d
-
-    To start the script automatically on bootup, create hardlinks that
-    indicate when to start/stop in:
-		    /etc/rc[S0123].d/
-    pointing to /etc/init.d/smartd. Create:
-	    K<knum>smartd in rcS.d, rc0.d, rc1.d, rc2.d
-	    S<snum>smartd in rc3.d
-    where <knum> is related to <snum> such that the higher snum is the
-    lower knum must be.
-
-    On usual configuration, '95' would be suitable for <snum> and '05'
-    for <knum> respectively.  If you choose these value, you can
-    create hardlinks by:
-
-    cd /etc
-    sh -c 'for n in S 0 1 2; do ln init.d/smartd rc$n.d/K05smartd; done'
-    sh -c 'for n in 3      ; do ln init.d/smartd rc$n.d/S95smartd; done'
-
-[9] Guidelines for Cygwin
-=========================
-
-Same as Red Hat:
-  ./configure --prefix=/usr                 \
-              --sysconfdir=/etc             \
-              --mandir='${prefix}/share/man'
-
-  OR EQUIVALENTLY
-  ./configure --sbindir=/usr/sbin                               \
-              --sysconfdir=/etc                                 \
-              --mandir=/usr/share/man                           \
-              --with-initscriptdir=/etc/rc.d/init.d             \
-              --with-docdir=/usr/share/doc/smartmontools-VERSION
-
-  Using DOS text file type as default for the working directories ("textmode"
-  mount option) is not recommended. Building the binaries and man pages using
-  "make" is possible, but "make dist" and related targets work only with UNIX
-  file type ("binmode" mount option) set. The "autogen.sh" script prints a
-  warning if DOS type is selected.
-
-[10] Guidelines for Windows
-==========================
-
-To compile the Windows release with MinGW, use the following on Cygwin:
-
-  ./configure --build=mingw32
-  make
-
-  Instead of using "make install", copy the .exe files into
-  some directory in the PATH.
-
-To build the Windows binary distribution, use:
-
-  make dist-win32
-  
-  This builds the distribution in directory
-
-  ./smartmontools-VERSION.win32/
-
-  and packs it into
-
-  ./smartmontools-VERSION.win32.zip
-
-  Additional make targets are distdir-win32 to build the directory
-  only and cleandist-win32 for cleanup.
-
-  The binary distribution includes all documentation files converted
-  to DOS text file format and *.html and *.txt preformatted man pages.
-  The tools unix2dos.exe (package cygutils) and zip.exe (package zip
-  or a native Win32 release of Info-ZIP, http://www.info-zip.org) are
-  necessary but may be not installed by Cygwin's default settings.
-
-  It is also possible to compile smartmontools with MSVC 6.0.
-  The project files (smartmontools_vc6.dsw, smart{ctl,d}_vc6.dsp) are
-  included in CVS (but not in source tarball). The config_vc6.h is no
-  longer maintained in CVS. The command:
-
-  make config-vc6
-
-  builds config_vc6.h from MinGW's config.h. Unlike MinGW, MSVC 6.0
-  can also be used to build the syslog message file tool syslogevt.exe.
-  See smartd man page for usage information about this tool.
-
-
-[11] Comments
-============
-
-To compile from another directory, you can replace the step
-  ./configure [options]
-by the following:
-  mkdir objdir
-  cd objdir
-  ../configure [options]
-
-To install to another destination (used mainly by package maintainers,
-or to examine the package contents without risk of modifying any
-system files) you can replace the step:
-  make install
-with:
-  make DESTDIR=/home/myself/smartmontools-package install
-
-Use a full path. Paths like ~/smartmontools-package may not work.
-
-After installing smartmontools, you can read the man pages, and try
-out the commands:
-   
-man smartd.conf
-man smartctl
-man smartd
-
-/usr/sbin/smartctl -s on -o on -S on /dev/hda (only root can do this)
-/usr/sbin/smartctl -a /dev/hda (only root can do this)
-
-Note that the default location for the manual pages are
-/usr/share/man/man5 and /usr/share/man/man8.  If "man" doesn't find
-them, you may need to add /usr/share/man to your MANPATH environment
-variable.
-
-Source and binary RPM packages are available at
-http://sourceforge.net/project/showfiles.php?group_id=64297
-
-Refer to http://smartmontools.sourceforge.net/index.html#howtodownload
-for any additional download and installation instructions.
-
-The following files are installed if ./configure has no options:
-
-/usr/local/sbin/smartd                                  [Executable daemon]
-/usr/local/sbin/smartctl                                [Executable command-line utility]
-/usr/local/etc/smartd.conf                              [Configuration file for smartd daemon]
-/usr/local/etc/rc.d/init.d/smartd                       [Init/Startup script for smartd]
-/usr/local/share/man/man5/smartd.conf.5                 [Manual page]
-/usr/local/share/man/man8/smartctl.8                    [Manual page]
-/usr/local/share/man/man8/smartd.8                      [Manual page]
-/usr/local/share/doc/smartmontools-5.X/AUTHORS          [Information about the authors and developers]
-/usr/local/share/doc/smartmontools-5.X/CHANGELOG        [A log of changes. Also see CVS]
-/usr/local/share/doc/smartmontools-5.X/COPYING          [GNU General Public License Version 2]
-/usr/local/share/doc/smartmontools-5.X/INSTALL          [Installation instructions: what you're reading!]
-/usr/local/share/doc/smartmontools-5.X/NEWS             [Significant bugs discovered in old versions]
-/usr/local/share/doc/smartmontools-5.X/README           [Overview]
-/usr/local/share/doc/smartmontools-5.X/TODO             [Things that need to be done/fixed]
-/usr/local/share/doc/smartmontools-5.X/WARNINGS         [Systems where lockups or other serious problems were reported]
-/usr/local/share/doc/smartmontools-5.X/smartd.conf      [Example configuration file for smartd]
-/usr/local/share/doc/smartmontools-5.X/examplescripts   [Executable scripts for -M exec of smartd.conf (4 files)]
-
-The commands:
-
-make htmlman
-make txtman
-
-may be used to build .html and .txt preformatted man pages.
-These are used by the dist-win32 make target to build the Windows
-distribution.
-The commands also work on other operating system configurations
-if suitable versions of man2html, groff and grotty are installed.
-On systems without man2html, the following command should work
-if groff is available:
-
-make MAN2HTML='groff -man -Thtml' htmlman
-
-
-[12] Detailed description of arguments to configure command
-===========================================================
-
-When you type:
-./configure [options]
-there are six particularly important variables that affect where the
-smartmontools software is installed.  The variables are listed here,
-with their default values in square brackets, and the quantities that
-they affect described following that.  This is a very wide table: please read
-it in a wide window.
-
-OPTIONS              DEFAULT                                      AFFECTS
--------              -------                                      -------
---prefix             /usr/local                                   Please see below
---sbindir            ${prefix}/sbin                               Directory for smartd/smartctl executables;
-                                                                  Contents of smartd/smartctl man pages
---mandir             ${prefix}/share/man                          Directory for smartctl/smartd/smartd.conf man pages
---sysconfdir         ${prefix}/etc                                Directory for smartd.conf;
-                                                                  Contents of smartd executable;
-                                                                  Contents of smartd/smartd.conf man pages;
-                                                                  Directory for rc.d/init.d/smartd init script
---with-initscriptdir  ${sysconfdir}/init.d/rc.d                   Location of init scripts       
---with-docdir	      ${prefix}/share/doc/smartmontools-5.X       Location of the documentation
---enable-sample	      --disable-sample				  Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file
-
-Here's an example:
-If you set --prefix=/home/joe and none of the other four
-variables then the different directories that are used would be:
---sbindir             /home/joe/sbin
---mandir              /home/joe/share/man
---sysconfdir          /home/joe/etc
---with-initscriptdir  /home/joe/etc/init.d/rc.d
---with-docdir	      /home/joe/doc/smartmontools-5.X
-
-This is useful for test installs in a harmless subdirectory somewhere.
-
-Here are the four possible cases for the four variables above:
-
-Case 1:
---prefix not set
---variable not set
-===> VARIABLE gets default value above
-
-Case 2:
---prefix set
---variable not set
-===> VARIABLE gets PREFIX/ prepended to default value above
-
-Case 3:
---prefix not set
---variable set
-===> VARIABLE gets value that is set
-
-Case 4:
---prefix is set
---variable is set
-===> PREFIX is IGNORED, VARIABLE gets value that is set
-
-
-Here are the differences with and without --enable-sample, assuming
-no other options specified (see above for details)
-
-Case 1:
---enable-sample provided
-==> Files installed are:
-	/usr/local/etc/smartd.conf.sample
-	/usr/local/etc/rc.d/init.d/smartd.sample
-
-Case 2:
---disable-sample provided or parameter left out
-==> Files installed are:
-	/usr/local/etc/smartd.conf
-	/usr/local/etc/rc.d/init.d/smartd
-
-Additional information about using configure can be found here:
-http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_mono/autoconf.html#SEC139
diff --git a/sm5/Makefile.am b/sm5/Makefile.am
deleted file mode 100644
index ffb43e784453fbe9559ab8ab62a08c6da869c680..0000000000000000000000000000000000000000
--- a/sm5/Makefile.am
+++ /dev/null
@@ -1,416 +0,0 @@
-## Process this file with automake to produce Makefile.in
-#
-# $Id: Makefile.am,v 1.60 2004/08/14 20:04:39 chrfranke Exp $
-#
-
-@SET_MAKE@
-
-AM_CPPFLAGS = -DSMARTMONTOOLS_SYSCONFDIR=\"$(sysconfdir)\"
-
-sbin_PROGRAMS = smartd 	\
-		smartctl
-
-smartd_SOURCES =  smartd.c       \
-                  smartd.h       \
-                  atacmdnames.c	\
-                  atacmdnames.h	\
-                  atacmds.c	\
-                  atacmds.h	\
-                  ataprint.c 	\
-                  ataprint.h	\
-                  extern.h      \
-                  int64.h       \
-                  knowndrives.c	\
-                  knowndrives.h	\
-                  scsicmds.c	\
-                  scsicmds.h	\
-                  scsiprint.c	\
-                  scsiprint.h	\
-                  utility.c 	\
-                  utility.h
-
-smartd_LDADD = @os_deps@ @os_libs@
-smartd_DEPENDENCIES = @os_deps@
-EXTRA_smartd_SOURCES = os_darwin.c \
-		       os_darwin.h \
-		       os_linux.c \
-                       os_linux.h \
-		       os_freebsd.c \
-		       os_freebsd.h \
-		       os_netbsd.c \
-		       os_netbsd.h \
-		       os_solaris.c \
-		       os_solaris.h \
-		       os_solaris_ata.s \
-		       os_win32.c \
-	               os_generic.c \
-	               os_generic.h
-
-
-if OS_WIN32_MINGW
-
-EXTRA_smartd_SOURCES += \
-                posix/regex.h \
-                posix/regex.c \
-                posix/regcomp.c \
-                posix/regexec.c \
-                posix/regex_internal.c \
-                posix/regex_internal.h \
-                os_win32/daemon_win32.h \
-                os_win32/daemon_win32.c \
-                os_win32/hostname_win32.h \
-                os_win32/hostname_win32.c \
-                os_win32/syslog.h \
-                os_win32/syslog_win32.c
-
-endif
-
-smartctl_SOURCES= smartctl.c    \
-                  smartctl.h    \
-                  atacmdnames.c	\
-                  atacmdnames.h	\
-                  atacmds.c	\
-                  atacmds.h	\
-                  ataprint.c	\
-                  ataprint.h	\
-                  extern.h      \
-                  int64.h       \
-                  knowndrives.c	\
-                  knowndrives.h	\
-                  scsicmds.c	\
-                  scsicmds.h	\
-                  scsiprint.c	\
-                  scsiprint.h	\
-                  utility.c	\
-                  utility.h
-
-smartctl_LDADD = @os_deps@ @os_libs@
-smartctl_DEPENDENCIES = @os_deps@
-EXTRA_smartctl_SOURCES = os_linux.c \
-                       os_linux.h   \
-		       os_freebsd.c \
-		       os_freebsd.h \
-		       os_netbsd.c \
-		       os_netbsd.h \
-		       os_solaris.c \
-		       os_solaris.h \
-		       os_win32.c \
-		       os_generic.c \
-		       os_generic.h
-
-if OS_WIN32_MINGW
-
-EXTRA_smartctl_SOURCES += \
-                posix/regex.h \
-                posix/regex.c \
-                posix/regcomp.c \
-                posix/regexec.c \
-                posix/regex_internal.c \
-                posix/regex_internal.h \
-                os_win32/syslog.h
-
-endif
-
-if OS_SOLARIS
-# This block is required because Solaris uses manual page section 1m
-# for administrative command (linux/freebsd use section 8) and Solaris
-# uses manual page section 4 for file formats (linux/freebsd use
-# section 5).  Automake can deal cleanly with man page sections 1-8
-# and n, but NOT with sections of the form 1m.
-extra_MANS =      smartd.conf.4 \
-                  smartctl.1m   \
-                  smartd.1m
-install-man: $(extra_MANS)
-	@$(NORMAL_INSTALL)
-	$(mkinstalldirs) $(DESTDIR)$(mandir)/man4
-	$(mkinstalldirs) $(DESTDIR)$(mandir)/man1m
-	for i in $(extra_MANS); do \
-	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
-	  else file=$$i; fi; \
-	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
-	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
-	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
-	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
-	  echo " $(INSTALL_DATA) $$file $(DESTDIR)$(mandir)/man$$ext/$$inst"; \
-	  $(INSTALL_DATA) $$file $(DESTDIR)$(mandir)/man$$ext/$$inst; \
-	done
-uninstall-man:
-	@$(NORMAL_UNINSTALL)
-	for i in $(extra_MANS); do \
-	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
-	  else file=$$i; fi; \
-	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
-	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
-	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
-	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
-	  echo " rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst"; \
-	  rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst; \
-	done
-%.1m: %.8
-	awk '/^.TH/ {$$3="1m"} {print}' < $< | \
-	sed -e 's/smartd\.conf\(.*\)(5)/smartd.conf\1(4)/g' \
-            -e 's/syslog\.conf\(.*\)(5)/syslog.conf\1(4)/g' \
-	    -e 's/smartctl\(.*\)(8)/smartctl\1(1m)/g' \
-	    -e 's/syslogd\(.*\)(8)/syslogd\1(1m)/g' \
-            -e 's|/var/log/messages|/var/adm/messages|g' \
-	    -e 's/smartd\(.*\)(8)/smartd\1(1m)/g' > $@
-%.4: %.5
-	awk '/^.TH/ {$$3="4"}  {print}' < $< | \
-	sed -e 's/smartd\.conf\(.*\)(5)/smartd.conf\1(4)/g' \
-            -e 's/syslog\.conf\(.*\)(5)/syslog.conf\1(4)/g' \
-	    -e 's/smartctl\(.*\)(8)/smartdctl\1(1m)/g' \
-	    -e 's/syslogd\(.*\)(8)/syslogd\1(1m)/g' \
-            -e 's|/var/log/messages|/var/adm/messages|g' \
-	    -e 's/smartd\(.*\)(8)/smartd\1(1m)/g' > $@
-else
-# For systems that adopts traditional manner
-man_MANS =        smartd.conf.5 \
-                  smartctl.8    \
-                  smartd.8
-endif
-
-docsdir=$(docdir)
-docs_DATA = AUTHORS   \
-            CHANGELOG \
-            COPYING   \
-            INSTALL   \
-            NEWS      \
-            README    \
-            TODO      \
-            WARNINGS  \
-            smartd.conf
-
-sysconf_DATA = smartd.conf$(smartd_suffix)
-
-if SMARTD_SUFFIX
-smartd.conf$(smartd_suffix): smartd.conf
-	cp smartd.conf smartd.conf$(smartd_suffix)
-endif
-
-EXTRA_DIST = \
-                smartmontools.spec	\
-                smartd.initd.in		\
-		smartd.8.in		\
-		smartctl.8.in		\
-		smartd.conf.5.in	\
-		smartd.conf		\
-		autogen.sh		\
-                $(docs_DATA)
-
-CLEANFILES = smartd.conf.5 \
-             smartd.conf.4 \
-             smartd.8      \
-             smartd.1m     \
-             smartd.8.html \
-             smartd.8.txt  \
-             smartctl.8    \
-             smartctl.1m   \
-             smartctl.8.html    \
-             smartctl.8.txt     \
-             smartd.conf.5.html \
-             smartd.conf.5.txt  \
-             smartd.initd  \
-             SMART
-
-
-
-smartd.conf.5.in: smartd.8.in
-	sed '1,/STARTINCLUDE/ D;/ENDINCLUDE/,$$D' < $(srcdir)/smartd.8.in > $(top_builddir)/tmp.directives
-	sed '/STARTINCLUDE/,$$D'  < $(srcdir)/smartd.conf.5.in > $(top_builddir)/tmp.head
-	sed '1,/ENDINCLUDE/D'   < $(srcdir)/smartd.conf.5.in > $(top_builddir)/tmp.tail
-	cat $(top_builddir)/tmp.head > $(srcdir)/smartd.conf.5.in
-	echo '.\" STARTINCLUDE' >> $(srcdir)/smartd.conf.5.in
-	cat $(top_builddir)/tmp.directives >> $(srcdir)/smartd.conf.5.in
-	echo '.\" ENDINCLUDE'   >> $(srcdir)/smartd.conf.5.in
-	cat $(top_builddir)/tmp.tail >> $(srcdir)/smartd.conf.5.in
-	rm -f $(top_builddir)/tmp.head $(top_builddir)/tmp.tail $(top_builddir)/tmp.directives
-
-if OS_DARWIN
-initd_DATA = SMART \
-	os_darwin/StartupParameters.plist \
-	os_darwin/English_Localizable.strings
-
-initd_install_name = SMART
-
-initd_DATA_install = install-initdDATA-darwin
-
-SMART : os_darwin/SMART.in
-	sed "s|/usr/sbin/|$(sbindir)/|" $< > $@
-
-install-initdDATA-darwin: $(initd_DATA)
-	$(mkinstalldirs) $(DESTDIR)$(initddir)
-	$(mkinstalldirs) $(DESTDIR)$(initddir)/SMART
-	$(mkinstalldirs) $(DESTDIR)$(initddir)/SMART/Resources
-	$(INSTALL_SCRIPT) $(top_builddir)/SMART $(DESTDIR)$(initddir)/SMART
-	$(INSTALL_DATA) $(srcdir)/os_darwin/StartupParameters.plist \
-	    $(DESTDIR)$(initddir)/SMART/StartupParameters.plist
-	for i in English ; do \
-	  RDIR=$(DESTDIR)$(initddir)/SMART/Resources/$${i}.lproj ; \
-	  $(mkinstalldirs) $$RDIR ;\
-	  $(INSTALL_DATA) $(srcdir)/os_darwin/$${i}_Localizable.strings \
-	    $$RDIR/Localizable.strings ; \
-	done
-	@echo -e "\n\n####################################################################\n#"
-	@echo -e "#                       PLEASE READ THIS BOX!\n#"
-	@echo -e "#   To manually start the smartd daemon, run:\n#   ${initddir}/SMART/SMART start\n#"
-	@echo -e "#   To automatically start smartd on bootup, add the line:\n#   SMARTd=-YES-\n#   to /etc/hostconfig\n#"
-	@echo -e "#   smartd can now use a configuration file ${sysconfdir}/smartd.conf. Do:\n#   man smartd"
-	@echo -e "#   to learn about it. A sample configuration file can be found in:\n#   ${docdir}\n#"
-	@echo -e "####################################################################\n\n"
-
-else
-
-initd_DATA = smartd.initd
-
-initd_install_name = smartd$(smartd_suffix)
-
-initd_DATA_install = install-initdDATA-generic
-
-install-initdDATA-generic: $(initd_DATA)
-	$(mkinstalldirs) $(DESTDIR)$(initddir)
-	$(INSTALL_SCRIPT) $(top_builddir)/smartd.initd $(DESTDIR)$(initddir)/smartd$(smartd_suffix)
-	@echo -e "\n\n####################################################################\n#"
-	@echo -e "#                       PLEASE READ THIS BOX!\n#"
-	@echo -e "#   To manually start the smartd daemon, run:\n#   ${initddir}/smartd start\n#"
-	@echo -e "#   To automatically start smartd on bootup, run:\n#   /sbin/chkconfig --add smartd\n#"
-	@echo -e "#   smartd can now use a configuration file ${sysconfdir}/smartd.conf. Do:\n#   man smartd"
-	@echo -e "#   to learn about it. A sample configuration file can be found in:\n#   ${docdir}\n#"
-	@echo -e "####################################################################\n\n"
-
-endif
-
-install-initdDATA : $(initd_DATA_install)
-
-uninstall-initdDATA:
-	rm -rf $(DESTDIR)$(initddir)/$(initd_install_name)
-
-uninstall-docsDATA:
-	rm -rf $(DESTDIR)$(docsdir)
-
-smart%: $(srcdir)/smart%.in Makefile
-	sed "s|CURRENT_CVS_VERSION|$(releaseversion)|g" $< | \
-	sed "s|CURRENT_CVS_DATE|$(smartmontools_release_date)|g" | \
-	sed "s|CURRENT_CVS_TIME|$(smartmontools_release_time)|g" | \
-	sed "s|/usr/share/man/|$(mandir)/|g" | \
-	sed "s|/usr/sbin/|$(sbindir)/|g" | \
-	sed "s|/etc/rc\\.d/init.d/|$(initddir)/|g" | \
-	sed "s|/usr/share/doc/smartmontools-5\\.1/|$(docsdir)/|g" | \
-	sed "s|/etc/smartd\\.conf|$(sysconfdir)/smartd\\.conf|g" > $@
-
-
-# Commands to convert man pages into .html and .txt
-# TODO: configure
-MAN2HTML = man2html
-#MAN2HTML = groff -man -Thtml
-MAN2TXT = groff -man -Tascii -P'-bcou'
-
-# Remove useless links from man2html output
-FIXHTML = sed 's,http://localhost/[-a-z/]*/man2html?\([1-8]\)+\([a-z.]*\),\2.\1.html,g' \
-        | sed 's,http://localhost/[-a-z/]*/man2html",.",' \
-        | sed 's,<A HREF="[bisfp][adyo][desrp][-a-zP1-8.]*">\([-a-zP.]*\)</A>,\1,g'
-
-# Convert man pages into .html and .txt
-
-htmlman: smartctl.8.html smartd.8.html smartd.conf.5.html
-
-txtman:  smartctl.8.txt smartd.8.txt smartd.conf.5.txt
-
-%.5.html: %.5
-	$(MAN2HTML) $< | $(FIXHTML) > $@
-
-%.8.html: %.8
-	$(MAN2HTML) $< | $(FIXHTML) > $@
-
-%.5.txt: %.5
-	$(MAN2TXT) $< > $@
-
-%.8.txt: %.8
-	$(MAN2TXT) $< > $@
-
-
-
-if OS_WIN32_MINGW
-# Definitions for Windows distribution
-
-distdir_win32 = $(PACKAGE)-$(VERSION).win32
-distzip_win32 = $(PACKAGE)-$(VERSION).win32.zip
-
-exedir_win32 = $(distdir_win32)/bin
-docdir_win32 = $(distdir_win32)/doc
-
-FILES_WIN32 = $(exedir_win32)/smartctl.exe \
-              $(exedir_win32)/smartd.exe \
-              $(docdir_win32)/AUTHORS.txt \
-              $(docdir_win32)/CHANGELOG.txt \
-              $(docdir_win32)/COPYING.txt \
-              $(docdir_win32)/INSTALL.txt \
-              $(docdir_win32)/NEWS.txt \
-              $(docdir_win32)/README.txt \
-              $(docdir_win32)/TODO.txt \
-              $(docdir_win32)/WARNINGS.txt \
-              $(docdir_win32)/smartd.conf \
-              $(docdir_win32)/smartctl.8.html \
-              $(docdir_win32)/smartctl.8.txt \
-              $(docdir_win32)/smartd.8.html \
-              $(docdir_win32)/smartd.8.txt \
-              $(docdir_win32)/smartd.conf.5.html \
-              $(docdir_win32)/smartd.conf.5.txt
-
-CLEANFILES += $(FILES_WIN32) $(exedir_win32)/syslogevt.exe distdir.mkdir syslogevt.check
-
-# Textfile converter from cygutils
-UNIX2DOS = unix2dos -D
-
-# Build Windows distribution
-
-dist-win32: $(distzip_win32)
-
-distdir-win32: distdir.mkdir $(FILES_WIN32) syslogevt.check
-
-$(distzip_win32): distdir.mkdir $(FILES_WIN32) syslogevt.check
-	@rm -fv $(distzip_win32)
-	cd $(distdir_win32) && zip -9Dr ../$(distzip_win32) .
-
-cleandist-win32:
-	rm -rf $(distdir_win32) distdir.mkdir syslogevt.check
-
-distdir.mkdir:
-	@test -d $(exedir_win32) || mkdir -pv $(exedir_win32)
-	@test -d $(docdir_win32) || mkdir -pv $(docdir_win32)
-	touch $@
-
-syslogevt.check:
-	@if [ -f $(srcdir)/os_win32/syslogevt.exe ]; then \
-	  cp -pv $(srcdir)/os_win32/syslogevt.exe $(exedir_win32)/syslogevt.exe; \
-	 else echo "Warning: $(srcdir)/os_win32/syslogevt.exe missing."; fi
-	touch $@
-
-$(exedir_win32)/%.exe: %.exe
-	cp -p $< $@
-	strip -p -s $@
-
-$(docdir_win32)/%.txt: $(srcdir)/%
-	$(UNIX2DOS) < $< > $@
-	touch -r $< $@
-
-$(docdir_win32)/%.conf: $(srcdir)/%.conf
-	$(UNIX2DOS) < $< > $@
-	touch -r $< $@
-
-$(docdir_win32)/%: %
-	$(UNIX2DOS) < $< > $@
-	touch -r $< $@
-
-
-# Build config_vc6.h for MSVC 6 from MinGW config.h
-
-config-vc6: $(srcdir)/os_win32/config_vc6.h
-
-$(srcdir)/os_win32/config_vc6.h: config.h
-	sed '1i/* config_vc6.h.  Generated by Makefile.  */' $< | \
-	sed 's,^#define HAVE_\(INTTYPES_H\|STDINT_H\|STRTOULL\|UNISTD_H\) 1$$,/* #undef HAVE_\1 */,' | \
-	sed 's,i.86-pc-mingw32,i686-pc-win32vc6,' > $@
-
-endif
-
-SUBDIRS= . examplescripts
diff --git a/sm5/NEWS b/sm5/NEWS
deleted file mode 100644
index ce48b03d0c6bca15f5700d62d04e35268226016b..0000000000000000000000000000000000000000
--- a/sm5/NEWS
+++ /dev/null
@@ -1,170 +0,0 @@
-smartmontools NEWS
-------------------
-CVS ID: $Id: NEWS,v 1.23 2004/07/07 14:45:19 ballen4705 Exp $
-
-The most up-to-date version of this file is:
-http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/NEWS?sortby=date&view=markup
-
-Date 2004-7-5
-Summary: smartmontools release 5.32 (STABLE)
------------------------------------------------------------
-This is an stable release of smartmontools.
-Note added 2004/7/7: users building a Solaris/Intel version of the code should 
-modify the 'configure' file, changing "pc-*-solaris*" on line 106
-to read "*-pc-solaris*".  Reference:
-http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/configure.in?r1=1.83&r2=1.84
-
-
-Date: 2004-5-4
-Summary: smartmontools release 5.31 (UNSTABLE/EXPERIMENTAL)
------------------------------------------------------------
-This is an unstable/experimental release of smartmontools.  It includes
-several new features:
-- Windows smartd daemon
-- smartd now monitors current and pending sector counts
-- Support for ATA-7 selective self-test features (Linux/NetBSD only)
-  Please report sucess/failure with this option to the smartmontools-support
-  mailing list.
-
-Date: 2004-3-6
-Summary: smartmontools release 5.30 (STABLE)
---------------------------------------------
-This is a stable release of smartmontools: the first stable release
-since 5.26.
-- KNOWN BUG (identified/fixed by CF): smartd will segv and crash if
-  the configuration file /etc/smartd.conf contains NO valid entries.
-  This bug was introduced in version 1.259 of smartd.c by BA and
-  is present in smartmontools releases 5.27-5.30 inclusive. This can
-  be fixed by editing line 3389 of smartd.c, and changing:
-  "else if (cfgentries[0]) {"
-  to read:
-  "else if (cfgentries && cfgentries[0]) {"
-
-
-Date: 2004-2-24
-Summary: smartmontools release 5.29 (Experimental, not STABLE)
---------------------------------------------------------------
-This is another experimental release, to replace the 5.27 release that
-had a damaged configure script.  The next stable release will be 5.30
-- This release has SCSI support for NetBSD
-
-
-Date: 2004-2-12 
-Summary: smartmontools release 5.27 (Experimental, not STABLE)
---------------------------------------------------------------
-- WARNING: this release has a broken --prefix=/a/path option to the
-  configure script.  The consequence is that smartd will not look for the
-  configuration file (smartd.conf) at the desired location.
-- NetBSD support added
-- A new Directive (-s) for smartd.conf now enables flexible automatic
-  scheduled self-testing for both ATA and SCSI devices.
-- Solaris now has ATA device support (SPARC only)
-- A new Directive (-n) for smartd.conf to avoid spinning up disks
-- Errors when smartd sends mail are now logged to SYSLOG
-- Solaris smartd mail now works correctly (uses mailx not mail)
-
-
-Date: 2003-11-29
-Summary: smartmontools release 5.26
------------------------------------
-This is a stable smartmontools release.  The only known problem is
-that under Solaris, the email features of smartd do not work 'out of
-the box'.  Three workarounds are:
-  [1] use '-M exec mailx' in /etc/smartd.conf
-  [2] in the start script for smartd, put /usr/ucb into PATH before
-      /bin
-  [3] upgrade to release 5.27 or later, or the latest CVS snapshot
-
-
-Date: 2003-11-19
-Summary: smartmontools release 5.25
------------------------------------
-This release should not hang when accessing USB devices. It provides
-smartd SCSI self-test log monitoring for self-test errors, and a
-larger table of known ATA drives.  DEVICESCAN should work correctly
-even on file systems containing XFS or JFS partitions, and on machines
-that use devfs, even without traditional links.
-
-From this time on, even numbered releases will be 'stable' ones and
-odd numbered releases (like 5.25) will be unstable/testing/development
-releases.
-
-
-Date: 2003-10-30
-Summary: smartmontools release 5.23
------------------------------------
-This release has one known problem: DEVICESCAN device scanning does
-not work correctly if the disk with the /dev directory also has XFS
-or JFS file systems on it.
-
-
-Date: 2003-10-28
-Summary: smartmontools release 5.22
------------------------------------
-Replaces flawed 5.21 release: the -T verypermissive option had to be
-entered as -T verpermissive. First experimental solaris support (SCSI
-only).  This release had a serious flaw: smartd left open file descriptors
-for devices that it couldn't monitor.
-
-
-Date: 2003-10-14
-Summary: smartmontools release 5.21
------------------------------------
-Preliminary support for FreeBSD added to smartmontools.  For FreeBSD,
-ATA support requires a 5.1-CURRENT kernel while SCSI support should
-work across multiple versions (any that support CAM).
-
-
-Date: 2003-10-04
-Summary: smartmontools release 5.20
------------------------------------
-Replaces flawed 5.19 release (which had a zero-length man page
-smartd.conf.5).
-
-
-Date: 2003-10-03
-Summary: smartmontools release 5.19
------------------------------------
-This is the first release of smartmontools based on autoconf/automake.
-For this reason, it is a very experimental release.  Please let us
-know in particular about documenation errors/omissions, missing or
-unneccesary files, and similar oversights.  The major changes are:
- [1]  installation scripts based on autoconfig/automake
- [2] ./configure [options] lets you set arbitrary paths
- [3] supports FHS with ./configure --prefix=/usr/local
- [4] correct paths are inserted into all man pages, binaries, etc.
- [5] tarballs and RPMs are now GPG-signed
-
-
-Date: 2003-10-02 11:35
-Summary: smartd SEGV
---------------------
-Some versions of smartd, including smartmontools release 5.1-18, will
-SEGV if the combination of Directives in /etc/smartd.conf contains
--l error
-AND/OR
--l selftest
-without any Attribute monitoring Directives.  This is fixed in 5.19
-and above.
-
-A good workaround is to add:
--o on
-OR
--o off
-to enable or disable automatic offline data collection.
-
-
-Date: 2002-11-17 07:41
-Summary: testunitready bug in smartd
-------------------------------------
-A bug in smartd prevented functioning on scsi devices.
-The bug in question only affects smartd users with scsi devices.
-To see if your version of smartd has the testunitready() bug, do
-smartd -V
-If the version of the module smartd.c in a line like:
-Module: smartd.c revision: 1.66 date: 2002/11/17
-has a revision greater than or equal to 1.30, and less than or
-equal to 1.64, then your version of the code has this problem.
-
-This problem affected releases starting with RELEASE_5_0_16 up to and
-including RELEASE_5_0_43.
diff --git a/sm5/README b/sm5/README
deleted file mode 100644
index 5ecca0b6acbdab96147b8640c002f663f61f6530..0000000000000000000000000000000000000000
--- a/sm5/README
+++ /dev/null
@@ -1,105 +0,0 @@
-====================================================
-smartmontools - S.M.A.R.T. utility toolset for Linux
-====================================================
-
-$Id: README,v 1.50 2004/05/03 15:58:33 ballen4705 Exp $
-
-== HOME ==
-The home for smartmontools is located at:
-    
-    http://smartmontools.sourceforge.net/
-
-Please see this web site for updates, documentation, and for submitting
-patches and bug reports.
-
-You will find a mailing list for support and other questions at:
-
-    http://lists.sourceforge.net/lists/listinfo/smartmontools-support
-
-
-== COPYING ==
-Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
-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, write to the Free Software Foundation, Inc., 675
-Mass Ave, Cambridge, MA 02139, USA.
-
-
-== CREDITS ==
-This code was originally developed as a Senior Thesis by Michael Cornwell
-at the Concurrent Systems Laboratory (now part of the Storage Systems
-Research Center), Jack Baskin School of Engineering, University of
-California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-
-
-== OVERVIEW ==
-smartmontools contains utilities that control and monitor storage
-devices using the Self-Monitoring, Analysis and Reporting Technology
-(S.M.A.R.T.) system build into ATA and SCSI Hard Drives. This is used
-to check the reliability of the hard drive and to predict drive
-failures.  smartmontools Version 5.x is designed to comply to the
-ATA/ATAPI-5 specification (Revision 1).  Future releases of
-smartmontools (Versions 6.x and 7.x) will comply with the ATA/ATAPI-6
-and ATA/ATAPI-7 specifications.
-
-This package is meant to be an up-to-date replacement for the
-ucsc-smartsuite and smartsuite packages, and is derived from that
-code.
-
-
-== CONTENTS ==
-The suite contains two utilities:
-
-smartctl is a command line utility designed to perform S.M.A.R.T. tasks
-	 such as disk self-checks, and to report the S.M.A.R.T. status of
-	 the disk.
-
-smartd   is a daemon that periodically monitors S.M.A.R.T. status and
-         reports errors and changes in S.M.A.R.T. attributes to syslog.
-
-
-== OBTAINING SMARTMONTOOLS ==
-
-Source tarballs
----------------
-
-http://sourceforge.net/project/showfiles.php?group_id=64297
-
-CVS
----
-
-cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools login (when prompted for a password, just press Enter)
-cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co sm5
-
-This will create a subdirectory called sm5/ containing the code.
-
-To instead get the 5.1-16 release:
-
-cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co -r RELEASE_5_1_16 sm5
-
-To update your sources to the 5.1-18 release:
-
-cd sm5
-cvs up -r RELEASE_5_1_18
-
-To update any tagged release to the latest development code:
-
-cd sm5
-cvs up -A
-
-You can see what the different tags are by looking at
-http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/smartmontools/sm5/ .
-You'll see the tag names in the little scroll window where it says "Show
-only files with tag".
-
-== BUILDING/INSTALLING SMARTMONTOOLS ==
-
-Refer to the "INSTALL" file for installation instructions.
-
-See the "WARNINGS" file for reports of hardware where these utilities
-might cause serious problems such as lockups.
diff --git a/sm5/TODO b/sm5/TODO
deleted file mode 100644
index 13856c06ae0885580830feb8cc3621bfb4290d5d..0000000000000000000000000000000000000000
--- a/sm5/TODO
+++ /dev/null
@@ -1,108 +0,0 @@
-TODO list for smartmontools:
-
-$Id: TODO,v 1.54 2004/08/06 13:11:35 chrfranke Exp $
-
-SATA devices
-------------
-Currently work OK if you use the standard IDE drivers in
-drivers/ide. If you use the new libata drivers, it won't work
-correctly because libata doesn't yet support the needed
-ATA-passthrough ioctl() calls. Jeff Garzik, the libata developer, says
-that this support will be added in the future. When this happens, add
-support to smartmontools for a new SATA/libata device type '-d sata'.
-
-USB devices
------------
-Some USB devices can hang smartctl or smartd.  This is because these
-devices fail to comply with SCSI specifications for their packet
-command sets.  Work on improving the detection and bail-out procedures
-for these flawed devices, so that the user sees an informative error
-message and smartd/smartctl don't hang.
-
-ATA-4 (no kidding!)
--------------------
-smartctl: add another -t TESTTYPE option to accomodate old-style ATA-4
-IBM disks (ATA-4 has no self-test commands). See IBM S25L-2426-02 OEM
-HARD DISK DRIVE SPECIFICATIONS for DBCA-203240/204860/206480 2.5-Inch
-Hard Disk Drive with ATA Interface Revision (1.0)
-http://www.hgst.com/tech/techlib.nsf/techdocs/85256AB8006A31E587256A7D00642A1D/$file/dbca_sp.pdf
-section 12.30.1.5 for details.  These disks offer no self-test option,
-and the -t offline command only tests a small part of the disk (a
-'segment').  We need a -t multioffline that:
- (1) issues auto offline immediate command (tests ONE segment)
- (2) waits until estimated completion time
- (3) tests if off-line data collection status is set to 0x02 (all
-     segments completed)
- (4) if not, return to (1)
-
-ATA-6/7
--------
-Support extended error logs
-Support extended self-test logs
-
-smartctl/smartd
----------------
-Add additional -v options (corresponding to comments in
-atacmds.c:ataPrintSmartAttribName().
-
-Add interface to Megaraid ATA RAID controllers (Erik)
-
-smartctl: 
----------
-Add command line option to issue SMART SAVE ATTRIBUTE VALUES command
-Feature Register value ATA_SMART_SAVE 0xd3
-
-Perhaps modify the -q option (quiet mode) so that it only warns of ATA
-errors if they have (say) taken place in the last 168 hours (week).
-
-Parse and print additional Attribute flag meanings (IBM ones, eg
-performance etc).  These are now documented in atacmds.h -- we just
-need to modify the format of the Attribute table.
-
-Modify the SMART self-test log table printing so that we ALSO print
-the value of the self-test failure checkpoint byte, if it's one of the
-recognized values.  See routine SelfTestFailureCodeName and
-documentation in atacmds.h.
-
-smartd:
--------
-Perhaps change <nomailer> special argument to -m to have also
-<nomailer_fork> which would actually work with -M exec to run the
-executable/script in the background rather than in the foreground.
-But let's wait for someone to request this. At that point we should
-probably use fork/exec rather than system().
-
-Perhaps change smartd to look in /proc/ide and /proc/scsi to see what
-exists? If something doesn't exit then don't try to open it?  This
-should probably be the default option if there is no configuration
-file.
-
-Add ability to monitor "worst" value from attributes (sometimes it
-gets larger!) and to monitor the threshold value (sometimes it
-changes!).
-
-Add command line option that scans devices then WRITES
-/etc/smartd.conf, perhaps as /etc/smartd.conf.output, just for devices
-that can be monitored.
-
-FreeBSD
--------
-Get interface for 3ware Escalade controllers working (Eduard).
-Modify smartctl -h examples
-
-Cygwin and Windows
-------------------
-Add IDE/ATA selective self test and check power mode.
-
-Access SCSI devices via IOCTL_SCSI_PASS_THROUGH on 2000/XP
-to support systems with missing ASPI driver.
-
-Windows
--------
-Provide some installer.
-
-Packaging
----------
-Under freebsd and solaris, the following are wrong:
-smartd.conf: has linux device paths
-smart*.in  : man pages have (mostly) linux device paths
diff --git a/sm5/WARNINGS b/sm5/WARNINGS
deleted file mode 100644
index d4dbb4c889779df8618571653a767a4ffc9888ed..0000000000000000000000000000000000000000
--- a/sm5/WARNINGS
+++ /dev/null
@@ -1,123 +0,0 @@
-$Id: WARNINGS,v 1.30 2004/07/17 23:19:00 geoffk1 Exp $
-
-The most recent version of this file can be found here:
-http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/WARNINGS?view=markup
-
-The following are reports of serious problems (eg system lockup) which
-were due to smartmontools.  There are DARWIN, LINUX, FREEBSD, SOLARIS
-and WINDOWS sections below.
-
-
-LINUX
------
-
-You may also wish to search the linux-kernel mailing list for problem
-reports concerning smartmontools.  Here is the URL:
-http://groups.google.com/groups?as_q=smartmontools&safe=images&ie=UTF-8&oe=UTF-8&as_ugroup=linux.kernel&lr=&num=100&hl=en
-
-SYSTEM:   Any system with USB ports and USB storage devices
-PROBLEM:  Using smartd/smartctl on USB "SCSI" storage devices can cause kernel hang
-REPORTER: see link below
-LINK:     https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=107615
-NOTE:     USB storage devices are handled as SCSI devices by the kernel. But many of these
-          devices do not comply with SCSI specs, and can cause the kernel to hang.
-          Avoid using smartd/smartctl on these devices (they don't do SMART anyway).
-          In particular, the use of smartd DEVICESCAN in /etc/smartd.conf can cause
-          these devices (typically represented by /dev/sda or /dev/sdb) to hang, and
-          the kernel to lock up.
-FIXED:    This problem should be fixed in smartmontools-5.25 and greater.
-
-
-SYSTEM:   Intel 875WP1-E motherboard with SATA drives on motherboard's SATA ports
-PROBLEM:  smartd makes NTP time drift
-REPORTER: nohez@cmie.com
-LINK:     http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=Pine.LNX.4.33.0310111545530.1047-100000%40venus.cmie.ernet.in.lucky.linux.kernel
-NOTE:     When using SATA disks, linux kernel k_smp-2.4.21-108 (SMP because
-          of hyper-threading) and xntp-4.1.1-177, the server time went
-          out of sync with system time.  Problem goes away when SATA
-          disks removed.
-
-
-SYSTEM:   Dell servers using AACRAID (SCSI)
-PROBLEM:  Locked up, needed to be rebooted
-REPORTER: drew@eastvan.bc.ca
-LINK:     http://sourceforge.net/mailarchive/forum.php?thread_id=1311313&forum_id=12495
-
-
-SYSTEM:   Box with Promise 20265 IDE-controller (pdc202xx-driver) and > 2.4.18 kernel with ide-taskfile support
-PROBLEM:  Smartctl locks system solid when used on /dev/hd[ef].
-REPORTER: Georg Acher <acher@in.tum.de>
-LINK:     http://sourceforge.net/mailarchive/forum.php?thread_id=1457979&forum_id=12495
-NOTE:     Lockup doesn't happen with 2.4.18 kernel, and doesn't affect /dev/hd[a-d]
-          This appears to be a problem with the pdc202xx-driver and has been reported
-          to the pdcx maintainers.  If you enable the Promise-BIOS (ATA100-BIOS) then
-          everything will work fine.  But if you disable it, then the machine will hang.
-
-
-SYSTEM:   Box with Promise 20262 IDE-controller
-PROBLEM:  Smartctl locks system solid
-REPORTER: Ben Low <ben@bdlow.net>
-LINK:     http://sourceforge.net/mailarchive/message.php?msg_id=5074201
-NOTE:     Similar to previous report: Promise Ultra66 2-port card (20262) which, with
-          linux 2.4.20, suffers from the lockups reported above.  But it was
-          impossible to enable the Promiste BIOS.  A kernel patch is referenced
-          to fix the problem.
-
-
-SYSTEM:   Promise 20265 IDE-controller
-PROBLEM:  Smartctl locks system solid when used on CDROM/DVD device
-REPORTER: see link below
-LINK:     http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=208964
-NOTE:     Problem seems to affect kernel 2.4.21 only.
-
-
-SYSTEM:   Promise IDE-controllers and perhaps others also
-PROBLEM:  System freezes under heavy load, perhaps when running SMART commands
-REPORTER: Mario 'BitKoenig' Holbe Mario.Holbe@RZ.TU-Ilmenau.DE
-LINK:     http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=1wUXW-2FA-9%40gated-at.bofh.it
-NOTE:     Before freezing, SYSLOG shows the following message(s)
-          kernel: hdf: dma timer expiry: dma status == 0xXX
-       	  where XX is two hexidecimal digits. This may be a kernel bug
-          or an underlying hardware problem.  It's not clear if
-          smartmontools plays a role in provoking this problem.  FINAL
-          NOTE: Problem was COMPLETELY resolved by replacing the power
-          supply.  See URL above, entry on May 29, 2004 by Holbe.  Other
-          things to try are exchanging cables, and cleaning PCI slots.
-
-FREEBSD
--------
-
-[No problem reports yet.]
-
-
-SOLARIS
--------
-
-[No problem reports yet.]
-
-
-CYGWIN and WINDOWS
-------------------
-
-SYSTEM:   Any Windows 2000 or XP system.
-PROBLEM:  Use of an undocumented system call for IDE/ATA read log
-          (smartctl -l, --log, -a, --all) may affect system stability.
-REPORTER: Christian Franke <smartmontools-support@lists.sourceforge.net>
-NOTE:     The IOCTL call SMART_RCV_DRIVE_DATA does not support 
-          ATA_SMART_READ_LOG_SECTOR on NT4/2000/XP. The Win32 
-          implementation of smartctl/smartd uses the undocumented
-          and possibly buggy IOCTL_IDE_PASS_THROUGH for this purpose.
-          This IOCTL is not implemented under NT4.
-          Invalid log output has been reported for at least one
-          W2K system.
-
-DARWIN
-------
-
-SYSTEM:   Any system up to at least 7H63
-PROBLEM:  Can't switch off SMART, can't switch off auto-save, can't run
-	  short tests.
-REPORTER: Geoff Keating <geoffk@geoffk.org>
-NOTE:	  There's a bug in the system library: when you ask it to
-	  do any of these things, it does the inverse (switches on,
- 	  runs extended tests).  Radar 3727283.
diff --git a/sm5/atacmdnames.c b/sm5/atacmdnames.c
deleted file mode 100644
index 05d6f408dbdce3883d7be78d7f69bdf270eb5670..0000000000000000000000000000000000000000
--- a/sm5/atacmdnames.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * atacmdnames.c
- *
- * This module is based on the T13/1532D Volume 1 Revision 3 (ATA/ATAPI-7)
- * specification, which is available from http://www.t13.org/#FTP_site
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003-4 Philip Williams
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "atacmdnames.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-#define COMMAND_TABLE_SIZE 256
-
-const char *atacmdnames_c_cvsid="$Id: atacmdnames.c,v 1.11 2004/01/02 16:05:24 ballen4705 Exp $" ATACMDNAMES_H_CVSID;
-
-const char cmd_reserved[]        = "[RESERVED]";
-const char cmd_vendor_specific[] = "[VENDOR SPECIFIC]";
-const char cmd_reserved_sa[]     = "[RESERVED FOR SERIAL ATA]";
-const char cmd_reserved_cf[]     = "[RESERVED FOR COMPACTFLASH ASSOCIATION]";
-const char cmd_reserved_mcpt[]   = "[RESERVED FOR MEDIA CARD PASS THROUGH]";
-const char cmd_recalibrate_ret4[]= "RECALIBRATE [RET-4]";
-const char cmd_seek_ret4[]       = "SEEK [RET-4]";
-
-const char *command_table[COMMAND_TABLE_SIZE] = {
-/*-------------------------------------------------- 00h-0Fh -----*/
-  "NOP",
-  cmd_reserved,
-  cmd_reserved,
-  "CFA REQUEST EXTENDED ERROR CODE",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "DEVICE RESET",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 10h-1Fh -----*/
-  "RECALIBRATE [OBS-4]",
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-/*-------------------------------------------------- 20h-2Fh -----*/
-  "READ SECTOR(S)",
-  "READ SECTOR(S) [OBS-5]",
-  "READ LONG (w/ retry) [OBS-4]",
-  "READ LONG (w/o retry) [OBS-4]",
-  "READ SECTOR(S) EXT",
-  "READ DMA EXT",
-  "READ DMA QUEUED EXT",
-  "READ NATIVE MAX ADDRESS EXT",
-  cmd_reserved,
-  "READ MULTIPLE EXT",
-  "READ STREAM DMA",
-  "READ STREAM PIO",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "READ LOG EXT",
-/*-------------------------------------------------- 30h-3Fh -----*/
-  "WRITE SECTOR(S)",
-  "WRITE SECTOR(S) [OBS-5]",
-  "WRITE LONG(w/ retry) [OBS-4]",
-  "WRITE LONG(w/o retry) [OBS-4]",
-  "WRITE SECTORS(S) EXT",
-  "WRITE DMA EXT",
-  "WRITE DMA QUEUED EXT",
-  "SET MAX ADDRESS EXT",
-  "CFA WRITE SECTORS WITHOUT ERASE",
-  "WRITE MULTIPLE EXT",
-  "WRITE STREAM DMA",
-  "WRITE STREAM PIO",
-  "WRITE VERIFY [OBS-4]",
-  "WRITE DMA FUA EXT",
-  "WRITE DMA QUEUED FUA EXT",
-  "WRITE LOG EXT",
-/*-------------------------------------------------- 40h-4Fh -----*/
-  "READ VERIFY SECTOR(S)",
-  "READ VERIFY SECTOR(S) [OBS-5]",
-  "READ VERIFY SECTOR(S) EXT",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 50h-5Fh -----*/
-  "FORMAT TRACK [OBS-4]",
-  "CONFIGURE STREAM",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 60h-6Fh -----*/
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 70h-7Fh -----*/
-  "SEEK [OBS-7]",
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-/*-------------------------------------------------- 80h-8Fh -----*/
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  "CFA TRANSLATE SECTOR [VS IF NO CFA]",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-/*-------------------------------------------------- 90h-9Fh -----*/
-  "EXECUTE DEVICE DIAGNOSTIC",
-  "INITIALIZE DEVICE PARAMETERS [OBS-6]",
-  "DOWNLOAD MICROCODE",
-  cmd_reserved,
-  "STANDBY IMMEDIATE [RET-4]",
-  "IDLE IMMEDIATE [RET-4]",
-  "STANDBY [RET-4]",
-  "IDLE [RET-4]",
-  "CHECK POWER MODE [RET-4]",
-  "SLEEP [RET-4]",
-  cmd_vendor_specific,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- A0h-AFh -----*/
-  "PACKET",
-  "IDENTIFY PACKET DEVICE",
-  "SERVICE",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- B0h-BFh -----*/
-  "SMART",
-  "DEVICE CONFIGURATION",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-/*-------------------------------------------------- C0h-CFh -----*/
-  "CFA ERASE SECTORS [VS IF NO CFA]",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  "READ MULTIPLE",
-  "WRITE MULTIPLE",
-  "SET MULTIPLE MODE",
-  "READ DMA QUEUED",
-  "READ DMA",
-  "READ DMA [OBS-5]",
-  "WRITE DMA",
-  "WRITE DMA [OBS-5]",
-  "WRITE DMA QUEUED",
-  "CFA WRITE MULTIPLE WITHOUT ERASE",
-  "WRITE MULTIPLE FUA EXT",
-  cmd_reserved,
-/*-------------------------------------------------- D0h-DFh -----*/
-  cmd_reserved,
-  "CHECK MEDIA CARD TYPE",
-  cmd_reserved_mcpt,
-  cmd_reserved_mcpt,
-  cmd_reserved_mcpt,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "GET MEDIA STATUS",
-  "ACKNOWLEDGE MEDIA CHANGE [RET-4]",
-  "BOOT POST-BOOT [RET-4]",
-  "BOOT PRE-BOOT [RET-4]",
-  "MEDIA LOCK",
-  "MEDIA UNLOCK",
-/*-------------------------------------------------- E0h-EFh -----*/
-  "STANDBY IMMEDIATE",
-  "IDLE IMMEDIATE",
-  "STANDBY",
-  "IDLE",
-  "READ BUFFER",
-  "CHECK POWER MODE",
-  "SLEEP",
-  "FLUSH CACHE",
-  "WRITE BUFFER",
-  "WRITE SAME [RET-4]",  /* Warning!  This command is retired but the value of
-                            f_reg is used in look_up_ata_command().  If this
-                            command code is reclaimed in a future standard then
-                            be sure to update look_up_ata_command(). */
-  "FLUSH CACHE EXIT",
-  cmd_reserved,
-  "IDENTIFY DEVICE",
-  "MEDIA EJECT",
-  "IDENTIFY DEVICE DMA [OBS-4]",
-  "SET FEATURES",
-/*-------------------------------------------------- F0h-FFh -----*/
-  cmd_vendor_specific,
-  "SECURITY SET PASSWORD",
-  "SECURITY UNLOCK",
-  "SECURITY ERASE PREPARE",
-  "SECURITY ERASE UNIT",
-  "SECURITY FREEZE LOCK",
-  "SECURITY DISABLE PASSWORD",
-  cmd_vendor_specific,
-  "READ NATIVE MAX ADDRESS",
-  "SET MAX",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific
-};
-
-/* Returns the name of the command (and possibly sub-command) with the given
-   command code and feature register values.   For most command codes this
-   simply returns the corresponding entry in the command_table array, but for
-   others the value of the feature register specifies a subcommand or
-   distinguishes commands. */
-const char *look_up_ata_command(unsigned char c_code, unsigned char f_reg) {
-
-  // check that command table not messed up.  The compiler will issue
-  // warnings if there are too many array elements, but won't issue
-  // warnings if there are not enough of them.
-  if (sizeof(command_table) != sizeof(char *)*COMMAND_TABLE_SIZE){
-    fprintf(stderr, 
-            "Problem in atacmdnames.c.  Command Table command_table[] does\n"
-            "not have %d entries!  It has %d entries. Please fix it.\n",
-            COMMAND_TABLE_SIZE, (int)(sizeof(command_table)/sizeof(char *)));
-    abort();
-  }
-
-  switch (c_code) {
-  case 0x00:  /* NOP */
-    switch (f_reg) {
-    case 0x00:
-      return "NOP [Abort queued commands]";
-    case 0x01:
-      return "NOP [Don't abort queued commands]";
-    default:
-      return "NOP [Reserved subcommand]";
-    }
-  case 0x92:  /* DOWNLOAD MICROCODE */
-    switch (f_reg) {
-    case 0x01:
-      return "DOWNLOAD MICROCODE [Temporary]";
-    case 0x07:
-      return "DOWNLOAD MICROCODE [Save]";
-    default:
-      return "DOWNLOAD MICROCODE [Reserved subcommand]";
-    }
-  case 0xB0:  /* SMART */
-    switch (f_reg) {
-    case 0xD0:
-      return "SMART READ DATA";
-    case 0xD1:
-      return "SMART READ ATTRIBUTE THRESHOLDS [OBS-4]";
-    case 0xD2:
-      return "SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE";
-    case 0xD3:
-      return "SMART SAVE ATTRIBUTE VALUES [OBS-6]";
-    case 0xD4:
-      return "SMART EXECUTE OFF-LINE IMMEDIATE";
-    case 0xD5:
-      return "SMART READ LOG";
-    case 0xD6:
-      return "SMART WRITE LOG";
-    case 0xD7:
-      return "SMART WRITE ATTRIBUTE THRESHOLDS [NS, OBS-4]";
-    case 0xD8:
-      return "SMART ENABLE OPERATIONS";
-    case 0xD9:
-      return "SMART DISABLE OPERATIONS";
-    case 0xDA:
-      return "SMART RETURN STATUS";
-    case 0xDB:
-      return "SMART EN/DISABLE AUTO OFFLINE [NS (SFF-8035i)]";
-    default:
-        if (f_reg >= 0xE0)
-          return "[Vendor specific SMART command]";
-        else
-          return "[Reserved SMART command]";
-    }
-  case 0xB1:  /* DEVICE CONFIGURATION */
-    switch (f_reg) {
-    case 0xC0:
-      return "DEVICE CONFIGURATION RESTORE";
-    case 0xC1:
-      return "DEVICE CONFIGURATION FREEZE LOCK";
-    case 0xC2:
-      return "DEVICE CONFIGURATION IDENTIFY";
-    case 0xC3:
-      return "DEVICE CONFIGURATION SET";
-    default:
-      return "DEVICE CONFIGURATION [Reserved command]";
-    }
-  case 0xE9:  /* WRITE SAME */
-    switch (f_reg) {
-    case 0x22:
-      return "WRITE SAME [Start specified] [RET-4]";
-    case 0xDD:
-      return "WRITE SAME [Start unspecified] [RET-4]";
-    default:
-      return "WRITE SAME [Invalid subcommand] [RET-4]";
-    } 
-  case 0xEF:  /* SET FEATURES */
-    switch (f_reg) {
-    case 0x01:
-      return "SET FEATURES [Enable 8-bit PIO]";
-    case 0x02:
-      return "SET FEATURES [Enable write cache]";
-    case 0x03:
-      return "SET FEATURES [Set transfer mode]";
-    case 0x04:
-      return "SET FEATURES [Enable auto DR] [OBS-4]";
-    case 0x05:
-      return "SET FEATURES [Enable APM]";
-    case 0x06:
-      return "SET FEATURES [Enable Pwr-Up In Standby]";
-    case 0x07:
-      return "SET FEATURES [Set device spin-up]";
-    case 0x09:
-      return "SET FEATURES [Reserved (address offset)]";
-    case 0x0A:
-      return "SET FEATURES [Enable CFA power mode 1]";
-    case 0x10:
-      return "SET FEATURES [Reserved for Serial ATA]";
-    case 0x20:
-      return "SET FEATURES [Set Time-ltd R/W WCT]";
-    case 0x21:
-      return "SET FEATURES [Set Time-ltd R/W EH]";
-    case 0x31:
-      return "SET FEATURES [Disable Media Status Notf]";
-    case 0x33:
-      return "SET FEATURES [Disable retry] [OBS-4]";
-    case 0x42:
-      return "SET FEATURES [Enable AAM]";
-    case 0x43:
-      return "SET FEATURES [Set Max Host I/F S Times]";
-    case 0x44:
-      return "SET FEATURES [Length of VS data] [OBS-4]";
-    case 0x54:
-      return "SET FEATURES [Set cache segs] [OBS-4]";
-    case 0x55:
-      return "SET FEATURES [Disable read look-ahead]";
-    case 0x5D:
-      return "SET FEATURES [Enable release interrupt]";
-    case 0x5E:
-      return "SET FEATURES [Enable SERVICE interrupt]";
-    case 0x66:
-      return "SET FEATURES [Disable revert defaults]";
-    case 0x77:
-      return "SET FEATURES [Disable ECC] [OBS-4]";
-    case 0x81:
-      return "SET FEATURES [Disable 8-bit PIO]";
-    case 0x82:
-      return "SET FEATURES [Disable write cache]";
-    case 0x84:
-      return "SET FEATURES [Disable auto DR] [OBS-4]";
-    case 0x85:
-      return "SET FEATURES [Disable APM]";
-    case 0x86:
-      return "SET FEATURES [Disable Pwr-Up In Standby]";
-    case 0x88:
-      return "SET FEATURES [Disable ECC] [OBS-4]";
-    case 0x89:
-      return "SET FEATURES [Reserved (address offset)]";
-    case 0x8A:
-      return "SET FEATURES [Disable CFA power mode 1]";
-    case 0x90:
-      return "SET FEATURES [Reserved for Serial ATA]";
-    case 0x95:
-      return "SET FEATURES [Enable Media Status Notf]";
-    case 0x99:
-      return "SET FEATURES [Enable retries] [OBS-4]";
-    case 0x9A:
-      return "SET FEATURES [Set max avg curr] [OBS-4]";
-    case 0xAA:
-      return "SET FEATURES [Enable read look-ahead]";
-    case 0xAB:
-      return "SET FEATURES [Set max prefetch] [OBS-4]";
-    case 0xBB:
-      return "SET FEATURES [4 bytes VS data] [OBS-4]";
-    case 0xC2:
-      return "SET FEATURES [Disable AAM]";
-    case 0xCC:
-      return "SET FEATURES [Enable revert to defaults]";
-    case 0xDD:
-      return "SET FEATURES [Disable release interrupt]";
-    case 0xDE:
-      return "SET FEATURES [Disable SERVICE interrupt]";
-    case 0xE0:
-      return "SET FEATURES [Obsolete subcommand]";
-    default:
-      if (f_reg >= 0xF0)
-        return "SET FEATURES [Reserved for CFA]";
-      else
-        return "SET FEATURES [Reserved subcommand]";
-    }
-  case 0xF9:  /* SET MAX */
-    switch (f_reg) {
-    case 0x00:
-      return "SET MAX ADDRESS [OBS-6]";
-    case 0x01:
-      return "SET MAX SET PASSWORD";
-    case 0x02:
-      return "SET MAX LOCK";
-    case 0x03:
-      return "SET MAX UNLOCK";
-    case 0x04:
-      return "SET MAX FREEZE LOCK";
-    default:
-      return "[Reserved SET MAX command]";
-    }
-  default:
-    return command_table[c_code];
-  }
-}
diff --git a/sm5/atacmdnames.cpp b/sm5/atacmdnames.cpp
deleted file mode 100644
index e2bc92607b3df4785b9aa30b6b9fe2fa4ac94d00..0000000000000000000000000000000000000000
--- a/sm5/atacmdnames.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * atacmdnames.c
- *
- * This module is based on the T13/1532D Volume 1 Revision 3 (ATA/ATAPI-7)
- * specification, which is available from http://www.t13.org/#FTP_site
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003-4 Philip Williams
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "atacmdnames.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-#define COMMAND_TABLE_SIZE 256
-
-const char *atacmdnames_c_cvsid="$Id: atacmdnames.cpp,v 1.11 2004/01/02 16:05:24 ballen4705 Exp $" ATACMDNAMES_H_CVSID;
-
-const char cmd_reserved[]        = "[RESERVED]";
-const char cmd_vendor_specific[] = "[VENDOR SPECIFIC]";
-const char cmd_reserved_sa[]     = "[RESERVED FOR SERIAL ATA]";
-const char cmd_reserved_cf[]     = "[RESERVED FOR COMPACTFLASH ASSOCIATION]";
-const char cmd_reserved_mcpt[]   = "[RESERVED FOR MEDIA CARD PASS THROUGH]";
-const char cmd_recalibrate_ret4[]= "RECALIBRATE [RET-4]";
-const char cmd_seek_ret4[]       = "SEEK [RET-4]";
-
-const char *command_table[COMMAND_TABLE_SIZE] = {
-/*-------------------------------------------------- 00h-0Fh -----*/
-  "NOP",
-  cmd_reserved,
-  cmd_reserved,
-  "CFA REQUEST EXTENDED ERROR CODE",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "DEVICE RESET",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 10h-1Fh -----*/
-  "RECALIBRATE [OBS-4]",
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-/*-------------------------------------------------- 20h-2Fh -----*/
-  "READ SECTOR(S)",
-  "READ SECTOR(S) [OBS-5]",
-  "READ LONG (w/ retry) [OBS-4]",
-  "READ LONG (w/o retry) [OBS-4]",
-  "READ SECTOR(S) EXT",
-  "READ DMA EXT",
-  "READ DMA QUEUED EXT",
-  "READ NATIVE MAX ADDRESS EXT",
-  cmd_reserved,
-  "READ MULTIPLE EXT",
-  "READ STREAM DMA",
-  "READ STREAM PIO",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "READ LOG EXT",
-/*-------------------------------------------------- 30h-3Fh -----*/
-  "WRITE SECTOR(S)",
-  "WRITE SECTOR(S) [OBS-5]",
-  "WRITE LONG(w/ retry) [OBS-4]",
-  "WRITE LONG(w/o retry) [OBS-4]",
-  "WRITE SECTORS(S) EXT",
-  "WRITE DMA EXT",
-  "WRITE DMA QUEUED EXT",
-  "SET MAX ADDRESS EXT",
-  "CFA WRITE SECTORS WITHOUT ERASE",
-  "WRITE MULTIPLE EXT",
-  "WRITE STREAM DMA",
-  "WRITE STREAM PIO",
-  "WRITE VERIFY [OBS-4]",
-  "WRITE DMA FUA EXT",
-  "WRITE DMA QUEUED FUA EXT",
-  "WRITE LOG EXT",
-/*-------------------------------------------------- 40h-4Fh -----*/
-  "READ VERIFY SECTOR(S)",
-  "READ VERIFY SECTOR(S) [OBS-5]",
-  "READ VERIFY SECTOR(S) EXT",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 50h-5Fh -----*/
-  "FORMAT TRACK [OBS-4]",
-  "CONFIGURE STREAM",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 60h-6Fh -----*/
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 70h-7Fh -----*/
-  "SEEK [OBS-7]",
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-/*-------------------------------------------------- 80h-8Fh -----*/
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  "CFA TRANSLATE SECTOR [VS IF NO CFA]",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-/*-------------------------------------------------- 90h-9Fh -----*/
-  "EXECUTE DEVICE DIAGNOSTIC",
-  "INITIALIZE DEVICE PARAMETERS [OBS-6]",
-  "DOWNLOAD MICROCODE",
-  cmd_reserved,
-  "STANDBY IMMEDIATE [RET-4]",
-  "IDLE IMMEDIATE [RET-4]",
-  "STANDBY [RET-4]",
-  "IDLE [RET-4]",
-  "CHECK POWER MODE [RET-4]",
-  "SLEEP [RET-4]",
-  cmd_vendor_specific,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- A0h-AFh -----*/
-  "PACKET",
-  "IDENTIFY PACKET DEVICE",
-  "SERVICE",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- B0h-BFh -----*/
-  "SMART",
-  "DEVICE CONFIGURATION",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-/*-------------------------------------------------- C0h-CFh -----*/
-  "CFA ERASE SECTORS [VS IF NO CFA]",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  "READ MULTIPLE",
-  "WRITE MULTIPLE",
-  "SET MULTIPLE MODE",
-  "READ DMA QUEUED",
-  "READ DMA",
-  "READ DMA [OBS-5]",
-  "WRITE DMA",
-  "WRITE DMA [OBS-5]",
-  "WRITE DMA QUEUED",
-  "CFA WRITE MULTIPLE WITHOUT ERASE",
-  "WRITE MULTIPLE FUA EXT",
-  cmd_reserved,
-/*-------------------------------------------------- D0h-DFh -----*/
-  cmd_reserved,
-  "CHECK MEDIA CARD TYPE",
-  cmd_reserved_mcpt,
-  cmd_reserved_mcpt,
-  cmd_reserved_mcpt,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "GET MEDIA STATUS",
-  "ACKNOWLEDGE MEDIA CHANGE [RET-4]",
-  "BOOT POST-BOOT [RET-4]",
-  "BOOT PRE-BOOT [RET-4]",
-  "MEDIA LOCK",
-  "MEDIA UNLOCK",
-/*-------------------------------------------------- E0h-EFh -----*/
-  "STANDBY IMMEDIATE",
-  "IDLE IMMEDIATE",
-  "STANDBY",
-  "IDLE",
-  "READ BUFFER",
-  "CHECK POWER MODE",
-  "SLEEP",
-  "FLUSH CACHE",
-  "WRITE BUFFER",
-  "WRITE SAME [RET-4]",  /* Warning!  This command is retired but the value of
-                            f_reg is used in look_up_ata_command().  If this
-                            command code is reclaimed in a future standard then
-                            be sure to update look_up_ata_command(). */
-  "FLUSH CACHE EXIT",
-  cmd_reserved,
-  "IDENTIFY DEVICE",
-  "MEDIA EJECT",
-  "IDENTIFY DEVICE DMA [OBS-4]",
-  "SET FEATURES",
-/*-------------------------------------------------- F0h-FFh -----*/
-  cmd_vendor_specific,
-  "SECURITY SET PASSWORD",
-  "SECURITY UNLOCK",
-  "SECURITY ERASE PREPARE",
-  "SECURITY ERASE UNIT",
-  "SECURITY FREEZE LOCK",
-  "SECURITY DISABLE PASSWORD",
-  cmd_vendor_specific,
-  "READ NATIVE MAX ADDRESS",
-  "SET MAX",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific
-};
-
-/* Returns the name of the command (and possibly sub-command) with the given
-   command code and feature register values.   For most command codes this
-   simply returns the corresponding entry in the command_table array, but for
-   others the value of the feature register specifies a subcommand or
-   distinguishes commands. */
-const char *look_up_ata_command(unsigned char c_code, unsigned char f_reg) {
-
-  // check that command table not messed up.  The compiler will issue
-  // warnings if there are too many array elements, but won't issue
-  // warnings if there are not enough of them.
-  if (sizeof(command_table) != sizeof(char *)*COMMAND_TABLE_SIZE){
-    fprintf(stderr, 
-            "Problem in atacmdnames.c.  Command Table command_table[] does\n"
-            "not have %d entries!  It has %d entries. Please fix it.\n",
-            COMMAND_TABLE_SIZE, (int)(sizeof(command_table)/sizeof(char *)));
-    abort();
-  }
-
-  switch (c_code) {
-  case 0x00:  /* NOP */
-    switch (f_reg) {
-    case 0x00:
-      return "NOP [Abort queued commands]";
-    case 0x01:
-      return "NOP [Don't abort queued commands]";
-    default:
-      return "NOP [Reserved subcommand]";
-    }
-  case 0x92:  /* DOWNLOAD MICROCODE */
-    switch (f_reg) {
-    case 0x01:
-      return "DOWNLOAD MICROCODE [Temporary]";
-    case 0x07:
-      return "DOWNLOAD MICROCODE [Save]";
-    default:
-      return "DOWNLOAD MICROCODE [Reserved subcommand]";
-    }
-  case 0xB0:  /* SMART */
-    switch (f_reg) {
-    case 0xD0:
-      return "SMART READ DATA";
-    case 0xD1:
-      return "SMART READ ATTRIBUTE THRESHOLDS [OBS-4]";
-    case 0xD2:
-      return "SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE";
-    case 0xD3:
-      return "SMART SAVE ATTRIBUTE VALUES [OBS-6]";
-    case 0xD4:
-      return "SMART EXECUTE OFF-LINE IMMEDIATE";
-    case 0xD5:
-      return "SMART READ LOG";
-    case 0xD6:
-      return "SMART WRITE LOG";
-    case 0xD7:
-      return "SMART WRITE ATTRIBUTE THRESHOLDS [NS, OBS-4]";
-    case 0xD8:
-      return "SMART ENABLE OPERATIONS";
-    case 0xD9:
-      return "SMART DISABLE OPERATIONS";
-    case 0xDA:
-      return "SMART RETURN STATUS";
-    case 0xDB:
-      return "SMART EN/DISABLE AUTO OFFLINE [NS (SFF-8035i)]";
-    default:
-        if (f_reg >= 0xE0)
-          return "[Vendor specific SMART command]";
-        else
-          return "[Reserved SMART command]";
-    }
-  case 0xB1:  /* DEVICE CONFIGURATION */
-    switch (f_reg) {
-    case 0xC0:
-      return "DEVICE CONFIGURATION RESTORE";
-    case 0xC1:
-      return "DEVICE CONFIGURATION FREEZE LOCK";
-    case 0xC2:
-      return "DEVICE CONFIGURATION IDENTIFY";
-    case 0xC3:
-      return "DEVICE CONFIGURATION SET";
-    default:
-      return "DEVICE CONFIGURATION [Reserved command]";
-    }
-  case 0xE9:  /* WRITE SAME */
-    switch (f_reg) {
-    case 0x22:
-      return "WRITE SAME [Start specified] [RET-4]";
-    case 0xDD:
-      return "WRITE SAME [Start unspecified] [RET-4]";
-    default:
-      return "WRITE SAME [Invalid subcommand] [RET-4]";
-    } 
-  case 0xEF:  /* SET FEATURES */
-    switch (f_reg) {
-    case 0x01:
-      return "SET FEATURES [Enable 8-bit PIO]";
-    case 0x02:
-      return "SET FEATURES [Enable write cache]";
-    case 0x03:
-      return "SET FEATURES [Set transfer mode]";
-    case 0x04:
-      return "SET FEATURES [Enable auto DR] [OBS-4]";
-    case 0x05:
-      return "SET FEATURES [Enable APM]";
-    case 0x06:
-      return "SET FEATURES [Enable Pwr-Up In Standby]";
-    case 0x07:
-      return "SET FEATURES [Set device spin-up]";
-    case 0x09:
-      return "SET FEATURES [Reserved (address offset)]";
-    case 0x0A:
-      return "SET FEATURES [Enable CFA power mode 1]";
-    case 0x10:
-      return "SET FEATURES [Reserved for Serial ATA]";
-    case 0x20:
-      return "SET FEATURES [Set Time-ltd R/W WCT]";
-    case 0x21:
-      return "SET FEATURES [Set Time-ltd R/W EH]";
-    case 0x31:
-      return "SET FEATURES [Disable Media Status Notf]";
-    case 0x33:
-      return "SET FEATURES [Disable retry] [OBS-4]";
-    case 0x42:
-      return "SET FEATURES [Enable AAM]";
-    case 0x43:
-      return "SET FEATURES [Set Max Host I/F S Times]";
-    case 0x44:
-      return "SET FEATURES [Length of VS data] [OBS-4]";
-    case 0x54:
-      return "SET FEATURES [Set cache segs] [OBS-4]";
-    case 0x55:
-      return "SET FEATURES [Disable read look-ahead]";
-    case 0x5D:
-      return "SET FEATURES [Enable release interrupt]";
-    case 0x5E:
-      return "SET FEATURES [Enable SERVICE interrupt]";
-    case 0x66:
-      return "SET FEATURES [Disable revert defaults]";
-    case 0x77:
-      return "SET FEATURES [Disable ECC] [OBS-4]";
-    case 0x81:
-      return "SET FEATURES [Disable 8-bit PIO]";
-    case 0x82:
-      return "SET FEATURES [Disable write cache]";
-    case 0x84:
-      return "SET FEATURES [Disable auto DR] [OBS-4]";
-    case 0x85:
-      return "SET FEATURES [Disable APM]";
-    case 0x86:
-      return "SET FEATURES [Disable Pwr-Up In Standby]";
-    case 0x88:
-      return "SET FEATURES [Disable ECC] [OBS-4]";
-    case 0x89:
-      return "SET FEATURES [Reserved (address offset)]";
-    case 0x8A:
-      return "SET FEATURES [Disable CFA power mode 1]";
-    case 0x90:
-      return "SET FEATURES [Reserved for Serial ATA]";
-    case 0x95:
-      return "SET FEATURES [Enable Media Status Notf]";
-    case 0x99:
-      return "SET FEATURES [Enable retries] [OBS-4]";
-    case 0x9A:
-      return "SET FEATURES [Set max avg curr] [OBS-4]";
-    case 0xAA:
-      return "SET FEATURES [Enable read look-ahead]";
-    case 0xAB:
-      return "SET FEATURES [Set max prefetch] [OBS-4]";
-    case 0xBB:
-      return "SET FEATURES [4 bytes VS data] [OBS-4]";
-    case 0xC2:
-      return "SET FEATURES [Disable AAM]";
-    case 0xCC:
-      return "SET FEATURES [Enable revert to defaults]";
-    case 0xDD:
-      return "SET FEATURES [Disable release interrupt]";
-    case 0xDE:
-      return "SET FEATURES [Disable SERVICE interrupt]";
-    case 0xE0:
-      return "SET FEATURES [Obsolete subcommand]";
-    default:
-      if (f_reg >= 0xF0)
-        return "SET FEATURES [Reserved for CFA]";
-      else
-        return "SET FEATURES [Reserved subcommand]";
-    }
-  case 0xF9:  /* SET MAX */
-    switch (f_reg) {
-    case 0x00:
-      return "SET MAX ADDRESS [OBS-6]";
-    case 0x01:
-      return "SET MAX SET PASSWORD";
-    case 0x02:
-      return "SET MAX LOCK";
-    case 0x03:
-      return "SET MAX UNLOCK";
-    case 0x04:
-      return "SET MAX FREEZE LOCK";
-    default:
-      return "[Reserved SET MAX command]";
-    }
-  default:
-    return command_table[c_code];
-  }
-}
diff --git a/sm5/atacmdnames.h b/sm5/atacmdnames.h
deleted file mode 100644
index 8b1ba7ecfb9b1de9bd9232a5094a4c3c460bcb77..0000000000000000000000000000000000000000
--- a/sm5/atacmdnames.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * atacmdnames.h
- *
- * This module is based on the T13/1532D Volume 1 Revision 3 (ATA/ATAPI-7)
- * specification, which is available from http://www.t13.org/#FTP_site
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003-4 Philip Williams
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef ATACMDNAMES_H_
-#define ATACMDNAMES_H_
-
-#define ATACMDNAMES_H_CVSID "$Id: atacmdnames.h,v 1.3 2004/01/02 16:05:24 ballen4705 Exp $\n"
-
-/* Returns the name of the command (and possibly sub-command) with the given
-   command code and feature register values. */
-const char *look_up_ata_command(unsigned char c_code, unsigned char f_reg);
-
-#endif
diff --git a/sm5/atacmds.c b/sm5/atacmds.c
deleted file mode 100644
index b2b8d4cd4216a339e8c577a092a6aca760a8db6f..0000000000000000000000000000000000000000
--- a/sm5/atacmds.c
+++ /dev/null
@@ -1,1873 +0,0 @@
-/*
- * atacmds.c
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- * 
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "atacmds.h"
-#include "config.h"
-#include "int64.h"
-#include "extern.h"
-#include "utility.h"
-
-const char *atacmds_c_cvsid="$Id: atacmds.c,v 1.160 2004/08/16 22:44:26 ballen4705 Exp $"
-ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// These Drive Identity tables are taken from hdparm 5.2, and are also
-// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command.  Note
-// that SMART was first added into the ATA/ATAPI-3 Standard with
-// Revision 3 of the document, July 25, 1995.  Look at the "Document
-// Status" revision commands at the beginning of
-// http://www.t13.org/project/d2008r6.pdf to see this.
-#define NOVAL_0                 0x0000
-#define NOVAL_1                 0xffff
-/* word 81: minor version number */
-#define MINOR_MAX 0x22
-const char *minor_str[] = {                     /* word 81 value: */
-  "Device does not report version",             /* 0x0000       */
-  "ATA-1 X3T9.2 781D prior to revision 4",      /* 0x0001       */
-  "ATA-1 published, ANSI X3.221-1994",          /* 0x0002       */
-  "ATA-1 X3T9.2 781D revision 4",               /* 0x0003       */
-  "ATA-2 published, ANSI X3.279-1996",          /* 0x0004       */
-  "ATA-2 X3T10 948D prior to revision 2k",      /* 0x0005       */
-  "ATA-3 X3T10 2008D revision 1",               /* 0x0006       */ /* SMART NOT INCLUDED */
-  "ATA-2 X3T10 948D revision 2k",               /* 0x0007       */
-  "ATA-3 X3T10 2008D revision 0",               /* 0x0008       */ 
-  "ATA-2 X3T10 948D revision 3",                /* 0x0009       */
-  "ATA-3 published, ANSI X3.298-199x",          /* 0x000a       */
-  "ATA-3 X3T10 2008D revision 6",               /* 0x000b       */ /* 1st VERSION WITH SMART */
-  "ATA-3 X3T13 2008D revision 7 and 7a",        /* 0x000c       */
-  "ATA/ATAPI-4 X3T13 1153D revision 6",         /* 0x000d       */
-  "ATA/ATAPI-4 T13 1153D revision 13",          /* 0x000e       */
-  "ATA/ATAPI-4 X3T13 1153D revision 7",         /* 0x000f       */
-  "ATA/ATAPI-4 T13 1153D revision 18",          /* 0x0010       */
-  "ATA/ATAPI-4 T13 1153D revision 15",          /* 0x0011       */
-  "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012       */
-  "ATA/ATAPI-5 T13 1321D revision 3",           /* 0x0013       */
-  "ATA/ATAPI-4 T13 1153D revision 14",          /* 0x0014       */
-  "ATA/ATAPI-5 T13 1321D revision 1",           /* 0x0015       */
-  "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016       */
-  "ATA/ATAPI-4 T13 1153D revision 17",          /* 0x0017       */
-  "ATA/ATAPI-6 T13 1410D revision 0",           /* 0x0018       */
-  "ATA/ATAPI-6 T13 1410D revision 3a",          /* 0x0019       */
-  "ATA/ATAPI-7 T13 1532D revision 1",           /* 0x001a       */
-  "ATA/ATAPI-6 T13 1410D revision 2",           /* 0x001b       */
-  "ATA/ATAPI-6 T13 1410D revision 1",           /* 0x001c       */
-  "reserved",                                   /* 0x001d       */
-  "ATA/ATAPI-7 T13 1532D revision 0",           /* 0x001e       */
-  "reserved",                                   /* 0x001f       */
-  "reserved",                                   /* 0x0020       */
-  "ATA/ATAPI-7 T13 1532D revision 4a",          /* 0x0021       */
-  "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022       */
-};
-
-// NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
-// attribute structures were NOT completely vendor specific.  So any
-// disk that is ATA/ATAPI-4 or above can not be trusted to show the
-// vendor values in sensible format.
-
-// Negative values below are because it doesn't support SMART
-const int actual_ver[] = { 
-  /* word 81 value: */
-  0,            /* 0x0000       WARNING:        */
-  1,            /* 0x0001       WARNING:        */
-  1,            /* 0x0002       WARNING:        */
-  1,            /* 0x0003       WARNING:        */
-  2,            /* 0x0004       WARNING:   This array           */
-  2,            /* 0x0005       WARNING:   corresponds          */
-  -3, /*<== */  /* 0x0006       WARNING:   *exactly*            */
-  2,            /* 0x0007       WARNING:   to the ATA/          */
-  -3, /*<== */  /* 0x0008       WARNING:   ATAPI version        */
-  2,            /* 0x0009       WARNING:   listed in            */
-  3,            /* 0x000a       WARNING:   the                  */
-  3,            /* 0x000b       WARNING:   minor_str            */
-  3,            /* 0x000c       WARNING:   array                */
-  4,            /* 0x000d       WARNING:   above.               */
-  4,            /* 0x000e       WARNING:                        */
-  4,            /* 0x000f       WARNING:   If you change        */
-  4,            /* 0x0010       WARNING:   that one,            */
-  4,            /* 0x0011       WARNING:   change this one      */
-  4,            /* 0x0012       WARNING:   too!!!               */
-  5,            /* 0x0013       WARNING:        */
-  4,            /* 0x0014       WARNING:        */
-  5,            /* 0x0015       WARNING:        */
-  5,            /* 0x0016       WARNING:        */
-  4,            /* 0x0017       WARNING:        */
-  6,            /* 0x0018       WARNING:        */
-  6,            /* 0x0019       WARNING:        */
-  7,            /* 0x001a       WARNING:        */
-  6,            /* 0x001b       WARNING:        */
-  6,            /* 0x001c       WARNING:        */
-  0,            /* 0x001d       WARNING:        */
-  7,            /* 0x001e       WARNING:        */
-  0,            /* 0x001f       WARNING:        */
-  0,            /* 0x0020       WARNING:        */
-  7,            /* 0x0021       WARNING:        */
-  6             /* 0x0022       WARNING:        */
-};
-
-// When you add additional items to this list, you should then:
-// 0 -- update this list
-// 1 -- modify the following function parse_attribute_def()
-// 2 -- if needed, modify ataPrintSmartAttribRawValue()
-// 3 -  if needed, modify ataPrintSmartAttribName()
-// 4 -- add #define PRESET_N_DESCRIPTION at top of knowndrives.c
-// 5 -- add drive in question into knowndrives[] table in knowndrives.c
-// 6 -- update smartctl.8
-// 7 -- update smartd.8
-// 8 -- do "make smartd.conf.5" to update smartd.conf.5
-// 9 -- update CHANGELOG file
-const char *vendorattributeargs[] = {
-  // 0  defs[9]=1
-  "9,minutes",
-  // 1  defs[9]=3
-  "9,seconds",
-  // 2  defs[9]=2
-  "9,temp",
-  // 3  defs[220]=1
-  "220,temp",
-  // 4  defs[*]=253
-  "N,raw8",
-  // 5  defs[*]=254
-  "N,raw16",
-  // 6  defs[*]=255
-  "N,raw48",
-  // 7  defs[200]=1
-  "200,writeerrorcount",
-  // 8  defs[9]=4
-  "9,halfminutes",
-  // 9  defs[194]=1
-  "194,10xCelsius",
-  // 10 defs[194]=2
-  "194,unknown",
-  // 11 defs[193]=1
-  "193,loadunload",
-  // 12 defs[201]=1
-  "201,detectedtacount",
-  // 13 defs[192]=1
-  "192,emergencyretractcyclect",
-  // 14 defs[198]=1
-  "198,offlinescanuncsectorct",
-  // NULL should always terminate the array
-  NULL
-};
-
-// This are the meanings of the Self-test failure checkpoint byte.
-// This is in the self-test log at offset 4 bytes into the self-test
-// descriptor and in the SMART READ DATA structure at byte offset
-// 371. These codes are not well documented.  The meanings returned by
-// this routine are used (at least) by Maxtor and IBM. Returns NULL if
-// not recognized.  Currently the maximum length is 15 bytes.
-const char *SelfTestFailureCodeName(unsigned char which){
-  
-  switch (which) {
-  case 0:
-    return "Write_Test";
-  case 1:
-    return "Servo_Basic";
-  case 2:
-    return "Servo_Random";
-  case 3:
-    return "G-list_Scan";
-  case 4:
-    return "Handling_Damage";
-  case 5:
-    return "Read_Scan";
-  default:
-    return NULL;
-  }
-}
-
-// This is a utility function for parsing pairs like "9,minutes" or
-// "220,temp", and putting the correct flag into the attributedefs
-// array.  Returns 1 if problem, 0 if pair has been recongized.
-int parse_attribute_def(char *pair, unsigned char **defsptr){
-  int i,j;
-  char temp[32];
-  unsigned char *defs;
-
-  // If array does not exist, allocate it
-  if (!*defsptr && !(*defsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM, 1))){
-    pout("Out of memory in parse_attribute_def\n");
-    EXIT(1);
-  }
-
-  defs=*defsptr;
-
-  // look along list and see if we find the pair
-  for (i=0; vendorattributeargs[i] && strcmp(pair, vendorattributeargs[i]); i++);
-
-  switch (i) {
-  case 0:
-    // attribute 9 is power on time in minutes
-    defs[9]=1;
-    return 0;
-  case 1:
-    // attribute 9 is power-on-time in seconds
-    defs[9]=3;
-    return 0;
-  case 2:
-    // attribute 9 is temperature in celsius
-    defs[9]=2;
-    return 0;
-  case 3:
-    // attribute 220 is temperature in celsius
-    defs[220]=1;
-    return 0;
-  case 4:
-    // print all attributes in raw 8-bit form
-    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)
-      defs[j]=253;
-    return 0;
-  case 5:
-    // print all attributes in raw 16-bit form
-    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)
-      defs[j]=254;
-    return 0;
-  case 6:
-    // print all attributes in raw 48-bit form
-    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)
-      defs[j]=255;
-    return 0;
-  case 7:
-    // attribute 200 is write error count
-    defs[200]=1;
-    return 0;
-  case 8:
-    // attribute 9 increments once every 30 seconds (power on time
-    // measure)
-    defs[9]=4;
-    return 0;
-  case 9:
-    // attribute 194 is ten times disk temp in Celsius
-    defs[194]=1;
-    return 0;
-  case 10:
-    // attribute 194 is unknown
-    defs[194]=2;
-    return 0;
-  case 11:
-    // Hitachi : Attributes 193 has 2 values : 1 load, 1 normal unload
-    defs[193]=1;
-    return 0;
-  case 12:
-    // Fujitsu
-    defs[201]=1;
-    return 0;
-  case 13:
-    // Fujitsu
-    defs[192]=1;
-    return 0;
-  case 14:
-    // Fujitsu
-    defs[198]=1;
-    return 0;
-  default:
-    // pair not found
-    break;
-  }
-  // At this point, either the pair was not found, or it is of the
-  // form N,uninterpreted, in which case we need to parse N
-  j=sscanf(pair,"%d,%14s", &i, temp);
- 
-  // if no match to pattern, unrecognized
-  if (j!=2 || i<0 || i >255)
-    return 1;
-
-  // check for recognized strings
-  if (!strcmp(temp, "raw8")) {
-    defs[i]=253;
-    return 0;
-  }
-  
-  // check for recognized strings
-  if (!strcmp(temp, "raw16")) {
-    defs[i]=254;
-    return 0;
-  }
-  
-  // check for recognized strings
-  if (!strcmp(temp, "raw48")) {
-    defs[i]=255;
-    return 0;
-  }
- 
-  // didn't recognize the string
-  return 1;
-}
-
-// Structure used in sorting the array vendorattributeargs[].
-typedef struct vaa_pair_s {
-  const char *vaa;
-  const char *padded_vaa;
-} vaa_pair;
-
-// Returns a copy of s with all numbers of less than three digits padded with
-// leading zeros.  Returns NULL if there isn't enough memory available.  The
-// memory for the string is dynamically allocated and should be freed by the
-// caller.
-char *pad_numbers(const char *s)
-{
-  char c, *t, *u;
-  const char *r;
-  int i, len, ndigits = 0;
-
-  // Allocate the maximum possible amount of memory needed.
-  if (!(t = (char *)malloc(strlen(s)*2+2)))
-    return NULL;
-
-  // Copy the string s to t, padding any numbers of less than three digits
-  // with leading zeros.  The string is copied backwards to simplify the code.
-  r = s + strlen(s);
-  u = t;
-  while (( r-- >= s)) {
-    if (isdigit((int)*r))
-      ndigits++;
-    else if (ndigits > 0) {
-      while (ndigits++ < 3)
-        *u++ = '0';
-      ndigits = 0;
-    }
-    *u++ = *r;
-  }
-  *u = '\0';
-
-  // Reverse the string in t.
-  len = strlen(t);
-  for (i = 0; i < len/2; i++) {
-    c          = t[i];
-    t[i]       = t[len-1-i];
-    t[len-1-i] = c;
-  }
-
-  return t;
-}
-
-// Comparison function for qsort().  Used by sort_vendorattributeargs().
-int compare_vaa_pairs(const void *a, const void *b)
-{
-  vaa_pair *p = (vaa_pair *)a;
-  vaa_pair *q = (vaa_pair *)b;
-
-  return strcmp(p->padded_vaa, q->padded_vaa);
-}
-
-// Returns a sorted list of vendorattributeargs or NULL if there is not enough
-// memory available.  The memory for the list is allocated dynamically and
-// should be freed by the caller.
-// To perform the sort, any numbers in the strings are padded out to three
-// digits by adding leading zeros.  For example,
-//
-//    "9,minutes"  becomes  "009,minutes"
-//    "N,raw16"    becomes  "N,raw016"
-//
-// and the original strings are paired with the padded strings.  The list of
-// pairs is then sorted by comparing the padded strings (using strcmp) and the
-// result is then the list of unpadded strings.
-//
-const char **sort_vendorattributeargs(void) {
-  const char **ps, **sorted_list = NULL;
-  vaa_pair *pairs, *pp;
-  int count, i;
-
-  // Figure out how many strings are in vendorattributeargs[] (not including
-  // the terminating NULL).
-  count = (sizeof vendorattributeargs) / sizeof(char *) - 1;
-
-  // Construct a list of pairs of strings from vendorattributeargs[] and their
-  // padded equivalents.
-  if (!(pairs = (vaa_pair *)malloc(sizeof(vaa_pair) * count)))
-    goto END;
-  for (ps = vendorattributeargs, pp = pairs; *ps; ps++, pp++) {
-    pp->vaa = *ps;
-    if (!(pp->padded_vaa = pad_numbers(*ps)))
-      goto END;
-  }
-
-  // Sort the array of vaa_pair structures by comparing the padded strings
-  // using strcmp().
-  qsort(pairs, count, sizeof(vaa_pair), compare_vaa_pairs);
-
-  // Construct the sorted list of strings.
-  if (!(sorted_list = (const char **)malloc(sizeof vendorattributeargs)))
-    goto END;
-  for (ps = sorted_list, pp = pairs, i = 0; i < count; ps++, pp++, i++)
-    *ps = pp->vaa;
-  *ps = NULL;
-
-END:
-  if (pairs) {
-    for (i = 0; i < count; i++)
-      if (pairs[i].padded_vaa)
-        free((void *)pairs[i].padded_vaa);
-    free((void *)pairs);
-  }
-
-  // If there was a problem creating the list then sorted_list should now
-  // contain NULL.
-  return sorted_list;
-}
-
-// Function to return a multiline string containing a list of the arguments in 
-// vendorattributeargs[].  The strings are preceeded by tabs and followed
-// (except for the last) by newlines.
-// This function allocates the required memory for the string and the caller
-// must use free() to free it.  It returns NULL if the required memory can't
-// be allocated.
-char *create_vendor_attribute_arg_list(void){
-  const char **ps, **sorted;
-  char *s;
-  int len;
-
-  // Get a sorted list of vendor attribute arguments.  If the sort fails
-  // (which should only happen if the system is really low on memory) then just
-  // use the unordered list.
-  if (!(sorted = (const char **) sort_vendorattributeargs()))
-    sorted = vendorattributeargs;
-
-  // Calculate the required number of characters
-  len = 1;                // At least one char ('\0')
-  for (ps = sorted; *ps != NULL; ps++) {
-    len += 1;             // For the tab
-    len += strlen(*ps);   // For the actual argument string
-    if (*(ps+1))
-      len++;              // For the newline if required
-  }
-
-  // Attempt to allocate memory for the string
-  if (!(s = (char *)malloc(len)))
-    return NULL;
-
-  // Construct the string
-  *s = '\0';
-  for (ps = sorted; *ps != NULL; ps++) {
-    strcat(s, "\t");
-    strcat(s, *ps);
-    if (*(ps+1))
-      strcat(s, "\n");
-  }
-
-  free((char **)sorted);
-
-  // Return a pointer to the string
-  return s;
-}
-
-// swap two bytes.  Point to low address
-void swap2(char *location){
-  char tmp=*location;
-  *location=*(location+1);
-  *(location+1)=tmp;
-  return;
-}
-
-// swap four bytes.  Point to low address
-void swap4(char *location){
-  char tmp=*location;
-  *location=*(location+3);
-  *(location+3)=tmp;
-  swap2(location+1);
-  return;
-}
-
-// swap eight bytes.  Points to low address
-void swap8(char *location){
-  char tmp=*location;
-  *location=*(location+7);
-  *(location+7)=tmp;
-  tmp=*(location+1);
-  *(location+1)=*(location+6);
-  *(location+6)=tmp;
-  swap4(location+2);
-  return;
-}
-
-static char *commandstrings[]={
-  "SMART ENABLE",
-  "SMART DISABLE",
-  "SMART AUTOMATIC ATTRIBUTE SAVE",
-  "SMART IMMEDIATE OFFLINE",
-  "SMART AUTO OFFLINE",
-  "SMART STATUS",
-  "SMART STATUS CHECK",
-  "SMART READ ATTRIBUTE VALUES",
-  "SMART READ ATTRIBUTE THRESHOLDS",
-  "SMART READ LOG",
-  "IDENTIFY DEVICE",
-  "IDENTIFY PACKET DEVICE",
-  "CHECK POWER MODE",
-  "SMART WRITE LOG",
-  "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT ")\n"
-};
-
-void prettyprint(unsigned char *stuff, char *name){
-  int i,j;
-  pout("\n===== [%s] DATA START (BASE-16) =====\n", name);
-  for (i=0; i<32; i++){
-    pout("%03d-%03d: ", 16*i, 16*(i+1)-1);
-    for (j=0; j<15; j++)
-      pout("%02x ",*stuff++);
-    pout("%02x\n",*stuff++);
-  }
-  pout("===== [%s] DATA END (512 Bytes) =====\n\n", name);
-}
-
-// This function provides the pretty-print reporting for SMART
-// commands: it implements the various -r "reporting" options for ATA
-// ioctls.
-int smartcommandhandler(int device, smart_command_set command, int select, char *data){
-  int retval;
-
-  // This conditional is true for commands that return data
-  int getsdata=(command==PIDENTIFY || 
-                command==IDENTIFY || 
-                command==READ_LOG || 
-                command==READ_THRESHOLDS || 
-                command==READ_VALUES ||
-		command==CHECK_POWER_MODE);
-
-  int sendsdata=(command==WRITE_LOG);
-  
-  // If reporting is enabled, say what the command will be before it's executed
-  if (con->reportataioctl){
-          // conditional is true for commands that use parameters
-          int usesparam=(command==READ_LOG || 
-                         command==AUTO_OFFLINE || 
-                         command==AUTOSAVE || 
-                         command==IMMEDIATE_OFFLINE ||
-                         command==WRITE_LOG);
-                  
-    pout("\nREPORT-IOCTL: DeviceFD=%d Command=%s", device, commandstrings[command]);
-    if (usesparam)
-      pout(" InputParameter=%d\n", select);
-    else
-      pout("\n");
-  }
-  
-  if ((getsdata || sendsdata) && !data){
-    pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
-    return -1;
-  }
-  
-  // The reporting is cleaner, and we will find coding bugs faster, if
-  // the commands that failed clearly return empty (zeroed) data
-  // structures
-  if (getsdata) {
-    if (command==CHECK_POWER_MODE)
-      data[0]=0;
-    else
-      memset(data, '\0', 512);
-  }
-
-
-  // If reporting is enabled, say what input was sent to the command
-  if (con->reportataioctl && sendsdata){
-    pout("REPORT-IOCTL: DeviceFD=%d Command=%s", device, commandstrings[command]);
-    // if requested, pretty-print the output data structure
-    if (con->reportataioctl>1)
-      prettyprint((unsigned char *)data, commandstrings[command]);
-  }
-
-  // In case the command produces an error, we'll want to know what it is:
-  errno=0;
-  
-  // now execute the command
-  switch (con->controller_type) {
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_3WARE_678K_CHAR:
-  case CONTROLLER_3WARE_9000_CHAR:
-    retval=escalade_command_interface(device, con->controller_port-1, con->controller_type, command, select, data);
-    break;
-  default:
-    retval=ata_command_interface(device, command, select, data);
-  }
-
-  // If reporting is enabled, say what output was produced by the command
-  if (con->reportataioctl){
-    if (errno)
-      pout("REPORT-IOCTL: DeviceFD=%d Command=%s returned %d errno=%d [%s]\n", 
-           device, commandstrings[command], retval, errno, strerror(errno));
-    else
-      pout("REPORT-IOCTL: DeviceFD=%d Command=%s returned %d\n",
-           device, commandstrings[command], retval);
-    
-    // if requested, pretty-print the output data structure
-    if (con->reportataioctl>1 && getsdata) {
-      if (command==CHECK_POWER_MODE)
-	pout("Sector Count Register (BASE-16): %02x\n", *data);
-      else
-	prettyprint((unsigned char *)data, commandstrings[command]);
-    }
-  }
-  return retval;
-}
-
-
-// This function computes the checksum of a single disk sector (512
-// bytes).  Returns zero if checksum is OK, nonzero if the checksum is
-// incorrect.  The size (512) is correct for all SMART structures.
-unsigned char checksum(unsigned char *buffer){
-  unsigned char sum=0;
-  int i;
-  
-  for (i=0; i<512; i++)
-    sum+=buffer[i];
-
-  return sum;
-}
-
-// returns -1 if command fails or the device is in Sleep mode, else
-// value of Sector Count register.  Sector Count result values:
-//   00h device is in Standby mode. 
-//   80h device is in Idle mode.
-//   FFh device is in Active mode or Idle mode.
-
-int ataCheckPowerMode(int device) {
-  unsigned char result;
-
-  if ((smartcommandhandler(device, CHECK_POWER_MODE, 0, (char *)&result)))
-    return -1;
-
-  if (result!=0 && result!=0x80 && result!=0xff)
-    pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result);
-
-  return (int)result;
-}
-
-
-
-
-// Reads current Device Identity info (512 bytes) into buf.  Returns 0
-// if all OK.  Returns -1 if no ATA Device identity can be
-// established.  Returns >0 if Device is ATA Packet Device (not SMART
-// capable).  The value of the integer helps identify the type of
-// Packet device, which is useful so that the user can connect the
-// formal device number with whatever object is inside their computer.
-int ataReadHDIdentity (int device, struct ata_identify_device *buf){
-  unsigned short *rawshort=(unsigned short *)buf;
-  unsigned char  *rawbyte =(unsigned char  *)buf;
-
-  // See if device responds either to IDENTIFY DEVICE or IDENTIFY
-  // PACKET DEVICE
-  if ((smartcommandhandler(device, IDENTIFY, 0, (char *)buf))){
-    if (smartcommandhandler(device, PIDENTIFY, 0, (char *)buf)){
-      return -1; 
-    }
-  }
-
-  // if machine is big-endian, swap byte order as needed
-  if (isbigendian()){
-    int i;
-    
-    // swap various capability words that are needed
-    for (i=0; i<33; i++)
-      swap2((char *)(buf->words047_079+i));
-    
-    for (i=80; i<=87; i++)
-      swap2((char *)(rawshort+i));
-    
-    for (i=0; i<168; i++)
-      swap2((char *)(buf->words088_255+i));
-  }
-  
-  // If there is a checksum there, validate it
-  if ((rawshort[255] & 0x00ff) == 0x00a5 && checksum(rawbyte))
-    checksumwarning("Drive Identity Structure");
-  
-  // If this is a PACKET DEVICE, return device type
-  if (rawbyte[1] & 0x80)
-    return 1+(rawbyte[1] & 0x1f);
-  
-  // Not a PACKET DEVICE
-  return 0;
-}
-
-// Returns ATA version as an integer, and a pointer to a string
-// describing which revision.  Note that Revision 0 of ATA-3 does NOT
-// support SMART.  For this one case we return -3 rather than +3 as
-// the version number.  See notes above.
-int ataVersionInfo (const char** description, struct ata_identify_device *drive, unsigned short *minor){
-  unsigned short major;
-  int i;
-
-  // check that arrays at the top of this file are defined
-  // consistently
-  if (sizeof(minor_str) != sizeof(char *)*(1+MINOR_MAX)){
-    pout("Internal error in ataVersionInfo().  minor_str[] size %d\n"
-         "is not consistent with value of MINOR_MAX+1 = %d\n", 
-         (int)(sizeof(minor_str)/sizeof(char *)), MINOR_MAX+1);
-    fflush(NULL);
-    abort();
-  }
-  if (sizeof(actual_ver) != sizeof(int)*(1+MINOR_MAX)){
-    pout("Internal error in ataVersionInfo().  actual_ver[] size %d\n"
-         "is not consistent with value of MINOR_MAX = %d\n",
-         (int)(sizeof(actual_ver)/sizeof(int)), MINOR_MAX+1);
-    fflush(NULL);
-    abort();
-  }
-
-  // get major and minor ATA revision numbers
-  major=drive->major_rev_num;
-  *minor=drive->minor_rev_num;
-  
-  // First check if device has ANY ATA version information in it
-  if (major==NOVAL_0 || major==NOVAL_1) {
-    *description=NULL;
-    return -1;
-  }
-  
-  // The minor revision number has more information - try there first
-  if (*minor && (*minor<=MINOR_MAX)){
-    int std = actual_ver[*minor];
-    if (std) {
-      *description=minor_str[*minor];
-      return std;
-    }
-  }
-  
-  // HDPARM has a very complicated algorithm from here on. Since SMART only
-  // exists on ATA-3 and later standards, let's punt on this.  If you don't
-  // like it, please fix it.  The code's in CVS.
-  for (i=15; i>0; i--)
-    if (major & (0x1<<i))
-      break;
-  
-  *description=NULL; 
-  if (i==0)
-    return 1;
-  else
-    return i;;
-}
-
-// returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
-int ataSmartSupport(struct ata_identify_device *drive){
-  unsigned short word82=drive->command_set_1;
-  unsigned short word83=drive->command_set_2;
-  
-  // check if words 82/83 contain valid info
-  if ((word83>>14) == 0x01)
-    // return value of SMART support bit 
-    return word82 & 0x0001;
-  
-  // since we can're rely on word 82, we don't know if SMART supported
-  return -1;
-}
-
-// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
-int ataIsSmartEnabled(struct ata_identify_device *drive){
-  unsigned short word85=drive->cfs_enable_1;
-  unsigned short word87=drive->csf_default;
-  
-  // check if words 85/86/87 contain valid info
-  if ((word87>>14) == 0x01)
-    // return value of SMART enabled bit
-    return word85 & 0x0001;
-  
-  // Since we can't rely word85, we don't know if SMART is enabled.
-  return -1;
-}
-
-
-// Reads SMART attributes into *data
-int ataReadSmartValues(int device, struct ata_smart_values *data){      
-  
-  if (smartcommandhandler(device, READ_VALUES, 0, (char *)data)){
-    syserror("Error SMART Values Read failed");
-    return -1;
-  }
-
-  // compute checksum
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART Attribute Data Structure");
-  
-  // byte swap if needed
-  if (isbigendian()){
-    int i;
-    swap2((char *)&(data->revnumber));
-    swap2((char *)&(data->total_time_to_complete_off_line));
-    swap2((char *)&(data->smart_capability));
-    for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-      struct ata_smart_attribute *x=data->vendor_attributes+i;
-      swap2((char *)&(x->flags));
-    }
-  }
-
-  return 0;
-}
-
-
-// This corrects some quantities that are byte reversed in the SMART
-// SELF TEST LOG
-void fixsamsungselftestlog(struct ata_smart_selftestlog *data){
-  int i;
-  
-  // bytes 508/509 (numbered from 0) swapped (swap of self-test index
-  // with one byte of reserved.
-  swap2((char *)&(data->mostrecenttest));
-
-  // LBA low register (here called 'selftestnumber", containing
-  // information about the TYPE of the self-test) is byte swapped with
-  // Self-test execution status byte.  These are bytes N, N+1 in the
-  // entries.
-  for (i=0; i<21; i++)
-    swap2((char *)&(data->selftest_struct[i].selftestnumber));
-
-  return;
-}
-
-// Reads the Self Test Log (log #6)
-int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){
-
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x06, (char *)data)){
-    syserror("Error SMART Error Self-Test Log Read failed");
-    return -1;
-  }
-
-  // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART Self-Test Log Structure");
-  
-  // fix firmware bugs in self-test log
-  if (con->fixfirmwarebug == FIX_SAMSUNG)
-    fixsamsungselftestlog(data);
-
-  // fix endian order, if needed
-  if (isbigendian()){
-    int i;
-    swap2((char*)&(data->revnumber));
-    for (i=0; i<21; i++){
-      struct ata_smart_selftestlog_struct *x=data->selftest_struct+i;
-      swap2((char *)&(x->timestamp));
-      swap4((char *)&(x->lbafirstfailure));
-    }
-  }
-
-  return 0;
-}
-
-
-// Reads the Log Directory (log #0).  Note: NO CHECKSUM!!
-int ataReadLogDirectory (int device, struct ata_smart_log_directory *data){     
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x00, (char *)data)){
-    return -1;
-  }
-
-  // swap endian order if needed
-  if (isbigendian()){
-    swap2((char *)&(data->logversion));
-  }
-  
-  return 0;
-}
-
-
-// Reads the selective self-test log (log #9)
-int ataReadSelectiveSelfTestLog(int device, struct ata_selective_self_test_log *data){  
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){
-    syserror("Error SMART Read Selective Self-Test Log failed");
-    return -1;
-  }
-   
-  // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART Selective Self-Test Log Structure");
-  
-  // swap endian order if needed
-  if (isbigendian()){
-    int i;
-    swap2((char *)&(data->logversion));
-    for (i=0;i<5;i++){
-      swap8((char *)&(data->span[i].start));
-      swap8((char *)&(data->span[i].end));
-    }
-    swap8((char *)&(data->currentlba));
-    swap2((char *)&(data->currentspan));
-    swap2((char *)&(data->flags));
-    swap2((char *)&(data->pendingtime));
-  }
-  
-  if (data->logversion != 1)
-    pout("SMART Selective Self-Test Log Data Structure Revision Number (%d) should be 1\n", data->logversion);
-  
-  return 0;
-}
-
-// Writes the selective self-test log (log #9)
-int ataWriteSelectiveSelfTestLog(int device, struct ata_smart_values *sv){   
-  int i;
-  struct ata_selective_self_test_log sstlog, *data=&sstlog;
-  unsigned char cksum=0;
-  unsigned char *ptr=(unsigned char *)data;
-  
-  // Read log
-  if (ataReadSelectiveSelfTestLog(device, data)) {
-    pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
-    return -1;
-  }
-  
-  // Fix logversion if needed
-  if (data->logversion !=1) {
-    pout("Error SMART Selective Self-Test Log Data Structure Revision not recognized\n"
-	 "Revision number should be 1 but is %d.  To be safe, aborting WRITE LOG\n", data->logversion);
-    return -2;
-  }
-
-  // Host is NOT allowed to write selective self-test log if a selective
-  // self-test is in progress.
-  if (0<data->currentspan && data->currentspan<6 && ((sv->self_test_exec_status)>>4)==15) {
-    pout("Error SMART Selective or other Self-Test in progress.\n");
-    return -4;
-  }
-  
-  // Clear spans
-  for (i=0; i<5; i++)
-    memset(data->span+i, 0, sizeof(struct test_span));
-  
-  // Set spans for testing 
-  for (i=0; i<con->smartselectivenumspans; i++){
-    data->span[i].start = con->smartselectivespan[i][0];
-    data->span[i].end   = con->smartselectivespan[i][1];
-  }
-
-  // host must initialize to zero before initiating selective self-test
-  data->currentlba=0;
-  data->currentspan=0;
-  
-  // Perform off-line scan after selective test?
-  if (1 == con->scanafterselect)
-    // NO
-    data->flags &= ~SELECTIVE_FLAG_DOSCAN;
-  else if (2 == con->scanafterselect)
-    // YES
-    data->flags |= SELECTIVE_FLAG_DOSCAN;
-  
-  // Must clear active and pending flags before writing
-  data->flags &= ~(SELECTIVE_FLAG_ACTIVE);  
-  data->flags &= ~(SELECTIVE_FLAG_PENDING);
-
-  // modify pending time?
-  if (con->pendingtime)
-    data->pendingtime=(unsigned short)(con->pendingtime-1);
-
-  // Set checksum to zero, then compute checksum
-  data->checksum=0;
-  for (i=0; i<512; i++)
-    cksum+=ptr[i];
-  cksum=~cksum;
-  cksum+=1;
-  data->checksum=cksum;
-
-    // swap endian order if needed
-  if (isbigendian()){
-    int i;
-    swap2((char *)&(data->logversion));
-    for (i=0;i<5;i++){
-      swap8((char *)&(data->span[i].start));
-      swap8((char *)&(data->span[i].end));
-    }
-    swap8((char *)&(data->currentlba));
-    swap2((char *)&(data->currentspan));
-    swap2((char *)&(data->flags));
-    swap2((char *)&(data->pendingtime));
-  }
-
-  // write new selective self-test log
-  if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){
-    syserror("Error Write Selective Self-Test Log failed");
-    return -3;
-  }
-
-  return 0;
-}
-
-// This corrects some quantities that are byte reversed in the SMART
-// ATA ERROR LOG.
-void fixsamsungerrorlog(struct ata_smart_errorlog *data){
-  int i,j;
-  
-  // FIXED IN SAMSUNG -25 FIRMWARE???
-  // Device error count in bytes 452-3
-  swap2((char *)&(data->ata_error_count));
-  
-  // FIXED IN SAMSUNG -22a FIRMWARE
-  // step through 5 error log data structures
-  for (i=0; i<5; i++){
-    // step through 5 command data structures
-    for (j=0; j<5; j++)
-      // Command data structure 4-byte millisec timestamp.  These are
-      // bytes (N+8, N+9, N+10, N+11).
-      swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
-    // Error data structure two-byte hour life timestamp.  These are
-    // bytes (N+28, N+29).
-    swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
-  }
-  return;
-}
-
-// NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
-void fixsamsungerrorlog2(struct ata_smart_errorlog *data){
-  // Device error count in bytes 452-3
-  swap2((char *)&(data->ata_error_count));
-  return;
-}
-
-// Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
-// Error Log is #2, and the Extended Comprehensive SMART Error log is
-// #3
-int ataReadErrorLog (int device, struct ata_smart_errorlog *data){      
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){
-    syserror("Error SMART Error Log Read failed");
-    return -1;
-  }
-  
-  // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART ATA Error Log Structure");
-  
-  // Some disks have the byte order reversed in some SMART Summary
-  // Error log entries
-  if (con->fixfirmwarebug == FIX_SAMSUNG)
-    fixsamsungerrorlog(data);
-  else if (con->fixfirmwarebug == FIX_SAMSUNG2)
-    fixsamsungerrorlog2(data);
-
-  // Correct endian order if necessary
-  if (isbigendian()){
-    int i,j;
-    
-    // Device error count in bytes 452-3
-    swap2((char *)&(data->ata_error_count));
-    
-    // step through 5 error log data structures
-    for (i=0; i<5; i++){
-      // step through 5 command data structures
-      for (j=0; j<5; j++)
-        // Command data structure 4-byte millisec timestamp
-        swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
-      // Error data structure life timestamp
-      swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
-    }
-  }
-  
-  return 0;
-}
-
-int ataReadSmartThresholds (int device, struct ata_smart_thresholds_pvt *data){
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
-    syserror("Error SMART Thresholds Read failed");
-    return -1;
-  }
-  
-  // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART Attribute Thresholds Structure");
-  
-  // byte swap if needed
-  if (isbigendian())
-    swap2((char *)&(data->revnumber));
-
-  return 0;
-}
-
-int ataEnableSmart (int device ){       
-  if (smartcommandhandler(device, ENABLE, 0, NULL)){
-    syserror("Error SMART Enable failed");
-    return -1;
-  }
-  return 0;
-}
-
-int ataDisableSmart (int device ){      
-  
-  if (smartcommandhandler(device, DISABLE, 0, NULL)){
-    syserror("Error SMART Disable failed");
-    return -1;
-  }  
-  return 0;
-}
-
-int ataEnableAutoSave(int device){  
-  if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
-    syserror("Error SMART Enable Auto-save failed");
-    return -1;
-  }
-  return 0;
-}
-
-int ataDisableAutoSave(int device){
-  
-  if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
-    syserror("Error SMART Disable Auto-save failed");
-    return -1;
-  }
-  return 0;
-}
-
-// In *ALL* ATA standards the Enable/Disable AutoOffline command is
-// marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
-// vendors still support it for backwards compatibility. IBM documents
-// it for some drives.
-int ataEnableAutoOffline (int device ){ 
-  
-  /* timer hard coded to 4 hours */  
-  if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
-    syserror("Error SMART Enable Automatic Offline failed");
-    return -1;
-  }
-  return 0;
-}
-
-// Another Obsolete Command.  See comments directly above, associated
-// with the corresponding Enable command.
-int ataDisableAutoOffline (int device ){        
-  
-  if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
-    syserror("Error SMART Disable Automatic Offline failed");
-    return -1;
-  }
-  return 0;
-}
-
-// If SMART is enabled, supported, and working, then this call is
-// guaranteed to return 1, else zero.  Silent inverse of
-// ataSmartStatus()
-int ataDoesSmartWork(int device){       
-  return !smartcommandhandler(device, STATUS, 0, NULL);
-}
-
-// This function uses a different interface (DRIVE_TASK) than the
-// other commands in this file.
-int ataSmartStatus2(int device){
-  return smartcommandhandler(device, STATUS_CHECK, 0, NULL);  
-}
-
-// This is the way to execute ALL tests: offline, short self-test,
-// extended self test, with and without captive mode, etc.
-int ataSmartTest(int device, int testtype, struct ata_smart_values *sv) {     
-  char cmdmsg[128],*type,*captive;
-  int errornum, cap, retval, select=0;
-
-  // Boolean, if set, says test is captive
-  cap=testtype & CAPTIVE_MASK;
-
-  // Set up strings that describe the type of test
-  if (cap)
-    captive="captive";
-  else
-    captive="off-line";
-  
-  if (testtype==OFFLINE_FULL_SCAN)
-    type="off-line";
-  else  if (testtype==SHORT_SELF_TEST || testtype==SHORT_CAPTIVE_SELF_TEST)
-    type="Short self-test";
-  else if (testtype==EXTEND_SELF_TEST || testtype==EXTEND_CAPTIVE_SELF_TEST)
-    type="Extended self-test";
-  else if (testtype==CONVEYANCE_SELF_TEST || testtype==CONVEYANCE_CAPTIVE_SELF_TEST)
-    type="Conveyance self-test";
-  else if ((select=(testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)))
-    type="Selective self-test";
-  else
-    type="[Unrecognized] self-test";
-  
-  // If doing a selective self-test, first use WRITE_LOG to write the
-  // selective self-test log.
-  if (select && (retval=ataWriteSelectiveSelfTestLog(device, sv))) {
-    if (retval==-4)
-      pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
-    return retval;
-  }
-
-  //  Print ouf message that we are sending the command to test
-  if (testtype==ABORT_SELF_TEST)
-    sprintf(cmdmsg,"Abort SMART off-line mode self-test routine");
-  else
-    sprintf(cmdmsg,"Execute SMART %s routine immediately in %s mode",type,captive);
-  pout("Sending command: \"%s\".\n",cmdmsg);
-
-  if (select) {
-    int i;
-    pout("SPAN         STARTING_LBA           ENDING_LBA\n");
-    for (i = 0; i < con->smartselectivenumspans; i++)
-      pout("   %d %20"PRId64" %20"PRId64"\n", i,
-           con->smartselectivespan[i][0],
-           con->smartselectivespan[i][1]);
-  }
-  
-  // Now send the command to test
-  errornum=smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL);
-  
-  if (errornum && !(cap && errno==EIO)){
-    char errormsg[128];
-    sprintf(errormsg,"Command \"%s\" failed",cmdmsg); 
-    syserror(errormsg);
-    pout("\n");
-    return -1;
-  }
-  
-  // Since the command succeeded, tell user
-  if (testtype==ABORT_SELF_TEST)
-    pout("Self-testing aborted!\n");
-  else
-    pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg);
-  return 0;
-}
-
-/* Test Time Functions */
-int TestTime(struct ata_smart_values *data,int testtype){
-  switch (testtype){
-  case OFFLINE_FULL_SCAN:
-    return (int) data->total_time_to_complete_off_line;
-  case SHORT_SELF_TEST:
-  case SHORT_CAPTIVE_SELF_TEST:
-    return (int) data->short_test_completion_time;
-  case EXTEND_SELF_TEST:
-  case EXTEND_CAPTIVE_SELF_TEST:
-    return (int) data->extend_test_completion_time;
-  case CONVEYANCE_SELF_TEST:
-  case CONVEYANCE_CAPTIVE_SELF_TEST:
-    return (int) data->conveyance_test_completion_time;
-  default:
-    return 0;
-  }
-}
-
-// This function tells you both about the ATA error log and the
-// self-test error log capability (introduced in ATA-5).  The bit is
-// poorly documented in the ATA/ATAPI standard.  Starting with ATA-6,
-// SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
-// word 84 and 87.  Top two bits must match the pattern 01. BEFORE
-// ATA-6 these top two bits still had to match the pattern 01, but the
-// remaining bits were reserved (==0).
-int isSmartErrorLogCapable (struct ata_smart_values *data, struct ata_identify_device *identity){
-
-  unsigned short word84=identity->command_set_extension;
-  unsigned short word87=identity->csf_default;
-  int isata6=identity->major_rev_num & (0x01<<6);
-  int isata7=identity->major_rev_num & (0x01<<7);
-
-  if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x01))
-    return 1;
-  
-  if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x01))
-    return 1;
-  
-  // otherwise we'll use the poorly documented capability bit
-  return data->errorlog_capability & 0x01;
-}
-
-// See previous function.  If the error log exists then the self-test
-// log should (must?) also exist.
-int isSmartTestLogCapable (struct ata_smart_values *data, struct ata_identify_device *identity){
-
-  unsigned short word84=identity->command_set_extension;
-  unsigned short word87=identity->csf_default;
-  int isata6=identity->major_rev_num & (0x01<<6);
-  int isata7=identity->major_rev_num & (0x01<<7);
-
-  if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x02))
-    return 1;
-  
-  if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x02))
-    return 1;
-
-
-  // otherwise we'll use the poorly documented capability bit
-    return data->errorlog_capability & 0x01;
-}
-
-
-int isGeneralPurposeLoggingCapable(struct ata_identify_device *identity){
-  unsigned short word84=identity->command_set_extension;
-  unsigned short word87=identity->csf_default;
-
-  // If bit 14 of word 84 is set to one and bit 15 of word 84 is
-  // cleared to zero, the contents of word 84 contains valid support
-  // information. If not, support information is not valid in this
-  // word.
-  if ((word84>>14) == 0x01)
-    // If bit 5 of word 84 is set to one, the device supports the
-    // General Purpose Logging feature set.
-    return (word84 & (0x01 << 5));
-  
-  // If bit 14 of word 87 is set to one and bit 15 of word 87 is
-  // cleared to zero, the contents of words (87:85) contain valid
-  // information. If not, information is not valid in these words.  
-  if ((word87>>14) == 0x01)
-    // If bit 5 of word 87 is set to one, the device supports
-    // the General Purpose Logging feature set.
-    return (word87 & (0x01 << 5));
-
-  // not capable
-  return 0;
-}
-
-
-// SMART self-test capability is also indicated in bit 1 of DEVICE
-// IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
-// However this was only introduced in ATA-6 (but self-test log was in
-// ATA-5).
-int isSupportExecuteOfflineImmediate(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x01;
-}
-// Note in the ATA-5 standard, the following bit is listed as "Vendor
-// Specific".  So it may not be reliable. The only use of this that I
-// have found is in IBM drives, where it is well-documented.  See for
-// example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
-// hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
-int isSupportAutomaticTimer(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x02;
-}
-int isSupportOfflineAbort(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x04;
-}
-int isSupportOfflineSurfaceScan(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x08;
-}
-int isSupportSelfTest (struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x10;
-}
-int isSupportConveyanceSelfTest(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x20;
-}
-int isSupportSelectiveSelfTest(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x40;
-}
-
-
-
-// Loop over all valid attributes.  If they are prefailure attributes
-// and are at or below the threshold value, then return the ID of the
-// first failing attribute found.  Return 0 if all prefailure
-// attributes are in bounds.  The spec says "Bit 0
-// -Pre-failure/advisory - If the value of this bit equals zero, an
-// attribute value less than or equal to its corresponding attribute
-// threshold indicates an advisory condition where the usage or age of
-// the device has exceeded its intended design life period. If the
-// value of this bit equals one, an atribute value less than or equal
-// to its corresponding attribute threshold indicates a pre-failure
-// condition where imminent loss of data is being predicted."
-
-
-// onlyfailed=0 : are or were any age or prefailure attributes <= threshold
-// onlyfailed=1:  are any prefailure attributes <= threshold now
-int ataCheckSmart(struct ata_smart_values *data,
-                  struct ata_smart_thresholds_pvt *thresholds,
-                  int onlyfailed){
-  int i;
-  
-  // loop over all attributes
-  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-
-    // pointers to disk's values and vendor's thresholds
-    struct ata_smart_attribute *disk=data->vendor_attributes+i;
-    struct ata_smart_threshold_entry *thre=thresholds->thres_entries+i;
- 
-    // consider only valid attributes
-    if (disk->id && thre->id){
-      int failednow,failedever;
-      
-      failednow =disk->current <= thre->threshold;
-      failedever=disk->worst   <= thre->threshold;
-      
-      if (!onlyfailed && failedever)
-        return disk->id;
-      
-      if (onlyfailed && failednow && ATTRIBUTE_FLAGS_PREFAILURE(disk->flags))
-        return disk->id;      
-    }
-  }
-  return 0;
-}
-
-
-
-// This checks the n'th attribute in the attribute list, NOT the
-// attribute with id==n.  If the attribute does not exist, or the
-// attribute is > threshold, then returns zero.  If the attribute is
-// <= threshold (failing) then we the attribute number if it is a
-// prefail attribute.  Else we return minus the attribute number if it
-// is a usage attribute.
-int ataCheckAttribute(struct ata_smart_values *data,
-                      struct ata_smart_thresholds_pvt *thresholds,
-                      int n){
-  struct ata_smart_attribute *disk;
-  struct ata_smart_threshold_entry *thre;
-  
-  if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !data || !thresholds)
-    return 0;
-  
-  // pointers to disk's values and vendor's thresholds
-  disk=data->vendor_attributes+n;
-  thre=thresholds->thres_entries+n;
-
-  if (!disk || !thre)
-    return 0;
-  
-  // consider only valid attributes, check for failure
-  if (!disk->id || !thre->id || (disk->id != thre->id) || disk->current> thre->threshold)
-    return 0;
-  
-  // We have found a failed attribute.  Return positive or negative? 
-  if (ATTRIBUTE_FLAGS_PREFAILURE(disk->flags))
-    return disk->id;
-  else
-    return -1*(disk->id);
-}
-
-
-// This routine prints the raw value of an attribute as a text string
-// into out. It also returns this 48-bit number as a long long.  The
-// array defs[] contains non-zero values if particular attributes have
-// non-default interpretations.
-
-int64_t ataPrintSmartAttribRawValue(char *out, 
-                                    struct ata_smart_attribute *attribute,
-                                    unsigned char *defs){
-  int64_t rawvalue;
-  unsigned word[3];
-  int j;
-  unsigned char select;
-  
-  // convert the six individual bytes to a long long (8 byte) integer.
-  // This is the value that we'll eventually return.
-  rawvalue = 0;
-  for (j=0; j<6; j++) {
-    // This looks a bit roundabout, but is necessary.  Don't
-    // succumb to the temptation to use raw[j]<<(8*j) since under
-    // the normal rules this will be promoted to the native type.
-    // On a 32 bit machine this might then overflow.
-    int64_t temp;
-    temp = attribute->raw[j];
-    temp <<= 8*j;
-    rawvalue |= temp;
-  }
-
-  // convert quantities to three two-byte words
-  for (j=0; j<3; j++){
-    word[j] = attribute->raw[2*j+1];
-    word[j] <<= 8;
-    word[j] |= attribute->raw[2*j];
-  }
-  
-  // if no data array, Attributes have default interpretations
-  if (defs)
-    select=defs[attribute->id];
-  else
-    select=0;
-
-  // Print six one-byte quantities.
-  if (select==253){
-    for (j=0; j<5; j++)
-      out+=sprintf(out, "%d ", attribute->raw[5-j]);
-    out+=sprintf(out, "%d ", attribute->raw[0]);
-    return rawvalue;
-  } 
-  
-  // Print three two-byte quantities
-  if (select==254){
-    out+=sprintf(out, "%d %d %d", word[2], word[1], word[0]); 
-    return rawvalue;
-  } 
-  
-  // Print one six-byte quantity
-  if (select==255){
-    out+=sprintf(out, "%"PRIu64, rawvalue);
-    return rawvalue;
-  }
-
-  // This switch statement is where we handle Raw attributes
-  // that are stored in an unusual vendor-specific format,
-  switch (attribute->id){
-    // Spin-up time
-  case 3:
-    out+=sprintf(out, "%d", word[0]);
-    // if second nonzero then it stores the average spin-up time
-    if (word[1])
-      out+=sprintf(out, " (Average %d)", word[1]);
-    break;
-    // Power on time
-  case 9:
-    if (select==1){
-      // minutes
-      int64_t tmp1=rawvalue/60;
-      int64_t tmp2=rawvalue%60;
-      out+=sprintf(out, "%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2);
-    }
-    else if (select==3){
-      // seconds
-      int64_t hours=rawvalue/3600;
-      int64_t minutes=(rawvalue-3600*hours)/60;
-      int64_t seconds=rawvalue%60;
-      out+=sprintf(out, "%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds);
-    }
-    else if (select==4){
-      // 30-second counter
-      int64_t tmp1=rawvalue/120;
-      int64_t tmp2=(rawvalue-120*tmp1)/2;
-      out+=sprintf(out, "%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2);
-    }
-    else
-      // hours
-      out+=sprintf(out, "%"PRIu64, rawvalue);  //stored in hours
-    break;
-   // Load unload cycles
-  case 193:
-    if (select==1){
-      // loadunload
-      long load  =attribute->raw[0] + (attribute->raw[1]<<8) + (attribute->raw[2]<<16);
-      long unload=attribute->raw[3] + (attribute->raw[4]<<8) + (attribute->raw[5]<<16);
-      out+=sprintf(out, "%lu/%lu", load, unload);
-    }
-    else
-      // associated
-      out+=sprintf(out, "%"PRIu64, rawvalue);
-    break;
-    // Temperature
-  case 194:
-    if (select==1){
-      // ten times temperature in Celsius
-      int deg=word[0]/10;
-      int tenths=word[0]%10;
-      out+=sprintf(out, "%d.%d", deg, tenths);
-    }
-    else if (select==2)
-      // unknown attribute
-      out+=sprintf(out, "%"PRIu64, rawvalue);
-    else {
-      out+=sprintf(out, "%d", word[0]);
-      if (!(rawvalue==word[0])) {
-	int min=word[1]<word[2]?word[1]:word[2];
-	int max=word[1]>word[2]?word[1]:word[2];
-        // The other bytes are in use. Try IBM's model
-        out+=sprintf(out, " (Lifetime Min/Max %d/%d)", min, max);
-      }
-    }
-    break;
-  default:
-    out+=sprintf(out, "%"PRIu64, rawvalue);
-  }
-  
-  // Return the full value
-  return rawvalue;
-}
-
-
-// Note some attribute names appear redundant because different
-// manufacturers use different attribute IDs for an attribute with the
-// same name.  The variable val should contain a non-zero value if a particular
-// attributes has a non-default interpretation.
-void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *definitions){
-  char *name;
-  unsigned char val;
-
-  // If no data array, use default interpretations
-  if (definitions)
-    val=definitions[id];
-  else
-    val=0;
-
-  switch (id){
-    
-  case 1:
-    name="Raw_Read_Error_Rate";
-    break;
-  case 2:
-    name="Throughput_Performance";
-    break;
-  case 3:
-    name="Spin_Up_Time";
-    break;
-  case 4:
-    name="Start_Stop_Count";
-    break;
-  case 5:
-    name="Reallocated_Sector_Ct";
-    break;
-  case 6:
-    name="Read_Channel_Margin";
-    break;
-  case 7:
-    name="Seek_Error_Rate";
-    break;
-  case 8:
-    name="Seek_Time_Performance";
-    break;
-  case 9:
-    switch (val) {
-    case 1:
-      name="Power_On_Minutes";
-      break;
-    case 2:
-      name="Temperature_Celsius";
-      break;
-    case 3:
-      name="Power_On_Seconds";
-      break;
-    case 4:
-      name="Power_On_Half_Minutes";
-      break;
-    default:
-      name="Power_On_Hours";
-      break;
-    }
-    break;
-  case 10:
-    name="Spin_Retry_Count";
-    break;
-  case 11:
-    name="Calibration_Retry_Count";
-    break;
-  case 12:
-    name="Power_Cycle_Count";
-    break;
-  case 13:
-    name="Read_Soft_Error_Rate";
-    break;
-  case 191:
-    name="G-Sense_Error_Rate";
-    break;
-  case 192:
-    switch (val) {
-    case 1:
-      // Fujitsu
-      name="Emergency_Retract_Cycle_Ct";
-      break;
-    default:
-      name="Power-Off_Retract_Count";
-      break;
-    }
-    break;
-  case 193:
-    name="Load_Cycle_Count";
-    break;
-  case 194:
-    switch (val){
-    case 1:
-      // Samsung SV1204H with RK100-13 firmware
-      name="Temperature_Celsius_x10";
-      break;
-    case 2:
-      // for disks with no temperature Attribute
-      name="Unknown_Attribute";
-      break;
-    default:
-      name="Temperature_Celsius";
-      break;
-    }
-    break;
-  case 195:
-    // Fujitsu name="ECC_On_The_Fly_Count";
-    name="Hardware_ECC_Recovered";
-    break;
-  case 196:
-    name="Reallocated_Event_Count";
-    break;
-  case 197:
-    name="Current_Pending_Sector";
-    break;
-  case 198:
-    switch (val){
-    case 1:
-      // Fujitsu
-      name="Off-line_Scan_UNC_Sector_Ct";
-      break;
-    default:
-      name="Offline_Uncorrectable";
-      break;
-    }
-    break;
-  case 199:
-    name="UDMA_CRC_Error_Count";
-    break;
-  case 200:
-    switch (val) {
-    case 1:
-      // Fujitsu MHS2020AT
-      name="Write_Error_Count";
-      break;
-    default:
-      // Western Digital
-      name="Multi_Zone_Error_Rate";
-      break;
-    }
-    break;
-  case 201:
-    switch (val) {
-    case 1:
-      // Fujitsu
-      name="Detected_TA_Count";
-      break;
-    default:
-      name="Soft_Read_Error_Rate";
-      break;
-    }
-    break;
-  case 202:
-    // Fujitsu
-    name="TA_Increase_Count";
-    // Maxtor: Data Address Mark Errors
-    break;
-  case 203:
-    // Fujitsu
-    name="Run_Out_Cancel";
-    // Maxtor: ECC Errors
-    break;
-  case 204:
-    // Fujitsu
-    name="Shock_Count_Write_Opern";
-    // Maxtor: Soft ECC Correction
-    break;
-  case 205:
-    // Fujitsu
-    name="Shock_Rate_Write_Opern";
-    // Maxtor: Thermal Aspirates
-    break;
-  case 206:
-    // Fujitsu
-    name="Flying_Height";
-    break;
-  case 207:
-    // Maxtor
-    name="Spin_High_Current";
-    break;
-  case 208:
-    // Maxtor
-    name="Spin_Buzz";
-    break;
-  case 209:
-    // Maxtor
-    name="Offline_Seek_Performnce";
-    break;
-  case 220:
-    switch (val) {
-    case 1:
-      name="Temperature_Celsius";
-      break;
-    default:
-      name="Disk_Shift";
-      break;
-    }
-    break;
-  case 221:
-    name="G-Sense_Error_Rate";
-    break;
-  case 222:
-    name="Loaded_Hours";
-    break;
-  case 223:
-    name="Load_Retry_Count";
-    break;
-  case 224:
-    name="Load_Friction";
-    break;
-  case 225:
-    name="Load_Cycle_Count";
-    break;
-  case 226:
-    name="Load-in_Time";
-    break;
-  case 227:
-    name="Torq-amp_Count";
-    break;
-  case 228:
-    name="Power-off_Retract_Count";
-    break;
-  case 230:
-    // seen in IBM DTPA-353750
-    name="Head_Amplitude";
-    break;
-  case 231:
-    name="Temperature_Celsius";
-    break;
-  case 240:
-    name="Head_Flying_Hours";
-    break;
-  case 250:
-    name="Read_Error_Retry_Rate";
-    break;
-  default:
-    name="Unknown_Attribute";
-    break;
-  }
-  sprintf(out,"%3hu %s",(short int)id,name);
-  return;
-}
-
-// Returns raw value of Attribute with ID==id. This will be in the
-// range 0 to 2^48-1 inclusive.  If the Attribute does not exist,
-// return -1.
-int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *data) {
-  int i;
-
-  // valid Attribute IDs are in the range 1 to 255 inclusive.
-  if (!id || !data)
-    return -1;
-  
-  // loop over Attributes to see if there is one with the desired ID
-  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++) {
-    struct ata_smart_attribute *this = data->vendor_attributes + i;
-    if (this->id == id) {
-      // we've found the desired Attribute.  Return its value
-      int64_t rawvalue=0;
-      int j;
-
-      for (j=0; j<6; j++) {
-	// This looks a bit roundabout, but is necessary.  Don't
-	// succumb to the temptation to use raw[j]<<(8*j) since under
-	// the normal rules this will be promoted to the native type.
-	// On a 32 bit machine this might then overflow.
-	int64_t temp;
-	temp = this->raw[j];
-	temp <<= 8*j;
-	rawvalue |= temp;
-      } // loop over j
-      return rawvalue;
-    } // found desired Attribute
-  } // loop over Attributes
-  
-  // fall-through: no such Attribute found
-  return -1;
-}
-
-
diff --git a/sm5/atacmds.h b/sm5/atacmds.h
deleted file mode 100644
index 4b5b710bc12b5427934388aa3a7c8dd0d49f49d1..0000000000000000000000000000000000000000
--- a/sm5/atacmds.h
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * atacmds.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef ATACMDS_H_
-#define ATACMDS_H_
-
-#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.72 2004/07/26 21:15:21 ballen4705 Exp $\n"
-
-#include "int64.h"
-
-typedef enum {
-  // returns no data, just succeeds or fails
-  ENABLE,
-  DISABLE,
-  AUTOSAVE,
-  IMMEDIATE_OFFLINE,
-  AUTO_OFFLINE,
-  STATUS,       // just says if SMART is working or not
-  STATUS_CHECK, // says if disk's SMART status is healthy, or failing
-  // return 512 bytes of data:
-  READ_VALUES,
-  READ_THRESHOLDS,
-  READ_LOG,
-  IDENTIFY,
-  PIDENTIFY,
-  // returns 1 byte of data
-  CHECK_POWER_MODE,
-  // writes 512 bytes of data:
-  WRITE_LOG
-} smart_command_set;
-
-// ATA Specification Command Register Values (Commands)
-#define ATA_IDENTIFY_DEVICE             0xec                                              
-#define ATA_IDENTIFY_PACKET_DEVICE      0xa1
-#define ATA_SMART_CMD                   0xb0
-#define ATA_CHECK_POWER_MODE            0xe5
-
-// ATA Specification Feature Register Values (SMART Subcommands).
-// Note that some are obsolete as of ATA-7.
-#define ATA_SMART_READ_VALUES           0xd0
-#define ATA_SMART_READ_THRESHOLDS       0xd1
-#define ATA_SMART_AUTOSAVE              0xd2
-#define ATA_SMART_SAVE                  0xd3
-#define ATA_SMART_IMMEDIATE_OFFLINE     0xd4
-#define ATA_SMART_READ_LOG_SECTOR       0xd5
-#define ATA_SMART_WRITE_LOG_SECTOR      0xd6
-#define ATA_SMART_WRITE_THRESHOLDS      0xd7
-#define ATA_SMART_ENABLE                0xd8
-#define ATA_SMART_DISABLE               0xd9
-#define ATA_SMART_STATUS                0xda
-// SFF 8035i Revision 2 Specification Feature Register Value (SMART
-// Subcommand)
-#define ATA_SMART_AUTO_OFFLINE          0xdb
-
-// Sector Number values for ATA_SMART_IMMEDIATE_OFFLINE Subcommand
-#define OFFLINE_FULL_SCAN               0
-#define SHORT_SELF_TEST                 1
-#define EXTEND_SELF_TEST                2
-#define CONVEYANCE_SELF_TEST            3
-#define SELECTIVE_SELF_TEST             4
-#define ABORT_SELF_TEST                 127
-#define SHORT_CAPTIVE_SELF_TEST         129
-#define EXTEND_CAPTIVE_SELF_TEST        130
-#define CONVEYANCE_CAPTIVE_SELF_TEST    131
-#define SELECTIVE_CAPTIVE_SELF_TEST     132
-#define CAPTIVE_MASK                    (0x01<<7)
-
-// Maximum allowed number of SMART Attributes
-#define NUMBER_ATA_SMART_ATTRIBUTES     30
-
-// Needed parts of the ATA DRIVE IDENTIFY Structure. Those labeled
-// word* are NOT used.
-#pragma pack(1)
-struct ata_identify_device {
-  unsigned short words000_009[10];
-  unsigned char  serial_no[20];
-  unsigned short words020_022[3];
-  unsigned char  fw_rev[8];
-  unsigned char  model[40];
-  unsigned short words047_079[33];
-  unsigned short major_rev_num;
-  unsigned short minor_rev_num;
-  unsigned short command_set_1;
-  unsigned short command_set_2;
-  unsigned short command_set_extension;
-  unsigned short cfs_enable_1;
-  unsigned short word086;
-  unsigned short csf_default;
-  unsigned short words088_255[168];
-};
-#pragma pack()
-
-/* ata_smart_attribute is the vendor specific in SFF-8035 spec */ 
-#pragma pack(1)
-struct ata_smart_attribute {
-  unsigned char id;
-  // meaning of flag bits: see MACROS just below
-  // WARNING: MISALIGNED!
-  unsigned short flags; 
-  unsigned char current;
-  unsigned char worst;
-  unsigned char raw[6];
-  unsigned char reserv;
-};
-#pragma pack()
-
-// MACROS to interpret the flags bits in the previous structure.
-// These have not been implemented using bitflags and a union, to make
-// it portable across bit/little endian and different platforms.
-
-// 0: Prefailure bit
-
-// From SFF 8035i Revision 2 page 19: Bit 0 (pre-failure/advisory bit)
-// - If the value of this bit equals zero, an attribute value less
-// than or equal to its corresponding attribute threshold indicates an
-// advisory condition where the usage or age of the device has
-// exceeded its intended design life period. If the value of this bit
-// equals one, an attribute value less than or equal to its
-// corresponding attribute threshold indicates a prefailure condition
-// where imminent loss of data is being predicted.
-#define ATTRIBUTE_FLAGS_PREFAILURE(x) (x & 0x01)
-
-// 1: Online bit 
-
-//  From SFF 8035i Revision 2 page 19: Bit 1 (on-line data collection
-// bit) - If the value of this bit equals zero, then the attribute
-// value is updated only during off-line data collection
-// activities. If the value of this bit equals one, then the attribute
-// value is updated during normal operation of the device or during
-// both normal operation and off-line testing.
-#define ATTRIBUTE_FLAGS_ONLINE(x) (x & 0x02)
-
-
-// The following are (probably) IBM's, Maxtors and  Quantum's definitions for the
-// vendor-specific bits:
-// 2: Performance type bit
-#define ATTRIBUTE_FLAGS_PERFORMANCE(x) (x & 0x04)
-
-// 3: Errorrate type bit
-#define ATTRIBUTE_FLAGS_ERRORRATE(x) (x & 0x08)
-
-// 4: Eventcount bit
-#define ATTRIBUTE_FLAGS_EVENTCOUNT(x) (x & 0x10)
-
-// 5: Selfpereserving bit
-#define ATTRIBUTE_FLAGS_SELFPRESERVING(x) (x & 0x20)
-
-
-// Last ten bits are reserved for future use
-
-/* ata_smart_values is format of the read drive Attribute command */
-/* see Table 34 of T13/1321D Rev 1 spec (Device SMART data structure) for *some* info */
-#pragma pack(1)
-struct ata_smart_values {
-  unsigned short int revnumber;
-  struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES];
-  unsigned char offline_data_collection_status;
-  unsigned char self_test_exec_status;  //IBM # segments for offline collection
-  unsigned short int total_time_to_complete_off_line; // IBM different
-  unsigned char vendor_specific_366; // Maxtor & IBM curent segment pointer
-  unsigned char offline_data_collection_capability;
-  unsigned short int smart_capability;
-  unsigned char errorlog_capability;
-  unsigned char vendor_specific_371;  // Maxtor, IBM: self-test failure checkpoint see below!
-  unsigned char short_test_completion_time;
-  unsigned char extend_test_completion_time;
-  unsigned char conveyance_test_completion_time;
-  unsigned char reserved_375_385[11];
-  unsigned char vendor_specific_386_510[125]; // Maxtor bytes 508-509 Attribute/Threshold Revision #
-  unsigned char chksum;
-}; 
-#pragma pack()
-
-/* Maxtor, IBM: self-test failure checkpoint byte meaning:
- 00 - write test
- 01 - servo basic
- 02 - servo random
- 03 - G-list scan
- 04 - Handling damage
- 05 - Read scan
-*/
-
-/* Vendor attribute of SMART Threshold (compare to ata_smart_attribute above) */
-#pragma pack(1)
-struct ata_smart_threshold_entry {
-  unsigned char id;
-  unsigned char threshold;
-  unsigned char reserved[10];
-};
-#pragma pack()
-
-/* Format of Read SMART THreshold Command */
-/* Compare to ata_smart_values above */
-#pragma pack(1)
-struct ata_smart_thresholds_pvt {
-  unsigned short int revnumber;
-  struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES];
-  unsigned char reserved[149];
-  unsigned char chksum;
-};
-#pragma pack()
-
-
-// Table 42 of T13/1321D Rev 1 spec (Error Data Structure)
-#pragma pack(1)
-struct ata_smart_errorlog_error_struct {
-  unsigned char reserved;
-  unsigned char error_register;
-  unsigned char sector_count;
-  unsigned char sector_number;
-  unsigned char cylinder_low;
-  unsigned char cylinder_high;
-  unsigned char drive_head;
-  unsigned char status;
-  unsigned char extended_error[19];
-  unsigned char state;
-  unsigned short timestamp;
-};
-#pragma pack()
-
-
-// Table 41 of T13/1321D Rev 1 spec (Command Data Structure)
-#pragma pack(1)
-struct ata_smart_errorlog_command_struct {
-  unsigned char devicecontrolreg;
-  unsigned char featuresreg;
-  unsigned char sector_count;
-  unsigned char sector_number;
-  unsigned char cylinder_low;
-  unsigned char cylinder_high;
-  unsigned char drive_head;
-  unsigned char commandreg;
-  unsigned int timestamp;
-};
-#pragma pack()
-
-// Table 40 of T13/1321D Rev 1 spec (Error log data structure)
-#pragma pack(1)
-struct ata_smart_errorlog_struct {
-  struct ata_smart_errorlog_command_struct commands[5];
-  struct ata_smart_errorlog_error_struct error_struct;
-};
-#pragma pack()
-
-// Table 39 of T13/1321D Rev 1 spec (SMART error log sector)
-#pragma pack(1)
-struct ata_smart_errorlog {
-  unsigned char revnumber;
-  unsigned char error_log_pointer;
-  struct ata_smart_errorlog_struct errorlog_struct[5];
-  unsigned short int ata_error_count;
-  unsigned char reserved[57];
-  unsigned char checksum;
-};
-#pragma pack()
-
-// Table 45 of T13/1321D Rev 1 spec (Self-test log descriptor entry)
-#pragma pack(1)
-struct ata_smart_selftestlog_struct {
-  unsigned char selftestnumber; // Sector number register
-  unsigned char selfteststatus;
-  unsigned short int timestamp;
-  unsigned char selftestfailurecheckpoint;
-  unsigned int lbafirstfailure;
-  unsigned char vendorspecific[15];
-};
-#pragma pack()
-
-// Table 44 of T13/1321D Rev 1 spec (Self-test log data structure)
-#pragma pack(1)
-struct ata_smart_selftestlog {
-  unsigned short int revnumber;
-  struct ata_smart_selftestlog_struct selftest_struct[21];
-  unsigned char vendorspecific[2];
-  unsigned char mostrecenttest;
-  unsigned char reserved[2];
-  unsigned char chksum;
-};
-#pragma pack()
-
-// SMART LOG DIRECTORY Table 52 of T13/1532D Vol 1 Rev 1a
-#pragma pack(1)
-struct ata_smart_log_entry {
-  unsigned char numsectors;
-  unsigned char reserved;
-};
-#pragma pack()
-
-#pragma pack(1)
-struct ata_smart_log_directory {
-  unsigned short int logversion;
-  struct ata_smart_log_entry entry[255];
-};
-#pragma pack()
-
-// SMART SELECTIVE SELF-TEST LOG Table 61 of T13/1532D Volume 1
-// Revision 3
-#pragma pack(1)
-struct test_span {
-  uint64_t start;
-  uint64_t end;
-};
-#pragma pack()
-
-#pragma pack(1)
-struct ata_selective_self_test_log {
-  unsigned short     logversion;
-  struct test_span   span[5];
-  unsigned char      reserved1[337-82+1];
-  unsigned char      vendor_specific1[491-338+1];
-  uint64_t           currentlba;
-  unsigned short     currentspan;
-  unsigned short     flags;
-  unsigned char      vendor_specific2[507-504+1];
-  unsigned short     pendingtime;
-  unsigned char      reserved2;
-  unsigned char      checksum;
-};
-#pragma pack()
-
-#define SELECTIVE_FLAG_DOSCAN  (0x0002)
-#define SELECTIVE_FLAG_PENDING (0x0008)
-#define SELECTIVE_FLAG_ACTIVE  (0x0010)
-
-// Get information from drive
-int ataReadHDIdentity(int device, struct ata_identify_device *buf);
-int ataCheckPowerMode(int device);
-
-/* Read S.M.A.R.T information from drive */
-int ataReadSmartValues(int device,struct ata_smart_values *);
-int ataReadSmartThresholds(int device, struct ata_smart_thresholds_pvt *);
-int ataReadErrorLog(int device, struct ata_smart_errorlog *);
-int ataReadSelfTestLog(int device, struct ata_smart_selftestlog *);
-int ataReadSelectiveSelfTestLog(int device, struct ata_selective_self_test_log *data);
-int ataSmartStatus(int device);
-int ataSetSmartThresholds(int device, struct ata_smart_thresholds_pvt *);
-int ataReadLogDirectory(int device, struct ata_smart_log_directory *);  
-
-/* Enable/Disable SMART on device */
-int ataEnableSmart ( int device );
-int ataDisableSmart (int device );
-int ataEnableAutoSave(int device);
-int ataDisableAutoSave(int device);
-
-/* Automatic Offline Testing */
-int ataEnableAutoOffline ( int device );
-int ataDisableAutoOffline (int device );
-
-/* S.M.A.R.T. test commands */
-int ataSmartOfflineTest (int device);
-int ataSmartExtendSelfTest (int device);
-int ataSmartShortSelfTest (int device);
-int ataSmartShortCapSelfTest (int device);
-int ataSmartExtendCapSelfTest (int device);
-int ataSmartSelfTestAbort (int device);
-
-// Returns the latest compatibility of ATA/ATAPI Version the device
-// supports. Returns -1 if Version command is not supported
-int ataVersionInfo (const char **description, struct ata_identify_device *drive, unsigned short *minor);
-
-// If SMART supported, this is guaranteed to return 1 if SMART is enabled, else 0.
-int ataDoesSmartWork(int device);
-
-// returns 1 if SMART supported, 0 if not supported or can't tell
-int ataSmartSupport ( struct ata_identify_device *drive);
-
-// Return values:
-//  1: SMART enabled
-//  0: SMART disabled
-// -1: can't tell if SMART is enabled -- try issuing ataDoesSmartWork command to see
-int ataIsSmartEnabled(struct ata_identify_device *drive);
-
-/* Check SMART for Threshold failure */
-// onlyfailed=0 : are or were any age or prefailure attributes <= threshold
-// onlyfailed=1:  are any prefailure attributes <= threshold now
-int ataCheckSmart ( struct ata_smart_values *data, struct ata_smart_thresholds_pvt *thresholds, int onlyfailed);
-
-int ataSmartStatus2(int device);
-
-// int isOfflineTestTime ( struct ata_smart_values data)
-//  returns S.M.A.R.T. Offline Test Time in seconds
-int isOfflineTestTime ( struct ata_smart_values *data);
-
-int isShortSelfTestTime ( struct ata_smart_values *data);
-
-int isExtendedSelfTestTime ( struct ata_smart_values *data);
-
-int isSmartErrorLogCapable(struct ata_smart_values *data, struct ata_identify_device *identity);
-
-int isSmartTestLogCapable(struct ata_smart_values *data, struct ata_identify_device *identity);
-
-int isGeneralPurposeLoggingCapable(struct ata_identify_device *identity);
-
-int isSupportExecuteOfflineImmediate ( struct ata_smart_values *data);
-
-int isSupportAutomaticTimer ( struct ata_smart_values *data);
-
-int isSupportOfflineAbort ( struct ata_smart_values *data);
-
-int isSupportOfflineSurfaceScan ( struct ata_smart_values *data);
-
-int isSupportSelfTest (struct ata_smart_values *data);
-
-int isSupportConveyanceSelfTest(struct ata_smart_values *data);
-
-int isSupportSelectiveSelfTest(struct ata_smart_values *data);
-
-int ataSmartTest(int device, int testtype, struct ata_smart_values *data);
-
-int TestTime(struct ata_smart_values *data,int testtype);
-
-// Prints the raw value (with appropriate formatting) into the
-// character string out.
-int64_t ataPrintSmartAttribRawValue(char *out, 
-                                    struct ata_smart_attribute *attribute,
-                                    unsigned char *defs);
-
-// Prints Attribute Name for standard SMART attributes. Writes a
-// 30 byte string with attribute name into output
-void ataPrintSmartAttribName(char *output, unsigned char id, unsigned char *definitions);
-
-// This checks the n'th attribute in the attribute list, NOT the
-// attribute with id==n.  If the attribute does not exist, or the
-// attribute is > threshold, then returns zero.  If the attribute is
-// <= threshold (failing) then we the attribute number if it is a
-// prefail attribute.  Else we return minus the attribute number if it
-// is a usage attribute.
-int ataCheckAttribute(struct ata_smart_values *data,
-                      struct ata_smart_thresholds_pvt *thresholds,
-                      int n);
-
-// External handler function, for when a checksum is not correct.  Can
-// simply return if no action is desired, or can print error messages
-// as needed, or exit.  Is passed a string with the name of the Data
-// Structure with the incorrect checksum.
-void checksumwarning(const char *string);
-
-// Returns raw value of Attribute with ID==id. This will be in the
-// range 0 to 2^48-1 inclusive.  If the Attribute does not exist,
-// return -1.
-int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *data);
-
-
-// This are the meanings of the Self-test failure checkpoint byte.
-// This is in the self-test log at offset 4 bytes into the self-test
-// descriptor and in the SMART READ DATA structure at byte offset
-// 371. These codes are not well documented.  The meanings returned by
-// this routine are used (at least) by Maxtor and IBM. Returns NULL if
-// not recognized.
-const char *SelfTestFailureCodeName(unsigned char which);
-
-
-#define MAX_ATTRIBUTE_NUM 256
-
-extern const char *vendorattributeargs[];
-
-// function to parse pairs like "9,minutes" or "220,temp".  See end of
-// extern.h for definition of defs[].  Returns 0 if pair recognized,
-// else 1 if there is a problem.  Allocates memory for array if the
-// array address is *defs==NULL.
-int parse_attribute_def(char *pair, unsigned char **defs);
-
-// Function to return a string containing a list of the arguments in
-// vendorattributeargs[].  Returns NULL if the required memory can't
-// be allocated.
-char *create_vendor_attribute_arg_list(void);
-
-
-// These are two of the functions that are defined in os_*.c and need
-// to be ported to get smartmontools onto another OS.
-int ata_command_interface(int device, smart_command_set command, int select, char *data);
-int escalade_command_interface(int fd, int escalade_port, int escalade_type, smart_command_set command, int select, char *data);
-
-// This function is exported to give low-level capability
-int smartcommandhandler(int device, smart_command_set command, int select, char *data);
-
-// Utility routines.
-void swap2(char *location);
-void swap4(char *location);
-void swap8(char *location);
-#endif /* ATACMDS_H_ */
diff --git a/sm5/ataprint.c b/sm5/ataprint.c
deleted file mode 100644
index ba736e26e3f4915e28f712440782e6f95dc427cc..0000000000000000000000000000000000000000
--- a/sm5/ataprint.c
+++ /dev/null
@@ -1,1833 +0,0 @@
-/*
- * ataprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include "atacmdnames.h"
-#include "atacmds.h"
-#include "ataprint.h"
-#include "smartctl.h"
-#include "int64.h"
-#include "extern.h"
-#include "utility.h"
-#include "knowndrives.h"
-#include "config.h"
-
-const char *ataprint_c_cvsid="$Id: ataprint.c,v 1.155 2004/07/13 14:48:06 ballen4705 Exp $"
-ATACMDNAMES_H_CVSID ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
-// bytes.
-void swapbytes(char *out, const char *in, size_t n)
-{
-  size_t i;
-
-  for (i = 0; i < n; i += 2) {
-    out[i]   = in[i+1];
-    out[i+1] = in[i];
-  }
-}
-
-// Copies in to out, but removes leading and trailing whitespace.
-void trim(char *out, const char *in)
-{
-  int i, first, last;
-
-  // Find the first non-space character (maybe none).
-  first = -1;
-  for (i = 0; in[i]; i++)
-    if (!isspace((int)in[i])) {
-      first = i;
-      break;
-    }
-
-  if (first == -1) {
-    // There are no non-space characters.
-    out[0] = '\0';
-    return;
-  }
-
-  // Find the last non-space character.
-  for (i = strlen(in)-1; i >= first && isspace((int)in[i]); i--)
-    ;
-  last = i;
-
-  strncpy(out, in+first, last-first+1);
-  out[last-first+1] = '\0';
-}
-
-// Convenience function for formatting strings from ata_identify_device
-void formatdriveidstring(char *out, const char *in, int n)
-{
-  char tmp[65];
-
-  n = n > 64 ? 64 : n;
-  swapbytes(tmp, in, n);
-  tmp[n] = '\0';
-  trim(out, tmp);
-}
-
-// Function for printing ASCII byte-swapped strings, skipping white
-// space. Please note that this is needed on both big- and
-// little-endian hardware.
-void printswap(char *output, char *in, unsigned int n){
-  formatdriveidstring(output, in, n);
-  if (*output)
-    pout("%s\n", output);
-  else
-    pout("[No Information Found]\n");
-}
-
-/* For the given Command Register (CR) and Features Register (FR), attempts
- * to construct a string that describes the contents of the Status
- * Register (ST) and Error Register (ER).  The string is dynamically allocated
- * memory and the return value is a pointer to this string.  It is up to the
- * caller to free this memory.  If there is insufficient memory or if the
- * meanings of the flags of the error register are not known for the given
- * command then it returns NULL.
- *
- * The meanings of the flags of the error register for all commands are
- * described in the ATA spec and could all be supported here in theory.
- * Currently, only a few commands are supported (those that have been seen
- * to produce errors).  If many more are to be added then this function
- * should probably be redesigned.
- */
-char *construct_st_er_desc(struct ata_smart_errorlog_struct *data) {
-  unsigned char CR=data->commands[4].commandreg;
-  unsigned char FR=data->commands[4].featuresreg;
-  unsigned char ST=data->error_struct.status;
-  unsigned char ER=data->error_struct.error_register;
-  char *s;
-  const char *error_flag[8];
-  int i, print_lba=0, print_sector=0;
-
-  // Set of character strings corresponding to different error codes.
-  // Please keep in alphabetic order if you add more.
-  const char  *abrt  = "ABRT";  // ABORTED
- const char   *amnf  = "AMNF";  // ADDRESS MARK NOT FOUND
- const char   *ccto  = "CCTO";  // COMMAND COMPLETTION TIMED OUT
- const char   *eom   = "EOM";   // END OF MEDIA
- const char   *icrc  = "ICRC";  // INTERFACE CRC ERROR
- const char   *idnf  = "IDNF";  // ID NOT FOUND
- const char   *ili   = "ILI";   // MEANING OF THIS BIT IS COMMAND-SET SPECIFIC
- const char   *mc    = "MC";    // MEDIA CHANGED 
- const char   *mcr   = "MCR";   // MEDIA CHANGE REQUEST
- const char   *nm    = "NM";    // NO MEDIA
- const char   *obs   = "obs";   // OBSOLETE
- const char   *tk0nf = "TK0NF"; // TRACK 0 NOT FOUND
- const char   *unc   = "UNC";   // UNCORRECTABLE
- const char   *wp    = "WP";    // WRITE PROTECTED
-
-  /* If for any command the Device Fault flag of the status register is
-   * not used then used_device_fault should be set to 0 (in the CR switch
-   * below)
-   */
-  int uses_device_fault = 1;
-
-  /* A value of NULL means that the error flag isn't used */
-  for (i = 0; i < 8; i++)
-    error_flag[i] = NULL;
-
-  switch (CR) {
-  case 0x10:  // RECALIBRATE
-    error_flag[2] = abrt;
-    error_flag[1] = tk0nf;
-    break;
-  case 0x20:  /* READ SECTOR(S) */
-  case 0x21:  // READ SECTOR(S)
-  case 0x24:  // READ SECTOR(S) EXT
-  case 0xC4:  /* READ MULTIPLE */
-  case 0x29:  // READ MULTIPLE EXT
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0x22:  // READ LONG (with retries)
-  case 0x23:  // READ LONG (without retries)
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0x2a:  // READ STREAM DMA
-  case 0x2b:  // READ STREAM PIO
-    if (CR==0x2a)
-      error_flag[7] = icrc;
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = ccto;
-    print_lba=1;
-    print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0x3A:  // WRITE STREAM DMA
-  case 0x3B:  // WRITE STREAM PIO
-    if (CR==0x3A)
-      error_flag[7] = icrc;
-    error_flag[6] = wp;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = ccto;
-    print_lba=1;
-    print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0x25:  /* READ DMA EXT */
-  case 0x26:  // READ DMA QUEUED EXT
-  case 0xC7:  // READ DMA QUEUED
-  case 0xC8:  /* READ DMA */
-  case 0xC9:
-    error_flag[7] = icrc;
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    if (CR==0x25 || CR==0xC8)
-      print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0x30:  /* WRITE SECTOR(S) */
-  case 0x31:  // WRITE SECTOR(S)
-  case 0x34:  // WRITE SECTOR(S) EXT
-  case 0xC5:  /* WRITE MULTIPLE */
-  case 0x39:  // WRITE MULTIPLE EXT
-  case 0xCE:  // WRITE MULTIPLE FUA EXT
-    error_flag[6] = wp;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    print_lba=1;
-    break;
-  case 0x32:  // WRITE LONG (with retries)
-  case 0x33:  // WRITE LONG (without retries)
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    print_lba=1;
-    break;
-  case 0x3C:  // WRITE VERIFY
-    error_flag[6] = unc;
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0x40: // READ VERIFY SECTOR(S) with retries
-  case 0x41: // READ VERIFY SECTOR(S) without retries
-  case 0x42: // READ VERIFY SECTOR(S) EXT
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0xA0:  /* PACKET */
-    /* Bits 4-7 are all used for sense key (a 'command packet set specific error
-     * indication' according to the ATA/ATAPI-7 standard), so "Sense key" will
-     * be repeated in the error description string if more than one of those
-     * bits is set.
-     */
-    error_flag[7] = "Sense key (bit 3)",
-    error_flag[6] = "Sense key (bit 2)",
-    error_flag[5] = "Sense key (bit 1)",
-    error_flag[4] = "Sense key (bit 0)",
-    error_flag[2] = abrt;
-    error_flag[1] = eom;
-    error_flag[0] = ili;
-    break;
-  case 0xA1:  /* IDENTIFY PACKET DEVICE */
-  case 0xEF:  /* SET FEATURES */
-  case 0x00:  /* NOP */
-  case 0xC6:  /* SET MULTIPLE MODE */
-    error_flag[2] = abrt;
-    break;
-  case 0x2F:  // READ LOG EXT
-    error_flag[6] = unc;
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = obs;
-    break;
-  case 0x3F:  // WRITE LOG EXT
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = obs;
-    break;
-  case 0xB0:  /* SMART */
-    switch(FR) {
-    case 0xD0:  // SMART READ DATA
-    case 0xD1:  // SMART READ ATTRIBUTE THRESHOLDS
-    case 0xD5:  /* SMART READ LOG */
-      error_flag[6] = unc;
-      error_flag[4] = idnf;
-      error_flag[2] = abrt;
-      error_flag[0] = obs;
-      break;
-    case 0xD6:  /* SMART WRITE LOG */
-      error_flag[4] = idnf;
-      error_flag[2] = abrt;
-      error_flag[0] = obs;
-      break;
-    case 0xD2:  // Enable/Disable Attribute Autosave
-    case 0xD3:  // SMART SAVE ATTRIBUTE VALUES (ATA-3)
-    case 0xD8:  // SMART ENABLE OPERATIONS
-    case 0xD9:  /* SMART DISABLE OPERATIONS */
-    case 0xDA:  /* SMART RETURN STATUS */
-    case 0xDB:  // Enable/Disable Auto Offline (SFF)
-      error_flag[2] = abrt;
-      break;
-    case 0xD4:  // SMART EXECUTE IMMEDIATE OFFLINE
-      error_flag[4] = idnf;
-      error_flag[2] = abrt;
-      break;
-    default:
-      return NULL;
-      break;
-    }
-    break;
-  case 0xB1:  /* DEVICE CONFIGURATION */
-    switch (FR) {
-    case 0xC0:  /* DEVICE CONFIGURATION RESTORE */
-      error_flag[2] = abrt;
-      break;
-    default:
-      return NULL;
-      break;
-    }
-    break;
-  case 0xCA:  /* WRITE DMA */
-  case 0xCB:
-  case 0x35:  // WRITE DMA EXT
-  case 0x3D:  // WRITE DMA FUA EXT
-  case 0xCC:  // WRITE DMA QUEUED
-  case 0x36:  // WRITE DMA QUEUED EXT
-  case 0x3E:  // WRITE DMA QUEUED FUA EXT
-    error_flag[7] = icrc;
-    error_flag[6] = wp;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    if (CR==0x35)
-      print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0xE4: // READ BUFFER
-  case 0xE8: // WRITE BUFFER
-    error_flag[2] = abrt;
-    break;
-  default:
-    return NULL;
-  }
-
-  /* 256 bytes -- that'll be plenty (OK, this is lazy!) */
-  if (!(s = (char *)malloc(256)))
-    return s;
-
-  s[0] = '\0';
-
-  /* We ignore any status flags other than Device Fault and Error */
-
-  if (uses_device_fault && (ST & (1 << 5))) {
-    strcat(s, "Device Fault");
-    if (ST & 1)  // Error flag
-      strcat(s, "; ");
-  }
-  if (ST & 1) {  // Error flag
-    int count = 0;
-
-    strcat(s, "Error: ");
-    for (i = 7; i >= 0; i--)
-      if ((ER & (1 << i)) && (error_flag[i])) {
-        if (count++ > 0)
-           strcat(s, ", ");
-        strcat(s, error_flag[i]);
-      }
-  }
-
-  // If the error was a READ or WRITE error, print the Logical Block
-  // Address (LBA) at which the read or write failed.
-  if (print_lba) {
-    char tmp[128];
-    int lba;
-
-    // bits 24-27: bits 0-3 of DH
-    lba   = 0xf & data->error_struct.drive_head;
-    lba <<= 8;
-    // bits 16-23: CH
-    lba  |= data->error_struct.cylinder_high;
-    lba <<= 8;
-    // bits 8-15:  CL
-    lba  |= data->error_struct.cylinder_low;
-    lba <<= 8;
-    // bits 0-7:   SN
-    lba  |= data->error_struct.sector_number;
-
-    // print number of sectors, if known, and append to print string
-    if (print_sector) {
-      snprintf(tmp, 128, " %d sectors", print_sector);
-      strcat(s, tmp);
-    }
-
-    // print LBA, and append to print string
-    snprintf(tmp, 128, " at LBA = 0x%08x = %d", lba, lba);
-    strcat(s, tmp);
-  }
-
-  return s;
-}
-
-// This returns the capacity of a disk drive and also prints this into
-// a string, using comma separators to make it easier to read.  If the
-// drive doesn't support LBA addressing or has no user writable
-// sectors (eg, CDROM or DVD) then routine returns zero.
-uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
-
-  unsigned short command_set_2  = drive->command_set_2;
-  unsigned short capabilities_0 = drive->words047_079[49-47];
-  unsigned short sects_16       = drive->words047_079[60-47];
-  unsigned short sects_32       = drive->words047_079[61-47];
-  unsigned short lba_16         = drive->words088_255[100-88];
-  unsigned short lba_32         = drive->words088_255[101-88];
-  unsigned short lba_48         = drive->words088_255[102-88];
-  unsigned short lba_64         = drive->words088_255[103-88];
-  uint64_t capacity_short=0, capacity=0, threedigits, power_of_ten;
-  int started=0,k=1000000000;
-  
-  // if drive supports LBA addressing, determine 32-bit LBA capacity
-  if (capabilities_0 & 0x0200) {
-    capacity_short = (unsigned int)sects_32 << 16 | 
-                     (unsigned int)sects_16 << 0  ;
-    
-    // if drive supports 48-bit addressing, determine THAT capacity
-    if ((command_set_2 & 0xc000) == 0x4000 && (command_set_2 & 0x0400))
-      capacity = (uint64_t)lba_64 << 48 | 
-	         (uint64_t)lba_48 << 32 |
-	         (uint64_t)lba_32 << 16 | 
-	         (uint64_t)lba_16 << 0  ;
-    
-    // choose the larger of the two possible capacities
-    if (capacity_short>capacity)
-      capacity=capacity_short;
-  }
-
-  // turn sectors into bytes
-  capacity_short = (capacity *= 512);
-  
-  // print with comma separators.  I know this is anglo-centric:
-  // tell me what to change to use LOCALE if you want.
-  power_of_ten =  k;
-  power_of_ten *= k;
-  
-  for (k=0; k<7; k++) {
-    threedigits = capacity/power_of_ten;
-    capacity   -= threedigits*power_of_ten;
-    if (started)
-      // we have already printed some digits
-      pstring += sprintf(pstring, ",%03"PRIu64, threedigits);
-    else if (threedigits || k==6) {
-      // these are the first digits that we are printing
-      pstring += sprintf(pstring, "%"PRIu64, threedigits);
-      started = 1;
-    }
-    if (k!=6)
-      power_of_ten /= 1000;
-  }
-  
-  return capacity_short;
-}
-
-void ataPrintDriveInfo (struct ata_identify_device *drive){
-  int version, drivetype;
-  const char *description;
-  char unknown[64], timedatetz[DATEANDEPOCHLEN];
-  unsigned short minorrev;
-  char model[64], serial[64], firm[64], capacity[64];
-  
-
-  // print out model, serial # and firmware versions  (byte-swap ASCI strings)
-  pout("Device Model:     ");
-  printswap(model, (char *)drive->model,40);
-
-  pout("Serial Number:    ");
-  printswap(serial, (char *)drive->serial_no,20);
-
-  pout("Firmware Version: ");
-  printswap(firm, (char *)drive->fw_rev,8);
-
-  if (determine_capacity(drive, capacity))
-    pout("User Capacity:    %s bytes\n", capacity);
-  
-  // See if drive is recognized
-  drivetype=lookupdrive(model, firm);
-  pout("Device is:        %s\n", drivetype<0?
-       "Not in smartctl database [for details use: -P showall]":
-       "In smartctl database [for details use: -P show]");
-
-  // now get ATA version info
-  version=ataVersionInfo(&description,drive, &minorrev);
-
-  // unrecognized minor revision code
-  if (!description){
-    if (!minorrev)
-      sprintf(unknown, "Exact ATA specification draft version not indicated");
-    else
-      sprintf(unknown,"Not recognized. Minor revision code: 0x%02hx", minorrev);
-    description=unknown;
-  }
-  
-  
-  // SMART Support was first added into the ATA/ATAPI-3 Standard with
-  // Revision 3 of the document, July 25, 1995.  Look at the "Document
-  // Status" revision commands at the beginning of
-  // http://www.t13.org/project/d2008r6.pdf to see this.  So it's not
-  // enough to check if we are ATA-3.  Version=-3 indicates ATA-3
-  // BEFORE Revision 3.
-  pout("ATA Version is:   %d\n",(int)abs(version));
-  pout("ATA Standard is:  %s\n",description);
-  
-  // print current time and date and timezone
-  dateandtimezone(timedatetz);
-  pout("Local Time is:    %s\n", timedatetz);
-
-  // Print warning message, if there is one
-  if (drivetype>=0 && knowndrives[drivetype].warningmsg)
-    pout("\n==> WARNING: %s\n\n", knowndrives[drivetype].warningmsg);
-
-  if (version>=3)
-    return;
-  
-  pout("SMART is only available in ATA Version 3 Revision 3 or greater.\n");
-  pout("We will try to proceed in spite of this.\n");
-  return;
-}
-
-
-const char *OfflineDataCollectionStatus(unsigned char status_byte){
-  unsigned char stat=status_byte & 0x7f;
-  
-  switch(stat){
-  case 0x00:
-    return "was never started";
-  case 0x02:
-    return "was completed without error";
-  case 0x03:
-    if (status_byte == 0x03)
-      return "is in progress";
-    else
-      return "is in a Reserved state";
-  case 0x04:
-    return "was suspended by an interrupting command from host";
-  case 0x05:
-    return "was aborted by an interrupting command from host";
-  case 0x06:
-    return "was aborted by the device with a fatal error";
-  default:
-    if (stat >= 0x40)
-      return "is in a Vendor Specific state\n";
-    else
-      return "is in a Reserved state\n";
-  }
-}
-  
-  
-  /*  prints verbose value Off-line data collection status byte */
-  void PrintSmartOfflineStatus(struct ata_smart_values *data){
-  
-  pout("Offline data collection status:  (0x%02x)\t",
-       (int)data->offline_data_collection_status);
-    
-  // Off-line data collection status byte is not a reserved
-  // or vendor specific value
-  pout("Offline data collection activity\n"
-       "\t\t\t\t\t%s.\n", OfflineDataCollectionStatus(data->offline_data_collection_status));
-  
-  // Report on Automatic Data Collection Status.  Only IBM documents
-  // this bit.  See SFF 8035i Revision 2 for details.
-  if (data->offline_data_collection_status & 0x80)
-    pout("\t\t\t\t\tAuto Offline Data Collection: Enabled.\n");
-  else
-    pout("\t\t\t\t\tAuto Offline Data Collection: Disabled.\n");
-  
-  return;
-}
-
-void PrintSmartSelfExecStatus(struct ata_smart_values *data)
-{
-   pout("Self-test execution status:      ");
-   
-   switch (data->self_test_exec_status >> 4)
-   {
-      case 0:
-        pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t",
-                (int)data->self_test_exec_status);
-        pout("without error or no self-test has ever \n\t\t\t\t\tbeen run.\n");
-        break;
-       case 1:
-         pout("(%4d)\tThe self-test routine was aborted by\n\t\t\t\t\t",
-                 (int)data->self_test_exec_status);
-         pout("the host.\n");
-         break;
-       case 2:
-         pout("(%4d)\tThe self-test routine was interrupted\n\t\t\t\t\t",
-                 (int)data->self_test_exec_status);
-         pout("by the host with a hard or soft reset.\n");
-         break;
-       case 3:
-          pout("(%4d)\tA fatal error or unknown test error\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("occurred while the device was executing\n\t\t\t\t\t");
-          pout("its self-test routine and the device \n\t\t\t\t\t");
-          pout("was unable to complete the self-test \n\t\t\t\t\t");
-          pout("routine.\n");
-          break;
-       case 4:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("a test element that failed and the test\n\t\t\t\t\t");
-          pout("element that failed is not known.\n");
-          break;
-       case 5:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the electrical element of the test\n\t\t\t\t\t");
-          pout("failed.\n");
-          break;
-       case 6:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the servo (and/or seek) element of the \n\t\t\t\t\t");
-          pout("test failed.\n");
-          break;
-       case 7:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the read element of the test failed.\n");
-          break;
-       case 15:
-          pout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("%1d0%% of test remaining.\n", 
-                  (int)(data->self_test_exec_status & 0x0f));
-          break;
-       default:
-          pout("(%4d)\tReserved.\n",
-                  (int)data->self_test_exec_status);
-          break;
-   }
-        
-}
-
-
-
-void PrintSmartTotalTimeCompleteOffline ( struct ata_smart_values *data){
-  pout("Total time to complete Offline \n");
-  pout("data collection: \t\t (%4d) seconds.\n", 
-       (int)data->total_time_to_complete_off_line);
-}
-
-
-
-void PrintSmartOfflineCollectCap(struct ata_smart_values *data){
-  pout("Offline data collection\n");
-  pout("capabilities: \t\t\t (0x%02x) ",
-       (int)data->offline_data_collection_capability);
-  
-  if (data->offline_data_collection_capability == 0x00){
-    pout("\tOffline data collection not supported.\n");
-  } 
-  else {
-    pout( "%s\n", isSupportExecuteOfflineImmediate(data)?
-          "SMART execute Offline immediate." :
-          "No SMART execute Offline immediate.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportAutomaticTimer(data)? 
-          "Auto Offline data collection on/off support.":
-          "No Auto Offline data collection support.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportOfflineAbort(data)? 
-          "Abort Offline collection upon new\n\t\t\t\t\tcommand.":
-          "Suspend Offline collection upon new\n\t\t\t\t\tcommand.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportOfflineSurfaceScan(data)? 
-          "Offline surface scan supported.":
-          "No Offline surface scan supported.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportSelfTest(data)? 
-          "Self-test supported.":
-          "No Self-test supported.");
-
-    pout( "\t\t\t\t\t%s\n", isSupportConveyanceSelfTest(data)? 
-          "Conveyance Self-test supported.":
-          "No Conveyance Self-test supported.");
-
-    pout( "\t\t\t\t\t%s\n", isSupportSelectiveSelfTest(data)? 
-          "Selective Self-test supported.":
-          "No Selective Self-test supported.");
-  }
-}
-
-
-
-void PrintSmartCapability ( struct ata_smart_values *data)
-{
-   pout("SMART capabilities:            ");
-   pout("(0x%04x)\t", (int)data->smart_capability);
-   
-   if (data->smart_capability == 0x00)
-   {
-       pout("Automatic saving of SMART data\t\t\t\t\tis not implemented.\n");
-   } 
-   else 
-   {
-        
-      pout( "%s\n", (data->smart_capability & 0x01)? 
-              "Saves SMART data before entering\n\t\t\t\t\tpower-saving mode.":
-              "Does not save SMART data before\n\t\t\t\t\tentering power-saving mode.");
-                
-      if ( data->smart_capability & 0x02 )
-      {
-          pout("\t\t\t\t\tSupports SMART auto save timer.\n");
-      }
-   }
-}
-
-void PrintSmartErrorLogCapability (struct ata_smart_values *data, struct ata_identify_device *identity)
-{
-
-   pout("Error logging capability:       ");
-    
-   if ( isSmartErrorLogCapable(data, identity) )
-   {
-      pout(" (0x%02x)\tError logging supported.\n",
-               (int)data->errorlog_capability);
-   }
-   else {
-       pout(" (0x%02x)\tError logging NOT supported.\n",
-                (int)data->errorlog_capability);
-   }
-}
-
-void PrintSmartShortSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Short self-test routine \n");
-  if (isSupportSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-         (int)data->short_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-void PrintSmartExtendedSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Extended self-test routine\n");
-  if (isSupportSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-         (int)data->extend_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-void PrintSmartConveyanceSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Conveyance self-test routine\n");
-  if (isSupportConveyanceSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-         (int)data->conveyance_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-// onlyfailed=0 : print all attribute values
-// onlyfailed=1:  just ones that are currently failed and have prefailure bit set
-// onlyfailed=2:  ones that are failed, or have failed with or without prefailure bit set
-void PrintSmartAttribWithThres (struct ata_smart_values *data, 
-                                struct ata_smart_thresholds_pvt *thresholds,
-                                int onlyfailed){
-  int i;
-  int needheader=1;
-  char rawstring[64];
-    
-  // step through all vendor attributes
-  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-    char *status;
-    struct ata_smart_attribute *disk=data->vendor_attributes+i;
-    struct ata_smart_threshold_entry *thre=thresholds->thres_entries+i;
-    
-    // consider only valid attributes
-    if (disk->id && thre->id){
-      char *type, *update;
-      int failednow,failedever;
-      char attributename[64];
-
-      failednow = (disk->current <= thre->threshold);
-      failedever= (disk->worst   <= thre->threshold);
-      
-      // These break out of the loop if we are only printing certain entries...
-      if (onlyfailed==1 && (!ATTRIBUTE_FLAGS_PREFAILURE(disk->flags) || !failednow))
-        continue;
-      
-      if (onlyfailed==2 && !failedever)
-        continue;
-      
-      // print header only if needed
-      if (needheader){
-        if (!onlyfailed){
-          pout("SMART Attributes Data Structure revision number: %d\n",(int)data->revnumber);
-          pout("Vendor Specific SMART Attributes with Thresholds:\n");
-        }
-        pout("ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE\n");
-        needheader=0;
-      }
-      
-      // is this Attribute currently failed, or has it ever failed?
-      if (failednow)
-        status="FAILING_NOW";
-      else if (failedever)
-        status="In_the_past";
-      else
-        status="    -";
-
-      // Print name of attribute
-      ataPrintSmartAttribName(attributename,disk->id, con->attributedefs);
-      pout("%-28s",attributename);
-
-      // printing line for each valid attribute
-      type=ATTRIBUTE_FLAGS_PREFAILURE(disk->flags)?"Pre-fail":"Old_age";
-      update=ATTRIBUTE_FLAGS_ONLINE(disk->flags)?"Always":"Offline";
-
-      pout("0x%04x   %.3d   %.3d   %.3d    %-10s%-9s%-12s", 
-             (int)disk->flags, (int)disk->current, (int)disk->worst,
-             (int)thre->threshold, type, update, status);
-
-      // print raw value of attribute
-      ataPrintSmartAttribRawValue(rawstring, disk, con->attributedefs);
-      pout("%s\n", rawstring);
-      
-      // print a warning if there is inconsistency here!
-      if (disk->id != thre->id){
-        char atdat[64],atthr[64];
-        ataPrintSmartAttribName(atdat, disk->id, con->attributedefs);
-        ataPrintSmartAttribName(atthr, thre->id, con->attributedefs);
-        pout("%-28s<== Data Page      |  WARNING: PREVIOUS ATTRIBUTE HAS TWO\n",atdat);
-        pout("%-28s<== Threshold Page |  INCONSISTENT IDENTITIES IN THE DATA\n",atthr);
-      }
-    }
-  }
-  if (!needheader) pout("\n");
-}
-
-void ataPrintGeneralSmartValues(struct ata_smart_values *data, struct ata_identify_device *drive){
-  pout("General SMART Values:\n");
-  
-  PrintSmartOfflineStatus(data); 
-  
-  if (isSupportSelfTest(data)){
-    PrintSmartSelfExecStatus (data);
-  }
-  
-  PrintSmartTotalTimeCompleteOffline(data);
-  PrintSmartOfflineCollectCap(data);
-  PrintSmartCapability(data);
-  
-  PrintSmartErrorLogCapability(data, drive);
-
-  pout( "\t\t\t\t\t%s\n", isGeneralPurposeLoggingCapable(drive)?
-        "General Purpose Logging supported.":
-        "No General Purpose Logging support.");
-
-  if (isSupportSelfTest(data)){
-    PrintSmartShortSelfTestPollingTime (data);
-    PrintSmartExtendedSelfTestPollingTime (data);
-  }
-  if (isSupportConveyanceSelfTest(data))
-    PrintSmartConveyanceSelfTestPollingTime (data);
-  
-  pout("\n");
-}
-
-int ataPrintLogDirectory(struct ata_smart_log_directory *data){
-  int i;
-  char *name;
-
-  pout("SMART Log Directory Logging Version %d%s\n",
-       data->logversion, data->logversion==1?" [multi-sector log support]":"");
-  for (i=0; i<=255; i++){
-    int numsect;
-    
-    // Directory log length
-    numsect = i? data->entry[i-1].numsectors : 1;
-    
-    // If the log is not empty, what is it's name
-    if (numsect){
-      switch (i) {
-      case 0:
-        name="Log Directory"; break;
-      case 1:
-        name="Summary SMART error log"; break;
-      case 2:
-        name="Comprehensive SMART error log"; break;
-      case 3:
-        name="Extended Comprehensive SMART error log"; break;
-      case 6:
-        name="SMART self-test log"; break;
-      case 7:
-        name="Extended self-test log"; break;
-      case 9:
-        name="Selective self-test log"; break;
-      case 0x20:
-        name="Streaming performance log"; break;
-      case 0x21:
-        name="Write stream error log"; break;
-      case 0x22:
-        name="Read stream error log"; break;
-      case 0x23:
-        name="Delayed sector log"; break;
-      default:
-        if (0xa0<=i && i<=0xbf) 
-          name="Device vendor specific log";
-        else if (0x80<=i && i<=0x9f)
-          name="Host vendor specific log";
-        else
-          name="Reserved log";
-        break;
-      }
-
-      // print name and length of log
-      pout("Log at address 0x%02x has %03d sectors [%s]\n",
-           i, numsect, name);
-    }
-  }
-  return 0;
-}
-
-// returns number of errors
-int ataPrintSmartErrorlog(struct ata_smart_errorlog *data){
-  int k;
-
-  pout("SMART Error Log Version: %d\n", (int)data->revnumber);
-  
-  // if no errors logged, return
-  if (!data->error_log_pointer){
-    pout("No Errors Logged\n\n");
-    return 0;
-  }
-  PRINT_ON(con);
-  // If log pointer out of range, return
-  if (data->error_log_pointer>5){
-    pout("Invalid Error Log index = 0x%02x (T13/1321D rev 1c "
-         "Section 8.41.6.8.2.2 gives valid range from 1 to 5)\n\n",
-         (int)data->error_log_pointer);
-    return 0;
-  }
-
-  // Some internal consistency checking of the data structures
-  if ((data->ata_error_count-data->error_log_pointer)%5 && con->fixfirmwarebug != FIX_SAMSUNG2) {
-    pout("Warning: ATA error count %d inconsistent with error log pointer %d\n\n",
-         data->ata_error_count,data->error_log_pointer);
-  }
-  
-  // starting printing error log info
-  if (data->ata_error_count<=5)
-    pout( "ATA Error Count: %d\n", (int)data->ata_error_count);
-  else
-    pout( "ATA Error Count: %d (device log contains only the most recent five errors)\n",
-           (int)data->ata_error_count);
-  PRINT_OFF(con);
-  pout("\tCR = Command Register [HEX]\n"
-       "\tFR = Features Register [HEX]\n"
-       "\tSC = Sector Count Register [HEX]\n"
-       "\tSN = Sector Number Register [HEX]\n"
-       "\tCL = Cylinder Low Register [HEX]\n"
-       "\tCH = Cylinder High Register [HEX]\n"
-       "\tDH = Device/Head Register [HEX]\n"
-       "\tDC = Device Command Register [HEX]\n"
-       "\tER = Error register [HEX]\n"
-       "\tST = Status register [HEX]\n"
-       "Powered_Up_Time is measured from power on, and printed as\n"
-       "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
-       "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
-  
-  // now step through the five error log data structures (table 39 of spec)
-  for (k = 4; k >= 0; k-- ) {
-    char *st_er_desc;
-
-    // The error log data structure entries are a circular buffer
-    int j, i=(data->error_log_pointer+k)%5;
-    struct ata_smart_errorlog_struct *elog=data->errorlog_struct+i;
-    struct ata_smart_errorlog_error_struct *summary=&(elog->error_struct);
-
-    // Spec says: unused error log structures shall be zero filled
-    if (nonempty((unsigned char*)elog,sizeof(*elog))){
-      // Table 57 of T13/1532D Volume 1 Revision 3
-      char *msgstate;
-      int bits=summary->state & 0x0f;
-      int days = (int)summary->timestamp/24;
-
-      switch (bits){
-      case 0x00: msgstate="in an unknown state";break;
-      case 0x01: msgstate="sleeping"; break;
-      case 0x02: msgstate="in standby mode"; break;
-      case 0x03: msgstate="active or idle"; break;
-      case 0x04: msgstate="doing SMART Offline or Self-test"; break;
-      default:   
-        if (bits<0x0b)
-          msgstate="in a reserved state";
-        else
-          msgstate="in a vendor specific state";
-      }
-
-      // See table 42 of ATA5 spec
-      PRINT_ON(con);
-      pout("Error %d occurred at disk power-on lifetime: %d hours (%d days + %d hours)\n",
-             (int)(data->ata_error_count+k-4), (int)summary->timestamp, days, (int)(summary->timestamp-24*days));
-      PRINT_OFF(con);
-      pout("  When the command that caused the error occurred, the device was %s.\n\n",msgstate);
-      pout("  After command completion occurred, registers were:\n"
-           "  ER ST SC SN CL CH DH\n"
-           "  -- -- -- -- -- -- --\n"
-           "  %02x %02x %02x %02x %02x %02x %02x",
-           (int)summary->error_register,
-           (int)summary->status,
-           (int)summary->sector_count,
-           (int)summary->sector_number,
-           (int)summary->cylinder_low,
-           (int)summary->cylinder_high,
-           (int)summary->drive_head);
-      // Add a description of the contents of the status and error registers
-      // if possible
-      st_er_desc = construct_st_er_desc(elog);
-      if (st_er_desc) {
-        pout("  %s", st_er_desc);
-        free(st_er_desc);
-      }
-      pout("\n\n");
-      pout("  Commands leading to the command that caused the error were:\n"
-           "  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name\n"
-           "  -- -- -- -- -- -- -- --  ----------------  --------------------\n");
-      for ( j = 4; j >= 0; j--){
-        struct ata_smart_errorlog_command_struct *thiscommand=elog->commands+j;
-
-        // Spec says: unused data command structures shall be zero filled
-        if (nonempty((unsigned char*)thiscommand,sizeof(*thiscommand))) {
-	  char timestring[32];
-	  
-	  // Convert integer milliseconds to a text-format string
-	  MsecToText(thiscommand->timestamp, timestring);
-	  
-          pout("  %02x %02x %02x %02x %02x %02x %02x %02x  %16s  %s\n",
-               (int)thiscommand->commandreg,
-               (int)thiscommand->featuresreg,
-               (int)thiscommand->sector_count,
-               (int)thiscommand->sector_number,
-               (int)thiscommand->cylinder_low,
-               (int)thiscommand->cylinder_high,
-               (int)thiscommand->drive_head,
-               (int)thiscommand->devicecontrolreg,
-	       timestring,
-               look_up_ata_command(thiscommand->commandreg, thiscommand->featuresreg));
-	}
-      }
-      pout("\n");
-    }
-  }
-  PRINT_ON(con);
-  if (con->printing_switchable)
-    pout("\n");
-  PRINT_OFF(con);
-  return data->ata_error_count;  
-}
-
-void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struct ata_smart_values *sv) {
-  int i,field1,field2;
-  char *msg;
-  char tmp[64];
-  uint64_t maxl=0,maxr=0;
-  uint64_t current=log->currentlba;
-  uint64_t currentend=current+65535;
-
-  // print data structure revision number
-  pout("SMART Selective self-test log data structure revision number %d\n",(int)log->logversion);
-  if (1 != log->logversion)
-    pout("Warning: ATA Specification requires selective self-test log data structure revision number = 1\n");
-  
-  switch((sv->self_test_exec_status)>>4){
-  case  0:msg="Completed";
-    break;
-  case  1:msg="Aborted_by_host";
-    break;
-  case  2:msg="Interrupted";
-    break;
-  case  3:msg="Fatal_error";
-    break;
-  case  4:msg="Completed_unknown_failure";
-    break;
-  case  5:msg="Completed_electrical_failure";
-    break;
-  case  6:msg="Completed_servo/seek_failure";
-    break;
-  case  7:msg="Completed_read_failure";
-    break;
-  case  8:msg="Completed_handling_damage??";
-    break;
-  case 15:msg="Self_test_in_progress";
-    break;
-  default:msg="Unknown_status ";
-    break;
-  }
-
-  // find the number of columns needed for printing. If in use, the
-  // start/end of span being read-scanned...
-  if (log->currentspan>5) {
-    maxl=current;
-    maxr=currentend;
-  }
-  for (i=0; i<5; i++) {
-    uint64_t start=log->span[i].start;
-    uint64_t end  =log->span[i].end; 
-    // ... plus max start/end of each of the five test spans.
-    if (start>maxl)
-      maxl=start;
-    if (end > maxr)
-      maxr=end;
-  }
-  
-  // we need at least 7 characters wide fields to accomodate the
-  // labels
-  if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7)
-    field1=7;
-  if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7)
-    field2=7;
-
-  // now print the five test spans
-  pout(" SPAN  %*s  %*s  CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA");
-
-  for (i=0; i<5; i++) {
-    uint64_t start=log->span[i].start;
-    uint64_t end=log->span[i].end;
-    
-    if ((i+1)==(int)log->currentspan)
-      // this span is currently under test
-      pout("    %d  %*"PRIu64"  %*"PRIu64"  %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n",
-	   i+1, field1, start, field2, end, msg,
-	   (int)(sv->self_test_exec_status & 0x7), current, currentend);
-    else
-      // this span is not currently under test
-      pout("    %d  %*"PRIu64"  %*"PRIu64"  Not_testing\n",
-	   i+1, field1, start, field2, end);
-  }  
-  
-  // if we are currently read-scanning, print LBAs and the status of
-  // the read scan
-  if (log->currentspan>5)
-    pout("%5d  %*"PRIu64"  %*"PRIu64"  Read_scanning %s\n",
-	 (int)log->currentspan, field1, current, field2, currentend,
-	 OfflineDataCollectionStatus(sv->offline_data_collection_status));
-  
-  /* Print selective self-test flags.  Possible flag combinations are
-     (numbering bits from 0-15):
-     Bit-1 Bit-3   Bit-4
-     Scan  Pending Active
-     0     *       *       Don't scan
-     1     0       0       Will carry out scan after selective test
-     1     1       0       Waiting to carry out scan after powerup
-     1     0       1       Currently scanning       
-     1     1       1       Currently scanning
-  */
-  
-  pout("Selective self-test flags (0x%x):\n", (unsigned int)log->flags);
-  if (log->flags & SELECTIVE_FLAG_DOSCAN) {
-    if (log->flags & SELECTIVE_FLAG_ACTIVE)
-      pout("  Currently read-scanning the remainder of the disk.\n");
-    else if (log->flags & SELECTIVE_FLAG_PENDING)
-      pout("  Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",
-	   (int)log->pendingtime);
-    else
-      pout("  After scanning selected spans, read-scan remainder of disk.\n");
-  }
-  else
-    pout("  After scanning selected spans, do NOT read-scan remainder of disk.\n");
-  
-  // print pending time
-  pout("If Selective self-test is pending on power-up, resume after %d minute delay.\n",
-       (int)log->pendingtime);
-
-  return; 
-}
-
-// return value is:
-// bottom 8 bits: number of entries found where self-test showed an error
-// remaining bits: if nonzero, power on hours of last self-test where error was found
-int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *data,int allentries){
-  int i,j,noheaderprinted=1;
-  int retval=0, hours=0, testno=0;
-
-  if (allentries)
-    pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);
-  if ((data->revnumber!=0x0001) && allentries && con->fixfirmwarebug != FIX_SAMSUNG)
-    pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
-  if (data->mostrecenttest==0){
-    if (allentries)
-      pout("No self-tests have been logged.  [To run self-tests, use: smartctl -t]\n\n");
-    return 0;
-  }
-
-  // print log      
-  for (i=20;i>=0;i--){    
-    struct ata_smart_selftestlog_struct *log;
-
-    // log is a circular buffer
-    j=(i+data->mostrecenttest)%21;
-    log=data->selftest_struct+j;
-
-    if (nonempty((unsigned char*)log,sizeof(*log))){
-      char *msgtest,*msgstat,percent[64],firstlba[64];
-      int errorfound=0;
-      
-      // count entry based on non-empty structures -- needed for
-      // Seagate only -- other vendors don't have blank entries 'in
-      // the middle'
-      testno++;
-
-      // test name
-      switch(log->selftestnumber){
-      case   0: msgtest="Offline            "; break;
-      case   1: msgtest="Short offline      "; break;
-      case   2: msgtest="Extended offline   "; break;
-      case   3: msgtest="Conveyance offline "; break;
-      case   4: msgtest="Selective offline  "; break;
-      case 127: msgtest="Abort offline test "; break;
-      case 129: msgtest="Short captive      "; break;
-      case 130: msgtest="Extended captive   "; break;
-      case 131: msgtest="Conveyance captive "; break;
-      case 132: msgtest="Selective captive  "; break;
-      default:  
-        if ( log->selftestnumber>=192 ||
-            (log->selftestnumber>= 64 && log->selftestnumber<=126))
-          msgtest="Vendor offline     ";
-        else
-          msgtest="Reserved offline   ";
-      }
-      
-      // test status
-      switch((log->selfteststatus)>>4){
-      case  0:msgstat="Completed without error      "; break;
-      case  1:msgstat="Aborted by host              "; break;
-      case  2:msgstat="Interrupted (host reset)     "; break;
-      case  3:msgstat="Fatal or unknown error       "; errorfound=1; break;
-      case  4:msgstat="Completed: unknown failure   "; errorfound=1; break;
-      case  5:msgstat="Completed: electrical failure"; errorfound=1; break;
-      case  6:msgstat="Completed: servo/seek failure"; errorfound=1; break;
-      case  7:msgstat="Completed: read failure      "; errorfound=1; break;
-      case  8:msgstat="Completed: handling damage?? "; errorfound=1; break;
-      case 15:msgstat="Self-test routine in progress"; break;
-      default:msgstat="Unknown/reserved test status ";
-      }
-
-      retval+=errorfound;
-      sprintf(percent,"%1d0%%",(log->selfteststatus)&0xf);
-
-      // T13/1321D revision 1c: (Data structure Rev #1)
-
-      //The failing LBA shall be the LBA of the uncorrectable sector
-      //that caused the test to fail. If the device encountered more
-      //than one uncorrectable sector during the test, this field
-      //shall indicate the LBA of the first uncorrectable sector
-      //encountered. If the test passed or the test failed for some
-      //reason other than an uncorrectable sector, the value of this
-      //field is undefined.
-
-      // This is true in ALL ATA-5 specs
-      
-      if (!errorfound || log->lbafirstfailure==0xffffffff || log->lbafirstfailure==0x00000000)
-        sprintf(firstlba,"%s","-");
-      else      
-        sprintf(firstlba,"%u",log->lbafirstfailure);
-
-      // print out a header if needed
-      if (noheaderprinted && (allentries || errorfound)){
-        pout("Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error\n");
-        noheaderprinted=0;
-      }
-      
-      // print out an entry, either if we are printing all entries OR
-      // if an error was found
-      if (allentries || errorfound)
-        pout("#%2d  %s %s %s  %8d         %s\n", testno, msgtest, msgstat, percent, (int)log->timestamp, firstlba);
-
-      // keep track of time of most recent error
-      if (errorfound && !hours)
-        hours=log->timestamp;
-    }
-  }
-  if (!allentries && retval)
-    pout("\n");
-
-  hours = hours << 8;
-  return (retval | hours);
-}
-
-void ataPseudoCheckSmart ( struct ata_smart_values *data, 
-                           struct ata_smart_thresholds_pvt *thresholds) {
-  int i;
-  int failed = 0;
-  for (i = 0 ; i < NUMBER_ATA_SMART_ATTRIBUTES ; i++) {
-    if (data->vendor_attributes[i].id &&   
-        thresholds->thres_entries[i].id &&
-        ATTRIBUTE_FLAGS_PREFAILURE(data->vendor_attributes[i].flags) &&
-        (data->vendor_attributes[i].current <= thresholds->thres_entries[i].threshold) &&
-        (thresholds->thres_entries[i].threshold != 0xFE)){
-      pout("Attribute ID %d Failed\n",(int)data->vendor_attributes[i].id);
-      failed = 1;
-    } 
-  }   
-  pout("%s\n", ( failed )?
-         "SMART overall-health self-assessment test result: FAILED!\n"
-         "Drive failure expected in less than 24 hours. SAVE ALL DATA":
-         "SMART overall-health self-assessment test result: PASSED");
-}
-
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-void failuretest(int type, int returnvalue){
-
-  // If this is an error in an "optional" SMART command
-  if (type==OPTIONAL_CMD){
-    if (con->conservative){
-      pout("An optional SMART command failed: exiting.  Remove '-T conservative' option to continue.\n");
-      EXIT(returnvalue);
-    }
-    return;
-  }
-
-  // If this is an error in a "mandatory" SMART command
-  if (type==MANDATORY_CMD){
-    if (con->permissive--)
-      return;
-    pout("A mandatory SMART command failed: exiting. To continue, add one or more '-T permissive' options.\n");
-    EXIT(returnvalue);
-  }
-
-  pout("Smartctl internal error in failuretest(type=%d). Please contact developers at " PACKAGE_HOMEPAGE "\n",type);
-  EXIT(returnvalue|FAILCMD);
-}
-
-// Used to warn users about invalid checksums.  Action to be taken may be
-// altered by the user.
-void checksumwarning(const char *string){
-  // user has asked us to ignore checksum errors
-  if (con->checksumignore)
-        return;
-
-  pout("Warning! %s error: invalid SMART checksum.\n",string);
-
-  // user has asked us to fail on checksum errors
-  if (con->checksumfail)
-    EXIT(FAILSMART);
-
-  return;
-}
-
-// Initialize to zero just in case some SMART routines don't work
-struct ata_identify_device drive;
-struct ata_smart_values smartval;
-struct ata_smart_thresholds_pvt smartthres;
-struct ata_smart_errorlog smarterror;
-struct ata_smart_selftestlog smartselftest;
-
-int ataPrintMain (int fd){
-  int timewait,code;
-  int returnval=0, retid=0, supported=0, needupdate=0;
-
-  // Start by getting Drive ID information.  We need this, to know if SMART is supported.
-  if ((retid=ataReadHDIdentity(fd,&drive))<0){
-    pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n");
-    failuretest(MANDATORY_CMD, returnval|=FAILID);
-  }
-
-  // If requested, show which presets would be used for this drive and exit.
-  if (con->showpresets) {
-    showpresets(&drive);
-    EXIT(0);
-  }
-
-  // Use preset vendor attribute options unless user has requested otherwise.
-  if (!con->ignorepresets){
-    unsigned char *charptr;
-    if ((charptr=con->attributedefs))
-      applypresets(&drive, &charptr, con);
-    else {
-      pout("Fatal internal error in ataPrintMain()\n");
-      EXIT(returnval|=FAILCMD);
-    }
-  }
-
-  // Print most drive identity information if requested
-  if (con->driveinfo){
-    pout("=== START OF INFORMATION SECTION ===\n");
-    ataPrintDriveInfo(&drive);
-  }
-
-  // Was this a packet device?
-  if (retid>0){
-    pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n", packetdevicetype(retid-1));
-    failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-  }
-  
-  // if drive does not supports SMART it's time to exit
-  supported=ataSmartSupport(&drive);
-  if (supported != 1){
-    if (supported==0) {
-      pout("SMART support is: Unavailable - device lacks SMART capability.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      pout("                  Checking to be sure by trying SMART ENABLE command.\n");
-    }
-    else {
-      pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      pout("                  Checking for SMART support by trying SMART ENABLE command.\n");
-    }
-
-    if (ataEnableSmart(fd)){
-      pout("                  SMART ENABLE failed - this establishes that this device lacks SMART functionality.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      supported=0;
-    }
-    else {
-      pout("                  SMART ENABLE appeared to work!  Continuing.\n");
-      supported=1;
-    }
-    if (!con->driveinfo) pout("\n");
-  }
-  
-  // Now print remaining drive info: is SMART enabled?    
-  if (con->driveinfo){
-    int ison=ataIsSmartEnabled(&drive),isenabled=ison;
-    
-    if (ison==-1) {
-      pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      // check SMART support by trying a command
-      pout("                  Checking to be sure by trying SMART RETURN STATUS command.\n");
-      isenabled=ataDoesSmartWork(fd);
-    }
-    else
-      pout("SMART support is: Available - device has SMART capability.\n");
-    
-    if (isenabled)
-      pout("SMART support is: Enabled\n");
-    else {
-      if (ison==-1)
-        pout("SMART support is: Unavailable\n");
-      else
-        pout("SMART support is: Disabled\n");
-    }
-    pout("\n");
-  }
-  
-  // START OF THE ENABLE/DISABLE SECTION OF THE CODE
-  if (con->smartenable || con->smartdisable || 
-      con->smartautosaveenable || con->smartautosavedisable || 
-      con->smartautoofflineenable || con->smartautoofflinedisable)
-    pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
-  
-  // Enable/Disable SMART commands
-  if (con->smartenable){
-    if (ataEnableSmart(fd)) {
-      pout("Smartctl: SMART Enable Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Enabled.\n");
-  }
-  
-  // From here on, every command requires that SMART be enabled...
-  if (!ataDoesSmartWork(fd)) {
-    pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
-    return returnval;
-  }
-  
-  // Turn off SMART on device
-  if (con->smartdisable){    
-    if (ataDisableSmart(fd)) {
-      pout( "Smartctl: SMART Disable Failed.\n\n");
-      failuretest(MANDATORY_CMD,returnval|=FAILSMART);
-    }
-    pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
-    return returnval;           
-  }
-  
-  // Let's ALWAYS issue this command to get the SMART status
-  code=ataSmartStatus2(fd);
-  if (code==-1)
-    failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-
-  // Enable/Disable Auto-save attributes
-  if (con->smartautosaveenable){
-    if (ataEnableAutoSave(fd)){
-      pout( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Attribute Autosave Enabled.\n");
-  }
-  if (con->smartautosavedisable){
-    if (ataDisableAutoSave(fd)){
-      pout( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Attribute Autosave Disabled.\n");
-  }
-  
-  // for everything else read values and thresholds are needed
-  if (ataReadSmartValues(fd, &smartval)){
-    pout("Smartctl: SMART Read Values failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  if (ataReadSmartThresholds(fd, &smartthres)){
-    pout("Smartctl: SMART Read Thresholds failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-
-  // Enable/Disable Off-line testing
-  if (con->smartautoofflineenable){
-    if (!isSupportAutomaticTimer(&smartval)){
-      pout("Warning: device does not support SMART Automatic Timers.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    needupdate=1;
-    if (ataEnableAutoOffline(fd)){
-      pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Automatic Offline Testing Enabled every four hours.\n");
-  }
-  if (con->smartautoofflinedisable){
-    if (!isSupportAutomaticTimer(&smartval)){
-      pout("Warning: device does not support SMART Automatic Timers.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    needupdate=1;
-    if (ataDisableAutoOffline(fd)){
-      pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Automatic Offline Testing Disabled.\n");
-  }
-
-  if (needupdate && ataReadSmartValues(fd, &smartval)){
-    pout("Smartctl: SMART Read Values failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-
-  // all this for a newline!
-  if (con->smartenable || con->smartdisable || 
-      con->smartautosaveenable || con->smartautosavedisable || 
-      con->smartautoofflineenable || con->smartautoofflinedisable)
-    pout("\n");
-
-  // START OF READ-ONLY OPTIONS APART FROM -V and -i
-  if (con->checksmart || con->generalsmartvalues || con->smartvendorattrib || con->smarterrorlog || con->smartselftestlog)
-    pout("=== START OF READ SMART DATA SECTION ===\n");
-  
-  // Check SMART status (use previously returned value)
-  if (con->checksmart){
-    switch (code) {
-
-    case 0:
-      // The case where the disk health is OK
-      pout("SMART overall-health self-assessment test result: PASSED\n");
-      if (ataCheckSmart(&smartval, &smartthres,0)){
-        if (con->smartvendorattrib)
-          pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
-        else {
-          PRINT_ON(con);
-          pout("Please note the following marginal Attributes:\n");
-          PrintSmartAttribWithThres(&smartval, &smartthres,2);
-        } 
-        returnval|=FAILAGE;
-      }
-      else
-        pout("\n");
-      break;
-      
-    case 1:
-      // The case where the disk health is NOT OK
-      PRINT_ON(con);
-      pout("SMART overall-health self-assessment test result: FAILED!\n"
-           "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-      PRINT_OFF(con);
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-        returnval|=FAILATTR;
-        if (con->smartvendorattrib)
-          pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-        else {
-          PRINT_ON(con);
-          pout("Failed Attributes:\n");
-          PrintSmartAttribWithThres(&smartval, &smartthres,1);
-        }
-      }
-      else
-        pout("No failed Attributes found.\n\n");   
-      returnval|=FAILSTATUS;
-      PRINT_OFF(con);
-      break;
-
-    case -1:
-    default:
-      // The case where something went wrong with HDIO_DRIVE_TASK ioctl()
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-        PRINT_ON(con);
-        pout("SMART overall-health self-assessment test result: FAILED!\n"
-             "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-        PRINT_OFF(con);
-        returnval|=FAILATTR;
-        returnval|=FAILSTATUS;
-        if (con->smartvendorattrib)
-          pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-        else {
-          PRINT_ON(con);
-          pout("Failed Attributes:\n");
-          PrintSmartAttribWithThres(&smartval, &smartthres,1);
-        }
-      }
-      else {
-        pout("SMART overall-health self-assessment test result: PASSED\n");
-        if (ataCheckSmart(&smartval, &smartthres,0)){
-          if (con->smartvendorattrib)
-            pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
-          else {
-            PRINT_ON(con);
-            pout("Please note the following marginal Attributes:\n");
-            PrintSmartAttribWithThres(&smartval, &smartthres,2);
-          } 
-          returnval|=FAILAGE;
-        }
-        else
-          pout("\n");
-      } 
-      PRINT_OFF(con);
-      break;
-    } // end of switch statement
-    
-    PRINT_OFF(con);
-  } // end of checking SMART Status
-  
-  // Print general SMART values
-  if (con->generalsmartvalues)
-    ataPrintGeneralSmartValues(&smartval, &drive); 
-
-  // Print vendor-specific attributes
-  if (con->smartvendorattrib){
-    PRINT_ON(con);
-    PrintSmartAttribWithThres(&smartval, &smartthres,con->printing_switchable?2:0);
-    PRINT_OFF(con);
-  }
-
-  // Print SMART log Directory
-  if (con->smartlogdirectory){
-    struct ata_smart_log_directory smartlogdirectory;
-    if (!isGeneralPurposeLoggingCapable(&drive)){
-      pout("Warning: device does not support General Purpose Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      PRINT_ON(con);
-      pout("Log Directory Supported\n");
-      if (ataReadLogDirectory(fd, &smartlogdirectory)){
-        PRINT_OFF(con);
-        pout("Read Log Directory failed.\n\n");
-        failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else
-        ataPrintLogDirectory( &smartlogdirectory);
-    }
-    PRINT_OFF(con);
-  }
-  
-  // Print SMART error log
-  if (con->smarterrorlog){
-    if (!isSmartErrorLogCapable(&smartval, &drive)){
-      pout("Warning: device does not support Error Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    if (ataReadErrorLog(fd, &smarterror)){
-      pout("Smartctl: SMART Error Log Read Failed\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      // quiet mode is turned on inside ataPrintSmartErrorLog()
-      if (ataPrintSmartErrorlog(&smarterror))
-	returnval|=FAILERR;
-      PRINT_OFF(con);
-    }
-  }
-  
-  // Print SMART self-test log
-  if (con->smartselftestlog){
-    if (!isSmartTestLogCapable(&smartval, &drive)){
-      pout("Warning: device does not support Self Test Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }    
-    if(ataReadSelfTestLog(fd, &smartselftest)){
-      pout("Smartctl: SMART Self Test Log Read Failed\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      PRINT_ON(con);
-      if (ataPrintSmartSelfTestlog(&smartselftest,!con->printing_switchable))
-	returnval|=FAILLOG;
-      PRINT_OFF(con);
-      pout("\n");
-    }
-  }
-
-  // Print SMART selective self-test log
-  if (con->selectivetestlog){
-    struct ata_selective_self_test_log log;
-    
-    if (!isSupportSelectiveSelfTest(&smartval))
-      pout("Device does not support Selective Self Tests/Logging\n");
-    else if(ataReadSelectiveSelfTestLog(fd, &log)) {
-      pout("Smartctl: SMART Selective Self Test Log Read Failed\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      PRINT_ON(con);
-      ataPrintSelectiveSelfTestLog(&log, &smartval);
-      PRINT_OFF(con);
-      pout("\n");
-    }
-  }
-
-  // START OF THE TESTING SECTION OF THE CODE.  IF NO TESTING, RETURN
-  if (con->testcase==-1)
-    return returnval;
-  
-  pout("=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
-  // if doing a self-test, be sure it's supported by the hardware
-  switch (con->testcase){
-  case OFFLINE_FULL_SCAN:
-    if (!isSupportExecuteOfflineImmediate(&smartval)){
-      pout("Warning: device does not support Execute Offline Immediate function.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case ABORT_SELF_TEST:
-  case SHORT_SELF_TEST:
-  case EXTEND_SELF_TEST:
-  case SHORT_CAPTIVE_SELF_TEST:
-  case EXTEND_CAPTIVE_SELF_TEST:
-    if (!isSupportSelfTest(&smartval)){
-      pout("Warning: device does not support Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case CONVEYANCE_SELF_TEST:
-  case CONVEYANCE_CAPTIVE_SELF_TEST:
-    if (!isSupportConveyanceSelfTest(&smartval)){
-      pout("Warning: device does not support Conveyance Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case SELECTIVE_SELF_TEST:
-  case SELECTIVE_CAPTIVE_SELF_TEST:
-    if (!isSupportSelectiveSelfTest(&smartval)){
-      pout("Warning: device does not support Selective Self-Test functions.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    break;
-  default:
-    pout("Internal error in smartctl: con->testcase==%d not recognized\n", (int)con->testcase);
-    pout("Please contact smartmontools developers at %s.\n", PACKAGE_BUGREPORT);
-    EXIT(returnval|=FAILCMD);
-  }
-
-  // Now do the test.  Note ataSmartTest prints its own error/success
-  // messages
-  if (ataSmartTest(fd, con->testcase, &smartval))
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  else {  
-    // Tell user how long test will take to complete.  This is tricky
-    // because in the case of an Offline Full Scan, the completion
-    // timer is volatile, and needs to be read AFTER the command is
-    // given. If this will interrupt the Offline Full Scan, we don't
-    // do it, just warn user.
-    if (con->testcase==OFFLINE_FULL_SCAN){
-      if (isSupportOfflineAbort(&smartval))
-	pout("Note: giving further SMART commands will abort Offline testing\n");
-      else if (ataReadSmartValues(fd, &smartval)){
-	pout("Smartctl: SMART Read Values failed.\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-    }
-    
-    // Now say how long the test will take to complete
-    if ((timewait=TestTime(&smartval,con->testcase))){ 
-      time_t t=time(NULL);
-      if (con->testcase==OFFLINE_FULL_SCAN) {
-	t+=timewait;
-	pout("Please wait %d seconds for test to complete.\n", (int)timewait);
-      } else {
-	t+=timewait*60;
-	pout("Please wait %d minutes for test to complete.\n", (int)timewait);
-      }
-      pout("Test will complete after %s\n", ctime(&t));
-      
-      if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && 
-	  con->testcase!=EXTEND_CAPTIVE_SELF_TEST && 
-	  con->testcase!=CONVEYANCE_CAPTIVE_SELF_TEST && 
-	  con->testcase!=SELECTIVE_CAPTIVE_SELF_TEST)
-	pout("Use smartctl -X to abort test.\n"); 
-    }
-  }
-
-  return returnval;
-}
diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp
deleted file mode 100644
index 13167d966dabc4fdf98da9c65c2cc1a9988211ae..0000000000000000000000000000000000000000
--- a/sm5/ataprint.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-/*
- * ataprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include "atacmdnames.h"
-#include "atacmds.h"
-#include "ataprint.h"
-#include "smartctl.h"
-#include "int64.h"
-#include "extern.h"
-#include "utility.h"
-#include "knowndrives.h"
-#include "config.h"
-
-const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.155 2004/07/13 14:48:06 ballen4705 Exp $"
-ATACMDNAMES_H_CVSID ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
-// bytes.
-void swapbytes(char *out, const char *in, size_t n)
-{
-  size_t i;
-
-  for (i = 0; i < n; i += 2) {
-    out[i]   = in[i+1];
-    out[i+1] = in[i];
-  }
-}
-
-// Copies in to out, but removes leading and trailing whitespace.
-void trim(char *out, const char *in)
-{
-  int i, first, last;
-
-  // Find the first non-space character (maybe none).
-  first = -1;
-  for (i = 0; in[i]; i++)
-    if (!isspace((int)in[i])) {
-      first = i;
-      break;
-    }
-
-  if (first == -1) {
-    // There are no non-space characters.
-    out[0] = '\0';
-    return;
-  }
-
-  // Find the last non-space character.
-  for (i = strlen(in)-1; i >= first && isspace((int)in[i]); i--)
-    ;
-  last = i;
-
-  strncpy(out, in+first, last-first+1);
-  out[last-first+1] = '\0';
-}
-
-// Convenience function for formatting strings from ata_identify_device
-void formatdriveidstring(char *out, const char *in, int n)
-{
-  char tmp[65];
-
-  n = n > 64 ? 64 : n;
-  swapbytes(tmp, in, n);
-  tmp[n] = '\0';
-  trim(out, tmp);
-}
-
-// Function for printing ASCII byte-swapped strings, skipping white
-// space. Please note that this is needed on both big- and
-// little-endian hardware.
-void printswap(char *output, char *in, unsigned int n){
-  formatdriveidstring(output, in, n);
-  if (*output)
-    pout("%s\n", output);
-  else
-    pout("[No Information Found]\n");
-}
-
-/* For the given Command Register (CR) and Features Register (FR), attempts
- * to construct a string that describes the contents of the Status
- * Register (ST) and Error Register (ER).  The string is dynamically allocated
- * memory and the return value is a pointer to this string.  It is up to the
- * caller to free this memory.  If there is insufficient memory or if the
- * meanings of the flags of the error register are not known for the given
- * command then it returns NULL.
- *
- * The meanings of the flags of the error register for all commands are
- * described in the ATA spec and could all be supported here in theory.
- * Currently, only a few commands are supported (those that have been seen
- * to produce errors).  If many more are to be added then this function
- * should probably be redesigned.
- */
-char *construct_st_er_desc(struct ata_smart_errorlog_struct *data) {
-  unsigned char CR=data->commands[4].commandreg;
-  unsigned char FR=data->commands[4].featuresreg;
-  unsigned char ST=data->error_struct.status;
-  unsigned char ER=data->error_struct.error_register;
-  char *s;
-  const char *error_flag[8];
-  int i, print_lba=0, print_sector=0;
-
-  // Set of character strings corresponding to different error codes.
-  // Please keep in alphabetic order if you add more.
-  const char  *abrt  = "ABRT";  // ABORTED
- const char   *amnf  = "AMNF";  // ADDRESS MARK NOT FOUND
- const char   *ccto  = "CCTO";  // COMMAND COMPLETTION TIMED OUT
- const char   *eom   = "EOM";   // END OF MEDIA
- const char   *icrc  = "ICRC";  // INTERFACE CRC ERROR
- const char   *idnf  = "IDNF";  // ID NOT FOUND
- const char   *ili   = "ILI";   // MEANING OF THIS BIT IS COMMAND-SET SPECIFIC
- const char   *mc    = "MC";    // MEDIA CHANGED 
- const char   *mcr   = "MCR";   // MEDIA CHANGE REQUEST
- const char   *nm    = "NM";    // NO MEDIA
- const char   *obs   = "obs";   // OBSOLETE
- const char   *tk0nf = "TK0NF"; // TRACK 0 NOT FOUND
- const char   *unc   = "UNC";   // UNCORRECTABLE
- const char   *wp    = "WP";    // WRITE PROTECTED
-
-  /* If for any command the Device Fault flag of the status register is
-   * not used then used_device_fault should be set to 0 (in the CR switch
-   * below)
-   */
-  int uses_device_fault = 1;
-
-  /* A value of NULL means that the error flag isn't used */
-  for (i = 0; i < 8; i++)
-    error_flag[i] = NULL;
-
-  switch (CR) {
-  case 0x10:  // RECALIBRATE
-    error_flag[2] = abrt;
-    error_flag[1] = tk0nf;
-    break;
-  case 0x20:  /* READ SECTOR(S) */
-  case 0x21:  // READ SECTOR(S)
-  case 0x24:  // READ SECTOR(S) EXT
-  case 0xC4:  /* READ MULTIPLE */
-  case 0x29:  // READ MULTIPLE EXT
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0x22:  // READ LONG (with retries)
-  case 0x23:  // READ LONG (without retries)
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0x2a:  // READ STREAM DMA
-  case 0x2b:  // READ STREAM PIO
-    if (CR==0x2a)
-      error_flag[7] = icrc;
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = ccto;
-    print_lba=1;
-    print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0x3A:  // WRITE STREAM DMA
-  case 0x3B:  // WRITE STREAM PIO
-    if (CR==0x3A)
-      error_flag[7] = icrc;
-    error_flag[6] = wp;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = ccto;
-    print_lba=1;
-    print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0x25:  /* READ DMA EXT */
-  case 0x26:  // READ DMA QUEUED EXT
-  case 0xC7:  // READ DMA QUEUED
-  case 0xC8:  /* READ DMA */
-  case 0xC9:
-    error_flag[7] = icrc;
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    if (CR==0x25 || CR==0xC8)
-      print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0x30:  /* WRITE SECTOR(S) */
-  case 0x31:  // WRITE SECTOR(S)
-  case 0x34:  // WRITE SECTOR(S) EXT
-  case 0xC5:  /* WRITE MULTIPLE */
-  case 0x39:  // WRITE MULTIPLE EXT
-  case 0xCE:  // WRITE MULTIPLE FUA EXT
-    error_flag[6] = wp;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    print_lba=1;
-    break;
-  case 0x32:  // WRITE LONG (with retries)
-  case 0x33:  // WRITE LONG (without retries)
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    print_lba=1;
-    break;
-  case 0x3C:  // WRITE VERIFY
-    error_flag[6] = unc;
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0x40: // READ VERIFY SECTOR(S) with retries
-  case 0x41: // READ VERIFY SECTOR(S) without retries
-  case 0x42: // READ VERIFY SECTOR(S) EXT
-    error_flag[6] = unc;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    break;
-  case 0xA0:  /* PACKET */
-    /* Bits 4-7 are all used for sense key (a 'command packet set specific error
-     * indication' according to the ATA/ATAPI-7 standard), so "Sense key" will
-     * be repeated in the error description string if more than one of those
-     * bits is set.
-     */
-    error_flag[7] = "Sense key (bit 3)",
-    error_flag[6] = "Sense key (bit 2)",
-    error_flag[5] = "Sense key (bit 1)",
-    error_flag[4] = "Sense key (bit 0)",
-    error_flag[2] = abrt;
-    error_flag[1] = eom;
-    error_flag[0] = ili;
-    break;
-  case 0xA1:  /* IDENTIFY PACKET DEVICE */
-  case 0xEF:  /* SET FEATURES */
-  case 0x00:  /* NOP */
-  case 0xC6:  /* SET MULTIPLE MODE */
-    error_flag[2] = abrt;
-    break;
-  case 0x2F:  // READ LOG EXT
-    error_flag[6] = unc;
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = obs;
-    break;
-  case 0x3F:  // WRITE LOG EXT
-    error_flag[4] = idnf;
-    error_flag[2] = abrt;
-    error_flag[0] = obs;
-    break;
-  case 0xB0:  /* SMART */
-    switch(FR) {
-    case 0xD0:  // SMART READ DATA
-    case 0xD1:  // SMART READ ATTRIBUTE THRESHOLDS
-    case 0xD5:  /* SMART READ LOG */
-      error_flag[6] = unc;
-      error_flag[4] = idnf;
-      error_flag[2] = abrt;
-      error_flag[0] = obs;
-      break;
-    case 0xD6:  /* SMART WRITE LOG */
-      error_flag[4] = idnf;
-      error_flag[2] = abrt;
-      error_flag[0] = obs;
-      break;
-    case 0xD2:  // Enable/Disable Attribute Autosave
-    case 0xD3:  // SMART SAVE ATTRIBUTE VALUES (ATA-3)
-    case 0xD8:  // SMART ENABLE OPERATIONS
-    case 0xD9:  /* SMART DISABLE OPERATIONS */
-    case 0xDA:  /* SMART RETURN STATUS */
-    case 0xDB:  // Enable/Disable Auto Offline (SFF)
-      error_flag[2] = abrt;
-      break;
-    case 0xD4:  // SMART EXECUTE IMMEDIATE OFFLINE
-      error_flag[4] = idnf;
-      error_flag[2] = abrt;
-      break;
-    default:
-      return NULL;
-      break;
-    }
-    break;
-  case 0xB1:  /* DEVICE CONFIGURATION */
-    switch (FR) {
-    case 0xC0:  /* DEVICE CONFIGURATION RESTORE */
-      error_flag[2] = abrt;
-      break;
-    default:
-      return NULL;
-      break;
-    }
-    break;
-  case 0xCA:  /* WRITE DMA */
-  case 0xCB:
-  case 0x35:  // WRITE DMA EXT
-  case 0x3D:  // WRITE DMA FUA EXT
-  case 0xCC:  // WRITE DMA QUEUED
-  case 0x36:  // WRITE DMA QUEUED EXT
-  case 0x3E:  // WRITE DMA QUEUED FUA EXT
-    error_flag[7] = icrc;
-    error_flag[6] = wp;
-    error_flag[5] = mc;
-    error_flag[4] = idnf;
-    error_flag[3] = mcr;
-    error_flag[2] = abrt;
-    error_flag[1] = nm;
-    error_flag[0] = amnf;
-    print_lba=1;
-    if (CR==0x35)
-      print_sector=(int)data->error_struct.sector_count;
-    break;
-  case 0xE4: // READ BUFFER
-  case 0xE8: // WRITE BUFFER
-    error_flag[2] = abrt;
-    break;
-  default:
-    return NULL;
-  }
-
-  /* 256 bytes -- that'll be plenty (OK, this is lazy!) */
-  if (!(s = (char *)malloc(256)))
-    return s;
-
-  s[0] = '\0';
-
-  /* We ignore any status flags other than Device Fault and Error */
-
-  if (uses_device_fault && (ST & (1 << 5))) {
-    strcat(s, "Device Fault");
-    if (ST & 1)  // Error flag
-      strcat(s, "; ");
-  }
-  if (ST & 1) {  // Error flag
-    int count = 0;
-
-    strcat(s, "Error: ");
-    for (i = 7; i >= 0; i--)
-      if ((ER & (1 << i)) && (error_flag[i])) {
-        if (count++ > 0)
-           strcat(s, ", ");
-        strcat(s, error_flag[i]);
-      }
-  }
-
-  // If the error was a READ or WRITE error, print the Logical Block
-  // Address (LBA) at which the read or write failed.
-  if (print_lba) {
-    char tmp[128];
-    int lba;
-
-    // bits 24-27: bits 0-3 of DH
-    lba   = 0xf & data->error_struct.drive_head;
-    lba <<= 8;
-    // bits 16-23: CH
-    lba  |= data->error_struct.cylinder_high;
-    lba <<= 8;
-    // bits 8-15:  CL
-    lba  |= data->error_struct.cylinder_low;
-    lba <<= 8;
-    // bits 0-7:   SN
-    lba  |= data->error_struct.sector_number;
-
-    // print number of sectors, if known, and append to print string
-    if (print_sector) {
-      snprintf(tmp, 128, " %d sectors", print_sector);
-      strcat(s, tmp);
-    }
-
-    // print LBA, and append to print string
-    snprintf(tmp, 128, " at LBA = 0x%08x = %d", lba, lba);
-    strcat(s, tmp);
-  }
-
-  return s;
-}
-
-// This returns the capacity of a disk drive and also prints this into
-// a string, using comma separators to make it easier to read.  If the
-// drive doesn't support LBA addressing or has no user writable
-// sectors (eg, CDROM or DVD) then routine returns zero.
-uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
-
-  unsigned short command_set_2  = drive->command_set_2;
-  unsigned short capabilities_0 = drive->words047_079[49-47];
-  unsigned short sects_16       = drive->words047_079[60-47];
-  unsigned short sects_32       = drive->words047_079[61-47];
-  unsigned short lba_16         = drive->words088_255[100-88];
-  unsigned short lba_32         = drive->words088_255[101-88];
-  unsigned short lba_48         = drive->words088_255[102-88];
-  unsigned short lba_64         = drive->words088_255[103-88];
-  uint64_t capacity_short=0, capacity=0, threedigits, power_of_ten;
-  int started=0,k=1000000000;
-  
-  // if drive supports LBA addressing, determine 32-bit LBA capacity
-  if (capabilities_0 & 0x0200) {
-    capacity_short = (unsigned int)sects_32 << 16 | 
-                     (unsigned int)sects_16 << 0  ;
-    
-    // if drive supports 48-bit addressing, determine THAT capacity
-    if ((command_set_2 & 0xc000) == 0x4000 && (command_set_2 & 0x0400))
-      capacity = (uint64_t)lba_64 << 48 | 
-	         (uint64_t)lba_48 << 32 |
-	         (uint64_t)lba_32 << 16 | 
-	         (uint64_t)lba_16 << 0  ;
-    
-    // choose the larger of the two possible capacities
-    if (capacity_short>capacity)
-      capacity=capacity_short;
-  }
-
-  // turn sectors into bytes
-  capacity_short = (capacity *= 512);
-  
-  // print with comma separators.  I know this is anglo-centric:
-  // tell me what to change to use LOCALE if you want.
-  power_of_ten =  k;
-  power_of_ten *= k;
-  
-  for (k=0; k<7; k++) {
-    threedigits = capacity/power_of_ten;
-    capacity   -= threedigits*power_of_ten;
-    if (started)
-      // we have already printed some digits
-      pstring += sprintf(pstring, ",%03"PRIu64, threedigits);
-    else if (threedigits || k==6) {
-      // these are the first digits that we are printing
-      pstring += sprintf(pstring, "%"PRIu64, threedigits);
-      started = 1;
-    }
-    if (k!=6)
-      power_of_ten /= 1000;
-  }
-  
-  return capacity_short;
-}
-
-void ataPrintDriveInfo (struct ata_identify_device *drive){
-  int version, drivetype;
-  const char *description;
-  char unknown[64], timedatetz[DATEANDEPOCHLEN];
-  unsigned short minorrev;
-  char model[64], serial[64], firm[64], capacity[64];
-  
-
-  // print out model, serial # and firmware versions  (byte-swap ASCI strings)
-  pout("Device Model:     ");
-  printswap(model, (char *)drive->model,40);
-
-  pout("Serial Number:    ");
-  printswap(serial, (char *)drive->serial_no,20);
-
-  pout("Firmware Version: ");
-  printswap(firm, (char *)drive->fw_rev,8);
-
-  if (determine_capacity(drive, capacity))
-    pout("User Capacity:    %s bytes\n", capacity);
-  
-  // See if drive is recognized
-  drivetype=lookupdrive(model, firm);
-  pout("Device is:        %s\n", drivetype<0?
-       "Not in smartctl database [for details use: -P showall]":
-       "In smartctl database [for details use: -P show]");
-
-  // now get ATA version info
-  version=ataVersionInfo(&description,drive, &minorrev);
-
-  // unrecognized minor revision code
-  if (!description){
-    if (!minorrev)
-      sprintf(unknown, "Exact ATA specification draft version not indicated");
-    else
-      sprintf(unknown,"Not recognized. Minor revision code: 0x%02hx", minorrev);
-    description=unknown;
-  }
-  
-  
-  // SMART Support was first added into the ATA/ATAPI-3 Standard with
-  // Revision 3 of the document, July 25, 1995.  Look at the "Document
-  // Status" revision commands at the beginning of
-  // http://www.t13.org/project/d2008r6.pdf to see this.  So it's not
-  // enough to check if we are ATA-3.  Version=-3 indicates ATA-3
-  // BEFORE Revision 3.
-  pout("ATA Version is:   %d\n",(int)abs(version));
-  pout("ATA Standard is:  %s\n",description);
-  
-  // print current time and date and timezone
-  dateandtimezone(timedatetz);
-  pout("Local Time is:    %s\n", timedatetz);
-
-  // Print warning message, if there is one
-  if (drivetype>=0 && knowndrives[drivetype].warningmsg)
-    pout("\n==> WARNING: %s\n\n", knowndrives[drivetype].warningmsg);
-
-  if (version>=3)
-    return;
-  
-  pout("SMART is only available in ATA Version 3 Revision 3 or greater.\n");
-  pout("We will try to proceed in spite of this.\n");
-  return;
-}
-
-
-const char *OfflineDataCollectionStatus(unsigned char status_byte){
-  unsigned char stat=status_byte & 0x7f;
-  
-  switch(stat){
-  case 0x00:
-    return "was never started";
-  case 0x02:
-    return "was completed without error";
-  case 0x03:
-    if (status_byte == 0x03)
-      return "is in progress";
-    else
-      return "is in a Reserved state";
-  case 0x04:
-    return "was suspended by an interrupting command from host";
-  case 0x05:
-    return "was aborted by an interrupting command from host";
-  case 0x06:
-    return "was aborted by the device with a fatal error";
-  default:
-    if (stat >= 0x40)
-      return "is in a Vendor Specific state\n";
-    else
-      return "is in a Reserved state\n";
-  }
-}
-  
-  
-  /*  prints verbose value Off-line data collection status byte */
-  void PrintSmartOfflineStatus(struct ata_smart_values *data){
-  
-  pout("Offline data collection status:  (0x%02x)\t",
-       (int)data->offline_data_collection_status);
-    
-  // Off-line data collection status byte is not a reserved
-  // or vendor specific value
-  pout("Offline data collection activity\n"
-       "\t\t\t\t\t%s.\n", OfflineDataCollectionStatus(data->offline_data_collection_status));
-  
-  // Report on Automatic Data Collection Status.  Only IBM documents
-  // this bit.  See SFF 8035i Revision 2 for details.
-  if (data->offline_data_collection_status & 0x80)
-    pout("\t\t\t\t\tAuto Offline Data Collection: Enabled.\n");
-  else
-    pout("\t\t\t\t\tAuto Offline Data Collection: Disabled.\n");
-  
-  return;
-}
-
-void PrintSmartSelfExecStatus(struct ata_smart_values *data)
-{
-   pout("Self-test execution status:      ");
-   
-   switch (data->self_test_exec_status >> 4)
-   {
-      case 0:
-        pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t",
-                (int)data->self_test_exec_status);
-        pout("without error or no self-test has ever \n\t\t\t\t\tbeen run.\n");
-        break;
-       case 1:
-         pout("(%4d)\tThe self-test routine was aborted by\n\t\t\t\t\t",
-                 (int)data->self_test_exec_status);
-         pout("the host.\n");
-         break;
-       case 2:
-         pout("(%4d)\tThe self-test routine was interrupted\n\t\t\t\t\t",
-                 (int)data->self_test_exec_status);
-         pout("by the host with a hard or soft reset.\n");
-         break;
-       case 3:
-          pout("(%4d)\tA fatal error or unknown test error\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("occurred while the device was executing\n\t\t\t\t\t");
-          pout("its self-test routine and the device \n\t\t\t\t\t");
-          pout("was unable to complete the self-test \n\t\t\t\t\t");
-          pout("routine.\n");
-          break;
-       case 4:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("a test element that failed and the test\n\t\t\t\t\t");
-          pout("element that failed is not known.\n");
-          break;
-       case 5:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the electrical element of the test\n\t\t\t\t\t");
-          pout("failed.\n");
-          break;
-       case 6:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the servo (and/or seek) element of the \n\t\t\t\t\t");
-          pout("test failed.\n");
-          break;
-       case 7:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the read element of the test failed.\n");
-          break;
-       case 15:
-          pout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("%1d0%% of test remaining.\n", 
-                  (int)(data->self_test_exec_status & 0x0f));
-          break;
-       default:
-          pout("(%4d)\tReserved.\n",
-                  (int)data->self_test_exec_status);
-          break;
-   }
-        
-}
-
-
-
-void PrintSmartTotalTimeCompleteOffline ( struct ata_smart_values *data){
-  pout("Total time to complete Offline \n");
-  pout("data collection: \t\t (%4d) seconds.\n", 
-       (int)data->total_time_to_complete_off_line);
-}
-
-
-
-void PrintSmartOfflineCollectCap(struct ata_smart_values *data){
-  pout("Offline data collection\n");
-  pout("capabilities: \t\t\t (0x%02x) ",
-       (int)data->offline_data_collection_capability);
-  
-  if (data->offline_data_collection_capability == 0x00){
-    pout("\tOffline data collection not supported.\n");
-  } 
-  else {
-    pout( "%s\n", isSupportExecuteOfflineImmediate(data)?
-          "SMART execute Offline immediate." :
-          "No SMART execute Offline immediate.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportAutomaticTimer(data)? 
-          "Auto Offline data collection on/off support.":
-          "No Auto Offline data collection support.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportOfflineAbort(data)? 
-          "Abort Offline collection upon new\n\t\t\t\t\tcommand.":
-          "Suspend Offline collection upon new\n\t\t\t\t\tcommand.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportOfflineSurfaceScan(data)? 
-          "Offline surface scan supported.":
-          "No Offline surface scan supported.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportSelfTest(data)? 
-          "Self-test supported.":
-          "No Self-test supported.");
-
-    pout( "\t\t\t\t\t%s\n", isSupportConveyanceSelfTest(data)? 
-          "Conveyance Self-test supported.":
-          "No Conveyance Self-test supported.");
-
-    pout( "\t\t\t\t\t%s\n", isSupportSelectiveSelfTest(data)? 
-          "Selective Self-test supported.":
-          "No Selective Self-test supported.");
-  }
-}
-
-
-
-void PrintSmartCapability ( struct ata_smart_values *data)
-{
-   pout("SMART capabilities:            ");
-   pout("(0x%04x)\t", (int)data->smart_capability);
-   
-   if (data->smart_capability == 0x00)
-   {
-       pout("Automatic saving of SMART data\t\t\t\t\tis not implemented.\n");
-   } 
-   else 
-   {
-        
-      pout( "%s\n", (data->smart_capability & 0x01)? 
-              "Saves SMART data before entering\n\t\t\t\t\tpower-saving mode.":
-              "Does not save SMART data before\n\t\t\t\t\tentering power-saving mode.");
-                
-      if ( data->smart_capability & 0x02 )
-      {
-          pout("\t\t\t\t\tSupports SMART auto save timer.\n");
-      }
-   }
-}
-
-void PrintSmartErrorLogCapability (struct ata_smart_values *data, struct ata_identify_device *identity)
-{
-
-   pout("Error logging capability:       ");
-    
-   if ( isSmartErrorLogCapable(data, identity) )
-   {
-      pout(" (0x%02x)\tError logging supported.\n",
-               (int)data->errorlog_capability);
-   }
-   else {
-       pout(" (0x%02x)\tError logging NOT supported.\n",
-                (int)data->errorlog_capability);
-   }
-}
-
-void PrintSmartShortSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Short self-test routine \n");
-  if (isSupportSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-         (int)data->short_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-void PrintSmartExtendedSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Extended self-test routine\n");
-  if (isSupportSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-         (int)data->extend_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-void PrintSmartConveyanceSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Conveyance self-test routine\n");
-  if (isSupportConveyanceSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-         (int)data->conveyance_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-// onlyfailed=0 : print all attribute values
-// onlyfailed=1:  just ones that are currently failed and have prefailure bit set
-// onlyfailed=2:  ones that are failed, or have failed with or without prefailure bit set
-void PrintSmartAttribWithThres (struct ata_smart_values *data, 
-                                struct ata_smart_thresholds_pvt *thresholds,
-                                int onlyfailed){
-  int i;
-  int needheader=1;
-  char rawstring[64];
-    
-  // step through all vendor attributes
-  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-    char *status;
-    struct ata_smart_attribute *disk=data->vendor_attributes+i;
-    struct ata_smart_threshold_entry *thre=thresholds->thres_entries+i;
-    
-    // consider only valid attributes
-    if (disk->id && thre->id){
-      char *type, *update;
-      int failednow,failedever;
-      char attributename[64];
-
-      failednow = (disk->current <= thre->threshold);
-      failedever= (disk->worst   <= thre->threshold);
-      
-      // These break out of the loop if we are only printing certain entries...
-      if (onlyfailed==1 && (!ATTRIBUTE_FLAGS_PREFAILURE(disk->flags) || !failednow))
-        continue;
-      
-      if (onlyfailed==2 && !failedever)
-        continue;
-      
-      // print header only if needed
-      if (needheader){
-        if (!onlyfailed){
-          pout("SMART Attributes Data Structure revision number: %d\n",(int)data->revnumber);
-          pout("Vendor Specific SMART Attributes with Thresholds:\n");
-        }
-        pout("ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE\n");
-        needheader=0;
-      }
-      
-      // is this Attribute currently failed, or has it ever failed?
-      if (failednow)
-        status="FAILING_NOW";
-      else if (failedever)
-        status="In_the_past";
-      else
-        status="    -";
-
-      // Print name of attribute
-      ataPrintSmartAttribName(attributename,disk->id, con->attributedefs);
-      pout("%-28s",attributename);
-
-      // printing line for each valid attribute
-      type=ATTRIBUTE_FLAGS_PREFAILURE(disk->flags)?"Pre-fail":"Old_age";
-      update=ATTRIBUTE_FLAGS_ONLINE(disk->flags)?"Always":"Offline";
-
-      pout("0x%04x   %.3d   %.3d   %.3d    %-10s%-9s%-12s", 
-             (int)disk->flags, (int)disk->current, (int)disk->worst,
-             (int)thre->threshold, type, update, status);
-
-      // print raw value of attribute
-      ataPrintSmartAttribRawValue(rawstring, disk, con->attributedefs);
-      pout("%s\n", rawstring);
-      
-      // print a warning if there is inconsistency here!
-      if (disk->id != thre->id){
-        char atdat[64],atthr[64];
-        ataPrintSmartAttribName(atdat, disk->id, con->attributedefs);
-        ataPrintSmartAttribName(atthr, thre->id, con->attributedefs);
-        pout("%-28s<== Data Page      |  WARNING: PREVIOUS ATTRIBUTE HAS TWO\n",atdat);
-        pout("%-28s<== Threshold Page |  INCONSISTENT IDENTITIES IN THE DATA\n",atthr);
-      }
-    }
-  }
-  if (!needheader) pout("\n");
-}
-
-void ataPrintGeneralSmartValues(struct ata_smart_values *data, struct ata_identify_device *drive){
-  pout("General SMART Values:\n");
-  
-  PrintSmartOfflineStatus(data); 
-  
-  if (isSupportSelfTest(data)){
-    PrintSmartSelfExecStatus (data);
-  }
-  
-  PrintSmartTotalTimeCompleteOffline(data);
-  PrintSmartOfflineCollectCap(data);
-  PrintSmartCapability(data);
-  
-  PrintSmartErrorLogCapability(data, drive);
-
-  pout( "\t\t\t\t\t%s\n", isGeneralPurposeLoggingCapable(drive)?
-        "General Purpose Logging supported.":
-        "No General Purpose Logging support.");
-
-  if (isSupportSelfTest(data)){
-    PrintSmartShortSelfTestPollingTime (data);
-    PrintSmartExtendedSelfTestPollingTime (data);
-  }
-  if (isSupportConveyanceSelfTest(data))
-    PrintSmartConveyanceSelfTestPollingTime (data);
-  
-  pout("\n");
-}
-
-int ataPrintLogDirectory(struct ata_smart_log_directory *data){
-  int i;
-  char *name;
-
-  pout("SMART Log Directory Logging Version %d%s\n",
-       data->logversion, data->logversion==1?" [multi-sector log support]":"");
-  for (i=0; i<=255; i++){
-    int numsect;
-    
-    // Directory log length
-    numsect = i? data->entry[i-1].numsectors : 1;
-    
-    // If the log is not empty, what is it's name
-    if (numsect){
-      switch (i) {
-      case 0:
-        name="Log Directory"; break;
-      case 1:
-        name="Summary SMART error log"; break;
-      case 2:
-        name="Comprehensive SMART error log"; break;
-      case 3:
-        name="Extended Comprehensive SMART error log"; break;
-      case 6:
-        name="SMART self-test log"; break;
-      case 7:
-        name="Extended self-test log"; break;
-      case 9:
-        name="Selective self-test log"; break;
-      case 0x20:
-        name="Streaming performance log"; break;
-      case 0x21:
-        name="Write stream error log"; break;
-      case 0x22:
-        name="Read stream error log"; break;
-      case 0x23:
-        name="Delayed sector log"; break;
-      default:
-        if (0xa0<=i && i<=0xbf) 
-          name="Device vendor specific log";
-        else if (0x80<=i && i<=0x9f)
-          name="Host vendor specific log";
-        else
-          name="Reserved log";
-        break;
-      }
-
-      // print name and length of log
-      pout("Log at address 0x%02x has %03d sectors [%s]\n",
-           i, numsect, name);
-    }
-  }
-  return 0;
-}
-
-// returns number of errors
-int ataPrintSmartErrorlog(struct ata_smart_errorlog *data){
-  int k;
-
-  pout("SMART Error Log Version: %d\n", (int)data->revnumber);
-  
-  // if no errors logged, return
-  if (!data->error_log_pointer){
-    pout("No Errors Logged\n\n");
-    return 0;
-  }
-  PRINT_ON(con);
-  // If log pointer out of range, return
-  if (data->error_log_pointer>5){
-    pout("Invalid Error Log index = 0x%02x (T13/1321D rev 1c "
-         "Section 8.41.6.8.2.2 gives valid range from 1 to 5)\n\n",
-         (int)data->error_log_pointer);
-    return 0;
-  }
-
-  // Some internal consistency checking of the data structures
-  if ((data->ata_error_count-data->error_log_pointer)%5 && con->fixfirmwarebug != FIX_SAMSUNG2) {
-    pout("Warning: ATA error count %d inconsistent with error log pointer %d\n\n",
-         data->ata_error_count,data->error_log_pointer);
-  }
-  
-  // starting printing error log info
-  if (data->ata_error_count<=5)
-    pout( "ATA Error Count: %d\n", (int)data->ata_error_count);
-  else
-    pout( "ATA Error Count: %d (device log contains only the most recent five errors)\n",
-           (int)data->ata_error_count);
-  PRINT_OFF(con);
-  pout("\tCR = Command Register [HEX]\n"
-       "\tFR = Features Register [HEX]\n"
-       "\tSC = Sector Count Register [HEX]\n"
-       "\tSN = Sector Number Register [HEX]\n"
-       "\tCL = Cylinder Low Register [HEX]\n"
-       "\tCH = Cylinder High Register [HEX]\n"
-       "\tDH = Device/Head Register [HEX]\n"
-       "\tDC = Device Command Register [HEX]\n"
-       "\tER = Error register [HEX]\n"
-       "\tST = Status register [HEX]\n"
-       "Powered_Up_Time is measured from power on, and printed as\n"
-       "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
-       "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
-  
-  // now step through the five error log data structures (table 39 of spec)
-  for (k = 4; k >= 0; k-- ) {
-    char *st_er_desc;
-
-    // The error log data structure entries are a circular buffer
-    int j, i=(data->error_log_pointer+k)%5;
-    struct ata_smart_errorlog_struct *elog=data->errorlog_struct+i;
-    struct ata_smart_errorlog_error_struct *summary=&(elog->error_struct);
-
-    // Spec says: unused error log structures shall be zero filled
-    if (nonempty((unsigned char*)elog,sizeof(*elog))){
-      // Table 57 of T13/1532D Volume 1 Revision 3
-      char *msgstate;
-      int bits=summary->state & 0x0f;
-      int days = (int)summary->timestamp/24;
-
-      switch (bits){
-      case 0x00: msgstate="in an unknown state";break;
-      case 0x01: msgstate="sleeping"; break;
-      case 0x02: msgstate="in standby mode"; break;
-      case 0x03: msgstate="active or idle"; break;
-      case 0x04: msgstate="doing SMART Offline or Self-test"; break;
-      default:   
-        if (bits<0x0b)
-          msgstate="in a reserved state";
-        else
-          msgstate="in a vendor specific state";
-      }
-
-      // See table 42 of ATA5 spec
-      PRINT_ON(con);
-      pout("Error %d occurred at disk power-on lifetime: %d hours (%d days + %d hours)\n",
-             (int)(data->ata_error_count+k-4), (int)summary->timestamp, days, (int)(summary->timestamp-24*days));
-      PRINT_OFF(con);
-      pout("  When the command that caused the error occurred, the device was %s.\n\n",msgstate);
-      pout("  After command completion occurred, registers were:\n"
-           "  ER ST SC SN CL CH DH\n"
-           "  -- -- -- -- -- -- --\n"
-           "  %02x %02x %02x %02x %02x %02x %02x",
-           (int)summary->error_register,
-           (int)summary->status,
-           (int)summary->sector_count,
-           (int)summary->sector_number,
-           (int)summary->cylinder_low,
-           (int)summary->cylinder_high,
-           (int)summary->drive_head);
-      // Add a description of the contents of the status and error registers
-      // if possible
-      st_er_desc = construct_st_er_desc(elog);
-      if (st_er_desc) {
-        pout("  %s", st_er_desc);
-        free(st_er_desc);
-      }
-      pout("\n\n");
-      pout("  Commands leading to the command that caused the error were:\n"
-           "  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name\n"
-           "  -- -- -- -- -- -- -- --  ----------------  --------------------\n");
-      for ( j = 4; j >= 0; j--){
-        struct ata_smart_errorlog_command_struct *thiscommand=elog->commands+j;
-
-        // Spec says: unused data command structures shall be zero filled
-        if (nonempty((unsigned char*)thiscommand,sizeof(*thiscommand))) {
-	  char timestring[32];
-	  
-	  // Convert integer milliseconds to a text-format string
-	  MsecToText(thiscommand->timestamp, timestring);
-	  
-          pout("  %02x %02x %02x %02x %02x %02x %02x %02x  %16s  %s\n",
-               (int)thiscommand->commandreg,
-               (int)thiscommand->featuresreg,
-               (int)thiscommand->sector_count,
-               (int)thiscommand->sector_number,
-               (int)thiscommand->cylinder_low,
-               (int)thiscommand->cylinder_high,
-               (int)thiscommand->drive_head,
-               (int)thiscommand->devicecontrolreg,
-	       timestring,
-               look_up_ata_command(thiscommand->commandreg, thiscommand->featuresreg));
-	}
-      }
-      pout("\n");
-    }
-  }
-  PRINT_ON(con);
-  if (con->printing_switchable)
-    pout("\n");
-  PRINT_OFF(con);
-  return data->ata_error_count;  
-}
-
-void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struct ata_smart_values *sv) {
-  int i,field1,field2;
-  char *msg;
-  char tmp[64];
-  uint64_t maxl=0,maxr=0;
-  uint64_t current=log->currentlba;
-  uint64_t currentend=current+65535;
-
-  // print data structure revision number
-  pout("SMART Selective self-test log data structure revision number %d\n",(int)log->logversion);
-  if (1 != log->logversion)
-    pout("Warning: ATA Specification requires selective self-test log data structure revision number = 1\n");
-  
-  switch((sv->self_test_exec_status)>>4){
-  case  0:msg="Completed";
-    break;
-  case  1:msg="Aborted_by_host";
-    break;
-  case  2:msg="Interrupted";
-    break;
-  case  3:msg="Fatal_error";
-    break;
-  case  4:msg="Completed_unknown_failure";
-    break;
-  case  5:msg="Completed_electrical_failure";
-    break;
-  case  6:msg="Completed_servo/seek_failure";
-    break;
-  case  7:msg="Completed_read_failure";
-    break;
-  case  8:msg="Completed_handling_damage??";
-    break;
-  case 15:msg="Self_test_in_progress";
-    break;
-  default:msg="Unknown_status ";
-    break;
-  }
-
-  // find the number of columns needed for printing. If in use, the
-  // start/end of span being read-scanned...
-  if (log->currentspan>5) {
-    maxl=current;
-    maxr=currentend;
-  }
-  for (i=0; i<5; i++) {
-    uint64_t start=log->span[i].start;
-    uint64_t end  =log->span[i].end; 
-    // ... plus max start/end of each of the five test spans.
-    if (start>maxl)
-      maxl=start;
-    if (end > maxr)
-      maxr=end;
-  }
-  
-  // we need at least 7 characters wide fields to accomodate the
-  // labels
-  if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7)
-    field1=7;
-  if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7)
-    field2=7;
-
-  // now print the five test spans
-  pout(" SPAN  %*s  %*s  CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA");
-
-  for (i=0; i<5; i++) {
-    uint64_t start=log->span[i].start;
-    uint64_t end=log->span[i].end;
-    
-    if ((i+1)==(int)log->currentspan)
-      // this span is currently under test
-      pout("    %d  %*"PRIu64"  %*"PRIu64"  %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n",
-	   i+1, field1, start, field2, end, msg,
-	   (int)(sv->self_test_exec_status & 0x7), current, currentend);
-    else
-      // this span is not currently under test
-      pout("    %d  %*"PRIu64"  %*"PRIu64"  Not_testing\n",
-	   i+1, field1, start, field2, end);
-  }  
-  
-  // if we are currently read-scanning, print LBAs and the status of
-  // the read scan
-  if (log->currentspan>5)
-    pout("%5d  %*"PRIu64"  %*"PRIu64"  Read_scanning %s\n",
-	 (int)log->currentspan, field1, current, field2, currentend,
-	 OfflineDataCollectionStatus(sv->offline_data_collection_status));
-  
-  /* Print selective self-test flags.  Possible flag combinations are
-     (numbering bits from 0-15):
-     Bit-1 Bit-3   Bit-4
-     Scan  Pending Active
-     0     *       *       Don't scan
-     1     0       0       Will carry out scan after selective test
-     1     1       0       Waiting to carry out scan after powerup
-     1     0       1       Currently scanning       
-     1     1       1       Currently scanning
-  */
-  
-  pout("Selective self-test flags (0x%x):\n", (unsigned int)log->flags);
-  if (log->flags & SELECTIVE_FLAG_DOSCAN) {
-    if (log->flags & SELECTIVE_FLAG_ACTIVE)
-      pout("  Currently read-scanning the remainder of the disk.\n");
-    else if (log->flags & SELECTIVE_FLAG_PENDING)
-      pout("  Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",
-	   (int)log->pendingtime);
-    else
-      pout("  After scanning selected spans, read-scan remainder of disk.\n");
-  }
-  else
-    pout("  After scanning selected spans, do NOT read-scan remainder of disk.\n");
-  
-  // print pending time
-  pout("If Selective self-test is pending on power-up, resume after %d minute delay.\n",
-       (int)log->pendingtime);
-
-  return; 
-}
-
-// return value is:
-// bottom 8 bits: number of entries found where self-test showed an error
-// remaining bits: if nonzero, power on hours of last self-test where error was found
-int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *data,int allentries){
-  int i,j,noheaderprinted=1;
-  int retval=0, hours=0, testno=0;
-
-  if (allentries)
-    pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);
-  if ((data->revnumber!=0x0001) && allentries && con->fixfirmwarebug != FIX_SAMSUNG)
-    pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
-  if (data->mostrecenttest==0){
-    if (allentries)
-      pout("No self-tests have been logged.  [To run self-tests, use: smartctl -t]\n\n");
-    return 0;
-  }
-
-  // print log      
-  for (i=20;i>=0;i--){    
-    struct ata_smart_selftestlog_struct *log;
-
-    // log is a circular buffer
-    j=(i+data->mostrecenttest)%21;
-    log=data->selftest_struct+j;
-
-    if (nonempty((unsigned char*)log,sizeof(*log))){
-      char *msgtest,*msgstat,percent[64],firstlba[64];
-      int errorfound=0;
-      
-      // count entry based on non-empty structures -- needed for
-      // Seagate only -- other vendors don't have blank entries 'in
-      // the middle'
-      testno++;
-
-      // test name
-      switch(log->selftestnumber){
-      case   0: msgtest="Offline            "; break;
-      case   1: msgtest="Short offline      "; break;
-      case   2: msgtest="Extended offline   "; break;
-      case   3: msgtest="Conveyance offline "; break;
-      case   4: msgtest="Selective offline  "; break;
-      case 127: msgtest="Abort offline test "; break;
-      case 129: msgtest="Short captive      "; break;
-      case 130: msgtest="Extended captive   "; break;
-      case 131: msgtest="Conveyance captive "; break;
-      case 132: msgtest="Selective captive  "; break;
-      default:  
-        if ( log->selftestnumber>=192 ||
-            (log->selftestnumber>= 64 && log->selftestnumber<=126))
-          msgtest="Vendor offline     ";
-        else
-          msgtest="Reserved offline   ";
-      }
-      
-      // test status
-      switch((log->selfteststatus)>>4){
-      case  0:msgstat="Completed without error      "; break;
-      case  1:msgstat="Aborted by host              "; break;
-      case  2:msgstat="Interrupted (host reset)     "; break;
-      case  3:msgstat="Fatal or unknown error       "; errorfound=1; break;
-      case  4:msgstat="Completed: unknown failure   "; errorfound=1; break;
-      case  5:msgstat="Completed: electrical failure"; errorfound=1; break;
-      case  6:msgstat="Completed: servo/seek failure"; errorfound=1; break;
-      case  7:msgstat="Completed: read failure      "; errorfound=1; break;
-      case  8:msgstat="Completed: handling damage?? "; errorfound=1; break;
-      case 15:msgstat="Self-test routine in progress"; break;
-      default:msgstat="Unknown/reserved test status ";
-      }
-
-      retval+=errorfound;
-      sprintf(percent,"%1d0%%",(log->selfteststatus)&0xf);
-
-      // T13/1321D revision 1c: (Data structure Rev #1)
-
-      //The failing LBA shall be the LBA of the uncorrectable sector
-      //that caused the test to fail. If the device encountered more
-      //than one uncorrectable sector during the test, this field
-      //shall indicate the LBA of the first uncorrectable sector
-      //encountered. If the test passed or the test failed for some
-      //reason other than an uncorrectable sector, the value of this
-      //field is undefined.
-
-      // This is true in ALL ATA-5 specs
-      
-      if (!errorfound || log->lbafirstfailure==0xffffffff || log->lbafirstfailure==0x00000000)
-        sprintf(firstlba,"%s","-");
-      else      
-        sprintf(firstlba,"%u",log->lbafirstfailure);
-
-      // print out a header if needed
-      if (noheaderprinted && (allentries || errorfound)){
-        pout("Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error\n");
-        noheaderprinted=0;
-      }
-      
-      // print out an entry, either if we are printing all entries OR
-      // if an error was found
-      if (allentries || errorfound)
-        pout("#%2d  %s %s %s  %8d         %s\n", testno, msgtest, msgstat, percent, (int)log->timestamp, firstlba);
-
-      // keep track of time of most recent error
-      if (errorfound && !hours)
-        hours=log->timestamp;
-    }
-  }
-  if (!allentries && retval)
-    pout("\n");
-
-  hours = hours << 8;
-  return (retval | hours);
-}
-
-void ataPseudoCheckSmart ( struct ata_smart_values *data, 
-                           struct ata_smart_thresholds_pvt *thresholds) {
-  int i;
-  int failed = 0;
-  for (i = 0 ; i < NUMBER_ATA_SMART_ATTRIBUTES ; i++) {
-    if (data->vendor_attributes[i].id &&   
-        thresholds->thres_entries[i].id &&
-        ATTRIBUTE_FLAGS_PREFAILURE(data->vendor_attributes[i].flags) &&
-        (data->vendor_attributes[i].current <= thresholds->thres_entries[i].threshold) &&
-        (thresholds->thres_entries[i].threshold != 0xFE)){
-      pout("Attribute ID %d Failed\n",(int)data->vendor_attributes[i].id);
-      failed = 1;
-    } 
-  }   
-  pout("%s\n", ( failed )?
-         "SMART overall-health self-assessment test result: FAILED!\n"
-         "Drive failure expected in less than 24 hours. SAVE ALL DATA":
-         "SMART overall-health self-assessment test result: PASSED");
-}
-
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-void failuretest(int type, int returnvalue){
-
-  // If this is an error in an "optional" SMART command
-  if (type==OPTIONAL_CMD){
-    if (con->conservative){
-      pout("An optional SMART command failed: exiting.  Remove '-T conservative' option to continue.\n");
-      EXIT(returnvalue);
-    }
-    return;
-  }
-
-  // If this is an error in a "mandatory" SMART command
-  if (type==MANDATORY_CMD){
-    if (con->permissive--)
-      return;
-    pout("A mandatory SMART command failed: exiting. To continue, add one or more '-T permissive' options.\n");
-    EXIT(returnvalue);
-  }
-
-  pout("Smartctl internal error in failuretest(type=%d). Please contact developers at " PACKAGE_HOMEPAGE "\n",type);
-  EXIT(returnvalue|FAILCMD);
-}
-
-// Used to warn users about invalid checksums.  Action to be taken may be
-// altered by the user.
-void checksumwarning(const char *string){
-  // user has asked us to ignore checksum errors
-  if (con->checksumignore)
-        return;
-
-  pout("Warning! %s error: invalid SMART checksum.\n",string);
-
-  // user has asked us to fail on checksum errors
-  if (con->checksumfail)
-    EXIT(FAILSMART);
-
-  return;
-}
-
-// Initialize to zero just in case some SMART routines don't work
-struct ata_identify_device drive;
-struct ata_smart_values smartval;
-struct ata_smart_thresholds_pvt smartthres;
-struct ata_smart_errorlog smarterror;
-struct ata_smart_selftestlog smartselftest;
-
-int ataPrintMain (int fd){
-  int timewait,code;
-  int returnval=0, retid=0, supported=0, needupdate=0;
-
-  // Start by getting Drive ID information.  We need this, to know if SMART is supported.
-  if ((retid=ataReadHDIdentity(fd,&drive))<0){
-    pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n");
-    failuretest(MANDATORY_CMD, returnval|=FAILID);
-  }
-
-  // If requested, show which presets would be used for this drive and exit.
-  if (con->showpresets) {
-    showpresets(&drive);
-    EXIT(0);
-  }
-
-  // Use preset vendor attribute options unless user has requested otherwise.
-  if (!con->ignorepresets){
-    unsigned char *charptr;
-    if ((charptr=con->attributedefs))
-      applypresets(&drive, &charptr, con);
-    else {
-      pout("Fatal internal error in ataPrintMain()\n");
-      EXIT(returnval|=FAILCMD);
-    }
-  }
-
-  // Print most drive identity information if requested
-  if (con->driveinfo){
-    pout("=== START OF INFORMATION SECTION ===\n");
-    ataPrintDriveInfo(&drive);
-  }
-
-  // Was this a packet device?
-  if (retid>0){
-    pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n", packetdevicetype(retid-1));
-    failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-  }
-  
-  // if drive does not supports SMART it's time to exit
-  supported=ataSmartSupport(&drive);
-  if (supported != 1){
-    if (supported==0) {
-      pout("SMART support is: Unavailable - device lacks SMART capability.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      pout("                  Checking to be sure by trying SMART ENABLE command.\n");
-    }
-    else {
-      pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      pout("                  Checking for SMART support by trying SMART ENABLE command.\n");
-    }
-
-    if (ataEnableSmart(fd)){
-      pout("                  SMART ENABLE failed - this establishes that this device lacks SMART functionality.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      supported=0;
-    }
-    else {
-      pout("                  SMART ENABLE appeared to work!  Continuing.\n");
-      supported=1;
-    }
-    if (!con->driveinfo) pout("\n");
-  }
-  
-  // Now print remaining drive info: is SMART enabled?    
-  if (con->driveinfo){
-    int ison=ataIsSmartEnabled(&drive),isenabled=ison;
-    
-    if (ison==-1) {
-      pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      // check SMART support by trying a command
-      pout("                  Checking to be sure by trying SMART RETURN STATUS command.\n");
-      isenabled=ataDoesSmartWork(fd);
-    }
-    else
-      pout("SMART support is: Available - device has SMART capability.\n");
-    
-    if (isenabled)
-      pout("SMART support is: Enabled\n");
-    else {
-      if (ison==-1)
-        pout("SMART support is: Unavailable\n");
-      else
-        pout("SMART support is: Disabled\n");
-    }
-    pout("\n");
-  }
-  
-  // START OF THE ENABLE/DISABLE SECTION OF THE CODE
-  if (con->smartenable || con->smartdisable || 
-      con->smartautosaveenable || con->smartautosavedisable || 
-      con->smartautoofflineenable || con->smartautoofflinedisable)
-    pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
-  
-  // Enable/Disable SMART commands
-  if (con->smartenable){
-    if (ataEnableSmart(fd)) {
-      pout("Smartctl: SMART Enable Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Enabled.\n");
-  }
-  
-  // From here on, every command requires that SMART be enabled...
-  if (!ataDoesSmartWork(fd)) {
-    pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
-    return returnval;
-  }
-  
-  // Turn off SMART on device
-  if (con->smartdisable){    
-    if (ataDisableSmart(fd)) {
-      pout( "Smartctl: SMART Disable Failed.\n\n");
-      failuretest(MANDATORY_CMD,returnval|=FAILSMART);
-    }
-    pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
-    return returnval;           
-  }
-  
-  // Let's ALWAYS issue this command to get the SMART status
-  code=ataSmartStatus2(fd);
-  if (code==-1)
-    failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-
-  // Enable/Disable Auto-save attributes
-  if (con->smartautosaveenable){
-    if (ataEnableAutoSave(fd)){
-      pout( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Attribute Autosave Enabled.\n");
-  }
-  if (con->smartautosavedisable){
-    if (ataDisableAutoSave(fd)){
-      pout( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Attribute Autosave Disabled.\n");
-  }
-  
-  // for everything else read values and thresholds are needed
-  if (ataReadSmartValues(fd, &smartval)){
-    pout("Smartctl: SMART Read Values failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  if (ataReadSmartThresholds(fd, &smartthres)){
-    pout("Smartctl: SMART Read Thresholds failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-
-  // Enable/Disable Off-line testing
-  if (con->smartautoofflineenable){
-    if (!isSupportAutomaticTimer(&smartval)){
-      pout("Warning: device does not support SMART Automatic Timers.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    needupdate=1;
-    if (ataEnableAutoOffline(fd)){
-      pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Automatic Offline Testing Enabled every four hours.\n");
-  }
-  if (con->smartautoofflinedisable){
-    if (!isSupportAutomaticTimer(&smartval)){
-      pout("Warning: device does not support SMART Automatic Timers.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    needupdate=1;
-    if (ataDisableAutoOffline(fd)){
-      pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Automatic Offline Testing Disabled.\n");
-  }
-
-  if (needupdate && ataReadSmartValues(fd, &smartval)){
-    pout("Smartctl: SMART Read Values failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-
-  // all this for a newline!
-  if (con->smartenable || con->smartdisable || 
-      con->smartautosaveenable || con->smartautosavedisable || 
-      con->smartautoofflineenable || con->smartautoofflinedisable)
-    pout("\n");
-
-  // START OF READ-ONLY OPTIONS APART FROM -V and -i
-  if (con->checksmart || con->generalsmartvalues || con->smartvendorattrib || con->smarterrorlog || con->smartselftestlog)
-    pout("=== START OF READ SMART DATA SECTION ===\n");
-  
-  // Check SMART status (use previously returned value)
-  if (con->checksmart){
-    switch (code) {
-
-    case 0:
-      // The case where the disk health is OK
-      pout("SMART overall-health self-assessment test result: PASSED\n");
-      if (ataCheckSmart(&smartval, &smartthres,0)){
-        if (con->smartvendorattrib)
-          pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
-        else {
-          PRINT_ON(con);
-          pout("Please note the following marginal Attributes:\n");
-          PrintSmartAttribWithThres(&smartval, &smartthres,2);
-        } 
-        returnval|=FAILAGE;
-      }
-      else
-        pout("\n");
-      break;
-      
-    case 1:
-      // The case where the disk health is NOT OK
-      PRINT_ON(con);
-      pout("SMART overall-health self-assessment test result: FAILED!\n"
-           "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-      PRINT_OFF(con);
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-        returnval|=FAILATTR;
-        if (con->smartvendorattrib)
-          pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-        else {
-          PRINT_ON(con);
-          pout("Failed Attributes:\n");
-          PrintSmartAttribWithThres(&smartval, &smartthres,1);
-        }
-      }
-      else
-        pout("No failed Attributes found.\n\n");   
-      returnval|=FAILSTATUS;
-      PRINT_OFF(con);
-      break;
-
-    case -1:
-    default:
-      // The case where something went wrong with HDIO_DRIVE_TASK ioctl()
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-        PRINT_ON(con);
-        pout("SMART overall-health self-assessment test result: FAILED!\n"
-             "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-        PRINT_OFF(con);
-        returnval|=FAILATTR;
-        returnval|=FAILSTATUS;
-        if (con->smartvendorattrib)
-          pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-        else {
-          PRINT_ON(con);
-          pout("Failed Attributes:\n");
-          PrintSmartAttribWithThres(&smartval, &smartthres,1);
-        }
-      }
-      else {
-        pout("SMART overall-health self-assessment test result: PASSED\n");
-        if (ataCheckSmart(&smartval, &smartthres,0)){
-          if (con->smartvendorattrib)
-            pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
-          else {
-            PRINT_ON(con);
-            pout("Please note the following marginal Attributes:\n");
-            PrintSmartAttribWithThres(&smartval, &smartthres,2);
-          } 
-          returnval|=FAILAGE;
-        }
-        else
-          pout("\n");
-      } 
-      PRINT_OFF(con);
-      break;
-    } // end of switch statement
-    
-    PRINT_OFF(con);
-  } // end of checking SMART Status
-  
-  // Print general SMART values
-  if (con->generalsmartvalues)
-    ataPrintGeneralSmartValues(&smartval, &drive); 
-
-  // Print vendor-specific attributes
-  if (con->smartvendorattrib){
-    PRINT_ON(con);
-    PrintSmartAttribWithThres(&smartval, &smartthres,con->printing_switchable?2:0);
-    PRINT_OFF(con);
-  }
-
-  // Print SMART log Directory
-  if (con->smartlogdirectory){
-    struct ata_smart_log_directory smartlogdirectory;
-    if (!isGeneralPurposeLoggingCapable(&drive)){
-      pout("Warning: device does not support General Purpose Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      PRINT_ON(con);
-      pout("Log Directory Supported\n");
-      if (ataReadLogDirectory(fd, &smartlogdirectory)){
-        PRINT_OFF(con);
-        pout("Read Log Directory failed.\n\n");
-        failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else
-        ataPrintLogDirectory( &smartlogdirectory);
-    }
-    PRINT_OFF(con);
-  }
-  
-  // Print SMART error log
-  if (con->smarterrorlog){
-    if (!isSmartErrorLogCapable(&smartval, &drive)){
-      pout("Warning: device does not support Error Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    if (ataReadErrorLog(fd, &smarterror)){
-      pout("Smartctl: SMART Error Log Read Failed\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      // quiet mode is turned on inside ataPrintSmartErrorLog()
-      if (ataPrintSmartErrorlog(&smarterror))
-	returnval|=FAILERR;
-      PRINT_OFF(con);
-    }
-  }
-  
-  // Print SMART self-test log
-  if (con->smartselftestlog){
-    if (!isSmartTestLogCapable(&smartval, &drive)){
-      pout("Warning: device does not support Self Test Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }    
-    if(ataReadSelfTestLog(fd, &smartselftest)){
-      pout("Smartctl: SMART Self Test Log Read Failed\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      PRINT_ON(con);
-      if (ataPrintSmartSelfTestlog(&smartselftest,!con->printing_switchable))
-	returnval|=FAILLOG;
-      PRINT_OFF(con);
-      pout("\n");
-    }
-  }
-
-  // Print SMART selective self-test log
-  if (con->selectivetestlog){
-    struct ata_selective_self_test_log log;
-    
-    if (!isSupportSelectiveSelfTest(&smartval))
-      pout("Device does not support Selective Self Tests/Logging\n");
-    else if(ataReadSelectiveSelfTestLog(fd, &log)) {
-      pout("Smartctl: SMART Selective Self Test Log Read Failed\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      PRINT_ON(con);
-      ataPrintSelectiveSelfTestLog(&log, &smartval);
-      PRINT_OFF(con);
-      pout("\n");
-    }
-  }
-
-  // START OF THE TESTING SECTION OF THE CODE.  IF NO TESTING, RETURN
-  if (con->testcase==-1)
-    return returnval;
-  
-  pout("=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
-  // if doing a self-test, be sure it's supported by the hardware
-  switch (con->testcase){
-  case OFFLINE_FULL_SCAN:
-    if (!isSupportExecuteOfflineImmediate(&smartval)){
-      pout("Warning: device does not support Execute Offline Immediate function.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case ABORT_SELF_TEST:
-  case SHORT_SELF_TEST:
-  case EXTEND_SELF_TEST:
-  case SHORT_CAPTIVE_SELF_TEST:
-  case EXTEND_CAPTIVE_SELF_TEST:
-    if (!isSupportSelfTest(&smartval)){
-      pout("Warning: device does not support Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case CONVEYANCE_SELF_TEST:
-  case CONVEYANCE_CAPTIVE_SELF_TEST:
-    if (!isSupportConveyanceSelfTest(&smartval)){
-      pout("Warning: device does not support Conveyance Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case SELECTIVE_SELF_TEST:
-  case SELECTIVE_CAPTIVE_SELF_TEST:
-    if (!isSupportSelectiveSelfTest(&smartval)){
-      pout("Warning: device does not support Selective Self-Test functions.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    break;
-  default:
-    pout("Internal error in smartctl: con->testcase==%d not recognized\n", (int)con->testcase);
-    pout("Please contact smartmontools developers at %s.\n", PACKAGE_BUGREPORT);
-    EXIT(returnval|=FAILCMD);
-  }
-
-  // Now do the test.  Note ataSmartTest prints its own error/success
-  // messages
-  if (ataSmartTest(fd, con->testcase, &smartval))
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  else {  
-    // Tell user how long test will take to complete.  This is tricky
-    // because in the case of an Offline Full Scan, the completion
-    // timer is volatile, and needs to be read AFTER the command is
-    // given. If this will interrupt the Offline Full Scan, we don't
-    // do it, just warn user.
-    if (con->testcase==OFFLINE_FULL_SCAN){
-      if (isSupportOfflineAbort(&smartval))
-	pout("Note: giving further SMART commands will abort Offline testing\n");
-      else if (ataReadSmartValues(fd, &smartval)){
-	pout("Smartctl: SMART Read Values failed.\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-    }
-    
-    // Now say how long the test will take to complete
-    if ((timewait=TestTime(&smartval,con->testcase))){ 
-      time_t t=time(NULL);
-      if (con->testcase==OFFLINE_FULL_SCAN) {
-	t+=timewait;
-	pout("Please wait %d seconds for test to complete.\n", (int)timewait);
-      } else {
-	t+=timewait*60;
-	pout("Please wait %d minutes for test to complete.\n", (int)timewait);
-      }
-      pout("Test will complete after %s\n", ctime(&t));
-      
-      if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && 
-	  con->testcase!=EXTEND_CAPTIVE_SELF_TEST && 
-	  con->testcase!=CONVEYANCE_CAPTIVE_SELF_TEST && 
-	  con->testcase!=SELECTIVE_CAPTIVE_SELF_TEST)
-	pout("Use smartctl -X to abort test.\n"); 
-    }
-  }
-
-  return returnval;
-}
diff --git a/sm5/ataprint.h b/sm5/ataprint.h
deleted file mode 100644
index 348b4a61c1e8459f61122e3003f3e1005036d634..0000000000000000000000000000000000000000
--- a/sm5/ataprint.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * ataprint.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef ATAPRINT_H_
-#define ATAPRINT_H_
-
-#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.26 2004/01/27 15:29:16 ballen4705 Exp $\n"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* Prints ATA Drive Information and S.M.A.R.T. Capability */
-void ataPrintDriveInfo(struct ata_identify_device *);
-
-void ataPrintGeneralSmartValues(struct ata_smart_values *, struct ata_identify_device *);
-
-void ataPrintSmartThresholds(struct ata_smart_thresholds_pvt *);
-
-// returns number of errors in Errorlog
-int  ataPrintSmartErrorlog(struct ata_smart_errorlog *);
-
-int ataPrintLogDirectory(struct ata_smart_log_directory *);
-
-void PrintSmartAttributes(struct ata_smart_values *);
-
-void PrintSmartAttribWithThres(struct ata_smart_values *,
-                                struct ata_smart_thresholds_pvt *,
-                                int onlyfailed);
-
-// returns number of entries that had logged errors
-int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *, int allentries);
-
-void ataPseudoCheckSmart(struct ata_smart_values *, struct ata_smart_thresholds_pvt *);
-
-// Convenience function for formatting strings from ata_identify_device.
-void formatdriveidstring(char *out, const char *in, int n);
-
-int ataPrintMain(int fd);
-
-#endif
diff --git a/sm5/autogen.sh b/sm5/autogen.sh
deleted file mode 100755
index c8ba690fc7cbafe52b834c194394dc94e5f36234..0000000000000000000000000000000000000000
--- a/sm5/autogen.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/sh
-# $Id: autogen.sh,v 1.8 2004/05/27 15:23:16 card_captor Exp $
-#
-# Generate ./configure from config.in and Makefile.in from Makefile.am.
-# This also adds files like missing,depcomp,install-sh to the source
-# direcory. To update these files at a later date use:
-#	autoreconf -f -i -v
-
-
-# Cygwin?
-test -x /usr/bin/uname && /usr/bin/uname | grep -i CYGWIN >/dev/null &&
-{
-    # Enable strict case checking
-    # (to avoid e.g "DIST_COMMON = ... ChangeLog ..." in Makefile.in)
-    export CYGWIN="${CYGWIN}${CYGWIN:+ }check_case:strict"
-
-    # Check for Unix text file type
-    echo > dostest.tmp
-    test "`wc -c < dostest.tmp`" -eq 1 ||
-        echo "Warning: DOS text file type set, 'make dist' and related targets will not work."
-    rm -f dostest.tmp
-}
-
-typep()
-{
-    cmd=$1 ; TMP=$IFS ; IFS=: ; set $PATH
-    for dir
-    do
-	if [ -x "$dir/$cmd" ]; then
-	    echo "$dir/$cmd"
-	    IFS=$TMP
-	    return 0
-        fi
-    done
-    IFS=$TMP
-    return 1
-}
-
-test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.8` || AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
-{
-echo
-echo "You must have at least GNU Automake 1.7 (up to 1.8.x) installed"
-echo "in order to bootstrap smartmontools from CVS. Download the"
-echo "appropriate package for your distribution, or the source tarball"
-echo "from ftp://ftp.gnu.org/gnu/automake/ ."
-echo
-echo "Also note that support for new Automake series (anything newer"
-echo "than 1.8.x) is only added after extensive tests. If you live in"
-echo "the bleeding edge, you should know what you're doing, mainly how"
-echo "to test it before the developers. Be patient."
-exit 1;
-}
-
-test -x "$ACLOCAL" || ACLOCAL="aclocal`echo "$AUTOMAKE" | sed 's/.*automake//'`" && ACLOCAL=`typep "$ACLOCAL"` ||
-{
-echo
-echo "autogen.sh found automake-1.7, or automake-1.8 in"
-echo "your PATH, but not the respective aclocal-1.7, or"
-echo "aclocal-1.8. Your installation of GNU Automake is broken or"
-echo "incomplete."
-exit 2;
-}
-
-set -e	# stops on error status
-
-${ACLOCAL}
-autoheader
-${AUTOMAKE} --add-missing --copy --foreign
-autoconf
diff --git a/sm5/configure.in b/sm5/configure.in
deleted file mode 100644
index 0afadafaf8035930351717502d2253b177fc09cd..0000000000000000000000000000000000000000
--- a/sm5/configure.in
+++ /dev/null
@@ -1,177 +0,0 @@
-#
-# $Id: configure.in,v 1.91 2004/08/13 14:09:21 arvoreen Exp $
-#
-dnl Process this file with autoconf to produce a configure script.
-AC_PREREQ(2.50)
-AC_INIT(smartmontools, 5.33, smartmontools-support@lists.sourceforge.net)
-AC_CONFIG_SRCDIR(smartctl.c)
-
-smartmontools_configure_date=`date -u +"%Y/%m/%d %T %Z"`
-smartmontools_cvs_tag=`echo '$Id: configure.in,v 1.91 2004/08/13 14:09:21 arvoreen Exp $'`
-smartmontools_release_date=2004/07/05
-smartmontools_release_time="08:10:26 UTC"
-
-AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args",            [smartmontools Configure Arguments])
-AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_DATE, "$smartmontools_configure_date", [smartmontools Configure Date])
-AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE,   "$smartmontools_release_date",   [smartmontools Release Date])
-AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_TIME,   "$smartmontools_release_time",   [smartmontools Release Time])
-AC_DEFINE_UNQUOTED(CONFIG_H_CVSID,               "$smartmontools_cvs_tag",        [smartmontools CVS Tag])
-AC_DEFINE_UNQUOTED(PACKAGE_HOMEPAGE,             "http://smartmontools.sourceforge.net/", [smartmontools Home Page])
-
-AM_CONFIG_HEADER(config.h)
-
-AM_INIT_AUTOMAKE
-
-AM_MAINTAINER_MODE
-
-AC_LANG_C
-dnl Checks for programs.
-AC_PROG_CC
-AM_PROG_AS
-AC_PROG_INSTALL
-
-AC_CANONICAL_HOST
-dnl Set flags which may affect AC_CHECK_*.
-case "${host}" in
-	*-*-mingw*)
-		CPPFLAGS="$CPPFLAGS -mno-cygwin"
-		LDFLAGS="$LDFLAGS -mno-cygwin"
-		CPPFLAGS="$CPPFLAGS -idirafter ${srcdir}/posix -idirafter ${srcdir}/os_win32"
-esac
-
-dnl Checks for libraries.needed for gethostbyname (Solaris needs
-dnl libnsl, might in the future also need libsocket)
-#  AC_SEARCH_LIBS (FUNCTION, SEARCH-LIBS, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES])
-AC_SEARCH_LIBS(gethostbyname, nsl, , AC_SEARCH_LIBS(gethostbyname, nsl, , , -lsocket), , )
-
-dnl Checks for header files.
-AC_CHECK_HEADER([getopt.h])
-AC_CHECK_HEADERS([dev/ata/atavar.h])
-AC_CHECK_HEADERS([sys/int_types.h])
-AC_CHECK_HEADERS([sys/inttypes.h])
-AC_CHECK_HEADERS([netdb.h])
-dnl Check for FreeBSD twe include files...currently missing on 5.2, but should be there
-AC_CHECK_HEADERS([sys/tweio.h])
-AC_CHECK_HEADERS([sys/twereg.h])
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-
-dnl Checks for library functions.
-AC_CHECK_FUNCS([getopt])
-AC_CHECK_FUNCS([getopt_long])
-AC_CHECK_FUNCS([getdomainname])
-AC_CHECK_FUNCS([gethostname])
-AC_CHECK_FUNCS([gethostbyname])
-AC_CHECK_FUNCS([sigset])
-AC_CHECK_FUNCS([strtoull])
-AC_CHECK_FUNCS([uname])
-
-AC_SUBST(CPPFLAGS)
-AC_SUBST(LDFLAGS)
-AC_SUBST(ASFLAGS)
-
-AC_SUBST([exampledir], ['${docdir}/examplescripts'])
-
-AC_ARG_WITH(initscriptdir,[AC_HELP_STRING([--with-initscriptdir=dir],[Location of init scripts (default is ${sysconfdir}/rc.d/init.d)])],[initddir="$withval"],[initddir='${sysconfdir}/rc.d/init.d'])
-AC_SUBST(initddir)
-
-AC_ARG_WITH(docdir,[AC_HELP_STRING([--with-docdir=dir],[Location of documentation (default is ${prefix}/share/doc/smartmontools-5.X)])],[docdir="$withval"],[docdir='${prefix}/share/doc/${PACKAGE}-${VERSION}'])
-AC_SUBST(docdir)
-
-AC_ARG_ENABLE(sample,[AC_HELP_STRING([--enable-sample],[Enables appending .sample to the installed smartd rc script and configuration file])],[smartd_suffix='.sample'],[smartd_suffix=''])
-AC_SUBST(smartd_suffix)
-AM_CONDITIONAL(SMARTD_SUFFIX, test $smartd_suffix)
-
-if test "$prefix" = "NONE"; then
-    dnl no prefix and no mandir, so use ${prefix}/share/man as default
-    if test "$mandir" = '${prefix}/man'; then
-    	AC_SUBST([mandir], ['${prefix}/share/man'])
-    fi
-fi
-
-AC_SUBST(releaseversion,['${PACKAGE}-${VERSION}'])
-AC_SUBST(smartmontools_release_date)
-AC_SUBST(smartmontools_release_time)
-
-dnl if OS not recognized, then use the os_generic modules
-case "${host}" in
-	*-*-linux-gnu*) 
-		AC_SUBST([os_deps], ['os_linux.o']) 
-		AC_SUBST([os_libs], ['']) ;;
-	*-*-linux*)
-		AC_SUBST([os_deps], ['os_linux.o']) 
-		AC_SUBST([os_libs], ['']) ;;
-	*-*-freebsd*)
-		AC_SUBST([os_deps], ['os_freebsd.o']) 
-		AC_SUBST([os_libs], ['-lcam']);;
-	sparc-*-solaris*) 
-		AC_DEFINE_UNQUOTED(DEFAULT_MAILER, "mailx", [use mailx as default mailer])
-		AC_DEFINE_UNQUOTED(NEED_SOLARIS_ATA_CODE, "os_solaris_ata.s", [need assembly code os_solaris_ata.s])
-		AC_SUBST([os_deps], ['os_solaris.o os_solaris_ata.o']) 
-		AC_SUBST([os_libs], ['']) ;;
-	*-pc-solaris*) 
-		AC_DEFINE_UNQUOTED(DEFAULT_MAILER, "mailx", [use mailx as default mailer]) 
-		AC_SUBST([os_deps], ['os_solaris.o']) 
-		AC_SUBST([os_libs], ['']) ;;
-	*-*-netbsd*)
-		AC_SUBST([os_deps], ['os_netbsd.o']) 
-		AC_SUBST([os_libs], ['-lutil']) ;;
-	*-*-cygwin*)
-		AC_SUBST([os_deps], ['os_win32.o'])
-		AC_SUBST([os_libs], ['']) ;;
-	*-*-mingw*)
-		AC_SUBST([os_deps], ['os_win32.o regex.o daemon_win32.o hostname_win32.o syslog_win32.o'])
-		AC_SUBST([os_libs], ['']) ;;
-	*-*-darwin*)
-		AC_SUBST([os_deps], ['os_darwin.o'])
-		AC_SUBST([os_libs], ['-framework CoreFoundation -framework IOKit']) ;;
-	*)
-		AC_SUBST([os_deps], ['os_generic.o']) 
-		AC_SUBST([os_libs], ['']) ;;
-esac
-
-dnl Define platform-specific symbol.
-AM_CONDITIONAL(OS_DARWIN, [echo $host_os | grep '^darwin' > /dev/null])
-AM_CONDITIONAL(OS_SOLARIS, [echo $host_os | grep '^solaris' > /dev/null])
-AM_CONDITIONAL(OS_WIN32_MINGW, [echo $host_os | grep '^mingw' > /dev/null])
-
-dnl Add -Wall and -W if using gcc and its not already specified.
-if test "x$GCC" = "xyes"; then
-  if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
-      CFLAGS="$CFLAGS -Wall"
-  fi
-# In the next line, do NOT delete the 2 spaces inside double quotes.
-  if test -z "`echo "$CFLAGS " | grep "\-W " 2> /dev/null`" ; then
-      CFLAGS="$CFLAGS -W"
-  fi
-  case "${host}" in
-    *-*-mingw*)
-      # MinGW uses MSVCRT.DLL which uses printf format "%I64d" and not "%lld" for int64_t
-      CFLAGS="$CFLAGS -Wno-format";;
-  esac
-else
- dnl We are NOT using gcc, so enable host-specific compiler flags
- case "${host}" in
-	*-*-solaris*) 
-          dnl set CFLAGS for Solaris C compiler
-          if test -z "`echo "$CFLAGS" | grep "\-xmemalign" 2> /dev/null`" ; then
-            dnl we have to tell the compilers about packed ATA structures
-            CFLAGS="-xmemalign=1i $CFLAGS"
-          fi
-          if test -z "`echo "$CFLAGS" | grep "\-xCC" 2> /dev/null`" ; then
-            dnl we have to tell the compiler to ignore C++ style comments
-            CFLAGS="-xCC $CFLAGS"
-          fi
-          if test -z "`echo "$CFLAGS" | grep "\-xO" 2> /dev/null`" ; then
-            dnl turn on optimization if user has not explicitly set its value
-            CFLAGS="-xO2 $CFLAGS"
-          fi
- esac
-fi
-
-AC_DEFINE_UNQUOTED(SMARTMONTOOLS_BUILD_HOST,     "${host}",                       [smartmontools Build Host])
-
-AC_SUBST(CFLAGS)
-
-AC_OUTPUT(Makefile examplescripts/Makefile smartd.initd)
-AC_PROG_MAKE_SET
diff --git a/sm5/do_release b/sm5/do_release
deleted file mode 100755
index 0031f5c239c64aafe6f0aefda5146da4a1f900a6..0000000000000000000000000000000000000000
--- a/sm5/do_release
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/bash -ev
-#
-# do a smartmontools release
-# (C) 2003-4 Bruce Allen <ballen4705@users.sourceforge.net>, 
-#          Guido Guenther <agx@sigxcpu.org>
-# $Id: do_release,v 1.31 2004/07/05 07:41:52 ballen4705 Exp $
-
-# Notes on generating releases:
-# (1) update NEWS
-# (2) update CHANGELOG -- put in release number
-# (3) update release number in configure.in and smartmontools.spec
-# (4) update internal changelog in smartmontools.spec
-
-USECVS=1
-
-KEYID=0x9BB19A22
-
-if [ -f /etc/redhat-release ]; then
-  RPM_BASE=/usr/src/redhat/
-else
-  RPM_BASE=/usr/src/rpm/
-fi
-SOURCES=$RPM_BASE/SOURCES/
-
-setup_cvs()
-{
-  CVS_SERVER=fakevalue
-  unset CVS_SERVER || echo "can't unset CVS_SERVER=$CVS_SERVER"
-  CVS_RSH=ssh
-  CVSROOT=:ext:ballen4705@cvs.sourceforge.net:/cvsroot/smartmontools
-}
-
-get_release()
-{
-  VERSION=`grep 'AC_INIT' configure.in | awk '{ print $2 }' | sed s/,//g`
-  RELEASE="RELEASE_${VERSION//\./_}"
-  echo "Version: $VERSION"
-  echo "Release: $RELEASE"
-}
-
-inc_release()
-{
-  MINOR=`echo $VERSION | cut -d. -f2`
-  MAJOR=`echo $VERSION | cut -d. -f1`
-  PERL_OLD=$MAJOR\\.$MINOR
-  ((MINOR++))
-  NEW_VERSION=$MAJOR.$MINOR
-  PERL_NEW=$MAJOR\\.$MINOR	
-  NEW_RELEASE="RELEASE_${NEW_VERSION//\./_}"
-  echo "New Version: $NEW_VERSION"
-  echo "New Release: $NEW_RELEASE"
-}
-
-# run automake/autoconf
-if [ -f Makefile ] ; then
-  make distcheck || exit 1
-  make clean
-  make distclean
-  rm -f Makefile configure
-fi
-
-if [ $USECVS -ne 0 ] ; then
-    smartmontools_release_date=`date -u +"%Y/%m/%d"`
-    smartmontools_release_time=`date -u +"%T %Z"`
-    cat configure.in  | sed "s|smartmontools_release_date=.*|smartmontools_release_date=${smartmontools_release_date}|" > configure.tmp
-    cat configure.tmp | sed "s|smartmontools_release_time=.*|smartmontools_release_time=\"${smartmontools_release_time}\"|" > configure.in
-    rm -f configure.tmp
-fi
-
-./autogen.sh
-
-get_release
-
-# tag CVS version
-if [ $USECVS -ne 0 ] ; then
-    setup_cvs
-    cvs commit -m "Release $VERSION $RELEASE"
-    cvs tag -d $RELEASE 
-    cvs tag $RELEASE
-fi
-
-# build .tar.gz
-rm -rf build
-mkdir build
-cd build
-../configure
-make distcheck || exit 1
-cd ..
-cp build/smartmontools-$VERSION.tar.gz $SOURCES
-
-# build rpm
-rpmbuild -ba --sign smartmontools.spec
-
-# remove source tarball
-rm -f $SOURCES/smartmontools-$VERSION.tar.gz
-
-# increase release number:
-inc_release
-if [ $USECVS -ne 0 ] ; then
-    perl -p -i.bak -e "s/$PERL_OLD/$PERL_NEW/" configure.in
-    perl -p -i.bak -e "s/Version:\t$PERL_OLD/Version:\t$PERL_NEW/" smartmontools.spec
-fi
-
-mv -f $RPM_BASE/RPMS/i386/smartmontools-$VERSION-*.i386.rpm .
-mv -f $RPM_BASE/SRPMS/smartmontools-$VERSION-*.src.rpm .
-cp -f build/smartmontools-$VERSION.tar.gz .
-if [ "$KEYID" ]; then
-  gpg --default-key $KEYID --armor --detach-sign ./smartmontools-$VERSION.tar.gz
-fi
-
-# cleanup
-rm -rf autom4te.cache build/ config.h.in Makefile.in examplescripts/Makefile.in \
-       depcomp mkinstalldirs install-sh configure aclocal.m4 missing *.bak
diff --git a/sm5/examplescripts/.cvsignore b/sm5/examplescripts/.cvsignore
deleted file mode 100644
index 282522db0342d8750454b3dc162493b5fc709cc8..0000000000000000000000000000000000000000
--- a/sm5/examplescripts/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/sm5/examplescripts/Example1 b/sm5/examplescripts/Example1
deleted file mode 100755
index 1b32a77a1d5546fc4c459e84a03e7a0fd4814a93..0000000000000000000000000000000000000000
--- a/sm5/examplescripts/Example1
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash 
-#
-# This is a script from the smartmontools examplescripts/ directory.
-# It can be used as an argument to the -M exec Directive in
-# /etc/smartd.conf, in a line like 
-# -m root@localhost -M exec /path/to/this/file
-#
-# Please see man 8 smartd or man 5 smartd.conf for further
-# information.
-#
-# $Id: Example1,v 1.5 2004/01/07 16:49:56 ballen4705 Exp $
-
-# Save standard input into a temp file
-cat > /root/tempfile
-
-# Echo command line arguments into temp file
-echo "Command line argument 1:" >> /root/tempfile
-echo $1 >> /root/tempfile
-echo "Command line argument 2:" >> /root/tempfile
-echo $2 >> /root/tempfile
-echo "Command line argument 3:" >> /root/tempfile
-echo $3 >> /root/tempfile
-
-# Echo environment variables into a temp file
-echo "Variables are":       >> /root/tempfile
-echo "$SMARTD_DEVICE"       >> /root/tempfile
-echo "$SMARTD_DEVICESTRING" >> /root/tempfile
-echo "$SMARTD_DEVICETYPE"   >> /root/tempfile
-echo "$SMARTD_MESSAGE"      >> /root/tempfile
-echo "$SMARTD_ADDRESS"      >> /root/tempfile
-echo "$SMARTD_SUBJECT"      >> /root/tempfile
-echo "$SMARTD_TFIRST"       >> /root/tempfile
-echo "$SMARTD_TFIRSTEPOCH"  >> /root/tempfile
-
-# Run smartctl -a and save output in temp file
-/usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/tempfile
-
-# Email the contents of the temp file. Solaris and other OSes
-# may need to use /bin/mailx not /bin/mail.
-/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile
-
-# And exit
-exit 0
diff --git a/sm5/examplescripts/Example2 b/sm5/examplescripts/Example2
deleted file mode 100755
index f6534332b3fce622decbd9f8ecedf04e5f0f7222..0000000000000000000000000000000000000000
--- a/sm5/examplescripts/Example2
+++ /dev/null
@@ -1,22 +0,0 @@
-#! /bin/bash
-#
-# This is a script from the smartmontools examplescripts/ directory.
-# It can be used as an argument to the -M exec Directive in
-# /etc/smartd.conf, in a line like 
-# -m root@localhost -M exec /path/to/this/file
-#
-# Please see man 8 smartd or man 5 smartd.conf for further
-# information.
-#
-# $Id: Example2,v 1.4 2004/01/07 16:49:56 ballen4705 Exp $
-
-# Save the email message (STDIN) to a file:
-cat > /root/msg
-
-# Append the output of smartctl -a to the message:
-/usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/msg
-
-# Now email the message to the user at address ADD.  Solaris and
-# other OSes may need to use /bin/mailx below.
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
-
diff --git a/sm5/examplescripts/Example3 b/sm5/examplescripts/Example3
deleted file mode 100755
index 6a1b11cdfef8cf821ad5f732adcbab67623cd516..0000000000000000000000000000000000000000
--- a/sm5/examplescripts/Example3
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /bin/bash
-#
-# This is a script from the smartmontools examplescripts/ directory.
-# It can be used as an argument to the -M exec Directive in
-# /etc/smartd.conf, in a line like 
-# -m <nomailer> -M exec /path/to/this/file
-#
-# Please see man 8 smartd or man 5 smartd.conf for further
-# information.
-#
-# $Id: Example3,v 1.4 2003/08/17 09:15:56 ballen4705 Exp $
-
-# Warn all users of a problem     
-wall 'Problem detected with disk: ' "$SMARTD_DEVICESTRING"    
-wall 'Warning message from smartd is: ' "$SMARTD_MESSAGE"      
-wall 'Shutting down machine in 30 seconds... '
-
-# Wait half a minute
-sleep 30 
-
-# Power down the machine (uncomment the shutdown command if you really
-# want to do this!)
-
-# /sbin/shutdown -hf now
-
diff --git a/sm5/examplescripts/Makefile.am b/sm5/examplescripts/Makefile.am
deleted file mode 100644
index d37c17dd3864f35c2dd2b95890c6f481cc51d5a9..0000000000000000000000000000000000000000
--- a/sm5/examplescripts/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-## Process this file with automake to produce Makefile.in
-examplesdir=$(exampledir)
-
-examples_DATA = README
-
-examples_SCRIPTS = Example1            \
-                       Example2        \
-                       Example3
-
-EXTRA_DIST = $(examples_SCRIPTS)
diff --git a/sm5/examplescripts/README b/sm5/examplescripts/README
deleted file mode 100644
index b424afb2cf47e49d4529f7859420c80061809cf3..0000000000000000000000000000000000000000
--- a/sm5/examplescripts/README
+++ /dev/null
@@ -1,50 +0,0 @@
-# Home page: http://smartmontools.sourceforge.net
-#
-# $Id: README,v 1.2 2004/01/02 16:05:25 ballen4705 Exp $
-#
-# Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-# 
-# 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, write to the Free Software Foundation, Inc., 675
-# Mass Ave, Cambridge, MA 02139, USA.
-#
-# This code was originally developed as a Senior Thesis by Michael Cornwell
-# at the Concurrent Systems Laboratory (now part of the Storage Systems
-# Research Center), Jack Baskin School of Engineering, University of
-# California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-
-This directory contains executable bash scripts, that are intended for
-use with the
-  -m address -M exec /path/to/an/executable
-Directive in /etc/smartd.conf.
-
-Details about how to use this Directive may be found in the man pages for
-smartd and smartd.conf.
-  man 8 smartd
-  man 5 smartd.conf
-should display those pages on your system.
-
-If you wish to contribute additional scripts to this collection,
-please email them to <smartmontools-support@lists.sourceforge.net>,
-and include a one-line description to use below.
-
-The files contained in this directory are:
-
-Example1: appends values of $SMARTD_* environment variables and the output
-          of smartctl -a to the normal email message, and sends that
-          to the email address listed as the argument to the -m
-          Directive.
-
-Example2: Appends output of smartctl -a to the normal email message
-	  and sends that to the email address listed as the argument
-	  to the -m Directive.
-
-Example3: Uses wall(1) to send a warning message to all users, then powers
-          down the machine.
-
-
diff --git a/sm5/extern.h b/sm5/extern.h
deleted file mode 100644
index a21e689985c2d400633fbbe3121a843fe87e24e2..0000000000000000000000000000000000000000
--- a/sm5/extern.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * extern.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef EXTERN_H_
-#define EXTERN_H_
-
-#define EXTERN_H_CVSID "$Id: extern.h,v 1.39 2004/08/13 13:57:12 arvoreen Exp $\n"
-
-// Possible values for fixfirmwarebug.  If use has NOT specified -F at
-// all, then value is 0.
-#define FIX_NOTSPECIFIED     0
-#define FIX_NONE             1
-#define FIX_SAMSUNG          2
-#define FIX_SAMSUNG2         3
-
-// Block used for global control/communications.  If you need more
-// global variables, this should be the only place that you need to
-// add them.
-typedef struct smartmonctrl_s {
-  // spans for selective self-test
-  uint64_t smartselectivespan[5][2];
-  // number of spans
-  int smartselectivenumspans;
-  int           testcase;
-  // one plus time in minutes to wait after powerup before restarting
-  // interrupted offline scan after selective self-test.
-  int  pendingtime;
-  // run offline scan after selective self-test.  0: don't change, 1:
-  // turn off scan after selective self-test, 2: turn on scan after
-  // selective self-test.
-  unsigned char scanafterselect;
-  unsigned char driveinfo;
-  unsigned char checksmart;
-  unsigned char smartvendorattrib;
-  unsigned char generalsmartvalues;
-  unsigned char smartlogdirectory;
-  unsigned char smartselftestlog;
-  unsigned char selectivetestlog;
-  unsigned char smarterrorlog;
-  unsigned char smartdisable;
-  unsigned char smartenable; 
-  unsigned char smartstatus;
-  unsigned char smartexeoffimmediate;
-  unsigned char smartshortselftest;
-  unsigned char smartextendselftest;
-  unsigned char smartconveyanceselftest;
-  unsigned char smartselectiveselftest;
-  unsigned char smartshortcapselftest;
-  unsigned char smartextendcapselftest;
-  unsigned char smartconveyancecapselftest;
-  unsigned char smartselectivecapselftest;
-  unsigned char smartselftestabort;
-  unsigned char smartautoofflineenable;
-  unsigned char smartautoofflinedisable;
-  unsigned char smartautosaveenable;
-  unsigned char smartautosavedisable;
-  unsigned char printing_switchable;
-  unsigned char dont_print;
-  unsigned char permissive;
-  unsigned char conservative;
-  unsigned char checksumfail;
-  unsigned char checksumignore;
-  unsigned char reportataioctl;
-  unsigned char reportscsiioctl;
-  unsigned char fixfirmwarebug;
-  // 3Ware controller type, but also extensible to other contoller types
-  unsigned char controller_type;
-  // For 3Ware controllers, nonzero value is 1 plus the disk number
-  unsigned char controller_port;
-  unsigned char ignorepresets;
-  unsigned char showpresets;
-  // The i'th entry in this array will modify the printed meaning of
-  // the i'th SMART attribute.  The default definitions of the
-  // Attributes are obtained by having the array be all zeros.  If
-  // attributedefs[i] is nonzero, it means that the i'th attribute has
-  // a non-default meaning.  See the ataPrintSmartAttribName and
-  // and parse_attribute_def functions.
-  unsigned char attributedefs[256];
-} smartmonctrl;
-
-#endif
diff --git a/sm5/int64.h b/sm5/int64.h
deleted file mode 100644
index 4e3bd9782049ee73c82d6e9d0763b8324dc9ee55..0000000000000000000000000000000000000000
--- a/sm5/int64.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * int64.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2004 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef INT64_H_
-#define INT64_H_
-
-#define INT64_H_CVSID "$Id: int64.h,v 1.5 2004/07/29 21:05:25 chrfranke Exp $\n"
-
-#ifndef CONFIG_H_CVSID
-// need HAVE_STDINT_H, HAVE_INTTYPES_H
-#include "config.h"
-#endif
-
-// 64 bit integer typedefs
-
-#ifdef HAVE_SYS_INT_TYPES_H
-#include <sys/int_types.h>
-#else
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#else
-#ifdef HAVE_SYS_INTTYPES_H
-#include <sys/inttypes.h>
-#else
-#if defined(_WIN32) && defined(_MSC_VER)
-// for MSVC 6.0
-typedef          __int64    int64_t;
-typedef unsigned __int64   uint64_t;
-#else
-// default is GCC style
-typedef          long long  int64_t;
-typedef unsigned long long uint64_t;
-#endif // _WIN32 && _MSC_VER
-#endif // HAVE_SYS_INTTYPES_H
-#endif // HAVE_STDINT_H
-#endif // HAVE_SYS_INT_TYPES_H
-
-// 64 bit integer format strings
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#if defined(_WIN32) && defined(_MSC_VER)
-// for MSVC 6.0
-#define PRId64 "I64d"
-#define PRIu64 "I64u"
-#define PRIx64 "I64x"
-#endif // _WIN32 && _MSC_VER
-#endif // HAVE_INTTYPES_H
-#ifndef PRId64		// not defined in inttypes.h....fix here
-// default is GCC style
-#define PRId64 "lld"
-#define PRIu64 "llu"
-#define PRIx64 "llx"
-#endif // ndef PRId64
-
-
-#if defined(_WIN32) && defined(_MSC_VER)
-// for MSVC 6.0: "unsigned __int64 -> double" conversion not implemented
-// replacement function implemented in os_win32/int64_vc6.c
-double uint64_to_double(unsigned __int64 ull);
-#else
-#define uint64_to_double(ull) ((double)(ull))
-#endif // _WIN32 && _MSC_VER
-
-
-#endif // INT64_H
diff --git a/sm5/knowndrives.c b/sm5/knowndrives.c
deleted file mode 100644
index 02813f3db83a02739581204d6150ff4f6f877eed..0000000000000000000000000000000000000000
--- a/sm5/knowndrives.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * knowndrives.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003-4 Philip Williams, Bruce Allen
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdio.h>
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "int64.h"
-#include "knowndrives.h"
-#include "utility.h" // includes <regex.h>
-#include "config.h"
-
-const char *knowndrives_c_cvsid="$Id: knowndrives.c,v 1.117 2004/07/31 16:38:00 pjwilliams Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
-
-#define MODEL_STRING_LENGTH                         40
-#define FIRMWARE_STRING_LENGTH                       8
-#define TABLEPRINTWIDTH                             19
-
-// See vendorattributeargs[] array in atacmds.c for definitions.
-#define PRESET_9_MINUTES                   {   9,  1 }
-#define PRESET_9_TEMP                      {   9,  2 }
-#define PRESET_9_SECONDS                   {   9,  3 }
-#define PRESET_9_HALFMINUTES               {   9,  4 }
-#define PRESET_192_EMERGENCYRETRACTCYCLECT { 192,  1 }
-#define PRESET_193_LOADUNLOAD              { 193,  1 }
-#define PRESET_194_10XCELSIUS              { 194,  1 }
-#define PRESET_194_UNKNOWN                 { 194,  2 }
-#define PRESET_198_OFFLINESCANUNCSECTORCT  { 198,  1 }
-#define PRESET_200_WRITEERRORCOUNT         { 200,  1 }
-#define PRESET_201_DETECTEDTACOUNT         { 201,  1 }         
-#define PRESET_220_TEMP                    { 220,  1 }
-
-/* Arrays of preset vendor-specific attribute options for use in
- * knowndrives[]. */
-
-extern int64_t bytes;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// These three are common to several models.
-const unsigned char vendoropts_9_minutes[][2] = {
-  PRESET_9_MINUTES,
-  {0,0}
-};
-const unsigned char vendoropts_9_halfminutes[][2] = {
-  PRESET_9_HALFMINUTES,
-  {0,0}
-};
-const unsigned char vendoropts_9_seconds[][2] = {
-  PRESET_9_SECONDS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_194_UNKNOWN,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
-  PRESET_9_SECONDS,
-  PRESET_192_EMERGENCYRETRACTCYCLECT,
-  PRESET_198_OFFLINESCANUNCSECTORCT,
-  PRESET_200_WRITEERRORCOUNT,
-  PRESET_201_DETECTEDTACOUNT,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHR2040AT[][2] = {
-  PRESET_9_SECONDS,
-  PRESET_192_EMERGENCYRETRACTCYCLECT,
-  PRESET_198_OFFLINESCANUNCSECTORCT,
-  PRESET_200_WRITEERRORCOUNT,
-  {0,0}
-};
-
-const unsigned char vendoropts_Samsung_SV4012H[][2] = {
-  PRESET_9_HALFMINUTES,
-  {0,0}
-};
-
-const unsigned char vendoropts_Samsung_SV1204H[][2] = {
-  PRESET_9_HALFMINUTES,
-  PRESET_194_10XCELSIUS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Hitachi_DK23XX[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_193_LOADUNLOAD,
-  {0,0}
-};
-
-const char same_as_minus_F[]="Fixes byte order in some SMART data (same as -F samsung)";
-const char same_as_minus_F2[]="Fixes byte order in some SMART data (same as -F samsung2)";
-
-const char may_need_minus_F_disabled[] ="May need -F samsung disabled; see manual for details.";
-const char may_need_minus_F2_disabled[]="May need -F samsung2 disabled; see manual for details.";
-const char may_need_minus_F2_enabled[] ="May need -F samsung2 enabled; see manual for details.";
-const char may_need_minus_F_enabled[]  ="May need -F samsung or -F samsung2 enabled; see manual for details.";
-
-/* Special-purpose functions for use in knowndrives[]. */
-void specialpurpose_reverse_samsung(smartmonctrl *con)
-{
-  if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
-    con->fixfirmwarebug = FIX_SAMSUNG;
-}
-void specialpurpose_reverse_samsung2(smartmonctrl *con)
-{
-  if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
-    con->fixfirmwarebug = FIX_SAMSUNG2;
-}
-
-/* Table of settings for known drives terminated by an element containing all
- * zeros.  The drivesettings structure is described in knowndrives.h.  Note
- * that lookupdrive() will search knowndrives[] from the start to end or
- * until it finds the first match, so the order in knowndrives[] is important
- * for distinct entries that could match the same drive. */
-
-// Note that the table just below uses EXTENDED REGULAR EXPRESSIONS.
-// A good on-line reference for these is:
-// http://www.zeus.com/extra/docsystem/docroot/apps/web/docs/modules/access/regex.html
-
-const drivesettings knowndrives[] = {
-  { // IBM Deskstar 60GXP series
-    "IC35L0[12346]0AVER07",
-    ".*",
-    "IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
-    "Please see http://www.geocities.com/dtla_update/index.html#rel and\n"
-    "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
-    "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
-    NULL, NULL, NULL
-  },
-  { // IBM Deskstar 40GV & 75GXP series (A5AA/A6AA firmware)
-    "(IBM-)?DTLA-30[57]0[123467][05]",
-    "^T[WX][123468A]OA[56]AA$",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM Deskstar 40GV & 75GXP series (all other firmware)
-    "(IBM-)?DTLA-30[57]0[123467][05]",
-    ".*",
-    "IBM Deskstar 40GV and 75GXP drives may need upgraded SMART firmware.\n"
-    "Please see http://www.geocities.com/dtla_update/ and\n"
-    "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
-    "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
-    NULL, NULL, NULL
-  },
-  { // ExcelStor J240
-    "^ExcelStor Technology J240$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Fujitsu MPB series
-    "^FUJITSU MPB....ATU?$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPD and MPE series
-    "^FUJITSU MP[DE]....A[HTE]$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPF series
-    "^FUJITSU MPF3(102A[HT]|153A[HT]|204A[HT])$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPG series
-    "^FUJITSU MPG3(102A(H|T  E)|204A(H|[HT]  E)|307A(H  E|T)|409A[HT]  E)$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPC series
-    "^FUJITSU MPC3(032AT|043AT|045AH|064A[HT]|084AT|096AT|102AT)$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHN2300AT
-    "^FUJITSU MHN2300AT$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHR2040AT
-    "^FUJITSU MHR2040AT$",
-    ".*",    // Tested on 40BA
-    NULL,
-    vendoropts_Fujitsu_MHR2040AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHSxxxxAT family
-    "^FUJITSU MHS20[6432]0AT(  .)?$",
-    ".*",
-    NULL,
-    vendoropts_Fujitsu_MHS2020AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHL2300AT, MHM2200AT, MHM2100AT, MHM2150AT
-    "^FUJITSU MH(L230|M2(20|10|15))0AT$",
-    ".*",
-    "This drive's firmware has a harmless Drive Identity Structure\n"
-      "checksum error bug.",
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHTxxxxAT family
-    "^FUJITSU MHT20[23468]0AT$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHTxxxxAH family
-    "^FUJITSU MHT20[468]0AH$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Samsung SV4012H (known firmware)
-    "^SAMSUNG SV4012H$",
-    "^RM100-08$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV4012H (all other firmware)
-    "^SAMSUNG SV4012H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV0412H (known firmware)
-    "^SAMSUNG SV0412H$",
-    "^SK100-01$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV0412H (all other firmware)
-    "^SAMSUNG SV0412H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV1204H (known firmware)
-    "^SAMSUNG SV1204H$",
-    "^RK100-1[3-5]$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { //Samsung SV1204H (all other firmware)
-    "^SAMSUNG SV1204H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { //SAMSUNG SV0322A tested with FW JK200-35
-    "^SAMSUNG SV0322A$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL
-  },
-  { // SAMSUNG SP40A2H with RR100-07 firmware
-    "^SAMSUNG SP40A2H$",
-    "^RR100-07$",
-    NULL,
-    vendoropts_9_halfminutes,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { 
-    // Any other Samsung disk with *-23 *-24 firmware
-    // SAMSUNG SP1213N (TL100-23 firmware)
-    // SAMSUNG SP0802N (TK100-23 firmware)
-    // Samsung SP1604N, tested with FW TM100-23 and TM100-24
-    "^SAMSUNG .*$",
-    ".*-2[34]$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung2,
-    same_as_minus_F2
-  },
-  { // All Samsung drives with '.*-25' firmware
-    "^SAMSUNG.*",
-    ".*-25$",
-    may_need_minus_F2_disabled,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung2,
-    same_as_minus_F2
-  },
-  { // All Samsung drives with '.*-26 or later (currently to -39)' firmware
-    "^SAMSUNG.*",
-    ".*-(2[6789]|3[0-9])$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    NULL,
-    NULL
-  },
-  { // Samsung ALL OTHER DRIVES
-    "^SAMSUNG.*",
-    ".*",
-    may_need_minus_F_enabled,
-    NULL, NULL, NULL
-  },
-  { // Maxtor Fireball 541DX family
-    "^Maxtor 2B0(0[468]|1[05]|20)H1$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 3400 Ultra ATA family
-    "^Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax D540X-4G family
-    "^Maxtor 4G(120J6|160J[68])$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor DiamondMax D540X-4K family
-    "^MAXTOR 4K(020H1|040H2|060H3|080H4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus D740X family
-    "^MAXTOR 6L0(20[JL]1|40[JL]2|60[JL]3|80[JL]4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 5120 Ultra ATA 33 family
-    "^Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 6800 Ultra ATA 66 family
-    "^Maxtor 9(2732U8|2390U7|2049U6|1707U5|1366U4|1024U3|0845U3|0683U2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax D540X-4D and Maxtor 4G120J6
-    "^Maxtor (4D0(20H1|40H2|60H3|80H4)|4G120J6)$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 16 family
-    "^Maxtor 4(R0[68]0[JL]|R1[26]0L|A160J)0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 4320 family
-    "^Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D4|90432D2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 20 VL family
-    "^Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax VL 30 family
-    "^Maxtor (33073U4|32049U3|31536U2|30768U1)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 36 family
-    "^Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 40 ATA 66 series
-    "^Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 40 series (Ultra ATA 66 and Ultra ATA 100)
-    "^Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 40 VL Ultra ATA 100 series
-    "^Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 45 Ulta ATA 100 family
-    "^Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 60 family
-    "^Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 80 family
-    "^Maxtor (98196H8|96147H6)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 536DX family
-    "^Maxtor 4W(100H6|080H6|060H4|040H3|030H2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 8 family
-    "^Maxtor 6E0[234]0L0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 9 family
-    "^Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor MaXLine Plus II
-    "^Maxtor 7Y250[PM]0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor MaXLine II family
-    "^Maxtor [45]A(25|32)0[JN]0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // HITACHI_DK14FA-20B
-    "^HITACHI_DK14FA-20B$",
-    ".*",
-    NULL,
-    vendoropts_Hitachi_DK23XX,
-    NULL, NULL
-  },
-  { // HITACHI Travelstar DK23XX/DK23XXB series
-    "^HITACHI_DK23..-..B?$",
-    ".*",
-    NULL,
-    vendoropts_Hitachi_DK23XX,
-    NULL, NULL
-  },
-  { // IBM Deskstar 14GXP and 16GP series
-    "^IBM-DTTA-3(7101|7129|7144|5032|5043|5064|5084|5101|5129|5168)0$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Deskstar 25GP and 22GXP family
-    "^IBM-DJNA-3(5(101|152|203|250)|7(091|135|180|220))0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM Travelstar 25GS, 18GT, and 12GN family
-    "^IBM-DARA-2(25|18|15|12|09|06)000$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Travelstar 48GH, 30GN, and 15GN family
-    "^IC25(T048ATDA05|N0(30|20|15|12|10|07|06|05)ATDA04)-.$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Travelstar 32GH, 30GT, and 20GN family
-    "^IBM-DJSA-2(32|30|20|10|05)$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Deskstar 37GP and 34GXP family
-    "^IBM-DPTA-3(5(375|300|225|150)|7(342|273|205|136))0$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM/Hitachi Travelstar 60GH and 40GN family
-    "^IC25(T060ATC[SX]05|N0[4321]0ATC[SX]04)-.$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM/Hitachi Travelstar 40GNX family
-    "^IC25N0[42]0ATC[SX]05-.$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // Hitachi Travelstar 80GN family
-    "^(Hitachi )?IC25N0[23468]0ATMR04-.$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Hitachi Travelstar 5K80 family
-    "^HTS5480[8642]0M9AT00$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM/Hitachi Deskstar 120GXP family
-    "^IC35L((020|040|060|080|120)AVVA|0[24]0AVVN)07-[01]$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM/Hitachi Deskstar GXP-180 family 
-    "^IC35L(030|060|090|120|180)AVV207-[01]$",
-    ".*", 
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Travelstar 14GS
-    "^IBM-DCYA-214000$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM Travelstar 4LP
-    "^IBM-DTNA-2(180|216)0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Hitachi Deskstar 7K250 series
-    "^HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK4025GAS
-    "^TOSHIBA MK4025GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK6021GAS [Bruce -- use for testing on laptop]
-    "^TOSHIBA MK6021GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK4019GAX/MK4019GAXB
-    "^TOSHIBA MK4019GAXB?$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK6409MAV
-    "^TOSHIBA MK6409MAV$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOS MK3019GAXB SUN30G
-    "^TOS MK3019GAXB SUN30G$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK2016GAP, MK2017GAP, MK2018GAP, MK2018GAS, MK2023GAS
-    "^TOSHIBA MK20(1[678]GAP|(18|23)GAS)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK4018GAS
-    "^TOSHIBA MK4018GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK3017GAP
-    "^TOSHIBA MK3017GAP$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Medalist 8641 family
-    "^ST3(2110|3221|4312|6531|8641)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U Series X family
-    "^ST3(10014A(CE)?|20014A)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U Series 6 family
-    "^ST3(8002|6002|4081|3061|2041)0A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U Series 5 family
-    "^ST3(40823|30621|20413|15311|10211)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U8 family
-    "^ST3(8410|4313|17221|13021)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA II family
-    "^ST3(3063|2042|1532|1021)0A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA III family
-    "^ST3(40824|30620|20414|15310|10215)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA IV family
-    "^ST3(20011|40016|60021|80021)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA V family
-    "^ST3(12002(3A|4A|9A|3AS)|800(23A|15A|23AS)|60(015A|210A)|40017A)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda 7200.7 and 7200.7 Plus family
-    "^ST3(200822AS?|16002[13]AS?|12002[26]AS?|8001[13]AS?|60014A|40014AS?)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Medalist 17242, 13032, 10232, 8422, and 4312
-    "^ST3(1724|1303|1023|842|431)2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Protege
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD([2468]00E|1[26]00A)B-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar family
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(2|3|4|6|8|10|12|16|18|20|25)00BB-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar WDxxxAB series
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(3|4|6)00AB-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar WDxxxAA series
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(64|84|102|136|205|272|307)AA(-.*)?$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar WDxxxBA series
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(102|136|153|205)BA$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar AC12500, AC24300, AC25100, AC36400, AC38400
-    "^WDC AC(125|243|251|364|384)00",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar SE family
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD((4|6|8|10|12|16|18|20|25)00JB|(12|20|25)00PB)-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar SE (Serial ATA) family
-    "^WDC WD(4|8|12|16|20|25)00JD-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar AC38400
-    "^WDC AC38400L$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar AC23200L
-    "^WDC AC23200L$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLlct15 20 and QUANTUM FIREBALLlct15 30
-    "^QUANTUM FIREBALLlct15 [23]0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLlct20 series
-    "^QUANTUM FIREBALLlct20 [234]0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL CX10.2A
-    "^QUANTUM FIREBALL CX10.2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLP LM15 and LM30
-    "^QUANTUM FIREBALLP LM(15|30)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL CR4.3A
-    "^QUANTUM FIREBALL CR4.3A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLP AS10.2 and AS40.0
-    "^QUANTUM FIREBALLP AS(10.2|40.0)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL EX6.4A
-    "^QUANTUM FIREBALL EX6.4A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL ST3.2A
-    "^QUANTUM FIREBALL ST3.2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL EX3.2A
-    "^QUANTUM FIREBALL EX3.2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  /*------------------------------------------------------------
-   *  End of table.  Do not add entries below this marker.
-   *------------------------------------------------------------ */
-  {NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
-// Searches knowndrives[] for a drive with the given model number and firmware
-// string.  If either the drive's model or firmware strings are not set by the
-// manufacturer then values of NULL may be used.  Returns the index of the
-// first match in knowndrives[] or -1 if no match if found.
-int lookupdrive(const char *model, const char *firmware)
-{
-  regex_t regex;
-  int i, index;
-  const char *empty = "";
-
-  model = model ? model : empty;
-  firmware = firmware ? firmware : empty;
-
-  for (i = 0, index = -1; index == -1 && knowndrives[i].modelregexp; i++) {
-    // Attempt to compile regular expression.
-    if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
-      goto CONTINUE;
-
-    // Check whether model matches the regular expression in knowndrives[i].
-    if (!regexec(&regex, model, 0, NULL, 0)) {
-      // model matches, now check firmware.
-      if (!knowndrives[i].firmwareregexp)
-        // The firmware regular expression in knowndrives[i] is NULL, which is
-        // considered a match.
-        index = i;
-      else {
-        // Compare firmware against the regular expression in knowndrives[i].
-        regfree(&regex);  // Recycle regex.
-        if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
-          goto CONTINUE;
-        if (!regexec(&regex, firmware, 0, NULL, 0))
-          index = i;
-      }
-    }
-  CONTINUE:
-    regfree(&regex);
-  }
-
-  return index;
-}
-
-
-// Shows all presets for drives in knowndrives[].
-void showonepreset(const drivesettings *drivetable){
-  
-  const unsigned char (* presets)[2] = drivetable->vendoropts;
-  int first_preset = 1;
-  
-  // Basic error check
-  if (!drivetable || !drivetable->modelregexp){
-    pout("Null known drive table pointer. Please report\n"
-         "this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
-    return;
-  }
-  
-  // print model and firmware regular expressions
-  pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", drivetable->modelregexp);
-  pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", drivetable->firmwareregexp ?
-       drivetable->firmwareregexp : "");
-  
-  // if there are any presets, then show them
-  if (presets && (*presets)[0]) while (1) {
-    char out[256];
-    const int attr = (*presets)[0], val  = (*presets)[1];
-    unsigned char fakearray[MAX_ATTRIBUTE_NUM];
-
-    // if we are at the end of the attribute list, break out
-    if (!attr)  
-      break;
-    
-    // This is a hack. ataPrintSmartAttribName() needs a pointer to an
-    // "array" to dereference, so we provide such a pointer.
-    fakearray[attr]=val;
-    ataPrintSmartAttribName(out, attr, fakearray);
-
-    // Use leading zeros instead of spaces so that everything lines up.
-    out[0] = (out[0] == ' ') ? '0' : out[0];
-    out[1] = (out[1] == ' ') ? '0' : out[1];
-    pout("%-*s %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "", out);
-    first_preset = 0;
-    presets++;
-  }
-  else
-    pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
-
-  
-  // Is a special purpose function defined?  If so, describe it
-  if (drivetable->specialpurpose){
-    pout("%-*s ", TABLEPRINTWIDTH, "OTHER PRESETS:");
-    pout("%s\n", drivetable->functiondesc ?
-         drivetable->functiondesc : "A special purpose function "
-         "is defined for this drive"); 
-  }
-  
-  // Print any special warnings
-  if (drivetable->warningmsg){
-    pout("%-*s ", TABLEPRINTWIDTH, "WARNINGS:");
-    pout("%s\n", drivetable->warningmsg);
-  }
-  
-  return;
-}
-
-void showallpresets(void){
-  int i;
-
-  // loop over all entries in the knowndrives[] table, printing them
-  // out in a nice format
-  for (i=0; knowndrives[i].modelregexp; i++){
-    showonepreset(&knowndrives[i]);
-    pout("\n");
-  }
-  pout("For information about adding a drive to the database see the FAQ on the\n");
-  pout("smartmontools home page: " PACKAGE_HOMEPAGE "\n");
-  return;
-}
-
-// Shows the presets (if any) that are available for the given drive.
-void showpresets(const struct ata_identify_device *drive){
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
-  
-  // and search to see if they match values in the table
-  if ((i = lookupdrive(model, firmware)) < 0) {
-    // no matches found
-    pout("No presets are defined for this drive.  Its identity strings:\n"
-         "MODEL:    %s\n"
-         "FIRMWARE: %s\n"
-         "do not match any of the known regular expressions.\n"
-         "Use -P showall to list all known regular expressions.\n",
-         model, firmware);
-    return;
-  }
-  
-  // We found a matching drive.  Print out all information about it.
-  pout("Drive found in smartmontools Database.  Drive identity strings:\n"
-       "%-*s %s\n"
-       "%-*s %s\n"
-       "match smartmontools Drive Database entry:\n",
-       TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmware);
-  showonepreset(&knowndrives[i]);
-  return;
-}
-
-// Sets preset vendor attribute options in opts by finding the entry
-// (if any) for the given drive in knowndrives[].  Values that have
-// already been set in opts will not be changed.  Returns <0 if drive
-// not recognized else index >=0 into drive database.
-int applypresets(const struct ata_identify_device *drive, unsigned char **optsptr,
-		 smartmonctrl *con) {
-  int i;
-  unsigned char *opts;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-  
-  if (*optsptr==NULL)
-    bytes+=MAX_ATTRIBUTE_NUM;
-  
-  if (*optsptr==NULL && !(*optsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM,1))){
-    pout("Unable to allocate memory in applypresets()");
-    bytes-=MAX_ATTRIBUTE_NUM;
-    EXIT(1);
-  }
-  
-  opts=*optsptr;
-  
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
-  
-  // Look up the drive in knowndrives[].
-  if ((i = lookupdrive(model, firmware)) >= 0) {
-    
-    // if vendoropts is non-NULL then Attribute interpretation presets
-    if (knowndrives[i].vendoropts) {
-      const unsigned char (* presets)[2];
-      
-      // For each attribute in list of attribute/val pairs...
-      presets = knowndrives[i].vendoropts;
-      while (1) {
-	const int attr = (*presets)[0];
-	const int val  = (*presets)[1];
-	
-	if (!attr)  
-	  break;
-	
-	// ... set attribute if user hasn't already done so.
-	if (!opts[attr])
-	  opts[attr] = val;
-	presets++;
-      }
-    }
-    
-    // If a special-purpose function is defined for this drive then
-    // call it. Note that if command line arguments or Directives
-    // over-ride this choice, then the specialpurpose function that is
-    // called must deal with this.
-    if (knowndrives[i].specialpurpose)
-      (*knowndrives[i].specialpurpose)(con);
-  }
-  
-  // return <0 if drive wasn't recognized, or index>=0 into database
-  // if it was
-  return i;
-}
diff --git a/sm5/knowndrives.cpp b/sm5/knowndrives.cpp
deleted file mode 100644
index 9026bc8bbc6781532076f8b498496f4f9a7be29e..0000000000000000000000000000000000000000
--- a/sm5/knowndrives.cpp
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * knowndrives.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003-4 Philip Williams, Bruce Allen
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdio.h>
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "int64.h"
-#include "knowndrives.h"
-#include "utility.h" // includes <regex.h>
-#include "config.h"
-
-const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.117 2004/07/31 16:38:00 pjwilliams Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
-
-#define MODEL_STRING_LENGTH                         40
-#define FIRMWARE_STRING_LENGTH                       8
-#define TABLEPRINTWIDTH                             19
-
-// See vendorattributeargs[] array in atacmds.c for definitions.
-#define PRESET_9_MINUTES                   {   9,  1 }
-#define PRESET_9_TEMP                      {   9,  2 }
-#define PRESET_9_SECONDS                   {   9,  3 }
-#define PRESET_9_HALFMINUTES               {   9,  4 }
-#define PRESET_192_EMERGENCYRETRACTCYCLECT { 192,  1 }
-#define PRESET_193_LOADUNLOAD              { 193,  1 }
-#define PRESET_194_10XCELSIUS              { 194,  1 }
-#define PRESET_194_UNKNOWN                 { 194,  2 }
-#define PRESET_198_OFFLINESCANUNCSECTORCT  { 198,  1 }
-#define PRESET_200_WRITEERRORCOUNT         { 200,  1 }
-#define PRESET_201_DETECTEDTACOUNT         { 201,  1 }         
-#define PRESET_220_TEMP                    { 220,  1 }
-
-/* Arrays of preset vendor-specific attribute options for use in
- * knowndrives[]. */
-
-extern int64_t bytes;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// These three are common to several models.
-const unsigned char vendoropts_9_minutes[][2] = {
-  PRESET_9_MINUTES,
-  {0,0}
-};
-const unsigned char vendoropts_9_halfminutes[][2] = {
-  PRESET_9_HALFMINUTES,
-  {0,0}
-};
-const unsigned char vendoropts_9_seconds[][2] = {
-  PRESET_9_SECONDS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_194_UNKNOWN,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
-  PRESET_9_SECONDS,
-  PRESET_192_EMERGENCYRETRACTCYCLECT,
-  PRESET_198_OFFLINESCANUNCSECTORCT,
-  PRESET_200_WRITEERRORCOUNT,
-  PRESET_201_DETECTEDTACOUNT,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHR2040AT[][2] = {
-  PRESET_9_SECONDS,
-  PRESET_192_EMERGENCYRETRACTCYCLECT,
-  PRESET_198_OFFLINESCANUNCSECTORCT,
-  PRESET_200_WRITEERRORCOUNT,
-  {0,0}
-};
-
-const unsigned char vendoropts_Samsung_SV4012H[][2] = {
-  PRESET_9_HALFMINUTES,
-  {0,0}
-};
-
-const unsigned char vendoropts_Samsung_SV1204H[][2] = {
-  PRESET_9_HALFMINUTES,
-  PRESET_194_10XCELSIUS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Hitachi_DK23XX[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_193_LOADUNLOAD,
-  {0,0}
-};
-
-const char same_as_minus_F[]="Fixes byte order in some SMART data (same as -F samsung)";
-const char same_as_minus_F2[]="Fixes byte order in some SMART data (same as -F samsung2)";
-
-const char may_need_minus_F_disabled[] ="May need -F samsung disabled; see manual for details.";
-const char may_need_minus_F2_disabled[]="May need -F samsung2 disabled; see manual for details.";
-const char may_need_minus_F2_enabled[] ="May need -F samsung2 enabled; see manual for details.";
-const char may_need_minus_F_enabled[]  ="May need -F samsung or -F samsung2 enabled; see manual for details.";
-
-/* Special-purpose functions for use in knowndrives[]. */
-void specialpurpose_reverse_samsung(smartmonctrl *con)
-{
-  if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
-    con->fixfirmwarebug = FIX_SAMSUNG;
-}
-void specialpurpose_reverse_samsung2(smartmonctrl *con)
-{
-  if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
-    con->fixfirmwarebug = FIX_SAMSUNG2;
-}
-
-/* Table of settings for known drives terminated by an element containing all
- * zeros.  The drivesettings structure is described in knowndrives.h.  Note
- * that lookupdrive() will search knowndrives[] from the start to end or
- * until it finds the first match, so the order in knowndrives[] is important
- * for distinct entries that could match the same drive. */
-
-// Note that the table just below uses EXTENDED REGULAR EXPRESSIONS.
-// A good on-line reference for these is:
-// http://www.zeus.com/extra/docsystem/docroot/apps/web/docs/modules/access/regex.html
-
-const drivesettings knowndrives[] = {
-  { // IBM Deskstar 60GXP series
-    "IC35L0[12346]0AVER07",
-    ".*",
-    "IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
-    "Please see http://www.geocities.com/dtla_update/index.html#rel and\n"
-    "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
-    "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
-    NULL, NULL, NULL
-  },
-  { // IBM Deskstar 40GV & 75GXP series (A5AA/A6AA firmware)
-    "(IBM-)?DTLA-30[57]0[123467][05]",
-    "^T[WX][123468A]OA[56]AA$",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM Deskstar 40GV & 75GXP series (all other firmware)
-    "(IBM-)?DTLA-30[57]0[123467][05]",
-    ".*",
-    "IBM Deskstar 40GV and 75GXP drives may need upgraded SMART firmware.\n"
-    "Please see http://www.geocities.com/dtla_update/ and\n"
-    "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
-    "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
-    NULL, NULL, NULL
-  },
-  { // ExcelStor J240
-    "^ExcelStor Technology J240$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Fujitsu MPB series
-    "^FUJITSU MPB....ATU?$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPD and MPE series
-    "^FUJITSU MP[DE]....A[HTE]$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPF series
-    "^FUJITSU MPF3(102A[HT]|153A[HT]|204A[HT])$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPG series
-    "^FUJITSU MPG3(102A(H|T  E)|204A(H|[HT]  E)|307A(H  E|T)|409A[HT]  E)$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MPC series
-    "^FUJITSU MPC3(032AT|043AT|045AH|064A[HT]|084AT|096AT|102AT)$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHN2300AT
-    "^FUJITSU MHN2300AT$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHR2040AT
-    "^FUJITSU MHR2040AT$",
-    ".*",    // Tested on 40BA
-    NULL,
-    vendoropts_Fujitsu_MHR2040AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHSxxxxAT family
-    "^FUJITSU MHS20[6432]0AT(  .)?$",
-    ".*",
-    NULL,
-    vendoropts_Fujitsu_MHS2020AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHL2300AT, MHM2200AT, MHM2100AT, MHM2150AT
-    "^FUJITSU MH(L230|M2(20|10|15))0AT$",
-    ".*",
-    "This drive's firmware has a harmless Drive Identity Structure\n"
-      "checksum error bug.",
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHTxxxxAT family
-    "^FUJITSU MHT20[23468]0AT$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHTxxxxAH family
-    "^FUJITSU MHT20[468]0AH$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Samsung SV4012H (known firmware)
-    "^SAMSUNG SV4012H$",
-    "^RM100-08$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV4012H (all other firmware)
-    "^SAMSUNG SV4012H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV0412H (known firmware)
-    "^SAMSUNG SV0412H$",
-    "^SK100-01$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV0412H (all other firmware)
-    "^SAMSUNG SV0412H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV1204H (known firmware)
-    "^SAMSUNG SV1204H$",
-    "^RK100-1[3-5]$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { //Samsung SV1204H (all other firmware)
-    "^SAMSUNG SV1204H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { //SAMSUNG SV0322A tested with FW JK200-35
-    "^SAMSUNG SV0322A$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL
-  },
-  { // SAMSUNG SP40A2H with RR100-07 firmware
-    "^SAMSUNG SP40A2H$",
-    "^RR100-07$",
-    NULL,
-    vendoropts_9_halfminutes,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { 
-    // Any other Samsung disk with *-23 *-24 firmware
-    // SAMSUNG SP1213N (TL100-23 firmware)
-    // SAMSUNG SP0802N (TK100-23 firmware)
-    // Samsung SP1604N, tested with FW TM100-23 and TM100-24
-    "^SAMSUNG .*$",
-    ".*-2[34]$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung2,
-    same_as_minus_F2
-  },
-  { // All Samsung drives with '.*-25' firmware
-    "^SAMSUNG.*",
-    ".*-25$",
-    may_need_minus_F2_disabled,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung2,
-    same_as_minus_F2
-  },
-  { // All Samsung drives with '.*-26 or later (currently to -39)' firmware
-    "^SAMSUNG.*",
-    ".*-(2[6789]|3[0-9])$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    NULL,
-    NULL
-  },
-  { // Samsung ALL OTHER DRIVES
-    "^SAMSUNG.*",
-    ".*",
-    may_need_minus_F_enabled,
-    NULL, NULL, NULL
-  },
-  { // Maxtor Fireball 541DX family
-    "^Maxtor 2B0(0[468]|1[05]|20)H1$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 3400 Ultra ATA family
-    "^Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax D540X-4G family
-    "^Maxtor 4G(120J6|160J[68])$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor DiamondMax D540X-4K family
-    "^MAXTOR 4K(020H1|040H2|060H3|080H4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus D740X family
-    "^MAXTOR 6L0(20[JL]1|40[JL]2|60[JL]3|80[JL]4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 5120 Ultra ATA 33 family
-    "^Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 6800 Ultra ATA 66 family
-    "^Maxtor 9(2732U8|2390U7|2049U6|1707U5|1366U4|1024U3|0845U3|0683U2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax D540X-4D and Maxtor 4G120J6
-    "^Maxtor (4D0(20H1|40H2|60H3|80H4)|4G120J6)$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 16 family
-    "^Maxtor 4(R0[68]0[JL]|R1[26]0L|A160J)0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 4320 family
-    "^Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D4|90432D2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 20 VL family
-    "^Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax VL 30 family
-    "^Maxtor (33073U4|32049U3|31536U2|30768U1)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 36 family
-    "^Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 40 ATA 66 series
-    "^Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 40 series (Ultra ATA 66 and Ultra ATA 100)
-    "^Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 40 VL Ultra ATA 100 series
-    "^Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 45 Ulta ATA 100 family
-    "^Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 60 family
-    "^Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 80 family
-    "^Maxtor (98196H8|96147H6)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax 536DX family
-    "^Maxtor 4W(100H6|080H6|060H4|040H3|030H2)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 8 family
-    "^Maxtor 6E0[234]0L0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor DiamondMax Plus 9 family
-    "^Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor MaXLine Plus II
-    "^Maxtor 7Y250[PM]0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor MaXLine II family
-    "^Maxtor [45]A(25|32)0[JN]0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // HITACHI_DK14FA-20B
-    "^HITACHI_DK14FA-20B$",
-    ".*",
-    NULL,
-    vendoropts_Hitachi_DK23XX,
-    NULL, NULL
-  },
-  { // HITACHI Travelstar DK23XX/DK23XXB series
-    "^HITACHI_DK23..-..B?$",
-    ".*",
-    NULL,
-    vendoropts_Hitachi_DK23XX,
-    NULL, NULL
-  },
-  { // IBM Deskstar 14GXP and 16GP series
-    "^IBM-DTTA-3(7101|7129|7144|5032|5043|5064|5084|5101|5129|5168)0$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Deskstar 25GP and 22GXP family
-    "^IBM-DJNA-3(5(101|152|203|250)|7(091|135|180|220))0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM Travelstar 25GS, 18GT, and 12GN family
-    "^IBM-DARA-2(25|18|15|12|09|06)000$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Travelstar 48GH, 30GN, and 15GN family
-    "^IC25(T048ATDA05|N0(30|20|15|12|10|07|06|05)ATDA04)-.$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Travelstar 32GH, 30GT, and 20GN family
-    "^IBM-DJSA-2(32|30|20|10|05)$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Deskstar 37GP and 34GXP family
-    "^IBM-DPTA-3(5(375|300|225|150)|7(342|273|205|136))0$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM/Hitachi Travelstar 60GH and 40GN family
-    "^IC25(T060ATC[SX]05|N0[4321]0ATC[SX]04)-.$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM/Hitachi Travelstar 40GNX family
-    "^IC25N0[42]0ATC[SX]05-.$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // Hitachi Travelstar 80GN family
-    "^(Hitachi )?IC25N0[23468]0ATMR04-.$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Hitachi Travelstar 5K80 family
-    "^HTS5480[8642]0M9AT00$",
-    ".*",
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM/Hitachi Deskstar 120GXP family
-    "^IC35L((020|040|060|080|120)AVVA|0[24]0AVVN)07-[01]$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM/Hitachi Deskstar GXP-180 family 
-    "^IC35L(030|060|090|120|180)AVV207-[01]$",
-    ".*", 
-    NULL, NULL, NULL, NULL 
-  },
-  { // IBM Travelstar 14GS
-    "^IBM-DCYA-214000$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // IBM Travelstar 4LP
-    "^IBM-DTNA-2(180|216)0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Hitachi Deskstar 7K250 series
-    "^HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK4025GAS
-    "^TOSHIBA MK4025GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK6021GAS [Bruce -- use for testing on laptop]
-    "^TOSHIBA MK6021GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK4019GAX/MK4019GAXB
-    "^TOSHIBA MK4019GAXB?$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK6409MAV
-    "^TOSHIBA MK6409MAV$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOS MK3019GAXB SUN30G
-    "^TOS MK3019GAXB SUN30G$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK2016GAP, MK2017GAP, MK2018GAP, MK2018GAS, MK2023GAS
-    "^TOSHIBA MK20(1[678]GAP|(18|23)GAS)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK4018GAS
-    "^TOSHIBA MK4018GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // TOSHIBA MK3017GAP
-    "^TOSHIBA MK3017GAP$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Medalist 8641 family
-    "^ST3(2110|3221|4312|6531|8641)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U Series X family
-    "^ST3(10014A(CE)?|20014A)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U Series 6 family
-    "^ST3(8002|6002|4081|3061|2041)0A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U Series 5 family
-    "^ST3(40823|30621|20413|15311|10211)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate U8 family
-    "^ST3(8410|4313|17221|13021)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA II family
-    "^ST3(3063|2042|1532|1021)0A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA III family
-    "^ST3(40824|30620|20414|15310|10215)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA IV family
-    "^ST3(20011|40016|60021|80021)A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda ATA V family
-    "^ST3(12002(3A|4A|9A|3AS)|800(23A|15A|23AS)|60(015A|210A)|40017A)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Barracuda 7200.7 and 7200.7 Plus family
-    "^ST3(200822AS?|16002[13]AS?|12002[26]AS?|8001[13]AS?|60014A|40014AS?)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Seagate Medalist 17242, 13032, 10232, 8422, and 4312
-    "^ST3(1724|1303|1023|842|431)2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Protege
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD([2468]00E|1[26]00A)B-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar family
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(2|3|4|6|8|10|12|16|18|20|25)00BB-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar WDxxxAB series
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(3|4|6)00AB-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar WDxxxAA series
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(64|84|102|136|205|272|307)AA(-.*)?$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar WDxxxBA series
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD(102|136|153|205)BA$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar AC12500, AC24300, AC25100, AC36400, AC38400
-    "^WDC AC(125|243|251|364|384)00",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar SE family
-  /* Western Digital drives with this comment all appear to use Attribute 9 in
-   * a  non-standard manner.  These entries may need to be updated when it
-   * is understood exactly how Attribute 9 should be interpreted.
-   * UPDATE: this is probably explained by the WD firmware bug described in the
-   * smartmontools FAQ */
-    "^WDC WD((4|6|8|10|12|16|18|20|25)00JB|(12|20|25)00PB)-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar SE (Serial ATA) family
-    "^WDC WD(4|8|12|16|20|25)00JD-.*$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar AC38400
-    "^WDC AC38400L$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Western Digital Caviar AC23200L
-    "^WDC AC23200L$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLlct15 20 and QUANTUM FIREBALLlct15 30
-    "^QUANTUM FIREBALLlct15 [23]0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLlct20 series
-    "^QUANTUM FIREBALLlct20 [234]0$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL CX10.2A
-    "^QUANTUM FIREBALL CX10.2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLP LM15 and LM30
-    "^QUANTUM FIREBALLP LM(15|30)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL CR4.3A
-    "^QUANTUM FIREBALL CR4.3A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALLP AS10.2 and AS40.0
-    "^QUANTUM FIREBALLP AS(10.2|40.0)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL EX6.4A
-    "^QUANTUM FIREBALL EX6.4A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL ST3.2A
-    "^QUANTUM FIREBALL ST3.2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // QUANTUM FIREBALL EX3.2A
-    "^QUANTUM FIREBALL EX3.2A$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  /*------------------------------------------------------------
-   *  End of table.  Do not add entries below this marker.
-   *------------------------------------------------------------ */
-  {NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
-// Searches knowndrives[] for a drive with the given model number and firmware
-// string.  If either the drive's model or firmware strings are not set by the
-// manufacturer then values of NULL may be used.  Returns the index of the
-// first match in knowndrives[] or -1 if no match if found.
-int lookupdrive(const char *model, const char *firmware)
-{
-  regex_t regex;
-  int i, index;
-  const char *empty = "";
-
-  model = model ? model : empty;
-  firmware = firmware ? firmware : empty;
-
-  for (i = 0, index = -1; index == -1 && knowndrives[i].modelregexp; i++) {
-    // Attempt to compile regular expression.
-    if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
-      goto CONTINUE;
-
-    // Check whether model matches the regular expression in knowndrives[i].
-    if (!regexec(&regex, model, 0, NULL, 0)) {
-      // model matches, now check firmware.
-      if (!knowndrives[i].firmwareregexp)
-        // The firmware regular expression in knowndrives[i] is NULL, which is
-        // considered a match.
-        index = i;
-      else {
-        // Compare firmware against the regular expression in knowndrives[i].
-        regfree(&regex);  // Recycle regex.
-        if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
-          goto CONTINUE;
-        if (!regexec(&regex, firmware, 0, NULL, 0))
-          index = i;
-      }
-    }
-  CONTINUE:
-    regfree(&regex);
-  }
-
-  return index;
-}
-
-
-// Shows all presets for drives in knowndrives[].
-void showonepreset(const drivesettings *drivetable){
-  
-  const unsigned char (* presets)[2] = drivetable->vendoropts;
-  int first_preset = 1;
-  
-  // Basic error check
-  if (!drivetable || !drivetable->modelregexp){
-    pout("Null known drive table pointer. Please report\n"
-         "this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
-    return;
-  }
-  
-  // print model and firmware regular expressions
-  pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", drivetable->modelregexp);
-  pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", drivetable->firmwareregexp ?
-       drivetable->firmwareregexp : "");
-  
-  // if there are any presets, then show them
-  if (presets && (*presets)[0]) while (1) {
-    char out[256];
-    const int attr = (*presets)[0], val  = (*presets)[1];
-    unsigned char fakearray[MAX_ATTRIBUTE_NUM];
-
-    // if we are at the end of the attribute list, break out
-    if (!attr)  
-      break;
-    
-    // This is a hack. ataPrintSmartAttribName() needs a pointer to an
-    // "array" to dereference, so we provide such a pointer.
-    fakearray[attr]=val;
-    ataPrintSmartAttribName(out, attr, fakearray);
-
-    // Use leading zeros instead of spaces so that everything lines up.
-    out[0] = (out[0] == ' ') ? '0' : out[0];
-    out[1] = (out[1] == ' ') ? '0' : out[1];
-    pout("%-*s %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "", out);
-    first_preset = 0;
-    presets++;
-  }
-  else
-    pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
-
-  
-  // Is a special purpose function defined?  If so, describe it
-  if (drivetable->specialpurpose){
-    pout("%-*s ", TABLEPRINTWIDTH, "OTHER PRESETS:");
-    pout("%s\n", drivetable->functiondesc ?
-         drivetable->functiondesc : "A special purpose function "
-         "is defined for this drive"); 
-  }
-  
-  // Print any special warnings
-  if (drivetable->warningmsg){
-    pout("%-*s ", TABLEPRINTWIDTH, "WARNINGS:");
-    pout("%s\n", drivetable->warningmsg);
-  }
-  
-  return;
-}
-
-void showallpresets(void){
-  int i;
-
-  // loop over all entries in the knowndrives[] table, printing them
-  // out in a nice format
-  for (i=0; knowndrives[i].modelregexp; i++){
-    showonepreset(&knowndrives[i]);
-    pout("\n");
-  }
-  pout("For information about adding a drive to the database see the FAQ on the\n");
-  pout("smartmontools home page: " PACKAGE_HOMEPAGE "\n");
-  return;
-}
-
-// Shows the presets (if any) that are available for the given drive.
-void showpresets(const struct ata_identify_device *drive){
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
-  
-  // and search to see if they match values in the table
-  if ((i = lookupdrive(model, firmware)) < 0) {
-    // no matches found
-    pout("No presets are defined for this drive.  Its identity strings:\n"
-         "MODEL:    %s\n"
-         "FIRMWARE: %s\n"
-         "do not match any of the known regular expressions.\n"
-         "Use -P showall to list all known regular expressions.\n",
-         model, firmware);
-    return;
-  }
-  
-  // We found a matching drive.  Print out all information about it.
-  pout("Drive found in smartmontools Database.  Drive identity strings:\n"
-       "%-*s %s\n"
-       "%-*s %s\n"
-       "match smartmontools Drive Database entry:\n",
-       TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmware);
-  showonepreset(&knowndrives[i]);
-  return;
-}
-
-// Sets preset vendor attribute options in opts by finding the entry
-// (if any) for the given drive in knowndrives[].  Values that have
-// already been set in opts will not be changed.  Returns <0 if drive
-// not recognized else index >=0 into drive database.
-int applypresets(const struct ata_identify_device *drive, unsigned char **optsptr,
-		 smartmonctrl *con) {
-  int i;
-  unsigned char *opts;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-  
-  if (*optsptr==NULL)
-    bytes+=MAX_ATTRIBUTE_NUM;
-  
-  if (*optsptr==NULL && !(*optsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM,1))){
-    pout("Unable to allocate memory in applypresets()");
-    bytes-=MAX_ATTRIBUTE_NUM;
-    EXIT(1);
-  }
-  
-  opts=*optsptr;
-  
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
-  
-  // Look up the drive in knowndrives[].
-  if ((i = lookupdrive(model, firmware)) >= 0) {
-    
-    // if vendoropts is non-NULL then Attribute interpretation presets
-    if (knowndrives[i].vendoropts) {
-      const unsigned char (* presets)[2];
-      
-      // For each attribute in list of attribute/val pairs...
-      presets = knowndrives[i].vendoropts;
-      while (1) {
-	const int attr = (*presets)[0];
-	const int val  = (*presets)[1];
-	
-	if (!attr)  
-	  break;
-	
-	// ... set attribute if user hasn't already done so.
-	if (!opts[attr])
-	  opts[attr] = val;
-	presets++;
-      }
-    }
-    
-    // If a special-purpose function is defined for this drive then
-    // call it. Note that if command line arguments or Directives
-    // over-ride this choice, then the specialpurpose function that is
-    // called must deal with this.
-    if (knowndrives[i].specialpurpose)
-      (*knowndrives[i].specialpurpose)(con);
-  }
-  
-  // return <0 if drive wasn't recognized, or index>=0 into database
-  // if it was
-  return i;
-}
diff --git a/sm5/knowndrives.h b/sm5/knowndrives.h
deleted file mode 100644
index fd5851e869fd76d23a4b3189e190fa389e8cb980..0000000000000000000000000000000000000000
--- a/sm5/knowndrives.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * knowndrives.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003-4 Philip Williams, Bruce Allen
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef KNOWNDRIVES_H_
-#define KNOWNDRIVES_H_
-
-#define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h,v 1.10 2004/01/02 16:05:25 ballen4705 Exp $\n"
-
-/* Structure used to store settings for specific drives in knowndrives[]. The
- * elements are used in the following ways:
- *
- *  modelregexp     POSIX regular expression to match the model of a device.
- *                  This should never be NULL (except to terminate the
- *                  knowndrives array).
- *  firmwareregexp  POSIX regular expression to match a devices's firmware
- *                  version.  This is optional and should be NULL if it is not
- *                  to be used.  If it is non-NULL then it will be used to
- *                  narrow the set of devices matched by modelregexp.
- *  warningmsg      A message that may be displayed for matching drives.  For
- *                  example, to inform the user that they may need to apply a
- *                  firmware patch.
- *  vendoropts      Pointer to first element of an array of vendor-specific
- *                  option attribute/value pairs that should be set for a
- *                  matching device unless the user has requested otherwise.
- *                  The user's own settings override these.  The array should
- *                  be terminated with the entry {0,0}.
- *  specialpurpose  Pointer to a function that defines some additional action
- *                  that may be taken for matching devices.
- *  functiondesc    A description of the effect of the specialpurpose
- *                  function.  Used by showpresets() and showallpresets() to
- *                  make the output more informative.
- */
-typedef struct drivesettings_s {
-  const char * const modelregexp;
-  const char * const firmwareregexp;
-  const char * const warningmsg;
-  const unsigned char (* const vendoropts)[2];
-  void (* const specialpurpose)(smartmonctrl *);
-  const char * const functiondesc;
-} drivesettings;
-
-/* Table of settings for known drives.  Defined in knowndrives.c. */
-extern const drivesettings knowndrives[];
-
-// Searches knowndrives[] for a drive with the given model number and firmware
-// string.
-int lookupdrive(const char *model, const char *firmware);
-
-// Shows the presets (if any) that are available for the given drive.
-void showpresets(const struct ata_identify_device *drive);
-
-// Shows all presets for drives in knowndrives[].
-void showallpresets(void);
-
-// Sets preset vendor attribute options in opts by finding the entry
-// (if any) for the given drive in knowndrives[].  Values that have
-// already been set in opts will not be changed.  Also sets options in
-// con.  Returns <0 if drive not recognized else index of drive in
-// database.
-int applypresets(const struct ata_identify_device *drive, unsigned char **opts,
-                  smartmonctrl *con);
-
-#endif
diff --git a/sm5/os_darwin.c b/sm5/os_darwin.c
deleted file mode 100644
index 4922a19515b3a67602da4e52c64236d5a4fd0234..0000000000000000000000000000000000000000
--- a/sm5/os_darwin.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * os_darwin.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Geoffrey Keating <geoffk@geoffk.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdbool.h>
-#include <errno.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach/mach_init.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOReturn.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/storage/ata/IOATAStorageDefines.h>
-#include <IOKit/storage/ata/ATASMARTLib.h>
-#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
-#include <IOKit/storage/IOMedia.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-  // No, I don't know why there isn't a header for this.
-#define kIOATABlockStorageDeviceClass   "IOATABlockStorageDevice"
-
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-#include "os_darwin.h"
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_darwin.c,v 1.7 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-
-// Print examples for smartctl.
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-  printf(
-         "  smartctl -a disk0                            (Prints all SMART information)\n\n"
-         "  smartctl -t long /dev/disk0              (Executes extended disk self-test)\n\n"
-#ifdef HAVE_GETOPT_LONG
-         "  smartctl --smart=on --saveauto=on /dev/rdisk0 (Enables SMART on first disk)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/disk0\n"
-         "                                        (Prints Self-Test & Attribute errors)\n\n"
-#else
-         "  smartctl -s on -S on /dev/rdisk0              (Enables SMART on first disk)\n\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/disk0\n"
-         "                                        (Prints Self-Test & Attribute errors)\n\n"
-#endif
-         "  smartctl -a IOService:/MacRISC2PE/pci@f4000000/AppleMacRiscPCI/ata-6@D/AppleKauaiATA/ATADeviceNub@0/IOATABlockStorageDriver/IOATABlockStorageDevice\n"
-         "                                                 (You can use IOService: ...)\n\n"
-         "  smartctl -c IODeviceTree:/pci@f4000000/ata-6@D/@0:0\n"
-         "                                                       (... Or IODeviceTree:)\n"
-         );
-  return;
-}
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char* dev_name) {
-  // Only ATA is supported right now, so that's what it'd better be.
-  dev_name = dev_name;  // suppress unused warning.
-  return CONTROLLER_ATA;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist); the
-// other N arrays each contain null-terminated character strings.  In
-// the case N==0, no arrays are allocated because the array of 0
-// pointers has zero length, equivalent to calling malloc(0).
-int make_device_names (char*** devlist, const char* name) {
-  IOReturn err;
-  io_iterator_t i;
-  io_object_t device;
-  int result;
-  int index;
-  const char * cls;
-
-  if (strcmp (name, "ATA") == 0)
-    cls = kIOATABlockStorageDeviceClass;
-  else  // only ATA supported right now.
-    return 0;
-
-  err = IOServiceGetMatchingServices (kIOMasterPortDefault,
-				      IOServiceMatching (cls),
-				      &i);
-  if (err != kIOReturnSuccess)
-    return -1;
-
-  // Count the devices.
-  for (result = 0; (device = IOIteratorNext (i)) != MACH_PORT_NULL; result++)
-    IOObjectRelease (device);
-
-  // Create an array of service names.
-  IOIteratorReset (i);
-  *devlist = Calloc (result, sizeof (char *));
-  if (! *devlist)
-    goto error;
-  for (index = 0; (device = IOIteratorNext (i)) != MACH_PORT_NULL; index++)
-    {
-      io_string_t devName;
-      IORegistryEntryGetPath(device, kIOServicePlane, devName);
-      IOObjectRelease (device);
-
-      (*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__);
-      if (! (*devlist)[index])
-	goto error;
-    }
-  IOObjectRelease (i);
-
-  return result;
-
- error:
-  IOObjectRelease (i);
-  if (*devlist)
-    {
-      for (index = 0; index < result; index++)
-	if ((*devlist)[index])
-	  FreeNonZero ((*devlist)[index], 0, __LINE__, __FILE__);
-      FreeNonZero (*devlist, result * sizeof (char *), __LINE__, __FILE__);
-    }
-  return -1;
-}
-
-// Information that we keep about each device.
-
-static struct {
-  io_object_t ioob;
-  bool hassmart;
-  IOCFPlugInInterface **plugin;
-  IOATASMARTInterface **smartIf;
-} devices[20];
-
-// Like open().  Return non-negative integer handle, only used by the
-// functions below.  type=="ATA" or "SCSI".  The return value is
-// an index into the devices[] array.  If the device can't be opened,
-// sets errno and returns -1.
-// Acceptable device names are:
-// /dev/disk*
-// /dev/rdisk*
-// disk*
-// IOService:*
-// IODeviceTree:*
-int deviceopen(const char *pathname, char *type){
-  size_t devnum;
-  const char *devname;
-  io_object_t disk;
-  
-  if (strcmp (type, "ATA") != 0)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-  
-  // Find a free device number.
-  for (devnum = 0; devnum < sizeof (devices) / sizeof (devices[0]); devnum++)
-    if (! devices[devnum].ioob)
-      break;
-  if (devnum == sizeof (devices) / sizeof (devices[0]))
-    {
-      errno = EMFILE;
-      return -1;
-    }
-  
-  devname = NULL;
-  if (strncmp (pathname, "/dev/rdisk", 10) == 0)
-    devname = pathname + 6;
-  else if (strncmp (pathname, "/dev/disk", 9) == 0)
-    devname = pathname + 5;
-  else if (strncmp (pathname, "disk", 4) == 0)
-    // allow user to just say 'disk0'
-    devname = pathname;
-
-  // Find the device.
-  if (devname)
-    {
-      CFMutableDictionaryRef matcher;
-      matcher = IOBSDNameMatching (kIOMasterPortDefault, 0, devname);
-      disk = IOServiceGetMatchingService (kIOMasterPortDefault, matcher);
-    }
-  else
-    {
-      disk = IORegistryEntryFromPath (kIOMasterPortDefault, pathname);
-    }
-
-  if (! disk)
-    {
-      errno = ENOENT;
-      return -1;
-    }
-  
-  // Find the ATA block storage driver that is the parent of this device
-  while (! IOObjectConformsTo (disk, kIOATABlockStorageDeviceClass))
-    {
-      IOReturn err;
-      io_object_t notdisk = disk;
-
-      err = IORegistryEntryGetParentEntry (notdisk, kIOServicePlane, &disk);
-      if (err != kIOReturnSuccess || ! disk)
-	{
-	  errno = ENODEV;
-	  IOObjectRelease (notdisk);
-	  return -1;
-	}
-    }
-
-  devices[devnum].ioob = disk;
-  
-  {
-    CFDictionaryRef diskChars = NULL;
-    CFNumberRef diskFeatures = NULL;
-    UInt32 ataFeatures;
-
-    // Determine whether the drive actually supports SMART.
-    if ((diskChars = IORegistryEntryCreateCFProperty (disk, 
-			      CFSTR (kIOPropertyDeviceCharacteristicsKey),
-						      kCFAllocatorDefault,
-						      kNilOptions)) != NULL
-	&& CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
-					  (const void **)&diskFeatures)
-	&& CFNumberGetValue (diskFeatures, kCFNumberLongType, &ataFeatures)
-	&& (ataFeatures & kIOATAFeatureSMART))
-      devices[devnum].hassmart = true;
-    else
-      devices[devnum].hassmart = false;
-    if (diskChars)
-      CFRelease (diskChars);
-  }
-  
-  {
-    SInt32 dummy;
-  
-    devices[devnum].plugin = NULL;
-    devices[devnum].smartIf = NULL;
-
-    // Create an interface to the ATA SMART library.
-    if (devices[devnum].hassmart
-	&& IOCreatePlugInInterfaceForService (disk,
-					      kIOATASMARTUserClientTypeID,
-					      kIOCFPlugInInterfaceID,
-					      &devices[devnum].plugin,
-					      &dummy) == kIOReturnSuccess)
-      (*devices[devnum].plugin)->QueryInterface
-	(devices[devnum].plugin,
-	 CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
-	 (LPVOID) &devices[devnum].smartIf);
-  }
-  
-  return devnum;
-}
-
-// Like close().  Acts only on integer handles returned by
-// deviceopen() above.
-int deviceclose(int fd){
-  if (devices[fd].smartIf)
-    (*devices[fd].smartIf)->Release (devices[fd].smartIf);
-  if (devices[fd].plugin)
-    IODestroyPlugInInterface (devices[fd].plugin);
-  IOObjectRelease (devices[fd].ioob);
-  devices[fd].ioob = MACH_PORT_NULL;
-  return 0;
-}
-
-// Interface to ATA devices.  See os_linux.c for the cannonical example.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   device: is the integer handle provided by deviceopen()
-//   command: defines the different operations, see atacmds.h
-//   select: additional input data IF NEEDED (which log, which type of
-//           self-test).
-//   data:   location to write output data, IF NEEDED (1 or 512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
-//  -1 if the command failed
-//   0 if the command succeeded,
-// RETURN VALUES if command==STATUS_CHECK
-//  -1 if the command failed OR the disk SMART status can't be determined
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-
-// Things that aren't available in the Darwin interfaces:
-// - Tests other than short and extended (in particular, can't run
-//   an immediate offline test)
-// - Captive-mode tests, aborting tests
-// - ability to switch automatic offline testing on or off
-
-// Note that some versions of Darwin, at least 7H63 and earlier,
-// have a buggy library that treats the boolean value in
-// SMARTEnableDisableOperations, SMARTEnableDisableAutosave, and
-// SMARTExecuteOffLineImmediate as always being true.
-int
-ata_command_interface(int fd, smart_command_set command,
-		      int select, char *data)
-{
-  IOATASMARTInterface **ifp = devices[fd].smartIf;
-  IOATASMARTInterface *smartIf;
-  IOReturn err;
-  
-  if (! ifp)
-    return -1;
-  smartIf = *ifp;
-
-  switch (command)
-    {
-    case STATUS:
-      return 0;
-    case STATUS_CHECK:
-      {
-	Boolean is_failing;
-	err = smartIf->SMARTReturnStatus (ifp, &is_failing);
-	if (err == kIOReturnSuccess && is_failing)
-	  return 1;
-	break;
-      }
-    case ENABLE:
-    case DISABLE:
-      err = smartIf->SMARTEnableDisableOperations (ifp, command == ENABLE);
-      break;
-    case AUTOSAVE:
-      err = smartIf->SMARTEnableDisableAutosave (ifp, select != 0);
-      break;
-    case IMMEDIATE_OFFLINE:
-      if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
-	{
-	  errno = EINVAL;
-	  return -1;
-	}
-      err = smartIf->SMARTExecuteOffLineImmediate (ifp, 
-						   select == EXTEND_SELF_TEST);
-      break;
-    case READ_VALUES:
-      err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
-      break;
-    case READ_THRESHOLDS:
-      err = smartIf->SMARTReadDataThresholds (ifp, 
-					      (ATASMARTDataThresholds *)data);
-      break;
-    case READ_LOG:
-      err = smartIf->SMARTReadLogAtAddress (ifp, select, data, 512);
-      break;
-    case WRITE_LOG:
-      err = smartIf->SMARTWriteLogAtAddress (ifp, select, data, 512);
-      break;
-    case IDENTIFY:
-      {
-	UInt32 dummy;
-	err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
-	if (err == kIOReturnSuccess && isbigendian())
-	  {
-	    int i;
-	    /* The system has already byte-swapped, undo it.  */
-	    for (i = 0; i < 256; i+=2)
-	      swap2 (data + i);
-	  }
-      }
-      break;
-    case CHECK_POWER_MODE:
-      // The information is right there in the device registry, but how
-      // to get to it portably?
-    default:
-      errno = ENOTSUP;
-      return -1;
-    }
-  if (err == kIOReturnExclusiveAccess)
-    errno = EBUSY;
-  return err == kIOReturnSuccess ? 0 : -1;
-}
-
-// There's no special handling needed for hidden devices, the kernel
-// must deal with them.
-int escalade_command_interface(int fd, int escalade_port, int escalade_type,
-			       smart_command_set command, int select,
-			       char *data)
-{
-  fd = fd;
-  escalade_port = escalade_port;
-  escalade_type = escalade_type;
-  command = command;
-  select = select;
-  data = data;
-  return -1;
-}
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  return -ENOSYS;
-}
diff --git a/sm5/os_darwin.cpp b/sm5/os_darwin.cpp
deleted file mode 100644
index 27d67a079e760069a33fca1ba844e0f83663e048..0000000000000000000000000000000000000000
--- a/sm5/os_darwin.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * os_darwin.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Geoffrey Keating <geoffk@geoffk.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdbool.h>
-#include <errno.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach/mach_init.h>
-#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOReturn.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/storage/ata/IOATAStorageDefines.h>
-#include <IOKit/storage/ata/ATASMARTLib.h>
-#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
-#include <IOKit/storage/IOMedia.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-  // No, I don't know why there isn't a header for this.
-#define kIOATABlockStorageDeviceClass   "IOATABlockStorageDevice"
-
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-#include "os_darwin.h"
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp,v 1.7 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-
-// Print examples for smartctl.
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-  printf(
-         "  smartctl -a disk0                            (Prints all SMART information)\n\n"
-         "  smartctl -t long /dev/disk0              (Executes extended disk self-test)\n\n"
-#ifdef HAVE_GETOPT_LONG
-         "  smartctl --smart=on --saveauto=on /dev/rdisk0 (Enables SMART on first disk)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/disk0\n"
-         "                                        (Prints Self-Test & Attribute errors)\n\n"
-#else
-         "  smartctl -s on -S on /dev/rdisk0              (Enables SMART on first disk)\n\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/disk0\n"
-         "                                        (Prints Self-Test & Attribute errors)\n\n"
-#endif
-         "  smartctl -a IOService:/MacRISC2PE/pci@f4000000/AppleMacRiscPCI/ata-6@D/AppleKauaiATA/ATADeviceNub@0/IOATABlockStorageDriver/IOATABlockStorageDevice\n"
-         "                                                 (You can use IOService: ...)\n\n"
-         "  smartctl -c IODeviceTree:/pci@f4000000/ata-6@D/@0:0\n"
-         "                                                       (... Or IODeviceTree:)\n"
-         );
-  return;
-}
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char* dev_name) {
-  // Only ATA is supported right now, so that's what it'd better be.
-  dev_name = dev_name;  // suppress unused warning.
-  return CONTROLLER_ATA;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist); the
-// other N arrays each contain null-terminated character strings.  In
-// the case N==0, no arrays are allocated because the array of 0
-// pointers has zero length, equivalent to calling malloc(0).
-int make_device_names (char*** devlist, const char* name) {
-  IOReturn err;
-  io_iterator_t i;
-  io_object_t device;
-  int result;
-  int index;
-  const char * cls;
-
-  if (strcmp (name, "ATA") == 0)
-    cls = kIOATABlockStorageDeviceClass;
-  else  // only ATA supported right now.
-    return 0;
-
-  err = IOServiceGetMatchingServices (kIOMasterPortDefault,
-				      IOServiceMatching (cls),
-				      &i);
-  if (err != kIOReturnSuccess)
-    return -1;
-
-  // Count the devices.
-  for (result = 0; (device = IOIteratorNext (i)) != MACH_PORT_NULL; result++)
-    IOObjectRelease (device);
-
-  // Create an array of service names.
-  IOIteratorReset (i);
-  *devlist = Calloc (result, sizeof (char *));
-  if (! *devlist)
-    goto error;
-  for (index = 0; (device = IOIteratorNext (i)) != MACH_PORT_NULL; index++)
-    {
-      io_string_t devName;
-      IORegistryEntryGetPath(device, kIOServicePlane, devName);
-      IOObjectRelease (device);
-
-      (*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__);
-      if (! (*devlist)[index])
-	goto error;
-    }
-  IOObjectRelease (i);
-
-  return result;
-
- error:
-  IOObjectRelease (i);
-  if (*devlist)
-    {
-      for (index = 0; index < result; index++)
-	if ((*devlist)[index])
-	  FreeNonZero ((*devlist)[index], 0, __LINE__, __FILE__);
-      FreeNonZero (*devlist, result * sizeof (char *), __LINE__, __FILE__);
-    }
-  return -1;
-}
-
-// Information that we keep about each device.
-
-static struct {
-  io_object_t ioob;
-  bool hassmart;
-  IOCFPlugInInterface **plugin;
-  IOATASMARTInterface **smartIf;
-} devices[20];
-
-// Like open().  Return non-negative integer handle, only used by the
-// functions below.  type=="ATA" or "SCSI".  The return value is
-// an index into the devices[] array.  If the device can't be opened,
-// sets errno and returns -1.
-// Acceptable device names are:
-// /dev/disk*
-// /dev/rdisk*
-// disk*
-// IOService:*
-// IODeviceTree:*
-int deviceopen(const char *pathname, char *type){
-  size_t devnum;
-  const char *devname;
-  io_object_t disk;
-  
-  if (strcmp (type, "ATA") != 0)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-  
-  // Find a free device number.
-  for (devnum = 0; devnum < sizeof (devices) / sizeof (devices[0]); devnum++)
-    if (! devices[devnum].ioob)
-      break;
-  if (devnum == sizeof (devices) / sizeof (devices[0]))
-    {
-      errno = EMFILE;
-      return -1;
-    }
-  
-  devname = NULL;
-  if (strncmp (pathname, "/dev/rdisk", 10) == 0)
-    devname = pathname + 6;
-  else if (strncmp (pathname, "/dev/disk", 9) == 0)
-    devname = pathname + 5;
-  else if (strncmp (pathname, "disk", 4) == 0)
-    // allow user to just say 'disk0'
-    devname = pathname;
-
-  // Find the device.
-  if (devname)
-    {
-      CFMutableDictionaryRef matcher;
-      matcher = IOBSDNameMatching (kIOMasterPortDefault, 0, devname);
-      disk = IOServiceGetMatchingService (kIOMasterPortDefault, matcher);
-    }
-  else
-    {
-      disk = IORegistryEntryFromPath (kIOMasterPortDefault, pathname);
-    }
-
-  if (! disk)
-    {
-      errno = ENOENT;
-      return -1;
-    }
-  
-  // Find the ATA block storage driver that is the parent of this device
-  while (! IOObjectConformsTo (disk, kIOATABlockStorageDeviceClass))
-    {
-      IOReturn err;
-      io_object_t notdisk = disk;
-
-      err = IORegistryEntryGetParentEntry (notdisk, kIOServicePlane, &disk);
-      if (err != kIOReturnSuccess || ! disk)
-	{
-	  errno = ENODEV;
-	  IOObjectRelease (notdisk);
-	  return -1;
-	}
-    }
-
-  devices[devnum].ioob = disk;
-  
-  {
-    CFDictionaryRef diskChars = NULL;
-    CFNumberRef diskFeatures = NULL;
-    UInt32 ataFeatures;
-
-    // Determine whether the drive actually supports SMART.
-    if ((diskChars = IORegistryEntryCreateCFProperty (disk, 
-			      CFSTR (kIOPropertyDeviceCharacteristicsKey),
-						      kCFAllocatorDefault,
-						      kNilOptions)) != NULL
-	&& CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
-					  (const void **)&diskFeatures)
-	&& CFNumberGetValue (diskFeatures, kCFNumberLongType, &ataFeatures)
-	&& (ataFeatures & kIOATAFeatureSMART))
-      devices[devnum].hassmart = true;
-    else
-      devices[devnum].hassmart = false;
-    if (diskChars)
-      CFRelease (diskChars);
-  }
-  
-  {
-    SInt32 dummy;
-  
-    devices[devnum].plugin = NULL;
-    devices[devnum].smartIf = NULL;
-
-    // Create an interface to the ATA SMART library.
-    if (devices[devnum].hassmart
-	&& IOCreatePlugInInterfaceForService (disk,
-					      kIOATASMARTUserClientTypeID,
-					      kIOCFPlugInInterfaceID,
-					      &devices[devnum].plugin,
-					      &dummy) == kIOReturnSuccess)
-      (*devices[devnum].plugin)->QueryInterface
-	(devices[devnum].plugin,
-	 CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
-	 (LPVOID) &devices[devnum].smartIf);
-  }
-  
-  return devnum;
-}
-
-// Like close().  Acts only on integer handles returned by
-// deviceopen() above.
-int deviceclose(int fd){
-  if (devices[fd].smartIf)
-    (*devices[fd].smartIf)->Release (devices[fd].smartIf);
-  if (devices[fd].plugin)
-    IODestroyPlugInInterface (devices[fd].plugin);
-  IOObjectRelease (devices[fd].ioob);
-  devices[fd].ioob = MACH_PORT_NULL;
-  return 0;
-}
-
-// Interface to ATA devices.  See os_linux.c for the cannonical example.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   device: is the integer handle provided by deviceopen()
-//   command: defines the different operations, see atacmds.h
-//   select: additional input data IF NEEDED (which log, which type of
-//           self-test).
-//   data:   location to write output data, IF NEEDED (1 or 512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
-//  -1 if the command failed
-//   0 if the command succeeded,
-// RETURN VALUES if command==STATUS_CHECK
-//  -1 if the command failed OR the disk SMART status can't be determined
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-
-// Things that aren't available in the Darwin interfaces:
-// - Tests other than short and extended (in particular, can't run
-//   an immediate offline test)
-// - Captive-mode tests, aborting tests
-// - ability to switch automatic offline testing on or off
-
-// Note that some versions of Darwin, at least 7H63 and earlier,
-// have a buggy library that treats the boolean value in
-// SMARTEnableDisableOperations, SMARTEnableDisableAutosave, and
-// SMARTExecuteOffLineImmediate as always being true.
-int
-ata_command_interface(int fd, smart_command_set command,
-		      int select, char *data)
-{
-  IOATASMARTInterface **ifp = devices[fd].smartIf;
-  IOATASMARTInterface *smartIf;
-  IOReturn err;
-  
-  if (! ifp)
-    return -1;
-  smartIf = *ifp;
-
-  switch (command)
-    {
-    case STATUS:
-      return 0;
-    case STATUS_CHECK:
-      {
-	Boolean is_failing;
-	err = smartIf->SMARTReturnStatus (ifp, &is_failing);
-	if (err == kIOReturnSuccess && is_failing)
-	  return 1;
-	break;
-      }
-    case ENABLE:
-    case DISABLE:
-      err = smartIf->SMARTEnableDisableOperations (ifp, command == ENABLE);
-      break;
-    case AUTOSAVE:
-      err = smartIf->SMARTEnableDisableAutosave (ifp, select != 0);
-      break;
-    case IMMEDIATE_OFFLINE:
-      if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
-	{
-	  errno = EINVAL;
-	  return -1;
-	}
-      err = smartIf->SMARTExecuteOffLineImmediate (ifp, 
-						   select == EXTEND_SELF_TEST);
-      break;
-    case READ_VALUES:
-      err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
-      break;
-    case READ_THRESHOLDS:
-      err = smartIf->SMARTReadDataThresholds (ifp, 
-					      (ATASMARTDataThresholds *)data);
-      break;
-    case READ_LOG:
-      err = smartIf->SMARTReadLogAtAddress (ifp, select, data, 512);
-      break;
-    case WRITE_LOG:
-      err = smartIf->SMARTWriteLogAtAddress (ifp, select, data, 512);
-      break;
-    case IDENTIFY:
-      {
-	UInt32 dummy;
-	err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
-	if (err == kIOReturnSuccess && isbigendian())
-	  {
-	    int i;
-	    /* The system has already byte-swapped, undo it.  */
-	    for (i = 0; i < 256; i+=2)
-	      swap2 (data + i);
-	  }
-      }
-      break;
-    case CHECK_POWER_MODE:
-      // The information is right there in the device registry, but how
-      // to get to it portably?
-    default:
-      errno = ENOTSUP;
-      return -1;
-    }
-  if (err == kIOReturnExclusiveAccess)
-    errno = EBUSY;
-  return err == kIOReturnSuccess ? 0 : -1;
-}
-
-// There's no special handling needed for hidden devices, the kernel
-// must deal with them.
-int escalade_command_interface(int fd, int escalade_port, int escalade_type,
-			       smart_command_set command, int select,
-			       char *data)
-{
-  fd = fd;
-  escalade_port = escalade_port;
-  escalade_type = escalade_type;
-  command = command;
-  select = select;
-  data = data;
-  return -1;
-}
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  return -ENOSYS;
-}
diff --git a/sm5/os_darwin.h b/sm5/os_darwin.h
deleted file mode 100644
index ae1f1c0c135be4369c60676dd0baeeef451c7260..0000000000000000000000000000000000000000
--- a/sm5/os_darwin.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * os_generic.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Geoff Keating <geoffk@geoffk.org>
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef OS_DARWIN_H_
-#define OS_DARWIN_H_
-
-#define OS_XXXX_H_CVSID "$Id: os_darwin.h,v 1.1 2004/07/16 01:41:20 geoffk1 Exp $\n"
-
-// There isn't actually any content here yet.
-
-#endif /* OS_DARWIN_H_ */
diff --git a/sm5/os_darwin/English_Localizable.strings b/sm5/os_darwin/English_Localizable.strings
deleted file mode 100644
index 4f5d3d6c48963d13aacfbcb2ffb15c06940718ca..0000000000000000000000000000000000000000
--- a/sm5/os_darwin/English_Localizable.strings
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
-<plist version="0.9">
-<dict>
-        <key>SMART disk monitoring</key>
-        <string>SMART disk monitoring</string>
-        <key>Starting SMART disk monitoring</key>
-        <string>Starting SMART disk monitoring</string>
-        <key>Stopping SMART disk monitoring</key>
-        <string>Stopping SMART disk monitoring</string>
-</dict>
-</plist>
diff --git a/sm5/os_darwin/SMART.in b/sm5/os_darwin/SMART.in
deleted file mode 100644
index 4425ca9b68f8d627097d515ad67a3be599f85b25..0000000000000000000000000000000000000000
--- a/sm5/os_darwin/SMART.in
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-
-# Darwin init file for smartd
-#
-# Home page of code is: http://smartmontools.sourceforge.net
-#
-# Copyright (C) 2004 Geoffrey Keating <geoffk@geoffk.org>
-#
-# 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, write to the Free Software Foundation, Inc., 675
-# Mass Ave, Cambridge, MA 02139, USA.
-
-# $Id: SMART.in,v 1.2 2004/08/09 05:31:43 geoffk1 Exp $
-
-##
-# SMART monitoring
-##
-
-. /etc/rc.common
-
-StartService ()
-{
-    if [ "${SMARTd:=-YES-}" = "-YES-" ] &&
-       ! GetPID smartd > /dev/null; then
-
-        ConsoleMessage "Starting SMART disk monitoring"
-
-        /usr/sbin/smartd -p /var/run/smartd.pid
-    fi
-}
-
-StopService ()
-{
-    if pid=$(GetPID smartd); then
-        ConsoleMessage "Stopping SMART disk monitoring"
-        kill -TERM "${pid}"
-    else
-        echo "smartd is not running."
-    fi
-}
-
-RestartService ()
-{
-    if pid=$(GetPID smartd); then
-        kill -HUP "${pid}"
-    else
-        StartService
-    fi
-}
-
-RunService "$1"
diff --git a/sm5/os_darwin/StartupParameters.plist b/sm5/os_darwin/StartupParameters.plist
deleted file mode 100644
index 174d831d031cc766ea12a9ba56ce83c47bf9c45f..0000000000000000000000000000000000000000
--- a/sm5/os_darwin/StartupParameters.plist
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  Description     = "SMART disk monitoring";
-  Provides        = ("SMART");
-  Requires        = ("System Log");
-}
diff --git a/sm5/os_freebsd.c b/sm5/os_freebsd.c
deleted file mode 100644
index 1cde13c0b01f49242b5b2ad68fce8465a57d57db..0000000000000000000000000000000000000000
--- a/sm5/os_freebsd.c
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * os_freebsd.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <err.h>
-#include <camlib.h>
-#include <cam/scsi/scsi_message.h>
-#include <sys/ata.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <glob.h>
-#include <fcntl.h>
-
-
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-#include "os_freebsd.h"
-
-static const char *filenameandversion="$Id: os_freebsd.c,v 1.40 2004/08/16 22:44:26 ballen4705 Exp $";
-
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.c,v 1.40 2004/08/16 22:44:26 ballen4705 Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Private table of open devices: guaranteed zero on startup since
-// part of static data.
-struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
-
-// forward declaration
-static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *ch);
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/ad0                       (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/ad0              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-//         "  smartctl -a --device=3ware,2 /dev/sda\n"
-//         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/ad0                       (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/ad0         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/ad0              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/ad0\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-//         "  smartctl -a -d 3ware,2 /dev/sda\n"
-//         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#endif
-  return;
-}
-
-// Like open().  Return positive integer handle, used by functions below only.  mode=="ATA" or "SCSI".
-int deviceopen (const char* dev, char* mode) {
-  struct freebsd_dev_channel *fdchan;
-  int parse_ok, i;
-
-  // Search table for a free entry
-  for (i=0; i<FREEBSD_MAXDEV; i++)
-    if (!devicetable[i])
-      break;
-  
-  // If no free entry found, return error.  We have max allowed number
-  // of "file descriptors" already allocated.
-  if (i==FREEBSD_MAXDEV) {
-    errno=EMFILE;
-    return -1;
-  }
-
-  fdchan = calloc(1,sizeof(struct freebsd_dev_channel));
-  if (fdchan == NULL) {
-    // errno already set by call to malloc()
-    return -1;
-  }
-
-  parse_ok = parse_ata_chan_dev (dev,fdchan);
-  if (parse_ok == CONTROLLER_UNKNOWN) {
-    free(fdchan);
-    errno = ENOTTY;
-    return -1; // can't handle what we don't know
-  }
-
-  if (parse_ok == CONTROLLER_ATA) {
-    if ((fdchan->atacommand = open("/dev/ata",O_RDWR))<0) {
-      int myerror = errno;      //preserve across free call
-      free (fdchan);
-      errno = myerror;
-      return -1;
-    }
-  }
-
-  if (parse_ok == CONTROLLER_3WARE_678K_CHAR) {
-    char buf[512];
-    sprintf(buf,"/dev/twe%d",fdchan->device);
-    printf("Using %s, as control device\n", buf);
-    if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
-      int myerror = errno; // preserver across free call
-      free(fdchan);
-      errno=myerror;
-      return -1;
-    }
-  }
-
-  if (parse_ok == CONTROLLER_SCSI) {
-    // this is really a NO-OP, as the parse takes care
-    // of filling in correct details
-  }
-  
-  // return pointer to "file descriptor" table entry, properly offset.
-  devicetable[i]=fdchan;
-  return i+FREEBSD_FDOFFSET;
-}
-
-// Returns 1 if device not available/open/found else 0.  Also shifts fd into valid range.
-static int isnotopen(int *fd, struct freebsd_dev_channel** fdchan) {
-  // put valid "file descriptor" into range 0...FREEBSD_MAXDEV-1
-  *fd -= FREEBSD_FDOFFSET;
-  
-  // check for validity of "file descriptor".
-  if (*fd<0 || *fd>=FREEBSD_MAXDEV || !((*fdchan)=devicetable[*fd])) {
-    errno = ENODEV;
-    return 1;
-  }
-  
-  return 0;
-}
-
-// Like close().  Acts on handles returned by above function.
-int deviceclose (int fd) {
-  struct freebsd_dev_channel *fdchan;
-  int failed = 0;
-
-  // check for valid file descriptor
-  if (isnotopen(&fd, &fdchan))
-    return -1;
-  
-
-  // did we allocate a SCSI device name?
-  if (fdchan->devname)
-    free(fdchan->devname);
-  
-  // close device, if open
-  if (fdchan->atacommand)
-    failed=close(fdchan->atacommand);
-
-  if (fdchan->scsicontrol)
-    failed=close(fdchan->scsicontrol);
-  
-  // if close succeeded, then remove from device list
-  // Eduard, should we also remove it from list if close() fails?  I'm
-  // not sure. Here I only remove it from list if close() worked.
-  if (!failed) {
-    free(fdchan);
-    devicetable[fd]=NULL;
-  }
-  
-  return failed;
-}
-
-#define NO_RETURN 0
-#define BAD_SMART 1
-#define NO_3WARE 2
-#define BAD_KERNEL 3
-#define MAX_MSG 3
-
-// Utility function for printing warnings
-void printwarning(int msgNo, const char* extra) {
-  static int printed[] = {0,0,0,0};
-  static const char* message[]={
-    "The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n can not be retrieved with this version of ATAng, please do not rely on this value\nYou should update to at least 5.2\n",
-    
-    "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
-    
-    PACKAGE_STRING " does not currentlly support TWE devices (3ware Escalade)\n",
-    
-    "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
-  };
-
-  if (msgNo >= 0 && msgNo <= MAX_MSG) {
-    if (!printed[msgNo]) {
-      printed[msgNo] = 1;
-      pout("%s", message[msgNo]);
-      if (extra)
-        pout("%s",extra);
-    }
-  }
-  return;
-}
-
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
-#ifndef ATAREQUEST
-  // sorry, but without ATAng, we can't do anything here
-  printwarning(BAD_KERNEL,NULL);
-  errno = ENOSYS;
-  return -1;
-#else
-  struct freebsd_dev_channel* con;
-  int retval, copydata=0;
-  struct ata_cmd iocmd;
-  unsigned char buff[512];
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -1;
-
-  bzero(buff,512);
-
-  bzero(&iocmd,sizeof(struct ata_cmd));
-  bzero(buff,512);
-  iocmd.cmd=ATAREQUEST;
-  iocmd.channel=con->channel;
-  iocmd.device=con->device;
-
-  iocmd.u.request.u.ata.command=ATA_SMART_CMD;
-  iocmd.u.request.timeout=600;
-  switch (command){
-  case READ_VALUES:
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_VALUES;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case READ_THRESHOLDS:
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_THRESHOLDS;
-    iocmd.u.request.u.ata.count=1;
-    iocmd.u.request.u.ata.lba=1|(0xc24f<<8);
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case READ_LOG:
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_LOG_SECTOR;
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
-    iocmd.u.request.u.ata.count=1;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case IDENTIFY:
-    iocmd.u.request.u.ata.command=ATA_IDENTIFY_DEVICE;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case PIDENTIFY:
-    iocmd.u.request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case ENABLE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_ENABLE;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case DISABLE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_DISABLE;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case AUTO_OFFLINE:
-    // NOTE: According to ATAPI 4 and UP, this command is obsolete
-    iocmd.u.request.u.ata.feature=ATA_SMART_AUTO_OFFLINE;
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case AUTOSAVE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_AUTOSAVE;
-    iocmd.u.request.u.ata.count=0xf1;  // to enable autosave
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case IMMEDIATE_OFFLINE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;
-    iocmd.u.request.u.ata.lba = select|(0xc24f<<8); // put test in sector
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case STATUS_CHECK: // same command, no HDIO in FreeBSD
-  case STATUS:
-    // this command only says if SMART is working.  It could be
-    // replaced with STATUS_CHECK below.
-    iocmd.u.request.u.ata.feature=ATA_SMART_STATUS;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  default:
-    pout("Unrecognized command %d in ata_command_interface()\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command);
-    errno=ENOSYS;
-    return -1;
-  }
-  
-  if (command==STATUS_CHECK){
-    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
-    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
-    unsigned char low,high;
-    
-    if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)))
-      return -1;
-
-#if __FreeBSD_version < 502000
-    printwarning(NO_RETURN,NULL);
-#endif
-
-    high = (iocmd.u.request.u.ata.lba >> 16) & 0xff;
-    low = (iocmd.u.request.u.ata.lba >> 8) & 0xff;
-    
-    // Cyl low and Cyl high unchanged means "Good SMART status"
-    if (low==normal_lo && high==normal_hi)
-      return 0;
-    
-    // These values mean "Bad SMART status"
-    if (low==failed_lo && high==failed_hi)
-      return 1;
-    
-    // We haven't gotten output that makes sense; print out some debugging info
-    char buf[512];
-    sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
-            (int)iocmd.u.request.u.ata.command,
-            (int)iocmd.u.request.u.ata.feature,
-            (int)iocmd.u.request.u.ata.count,
-            (int)((iocmd.u.request.u.ata.lba) & 0xff),
-            (int)((iocmd.u.request.u.ata.lba>>8) & 0xff),
-            (int)((iocmd.u.request.u.ata.lba>>16) & 0xff),
-            (int)iocmd.u.request.error);
-    printwarning(BAD_SMART,buf);
-    return 0;   
-  }
-
-  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) {
-    perror("Failed command: ");
-    return -1;
-  }
-  // 
-  if (copydata)
-    memcpy(data, buff, 512);
-  
-  return 0;
-#endif
-}
-
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-  struct freebsd_dev_channel* con = NULL;
-  struct cam_device* cam_dev = NULL;
-  union ccb *ccb;
-  
-  
-    if (report > 0) {
-        unsigned int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -ENOTTY;
-
-
-  if (!(cam_dev = cam_open_spec_device(con->devname,con->unitnum,O_RDWR,NULL))) {
-    warnx("%s",cam_errbuf);
-    return -1;
-  }
-
-  if (!(ccb = cam_getccb(cam_dev))) {
-    warnx("error allocating ccb");
-    return -ENOMEM;
-  }
-
-  // clear out structure, except for header that was filled in for us
-  bzero(&(&ccb->ccb_h)[1],
-        sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
-
-  cam_fill_csio(&ccb->csio,
-                /*retrires*/ 1,
-                /*cbfcnp*/ NULL,
-                /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
-                /* tagaction */ MSG_SIMPLE_Q_TAG,
-                /* dataptr */ iop->dxferp,
-                /* datalen */ iop->dxfer_len,
-                /* senselen */ iop->max_sense_len,
-                /* cdblen */ iop->cmnd_len,
-                /* timout (converted to seconds) */ iop->timeout*1000);
-  memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
-
-  if (cam_send_ccb(cam_dev,ccb) < 0) {
-    warn("error sending SCSI ccb");
- #if __FreeBSD_version > 500000
-    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
- #endif
-    cam_freeccb(ccb);
-    return -1;
-  }
-
-  if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- #if __FreeBSD_version > 500000
-    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
- #endif
-    cam_freeccb(ccb);
-    return -1;
-  }
-
-  if (iop->sensep) {
-    memcpy(iop->sensep,&(ccb->csio.sense_data),sizeof(struct scsi_sense_data));
-    iop->resp_sense_len = sizeof(struct scsi_sense_data);
-  }
-
-  iop->scsi_status = ccb->csio.scsi_status;
-
-  cam_freeccb(ccb);
-  
-  if (cam_dev)
-    cam_close_device(cam_dev);
-
-  if (report > 0) {
-    int trunc;
-
-    pout("  status=0\n");
-    trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-         (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-  return 0;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) {
-
-  // to hold true file descriptor
-  struct freebsd_dev_channel* con;
-
-  // return value and buffer for ioctl()
-  int  ioctlreturn, readdata=0;
-
-  // Used by both the SCSI and char interfaces
-  char ioctl_buffer[sizeof(struct twe_usercommand)];
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -1;
-
-  memset(ioctl_buffer, 0, sizeof(struct twe_usercommand));
-
-  struct twe_usercommand* cmd = (struct twe_usercommand*)ioctl_buffer;
-  cmd->tu_command.ata.opcode = TWE_OP_ATA_PASSTHROUGH;
-
-  // Same for (almost) all commands - but some reset below
-  cmd->tu_command.ata.request_id    = 0xFF;
-  cmd->tu_command.ata.unit   = disknum;
-  cmd->tu_command.ata.host_id = 0;
-  cmd->tu_command.ata.status        = 0;           
-  cmd->tu_command.ata.flags         = 0x1;
-  cmd->tu_command.ata.drive_head    = 0x0;
-  cmd->tu_command.ata.sector_num    = 0;
-
-  // All SMART commands use this CL/CH signature.  These are magic
-  // values from the ATA specifications.
-  cmd->tu_command.ata.cylinder_lo   = 0x4F;
-  cmd->tu_command.ata.cylinder_hi   = 0xC2;
-  
-  // SMART ATA COMMAND REGISTER value
-  cmd->tu_command.ata.command       = ATA_SMART_CMD;
-  
-  // Is this a command that reads or returns 512 bytes?
-  // passthru->param values are:
-  // 0x0 - non data command without TFR write check,
-  // 0x8 - non data command with TFR write check,
-  // 0xD - data command that returns data to host from device
-  // 0xF - data command that writes data from host to device
-  // passthru->size values are 0x5 for non-data and 0x07 for data
-  if (command == READ_VALUES     ||
-      command == READ_THRESHOLDS ||
-      command == READ_LOG        ||
-      command == IDENTIFY        ||
-      command == WRITE_LOG ) {
-    readdata=1;
-    cmd->tu_size = 512;
-    cmd->tu_data = data;
-    cmd->tu_command.ata.sgl_offset = 0x5;
-    cmd->tu_command.ata.size         = 0x5;
-    cmd->tu_command.ata.param        = 0xD;
-    cmd->tu_command.ata.sector_count = 0x1;
-    // For 64-bit to work correctly, up the size of the command packet
-    // in dwords by 1 to account for the 64-bit single sgl 'address'
-    // field. Note that this doesn't agree with the typedefs but it's
-    // right (agree with kernel driver behavior/typedefs).
-    //if (sizeof(long)==8)
-    //  cmd->tu_command.ata.size++;
-  }
-  else {
-    // Non data command -- but doesn't use large sector 
-    // count register values.  
-    cmd->tu_command.ata.sgl_offset = 0x0;
-    cmd->tu_command.ata.size         = 0x5;
-    cmd->tu_command.ata.param        = 0x8;
-    cmd->tu_command.ata.sector_count = 0x0;
-  }
-  
-  // Now set ATA registers depending upon command
-  switch (command){
-  case CHECK_POWER_MODE:
-    cmd->tu_command.ata.command     = ATA_CHECK_POWER_MODE;
-    cmd->tu_command.ata.features    = 0;
-    cmd->tu_command.ata.cylinder_lo = 0;
-    cmd->tu_command.ata.cylinder_hi = 0;
-    break;
-  case READ_VALUES:
-    cmd->tu_command.ata.features = ATA_SMART_READ_VALUES;
-    break;
-  case READ_THRESHOLDS:
-    cmd->tu_command.ata.features = ATA_SMART_READ_THRESHOLDS;
-    break;
-  case READ_LOG:
-    cmd->tu_command.ata.features = ATA_SMART_READ_LOG_SECTOR;
-    // log number to return
-    cmd->tu_command.ata.sector_num  = select;
-    break;
-  case WRITE_LOG:
-    cmd->tu_data = data;
-    readdata=0;
-    cmd->tu_command.ata.features     = ATA_SMART_WRITE_LOG_SECTOR;
-    cmd->tu_command.ata.sector_count = 1;
-    cmd->tu_command.ata.sector_num   = select;
-    cmd->tu_command.ata.param        = 0xF;  // PIO data write
-    break;
-  case IDENTIFY:
-    // ATA IDENTIFY DEVICE
-    cmd->tu_command.ata.command     = ATA_IDENTIFY_DEVICE;
-    cmd->tu_command.ata.features    = 0;
-    cmd->tu_command.ata.cylinder_lo = 0;
-    cmd->tu_command.ata.cylinder_hi = 0;
-    break;
-  case PIDENTIFY:
-    // 3WARE controller can NOT have packet device internally
-    pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
-    errno=ENODEV;
-    return -1;
-  case ENABLE:
-    cmd->tu_command.ata.features = ATA_SMART_ENABLE;
-    break;
-  case DISABLE:
-    cmd->tu_command.ata.features = ATA_SMART_DISABLE;
-    break;
-  case AUTO_OFFLINE:
-    cmd->tu_command.ata.features     = ATA_SMART_AUTO_OFFLINE;
-    // Enable or disable?
-    cmd->tu_command.ata.sector_count = select;
-    break;
-  case AUTOSAVE:
-    cmd->tu_command.ata.features     = ATA_SMART_AUTOSAVE;
-    // Enable or disable?
-    cmd->tu_command.ata.sector_count = select;
-    break;
-  case IMMEDIATE_OFFLINE:
-    cmd->tu_command.ata.features    = ATA_SMART_IMMEDIATE_OFFLINE;
-    // What test type to run?
-    cmd->tu_command.ata.sector_num  = select;
-    break;
-  case STATUS_CHECK:
-    cmd->tu_command.ata.features = ATA_SMART_STATUS;
-    break;
-  case STATUS:
-    // This is JUST to see if SMART is enabled, by giving SMART status
-    // command. But it doesn't say if status was good, or failing.
-    // See below for the difference.
-    cmd->tu_command.ata.features = ATA_SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  // Now send the command down through an ioctl()
-  ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd);
-  
-  // Deal with the different error cases
-  if (ioctlreturn) {
-    if (!errno)
-      errno=EIO;
-    return -1;
-  }
-  
-  // See if the ATA command failed.  Now that we have returned from
-  // the ioctl() call, if passthru is valid, then:
-  // - cmd->tu_command.ata.status contains the 3ware controller STATUS
-  // - cmd->tu_command.ata.command contains the ATA STATUS register
-  // - cmd->tu_command.ata.features contains the ATA ERROR register
-  //
-  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
-  // If bit 0 (error bit) is set, then ATA ERROR register is valid.
-  // While we *might* decode the ATA ERROR register, at the moment it
-  // doesn't make much sense: we don't care in detail why the error
-  // happened.
-  
-  if (cmd->tu_command.ata.status || (cmd->tu_command.ata.command & 0x21)) {
-    pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",cmd->tu_command.ata.status,cmd->tu_command.ata.command,cmd->tu_command.ata.flags);
-    errno=EIO;
-    return -1;
-  }
-  
-  // For STATUS_CHECK, we need to check register values
-  if (command==STATUS_CHECK) {
-    
-    // To find out if the SMART RETURN STATUS is good or failing, we
-    // need to examine the values of the Cylinder Low and Cylinder
-    // High Registers.
-    
-    unsigned short cyl_lo=cmd->tu_command.ata.cylinder_lo;
-    unsigned short cyl_hi=cmd->tu_command.ata.cylinder_hi;
-    
-    // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
-    if (cyl_lo==0x4F && cyl_hi==0xC2)
-      return 0;
-    
-    // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
-    if (cyl_lo==0xF4 && cyl_hi==0x2C)
-      return 1;
-    
-      errno=EIO;
-      return -1;
-  }
-  
-  // copy sector count register (one byte!) to return data
-  if (command==CHECK_POWER_MODE)
-    *data=*(char *)&(cmd->tu_command.ata.sector_count);
-  
-  // look for nonexistent devices/ports
-  if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
-    errno=ENODEV;
-    return -1;
-  }
-  
-  return 0;
-}
-
-static int get_twe_channel_unit (const char* name, int* unit, int* dev) {
-  // at some  point, we need to figure out which TWE controller any
-  // given disk belongs to.....
-  // at this point, I have no clue how to do this...so for now, it is
-  // always going to be controller 0
-  *dev=0;
-  *unit=0; // not really needed for TWE drives, as we handle that seperately
-  return 0;
-}
-
-static int get_ata_channel_unit ( const char* name, int* unit, int* dev) {
-#ifndef ATAREQUEST
-  *dev=0;
-  *unit=0;
-return 0;
-#else
-  // there is no direct correlation between name 'ad0, ad1, ...' and
-  // channel/unit number.  So we need to iterate through the possible
-  // channels and check each unit to see if we match names
-  struct ata_cmd iocmd;
-  int fd,maxunit;
-  
-  bzero(&iocmd, sizeof(struct ata_cmd));
-
-  if ((fd = open("/dev/ata", O_RDWR)) < 0)
-    return -errno;
-  
-  iocmd.cmd = ATAGMAXCHANNEL;
-  if (ioctl(fd, IOCATA, &iocmd) < 0) {
-    return -errno;
-    close(fd);
-  }
-  maxunit = iocmd.u.maxchan;
-  for (*unit = 0; *unit < maxunit; (*unit)++) {
-    iocmd.channel = *unit;
-    iocmd.device = -1;
-    iocmd.cmd = ATAGPARM;
-    if (ioctl(fd, IOCATA, &iocmd) < 0) {
-      close(fd);
-      return -errno;
-    }
-    if (iocmd.u.param.type[0] && !strcmp(name,iocmd.u.param.name[0])) {
-      *dev = 0;
-      break;
-    }
-    if (iocmd.u.param.type[1] && !strcmp(name,iocmd.u.param.name[1])) {
-      *dev = 1;
-      break;
-    }
-  }
-  close(fd);
-  if (*unit == maxunit)
-    return -1;
-  else
-    return 0;
-#endif
-}
-
-
-// Guess device type (ata or scsi) based on device name (FreeBSD
-// specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
-// osst, nosst and sg.
-static const char * fbsd_dev_prefix = "/dev/";
-static const char * fbsd_dev_ata_disk_prefix = "ad";
-static const char * fbsd_dev_scsi_disk_plus = "da";
-static const char * fbsd_dev_scsi_tape1 = "sa";
-static const char * fbsd_dev_scsi_tape2 = "nsa";
-static const char * fbsd_dev_scsi_tape3 = "esa";
-static const char * fbsd_dev_twe_disk = "twed";
-
-static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
-  int len;
-  int dev_prefix_len = strlen(fbsd_dev_prefix);
-  
-  // if dev_name null, or string length zero
-  if (!dev_name || !(len = strlen(dev_name)))
-    return CONTROLLER_UNKNOWN;;
-  
-  // Remove the leading /dev/... if it's there
-  if (!strncmp(fbsd_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len) 
-      // if nothing else in the string, unrecognized
-      return CONTROLLER_UNKNOWN;
-    // else advance pointer to following characters
-    dev_name += dev_prefix_len;
-  }
-  // form /dev/ad* or ad*
-  if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
-               strlen(fbsd_dev_ata_disk_prefix))) {
-    if (chan != NULL) {
-      if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
-        return CONTROLLER_UNKNOWN;
-      }
-    }
-    return CONTROLLER_ATA;
-  }
-  
-  // form /dev/da* or da*
-  if (!strncmp(fbsd_dev_scsi_disk_plus, dev_name,
-               strlen(fbsd_dev_scsi_disk_plus)))
-    goto handlescsi;
-
-  // form /dev/sa* or sa*
-  if (!strncmp(fbsd_dev_scsi_tape1, dev_name,
-              strlen(fbsd_dev_scsi_tape1)))
-    goto handlescsi;
-
-  // form /dev/nsa* or nsa*
-  if (!strncmp(fbsd_dev_scsi_tape2, dev_name,
-              strlen(fbsd_dev_scsi_tape2)))
-    goto handlescsi;
-
-  // form /dev/esa* or esa*
-  if (!strncmp(fbsd_dev_scsi_tape3, dev_name,
-              strlen(fbsd_dev_scsi_tape3)))
-    goto handlescsi;
-  
-  if (!strncmp(fbsd_dev_twe_disk,dev_name,
-	       strlen(fbsd_dev_twe_disk))) {
-    if (chan != NULL) {
-      if (get_twe_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
-	return CONTROLLER_UNKNOWN;
-      }
-    }
-    return CONTROLLER_3WARE_678K_CHAR;
-  }
-
-  // we failed to recognize any of the forms
-  return CONTROLLER_UNKNOWN;
-
- handlescsi:
-  if (chan != NULL) {
-    if (!(chan->devname = calloc(1,DEV_IDLEN+1)))
-      return CONTROLLER_UNKNOWN;
-    
-    if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)
-      return CONTROLLER_UNKNOWN;
-  }
-  return CONTROLLER_SCSI;
-  
-}
-
-int guess_device_type (const char* dev_name) {
-  return parse_ata_chan_dev(dev_name,NULL);
-}
-
-// global variable holding byte count of allocated memory
-extern long long bytes;
-
-// we are going to take advantage of the fact that FreeBSD's devfs will only
-// have device entries for devices that exist.  So if we get the equivilent of
-// ls /dev/ad?, we have all the ATA devices on the system
-//
-// If any errors occur, leave errno set as it was returned by the
-// system call, and return <0.
-
-// Return values:
-// -1 out of memory
-// -2 to -5 errors in glob
-
-int get_dev_names(char*** names, const char* prefix) {
-  int n = 0;
-  char** mp;
-  int retglob,lim;
-  glob_t globbuf;
-  int i;
-  char pattern1[128],pattern2[128];
-
-  bzero(&globbuf,sizeof(globbuf));
-  // in case of non-clean exit
-  *names=NULL;
-
-  // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV
-  sprintf(pattern1,"/dev/%s[0-9]",prefix);
-  sprintf(pattern2,"/dev/%s[0-9][0-9]",prefix);
-  
-  // Use glob to look for any directory entries matching the patterns
-  // first call inits with first pattern match, second call appends
-  // to first list. Turn on NOCHECK for second call. This results in no
-  // error if no more matches found, however it does append the actual
-  // pattern to the list of paths....
-  if ((retglob=glob(pattern1, GLOB_ERR, NULL, &globbuf)) ||
-      (retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {
-     int retval = -1;
-    // glob failed
-    if (retglob==GLOB_NOSPACE)
-      pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",
-           pattern1, pattern2);
-    else if (retglob==GLOB_ABORTED)
-      pout("glob(3) aborted matching patterns (%s),(%s)\n",
-           pattern1, pattern2);
-    else if (retglob==GLOB_NOMATCH) {
-      pout("glob(3) found no matches for patterns (%s),(%s)\n",
-           pattern1, pattern2);
-      retval = 0;
-    }
-    else if (retglob)
-      pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",
-           pattern1, pattern2);
-    
-    //  Free memory and return
-    globfree(&globbuf);
-
-    return retval;
-  }
-
-  // did we find too many paths?
-  // did we find too many paths?
-  lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;
-  if (lim < globbuf.gl_pathc)
-    pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n", 
-         globbuf.gl_pathc, MAX_NUM_DEV, pattern1,pattern2,
-         globbuf.gl_pathc-MAX_NUM_DEV);
-  
-  // allocate space for up to lim number of ATA devices
-  if (!(mp =  (char **)calloc(lim, sizeof(char*)))){
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-
-  // now step through the list returned by glob.  No link checking needed
-  // in FreeBSD
-  for (i=0; i<globbuf.gl_pathc; i++){
-    // becuase of the NO_CHECK on second call to glob,
-    // the pattern itself will be added to path list..
-    // so ignore any paths that have the ']' from pattern
-    if (strchr(globbuf.gl_pathv[i],']') == NULL)
-      mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
-  }
-
-  globfree(&globbuf);
-  mp = realloc(mp,n*(sizeof(char*))); // shrink to correct size
-  bytes += (n)*(sizeof(char*)); // and set allocated byte count
-  *names=mp;
-  return n;
-}
-
-int make_device_names (char*** devlist, const char* name) {
-  if (!strcmp(name,"SCSI"))
-    return get_dev_names(devlist,"da");
-  else if (!strcmp(name,"ATA"))
-    return get_dev_names(devlist,"ad");
-  else
-    return 0;
-}
diff --git a/sm5/os_freebsd.cpp b/sm5/os_freebsd.cpp
deleted file mode 100644
index 1bfc3a1babac2cb63bf91f20f8fc49ec75adda9e..0000000000000000000000000000000000000000
--- a/sm5/os_freebsd.cpp
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * os_freebsd.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <err.h>
-#include <camlib.h>
-#include <cam/scsi/scsi_message.h>
-#include <sys/ata.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <glob.h>
-#include <fcntl.h>
-
-
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-#include "os_freebsd.h"
-
-static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.40 2004/08/16 22:44:26 ballen4705 Exp $";
-
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.40 2004/08/16 22:44:26 ballen4705 Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Private table of open devices: guaranteed zero on startup since
-// part of static data.
-struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
-
-// forward declaration
-static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *ch);
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/ad0                       (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/ad0              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-//         "  smartctl -a --device=3ware,2 /dev/sda\n"
-//         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/ad0                       (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/ad0         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/ad0              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/ad0\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-//         "  smartctl -a -d 3ware,2 /dev/sda\n"
-//         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#endif
-  return;
-}
-
-// Like open().  Return positive integer handle, used by functions below only.  mode=="ATA" or "SCSI".
-int deviceopen (const char* dev, char* mode) {
-  struct freebsd_dev_channel *fdchan;
-  int parse_ok, i;
-
-  // Search table for a free entry
-  for (i=0; i<FREEBSD_MAXDEV; i++)
-    if (!devicetable[i])
-      break;
-  
-  // If no free entry found, return error.  We have max allowed number
-  // of "file descriptors" already allocated.
-  if (i==FREEBSD_MAXDEV) {
-    errno=EMFILE;
-    return -1;
-  }
-
-  fdchan = calloc(1,sizeof(struct freebsd_dev_channel));
-  if (fdchan == NULL) {
-    // errno already set by call to malloc()
-    return -1;
-  }
-
-  parse_ok = parse_ata_chan_dev (dev,fdchan);
-  if (parse_ok == CONTROLLER_UNKNOWN) {
-    free(fdchan);
-    errno = ENOTTY;
-    return -1; // can't handle what we don't know
-  }
-
-  if (parse_ok == CONTROLLER_ATA) {
-    if ((fdchan->atacommand = open("/dev/ata",O_RDWR))<0) {
-      int myerror = errno;      //preserve across free call
-      free (fdchan);
-      errno = myerror;
-      return -1;
-    }
-  }
-
-  if (parse_ok == CONTROLLER_3WARE_678K_CHAR) {
-    char buf[512];
-    sprintf(buf,"/dev/twe%d",fdchan->device);
-    printf("Using %s, as control device\n", buf);
-    if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
-      int myerror = errno; // preserver across free call
-      free(fdchan);
-      errno=myerror;
-      return -1;
-    }
-  }
-
-  if (parse_ok == CONTROLLER_SCSI) {
-    // this is really a NO-OP, as the parse takes care
-    // of filling in correct details
-  }
-  
-  // return pointer to "file descriptor" table entry, properly offset.
-  devicetable[i]=fdchan;
-  return i+FREEBSD_FDOFFSET;
-}
-
-// Returns 1 if device not available/open/found else 0.  Also shifts fd into valid range.
-static int isnotopen(int *fd, struct freebsd_dev_channel** fdchan) {
-  // put valid "file descriptor" into range 0...FREEBSD_MAXDEV-1
-  *fd -= FREEBSD_FDOFFSET;
-  
-  // check for validity of "file descriptor".
-  if (*fd<0 || *fd>=FREEBSD_MAXDEV || !((*fdchan)=devicetable[*fd])) {
-    errno = ENODEV;
-    return 1;
-  }
-  
-  return 0;
-}
-
-// Like close().  Acts on handles returned by above function.
-int deviceclose (int fd) {
-  struct freebsd_dev_channel *fdchan;
-  int failed = 0;
-
-  // check for valid file descriptor
-  if (isnotopen(&fd, &fdchan))
-    return -1;
-  
-
-  // did we allocate a SCSI device name?
-  if (fdchan->devname)
-    free(fdchan->devname);
-  
-  // close device, if open
-  if (fdchan->atacommand)
-    failed=close(fdchan->atacommand);
-
-  if (fdchan->scsicontrol)
-    failed=close(fdchan->scsicontrol);
-  
-  // if close succeeded, then remove from device list
-  // Eduard, should we also remove it from list if close() fails?  I'm
-  // not sure. Here I only remove it from list if close() worked.
-  if (!failed) {
-    free(fdchan);
-    devicetable[fd]=NULL;
-  }
-  
-  return failed;
-}
-
-#define NO_RETURN 0
-#define BAD_SMART 1
-#define NO_3WARE 2
-#define BAD_KERNEL 3
-#define MAX_MSG 3
-
-// Utility function for printing warnings
-void printwarning(int msgNo, const char* extra) {
-  static int printed[] = {0,0,0,0};
-  static const char* message[]={
-    "The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n can not be retrieved with this version of ATAng, please do not rely on this value\nYou should update to at least 5.2\n",
-    
-    "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
-    
-    PACKAGE_STRING " does not currentlly support TWE devices (3ware Escalade)\n",
-    
-    "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
-  };
-
-  if (msgNo >= 0 && msgNo <= MAX_MSG) {
-    if (!printed[msgNo]) {
-      printed[msgNo] = 1;
-      pout("%s", message[msgNo]);
-      if (extra)
-        pout("%s",extra);
-    }
-  }
-  return;
-}
-
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
-#ifndef ATAREQUEST
-  // sorry, but without ATAng, we can't do anything here
-  printwarning(BAD_KERNEL,NULL);
-  errno = ENOSYS;
-  return -1;
-#else
-  struct freebsd_dev_channel* con;
-  int retval, copydata=0;
-  struct ata_cmd iocmd;
-  unsigned char buff[512];
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -1;
-
-  bzero(buff,512);
-
-  bzero(&iocmd,sizeof(struct ata_cmd));
-  bzero(buff,512);
-  iocmd.cmd=ATAREQUEST;
-  iocmd.channel=con->channel;
-  iocmd.device=con->device;
-
-  iocmd.u.request.u.ata.command=ATA_SMART_CMD;
-  iocmd.u.request.timeout=600;
-  switch (command){
-  case READ_VALUES:
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_VALUES;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case READ_THRESHOLDS:
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_THRESHOLDS;
-    iocmd.u.request.u.ata.count=1;
-    iocmd.u.request.u.ata.lba=1|(0xc24f<<8);
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case READ_LOG:
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_LOG_SECTOR;
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
-    iocmd.u.request.u.ata.count=1;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case IDENTIFY:
-    iocmd.u.request.u.ata.command=ATA_IDENTIFY_DEVICE;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case PIDENTIFY:
-    iocmd.u.request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case ENABLE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_ENABLE;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case DISABLE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_DISABLE;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case AUTO_OFFLINE:
-    // NOTE: According to ATAPI 4 and UP, this command is obsolete
-    iocmd.u.request.u.ata.feature=ATA_SMART_AUTO_OFFLINE;
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case AUTOSAVE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_AUTOSAVE;
-    iocmd.u.request.u.ata.count=0xf1;  // to enable autosave
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case IMMEDIATE_OFFLINE:
-    iocmd.u.request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;
-    iocmd.u.request.u.ata.lba = select|(0xc24f<<8); // put test in sector
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case STATUS_CHECK: // same command, no HDIO in FreeBSD
-  case STATUS:
-    // this command only says if SMART is working.  It could be
-    // replaced with STATUS_CHECK below.
-    iocmd.u.request.u.ata.feature=ATA_SMART_STATUS;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  default:
-    pout("Unrecognized command %d in ata_command_interface()\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command);
-    errno=ENOSYS;
-    return -1;
-  }
-  
-  if (command==STATUS_CHECK){
-    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
-    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
-    unsigned char low,high;
-    
-    if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)))
-      return -1;
-
-#if __FreeBSD_version < 502000
-    printwarning(NO_RETURN,NULL);
-#endif
-
-    high = (iocmd.u.request.u.ata.lba >> 16) & 0xff;
-    low = (iocmd.u.request.u.ata.lba >> 8) & 0xff;
-    
-    // Cyl low and Cyl high unchanged means "Good SMART status"
-    if (low==normal_lo && high==normal_hi)
-      return 0;
-    
-    // These values mean "Bad SMART status"
-    if (low==failed_lo && high==failed_hi)
-      return 1;
-    
-    // We haven't gotten output that makes sense; print out some debugging info
-    char buf[512];
-    sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
-            (int)iocmd.u.request.u.ata.command,
-            (int)iocmd.u.request.u.ata.feature,
-            (int)iocmd.u.request.u.ata.count,
-            (int)((iocmd.u.request.u.ata.lba) & 0xff),
-            (int)((iocmd.u.request.u.ata.lba>>8) & 0xff),
-            (int)((iocmd.u.request.u.ata.lba>>16) & 0xff),
-            (int)iocmd.u.request.error);
-    printwarning(BAD_SMART,buf);
-    return 0;   
-  }
-
-  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) {
-    perror("Failed command: ");
-    return -1;
-  }
-  // 
-  if (copydata)
-    memcpy(data, buff, 512);
-  
-  return 0;
-#endif
-}
-
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-  struct freebsd_dev_channel* con = NULL;
-  struct cam_device* cam_dev = NULL;
-  union ccb *ccb;
-  
-  
-    if (report > 0) {
-        unsigned int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -ENOTTY;
-
-
-  if (!(cam_dev = cam_open_spec_device(con->devname,con->unitnum,O_RDWR,NULL))) {
-    warnx("%s",cam_errbuf);
-    return -1;
-  }
-
-  if (!(ccb = cam_getccb(cam_dev))) {
-    warnx("error allocating ccb");
-    return -ENOMEM;
-  }
-
-  // clear out structure, except for header that was filled in for us
-  bzero(&(&ccb->ccb_h)[1],
-        sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
-
-  cam_fill_csio(&ccb->csio,
-                /*retrires*/ 1,
-                /*cbfcnp*/ NULL,
-                /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
-                /* tagaction */ MSG_SIMPLE_Q_TAG,
-                /* dataptr */ iop->dxferp,
-                /* datalen */ iop->dxfer_len,
-                /* senselen */ iop->max_sense_len,
-                /* cdblen */ iop->cmnd_len,
-                /* timout (converted to seconds) */ iop->timeout*1000);
-  memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
-
-  if (cam_send_ccb(cam_dev,ccb) < 0) {
-    warn("error sending SCSI ccb");
- #if __FreeBSD_version > 500000
-    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
- #endif
-    cam_freeccb(ccb);
-    return -1;
-  }
-
-  if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- #if __FreeBSD_version > 500000
-    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
- #endif
-    cam_freeccb(ccb);
-    return -1;
-  }
-
-  if (iop->sensep) {
-    memcpy(iop->sensep,&(ccb->csio.sense_data),sizeof(struct scsi_sense_data));
-    iop->resp_sense_len = sizeof(struct scsi_sense_data);
-  }
-
-  iop->scsi_status = ccb->csio.scsi_status;
-
-  cam_freeccb(ccb);
-  
-  if (cam_dev)
-    cam_close_device(cam_dev);
-
-  if (report > 0) {
-    int trunc;
-
-    pout("  status=0\n");
-    trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-         (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-  return 0;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) {
-
-  // to hold true file descriptor
-  struct freebsd_dev_channel* con;
-
-  // return value and buffer for ioctl()
-  int  ioctlreturn, readdata=0;
-
-  // Used by both the SCSI and char interfaces
-  char ioctl_buffer[sizeof(struct twe_usercommand)];
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -1;
-
-  memset(ioctl_buffer, 0, sizeof(struct twe_usercommand));
-
-  struct twe_usercommand* cmd = (struct twe_usercommand*)ioctl_buffer;
-  cmd->tu_command.ata.opcode = TWE_OP_ATA_PASSTHROUGH;
-
-  // Same for (almost) all commands - but some reset below
-  cmd->tu_command.ata.request_id    = 0xFF;
-  cmd->tu_command.ata.unit   = disknum;
-  cmd->tu_command.ata.host_id = 0;
-  cmd->tu_command.ata.status        = 0;           
-  cmd->tu_command.ata.flags         = 0x1;
-  cmd->tu_command.ata.drive_head    = 0x0;
-  cmd->tu_command.ata.sector_num    = 0;
-
-  // All SMART commands use this CL/CH signature.  These are magic
-  // values from the ATA specifications.
-  cmd->tu_command.ata.cylinder_lo   = 0x4F;
-  cmd->tu_command.ata.cylinder_hi   = 0xC2;
-  
-  // SMART ATA COMMAND REGISTER value
-  cmd->tu_command.ata.command       = ATA_SMART_CMD;
-  
-  // Is this a command that reads or returns 512 bytes?
-  // passthru->param values are:
-  // 0x0 - non data command without TFR write check,
-  // 0x8 - non data command with TFR write check,
-  // 0xD - data command that returns data to host from device
-  // 0xF - data command that writes data from host to device
-  // passthru->size values are 0x5 for non-data and 0x07 for data
-  if (command == READ_VALUES     ||
-      command == READ_THRESHOLDS ||
-      command == READ_LOG        ||
-      command == IDENTIFY        ||
-      command == WRITE_LOG ) {
-    readdata=1;
-    cmd->tu_size = 512;
-    cmd->tu_data = data;
-    cmd->tu_command.ata.sgl_offset = 0x5;
-    cmd->tu_command.ata.size         = 0x5;
-    cmd->tu_command.ata.param        = 0xD;
-    cmd->tu_command.ata.sector_count = 0x1;
-    // For 64-bit to work correctly, up the size of the command packet
-    // in dwords by 1 to account for the 64-bit single sgl 'address'
-    // field. Note that this doesn't agree with the typedefs but it's
-    // right (agree with kernel driver behavior/typedefs).
-    //if (sizeof(long)==8)
-    //  cmd->tu_command.ata.size++;
-  }
-  else {
-    // Non data command -- but doesn't use large sector 
-    // count register values.  
-    cmd->tu_command.ata.sgl_offset = 0x0;
-    cmd->tu_command.ata.size         = 0x5;
-    cmd->tu_command.ata.param        = 0x8;
-    cmd->tu_command.ata.sector_count = 0x0;
-  }
-  
-  // Now set ATA registers depending upon command
-  switch (command){
-  case CHECK_POWER_MODE:
-    cmd->tu_command.ata.command     = ATA_CHECK_POWER_MODE;
-    cmd->tu_command.ata.features    = 0;
-    cmd->tu_command.ata.cylinder_lo = 0;
-    cmd->tu_command.ata.cylinder_hi = 0;
-    break;
-  case READ_VALUES:
-    cmd->tu_command.ata.features = ATA_SMART_READ_VALUES;
-    break;
-  case READ_THRESHOLDS:
-    cmd->tu_command.ata.features = ATA_SMART_READ_THRESHOLDS;
-    break;
-  case READ_LOG:
-    cmd->tu_command.ata.features = ATA_SMART_READ_LOG_SECTOR;
-    // log number to return
-    cmd->tu_command.ata.sector_num  = select;
-    break;
-  case WRITE_LOG:
-    cmd->tu_data = data;
-    readdata=0;
-    cmd->tu_command.ata.features     = ATA_SMART_WRITE_LOG_SECTOR;
-    cmd->tu_command.ata.sector_count = 1;
-    cmd->tu_command.ata.sector_num   = select;
-    cmd->tu_command.ata.param        = 0xF;  // PIO data write
-    break;
-  case IDENTIFY:
-    // ATA IDENTIFY DEVICE
-    cmd->tu_command.ata.command     = ATA_IDENTIFY_DEVICE;
-    cmd->tu_command.ata.features    = 0;
-    cmd->tu_command.ata.cylinder_lo = 0;
-    cmd->tu_command.ata.cylinder_hi = 0;
-    break;
-  case PIDENTIFY:
-    // 3WARE controller can NOT have packet device internally
-    pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
-    errno=ENODEV;
-    return -1;
-  case ENABLE:
-    cmd->tu_command.ata.features = ATA_SMART_ENABLE;
-    break;
-  case DISABLE:
-    cmd->tu_command.ata.features = ATA_SMART_DISABLE;
-    break;
-  case AUTO_OFFLINE:
-    cmd->tu_command.ata.features     = ATA_SMART_AUTO_OFFLINE;
-    // Enable or disable?
-    cmd->tu_command.ata.sector_count = select;
-    break;
-  case AUTOSAVE:
-    cmd->tu_command.ata.features     = ATA_SMART_AUTOSAVE;
-    // Enable or disable?
-    cmd->tu_command.ata.sector_count = select;
-    break;
-  case IMMEDIATE_OFFLINE:
-    cmd->tu_command.ata.features    = ATA_SMART_IMMEDIATE_OFFLINE;
-    // What test type to run?
-    cmd->tu_command.ata.sector_num  = select;
-    break;
-  case STATUS_CHECK:
-    cmd->tu_command.ata.features = ATA_SMART_STATUS;
-    break;
-  case STATUS:
-    // This is JUST to see if SMART is enabled, by giving SMART status
-    // command. But it doesn't say if status was good, or failing.
-    // See below for the difference.
-    cmd->tu_command.ata.features = ATA_SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  // Now send the command down through an ioctl()
-  ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd);
-  
-  // Deal with the different error cases
-  if (ioctlreturn) {
-    if (!errno)
-      errno=EIO;
-    return -1;
-  }
-  
-  // See if the ATA command failed.  Now that we have returned from
-  // the ioctl() call, if passthru is valid, then:
-  // - cmd->tu_command.ata.status contains the 3ware controller STATUS
-  // - cmd->tu_command.ata.command contains the ATA STATUS register
-  // - cmd->tu_command.ata.features contains the ATA ERROR register
-  //
-  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
-  // If bit 0 (error bit) is set, then ATA ERROR register is valid.
-  // While we *might* decode the ATA ERROR register, at the moment it
-  // doesn't make much sense: we don't care in detail why the error
-  // happened.
-  
-  if (cmd->tu_command.ata.status || (cmd->tu_command.ata.command & 0x21)) {
-    pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",cmd->tu_command.ata.status,cmd->tu_command.ata.command,cmd->tu_command.ata.flags);
-    errno=EIO;
-    return -1;
-  }
-  
-  // For STATUS_CHECK, we need to check register values
-  if (command==STATUS_CHECK) {
-    
-    // To find out if the SMART RETURN STATUS is good or failing, we
-    // need to examine the values of the Cylinder Low and Cylinder
-    // High Registers.
-    
-    unsigned short cyl_lo=cmd->tu_command.ata.cylinder_lo;
-    unsigned short cyl_hi=cmd->tu_command.ata.cylinder_hi;
-    
-    // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
-    if (cyl_lo==0x4F && cyl_hi==0xC2)
-      return 0;
-    
-    // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
-    if (cyl_lo==0xF4 && cyl_hi==0x2C)
-      return 1;
-    
-      errno=EIO;
-      return -1;
-  }
-  
-  // copy sector count register (one byte!) to return data
-  if (command==CHECK_POWER_MODE)
-    *data=*(char *)&(cmd->tu_command.ata.sector_count);
-  
-  // look for nonexistent devices/ports
-  if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
-    errno=ENODEV;
-    return -1;
-  }
-  
-  return 0;
-}
-
-static int get_twe_channel_unit (const char* name, int* unit, int* dev) {
-  // at some  point, we need to figure out which TWE controller any
-  // given disk belongs to.....
-  // at this point, I have no clue how to do this...so for now, it is
-  // always going to be controller 0
-  *dev=0;
-  *unit=0; // not really needed for TWE drives, as we handle that seperately
-  return 0;
-}
-
-static int get_ata_channel_unit ( const char* name, int* unit, int* dev) {
-#ifndef ATAREQUEST
-  *dev=0;
-  *unit=0;
-return 0;
-#else
-  // there is no direct correlation between name 'ad0, ad1, ...' and
-  // channel/unit number.  So we need to iterate through the possible
-  // channels and check each unit to see if we match names
-  struct ata_cmd iocmd;
-  int fd,maxunit;
-  
-  bzero(&iocmd, sizeof(struct ata_cmd));
-
-  if ((fd = open("/dev/ata", O_RDWR)) < 0)
-    return -errno;
-  
-  iocmd.cmd = ATAGMAXCHANNEL;
-  if (ioctl(fd, IOCATA, &iocmd) < 0) {
-    return -errno;
-    close(fd);
-  }
-  maxunit = iocmd.u.maxchan;
-  for (*unit = 0; *unit < maxunit; (*unit)++) {
-    iocmd.channel = *unit;
-    iocmd.device = -1;
-    iocmd.cmd = ATAGPARM;
-    if (ioctl(fd, IOCATA, &iocmd) < 0) {
-      close(fd);
-      return -errno;
-    }
-    if (iocmd.u.param.type[0] && !strcmp(name,iocmd.u.param.name[0])) {
-      *dev = 0;
-      break;
-    }
-    if (iocmd.u.param.type[1] && !strcmp(name,iocmd.u.param.name[1])) {
-      *dev = 1;
-      break;
-    }
-  }
-  close(fd);
-  if (*unit == maxunit)
-    return -1;
-  else
-    return 0;
-#endif
-}
-
-
-// Guess device type (ata or scsi) based on device name (FreeBSD
-// specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
-// osst, nosst and sg.
-static const char * fbsd_dev_prefix = "/dev/";
-static const char * fbsd_dev_ata_disk_prefix = "ad";
-static const char * fbsd_dev_scsi_disk_plus = "da";
-static const char * fbsd_dev_scsi_tape1 = "sa";
-static const char * fbsd_dev_scsi_tape2 = "nsa";
-static const char * fbsd_dev_scsi_tape3 = "esa";
-static const char * fbsd_dev_twe_disk = "twed";
-
-static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
-  int len;
-  int dev_prefix_len = strlen(fbsd_dev_prefix);
-  
-  // if dev_name null, or string length zero
-  if (!dev_name || !(len = strlen(dev_name)))
-    return CONTROLLER_UNKNOWN;;
-  
-  // Remove the leading /dev/... if it's there
-  if (!strncmp(fbsd_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len) 
-      // if nothing else in the string, unrecognized
-      return CONTROLLER_UNKNOWN;
-    // else advance pointer to following characters
-    dev_name += dev_prefix_len;
-  }
-  // form /dev/ad* or ad*
-  if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
-               strlen(fbsd_dev_ata_disk_prefix))) {
-    if (chan != NULL) {
-      if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
-        return CONTROLLER_UNKNOWN;
-      }
-    }
-    return CONTROLLER_ATA;
-  }
-  
-  // form /dev/da* or da*
-  if (!strncmp(fbsd_dev_scsi_disk_plus, dev_name,
-               strlen(fbsd_dev_scsi_disk_plus)))
-    goto handlescsi;
-
-  // form /dev/sa* or sa*
-  if (!strncmp(fbsd_dev_scsi_tape1, dev_name,
-              strlen(fbsd_dev_scsi_tape1)))
-    goto handlescsi;
-
-  // form /dev/nsa* or nsa*
-  if (!strncmp(fbsd_dev_scsi_tape2, dev_name,
-              strlen(fbsd_dev_scsi_tape2)))
-    goto handlescsi;
-
-  // form /dev/esa* or esa*
-  if (!strncmp(fbsd_dev_scsi_tape3, dev_name,
-              strlen(fbsd_dev_scsi_tape3)))
-    goto handlescsi;
-  
-  if (!strncmp(fbsd_dev_twe_disk,dev_name,
-	       strlen(fbsd_dev_twe_disk))) {
-    if (chan != NULL) {
-      if (get_twe_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
-	return CONTROLLER_UNKNOWN;
-      }
-    }
-    return CONTROLLER_3WARE_678K_CHAR;
-  }
-
-  // we failed to recognize any of the forms
-  return CONTROLLER_UNKNOWN;
-
- handlescsi:
-  if (chan != NULL) {
-    if (!(chan->devname = calloc(1,DEV_IDLEN+1)))
-      return CONTROLLER_UNKNOWN;
-    
-    if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)
-      return CONTROLLER_UNKNOWN;
-  }
-  return CONTROLLER_SCSI;
-  
-}
-
-int guess_device_type (const char* dev_name) {
-  return parse_ata_chan_dev(dev_name,NULL);
-}
-
-// global variable holding byte count of allocated memory
-extern long long bytes;
-
-// we are going to take advantage of the fact that FreeBSD's devfs will only
-// have device entries for devices that exist.  So if we get the equivilent of
-// ls /dev/ad?, we have all the ATA devices on the system
-//
-// If any errors occur, leave errno set as it was returned by the
-// system call, and return <0.
-
-// Return values:
-// -1 out of memory
-// -2 to -5 errors in glob
-
-int get_dev_names(char*** names, const char* prefix) {
-  int n = 0;
-  char** mp;
-  int retglob,lim;
-  glob_t globbuf;
-  int i;
-  char pattern1[128],pattern2[128];
-
-  bzero(&globbuf,sizeof(globbuf));
-  // in case of non-clean exit
-  *names=NULL;
-
-  // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV
-  sprintf(pattern1,"/dev/%s[0-9]",prefix);
-  sprintf(pattern2,"/dev/%s[0-9][0-9]",prefix);
-  
-  // Use glob to look for any directory entries matching the patterns
-  // first call inits with first pattern match, second call appends
-  // to first list. Turn on NOCHECK for second call. This results in no
-  // error if no more matches found, however it does append the actual
-  // pattern to the list of paths....
-  if ((retglob=glob(pattern1, GLOB_ERR, NULL, &globbuf)) ||
-      (retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {
-     int retval = -1;
-    // glob failed
-    if (retglob==GLOB_NOSPACE)
-      pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",
-           pattern1, pattern2);
-    else if (retglob==GLOB_ABORTED)
-      pout("glob(3) aborted matching patterns (%s),(%s)\n",
-           pattern1, pattern2);
-    else if (retglob==GLOB_NOMATCH) {
-      pout("glob(3) found no matches for patterns (%s),(%s)\n",
-           pattern1, pattern2);
-      retval = 0;
-    }
-    else if (retglob)
-      pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",
-           pattern1, pattern2);
-    
-    //  Free memory and return
-    globfree(&globbuf);
-
-    return retval;
-  }
-
-  // did we find too many paths?
-  // did we find too many paths?
-  lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;
-  if (lim < globbuf.gl_pathc)
-    pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n", 
-         globbuf.gl_pathc, MAX_NUM_DEV, pattern1,pattern2,
-         globbuf.gl_pathc-MAX_NUM_DEV);
-  
-  // allocate space for up to lim number of ATA devices
-  if (!(mp =  (char **)calloc(lim, sizeof(char*)))){
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-
-  // now step through the list returned by glob.  No link checking needed
-  // in FreeBSD
-  for (i=0; i<globbuf.gl_pathc; i++){
-    // becuase of the NO_CHECK on second call to glob,
-    // the pattern itself will be added to path list..
-    // so ignore any paths that have the ']' from pattern
-    if (strchr(globbuf.gl_pathv[i],']') == NULL)
-      mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
-  }
-
-  globfree(&globbuf);
-  mp = realloc(mp,n*(sizeof(char*))); // shrink to correct size
-  bytes += (n)*(sizeof(char*)); // and set allocated byte count
-  *names=mp;
-  return n;
-}
-
-int make_device_names (char*** devlist, const char* name) {
-  if (!strcmp(name,"SCSI"))
-    return get_dev_names(devlist,"da");
-  else if (!strcmp(name,"ATA"))
-    return get_dev_names(devlist,"ad");
-  else
-    return 0;
-}
diff --git a/sm5/os_freebsd.h b/sm5/os_freebsd.h
deleted file mode 100644
index 87d3039302e6c0b2b19be3d2cac4892f12ff811d..0000000000000000000000000000000000000000
--- a/sm5/os_freebsd.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * os_freebsd.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef OS_FREEBSD_H_
-#define OS_FREEBSD_H_
-
-#define OS_XXXX_H_CVSID "$Id: os_freebsd.h,v 1.12 2004/08/16 22:44:26 ballen4705 Exp $\n"
-
-struct freebsd_dev_channel {
-  int   channel;                // the ATA channel to work with
-  int   device;                 // the device on the channel
-  int   atacommand;             // the ATA Command file descriptor (/dev/ata)
-  char* devname;                // the SCSI device name
-  int   unitnum;                // the SCSI unit number
-  int   scsicontrol;            // the SCSI control interface
-};
-
-#define FREEBSD_MAXDEV 64
-#define FREEBSD_FDOFFSET 16;
-#define MAX_NUM_DEV 26
-
-#ifdef  HAVE_SYS_TWEREG_H
-#include <twereg.h>
-#else
-#include "twereg.h"
-#endif
-
-#ifdef  HAVE_SYS_TWEIO_H
-#include <tweio.h>
-#else
-#include "tweio.h"
-#endif
-
-/* 
-   The following definitions/macros/prototypes are used for three
-   different interfaces, referred to as "the three cases" below.
-   CONTROLLER_3WARE_678K      -- 6000, 7000, and 8000 controllers via /dev/sd?
-   CONTROLLER_3WARE_678K_CHAR -- 6000, 7000, and 8000 controllers via /dev/twe?
-   CONTROLLER_3WARE_9000_CHAR -- 9000 controllers via /dev/twa?
-*/
-
-
-#endif /* OS_FREEBSD_H_ */
diff --git a/sm5/os_generic.c b/sm5/os_generic.c
deleted file mode 100644
index 0101f3bdfb6e1af445bba9232b2d29a1abef0d2c..0000000000000000000000000000000000000000
--- a/sm5/os_generic.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * os_generic.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*  PORTING NOTES AND COMMENTS
-
-    To port smartmontools to the OS of your choice, please:
-
- [0] Contact smartmontools-support@lists.sourceforge.net to check
-     that it's not already been done.
-
- [1] Make copies of os_generic.[hc] called os_myOS.[hc].
-
- [2] Modify configure.in so that case "${host}" includes myOS.
-
- [3] Verify that ./autogen.sh && ./configure && make compiles the
-     code.  If not, fix any compilation problems.  If your OS lacks
-     some function that is used elsewhere in the code, then add a
-     AC_CHECK_FUNCS([missingfunction]) line to configure.in, and
-     surround uses of the function with:
-     #ifdef HAVE_MISSINGFUNCTION
-     ... 
-     #endif
-     where the macro HAVE_MISSINGFUNCTION is (or is not) defined in
-     config.h.
-
- [4] Provide the functions defined in this file by fleshing out the
-     skeletons below.  You can entirely eliminate the function
-     'unsupported()'.
-
- [5] Contact smartmontools-support@lists.sourceforge.net to see
-     about checking your code into the smartmontools CVS archive.
-*/
-
-// These are needed to define prototypes for the functions defined below
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-// This is to include whatever prototypes you define in os_generic.h
-#include "os_generic.h"
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_generic.c,v 1.15 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-
-// Please eliminate the following block: both the two #includes and
-// the 'unsupported()' function.  They are only here to warn
-// unsuspecting users that their Operating System is not supported! If
-// you wish, you can use a similar warning mechanism for any of the
-// functions in this file that you can not (or choose not to)
-// implement.
-
-#include "config.h"
-#ifdef HAVE_UNAME
-#include <sys/utsname.h>
-#endif
-
-static void unsupported(){
-  static int warninggiven;
-
-  if (!warninggiven) {
-    char *osname;
-    extern unsigned char debugmode;
-    unsigned char savedebugmode=debugmode;
-    
-#ifdef HAVE_UNAME
-    struct utsname ostype;
-    uname(&ostype);
-    osname=ostype.sysname;
-#else
-    osname="host's";
-#endif
-
-    debugmode=1;
-    pout("\n"
-         "############################################################################\n"
-         "WARNING: smartmontools has not been ported to the %s Operating System.\n"
-         "Please see the files os_generic.c and os_generic.h for porting instructions.\n"
-         "############################################################################\n\n",
-         osname);
-    debugmode=savedebugmode;
-    warninggiven=1;
-  }
-  
-  return;
-}
-// End of the 'unsupported()' block that you should eliminate.
-
-
-// print examples for smartctl.  You should modify this function so
-// that the device paths are sensible for your OS, and to eliminate
-// unsupported commands (eg, 3ware controllers).
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a --device=3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a -d 3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#endif
-  return;
-}
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char* dev_name) {
-  unsupported();
-  return CONTROLLER_UNKNOWN;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist); the
-// other N arrays each contain null-terminated character strings.  In
-// the case N==0, no arrays are allocated because the array of 0
-// pointers has zero length, equivalent to calling malloc(0).
-int make_device_names (char*** devlist, const char* name) {
-  unsupported();
-  return 0;
-}
-
-// Like open().  Return non-negative integer handle, only used by the
-// functions below.  type=="ATA" or "SCSI".  If you need to store
-// extra information about your devices, create a private internal
-// array within this file (see os_freebsd.c for an example).  If you
-// can not open the device (permission denied, does not exist, etc)
-// set errno as open() does and return <0.
-int deviceopen(const char *pathname, char *type){
-  unsupported();
-  return -1;
-}
-
-// Like close().  Acts only on integer handles returned by
-// deviceopen() above.
-int deviceclose(int fd){
-  unsupported();
-  return 0;
-}
-
-// Interface to ATA devices.  See os_linux.c for the cannonical example.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   device: is the integer handle provided by deviceopen()
-//   command: defines the different operations, see atacmds.h
-//   select: additional input data IF NEEDED (which log, which type of
-//           self-test).
-//   data:   location to write output data, IF NEEDED (1 or 512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
-//  -1 if the command failed
-//   0 if the command succeeded,
-// RETURN VALUES if command==STATUS_CHECK
-//  -1 if the command failed OR the disk SMART status can't be determined
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-int ata_command_interface(int fd, smart_command_set command, int select, char *data){
-  unsupported();
-  return -1;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller
-// cards.  Same description as ata_command_interface() above except
-// that 0 <= disknum <= 15 specifies the ATA disk attached to the
-// controller.
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-  unsupported();
-  return -1;
-}
-
-#include <errno.h>
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  unsupported();
-  return -ENOSYS;
-}
diff --git a/sm5/os_generic.cpp b/sm5/os_generic.cpp
deleted file mode 100644
index 56d5858f7901a24383889cf36d9db438c0b528ad..0000000000000000000000000000000000000000
--- a/sm5/os_generic.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * os_generic.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*  PORTING NOTES AND COMMENTS
-
-    To port smartmontools to the OS of your choice, please:
-
- [0] Contact smartmontools-support@lists.sourceforge.net to check
-     that it's not already been done.
-
- [1] Make copies of os_generic.[hc] called os_myOS.[hc].
-
- [2] Modify configure.in so that case "${host}" includes myOS.
-
- [3] Verify that ./autogen.sh && ./configure && make compiles the
-     code.  If not, fix any compilation problems.  If your OS lacks
-     some function that is used elsewhere in the code, then add a
-     AC_CHECK_FUNCS([missingfunction]) line to configure.in, and
-     surround uses of the function with:
-     #ifdef HAVE_MISSINGFUNCTION
-     ... 
-     #endif
-     where the macro HAVE_MISSINGFUNCTION is (or is not) defined in
-     config.h.
-
- [4] Provide the functions defined in this file by fleshing out the
-     skeletons below.  You can entirely eliminate the function
-     'unsupported()'.
-
- [5] Contact smartmontools-support@lists.sourceforge.net to see
-     about checking your code into the smartmontools CVS archive.
-*/
-
-// These are needed to define prototypes for the functions defined below
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-// This is to include whatever prototypes you define in os_generic.h
-#include "os_generic.h"
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_generic.cpp,v 1.15 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-
-// Please eliminate the following block: both the two #includes and
-// the 'unsupported()' function.  They are only here to warn
-// unsuspecting users that their Operating System is not supported! If
-// you wish, you can use a similar warning mechanism for any of the
-// functions in this file that you can not (or choose not to)
-// implement.
-
-#include "config.h"
-#ifdef HAVE_UNAME
-#include <sys/utsname.h>
-#endif
-
-static void unsupported(){
-  static int warninggiven;
-
-  if (!warninggiven) {
-    char *osname;
-    extern unsigned char debugmode;
-    unsigned char savedebugmode=debugmode;
-    
-#ifdef HAVE_UNAME
-    struct utsname ostype;
-    uname(&ostype);
-    osname=ostype.sysname;
-#else
-    osname="host's";
-#endif
-
-    debugmode=1;
-    pout("\n"
-         "############################################################################\n"
-         "WARNING: smartmontools has not been ported to the %s Operating System.\n"
-         "Please see the files os_generic.c and os_generic.h for porting instructions.\n"
-         "############################################################################\n\n",
-         osname);
-    debugmode=savedebugmode;
-    warninggiven=1;
-  }
-  
-  return;
-}
-// End of the 'unsupported()' block that you should eliminate.
-
-
-// print examples for smartctl.  You should modify this function so
-// that the device paths are sensible for your OS, and to eliminate
-// unsupported commands (eg, 3ware controllers).
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a --device=3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a -d 3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#endif
-  return;
-}
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char* dev_name) {
-  unsupported();
-  return CONTROLLER_UNKNOWN;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist); the
-// other N arrays each contain null-terminated character strings.  In
-// the case N==0, no arrays are allocated because the array of 0
-// pointers has zero length, equivalent to calling malloc(0).
-int make_device_names (char*** devlist, const char* name) {
-  unsupported();
-  return 0;
-}
-
-// Like open().  Return non-negative integer handle, only used by the
-// functions below.  type=="ATA" or "SCSI".  If you need to store
-// extra information about your devices, create a private internal
-// array within this file (see os_freebsd.c for an example).  If you
-// can not open the device (permission denied, does not exist, etc)
-// set errno as open() does and return <0.
-int deviceopen(const char *pathname, char *type){
-  unsupported();
-  return -1;
-}
-
-// Like close().  Acts only on integer handles returned by
-// deviceopen() above.
-int deviceclose(int fd){
-  unsupported();
-  return 0;
-}
-
-// Interface to ATA devices.  See os_linux.c for the cannonical example.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   device: is the integer handle provided by deviceopen()
-//   command: defines the different operations, see atacmds.h
-//   select: additional input data IF NEEDED (which log, which type of
-//           self-test).
-//   data:   location to write output data, IF NEEDED (1 or 512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
-//  -1 if the command failed
-//   0 if the command succeeded,
-// RETURN VALUES if command==STATUS_CHECK
-//  -1 if the command failed OR the disk SMART status can't be determined
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-int ata_command_interface(int fd, smart_command_set command, int select, char *data){
-  unsupported();
-  return -1;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller
-// cards.  Same description as ata_command_interface() above except
-// that 0 <= disknum <= 15 specifies the ATA disk attached to the
-// controller.
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-  unsupported();
-  return -1;
-}
-
-#include <errno.h>
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  unsupported();
-  return -ENOSYS;
-}
diff --git a/sm5/os_generic.h b/sm5/os_generic.h
deleted file mode 100644
index ed5415c3c513102a6c57a26f3ee1a90ed7e92b89..0000000000000000000000000000000000000000
--- a/sm5/os_generic.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * os_generic.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef OS_GENERIC_H_
-#define OS_GENERIC_H_
-
-#define OS_XXXX_H_CVSID "$Id: os_generic.h,v 1.3 2004/01/02 16:05:25 ballen4705 Exp $\n"
-
-// Additional material should start here.  Note: to keep the '-V' CVS
-// reporting option working as intended, you should only #include
-// system include files <something.h>.  Local #include files
-// <"something.h"> should be #included in os_generic.c
-
-#endif /* OS_GENERIC_H_ */
diff --git a/sm5/os_linux.c b/sm5/os_linux.c
deleted file mode 100644
index 28dbfd0ff875cb9cea27d020d77ef41c489dbaab..0000000000000000000000000000000000000000
--- a/sm5/os_linux.c
+++ /dev/null
@@ -1,1387 +0,0 @@
-/* 
- *  os_linux.c
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003-4 Doug Gilbert <dougg@torque.net>
- *
- *  Parts of this file are derived from code that was
- *
- *  Written By: Adam Radford <linux@3ware.com>
- *  Modifications By: Joel Jacobson <linux@3ware.com>
- *                   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *                    Brad Strand <linux@3ware.com>
- *
- *  Copyright (C) 1999-2003 3ware Inc.
- *
- *  Kernel compatablity By:     Andre Hedrick <andre@suse.com>
- *  Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
- *
- * Other ars of this file are derived from code that was
- * 
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- * 
- */
-
-// This file contains the linux-specific IOCTL parts of
-// smartmontools. It includes one interface routine for ATA devices,
-// one for SCSI devices, and one for ATA devices behind escalade
-// controllers.
-
-#include <errno.h>
-#include <fcntl.h>
-#include <glob.h>
-#include <scsi/scsi_ioctl.h>
-#include <scsi/sg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#ifndef makedev // old versions of types.h do not include sysmacros.h
-#include <sys/sysmacros.h>
-#endif
-
-#include "atacmds.h"
-#include "os_linux.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-#ifndef ENOTSUP
-#define ENOTSUP ENOSYS
-#endif
-typedef unsigned long long u8;
-
-#define ARGUSED(x) ((void)(x))
-
-static const char *filenameandversion="$Id: os_linux.c,v 1.70 2004/08/16 22:44:26 ballen4705 Exp $";
-
-const char *os_XXXX_c_cvsid="$Id: os_linux.c,v 1.70 2004/08/16 22:44:26 ballen4705 Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// global variable holding byte count of allocated memory
-extern long long bytes;
-
-
-
-/* This function will setup and fix device nodes for a 3ware controller. */
-#define MAJOR_STRING_LENGTH 3
-#define DEVICE_STRING_LENGTH 32
-#define NODE_STRING_LENGTH 16
-int setup_3ware_nodes(char *nodename, char *driver_name) {
-  int              tw_major      = 0;
-  int              index         = 0;
-  char             majorstring[MAJOR_STRING_LENGTH+1];
-  char             device_name[DEVICE_STRING_LENGTH+1];
-  char             nodestring[NODE_STRING_LENGTH];
-  struct stat      stat_buf;
-  FILE             *file;
-  
-  /* First try to open up /proc/devices */
-  if (!(file = fopen("/proc/devices", "r"))) {
-    pout("Error opening /proc/devices to check/create 3ware device nodes\n");
-    syserror("fopen");
-    return 0;  // don't fail here: user might not have /proc !
-  }
-  
-  /* Attempt to get device major number */
-  while (EOF != fscanf(file, "%3s %32s", majorstring, device_name)) {
-    majorstring[MAJOR_STRING_LENGTH]='\0';
-    device_name[DEVICE_STRING_LENGTH]='\0';
-    if (!strncmp(device_name, nodename, DEVICE_STRING_LENGTH)) {
-      tw_major = atoi(majorstring);
-      break;
-    }
-  }
-  fclose(file);
-  
-  /* See if we found a major device number */
-  if (!tw_major) {
-    pout("No major number for /dev/%s listed in /proc/devices. Is the %s driver loaded?\n", nodename, driver_name);
-    return 2;
-  }
-  
-  /* Now check if nodes are correct */
-  for (index=0; index<16; index++) {
-    sprintf(nodestring, "/dev/%s%d", nodename, index);
-	  
-    /* Try to stat the node */
-    if ((stat(nodestring, &stat_buf))) {
-      /* Create a new node if it doesn't exist */
-      if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
-	pout("problem creating 3ware device nodes %s", nodestring);
-	syserror("mknod");
-	return 3;
-      }
-    }
-    
-    /* See if nodes major and minor numbers are correct */
-    if ((tw_major != (int)(major(stat_buf.st_rdev))) ||
-	(index    != (int)(minor(stat_buf.st_rdev))) ||
-	(!S_ISCHR(stat_buf.st_mode))) {
-      
-      /* Delete the old node */
-      if (unlink(nodestring)) {
-	pout("problem unlinking stale 3ware device node %s", nodestring);
-	syserror("unlink");
-	return 4;
-      }
-      
-      /* Make a new node */
-      if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
-	pout("problem creating 3ware device nodes %s", nodestring);
-	syserror("mknod");
-	return 5;
-      }
-    }
-  }
-  return 0;
-}
-
-// equivalent to open(path, flags)
-int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) {
-    int fd = open(pathname, O_RDWR | O_NONBLOCK);
-    if (fd < 0 && errno == EROFS)
-      fd = open(pathname, O_RDONLY | O_NONBLOCK);
-    return fd;
-  }
-  else if (!strcmp(type,"ATA")) 
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  else if (!strcmp(type,"ATA_3WARE_9000")) {
-    // the device nodes for this controller are dynamically assigned,
-    // so we need to check that they exist with the correct major
-    // numbers and if not, create them
-    if (setup_3ware_nodes("twa", "3w-9xxx")) {
-      if (!errno)
-	errno=ENXIO;
-      return -1;
-    }
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  }
-  else if (!strcmp(type,"ATA_3WARE_678K")) {
-    // the device nodes for this controller are dynamically assigned,
-    // so we need to check that they exist with the correct major
-    // numbers and if not, create them
-    if (setup_3ware_nodes("twe", "3w-xxxx")) {
-      if (!errno)
-	errno=ENXIO;
-      return -1;
-    }
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  }
-  else
-    return -1;
-}
-
-// equivalent to close(file descriptor)
-int deviceclose(int fd){
-  return close(fd);
-}
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a --device=3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a -d 3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#endif
-  return;
-}
-
-
-// we are going to take advantage of the fact that Linux's devfs will only
-// have device entries for devices that exist.  So if we get the equivalent of
-// ls /dev/hd[a-t], we have all the ATA devices on the system
-//
-// If any errors occur, leave errno set as it was returned by the
-// system call, and return <0.
-int get_dev_names(char*** names, const char* pattern, const char* name, int max) {
-  int n = 0, retglob, i, lim;
-  char** mp;
-  glob_t globbuf;
-  
-  memset(&globbuf, 0, sizeof(globbuf));
-
-  // in case of non-clean exit
-  *names=NULL;
-  
-  // Use glob to look for any directory entries matching the pattern
-  if ((retglob=glob(pattern, GLOB_ERR, NULL, &globbuf))) {
-    
-    //  glob failed: free memory and return
-    globfree(&globbuf);
-    
-    if (retglob==GLOB_NOMATCH){
-      pout("glob(3) found no matches for pattern %s\n", pattern);
-      return 0;
-    }
-    
-    if (retglob==GLOB_NOSPACE)
-      pout("glob(3) ran out of memory matching pattern %s\n", pattern);
-#ifdef GLOB_ABORTED // missing in old versions of glob.h
-    else if (retglob==GLOB_ABORTED)
-      pout("glob(3) aborted matching pattern %s\n", pattern);
-#endif
-    else
-      pout("Unexplained error in glob(3) of pattern %s\n", pattern);
-    
-    return -1;
-  }
-
-  // did we find too many paths?
-  lim = ((int)globbuf.gl_pathc < max) ? (int)globbuf.gl_pathc : max;
-  if (lim < (int)globbuf.gl_pathc)
-    pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n", 
-         (int)globbuf.gl_pathc, max, pattern, (int)(globbuf.gl_pathc-max));
-  
-  // allocate space for up to lim number of ATA devices
-  if (!(mp =  (char **)calloc(lim, sizeof(char*)))){
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-  
-  // now step through the list returned by glob.  If not a link, copy
-  // to list.  If it is a link, evaluate it and see if the path ends
-  // in "disc".
-  for (i=0; i<lim; i++){
-    int retlink;
-    
-    // prepare a buffer for storing the link
-    char linkbuf[1024];
-    
-    // see if path is a link
-    retlink=readlink(globbuf.gl_pathv[i], linkbuf, 1023);
-    
-    // if not a link (or a strange link), keep it
-    if (retlink<=0 || retlink>1023)
-      mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
-    else {
-      // or if it's a link that points to a disc, follow it
-      char *p;
-      linkbuf[retlink]='\0';
-      if ((p=strrchr(linkbuf,'/')) && !strcmp(p+1, "disc"))
-        // This is the branch of the code that gets followed if we are
-        // using devfs WITH traditional compatibility links. In this
-        // case, we add the traditional device name to the list that
-        // is returned.
-        mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
-      else {
-        // This is the branch of the code that gets followed if we are
-        // using devfs WITHOUT traditional compatibility links.  In
-        // this case, we check that the link to the directory is of
-        // the correct type, and then append "disc" to it.
-        char tmpname[1024]={0};
-        char *type=strcmp(name,"ATA")?"scsi":"ide";
-        if (strstr(linkbuf, type)){
-          snprintf(tmpname, 1024, "%s/disc", globbuf.gl_pathv[i]);
-          mp[n++] = CustomStrDup(tmpname, 1, __LINE__, filenameandversion);
-        }
-      }
-    }
-  }
-  
-  // free memory, track memory usage
-  globfree(&globbuf);
-  mp = realloc(mp,n*(sizeof(char*)));
-  bytes += n*(sizeof(char*));
-  
-  // and set up return values
-  *names=mp;
-  return n;
-}
-
-// makes a list of device names to scan, for either ATA or SCSI
-// devices.  Return -1 if no memory remaining, else the number of
-// devices on the list, which can be >=0.
-int make_device_names (char*** devlist, const char* name) {
-  int retval, maxdev;
-  
-#if 0
-  // for testing case where no device names are found
-  return 0;
-#endif
-  
-  if (!strcmp(name,"SCSI"))
-    retval=get_dev_names(devlist,"/dev/sd[a-z]", name, maxdev=26);
-  else if (!strcmp(name,"ATA"))
-    retval=get_dev_names(devlist,"/dev/hd[a-t]", name, maxdev=20);
-  else
-    // don't recognize disk type!
-    return 0;
-
-  // if we found traditional links, we are done
-  if (retval>0)
-    return retval;
-  
-  // else look for devfs entries without traditional links
-  return get_dev_names(devlist,"/dev/discs/disc*", name, maxdev);
-}
-
-
-// PURPOSE
-//   This is an interface routine meant to isolate the OS dependent
-//   parts of the code, and to provide a debugging interface.  Each
-//   different port and OS needs to provide it's own interface.  This
-//   is the linux one.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   device: is the file descriptor provided by open()
-//   command: defines the different operations.
-//   select: additional input data if needed (which log, which type of
-//           self-test).
-//   data:   location to write output data, if needed (512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES
-//  -1 if the command failed
-//   0 if the command succeeded,
-//   STATUS_CHECK routine: 
-//  -1 if the command failed
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-
-
-// huge value of buffer size needed because HDIO_DRIVE_CMD assumes
-// that buff[3] is the data size.  Since the ATA_SMART_AUTOSAVE and
-// ATA_SMART_AUTO_OFFLINE use values of 0xf1 and 0xf8 we need the space.
-// Otherwise a 4+512 byte buffer would be enough.
-#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
-
-int ata_command_interface(int device, smart_command_set command, int select, char *data){
-  unsigned char buff[STRANGE_BUFFER_LENGTH];
-  // positive: bytes to write to caller.  negative: bytes to READ from
-  // caller. zero: non-data command
-  int copydata=0;
-
-  const int HDIO_DRIVE_CMD_OFFSET = 4;
-
-  // See struct hd_drive_cmd_hdr in hdreg.h.  Before calling ioctl()
-  // buff[0]: ATA COMMAND CODE REGISTER
-  // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
-  // buff[2]: ATA FEATURES REGISTER
-  // buff[3]: ATA SECTOR COUNT REGISTER
-
-  // Note that on return:
-  // buff[2] contains the ATA SECTOR COUNT REGISTER
-  
-  // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
-  memset(buff, 0, STRANGE_BUFFER_LENGTH);
-
-  buff[0]=ATA_SMART_CMD;
-  switch (command){
-  case CHECK_POWER_MODE:
-    buff[0]=ATA_CHECK_POWER_MODE;
-    copydata=1;
-    break;
-  case READ_VALUES:
-    buff[2]=ATA_SMART_READ_VALUES;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case READ_THRESHOLDS:
-    buff[2]=ATA_SMART_READ_THRESHOLDS;
-    buff[1]=buff[3]=1;
-    copydata=512;
-    break;
-  case READ_LOG:
-    buff[2]=ATA_SMART_READ_LOG_SECTOR;
-    buff[1]=select;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case WRITE_LOG:
-    break;
-  case IDENTIFY:
-    buff[0]=ATA_IDENTIFY_DEVICE;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case PIDENTIFY:
-    buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case ENABLE:
-    buff[2]=ATA_SMART_ENABLE;
-    buff[1]=1;
-    break;
-  case DISABLE:
-    buff[2]=ATA_SMART_DISABLE;
-    buff[1]=1;
-    break;
-  case STATUS:
-    // this command only says if SMART is working.  It could be
-    // replaced with STATUS_CHECK below.
-    buff[2]=ATA_SMART_STATUS;
-    break;
-  case AUTO_OFFLINE:
-    buff[2]=ATA_SMART_AUTO_OFFLINE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case AUTOSAVE:
-    buff[2]=ATA_SMART_AUTOSAVE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case IMMEDIATE_OFFLINE:
-    buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
-    buff[1]=select;
-    break;
-  case STATUS_CHECK:
-    // This command uses HDIO_DRIVE_TASK and has different syntax than
-    // the other commands.
-    buff[1]=ATA_SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in linux_ata_command_interface()\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command);
-    errno=ENOSYS;
-    return -1;
-  }
-  
-  // This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
-  // only ioctl() that can be used to WRITE data to the disk.
-  if (command==WRITE_LOG) {    
-    unsigned char task[sizeof(ide_task_request_t)+512];
-    ide_task_request_t *reqtask=(ide_task_request_t *) task;
-    task_struct_t      *taskfile=(task_struct_t *) reqtask->io_ports;
-    int retval;
-
-    memset(task,      0, sizeof(task));
-    
-    taskfile->data           = 0;
-    taskfile->feature        = ATA_SMART_WRITE_LOG_SECTOR;
-    taskfile->sector_count   = 1;
-    taskfile->sector_number  = select;
-    taskfile->low_cylinder   = 0x4f;;
-    taskfile->high_cylinder  = 0xc2;
-    taskfile->device_head    = 0;
-    taskfile->command        = ATA_SMART_CMD;
-    
-    reqtask->data_phase      = TASKFILE_OUT;
-    reqtask->req_cmd         = IDE_DRIVE_TASK_OUT;
-    reqtask->out_size        = 512;
-    reqtask->in_size         = 0;
-    
-    // copy user data into the task request structure
-    memcpy(task+sizeof(ide_task_request_t), data, 512);
-      
-    if ((retval=ioctl(device, HDIO_DRIVE_TASKFILE, task))) {
-      if (retval==-EINVAL)
-	pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
-      return -1;
-    }
-    return 0;
-  }
-    
-  // There are two different types of ioctls().  The HDIO_DRIVE_TASK
-  // one is this:
-  if (command==STATUS_CHECK){
-    int retval;
-
-    // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
-    // have to read the IDE driver source code.  Sigh.
-    // buff[0]: ATA COMMAND CODE REGISTER
-    // buff[1]: ATA FEATURES REGISTER
-    // buff[2]: ATA SECTOR_COUNT
-    // buff[3]: ATA SECTOR NUMBER
-    // buff[4]: ATA CYL LO REGISTER
-    // buff[5]: ATA CYL HI REGISTER
-    // buff[6]: ATA DEVICE HEAD
-
-    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
-    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
-    buff[4]=normal_lo;
-    buff[5]=normal_hi;
-    
-    if ((retval=ioctl(device, HDIO_DRIVE_TASK, buff))) {
-      if (retval==-EINVAL) {
-	pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
-	pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
-      }
-      else
-	syserror("Error SMART Status command failed");
-      return -1;
-    }
-    
-    // Cyl low and Cyl high unchanged means "Good SMART status"
-    if (buff[4]==normal_lo && buff[5]==normal_hi)
-      return 0;
-    
-    // These values mean "Bad SMART status"
-    if (buff[4]==failed_lo && buff[5]==failed_hi)
-      return 1;
-    
-    // We haven't gotten output that makes sense; print out some debugging info
-    syserror("Error SMART Status command failed");
-    pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
-    pout("Register values returned from SMART Status command are:\n");
-    pout("CMD=0x%02x\n",(int)buff[0]);
-    pout("FR =0x%02x\n",(int)buff[1]);
-    pout("NS =0x%02x\n",(int)buff[2]);
-    pout("SC =0x%02x\n",(int)buff[3]);
-    pout("CL =0x%02x\n",(int)buff[4]);
-    pout("CH =0x%02x\n",(int)buff[5]);
-    pout("SEL=0x%02x\n",(int)buff[6]);
-    return -1;   
-  }
-  
-#if 1
-  // Note to people doing ports to other OSes -- don't worry about
-  // this block -- you can safely ignore it.  I have put it here
-  // because under linux when you do IDENTIFY DEVICE to a packet
-  // device, it generates an ugly kernel syslog error message.  This
-  // is harmless but frightens users.  So this block detects packet
-  // devices and make IDENTIFY DEVICE fail "nicely" without a syslog
-  // error message.
-  //
-  // If you read only the ATA specs, it appears as if a packet device
-  // *might* respond to the IDENTIFY DEVICE command.  This is
-  // misleading - it's because around the time that SFF-8020 was
-  // incorporated into the ATA-3/4 standard, the ATA authors were
-  // sloppy. See SFF-8020 and you will see that ATAPI devices have
-  // *always* had IDENTIFY PACKET DEVICE as a mandatory part of their
-  // command set, and return 'Command Aborted' to IDENTIFY DEVICE.
-  if (command==IDENTIFY || command==PIDENTIFY){
-    unsigned short deviceid[256];
-    // check the device identity, as seen when the system was booted
-    // or the device was FIRST registered.  This will not be current
-    // if the user has subsequently changed some of the parameters. If
-    // device is a packet device, swap the command interpretations.
-    if (!ioctl(device, HDIO_GET_IDENTITY, deviceid) && (deviceid[0] & 0x8000))
-      buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE;
-  }
-#endif
-  
-  // We are now doing the HDIO_DRIVE_CMD type ioctl.
-  if ((ioctl(device, HDIO_DRIVE_CMD, buff)))
-    return -1;
-
-  // CHECK POWER MODE command returns information in the Sector Count
-  // register (buff[3]).  Copy to return data buffer.
-  if (command==CHECK_POWER_MODE)
-    buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
-
-  // if the command returns data then copy it back
-  if (copydata)
-    memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
-  
-  return 0; 
-}
-
-// >>>>>> Start of general SCSI specific linux code
-
-/* Linux specific code.
- * Historically smartmontools (and smartsuite before it) used the
- * SCSI_IOCTL_SEND_COMMAND ioctl which is available to all linux device
- * nodes that use the SCSI subsystem. A better interface has been available
- * via the SCSI generic (sg) driver but this involves the extra step of
- * mapping disk devices (e.g. /dev/sda) to the corresponding sg device
- * (e.g. /dev/sg2). In the linux kernel 2.6 series most of the facilities of
- * the sg driver have become available via the SG_IO ioctl which is available
- * on all SCSI devices (on SCSI tape devices from lk 2.6.6).
- * So the strategy below is to find out if the SG_IO ioctl is available and
- * if so use it; failing that use the older SCSI_IOCTL_SEND_COMMAND ioctl.
- * Should work in 2.0, 2.2, 2.4 and 2.6 series linux kernels. */
-
-#define MAX_DXFER_LEN 1024      /* can be increased if necessary */
-#define SEND_IOCTL_RESP_SENSE_LEN 16    /* ioctl limitation */
-#define SG_IO_RESP_SENSE_LEN 64 /* large enough see buffer */
-#define LSCSI_DRIVER_MASK  0xf /* mask out "suggestions" */
-#define LSCSI_DRIVER_SENSE  0x8 /* alternate CHECK CONDITION indication */
-#define LSCSI_DRIVER_TIMEOUT  0x6
-#define LSCSI_DID_TIME_OUT  0x3
-#define LSCSI_DID_BUS_BUSY  0x2
-#define LSCSI_DID_NO_CONNECT  0x1
-
-#ifndef SCSI_IOCTL_SEND_COMMAND
-#define SCSI_IOCTL_SEND_COMMAND 1
-#endif
-
-#define SG_IO_PRESENT_UNKNOWN 0
-#define SG_IO_PRESENT_YES 1
-#define SG_IO_PRESENT_NO 2
-
-static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
-static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
-
-static int sg_io_state = SG_IO_PRESENT_UNKNOWN;
-
-/* Preferred implementation for issuing SCSI commands in linux. This
- * function uses the SG_IO ioctl. Return 0 if command issued successfully
- * (various status values should still be checked). If the SCSI command
- * cannot be issued then a negative errno value is returned. */
-static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-#ifndef SG_IO
-    ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report);
-    return -ENOTTY;
-#else
-    struct sg_io_hdr io_hdr;
-
-    if (report > 0) {
-        int k, j;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-        char buff[256];
-        const int sz = (int)sizeof(buff);
-
-        np = scsi_get_opcode_name(ucp[0]);
-        j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
-                          "data, len=%d%s:\n", (int)iop->dxfer_len,
-                          (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((const char *)iop->dxferp, 
-		    (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
-        pout(buff);
-    }
-    memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-    io_hdr.interface_id = 'S';
-    io_hdr.cmd_len = iop->cmnd_len;
-    io_hdr.mx_sb_len = iop->max_sense_len;
-    io_hdr.dxfer_len = iop->dxfer_len;
-    io_hdr.dxferp = iop->dxferp;
-    io_hdr.cmdp = iop->cmnd;
-    io_hdr.sbp = iop->sensep;
-    /* sg_io_hdr interface timeout has millisecond units. Timeout of 0
-       defaults to 60 seconds. */
-    io_hdr.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000;
-    switch (iop->dxfer_dir) {
-        case DXFER_NONE:
-            io_hdr.dxfer_direction = SG_DXFER_NONE;
-            break;
-        case DXFER_FROM_DEVICE:
-            io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-            break;
-        case DXFER_TO_DEVICE:
-            io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
-            break;
-        default:
-            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-            return -EINVAL;
-    }
-    iop->resp_sense_len = 0;
-    iop->scsi_status = 0;
-    iop->resid = 0;
-    if (ioctl(dev_fd, SG_IO, &io_hdr) < 0) {
-        if (report)
-            pout("  SG_IO ioctl failed, errno=%d [%s]\n", errno,
-		 strerror(errno));
-        return -errno;
-    }
-    if (report > 0) {
-        pout("  scsi_status=0x%x, host_status=0x%x, driver_status=0x%x\n"
-	     "  info=0x%x  duration=%d milliseconds\n", io_hdr.status, 
-	     io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
-	     io_hdr.duration);
-        if (report > 1) {
-            if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex((const char*)iop->dxferp, 
-		        (trunc ? 256 : iop->dxfer_len) , 1);
-            }
-        }
-    }
-    iop->resid = io_hdr.resid;
-    iop->scsi_status = io_hdr.status;
-
-    if (io_hdr.info | SG_INFO_CHECK) { /* error or warning */
-	int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
-
-	if (0 != io_hdr.host_status) {
-            if ((LSCSI_DID_NO_CONNECT == io_hdr.host_status) ||
-                (LSCSI_DID_BUS_BUSY == io_hdr.host_status) ||
-                (LSCSI_DID_TIME_OUT == io_hdr.host_status))
-                return -ETIMEDOUT;
-	    else
-		return -EIO;	/* catch all */
-        }
-        if (0 != masked_driver_status) {
-            if (LSCSI_DRIVER_TIMEOUT == masked_driver_status)
-                return -ETIMEDOUT;
-	    else
-		return -EIO;	/* catch all */
-	}
-        if (LSCSI_DRIVER_SENSE == (io_hdr.driver_status & 0xf))
-            iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-        iop->resp_sense_len = io_hdr.sb_len_wr;
-        if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && 
-            iop->sensep && (iop->resp_sense_len > 0)) {
-            if (report > 1) {
-                pout("  >>> Sense buffer, len=%d:\n",
-		     (int)iop->resp_sense_len);
-                dStrHex((const char *)iop->sensep, iop->resp_sense_len , 1);
-            }
-        }
-        if (report) {
-            if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
-                pout("  status=%x: sense_key=%x asc=%x ascq=%x\n",
-		     iop->scsi_status, iop->sensep[2] & 0xf, iop->sensep[12],
-		     iop->sensep[13]);
-            }
-            else
-                pout("  status=0x%x\n", iop->scsi_status);
-        }
-    }
-    return 0;
-#endif
-}
-
-struct linux_ioctl_send_command
-{
-    int inbufsize;
-    int outbufsize;
-    UINT8 buff[MAX_DXFER_LEN + 16];
-};
-
-/* The Linux SCSI_IOCTL_SEND_COMMAND ioctl is primitive and it doesn't 
- * support: CDB length (guesses it from opcode), resid and timeout.
- * Patches in Linux 2.4.21 and 2.5.70 to extend SEND DIAGNOSTIC timeout
- * to 2 hours in order to allow long foreground extended self tests. */
-static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-    struct linux_ioctl_send_command wrk;
-    int status, buff_offset;
-    size_t len;
-
-    memcpy(wrk.buff, iop->cmnd, iop->cmnd_len);
-    buff_offset = iop->cmnd_len;
-    if (report > 0) {
-        int k, j;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-        char buff[256];
-        const int sz = (int)sizeof(buff);
-
-        np = scsi_get_opcode_name(ucp[0]);
-        j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
-                          "data, len=%d%s:\n", (int)iop->dxfer_len,
-                          (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((const char *)iop->dxferp, 
-		    (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
-        pout(buff);
-    }
-    switch (iop->dxfer_dir) {
-        case DXFER_NONE:
-            wrk.inbufsize = 0;
-            wrk.outbufsize = 0;
-            break;
-        case DXFER_FROM_DEVICE:
-            wrk.inbufsize = 0;
-            if (iop->dxfer_len > MAX_DXFER_LEN)
-                return -EINVAL;
-            wrk.outbufsize = iop->dxfer_len;
-            break;
-        case DXFER_TO_DEVICE:
-            if (iop->dxfer_len > MAX_DXFER_LEN)
-                return -EINVAL;
-            memcpy(wrk.buff + buff_offset, iop->dxferp, iop->dxfer_len);
-            wrk.inbufsize = iop->dxfer_len;
-            wrk.outbufsize = 0;
-            break;
-        default:
-            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-            return -EINVAL;
-    }
-    iop->resp_sense_len = 0;
-    iop->scsi_status = 0;
-    iop->resid = 0;
-    status = ioctl(dev_fd, SCSI_IOCTL_SEND_COMMAND, &wrk);
-    if (-1 == status) {
-        if (report)
-            pout("  SCSI_IOCTL_SEND_COMMAND ioctl failed, errno=%d [%s]\n",
-                 errno, strerror(errno));
-        return -errno;
-    }
-    if (0 == status) {
-        if (report > 0)
-            pout("  status=0\n");
-        if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-            memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
-            if (report > 1) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex((const char*)iop->dxferp, 
-			(trunc ? 256 : iop->dxfer_len) , 1);
-            }
-        }
-        return 0;
-    }
-    iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
-    if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
-        iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-    len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
-                SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
-    if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && 
-        iop->sensep && (len > 0)) {
-        memcpy(iop->sensep, wrk.buff, len);
-        iop->resp_sense_len = len;
-        if (report > 1) {
-            pout("  >>> Sense buffer, len=%d:\n", (int)len);
-            dStrHex((const char *)wrk.buff, len , 1);
-        }
-    }
-    if (report) {
-        if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
-            pout("  status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
-                 wrk.buff[2] & 0xf, wrk.buff[12], wrk.buff[13]);
-        }
-        else
-            pout("  status=0x%x\n", status);
-    }
-    if (iop->scsi_status > 0)
-        return 0;
-    else {
-        if (report > 0)
-            pout("  ioctl status=0x%x but scsi status=0, fail with EIO\n", 
-                 status);
-        return -EIO;      /* give up, assume no device there */
-    }
-}
-
-/* SCSI command transmission interface function, linux version.
- * Returns 0 if SCSI command successfully launched and response
- * received. Even when 0 is returned the caller should check 
- * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
- * (e.g. CHECK CONDITION). If the SCSI command could not be issued
- * (e.g. device not present or timeout) or some other problem
- * (e.g. timeout) then returns a negative errno value */
-int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-    int res;
-
-    /* implementation relies on static sg_io_state variable. If not
-     * previously set tries the SG_IO ioctl. If that succeeds assume
-     * that SG_IO ioctl functional. If it fails with an errno value
-     * other than ENODEV (no device) or permission then assume 
-     * SCSI_IOCTL_SEND_COMMAND is the only option. */
-    switch (sg_io_state) {
-    case SG_IO_PRESENT_UNKNOWN:
-        /* ignore report argument */
-	if (0 == (res = sg_io_cmnd_io(dev_fd, iop, 0))) {
-	    sg_io_state = SG_IO_PRESENT_YES;
-	    return 0;
-	} else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
-	    return res;		/* wait until we see a device */
-        sg_io_state = SG_IO_PRESENT_NO;
-	/* drop through by design */
-    case SG_IO_PRESENT_NO:
-	return sisc_cmnd_io(dev_fd, iop, report);
-    case SG_IO_PRESENT_YES:
-	return sg_io_cmnd_io(dev_fd, iop, report);
-    default:
-	pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state); 
-	sg_io_state = SG_IO_PRESENT_UNKNOWN;
-        return -EIO; 	/* report error and reset state */
-    }
-}
-
-// >>>>>> End of general SCSI specific linux code
-
-
-// prototype
-void printwarning(smart_command_set command);
-
-// PURPOSE
-//   This is an interface routine meant to isolate the OS dependent
-//   parts of the code, and to provide a debugging interface.  Each
-//   different port and OS needs to provide it's own interface.  This
-//   is the linux interface to the 3ware 3w-xxxx driver.  It allows ATA
-//   commands to be passed through the SCSI driver.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   fd: is the file descriptor provided by open()
-//   disknum is the disk number (0 to 15) in the RAID array
-//   escalade_type indicates the type of controller type, and if scsi or char interface is used
-//   command: defines the different operations.
-//   select: additional input data if needed (which log, which type of
-//           self-test).
-//   data:   location to write output data, if needed (512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES
-//  -1 if the command failed
-//   0 if the command succeeded,
-//   STATUS_CHECK routine: 
-//  -1 if the command failed
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-
-
-/* 512 is the max payload size: increase if needed */
-#define BUFFER_LEN_678K      ( sizeof(TW_Ioctl)                  ) // 1044 unpacked, 1041 packed
-#define BUFFER_LEN_678K_CHAR ( sizeof(TW_New_Ioctl)+512-1        ) // 1539 unpacked, 1536 packed
-#define BUFFER_LEN_9000      ( sizeof(TW_Ioctl_Buf_Apache)+512-1 ) // 2051 unpacked, 2048 packed
-#define TW_IOCTL_BUFFER_SIZE ( MAX(MAX(BUFFER_LEN_678K, BUFFER_LEN_9000), BUFFER_LEN_678K_CHAR) )
-
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-
-  // return value and buffer for ioctl()
-  int  ioctlreturn, readdata=0;
-
-  // Used by both the SCSI and char interfaces
-  TW_Passthru *passthru=NULL;
-  char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
-
-  // only used for SCSI device interface
-  TW_Ioctl   *tw_ioctl=NULL;
-  TW_Output *tw_output=NULL;
-
-  // only used for 6000/7000/8000 char device interface
-  TW_New_Ioctl *tw_ioctl_char=NULL;
-
-  // only used for 9000 character device interface
-  TW_Ioctl_Buf_Apache *tw_ioctl_apache=NULL;
-  
-  memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
-
-  if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
-    tw_ioctl_apache                               = (TW_Ioctl_Buf_Apache *)ioctl_buffer;
-    tw_ioctl_apache->driver_command.control_code  = TW_IOCTL_FIRMWARE_PASS_THROUGH;
-    tw_ioctl_apache->driver_command.buffer_length = 512; /* payload size */
-    passthru                                      = (TW_Passthru *)&(tw_ioctl_apache->firmware_command.command.oldcommand);
-  }
-  else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
-    tw_ioctl_char                                 = (TW_New_Ioctl *)ioctl_buffer;
-    tw_ioctl_char->data_buffer_length             = 512;
-    passthru                                      = (TW_Passthru *)&(tw_ioctl_char->firmware_command);
-  }
-  else if (escalade_type==CONTROLLER_3WARE_678K) {
-    tw_ioctl                                      = (TW_Ioctl *)ioctl_buffer;
-    tw_ioctl->cdb[0]                              = TW_IOCTL;
-    tw_ioctl->opcode                              = TW_ATA_PASSTHRU;
-    tw_ioctl->input_length                        = 512; // correct even for non-data commands
-    tw_ioctl->output_length                       = 512; // correct even for non-data commands
-    tw_output                                     = (TW_Output *)tw_ioctl;
-    passthru                                      = (TW_Passthru *)&(tw_ioctl->input_data);
-  }
-  else {
-    pout("Unrecognized escalade_type %d in linux_3ware_command_interface(disk %d)\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  // Same for (almost) all commands - but some reset below
-  passthru->byte0.opcode  = TW_OP_ATA_PASSTHRU;
-  passthru->request_id    = 0xFF;
-  passthru->byte3.aport   = disknum;
-  passthru->byte3.host_id = 0;
-  passthru->status        = 0;           
-  passthru->flags         = 0x1;
-  passthru->drive_head    = 0x0;
-  passthru->sector_num    = 0;
-
-  // All SMART commands use this CL/CH signature.  These are magic
-  // values from the ATA specifications.
-  passthru->cylinder_lo   = 0x4F;
-  passthru->cylinder_hi   = 0xC2;
-  
-  // SMART ATA COMMAND REGISTER value
-  passthru->command       = ATA_SMART_CMD;
-  
-  // Is this a command that reads or returns 512 bytes?
-  // passthru->param values are:
-  // 0x0 - non data command without TFR write check,
-  // 0x8 - non data command with TFR write check,
-  // 0xD - data command that returns data to host from device
-  // 0xF - data command that writes data from host to device
-  // passthru->size values are 0x5 for non-data and 0x07 for data
-  if (command == READ_VALUES     ||
-      command == READ_THRESHOLDS ||
-      command == READ_LOG        ||
-      command == IDENTIFY        ||
-      command == WRITE_LOG ) {
-    readdata=1;
-    passthru->byte0.sgloff = 0x5;
-    passthru->size         = 0x7;
-    passthru->param        = 0xD;
-    passthru->sector_count = 0x1;
-    // For 64-bit to work correctly, up the size of the command packet
-    // in dwords by 1 to account for the 64-bit single sgl 'address'
-    // field. Note that this doesn't agree with the typedefs but it's
-    // right (agree with kernel driver behavior/typedefs).
-    if (escalade_type==CONTROLLER_3WARE_9000_CHAR && sizeof(long)==8)
-      passthru->size++;
-  }
-  else {
-    // Non data command -- but doesn't use large sector 
-    // count register values.  
-    passthru->byte0.sgloff = 0x0;
-    passthru->size         = 0x5;
-    passthru->param        = 0x8;
-    passthru->sector_count = 0x0;
-  }
-  
-  // Now set ATA registers depending upon command
-  switch (command){
-  case CHECK_POWER_MODE:
-    passthru->command     = ATA_CHECK_POWER_MODE;
-    passthru->features    = 0;
-    passthru->cylinder_lo = 0;
-    passthru->cylinder_hi = 0;
-    break;
-  case READ_VALUES:
-    passthru->features = ATA_SMART_READ_VALUES;
-    break;
-  case READ_THRESHOLDS:
-    passthru->features = ATA_SMART_READ_THRESHOLDS;
-    break;
-  case READ_LOG:
-    passthru->features = ATA_SMART_READ_LOG_SECTOR;
-    // log number to return
-    passthru->sector_num  = select;
-    break;
-  case WRITE_LOG:
-    if (escalade_type == CONTROLLER_3WARE_9000_CHAR)
-      memcpy((unsigned char *)tw_ioctl_apache->data_buffer, data, 512);
-    else if (escalade_type == CONTROLLER_3WARE_678K_CHAR)
-      memcpy((unsigned char *)tw_ioctl_char->data_buffer,   data, 512);
-    else {
-      // COMMAND NOT SUPPORTED VIA SCSI IOCTL INTERFACE
-      // memcpy(tw_output->output_data, data, 512);
-      printwarning(command);
-      errno=ENOTSUP;
-      return -1;
-    }
-    readdata=0;
-    passthru->features     = ATA_SMART_WRITE_LOG_SECTOR;
-    passthru->sector_count = 1;
-    passthru->sector_num   = select;
-    passthru->param        = 0xF;  // PIO data write
-    break;
-  case IDENTIFY:
-    // ATA IDENTIFY DEVICE
-    passthru->command     = ATA_IDENTIFY_DEVICE;
-    passthru->features    = 0;
-    passthru->cylinder_lo = 0;
-    passthru->cylinder_hi = 0;
-    break;
-  case PIDENTIFY:
-    // 3WARE controller can NOT have packet device internally
-    pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
-    errno=ENODEV;
-    return -1;
-  case ENABLE:
-    passthru->features = ATA_SMART_ENABLE;
-    break;
-  case DISABLE:
-    passthru->features = ATA_SMART_DISABLE;
-    break;
-  case AUTO_OFFLINE:
-    passthru->features     = ATA_SMART_AUTO_OFFLINE;
-    // Enable or disable?
-    passthru->sector_count = select;
-    break;
-  case AUTOSAVE:
-    passthru->features     = ATA_SMART_AUTOSAVE;
-    // Enable or disable?
-    passthru->sector_count = select;
-    break;
-  case IMMEDIATE_OFFLINE:
-    passthru->features    = ATA_SMART_IMMEDIATE_OFFLINE;
-    // What test type to run?
-    passthru->sector_num  = select;
-    break;
-  case STATUS_CHECK:
-    passthru->features = ATA_SMART_STATUS;
-    break;
-  case STATUS:
-    // This is JUST to see if SMART is enabled, by giving SMART status
-    // command. But it doesn't say if status was good, or failing.
-    // See below for the difference.
-    passthru->features = ATA_SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in linux_3ware_command_interface(disk %d)\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  // Now send the command down through an ioctl()
-  if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
-    ioctlreturn=ioctl(fd, TW_IOCTL_FIRMWARE_PASS_THROUGH, tw_ioctl_apache);
-  else if (escalade_type==CONTROLLER_3WARE_678K_CHAR)
-    ioctlreturn=ioctl(fd, TW_CMD_PACKET_WITH_DATA, tw_ioctl_char);
-  else
-    ioctlreturn=ioctl(fd, SCSI_IOCTL_SEND_COMMAND, tw_ioctl);
-  
-  // Deal with the different error cases
-  if (ioctlreturn) {
-    if (CONTROLLER_3WARE_678K==escalade_type && ((command==AUTO_OFFLINE || command==AUTOSAVE) && select)){
-      // error here is probably a kernel driver whose version is too old
-      printwarning(command);
-      errno=ENOTSUP;
-    }
-    if (!errno)
-      errno=EIO;
-    return -1;
-  }
-  
-  // The passthru structure is valid after return from an ioctl if:
-  // - we are using the character interface OR 
-  // - we are using the SCSI interface and this is a NON-READ-DATA command
-  // For SCSI interface, note that we set passthru to a different
-  // value after ioctl().
-  if (CONTROLLER_3WARE_678K==escalade_type) {
-    if (readdata)
-      passthru=NULL;
-    else
-      passthru=(TW_Passthru *)&(tw_output->output_data);
-  }
-
-  // See if the ATA command failed.  Now that we have returned from
-  // the ioctl() call, if passthru is valid, then:
-  // - passthru->status contains the 3ware controller STATUS
-  // - passthru->command contains the ATA STATUS register
-  // - passthru->features contains the ATA ERROR register
-  //
-  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
-  // If bit 0 (error bit) is set, then ATA ERROR register is valid.
-  // While we *might* decode the ATA ERROR register, at the moment it
-  // doesn't make much sense: we don't care in detail why the error
-  // happened.
-  
-  if (passthru && (passthru->status || (passthru->command & 0x21))) {
-    errno=EIO;
-    return -1;
-  }
-  
-  // If this is a read data command, copy data to output buffer
-  if (readdata) {
-    if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
-      memcpy(data, (unsigned char *)tw_ioctl_apache->data_buffer, 512);
-    else if (escalade_type==CONTROLLER_3WARE_678K_CHAR)
-      memcpy(data, (unsigned char *)tw_ioctl_char->data_buffer, 512);
-    else
-      memcpy(data, tw_output->output_data, 512);
-  }
-
-  // For STATUS_CHECK, we need to check register values
-  if (command==STATUS_CHECK) {
-    
-    // To find out if the SMART RETURN STATUS is good or failing, we
-    // need to examine the values of the Cylinder Low and Cylinder
-    // High Registers.
-    
-    unsigned short cyl_lo=passthru->cylinder_lo;
-    unsigned short cyl_hi=passthru->cylinder_hi;
-    
-    // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
-    if (cyl_lo==0x4F && cyl_hi==0xC2)
-      return 0;
-    
-    // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
-    if (cyl_lo==0xF4 && cyl_hi==0x2C)
-      return 1;
-    
-    // Any other values mean that something has gone wrong with the command
-    if (CONTROLLER_3WARE_678K==escalade_type) {
-      printwarning(command);
-      errno=ENOSYS;
-      return 0;
-    }
-    else {
-      errno=EIO;
-      return -1;
-    }
-  }
-  
-  // copy sector count register (one byte!) to return data
-  if (command==CHECK_POWER_MODE)
-    *data=*(char *)&(passthru->sector_count);
-  
-  // look for nonexistent devices/ports
-  if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
-    errno=ENODEV;
-    return -1;
-  }
-  
-  return 0;
-}
-
-// Utility function for printing warnings
-void printwarning(smart_command_set command){
-  static int printed[4]={0,0,0,0};
-  const char* message=
-    "can not be passed through the 3ware 3w-xxxx driver.  This can be fixed by\n"
-    "applying a simple 3w-xxxx driver patch that can be found here:\n"
-    PACKAGE_HOMEPAGE "\n"
-    "Alternatively, upgrade your 3w-xxxx driver to version 1.02.00.037 or greater.\n\n";
-
-  if (command==AUTO_OFFLINE && !printed[0]) {
-    printed[0]=1;
-    pout("The SMART AUTO-OFFLINE ENABLE command (smartmontools -o on option/Directive)\n%s", message);
-  } 
-  else if (command==AUTOSAVE && !printed[1]) {
-    printed[1]=1;
-    pout("The SMART AUTOSAVE ENABLE command (smartmontools -S on option/Directive)\n%s", message);
-  }
-  else if (command==STATUS_CHECK && !printed[2]) {
-    printed[2]=1;
-    pout("The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n%s", message);
-  }
-  else if (command==WRITE_LOG && !printed[3])  {
-    printed[3]=1;
-    pout("The SMART WRITE LOG command (smartmontools -t selective) only supported via char /dev/tw[ae] interface\n");
-  }
-  
-  return;
-}
-
-// Guess device type (ata or scsi) based on device name (Linux
-// specific) SCSI device name in linux can be sd, sr, scd, st, nst,
-// osst, nosst and sg.
-static const char * lin_dev_prefix = "/dev/";
-static const char * lin_dev_ata_disk_plus = "h";
-static const char * lin_dev_ata_devfs_disk_plus = "ide/";
-static const char * lin_dev_scsi_devfs_disk_plus = "scsi/";
-static const char * lin_dev_scsi_disk_plus = "s";
-static const char * lin_dev_scsi_tape1 = "ns";
-static const char * lin_dev_scsi_tape2 = "os";
-static const char * lin_dev_scsi_tape3 = "nos";
-static const char * lin_dev_3ware_9000_char = "twa";
-static const char * lin_dev_3ware_678k_char = "twe";
-
-int guess_device_type(const char * dev_name) {
-  int len;
-  int dev_prefix_len = strlen(lin_dev_prefix);
-  
-  // if dev_name null, or string length zero
-  if (!dev_name || !(len = strlen(dev_name)))
-    return CONTROLLER_UNKNOWN;
-  
-  // Remove the leading /dev/... if it's there
-  if (!strncmp(lin_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len)
-      // if nothing else in the string, unrecognized
-      return CONTROLLER_UNKNOWN;
-    // else advance pointer to following characters
-    dev_name += dev_prefix_len;
-  }
-  
-  // form /dev/h* or h*
-  if (!strncmp(lin_dev_ata_disk_plus, dev_name,
-               strlen(lin_dev_ata_disk_plus)))
-    return CONTROLLER_ATA;
-  
-  // form /dev/ide/* or ide/*
-  if (!strncmp(lin_dev_ata_devfs_disk_plus, dev_name,
-               strlen(lin_dev_ata_devfs_disk_plus)))
-    return CONTROLLER_ATA;
-
-  // form /dev/s* or s*
-  if (!strncmp(lin_dev_scsi_disk_plus, dev_name,
-               strlen(lin_dev_scsi_disk_plus)))
-    return CONTROLLER_SCSI;
-
-  // form /dev/scsi/* or scsi/*
-  if (!strncmp(lin_dev_scsi_devfs_disk_plus, dev_name,
-               strlen(lin_dev_scsi_devfs_disk_plus)))
-    return CONTROLLER_SCSI;
-  
-  // form /dev/ns* or ns*
-  if (!strncmp(lin_dev_scsi_tape1, dev_name,
-               strlen(lin_dev_scsi_tape1)))
-    return CONTROLLER_SCSI;
-  
-  // form /dev/os* or os*
-  if (!strncmp(lin_dev_scsi_tape2, dev_name,
-               strlen(lin_dev_scsi_tape2)))
-    return CONTROLLER_SCSI;
-  
-  // form /dev/nos* or nos*
-  if (!strncmp(lin_dev_scsi_tape3, dev_name,
-               strlen(lin_dev_scsi_tape3)))
-    return CONTROLLER_SCSI;
-
-  // form /dev/twa*
-  if (!strncmp(lin_dev_3ware_9000_char, dev_name,
-               strlen(lin_dev_3ware_9000_char)))
-    return CONTROLLER_3WARE_9000_CHAR;
-
-  // form /dev/twe*
-  if (!strncmp(lin_dev_3ware_678k_char, dev_name,
-               strlen(lin_dev_3ware_678k_char)))
-    return CONTROLLER_3WARE_678K_CHAR;
-
-  // we failed to recognize any of the forms
-  return CONTROLLER_UNKNOWN;
-}
-
-
-#if 0
-
-[ed@firestorm ed]$ ls -l  /dev/discs
-total 0
-lr-xr-xr-x    1 root     root           30 Dec 31  1969 disc0 -> ../ide/host2/bus0/target0/lun0/
-lr-xr-xr-x    1 root     root           30 Dec 31  1969 disc1 -> ../ide/host2/bus1/target0/lun0/
-[ed@firestorm ed]$ ls -l  dev/ide/host*/bus*/target*/lun*/disc
-ls: dev/ide/host*/bus*/target*/lun*/disc: No such file or directory
-[ed@firestorm ed]$ ls -l  /dev/ide/host*/bus*/target*/lun*/disc
-brw-------    1 root     root      33,   0 Dec 31  1969 /dev/ide/host2/bus0/target0/lun0/disc
-brw-------    1 root     root      34,   0 Dec 31  1969 /dev/ide/host2/bus1/target0/lun0/disc
-[ed@firestorm ed]$ ls -l  /dev/ide/c*b*t*u*
-ls: /dev/ide/c*b*t*u*: No such file or directory
-[ed@firestorm ed]$ 
-Script done on Fri Nov  7 13:46:28 2003
-
-#endif
diff --git a/sm5/os_linux.cpp b/sm5/os_linux.cpp
deleted file mode 100644
index 380b3a60c31d30be797d8a02115acec26b17a86b..0000000000000000000000000000000000000000
--- a/sm5/os_linux.cpp
+++ /dev/null
@@ -1,1387 +0,0 @@
-/* 
- *  os_linux.c
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003-4 Doug Gilbert <dougg@torque.net>
- *
- *  Parts of this file are derived from code that was
- *
- *  Written By: Adam Radford <linux@3ware.com>
- *  Modifications By: Joel Jacobson <linux@3ware.com>
- *                   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *                    Brad Strand <linux@3ware.com>
- *
- *  Copyright (C) 1999-2003 3ware Inc.
- *
- *  Kernel compatablity By:     Andre Hedrick <andre@suse.com>
- *  Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
- *
- * Other ars of this file are derived from code that was
- * 
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- * 
- */
-
-// This file contains the linux-specific IOCTL parts of
-// smartmontools. It includes one interface routine for ATA devices,
-// one for SCSI devices, and one for ATA devices behind escalade
-// controllers.
-
-#include <errno.h>
-#include <fcntl.h>
-#include <glob.h>
-#include <scsi/scsi_ioctl.h>
-#include <scsi/sg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#ifndef makedev // old versions of types.h do not include sysmacros.h
-#include <sys/sysmacros.h>
-#endif
-
-#include "atacmds.h"
-#include "os_linux.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-#ifndef ENOTSUP
-#define ENOTSUP ENOSYS
-#endif
-typedef unsigned long long u8;
-
-#define ARGUSED(x) ((void)(x))
-
-static const char *filenameandversion="$Id: os_linux.cpp,v 1.70 2004/08/16 22:44:26 ballen4705 Exp $";
-
-const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.70 2004/08/16 22:44:26 ballen4705 Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// global variable holding byte count of allocated memory
-extern long long bytes;
-
-
-
-/* This function will setup and fix device nodes for a 3ware controller. */
-#define MAJOR_STRING_LENGTH 3
-#define DEVICE_STRING_LENGTH 32
-#define NODE_STRING_LENGTH 16
-int setup_3ware_nodes(char *nodename, char *driver_name) {
-  int              tw_major      = 0;
-  int              index         = 0;
-  char             majorstring[MAJOR_STRING_LENGTH+1];
-  char             device_name[DEVICE_STRING_LENGTH+1];
-  char             nodestring[NODE_STRING_LENGTH];
-  struct stat      stat_buf;
-  FILE             *file;
-  
-  /* First try to open up /proc/devices */
-  if (!(file = fopen("/proc/devices", "r"))) {
-    pout("Error opening /proc/devices to check/create 3ware device nodes\n");
-    syserror("fopen");
-    return 0;  // don't fail here: user might not have /proc !
-  }
-  
-  /* Attempt to get device major number */
-  while (EOF != fscanf(file, "%3s %32s", majorstring, device_name)) {
-    majorstring[MAJOR_STRING_LENGTH]='\0';
-    device_name[DEVICE_STRING_LENGTH]='\0';
-    if (!strncmp(device_name, nodename, DEVICE_STRING_LENGTH)) {
-      tw_major = atoi(majorstring);
-      break;
-    }
-  }
-  fclose(file);
-  
-  /* See if we found a major device number */
-  if (!tw_major) {
-    pout("No major number for /dev/%s listed in /proc/devices. Is the %s driver loaded?\n", nodename, driver_name);
-    return 2;
-  }
-  
-  /* Now check if nodes are correct */
-  for (index=0; index<16; index++) {
-    sprintf(nodestring, "/dev/%s%d", nodename, index);
-	  
-    /* Try to stat the node */
-    if ((stat(nodestring, &stat_buf))) {
-      /* Create a new node if it doesn't exist */
-      if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
-	pout("problem creating 3ware device nodes %s", nodestring);
-	syserror("mknod");
-	return 3;
-      }
-    }
-    
-    /* See if nodes major and minor numbers are correct */
-    if ((tw_major != (int)(major(stat_buf.st_rdev))) ||
-	(index    != (int)(minor(stat_buf.st_rdev))) ||
-	(!S_ISCHR(stat_buf.st_mode))) {
-      
-      /* Delete the old node */
-      if (unlink(nodestring)) {
-	pout("problem unlinking stale 3ware device node %s", nodestring);
-	syserror("unlink");
-	return 4;
-      }
-      
-      /* Make a new node */
-      if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
-	pout("problem creating 3ware device nodes %s", nodestring);
-	syserror("mknod");
-	return 5;
-      }
-    }
-  }
-  return 0;
-}
-
-// equivalent to open(path, flags)
-int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) {
-    int fd = open(pathname, O_RDWR | O_NONBLOCK);
-    if (fd < 0 && errno == EROFS)
-      fd = open(pathname, O_RDONLY | O_NONBLOCK);
-    return fd;
-  }
-  else if (!strcmp(type,"ATA")) 
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  else if (!strcmp(type,"ATA_3WARE_9000")) {
-    // the device nodes for this controller are dynamically assigned,
-    // so we need to check that they exist with the correct major
-    // numbers and if not, create them
-    if (setup_3ware_nodes("twa", "3w-9xxx")) {
-      if (!errno)
-	errno=ENXIO;
-      return -1;
-    }
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  }
-  else if (!strcmp(type,"ATA_3WARE_678K")) {
-    // the device nodes for this controller are dynamically assigned,
-    // so we need to check that they exist with the correct major
-    // numbers and if not, create them
-    if (setup_3ware_nodes("twe", "3w-xxxx")) {
-      if (!errno)
-	errno=ENXIO;
-      return -1;
-    }
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  }
-  else
-    return -1;
-}
-
-// equivalent to close(file descriptor)
-int deviceclose(int fd){
-  return close(fd);
-}
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a --device=3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         "  smartctl -a -d 3ware,2 /dev/sda\n"
-         "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-         );
-#endif
-  return;
-}
-
-
-// we are going to take advantage of the fact that Linux's devfs will only
-// have device entries for devices that exist.  So if we get the equivalent of
-// ls /dev/hd[a-t], we have all the ATA devices on the system
-//
-// If any errors occur, leave errno set as it was returned by the
-// system call, and return <0.
-int get_dev_names(char*** names, const char* pattern, const char* name, int max) {
-  int n = 0, retglob, i, lim;
-  char** mp;
-  glob_t globbuf;
-  
-  memset(&globbuf, 0, sizeof(globbuf));
-
-  // in case of non-clean exit
-  *names=NULL;
-  
-  // Use glob to look for any directory entries matching the pattern
-  if ((retglob=glob(pattern, GLOB_ERR, NULL, &globbuf))) {
-    
-    //  glob failed: free memory and return
-    globfree(&globbuf);
-    
-    if (retglob==GLOB_NOMATCH){
-      pout("glob(3) found no matches for pattern %s\n", pattern);
-      return 0;
-    }
-    
-    if (retglob==GLOB_NOSPACE)
-      pout("glob(3) ran out of memory matching pattern %s\n", pattern);
-#ifdef GLOB_ABORTED // missing in old versions of glob.h
-    else if (retglob==GLOB_ABORTED)
-      pout("glob(3) aborted matching pattern %s\n", pattern);
-#endif
-    else
-      pout("Unexplained error in glob(3) of pattern %s\n", pattern);
-    
-    return -1;
-  }
-
-  // did we find too many paths?
-  lim = ((int)globbuf.gl_pathc < max) ? (int)globbuf.gl_pathc : max;
-  if (lim < (int)globbuf.gl_pathc)
-    pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n", 
-         (int)globbuf.gl_pathc, max, pattern, (int)(globbuf.gl_pathc-max));
-  
-  // allocate space for up to lim number of ATA devices
-  if (!(mp =  (char **)calloc(lim, sizeof(char*)))){
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-  
-  // now step through the list returned by glob.  If not a link, copy
-  // to list.  If it is a link, evaluate it and see if the path ends
-  // in "disc".
-  for (i=0; i<lim; i++){
-    int retlink;
-    
-    // prepare a buffer for storing the link
-    char linkbuf[1024];
-    
-    // see if path is a link
-    retlink=readlink(globbuf.gl_pathv[i], linkbuf, 1023);
-    
-    // if not a link (or a strange link), keep it
-    if (retlink<=0 || retlink>1023)
-      mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
-    else {
-      // or if it's a link that points to a disc, follow it
-      char *p;
-      linkbuf[retlink]='\0';
-      if ((p=strrchr(linkbuf,'/')) && !strcmp(p+1, "disc"))
-        // This is the branch of the code that gets followed if we are
-        // using devfs WITH traditional compatibility links. In this
-        // case, we add the traditional device name to the list that
-        // is returned.
-        mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
-      else {
-        // This is the branch of the code that gets followed if we are
-        // using devfs WITHOUT traditional compatibility links.  In
-        // this case, we check that the link to the directory is of
-        // the correct type, and then append "disc" to it.
-        char tmpname[1024]={0};
-        char *type=strcmp(name,"ATA")?"scsi":"ide";
-        if (strstr(linkbuf, type)){
-          snprintf(tmpname, 1024, "%s/disc", globbuf.gl_pathv[i]);
-          mp[n++] = CustomStrDup(tmpname, 1, __LINE__, filenameandversion);
-        }
-      }
-    }
-  }
-  
-  // free memory, track memory usage
-  globfree(&globbuf);
-  mp = realloc(mp,n*(sizeof(char*)));
-  bytes += n*(sizeof(char*));
-  
-  // and set up return values
-  *names=mp;
-  return n;
-}
-
-// makes a list of device names to scan, for either ATA or SCSI
-// devices.  Return -1 if no memory remaining, else the number of
-// devices on the list, which can be >=0.
-int make_device_names (char*** devlist, const char* name) {
-  int retval, maxdev;
-  
-#if 0
-  // for testing case where no device names are found
-  return 0;
-#endif
-  
-  if (!strcmp(name,"SCSI"))
-    retval=get_dev_names(devlist,"/dev/sd[a-z]", name, maxdev=26);
-  else if (!strcmp(name,"ATA"))
-    retval=get_dev_names(devlist,"/dev/hd[a-t]", name, maxdev=20);
-  else
-    // don't recognize disk type!
-    return 0;
-
-  // if we found traditional links, we are done
-  if (retval>0)
-    return retval;
-  
-  // else look for devfs entries without traditional links
-  return get_dev_names(devlist,"/dev/discs/disc*", name, maxdev);
-}
-
-
-// PURPOSE
-//   This is an interface routine meant to isolate the OS dependent
-//   parts of the code, and to provide a debugging interface.  Each
-//   different port and OS needs to provide it's own interface.  This
-//   is the linux one.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   device: is the file descriptor provided by open()
-//   command: defines the different operations.
-//   select: additional input data if needed (which log, which type of
-//           self-test).
-//   data:   location to write output data, if needed (512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES
-//  -1 if the command failed
-//   0 if the command succeeded,
-//   STATUS_CHECK routine: 
-//  -1 if the command failed
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-
-
-// huge value of buffer size needed because HDIO_DRIVE_CMD assumes
-// that buff[3] is the data size.  Since the ATA_SMART_AUTOSAVE and
-// ATA_SMART_AUTO_OFFLINE use values of 0xf1 and 0xf8 we need the space.
-// Otherwise a 4+512 byte buffer would be enough.
-#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
-
-int ata_command_interface(int device, smart_command_set command, int select, char *data){
-  unsigned char buff[STRANGE_BUFFER_LENGTH];
-  // positive: bytes to write to caller.  negative: bytes to READ from
-  // caller. zero: non-data command
-  int copydata=0;
-
-  const int HDIO_DRIVE_CMD_OFFSET = 4;
-
-  // See struct hd_drive_cmd_hdr in hdreg.h.  Before calling ioctl()
-  // buff[0]: ATA COMMAND CODE REGISTER
-  // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
-  // buff[2]: ATA FEATURES REGISTER
-  // buff[3]: ATA SECTOR COUNT REGISTER
-
-  // Note that on return:
-  // buff[2] contains the ATA SECTOR COUNT REGISTER
-  
-  // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
-  memset(buff, 0, STRANGE_BUFFER_LENGTH);
-
-  buff[0]=ATA_SMART_CMD;
-  switch (command){
-  case CHECK_POWER_MODE:
-    buff[0]=ATA_CHECK_POWER_MODE;
-    copydata=1;
-    break;
-  case READ_VALUES:
-    buff[2]=ATA_SMART_READ_VALUES;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case READ_THRESHOLDS:
-    buff[2]=ATA_SMART_READ_THRESHOLDS;
-    buff[1]=buff[3]=1;
-    copydata=512;
-    break;
-  case READ_LOG:
-    buff[2]=ATA_SMART_READ_LOG_SECTOR;
-    buff[1]=select;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case WRITE_LOG:
-    break;
-  case IDENTIFY:
-    buff[0]=ATA_IDENTIFY_DEVICE;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case PIDENTIFY:
-    buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
-    buff[3]=1;
-    copydata=512;
-    break;
-  case ENABLE:
-    buff[2]=ATA_SMART_ENABLE;
-    buff[1]=1;
-    break;
-  case DISABLE:
-    buff[2]=ATA_SMART_DISABLE;
-    buff[1]=1;
-    break;
-  case STATUS:
-    // this command only says if SMART is working.  It could be
-    // replaced with STATUS_CHECK below.
-    buff[2]=ATA_SMART_STATUS;
-    break;
-  case AUTO_OFFLINE:
-    buff[2]=ATA_SMART_AUTO_OFFLINE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case AUTOSAVE:
-    buff[2]=ATA_SMART_AUTOSAVE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case IMMEDIATE_OFFLINE:
-    buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
-    buff[1]=select;
-    break;
-  case STATUS_CHECK:
-    // This command uses HDIO_DRIVE_TASK and has different syntax than
-    // the other commands.
-    buff[1]=ATA_SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in linux_ata_command_interface()\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command);
-    errno=ENOSYS;
-    return -1;
-  }
-  
-  // This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
-  // only ioctl() that can be used to WRITE data to the disk.
-  if (command==WRITE_LOG) {    
-    unsigned char task[sizeof(ide_task_request_t)+512];
-    ide_task_request_t *reqtask=(ide_task_request_t *) task;
-    task_struct_t      *taskfile=(task_struct_t *) reqtask->io_ports;
-    int retval;
-
-    memset(task,      0, sizeof(task));
-    
-    taskfile->data           = 0;
-    taskfile->feature        = ATA_SMART_WRITE_LOG_SECTOR;
-    taskfile->sector_count   = 1;
-    taskfile->sector_number  = select;
-    taskfile->low_cylinder   = 0x4f;;
-    taskfile->high_cylinder  = 0xc2;
-    taskfile->device_head    = 0;
-    taskfile->command        = ATA_SMART_CMD;
-    
-    reqtask->data_phase      = TASKFILE_OUT;
-    reqtask->req_cmd         = IDE_DRIVE_TASK_OUT;
-    reqtask->out_size        = 512;
-    reqtask->in_size         = 0;
-    
-    // copy user data into the task request structure
-    memcpy(task+sizeof(ide_task_request_t), data, 512);
-      
-    if ((retval=ioctl(device, HDIO_DRIVE_TASKFILE, task))) {
-      if (retval==-EINVAL)
-	pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
-      return -1;
-    }
-    return 0;
-  }
-    
-  // There are two different types of ioctls().  The HDIO_DRIVE_TASK
-  // one is this:
-  if (command==STATUS_CHECK){
-    int retval;
-
-    // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
-    // have to read the IDE driver source code.  Sigh.
-    // buff[0]: ATA COMMAND CODE REGISTER
-    // buff[1]: ATA FEATURES REGISTER
-    // buff[2]: ATA SECTOR_COUNT
-    // buff[3]: ATA SECTOR NUMBER
-    // buff[4]: ATA CYL LO REGISTER
-    // buff[5]: ATA CYL HI REGISTER
-    // buff[6]: ATA DEVICE HEAD
-
-    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
-    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
-    buff[4]=normal_lo;
-    buff[5]=normal_hi;
-    
-    if ((retval=ioctl(device, HDIO_DRIVE_TASK, buff))) {
-      if (retval==-EINVAL) {
-	pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
-	pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
-      }
-      else
-	syserror("Error SMART Status command failed");
-      return -1;
-    }
-    
-    // Cyl low and Cyl high unchanged means "Good SMART status"
-    if (buff[4]==normal_lo && buff[5]==normal_hi)
-      return 0;
-    
-    // These values mean "Bad SMART status"
-    if (buff[4]==failed_lo && buff[5]==failed_hi)
-      return 1;
-    
-    // We haven't gotten output that makes sense; print out some debugging info
-    syserror("Error SMART Status command failed");
-    pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
-    pout("Register values returned from SMART Status command are:\n");
-    pout("CMD=0x%02x\n",(int)buff[0]);
-    pout("FR =0x%02x\n",(int)buff[1]);
-    pout("NS =0x%02x\n",(int)buff[2]);
-    pout("SC =0x%02x\n",(int)buff[3]);
-    pout("CL =0x%02x\n",(int)buff[4]);
-    pout("CH =0x%02x\n",(int)buff[5]);
-    pout("SEL=0x%02x\n",(int)buff[6]);
-    return -1;   
-  }
-  
-#if 1
-  // Note to people doing ports to other OSes -- don't worry about
-  // this block -- you can safely ignore it.  I have put it here
-  // because under linux when you do IDENTIFY DEVICE to a packet
-  // device, it generates an ugly kernel syslog error message.  This
-  // is harmless but frightens users.  So this block detects packet
-  // devices and make IDENTIFY DEVICE fail "nicely" without a syslog
-  // error message.
-  //
-  // If you read only the ATA specs, it appears as if a packet device
-  // *might* respond to the IDENTIFY DEVICE command.  This is
-  // misleading - it's because around the time that SFF-8020 was
-  // incorporated into the ATA-3/4 standard, the ATA authors were
-  // sloppy. See SFF-8020 and you will see that ATAPI devices have
-  // *always* had IDENTIFY PACKET DEVICE as a mandatory part of their
-  // command set, and return 'Command Aborted' to IDENTIFY DEVICE.
-  if (command==IDENTIFY || command==PIDENTIFY){
-    unsigned short deviceid[256];
-    // check the device identity, as seen when the system was booted
-    // or the device was FIRST registered.  This will not be current
-    // if the user has subsequently changed some of the parameters. If
-    // device is a packet device, swap the command interpretations.
-    if (!ioctl(device, HDIO_GET_IDENTITY, deviceid) && (deviceid[0] & 0x8000))
-      buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE;
-  }
-#endif
-  
-  // We are now doing the HDIO_DRIVE_CMD type ioctl.
-  if ((ioctl(device, HDIO_DRIVE_CMD, buff)))
-    return -1;
-
-  // CHECK POWER MODE command returns information in the Sector Count
-  // register (buff[3]).  Copy to return data buffer.
-  if (command==CHECK_POWER_MODE)
-    buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
-
-  // if the command returns data then copy it back
-  if (copydata)
-    memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
-  
-  return 0; 
-}
-
-// >>>>>> Start of general SCSI specific linux code
-
-/* Linux specific code.
- * Historically smartmontools (and smartsuite before it) used the
- * SCSI_IOCTL_SEND_COMMAND ioctl which is available to all linux device
- * nodes that use the SCSI subsystem. A better interface has been available
- * via the SCSI generic (sg) driver but this involves the extra step of
- * mapping disk devices (e.g. /dev/sda) to the corresponding sg device
- * (e.g. /dev/sg2). In the linux kernel 2.6 series most of the facilities of
- * the sg driver have become available via the SG_IO ioctl which is available
- * on all SCSI devices (on SCSI tape devices from lk 2.6.6).
- * So the strategy below is to find out if the SG_IO ioctl is available and
- * if so use it; failing that use the older SCSI_IOCTL_SEND_COMMAND ioctl.
- * Should work in 2.0, 2.2, 2.4 and 2.6 series linux kernels. */
-
-#define MAX_DXFER_LEN 1024      /* can be increased if necessary */
-#define SEND_IOCTL_RESP_SENSE_LEN 16    /* ioctl limitation */
-#define SG_IO_RESP_SENSE_LEN 64 /* large enough see buffer */
-#define LSCSI_DRIVER_MASK  0xf /* mask out "suggestions" */
-#define LSCSI_DRIVER_SENSE  0x8 /* alternate CHECK CONDITION indication */
-#define LSCSI_DRIVER_TIMEOUT  0x6
-#define LSCSI_DID_TIME_OUT  0x3
-#define LSCSI_DID_BUS_BUSY  0x2
-#define LSCSI_DID_NO_CONNECT  0x1
-
-#ifndef SCSI_IOCTL_SEND_COMMAND
-#define SCSI_IOCTL_SEND_COMMAND 1
-#endif
-
-#define SG_IO_PRESENT_UNKNOWN 0
-#define SG_IO_PRESENT_YES 1
-#define SG_IO_PRESENT_NO 2
-
-static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
-static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
-
-static int sg_io_state = SG_IO_PRESENT_UNKNOWN;
-
-/* Preferred implementation for issuing SCSI commands in linux. This
- * function uses the SG_IO ioctl. Return 0 if command issued successfully
- * (various status values should still be checked). If the SCSI command
- * cannot be issued then a negative errno value is returned. */
-static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-#ifndef SG_IO
-    ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report);
-    return -ENOTTY;
-#else
-    struct sg_io_hdr io_hdr;
-
-    if (report > 0) {
-        int k, j;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-        char buff[256];
-        const int sz = (int)sizeof(buff);
-
-        np = scsi_get_opcode_name(ucp[0]);
-        j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
-                          "data, len=%d%s:\n", (int)iop->dxfer_len,
-                          (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((const char *)iop->dxferp, 
-		    (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
-        pout(buff);
-    }
-    memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-    io_hdr.interface_id = 'S';
-    io_hdr.cmd_len = iop->cmnd_len;
-    io_hdr.mx_sb_len = iop->max_sense_len;
-    io_hdr.dxfer_len = iop->dxfer_len;
-    io_hdr.dxferp = iop->dxferp;
-    io_hdr.cmdp = iop->cmnd;
-    io_hdr.sbp = iop->sensep;
-    /* sg_io_hdr interface timeout has millisecond units. Timeout of 0
-       defaults to 60 seconds. */
-    io_hdr.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000;
-    switch (iop->dxfer_dir) {
-        case DXFER_NONE:
-            io_hdr.dxfer_direction = SG_DXFER_NONE;
-            break;
-        case DXFER_FROM_DEVICE:
-            io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-            break;
-        case DXFER_TO_DEVICE:
-            io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
-            break;
-        default:
-            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-            return -EINVAL;
-    }
-    iop->resp_sense_len = 0;
-    iop->scsi_status = 0;
-    iop->resid = 0;
-    if (ioctl(dev_fd, SG_IO, &io_hdr) < 0) {
-        if (report)
-            pout("  SG_IO ioctl failed, errno=%d [%s]\n", errno,
-		 strerror(errno));
-        return -errno;
-    }
-    if (report > 0) {
-        pout("  scsi_status=0x%x, host_status=0x%x, driver_status=0x%x\n"
-	     "  info=0x%x  duration=%d milliseconds\n", io_hdr.status, 
-	     io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
-	     io_hdr.duration);
-        if (report > 1) {
-            if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex((const char*)iop->dxferp, 
-		        (trunc ? 256 : iop->dxfer_len) , 1);
-            }
-        }
-    }
-    iop->resid = io_hdr.resid;
-    iop->scsi_status = io_hdr.status;
-
-    if (io_hdr.info | SG_INFO_CHECK) { /* error or warning */
-	int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
-
-	if (0 != io_hdr.host_status) {
-            if ((LSCSI_DID_NO_CONNECT == io_hdr.host_status) ||
-                (LSCSI_DID_BUS_BUSY == io_hdr.host_status) ||
-                (LSCSI_DID_TIME_OUT == io_hdr.host_status))
-                return -ETIMEDOUT;
-	    else
-		return -EIO;	/* catch all */
-        }
-        if (0 != masked_driver_status) {
-            if (LSCSI_DRIVER_TIMEOUT == masked_driver_status)
-                return -ETIMEDOUT;
-	    else
-		return -EIO;	/* catch all */
-	}
-        if (LSCSI_DRIVER_SENSE == (io_hdr.driver_status & 0xf))
-            iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-        iop->resp_sense_len = io_hdr.sb_len_wr;
-        if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && 
-            iop->sensep && (iop->resp_sense_len > 0)) {
-            if (report > 1) {
-                pout("  >>> Sense buffer, len=%d:\n",
-		     (int)iop->resp_sense_len);
-                dStrHex((const char *)iop->sensep, iop->resp_sense_len , 1);
-            }
-        }
-        if (report) {
-            if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
-                pout("  status=%x: sense_key=%x asc=%x ascq=%x\n",
-		     iop->scsi_status, iop->sensep[2] & 0xf, iop->sensep[12],
-		     iop->sensep[13]);
-            }
-            else
-                pout("  status=0x%x\n", iop->scsi_status);
-        }
-    }
-    return 0;
-#endif
-}
-
-struct linux_ioctl_send_command
-{
-    int inbufsize;
-    int outbufsize;
-    UINT8 buff[MAX_DXFER_LEN + 16];
-};
-
-/* The Linux SCSI_IOCTL_SEND_COMMAND ioctl is primitive and it doesn't 
- * support: CDB length (guesses it from opcode), resid and timeout.
- * Patches in Linux 2.4.21 and 2.5.70 to extend SEND DIAGNOSTIC timeout
- * to 2 hours in order to allow long foreground extended self tests. */
-static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-    struct linux_ioctl_send_command wrk;
-    int status, buff_offset;
-    size_t len;
-
-    memcpy(wrk.buff, iop->cmnd, iop->cmnd_len);
-    buff_offset = iop->cmnd_len;
-    if (report > 0) {
-        int k, j;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-        char buff[256];
-        const int sz = (int)sizeof(buff);
-
-        np = scsi_get_opcode_name(ucp[0]);
-        j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
-                          "data, len=%d%s:\n", (int)iop->dxfer_len,
-                          (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((const char *)iop->dxferp, 
-		    (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
-        pout(buff);
-    }
-    switch (iop->dxfer_dir) {
-        case DXFER_NONE:
-            wrk.inbufsize = 0;
-            wrk.outbufsize = 0;
-            break;
-        case DXFER_FROM_DEVICE:
-            wrk.inbufsize = 0;
-            if (iop->dxfer_len > MAX_DXFER_LEN)
-                return -EINVAL;
-            wrk.outbufsize = iop->dxfer_len;
-            break;
-        case DXFER_TO_DEVICE:
-            if (iop->dxfer_len > MAX_DXFER_LEN)
-                return -EINVAL;
-            memcpy(wrk.buff + buff_offset, iop->dxferp, iop->dxfer_len);
-            wrk.inbufsize = iop->dxfer_len;
-            wrk.outbufsize = 0;
-            break;
-        default:
-            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-            return -EINVAL;
-    }
-    iop->resp_sense_len = 0;
-    iop->scsi_status = 0;
-    iop->resid = 0;
-    status = ioctl(dev_fd, SCSI_IOCTL_SEND_COMMAND, &wrk);
-    if (-1 == status) {
-        if (report)
-            pout("  SCSI_IOCTL_SEND_COMMAND ioctl failed, errno=%d [%s]\n",
-                 errno, strerror(errno));
-        return -errno;
-    }
-    if (0 == status) {
-        if (report > 0)
-            pout("  status=0\n");
-        if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-            memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
-            if (report > 1) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex((const char*)iop->dxferp, 
-			(trunc ? 256 : iop->dxfer_len) , 1);
-            }
-        }
-        return 0;
-    }
-    iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
-    if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
-        iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-    len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
-                SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
-    if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && 
-        iop->sensep && (len > 0)) {
-        memcpy(iop->sensep, wrk.buff, len);
-        iop->resp_sense_len = len;
-        if (report > 1) {
-            pout("  >>> Sense buffer, len=%d:\n", (int)len);
-            dStrHex((const char *)wrk.buff, len , 1);
-        }
-    }
-    if (report) {
-        if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
-            pout("  status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
-                 wrk.buff[2] & 0xf, wrk.buff[12], wrk.buff[13]);
-        }
-        else
-            pout("  status=0x%x\n", status);
-    }
-    if (iop->scsi_status > 0)
-        return 0;
-    else {
-        if (report > 0)
-            pout("  ioctl status=0x%x but scsi status=0, fail with EIO\n", 
-                 status);
-        return -EIO;      /* give up, assume no device there */
-    }
-}
-
-/* SCSI command transmission interface function, linux version.
- * Returns 0 if SCSI command successfully launched and response
- * received. Even when 0 is returned the caller should check 
- * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
- * (e.g. CHECK CONDITION). If the SCSI command could not be issued
- * (e.g. device not present or timeout) or some other problem
- * (e.g. timeout) then returns a negative errno value */
-int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-    int res;
-
-    /* implementation relies on static sg_io_state variable. If not
-     * previously set tries the SG_IO ioctl. If that succeeds assume
-     * that SG_IO ioctl functional. If it fails with an errno value
-     * other than ENODEV (no device) or permission then assume 
-     * SCSI_IOCTL_SEND_COMMAND is the only option. */
-    switch (sg_io_state) {
-    case SG_IO_PRESENT_UNKNOWN:
-        /* ignore report argument */
-	if (0 == (res = sg_io_cmnd_io(dev_fd, iop, 0))) {
-	    sg_io_state = SG_IO_PRESENT_YES;
-	    return 0;
-	} else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
-	    return res;		/* wait until we see a device */
-        sg_io_state = SG_IO_PRESENT_NO;
-	/* drop through by design */
-    case SG_IO_PRESENT_NO:
-	return sisc_cmnd_io(dev_fd, iop, report);
-    case SG_IO_PRESENT_YES:
-	return sg_io_cmnd_io(dev_fd, iop, report);
-    default:
-	pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state); 
-	sg_io_state = SG_IO_PRESENT_UNKNOWN;
-        return -EIO; 	/* report error and reset state */
-    }
-}
-
-// >>>>>> End of general SCSI specific linux code
-
-
-// prototype
-void printwarning(smart_command_set command);
-
-// PURPOSE
-//   This is an interface routine meant to isolate the OS dependent
-//   parts of the code, and to provide a debugging interface.  Each
-//   different port and OS needs to provide it's own interface.  This
-//   is the linux interface to the 3ware 3w-xxxx driver.  It allows ATA
-//   commands to be passed through the SCSI driver.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   fd: is the file descriptor provided by open()
-//   disknum is the disk number (0 to 15) in the RAID array
-//   escalade_type indicates the type of controller type, and if scsi or char interface is used
-//   command: defines the different operations.
-//   select: additional input data if needed (which log, which type of
-//           self-test).
-//   data:   location to write output data, if needed (512 bytes).
-//   Note: not all commands use all arguments.
-// RETURN VALUES
-//  -1 if the command failed
-//   0 if the command succeeded,
-//   STATUS_CHECK routine: 
-//  -1 if the command failed
-//   0 if the command succeeded and disk SMART status is "OK"
-//   1 if the command succeeded and disk SMART status is "FAILING"
-
-
-/* 512 is the max payload size: increase if needed */
-#define BUFFER_LEN_678K      ( sizeof(TW_Ioctl)                  ) // 1044 unpacked, 1041 packed
-#define BUFFER_LEN_678K_CHAR ( sizeof(TW_New_Ioctl)+512-1        ) // 1539 unpacked, 1536 packed
-#define BUFFER_LEN_9000      ( sizeof(TW_Ioctl_Buf_Apache)+512-1 ) // 2051 unpacked, 2048 packed
-#define TW_IOCTL_BUFFER_SIZE ( MAX(MAX(BUFFER_LEN_678K, BUFFER_LEN_9000), BUFFER_LEN_678K_CHAR) )
-
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-
-  // return value and buffer for ioctl()
-  int  ioctlreturn, readdata=0;
-
-  // Used by both the SCSI and char interfaces
-  TW_Passthru *passthru=NULL;
-  char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
-
-  // only used for SCSI device interface
-  TW_Ioctl   *tw_ioctl=NULL;
-  TW_Output *tw_output=NULL;
-
-  // only used for 6000/7000/8000 char device interface
-  TW_New_Ioctl *tw_ioctl_char=NULL;
-
-  // only used for 9000 character device interface
-  TW_Ioctl_Buf_Apache *tw_ioctl_apache=NULL;
-  
-  memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
-
-  if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
-    tw_ioctl_apache                               = (TW_Ioctl_Buf_Apache *)ioctl_buffer;
-    tw_ioctl_apache->driver_command.control_code  = TW_IOCTL_FIRMWARE_PASS_THROUGH;
-    tw_ioctl_apache->driver_command.buffer_length = 512; /* payload size */
-    passthru                                      = (TW_Passthru *)&(tw_ioctl_apache->firmware_command.command.oldcommand);
-  }
-  else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
-    tw_ioctl_char                                 = (TW_New_Ioctl *)ioctl_buffer;
-    tw_ioctl_char->data_buffer_length             = 512;
-    passthru                                      = (TW_Passthru *)&(tw_ioctl_char->firmware_command);
-  }
-  else if (escalade_type==CONTROLLER_3WARE_678K) {
-    tw_ioctl                                      = (TW_Ioctl *)ioctl_buffer;
-    tw_ioctl->cdb[0]                              = TW_IOCTL;
-    tw_ioctl->opcode                              = TW_ATA_PASSTHRU;
-    tw_ioctl->input_length                        = 512; // correct even for non-data commands
-    tw_ioctl->output_length                       = 512; // correct even for non-data commands
-    tw_output                                     = (TW_Output *)tw_ioctl;
-    passthru                                      = (TW_Passthru *)&(tw_ioctl->input_data);
-  }
-  else {
-    pout("Unrecognized escalade_type %d in linux_3ware_command_interface(disk %d)\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  // Same for (almost) all commands - but some reset below
-  passthru->byte0.opcode  = TW_OP_ATA_PASSTHRU;
-  passthru->request_id    = 0xFF;
-  passthru->byte3.aport   = disknum;
-  passthru->byte3.host_id = 0;
-  passthru->status        = 0;           
-  passthru->flags         = 0x1;
-  passthru->drive_head    = 0x0;
-  passthru->sector_num    = 0;
-
-  // All SMART commands use this CL/CH signature.  These are magic
-  // values from the ATA specifications.
-  passthru->cylinder_lo   = 0x4F;
-  passthru->cylinder_hi   = 0xC2;
-  
-  // SMART ATA COMMAND REGISTER value
-  passthru->command       = ATA_SMART_CMD;
-  
-  // Is this a command that reads or returns 512 bytes?
-  // passthru->param values are:
-  // 0x0 - non data command without TFR write check,
-  // 0x8 - non data command with TFR write check,
-  // 0xD - data command that returns data to host from device
-  // 0xF - data command that writes data from host to device
-  // passthru->size values are 0x5 for non-data and 0x07 for data
-  if (command == READ_VALUES     ||
-      command == READ_THRESHOLDS ||
-      command == READ_LOG        ||
-      command == IDENTIFY        ||
-      command == WRITE_LOG ) {
-    readdata=1;
-    passthru->byte0.sgloff = 0x5;
-    passthru->size         = 0x7;
-    passthru->param        = 0xD;
-    passthru->sector_count = 0x1;
-    // For 64-bit to work correctly, up the size of the command packet
-    // in dwords by 1 to account for the 64-bit single sgl 'address'
-    // field. Note that this doesn't agree with the typedefs but it's
-    // right (agree with kernel driver behavior/typedefs).
-    if (escalade_type==CONTROLLER_3WARE_9000_CHAR && sizeof(long)==8)
-      passthru->size++;
-  }
-  else {
-    // Non data command -- but doesn't use large sector 
-    // count register values.  
-    passthru->byte0.sgloff = 0x0;
-    passthru->size         = 0x5;
-    passthru->param        = 0x8;
-    passthru->sector_count = 0x0;
-  }
-  
-  // Now set ATA registers depending upon command
-  switch (command){
-  case CHECK_POWER_MODE:
-    passthru->command     = ATA_CHECK_POWER_MODE;
-    passthru->features    = 0;
-    passthru->cylinder_lo = 0;
-    passthru->cylinder_hi = 0;
-    break;
-  case READ_VALUES:
-    passthru->features = ATA_SMART_READ_VALUES;
-    break;
-  case READ_THRESHOLDS:
-    passthru->features = ATA_SMART_READ_THRESHOLDS;
-    break;
-  case READ_LOG:
-    passthru->features = ATA_SMART_READ_LOG_SECTOR;
-    // log number to return
-    passthru->sector_num  = select;
-    break;
-  case WRITE_LOG:
-    if (escalade_type == CONTROLLER_3WARE_9000_CHAR)
-      memcpy((unsigned char *)tw_ioctl_apache->data_buffer, data, 512);
-    else if (escalade_type == CONTROLLER_3WARE_678K_CHAR)
-      memcpy((unsigned char *)tw_ioctl_char->data_buffer,   data, 512);
-    else {
-      // COMMAND NOT SUPPORTED VIA SCSI IOCTL INTERFACE
-      // memcpy(tw_output->output_data, data, 512);
-      printwarning(command);
-      errno=ENOTSUP;
-      return -1;
-    }
-    readdata=0;
-    passthru->features     = ATA_SMART_WRITE_LOG_SECTOR;
-    passthru->sector_count = 1;
-    passthru->sector_num   = select;
-    passthru->param        = 0xF;  // PIO data write
-    break;
-  case IDENTIFY:
-    // ATA IDENTIFY DEVICE
-    passthru->command     = ATA_IDENTIFY_DEVICE;
-    passthru->features    = 0;
-    passthru->cylinder_lo = 0;
-    passthru->cylinder_hi = 0;
-    break;
-  case PIDENTIFY:
-    // 3WARE controller can NOT have packet device internally
-    pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
-    errno=ENODEV;
-    return -1;
-  case ENABLE:
-    passthru->features = ATA_SMART_ENABLE;
-    break;
-  case DISABLE:
-    passthru->features = ATA_SMART_DISABLE;
-    break;
-  case AUTO_OFFLINE:
-    passthru->features     = ATA_SMART_AUTO_OFFLINE;
-    // Enable or disable?
-    passthru->sector_count = select;
-    break;
-  case AUTOSAVE:
-    passthru->features     = ATA_SMART_AUTOSAVE;
-    // Enable or disable?
-    passthru->sector_count = select;
-    break;
-  case IMMEDIATE_OFFLINE:
-    passthru->features    = ATA_SMART_IMMEDIATE_OFFLINE;
-    // What test type to run?
-    passthru->sector_num  = select;
-    break;
-  case STATUS_CHECK:
-    passthru->features = ATA_SMART_STATUS;
-    break;
-  case STATUS:
-    // This is JUST to see if SMART is enabled, by giving SMART status
-    // command. But it doesn't say if status was good, or failing.
-    // See below for the difference.
-    passthru->features = ATA_SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in linux_3ware_command_interface(disk %d)\n"
-         "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  // Now send the command down through an ioctl()
-  if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
-    ioctlreturn=ioctl(fd, TW_IOCTL_FIRMWARE_PASS_THROUGH, tw_ioctl_apache);
-  else if (escalade_type==CONTROLLER_3WARE_678K_CHAR)
-    ioctlreturn=ioctl(fd, TW_CMD_PACKET_WITH_DATA, tw_ioctl_char);
-  else
-    ioctlreturn=ioctl(fd, SCSI_IOCTL_SEND_COMMAND, tw_ioctl);
-  
-  // Deal with the different error cases
-  if (ioctlreturn) {
-    if (CONTROLLER_3WARE_678K==escalade_type && ((command==AUTO_OFFLINE || command==AUTOSAVE) && select)){
-      // error here is probably a kernel driver whose version is too old
-      printwarning(command);
-      errno=ENOTSUP;
-    }
-    if (!errno)
-      errno=EIO;
-    return -1;
-  }
-  
-  // The passthru structure is valid after return from an ioctl if:
-  // - we are using the character interface OR 
-  // - we are using the SCSI interface and this is a NON-READ-DATA command
-  // For SCSI interface, note that we set passthru to a different
-  // value after ioctl().
-  if (CONTROLLER_3WARE_678K==escalade_type) {
-    if (readdata)
-      passthru=NULL;
-    else
-      passthru=(TW_Passthru *)&(tw_output->output_data);
-  }
-
-  // See if the ATA command failed.  Now that we have returned from
-  // the ioctl() call, if passthru is valid, then:
-  // - passthru->status contains the 3ware controller STATUS
-  // - passthru->command contains the ATA STATUS register
-  // - passthru->features contains the ATA ERROR register
-  //
-  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
-  // If bit 0 (error bit) is set, then ATA ERROR register is valid.
-  // While we *might* decode the ATA ERROR register, at the moment it
-  // doesn't make much sense: we don't care in detail why the error
-  // happened.
-  
-  if (passthru && (passthru->status || (passthru->command & 0x21))) {
-    errno=EIO;
-    return -1;
-  }
-  
-  // If this is a read data command, copy data to output buffer
-  if (readdata) {
-    if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
-      memcpy(data, (unsigned char *)tw_ioctl_apache->data_buffer, 512);
-    else if (escalade_type==CONTROLLER_3WARE_678K_CHAR)
-      memcpy(data, (unsigned char *)tw_ioctl_char->data_buffer, 512);
-    else
-      memcpy(data, tw_output->output_data, 512);
-  }
-
-  // For STATUS_CHECK, we need to check register values
-  if (command==STATUS_CHECK) {
-    
-    // To find out if the SMART RETURN STATUS is good or failing, we
-    // need to examine the values of the Cylinder Low and Cylinder
-    // High Registers.
-    
-    unsigned short cyl_lo=passthru->cylinder_lo;
-    unsigned short cyl_hi=passthru->cylinder_hi;
-    
-    // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
-    if (cyl_lo==0x4F && cyl_hi==0xC2)
-      return 0;
-    
-    // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
-    if (cyl_lo==0xF4 && cyl_hi==0x2C)
-      return 1;
-    
-    // Any other values mean that something has gone wrong with the command
-    if (CONTROLLER_3WARE_678K==escalade_type) {
-      printwarning(command);
-      errno=ENOSYS;
-      return 0;
-    }
-    else {
-      errno=EIO;
-      return -1;
-    }
-  }
-  
-  // copy sector count register (one byte!) to return data
-  if (command==CHECK_POWER_MODE)
-    *data=*(char *)&(passthru->sector_count);
-  
-  // look for nonexistent devices/ports
-  if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
-    errno=ENODEV;
-    return -1;
-  }
-  
-  return 0;
-}
-
-// Utility function for printing warnings
-void printwarning(smart_command_set command){
-  static int printed[4]={0,0,0,0};
-  const char* message=
-    "can not be passed through the 3ware 3w-xxxx driver.  This can be fixed by\n"
-    "applying a simple 3w-xxxx driver patch that can be found here:\n"
-    PACKAGE_HOMEPAGE "\n"
-    "Alternatively, upgrade your 3w-xxxx driver to version 1.02.00.037 or greater.\n\n";
-
-  if (command==AUTO_OFFLINE && !printed[0]) {
-    printed[0]=1;
-    pout("The SMART AUTO-OFFLINE ENABLE command (smartmontools -o on option/Directive)\n%s", message);
-  } 
-  else if (command==AUTOSAVE && !printed[1]) {
-    printed[1]=1;
-    pout("The SMART AUTOSAVE ENABLE command (smartmontools -S on option/Directive)\n%s", message);
-  }
-  else if (command==STATUS_CHECK && !printed[2]) {
-    printed[2]=1;
-    pout("The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n%s", message);
-  }
-  else if (command==WRITE_LOG && !printed[3])  {
-    printed[3]=1;
-    pout("The SMART WRITE LOG command (smartmontools -t selective) only supported via char /dev/tw[ae] interface\n");
-  }
-  
-  return;
-}
-
-// Guess device type (ata or scsi) based on device name (Linux
-// specific) SCSI device name in linux can be sd, sr, scd, st, nst,
-// osst, nosst and sg.
-static const char * lin_dev_prefix = "/dev/";
-static const char * lin_dev_ata_disk_plus = "h";
-static const char * lin_dev_ata_devfs_disk_plus = "ide/";
-static const char * lin_dev_scsi_devfs_disk_plus = "scsi/";
-static const char * lin_dev_scsi_disk_plus = "s";
-static const char * lin_dev_scsi_tape1 = "ns";
-static const char * lin_dev_scsi_tape2 = "os";
-static const char * lin_dev_scsi_tape3 = "nos";
-static const char * lin_dev_3ware_9000_char = "twa";
-static const char * lin_dev_3ware_678k_char = "twe";
-
-int guess_device_type(const char * dev_name) {
-  int len;
-  int dev_prefix_len = strlen(lin_dev_prefix);
-  
-  // if dev_name null, or string length zero
-  if (!dev_name || !(len = strlen(dev_name)))
-    return CONTROLLER_UNKNOWN;
-  
-  // Remove the leading /dev/... if it's there
-  if (!strncmp(lin_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len)
-      // if nothing else in the string, unrecognized
-      return CONTROLLER_UNKNOWN;
-    // else advance pointer to following characters
-    dev_name += dev_prefix_len;
-  }
-  
-  // form /dev/h* or h*
-  if (!strncmp(lin_dev_ata_disk_plus, dev_name,
-               strlen(lin_dev_ata_disk_plus)))
-    return CONTROLLER_ATA;
-  
-  // form /dev/ide/* or ide/*
-  if (!strncmp(lin_dev_ata_devfs_disk_plus, dev_name,
-               strlen(lin_dev_ata_devfs_disk_plus)))
-    return CONTROLLER_ATA;
-
-  // form /dev/s* or s*
-  if (!strncmp(lin_dev_scsi_disk_plus, dev_name,
-               strlen(lin_dev_scsi_disk_plus)))
-    return CONTROLLER_SCSI;
-
-  // form /dev/scsi/* or scsi/*
-  if (!strncmp(lin_dev_scsi_devfs_disk_plus, dev_name,
-               strlen(lin_dev_scsi_devfs_disk_plus)))
-    return CONTROLLER_SCSI;
-  
-  // form /dev/ns* or ns*
-  if (!strncmp(lin_dev_scsi_tape1, dev_name,
-               strlen(lin_dev_scsi_tape1)))
-    return CONTROLLER_SCSI;
-  
-  // form /dev/os* or os*
-  if (!strncmp(lin_dev_scsi_tape2, dev_name,
-               strlen(lin_dev_scsi_tape2)))
-    return CONTROLLER_SCSI;
-  
-  // form /dev/nos* or nos*
-  if (!strncmp(lin_dev_scsi_tape3, dev_name,
-               strlen(lin_dev_scsi_tape3)))
-    return CONTROLLER_SCSI;
-
-  // form /dev/twa*
-  if (!strncmp(lin_dev_3ware_9000_char, dev_name,
-               strlen(lin_dev_3ware_9000_char)))
-    return CONTROLLER_3WARE_9000_CHAR;
-
-  // form /dev/twe*
-  if (!strncmp(lin_dev_3ware_678k_char, dev_name,
-               strlen(lin_dev_3ware_678k_char)))
-    return CONTROLLER_3WARE_678K_CHAR;
-
-  // we failed to recognize any of the forms
-  return CONTROLLER_UNKNOWN;
-}
-
-
-#if 0
-
-[ed@firestorm ed]$ ls -l  /dev/discs
-total 0
-lr-xr-xr-x    1 root     root           30 Dec 31  1969 disc0 -> ../ide/host2/bus0/target0/lun0/
-lr-xr-xr-x    1 root     root           30 Dec 31  1969 disc1 -> ../ide/host2/bus1/target0/lun0/
-[ed@firestorm ed]$ ls -l  dev/ide/host*/bus*/target*/lun*/disc
-ls: dev/ide/host*/bus*/target*/lun*/disc: No such file or directory
-[ed@firestorm ed]$ ls -l  /dev/ide/host*/bus*/target*/lun*/disc
-brw-------    1 root     root      33,   0 Dec 31  1969 /dev/ide/host2/bus0/target0/lun0/disc
-brw-------    1 root     root      34,   0 Dec 31  1969 /dev/ide/host2/bus1/target0/lun0/disc
-[ed@firestorm ed]$ ls -l  /dev/ide/c*b*t*u*
-ls: /dev/ide/c*b*t*u*: No such file or directory
-[ed@firestorm ed]$ 
-Script done on Fri Nov  7 13:46:28 2003
-
-#endif
diff --git a/sm5/os_linux.h b/sm5/os_linux.h
deleted file mode 100644
index 24c5e92df7816f2f66c2f571ff1985ac854964c0..0000000000000000000000000000000000000000
--- a/sm5/os_linux.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/* 
- *  os_linux.h
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- *
- * Derived from code that was
- *
- *  Written By: Adam Radford <linux@3ware.com>
- *  Modifications By: Joel Jacobson <linux@3ware.com>
- *                   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *                    Brad Strand <linux@3ware.com>
- *
- *  Copyright (C) 1999-2003 3ware Inc.
- *
- *  Kernel compatablity By:     Andre Hedrick <andre@suse.com>
- *  Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
- *
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- * 
- */
-
-
-#ifndef OS_LINUX_H_
-#define OS_LINUX_H_
-
-#define OS_XXXX_H_CVSID "$Id: os_linux.h,v 1.21 2004/08/16 22:44:27 ballen4705 Exp $\n"
-
-/* 
-   The following definitions/macros/prototypes are used for three
-   different interfaces, referred to as "the three cases" below.
-   CONTROLLER_3WARE_678K      -- 6000, 7000, and 8000 controllers via /dev/sd?
-   CONTROLLER_3WARE_678K_CHAR -- 6000, 7000, and 8000 controllers via /dev/twe?
-   CONTROLLER_3WARE_9000_CHAR -- 9000 controllers via /dev/twa?
-*/
-
-// USED FOR ALL THREE CASES
-
-#define u32 unsigned int
-#define TW_OP_ATA_PASSTHRU 0x11
-#define MAX(x,y) ( (x)>(y)?(x):(y) )
-
-#pragma pack(1)
-/* Scatter gather list entry */
-typedef struct TAG_TW_SG_Entry {
-  unsigned int address;
-  unsigned int length;
-} TW_SG_Entry;
-
-/* Command header for ATA pass-thru.  Note that for different
-   drivers/interfaces the length of sg_list (here TW_ATA_PASS_SGL_MAX)
-   is different.  But it can be taken as same for all three cases
-   because it's never used to define any other structures, and we
-   never use anything in the sg_list or beyond! */
-
-#define TW_ATA_PASS_SGL_MAX      60
-
-typedef struct TAG_TW_Passthru {
-  struct {
-    unsigned char opcode:5;
-    unsigned char sgloff:3;
-  } byte0;
-  unsigned char size;
-  unsigned char request_id;
-  struct { 
-    unsigned char aport:4;
-    unsigned char host_id:4;
-  } byte3;
-  unsigned char status;  // On return, contains 3ware STATUS register
-  unsigned char flags;
-  unsigned short param;
-  unsigned short features;  // On return, contains ATA ERROR register
-  unsigned short sector_count;
-  unsigned short sector_num;
-  unsigned short cylinder_lo;
-  unsigned short cylinder_hi;
-  unsigned char drive_head;
-  unsigned char command; // On return, contains ATA STATUS register
-  TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX];
-  unsigned char padding[12];
-} TW_Passthru;
-
-// the following are for the SCSI interface only 
-
-// Ioctl buffer: Note that this defn has changed in kernel tree...
-// Total size is 1041 bytes -- this is really weird
-
-#define TW_IOCTL                 0x80
-#define TW_ATA_PASSTHRU          0x1e
-
-// Adam -- should this be #pramga packed? Otherwise table_id gets
-// moved for byte alignment.  Without packing, input passthru for SCSI
-// ioctl is 31 bytes in.  With packing it is 30 bytes in.
-typedef struct TAG_TW_Ioctl { 
-  int input_length;
-  int output_length;
-  unsigned char cdb[16];
-  unsigned char opcode;
-  // This one byte of padding is missing from the typedefs in the
-  // kernel code, but it is indeed present.  We put it explicitly
-  // here, so that the structure can be packed.  Adam agrees with
-  // this.
-  unsigned char packing;
-  unsigned short table_id;
-  unsigned char parameter_id;
-  unsigned char parameter_size_bytes;
-  unsigned char unit_index;
-  // Size up to here is 30 bytes + 1 padding!
-  unsigned char input_data[499];
-  // Reserve lots of extra space for commands that set Sector Count
-  // register to large values
-  unsigned char output_data[512]; // starts 530 bytes in!
-  // two more padding bytes here if structure NOT packed.
-} TW_Ioctl;
-
-/* Ioctl buffer output -- SCSI interface only! */
-typedef struct TAG_TW_Output {
-  int padding[2];
-  char output_data[512];
-} TW_Output; 
-
-// What follows is needed for 9000 char interface only
-
-#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
-#define TW_MAX_SGL_LENGTH_9000 61
-
-typedef struct TAG_TW_Ioctl_Driver_Command_9000 {
-  unsigned int control_code;
-  unsigned int status;
-  unsigned int unique_id;
-  unsigned int sequence_id;
-  unsigned int os_specific;
-  unsigned int buffer_length;
-} TW_Ioctl_Driver_Command_9000;
-
-/* Command Packet */
-typedef struct TW_Command_9000 {
-  /* First DWORD */
-  struct {
-    unsigned char opcode:5;
-    unsigned char sgl_offset:3;
-  } byte0;
-  unsigned char size;
-  unsigned char request_id;
-  struct {
-    unsigned char unit:4;
-    unsigned char host_id:4;
-  } byte3;
-  /* Second DWORD */
-  unsigned char status;
-  unsigned char flags;
-  union {
-    unsigned short block_count;
-    unsigned short parameter_count;
-    unsigned short message_credits;
-  } byte6;
-  union {
-    struct {
-      u32 lba;
-      TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
-      u32 padding;
-    } io;
-    struct {
-      TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
-      u32 padding[2];
-    } param;
-    struct {
-      u32 response_queue_pointer;
-      u32 padding[125]; /* pad entire structure to 512 bytes */
-    } init_connection;
-    struct {
-      char version[504];
-    } ioctl_miniport_version;
-  } byte8;
-} TW_Command_9000;
-
-/* Command Packet for 9000+ controllers */
-typedef struct TAG_TW_Command_Apache {
-  struct {
-    unsigned char opcode:5;
-    unsigned char reserved:3;
-  } command;
-  unsigned char   unit;
-  unsigned short  request_id;
-  unsigned char   sense_length;
-  unsigned char   sgl_offset;
-  unsigned short  sgl_entries;
-  unsigned char   cdb[16];
-  TW_SG_Entry     sg_list[TW_MAX_SGL_LENGTH_9000];
-} TW_Command_Apache;
-
-/* New command packet header */
-typedef struct TAG_TW_Command_Apache_Header {
-  unsigned char sense_data[18];
-  struct {
-    char reserved[4];
-    unsigned short error;
-    unsigned char status;
-    struct {
-      unsigned char severity:3;
-      unsigned char reserved:5;
-    } substatus_block;
-  } status_block;
-  unsigned char err_specific_desc[102];
-} TW_Command_Apache_Header;
-
-/* This struct is a union of the 2 command packets */
-typedef struct TAG_TW_Command_Full_9000 {
-  TW_Command_Apache_Header header;
-  union {
-    TW_Command_9000   oldcommand;
-    TW_Command_Apache newcommand;
-  } command;
-  unsigned char padding[384]; /* Pad to 1024 bytes */
-} TW_Command_Full_9000;
-
-typedef struct TAG_TW_Ioctl_Apache {
-  TW_Ioctl_Driver_Command_9000 driver_command;
-  char                         padding[488];
-  TW_Command_Full_9000         firmware_command;
-  char                         data_buffer[1];
-  // three bytes of padding here if structure not packed!
-} TW_Ioctl_Buf_Apache;
-
-
-
-// START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE
-// 6000/7000/8000 drivers
-
-#define TW_MAX_SGL_LENGTH        62
-#define TW_CMD_PACKET_WITH_DATA 0x1f
-
-/* Command Packet */
-typedef struct TW_Command {
-  /* First DWORD */
-  struct {
-    unsigned char opcode:5;
-    unsigned char sgl_offset:3;
-  } byte0;
-  unsigned char size;
-  unsigned char request_id;
-  struct {
-    unsigned char unit:4;
-    unsigned char host_id:4;
-  } byte3;
-  /* Second DWORD */
-  unsigned char status;
-  unsigned char flags;
-  union {
-    unsigned short block_count;
-    unsigned short parameter_count;
-    unsigned short message_credits;
-  } byte6;
-  union {
-    struct {
-      u32 lba;
-      TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
-      u32 padding;	/* pad to 512 bytes */
-    } io;
-    struct {
-      TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
-      u32 padding[2];
-    } param;
-    struct {
-      u32 response_queue_pointer;
-      u32 padding[125];
-    } init_connection;
-    struct {
-      char version[504];
-    } ioctl_miniport_version;
-  } byte8;
-} TW_Command;
-
-typedef struct TAG_TW_New_Ioctl {
-  unsigned int  data_buffer_length;
-  unsigned char padding [508];
-  TW_Command    firmware_command;
-  char          data_buffer[1];
-  // three bytes of padding here
-} TW_New_Ioctl;
-#pragma pack()
-
-#if 0
-// Useful for checking/understanding packing of 3ware data structures
-// above.
-void my(int x, char *y){
-  printf("The size of %30s is: %5d\n",y, x);
-  return;
-}
-
-int main() {
-  TW_Ioctl tmp;
-  my(sizeof(TW_SG_Entry),"TW_SG_Entry");
-  my(sizeof(TW_Passthru),"TW_Passthru");
-  my(sizeof(TW_Ioctl),"TW_Ioctl");
-  my(sizeof(TW_Output),"TW_Output");
-  my(sizeof(TW_Ioctl_Driver_Command_9000),"TW_Ioctl_Driver_Command_9000");
-  my(sizeof(TW_Command_9000),"TW_Command_9000");
-  my(sizeof(TW_Command_Apache),"TW_Command_Apache");
-  my(sizeof(TW_Command_Apache_Header),"TW_Command_Apache_Header");
-  my(sizeof(TW_Command_Full_9000),"TW_Command_Full_9000");
-  my(sizeof(TW_Ioctl_Buf_Apache),"TW_Ioctl_Buf_Apache");
-  my(sizeof(TW_Command),"TW_Command");
-  my(sizeof(TW_New_Ioctl),"TW_New_Ioctl");                                                                
-  printf("TW_Ioctl.table_id - start = %d (irrelevant)\n",
-         (void *)&tmp.table_id - (void *)&tmp);
-  printf("TW_Ioctl.input_data - start = %d (input passthru location)\n",
-         (void *)&tmp.input_data - (void *)&tmp);
-  printf("TW_Ioctl.output_data - start = %d (irrelevant)\n",
-         (void *)&tmp.output_data - (void *)&tmp);
-  return 0;
-}
-#endif
-
-// The following definitions are from hdreg.h in the kernel source
-// tree.  They don't carry any Copyright statements, but I think they
-// are primarily from Mark Lord and Andre Hedrick.
-typedef unsigned char task_ioreg_t;
-
-typedef struct hd_drive_task_hdr {
-  task_ioreg_t data;
-  task_ioreg_t feature;
-  task_ioreg_t sector_count;
-  task_ioreg_t sector_number;
-  task_ioreg_t low_cylinder;
-  task_ioreg_t high_cylinder;
-  task_ioreg_t device_head;
-  task_ioreg_t command;
-} task_struct_t;
-
-typedef union ide_reg_valid_s {
-  unsigned all			: 16;
-  struct {
-    unsigned data		: 1;
-    unsigned error_feature	: 1;
-    unsigned sector		: 1;
-    unsigned nsector		: 1;
-    unsigned lcyl		: 1;
-    unsigned hcyl		: 1;
-    unsigned select		: 1;
-    unsigned status_command	: 1;
-    unsigned data_hob		: 1;
-    unsigned error_feature_hob	: 1;
-    unsigned sector_hob		: 1;
-    unsigned nsector_hob	: 1;
-    unsigned lcyl_hob		: 1;
-    unsigned hcyl_hob		: 1;
-    unsigned select_hob		: 1;
-    unsigned control_hob	: 1;
-  } b;
-} ide_reg_valid_t;
-
-typedef struct ide_task_request_s {
-  task_ioreg_t	   io_ports[8];
-  task_ioreg_t	   hob_ports[8];
-  ide_reg_valid_t  out_flags;
-  ide_reg_valid_t  in_flags;
-  int		   data_phase;
-  int		   req_cmd;
-  unsigned long	   out_size;
-  unsigned long	   in_size;
-} ide_task_request_t;
-
-#define TASKFILE_NO_DATA	  0x0000
-#define TASKFILE_IN		  0x0001
-#define TASKFILE_OUT		  0x0004
-#define HDIO_DRIVE_TASK_HDR_SIZE  8*sizeof(task_ioreg_t)
-#define IDE_DRIVE_TASK_NO_DATA	       0
-#define IDE_DRIVE_TASK_IN	       2
-#define IDE_DRIVE_TASK_OUT	       3
-#define HDIO_DRIVE_CMD            0x031f
-#define HDIO_DRIVE_TASK           0x031e
-#define HDIO_DRIVE_TASKFILE       0x031d
-#define HDIO_GET_IDENTITY         0x030d
-
-#endif /* OS_LINUX_H_ */
diff --git a/sm5/os_netbsd.c b/sm5/os_netbsd.c
deleted file mode 100644
index 0b4cf959fdc561da07d4b4d7efb6333a8dac5d82..0000000000000000000000000000000000000000
--- a/sm5/os_netbsd.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * os_netbsd.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Sergey Svishchev <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-#include "os_netbsd.h"
-
-const char *os_XXXX_c_cvsid = "$Id: os_netbsd.c,v 1.8 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID OS_NETBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-/* global variable holding byte count of allocated memory */
-extern long long bytes;
-
-enum warnings {
-  BAD_SMART, NO_3WARE, MAX_MSG
-};
-
-/* Utility function for printing warnings */
-void
-printwarning(int msgNo, const char *extra)
-{
-  static int printed[] = {0, 0};
-  static const char *message[] = {
-    "Error: SMART Status command failed.\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
-    PACKAGE_STRING " does not currentlly support twe(4) devices (3ware Escalade)\n",
-  };
-
-  if (msgNo >= 0 && msgNo <= MAX_MSG) {
-    if (!printed[msgNo]) {
-      printed[msgNo] = 1;
-      pout("%s", message[msgNo]);
-      if (extra)
-	pout("%s", extra);
-    }
-  }
-  return;
-}
-
-static const char *net_dev_prefix = "/dev/";
-static const char *net_dev_ata_disk = "wd";
-static const char *net_dev_scsi_disk = "sd";
-static const char *net_dev_scsi_tape = "enrst";
-
-/* Guess device type(ata or scsi) based on device name */
-int
-guess_device_type(const char *dev_name)
-{
-  int len;
-  int dev_prefix_len = strlen(net_dev_prefix);
-
-  if (!dev_name || !(len = strlen(dev_name)))
-    return CONTROLLER_UNKNOWN;
-
-  if (!strncmp(net_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len)
-      return CONTROLLER_UNKNOWN;
-    else
-      dev_name += dev_prefix_len;
-  }
-  if (!strncmp(net_dev_ata_disk, dev_name, strlen(net_dev_ata_disk)))
-    return CONTROLLER_ATA;
-
-  if (!strncmp(net_dev_scsi_disk, dev_name, strlen(net_dev_scsi_disk)))
-    return CONTROLLER_SCSI;
-
-  if (!strncmp(net_dev_scsi_tape, dev_name, strlen(net_dev_scsi_tape)))
-    return CONTROLLER_SCSI;
-
-  return CONTROLLER_UNKNOWN;
-}
-
-int
-get_dev_names(char ***names, const char *prefix)
-{
-  char *disknames, *p, **mp;
-  int n = 0;
-  int sysctl_mib[2];
-  size_t sysctl_len;
-
-  *names = NULL;
-
-  sysctl_mib[0] = CTL_HW;
-  sysctl_mib[1] = HW_DISKNAMES;
-  if (-1 == sysctl(sysctl_mib, 2, NULL, &sysctl_len, NULL, 0)) {
-    pout("Failed to get value of sysctl `hw.disknames'\n");
-    return -1;
-  }
-  if (!(disknames = malloc(sysctl_len))) {
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-  if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
-    pout("Failed to get value of sysctl `hw.disknames'\n");
-    return -1;
-  }
-  if (!(mp = (char **) calloc(strlen(disknames) / 2, sizeof(char *)))) {
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-  for (p = strtok(disknames, " "); p; p = strtok(NULL, " ")) {
-    if (strncmp(p, prefix, strlen(prefix))) {
-      continue;
-    }
-    mp[n] = malloc(strlen(net_dev_prefix) + strlen(p) + 2);
-    if (!mp[n]) {
-      pout("Out of memory constructing scan device list\n");
-      return -1;
-    }
-    sprintf(mp[n], "%s%s%c", net_dev_prefix, p, 'a' + getrawpartition());
-    bytes += strlen(mp[n]) + 1;
-    n++;
-  }
-
-  mp = realloc(mp, n * (sizeof(char *)));
-  bytes += (n) * (sizeof(char *));
-  *names = mp;
-  return n;
-}
-
-int
-make_device_names(char ***devlist, const char *name)
-{
-  if (!strcmp(name, "SCSI"))
-    return get_dev_names(devlist, net_dev_scsi_disk);
-  else if (!strcmp(name, "ATA"))
-    return get_dev_names(devlist, net_dev_ata_disk);
-  else
-    return 0;
-}
-
-int
-deviceopen(const char *pathname, char *type)
-{
-  if (!strcmp(type, "SCSI")) {
-    int fd = open(pathname, O_RDWR | O_NONBLOCK);
-    if (fd < 0 && errno == EROFS)
-      fd = open(pathname, O_RDONLY | O_NONBLOCK);
-    return fd;
-  } else if (!strcmp(type, "ATA"))
-    return open(pathname, O_RDWR | O_NONBLOCK);
-  else
-    return -1;
-}
-
-int
-deviceclose(int fd)
-{
-  return close(fd);
-}
-
-int
-ata_command_interface(int fd, smart_command_set command, int select, char *data)
-{
-  struct atareq req;
-  unsigned char inbuf[DEV_BSIZE];
-  int retval, copydata = 0;
-
-  memset(&req, 0, sizeof(req));
-  memset(&inbuf, 0, sizeof(inbuf));
-
-  switch (command) {
-  case READ_VALUES:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_RD_DATA;
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case READ_THRESHOLDS:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_RD_THRESHOLDS;
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case READ_LOG:
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_READ_LOG_SECTOR;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case WRITE_LOG:
-    memcpy(inbuf, data, 512);
-    req.flags = ATACMD_WRITE;
-    req.features = ATA_SMART_WRITE_LOG_SECTOR;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    break;
-  case IDENTIFY:
-    req.flags = ATACMD_READ;
-    req.command = WDCC_IDENTIFY;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case PIDENTIFY:
-    req.flags = ATACMD_READ;
-    req.command = ATAPI_IDENTIFY_DEVICE;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case ENABLE:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_ENABLE_OPS;
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    break;
-  case DISABLE:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_DISABLE_OPS;
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    break;
-  case AUTO_OFFLINE:
-    /* NOTE: According to ATAPI 4 and UP, this command is obsolete */
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_AUTO_OFFLINE;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    break;
-  case AUTOSAVE:
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_AUTOSAVE;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_count = 0xf1;
-    /* to enable autosave */
-    req.timeout = 1000;
-    break;
-  case IMMEDIATE_OFFLINE:
-    /* NOTE: According to ATAPI 4 and UP, this command is obsolete */
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_IMMEDIATE_OFFLINE;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    break;
-  case STATUS_CHECK:
-    /* same command, no HDIO in NetBSD */
-  case STATUS:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_STATUS;
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    break;
-  case CHECK_POWER_MODE:
-    req.flags = ATACMD_READREG;
-    req.command = WDCC_CHECK_PWR;
-    req.timeout = 1000;
-    break;
-  default:
-    pout("Unrecognized command %d in ata_command_interface()\n", command);
-    errno = ENOSYS;
-    return -1;
-  }
-
-  if (command == STATUS_CHECK) {
-    char buf[512];
-
-    unsigned const short normal = WDSMART_CYL, failed = 0x2cf4;
-
-    if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) {
-      perror("Failed command");
-      return -1;
-    }
-    /* Cyl low and Cyl high unchanged means "Good SMART status" */
-    if (le16toh(req.cylinder) == normal)
-      return 0;
-
-    /* These values mean "Bad SMART status" */
-    if (le16toh(req.cylinder) == failed)
-      return 1;
-
-    /* We haven't gotten output that makes sense; 
-     * print out some debugging info */
-    snprintf(buf, sizeof(buf),
-      "CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
-      (int) req.command, (int) req.features, (int) req.sec_count, (int) req.sec_num,
-      (int) (le16toh(req.cylinder) & 0xff), (int) ((le16toh(req.cylinder) >> 8) & 0xff),
-      (int) req.error);
-    printwarning(BAD_SMART, buf);
-    return 0;
-  }
-  if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) {
-    perror("Failed command");
-    return -1;
-  }
-  if (command == CHECK_POWER_MODE)
-    data[0] = req.sec_count;
-
-  if (copydata)
-    memcpy(data, inbuf, 512);
-
-  return 0;
-}
-
-int
-escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data)
-{
-  printwarning(NO_3WARE, NULL);
-  return -1;
-}
-
-int
-do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-  struct scsireq sc;
-
-  if (report > 0) {
-    size_t k;
-
-    const unsigned char *ucp = iop->cmnd;
-    const char *np;
-
-    np = scsi_get_opcode_name(ucp[0]);
-    pout(" [%s: ", np ? np : "<unknown opcode>");
-    for (k = 0; k < iop->cmnd_len; ++k)
-      pout("%02x ", ucp[k]);
-    if ((report > 1) &&
-      (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-      int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-      pout("]\n  Outgoing data, len=%d%s:\n", (int) iop->dxfer_len,
-	(trunc ? " [only first 256 bytes shown]" : ""));
-      dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
-    } else
-      pout("]");
-  }
-  memset(&sc, 0, sizeof(sc));
-  memcpy(sc.cmd, iop->cmnd, iop->cmnd_len);
-  sc.cmdlen = iop->cmnd_len;
-  sc.databuf = iop->dxferp;
-  sc.datalen = iop->dxfer_len;
-  sc.senselen = iop->max_sense_len;
-  sc.timeout = iop->timeout == 0 ? 60000 : iop->timeout;	/* XXX */
-  sc.flags =
-    (iop->dxfer_dir == DXFER_NONE ? SCCMD_READ :	/* XXX */
-    (iop->dxfer_dir == DXFER_FROM_DEVICE ? SCCMD_READ : SCCMD_WRITE));
-
-  if (ioctl(fd, SCIOCCOMMAND, &sc) < 0) {
-    warn("error sending SCSI ccb");
-    return -1;
-  }
-  iop->resid = sc.datalen - sc.datalen_used;
-  iop->scsi_status = sc.status;
-  if (iop->sensep) {
-    memcpy(iop->sensep, sc.sense, sc.senselen_used);
-    iop->resp_sense_len = sc.senselen_used;
-  }
-  if (report > 0) {
-    int trunc;
-
-    pout("  status=0\n");
-    trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-    pout("  Incoming data, len=%d%s:\n", (int) iop->dxfer_len,
-      (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
-  }
-  return 0;
-}
-
-/* print examples for smartctl */
-void 
-print_smartctl_examples()
-{
-  char p;
-
-  p = 'a' + getrawpartition();
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-    "  smartctl -a /dev/wd0%c                      (Prints all SMART information)\n\n"
-    "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/wd0%c\n"
-    "                                              (Enables SMART on first disk)\n\n"
-    "  smartctl -t long /dev/wd0%c             (Executes extended disk self-test)\n\n"
-    "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/wd0%c\n"
-    "                                      (Prints Self-Test & Attribute errors)\n",
-    p, p, p, p
-    );
-#else
-  printf(
-    "  smartctl -a /dev/wd0%c                     (Prints all SMART information)\n"
-    "  smartctl -s on -o on -S on /dev/wd0%c        (Enables SMART on first disk)\n"
-    "  smartctl -t long /dev/wd0%c            (Executes extended disk self-test)\n"
-    "  smartctl -A -l selftest -q errorsonly /dev/wd0%c"
-    "                                      (Prints Self-Test & Attribute errors)\n",
-    p, p, p, p
-    );
-#endif
-  return;
-}
diff --git a/sm5/os_netbsd.cpp b/sm5/os_netbsd.cpp
deleted file mode 100644
index 255ec8ba294c7b84dde97189cffe4331cced18cc..0000000000000000000000000000000000000000
--- a/sm5/os_netbsd.cpp
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * os_netbsd.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Sergey Svishchev <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-#include "os_netbsd.h"
-
-const char *os_XXXX_c_cvsid = "$Id: os_netbsd.cpp,v 1.8 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID OS_NETBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-/* global variable holding byte count of allocated memory */
-extern long long bytes;
-
-enum warnings {
-  BAD_SMART, NO_3WARE, MAX_MSG
-};
-
-/* Utility function for printing warnings */
-void
-printwarning(int msgNo, const char *extra)
-{
-  static int printed[] = {0, 0};
-  static const char *message[] = {
-    "Error: SMART Status command failed.\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
-    PACKAGE_STRING " does not currentlly support twe(4) devices (3ware Escalade)\n",
-  };
-
-  if (msgNo >= 0 && msgNo <= MAX_MSG) {
-    if (!printed[msgNo]) {
-      printed[msgNo] = 1;
-      pout("%s", message[msgNo]);
-      if (extra)
-	pout("%s", extra);
-    }
-  }
-  return;
-}
-
-static const char *net_dev_prefix = "/dev/";
-static const char *net_dev_ata_disk = "wd";
-static const char *net_dev_scsi_disk = "sd";
-static const char *net_dev_scsi_tape = "enrst";
-
-/* Guess device type(ata or scsi) based on device name */
-int
-guess_device_type(const char *dev_name)
-{
-  int len;
-  int dev_prefix_len = strlen(net_dev_prefix);
-
-  if (!dev_name || !(len = strlen(dev_name)))
-    return CONTROLLER_UNKNOWN;
-
-  if (!strncmp(net_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len)
-      return CONTROLLER_UNKNOWN;
-    else
-      dev_name += dev_prefix_len;
-  }
-  if (!strncmp(net_dev_ata_disk, dev_name, strlen(net_dev_ata_disk)))
-    return CONTROLLER_ATA;
-
-  if (!strncmp(net_dev_scsi_disk, dev_name, strlen(net_dev_scsi_disk)))
-    return CONTROLLER_SCSI;
-
-  if (!strncmp(net_dev_scsi_tape, dev_name, strlen(net_dev_scsi_tape)))
-    return CONTROLLER_SCSI;
-
-  return CONTROLLER_UNKNOWN;
-}
-
-int
-get_dev_names(char ***names, const char *prefix)
-{
-  char *disknames, *p, **mp;
-  int n = 0;
-  int sysctl_mib[2];
-  size_t sysctl_len;
-
-  *names = NULL;
-
-  sysctl_mib[0] = CTL_HW;
-  sysctl_mib[1] = HW_DISKNAMES;
-  if (-1 == sysctl(sysctl_mib, 2, NULL, &sysctl_len, NULL, 0)) {
-    pout("Failed to get value of sysctl `hw.disknames'\n");
-    return -1;
-  }
-  if (!(disknames = malloc(sysctl_len))) {
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-  if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
-    pout("Failed to get value of sysctl `hw.disknames'\n");
-    return -1;
-  }
-  if (!(mp = (char **) calloc(strlen(disknames) / 2, sizeof(char *)))) {
-    pout("Out of memory constructing scan device list\n");
-    return -1;
-  }
-  for (p = strtok(disknames, " "); p; p = strtok(NULL, " ")) {
-    if (strncmp(p, prefix, strlen(prefix))) {
-      continue;
-    }
-    mp[n] = malloc(strlen(net_dev_prefix) + strlen(p) + 2);
-    if (!mp[n]) {
-      pout("Out of memory constructing scan device list\n");
-      return -1;
-    }
-    sprintf(mp[n], "%s%s%c", net_dev_prefix, p, 'a' + getrawpartition());
-    bytes += strlen(mp[n]) + 1;
-    n++;
-  }
-
-  mp = realloc(mp, n * (sizeof(char *)));
-  bytes += (n) * (sizeof(char *));
-  *names = mp;
-  return n;
-}
-
-int
-make_device_names(char ***devlist, const char *name)
-{
-  if (!strcmp(name, "SCSI"))
-    return get_dev_names(devlist, net_dev_scsi_disk);
-  else if (!strcmp(name, "ATA"))
-    return get_dev_names(devlist, net_dev_ata_disk);
-  else
-    return 0;
-}
-
-int
-deviceopen(const char *pathname, char *type)
-{
-  if (!strcmp(type, "SCSI")) {
-    int fd = open(pathname, O_RDWR | O_NONBLOCK);
-    if (fd < 0 && errno == EROFS)
-      fd = open(pathname, O_RDONLY | O_NONBLOCK);
-    return fd;
-  } else if (!strcmp(type, "ATA"))
-    return open(pathname, O_RDWR | O_NONBLOCK);
-  else
-    return -1;
-}
-
-int
-deviceclose(int fd)
-{
-  return close(fd);
-}
-
-int
-ata_command_interface(int fd, smart_command_set command, int select, char *data)
-{
-  struct atareq req;
-  unsigned char inbuf[DEV_BSIZE];
-  int retval, copydata = 0;
-
-  memset(&req, 0, sizeof(req));
-  memset(&inbuf, 0, sizeof(inbuf));
-
-  switch (command) {
-  case READ_VALUES:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_RD_DATA;
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case READ_THRESHOLDS:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_RD_THRESHOLDS;
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case READ_LOG:
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_READ_LOG_SECTOR;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case WRITE_LOG:
-    memcpy(inbuf, data, 512);
-    req.flags = ATACMD_WRITE;
-    req.features = ATA_SMART_WRITE_LOG_SECTOR;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    break;
-  case IDENTIFY:
-    req.flags = ATACMD_READ;
-    req.command = WDCC_IDENTIFY;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case PIDENTIFY:
-    req.flags = ATACMD_READ;
-    req.command = ATAPI_IDENTIFY_DEVICE;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.timeout = 1000;
-    copydata = 1;
-    break;
-  case ENABLE:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_ENABLE_OPS;
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    break;
-  case DISABLE:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_DISABLE_OPS;
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    break;
-  case AUTO_OFFLINE:
-    /* NOTE: According to ATAPI 4 and UP, this command is obsolete */
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_AUTO_OFFLINE;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    break;
-  case AUTOSAVE:
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_AUTOSAVE;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_count = 0xf1;
-    /* to enable autosave */
-    req.timeout = 1000;
-    break;
-  case IMMEDIATE_OFFLINE:
-    /* NOTE: According to ATAPI 4 and UP, this command is obsolete */
-    req.flags = ATACMD_READ;
-    req.features = ATA_SMART_IMMEDIATE_OFFLINE;	/* XXX missing from wdcreg.h */
-    req.command = WDCC_SMART;
-    req.databuf = (caddr_t) inbuf;
-    req.datalen = sizeof(inbuf);
-    req.cylinder = htole16(WDSMART_CYL);
-    req.sec_num = select;
-    req.sec_count = 1;
-    req.timeout = 1000;
-    break;
-  case STATUS_CHECK:
-    /* same command, no HDIO in NetBSD */
-  case STATUS:
-    req.flags = ATACMD_READ;
-    req.features = WDSM_STATUS;
-    req.command = WDCC_SMART;
-    req.cylinder = htole16(WDSMART_CYL);
-    req.timeout = 1000;
-    break;
-  case CHECK_POWER_MODE:
-    req.flags = ATACMD_READREG;
-    req.command = WDCC_CHECK_PWR;
-    req.timeout = 1000;
-    break;
-  default:
-    pout("Unrecognized command %d in ata_command_interface()\n", command);
-    errno = ENOSYS;
-    return -1;
-  }
-
-  if (command == STATUS_CHECK) {
-    char buf[512];
-
-    unsigned const short normal = WDSMART_CYL, failed = 0x2cf4;
-
-    if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) {
-      perror("Failed command");
-      return -1;
-    }
-    /* Cyl low and Cyl high unchanged means "Good SMART status" */
-    if (le16toh(req.cylinder) == normal)
-      return 0;
-
-    /* These values mean "Bad SMART status" */
-    if (le16toh(req.cylinder) == failed)
-      return 1;
-
-    /* We haven't gotten output that makes sense; 
-     * print out some debugging info */
-    snprintf(buf, sizeof(buf),
-      "CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
-      (int) req.command, (int) req.features, (int) req.sec_count, (int) req.sec_num,
-      (int) (le16toh(req.cylinder) & 0xff), (int) ((le16toh(req.cylinder) >> 8) & 0xff),
-      (int) req.error);
-    printwarning(BAD_SMART, buf);
-    return 0;
-  }
-  if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) {
-    perror("Failed command");
-    return -1;
-  }
-  if (command == CHECK_POWER_MODE)
-    data[0] = req.sec_count;
-
-  if (copydata)
-    memcpy(data, inbuf, 512);
-
-  return 0;
-}
-
-int
-escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data)
-{
-  printwarning(NO_3WARE, NULL);
-  return -1;
-}
-
-int
-do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-  struct scsireq sc;
-
-  if (report > 0) {
-    size_t k;
-
-    const unsigned char *ucp = iop->cmnd;
-    const char *np;
-
-    np = scsi_get_opcode_name(ucp[0]);
-    pout(" [%s: ", np ? np : "<unknown opcode>");
-    for (k = 0; k < iop->cmnd_len; ++k)
-      pout("%02x ", ucp[k]);
-    if ((report > 1) &&
-      (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-      int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-      pout("]\n  Outgoing data, len=%d%s:\n", (int) iop->dxfer_len,
-	(trunc ? " [only first 256 bytes shown]" : ""));
-      dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
-    } else
-      pout("]");
-  }
-  memset(&sc, 0, sizeof(sc));
-  memcpy(sc.cmd, iop->cmnd, iop->cmnd_len);
-  sc.cmdlen = iop->cmnd_len;
-  sc.databuf = iop->dxferp;
-  sc.datalen = iop->dxfer_len;
-  sc.senselen = iop->max_sense_len;
-  sc.timeout = iop->timeout == 0 ? 60000 : iop->timeout;	/* XXX */
-  sc.flags =
-    (iop->dxfer_dir == DXFER_NONE ? SCCMD_READ :	/* XXX */
-    (iop->dxfer_dir == DXFER_FROM_DEVICE ? SCCMD_READ : SCCMD_WRITE));
-
-  if (ioctl(fd, SCIOCCOMMAND, &sc) < 0) {
-    warn("error sending SCSI ccb");
-    return -1;
-  }
-  iop->resid = sc.datalen - sc.datalen_used;
-  iop->scsi_status = sc.status;
-  if (iop->sensep) {
-    memcpy(iop->sensep, sc.sense, sc.senselen_used);
-    iop->resp_sense_len = sc.senselen_used;
-  }
-  if (report > 0) {
-    int trunc;
-
-    pout("  status=0\n");
-    trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-    pout("  Incoming data, len=%d%s:\n", (int) iop->dxfer_len,
-      (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
-  }
-  return 0;
-}
-
-/* print examples for smartctl */
-void 
-print_smartctl_examples()
-{
-  char p;
-
-  p = 'a' + getrawpartition();
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-    "  smartctl -a /dev/wd0%c                      (Prints all SMART information)\n\n"
-    "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/wd0%c\n"
-    "                                              (Enables SMART on first disk)\n\n"
-    "  smartctl -t long /dev/wd0%c             (Executes extended disk self-test)\n\n"
-    "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/wd0%c\n"
-    "                                      (Prints Self-Test & Attribute errors)\n",
-    p, p, p, p
-    );
-#else
-  printf(
-    "  smartctl -a /dev/wd0%c                     (Prints all SMART information)\n"
-    "  smartctl -s on -o on -S on /dev/wd0%c        (Enables SMART on first disk)\n"
-    "  smartctl -t long /dev/wd0%c            (Executes extended disk self-test)\n"
-    "  smartctl -A -l selftest -q errorsonly /dev/wd0%c"
-    "                                      (Prints Self-Test & Attribute errors)\n",
-    p, p, p, p
-    );
-#endif
-  return;
-}
diff --git a/sm5/os_netbsd.h b/sm5/os_netbsd.h
deleted file mode 100644
index 58a81b3568ec399a0bd4d646a2abb99f0dd7cff2..0000000000000000000000000000000000000000
--- a/sm5/os_netbsd.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * os_netbsd.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Sergey Svishchev <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef OS_NETBSD_H_
-#define OS_NETBSD_H_
-
-#define OS_NETBSD_H_CVSID "$Id: os_netbsd.h,v 1.7 2004/04/29 19:00:36 shattered Exp $\n"
-
-#include <sys/device.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-
-#include <sys/scsiio.h>
-#include <sys/ataio.h>
-
-#define ata_smart_selftestlog __netbsd_ata_smart_selftestlog
-#include <dev/ata/atareg.h>
-#if HAVE_DEV_ATA_ATAVAR_H
-#include <dev/ata/atavar.h>
-#endif
-#include <dev/ic/wdcreg.h>
-#undef ata_smart_selftestlog
-
-#include <err.h>
-#include <fcntl.h>
-#include <util.h>
-
-#ifndef	WDSM_RD_THRESHOLDS	/* pre-1.6.2 system */
-#define	WDSM_RD_THRESHOLDS	0xd1
-#endif
-#ifndef	WDSMART_CYL
-#define	WDSMART_CYL		0xc24f
-#endif
-
-#endif /* OS_NETBSD_H_ */
diff --git a/sm5/os_solaris.c b/sm5/os_solaris.c
deleted file mode 100644
index 4a74980a168da73c4dc632b133146e614be04a30..0000000000000000000000000000000000000000
--- a/sm5/os_solaris.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * os_solaris.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Casper Dik <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-
-// These are needed to define prototypes for the functions defined below
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-// This is to include whatever prototypes you define in os_solaris.h
-#include "os_solaris.h"
-
-extern long long bytes;
-
-static const char *filenameandversion="$Id: os_solaris.c,v 1.19 2004/08/13 13:57:12 arvoreen Exp $";
-
-const char *os_XXXX_c_cvsid="$Id: os_solaris.c,v 1.19 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// The printwarning() function warns about unimplemented functions
-int printedout[2];
-char *unimplemented[2]={
-  "ATA command routine ata_command_interface()",
-  "3ware Escalade Controller command routine escalade_command_interface()",
-};
-
-int printwarning(int which){
-  if (!unimplemented[which])
-    return 0;
-
-  if (printedout[which])
-    return 1;
-  
-  printedout[which]=1;
-  
-  pout("\n"
-       "#######################################################################\n"
-       "%s NOT IMPLEMENTED under Solaris.\n"
-       "Please contact " PACKAGE_BUGREPORT " if\n"
-       "you want to help in porting smartmontools to Solaris.\n"
-       "#######################################################################\n"
-       "\n",
-       unimplemented[which]);
-
-  return 1;
-}
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/rdsk/c0t0d0s0             (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/rdsk/c0t0d0s0\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/rdsk/c0t0d0s0 (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/rdsk/c0t0d0s0\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/rdsk/c0t0d0s0               (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/rdsk/c0t0d0s0 (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/rdsk/c0t0d0s0      (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/rdsk/c0t0d0s0\n"
-         "                                        (Prints Self-Test & Attribute errors)\n"
-         );
-#endif
-  return;
-}
-
-static const char *uscsidrvrs[] = {
-        "sd",
-        "ssd",
-        "st"
-};
-
-static const char *atadrvrs[] = {
-        "cmdk",
-        "dad",
-};
-
-static int
-isdevtype(const char *dev_name, const char *table[], int tsize)
-{
-  char devpath[MAXPATHLEN];
-  int i;
-  char *basename;
-
-  if (realpath(dev_name, devpath) == NULL)
-    return 0;
- 
-  if ((basename = strrchr(devpath, '/')) == NULL)
-    return 0;
-
-  basename++;
-
-  for (i = 0; i < tsize; i++) {
-    int l = strlen(table[i]);
-    if (strncmp(basename, table[i], l) == 0 && basename[l] == '@')
-      return 1;
-  }
-  return 0;
-}
-
-static int
-isscsidev(const char *path)
-{
-  return isdevtype(path, uscsidrvrs, sizeof (uscsidrvrs) / sizeof (char *));
-}
-
-static int
-isatadev(const char *path)
-{
-  return isdevtype(path, atadrvrs, sizeof (atadrvrs) / sizeof (char *));
-}
-
-// tries to guess device type given the name (a path)
-int guess_device_type (const char* dev_name) {
-  if (isscsidev(dev_name))
-    return CONTROLLER_SCSI;
-  else if (isatadev(dev_name))
-    return CONTROLLER_ATA;
-  else
-    return CONTROLLER_UNKNOW;
-}
-
-struct pathlist {
-        char **names;
-        int  nnames;
-        int  maxnames;
-};
-
-static int
-addpath(const char *path, struct pathlist *res)
-{
-        if (++res->nnames > res->maxnames) {
-                res->maxnames += 16;
-                res->names = realloc(res->names, res->maxnames * sizeof (char *));
-                if (res->names == NULL)
-                        return -1;
-                bytes += 16*sizeof(char *);
-        }
-        if (!(res->names[res->nnames-1] = CustomStrDup((char *)path, 1, __LINE__, filenameandversion)))
-                return -1;
-        return 0;
-}
-
-static int 
-grokdir(const char *dir, struct pathlist *res, int testfun(const char *))
-{
-        char pathbuf[MAXPATHLEN];
-        size_t len;
-        DIR *dp;
-        struct dirent *de;
-        int isdisk = strstr(dir, "dsk") != NULL;
-        char *p;
-
-        len = snprintf(pathbuf, sizeof (pathbuf), "%s/", dir);
-        if (len >= sizeof (pathbuf))
-                return -1;
-
-        dp = opendir(dir);
-        if (dp == NULL)
-                return 0;
-
-        while ((de = readdir(dp)) != NULL) {
-                if (de->d_name[0] == '.')
-                        continue;
-
-                if (strlen(de->d_name) + len >= sizeof (pathbuf))
-                        continue;
-
-                if (isdisk) {
-                        /* Disk represented by slice 0 */
-                        p = strstr(de->d_name, "s0");
-                        /* String doesn't end in "s0\0" */
-                        if (p == NULL || p[2] != '\0')
-                                continue;
-                } else {
-                        /* Tape drive represented by the all-digit device */
-                        for (p = de->d_name; *p; p++)
-                                if (!isdigit((int)(*p)))
-                                        break;
-                        if (*p != '\0')
-                                continue;
-                }
-                strcpy(&pathbuf[len], de->d_name);
-                if (testfun(pathbuf)) {
-                        if (addpath(pathbuf, res) == -1) {
-                                closedir(dp);
-                                return -1;
-                        }
-                }
-        }
-        closedir(dp);
-
-        return 0;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number of devices, or -1 if out of memory.
-int make_device_names (char*** devlist, const char* name) {
-        struct pathlist res;
-
-        res.nnames = res.maxnames = 0;
-        res.names = NULL;
-        if (strcmp(name, "SCSI") == 0) {
-                if (grokdir("/dev/rdsk", &res, isscsidev) == -1)
-                        return -1;
-                if (grokdir("/dev/rmt", &res, isscsidev) == -1)
-                        return -1;
-	} else if (strcmp(name, "ATA") == 0) {
-                if (grokdir("/dev/rdsk", &res, isatadev) == -1)
-                        return -1;
-	} else {
-                // non-SCSI and non-ATA case not implemented
-                *devlist=NULL;
-                return 0;
-	}
-
-	// shrink array to min possible size
-	res.names = realloc(res.names, res.nnames * sizeof (char *));
-	bytes -= sizeof(char *)*(res.maxnames-res.nnames);
-
-	// pass list back
-	*devlist = res.names;
-	return res.nnames;
-}
-
-// Like open().  Return integer handle, used by functions below only.
-// type="ATA" or "SCSI".
-int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) 
-    return open(pathname, O_RDWR | O_NONBLOCK);
-  else if (!strcmp(type,"ATA")) 
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  else
-    return -1;
-}
-
-// Like close().  Acts on handles returned by above function.
-int deviceclose(int fd){
-    return close(fd);
-}
-
-static void swap_sector(void *p)
-{
-    int i;
-    unsigned char t, *cp = p;
-    for(i = 0; i < 256; i++) {
-        t = cp[0]; cp[0] = cp[1]; cp[1] = t;
-        cp += 2;
-    }
-}
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data){
-#if defined(__sparc)
-    int err;
- 
-    switch (command){
-    case CHECK_POWER_MODE:
-	/* currently not recognized */
-	return -1;
-    case READ_VALUES:
-	return smart_read_data(fd, data);
-    case READ_THRESHOLDS:
-	return smart_read_thresholds(fd, data);
-    case READ_LOG:
-	return smart_read_log(fd, select, 1, data);
-    case IDENTIFY:
-	err = ata_identify(fd, data);
-	if(err) return err;
-	swap_sector(data);
-	return 0;
-    case PIDENTIFY:
-	err = ata_pidentify(fd, data);
-	if(err) return err;
-	swap_sector(data);
-	return 0;
-    case ENABLE:
-	return smart_enable(fd);
-    case DISABLE:
-	return smart_disable(fd);
-    case STATUS:
-	return smart_status(fd);
-    case AUTO_OFFLINE:
-	return smart_auto_offline(fd, select);
-    case AUTOSAVE:
-	return smart_auto_save(fd, select);
-    case IMMEDIATE_OFFLINE:
-	return smart_immediate_offline(fd, select);
-    case STATUS_CHECK:
-	return smart_status_check(fd);
-    default:
-	pout("Unrecognized command %d in ata_command_interface() of os_solaris.c\n", command);
-	exit(1);
-	break;
-    }
-#else /* __sparc */
-    // avoid gcc warnings//
-    fd=command=select=0;
-    data=NULL;
-
-    /* Above smart_* routines uses undocumented ioctls of "dada"
-     * driver, which is specific to SPARC Solaris. x86 Solaris seems
-     * not to provide similar or alternative interface... */
-    if (printwarning(0))
-	return -1;
-#endif
-    return -1;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-  // avoid gcc warnings//
-  fd=disknum=escalade_type=command=select=0;
-  data=NULL;
-
-  if (printwarning(1))
-    return -1;
-  return -1;
-}
-
-#include <errno.h>
-#include <sys/scsi/generic/commands.h>
-#include <sys/scsi/generic/status.h>
-#include <sys/scsi/impl/types.h>
-#include <sys/scsi/impl/uscsi.h>
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  struct uscsi_cmd uscsi;
-
-    if (report > 0) {
-        int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-
-
-  memset(&uscsi, 0, sizeof (uscsi));
-
-  uscsi.uscsi_cdb = (void *)iop->cmnd;
-  uscsi.uscsi_cdblen = iop->cmnd_len;
-  if (iop->timeout == 0)
-    uscsi.uscsi_timeout = 60; /* XXX */
-  else
-    uscsi.uscsi_timeout = iop->timeout;
-  uscsi.uscsi_bufaddr = (void *)iop->dxferp;
-  uscsi.uscsi_buflen = iop->dxfer_len;
-  uscsi.uscsi_rqbuf = (void *)iop->sensep;
-  uscsi.uscsi_rqlen = iop->max_sense_len;
-
-  switch (iop->dxfer_dir) {
-  case DXFER_NONE:
-  case DXFER_FROM_DEVICE:
-    uscsi.uscsi_flags = USCSI_READ;
-    break;
-  case DXFER_TO_DEVICE:
-    uscsi.uscsi_flags = USCSI_WRITE;
-    break;
-  default:
-    return -EINVAL;
-  }
-  uscsi.uscsi_flags |= USCSI_ISOLATE;
-
-  if (ioctl(fd, USCSICMD, &uscsi))
-    return -errno;
-
-  iop->scsi_status = uscsi.uscsi_status;
-  iop->resid = uscsi.uscsi_resid;
-  iop->resp_sense_len = iop->max_sense_len - uscsi.uscsi_rqresid;
-
-  if (report > 0) {
-    int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    pout("  status=0\n");
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-         (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-
-  return (0);
-}
diff --git a/sm5/os_solaris.cpp b/sm5/os_solaris.cpp
deleted file mode 100644
index ddf2ab4e6e84f56b113529cdb333951b3487a814..0000000000000000000000000000000000000000
--- a/sm5/os_solaris.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * os_solaris.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Casper Dik <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-
-// These are needed to define prototypes for the functions defined below
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-// This is to include whatever prototypes you define in os_solaris.h
-#include "os_solaris.h"
-
-extern long long bytes;
-
-static const char *filenameandversion="$Id: os_solaris.cpp,v 1.19 2004/08/13 13:57:12 arvoreen Exp $";
-
-const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.19 2004/08/13 13:57:12 arvoreen Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// The printwarning() function warns about unimplemented functions
-int printedout[2];
-char *unimplemented[2]={
-  "ATA command routine ata_command_interface()",
-  "3ware Escalade Controller command routine escalade_command_interface()",
-};
-
-int printwarning(int which){
-  if (!unimplemented[which])
-    return 0;
-
-  if (printedout[which])
-    return 1;
-  
-  printedout[which]=1;
-  
-  pout("\n"
-       "#######################################################################\n"
-       "%s NOT IMPLEMENTED under Solaris.\n"
-       "Please contact " PACKAGE_BUGREPORT " if\n"
-       "you want to help in porting smartmontools to Solaris.\n"
-       "#######################################################################\n"
-       "\n",
-       unimplemented[which]);
-
-  return 1;
-}
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-         "  smartctl -a /dev/rdsk/c0t0d0s0             (Prints all SMART information)\n\n"
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/rdsk/c0t0d0s0\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/rdsk/c0t0d0s0 (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/rdsk/c0t0d0s0\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-         );
-#else
-  printf(
-         "  smartctl -a /dev/rdsk/c0t0d0s0               (Prints all SMART information)\n"
-         "  smartctl -s on -o on -S on /dev/rdsk/c0t0d0s0 (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/rdsk/c0t0d0s0      (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/rdsk/c0t0d0s0\n"
-         "                                        (Prints Self-Test & Attribute errors)\n"
-         );
-#endif
-  return;
-}
-
-static const char *uscsidrvrs[] = {
-        "sd",
-        "ssd",
-        "st"
-};
-
-static const char *atadrvrs[] = {
-        "cmdk",
-        "dad",
-};
-
-static int
-isdevtype(const char *dev_name, const char *table[], int tsize)
-{
-  char devpath[MAXPATHLEN];
-  int i;
-  char *basename;
-
-  if (realpath(dev_name, devpath) == NULL)
-    return 0;
- 
-  if ((basename = strrchr(devpath, '/')) == NULL)
-    return 0;
-
-  basename++;
-
-  for (i = 0; i < tsize; i++) {
-    int l = strlen(table[i]);
-    if (strncmp(basename, table[i], l) == 0 && basename[l] == '@')
-      return 1;
-  }
-  return 0;
-}
-
-static int
-isscsidev(const char *path)
-{
-  return isdevtype(path, uscsidrvrs, sizeof (uscsidrvrs) / sizeof (char *));
-}
-
-static int
-isatadev(const char *path)
-{
-  return isdevtype(path, atadrvrs, sizeof (atadrvrs) / sizeof (char *));
-}
-
-// tries to guess device type given the name (a path)
-int guess_device_type (const char* dev_name) {
-  if (isscsidev(dev_name))
-    return CONTROLLER_SCSI;
-  else if (isatadev(dev_name))
-    return CONTROLLER_ATA;
-  else
-    return CONTROLLER_UNKNOW;
-}
-
-struct pathlist {
-        char **names;
-        int  nnames;
-        int  maxnames;
-};
-
-static int
-addpath(const char *path, struct pathlist *res)
-{
-        if (++res->nnames > res->maxnames) {
-                res->maxnames += 16;
-                res->names = realloc(res->names, res->maxnames * sizeof (char *));
-                if (res->names == NULL)
-                        return -1;
-                bytes += 16*sizeof(char *);
-        }
-        if (!(res->names[res->nnames-1] = CustomStrDup((char *)path, 1, __LINE__, filenameandversion)))
-                return -1;
-        return 0;
-}
-
-static int 
-grokdir(const char *dir, struct pathlist *res, int testfun(const char *))
-{
-        char pathbuf[MAXPATHLEN];
-        size_t len;
-        DIR *dp;
-        struct dirent *de;
-        int isdisk = strstr(dir, "dsk") != NULL;
-        char *p;
-
-        len = snprintf(pathbuf, sizeof (pathbuf), "%s/", dir);
-        if (len >= sizeof (pathbuf))
-                return -1;
-
-        dp = opendir(dir);
-        if (dp == NULL)
-                return 0;
-
-        while ((de = readdir(dp)) != NULL) {
-                if (de->d_name[0] == '.')
-                        continue;
-
-                if (strlen(de->d_name) + len >= sizeof (pathbuf))
-                        continue;
-
-                if (isdisk) {
-                        /* Disk represented by slice 0 */
-                        p = strstr(de->d_name, "s0");
-                        /* String doesn't end in "s0\0" */
-                        if (p == NULL || p[2] != '\0')
-                                continue;
-                } else {
-                        /* Tape drive represented by the all-digit device */
-                        for (p = de->d_name; *p; p++)
-                                if (!isdigit((int)(*p)))
-                                        break;
-                        if (*p != '\0')
-                                continue;
-                }
-                strcpy(&pathbuf[len], de->d_name);
-                if (testfun(pathbuf)) {
-                        if (addpath(pathbuf, res) == -1) {
-                                closedir(dp);
-                                return -1;
-                        }
-                }
-        }
-        closedir(dp);
-
-        return 0;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number of devices, or -1 if out of memory.
-int make_device_names (char*** devlist, const char* name) {
-        struct pathlist res;
-
-        res.nnames = res.maxnames = 0;
-        res.names = NULL;
-        if (strcmp(name, "SCSI") == 0) {
-                if (grokdir("/dev/rdsk", &res, isscsidev) == -1)
-                        return -1;
-                if (grokdir("/dev/rmt", &res, isscsidev) == -1)
-                        return -1;
-	} else if (strcmp(name, "ATA") == 0) {
-                if (grokdir("/dev/rdsk", &res, isatadev) == -1)
-                        return -1;
-	} else {
-                // non-SCSI and non-ATA case not implemented
-                *devlist=NULL;
-                return 0;
-	}
-
-	// shrink array to min possible size
-	res.names = realloc(res.names, res.nnames * sizeof (char *));
-	bytes -= sizeof(char *)*(res.maxnames-res.nnames);
-
-	// pass list back
-	*devlist = res.names;
-	return res.nnames;
-}
-
-// Like open().  Return integer handle, used by functions below only.
-// type="ATA" or "SCSI".
-int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) 
-    return open(pathname, O_RDWR | O_NONBLOCK);
-  else if (!strcmp(type,"ATA")) 
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  else
-    return -1;
-}
-
-// Like close().  Acts on handles returned by above function.
-int deviceclose(int fd){
-    return close(fd);
-}
-
-static void swap_sector(void *p)
-{
-    int i;
-    unsigned char t, *cp = p;
-    for(i = 0; i < 256; i++) {
-        t = cp[0]; cp[0] = cp[1]; cp[1] = t;
-        cp += 2;
-    }
-}
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data){
-#if defined(__sparc)
-    int err;
- 
-    switch (command){
-    case CHECK_POWER_MODE:
-	/* currently not recognized */
-	return -1;
-    case READ_VALUES:
-	return smart_read_data(fd, data);
-    case READ_THRESHOLDS:
-	return smart_read_thresholds(fd, data);
-    case READ_LOG:
-	return smart_read_log(fd, select, 1, data);
-    case IDENTIFY:
-	err = ata_identify(fd, data);
-	if(err) return err;
-	swap_sector(data);
-	return 0;
-    case PIDENTIFY:
-	err = ata_pidentify(fd, data);
-	if(err) return err;
-	swap_sector(data);
-	return 0;
-    case ENABLE:
-	return smart_enable(fd);
-    case DISABLE:
-	return smart_disable(fd);
-    case STATUS:
-	return smart_status(fd);
-    case AUTO_OFFLINE:
-	return smart_auto_offline(fd, select);
-    case AUTOSAVE:
-	return smart_auto_save(fd, select);
-    case IMMEDIATE_OFFLINE:
-	return smart_immediate_offline(fd, select);
-    case STATUS_CHECK:
-	return smart_status_check(fd);
-    default:
-	pout("Unrecognized command %d in ata_command_interface() of os_solaris.c\n", command);
-	exit(1);
-	break;
-    }
-#else /* __sparc */
-    // avoid gcc warnings//
-    fd=command=select=0;
-    data=NULL;
-
-    /* Above smart_* routines uses undocumented ioctls of "dada"
-     * driver, which is specific to SPARC Solaris. x86 Solaris seems
-     * not to provide similar or alternative interface... */
-    if (printwarning(0))
-	return -1;
-#endif
-    return -1;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-  // avoid gcc warnings//
-  fd=disknum=escalade_type=command=select=0;
-  data=NULL;
-
-  if (printwarning(1))
-    return -1;
-  return -1;
-}
-
-#include <errno.h>
-#include <sys/scsi/generic/commands.h>
-#include <sys/scsi/generic/status.h>
-#include <sys/scsi/impl/types.h>
-#include <sys/scsi/impl/uscsi.h>
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  struct uscsi_cmd uscsi;
-
-    if (report > 0) {
-        int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-
-
-  memset(&uscsi, 0, sizeof (uscsi));
-
-  uscsi.uscsi_cdb = (void *)iop->cmnd;
-  uscsi.uscsi_cdblen = iop->cmnd_len;
-  if (iop->timeout == 0)
-    uscsi.uscsi_timeout = 60; /* XXX */
-  else
-    uscsi.uscsi_timeout = iop->timeout;
-  uscsi.uscsi_bufaddr = (void *)iop->dxferp;
-  uscsi.uscsi_buflen = iop->dxfer_len;
-  uscsi.uscsi_rqbuf = (void *)iop->sensep;
-  uscsi.uscsi_rqlen = iop->max_sense_len;
-
-  switch (iop->dxfer_dir) {
-  case DXFER_NONE:
-  case DXFER_FROM_DEVICE:
-    uscsi.uscsi_flags = USCSI_READ;
-    break;
-  case DXFER_TO_DEVICE:
-    uscsi.uscsi_flags = USCSI_WRITE;
-    break;
-  default:
-    return -EINVAL;
-  }
-  uscsi.uscsi_flags |= USCSI_ISOLATE;
-
-  if (ioctl(fd, USCSICMD, &uscsi))
-    return -errno;
-
-  iop->scsi_status = uscsi.uscsi_status;
-  iop->resid = uscsi.uscsi_resid;
-  iop->resp_sense_len = iop->max_sense_len - uscsi.uscsi_rqresid;
-
-  if (report > 0) {
-    int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    pout("  status=0\n");
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-         (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-
-  return (0);
-}
diff --git a/sm5/os_solaris.h b/sm5/os_solaris.h
deleted file mode 100644
index b62cbd89253e8ec3b14788cc2d291b8781820ff4..0000000000000000000000000000000000000000
--- a/sm5/os_solaris.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * os_solaris.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003-4 Casper Dik <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef OS_SOLARIS_H_
-#define OS_SOLARIS_H_
-
-#define OS_XXXX_H_CVSID "$Id: os_solaris.h,v 1.8 2004/02/12 18:30:30 card_captor Exp $\n"
-
-// Additional material should start here.  Note: to keep the '-V' CVS
-// reporting option working as intended, you should only #include
-// system include files <something.h>.  Local #include files
-// <"something.h"> should be #included in os_solaris.c
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-// function prototypes for functions defined in os_solaris_ata.s
-int smart_read_data(int fd, void *data);
-int smart_read_thresholds(int fd, void *data);
-int smart_read_log(int fd, int s, int count, void *data);
-int ata_identify(int fd, void *data);
-int ata_pidentify(int fd, void *data);
-int smart_enable(int fd);
-int smart_disable(int fd);
-int smart_status(int fd);
-int smart_auto_offline(int fd, int s);
-int smart_auto_save(int fd, int s);
-int smart_immediate_offline(int fd, int s);
-int smart_status_check(int fd);
-
-// wrapper macros
-#define smart_enable_auto_save(fd)	smart_auto_save(fd, 0xf1)
-#define smart_disable_auto_save(fd)	smart_auto_save(fd, 0x00)
-
-#endif /* OS_SOLARIS_H_ */
diff --git a/sm5/os_solaris_ata.s b/sm5/os_solaris_ata.s
deleted file mode 100644
index 765e2ecdc9a626152309a919e38ebcdbb6c35c95..0000000000000000000000000000000000000000
--- a/sm5/os_solaris_ata.s
+++ /dev/null
@@ -1,721 +0,0 @@
-! 
-!   os_solaris_ata.s
-! 
-!   Home page of code is: http://smartmontools.sourceforge.net
-! 
-!   Copyright (C) 2003-4 SAWADA Keiji <smartmontools-support@lists.sourceforge.net>
-! 
-!   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 of the License, or
-!   (at your option) any later version.
-! 
-!   This program is distributed in the hope that it will be useful, but
-!   WITHOUT ANY WARRANTY; without even the implied warranty of
-!   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-!   General Public License for more details.
-! 
-!   You should have received a copy of the GNU General Public License
-!   along with this program; if not, write to the Free Software
-!   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-! 
-! 
-!        --------------------------------------------------------
-!        direct access routines to ATA device under Solaris/SPARC
-!        --------------------------------------------------------
-! 
-! Information
-! -----------
-! 
-! In Solaris, programmer can pass SCSI command to target device directly
-! by using USCSI ioctl or using "scg" generic SCSI driver.  But, such
-! method does not exist for ATA devices.
-! 
-! However, I can access Solaris kernel source because I am subscriber of
-! Source Foundation Program of Solaris.  So, I can find method of
-! accessing ATA device directly.  The method is to pack command in
-! undocumented structure and issue ioctl that appears only in kernel
-! source.  Yes, that is the same way in using USCSI interface.
-! 
-! But, I met difficulty in disclosing this technique.  I have signed NDA
-! with Sun that inhibits me not to violate their intellectual property.
-! 
-! Fortunately, Sun allows licensees to publish "Interfaces" if:
-! 
-! (1) he/she treats Solaris code as confidential
-! 
-! (2) and he/she doesn't incorporate Sun's code into his/her code
-! 
-! (3) and disclose enough information to use "Interface" to everyone.
-! 
-! So, I publish that technique in assembly code or object code because:
-! 
-! (1) I believe Sun's intellectural property is not invaded because I
-!     didn't reveal any struct member and ioctl to non-licensee.
-! 
-! (2) no piece of kernel source is included in this code.
-! 
-! (3) And finally, I publish enough information below in order to use
-!     this code.
-! 
-! For last reason, please don't remove "Calling Interface" section from
-! distribution.
-! 
-! 
-! Calling Interface
-! -----------------
-! 
-! Name of function/macro presents corresponding S.M.A.R.T. command.
-! 
-! Parameters are described below.
-! 
-! int fd
-! 
-!     File descriptor of ATA device.  Device would be
-!     /dev/rdsk/cXtXdXsX.
-! 
-!     Device should be raw device serviced by "dada" driver.  ATAPI
-!     CD-ROM/R/RW, DVD-ROM, and so on are not allowed because they are
-!     serviced by "sd" driver.  On x86 Solaris, "cmdk" driver services
-!     them, this routines doesn't work.
-! 
-! int s
-!     Select sector for service.  For example, this indicates log sector
-!     number for smart_read_log() function.  Probably you need to read
-!     ATA specification for this parameter.
-! 
-! void *data
-!     Data going to be read/written.  It don't have to be word aligned,
-!     But data shall points valid user memory space.
-! 
-! This is very tiny routines, but if you feel this insufficient, please
-! let me know.
-! 
-! 					ksw / SAWADA Keiji
-! 					<card_captor@users.sourceforge.net>
-	.file	"os_solaris_ata.s"
-        .global os_solaris_ata_s_cvsid
-
-	.section	".rodata"
-        .align 8
-.LLC0:
-	.asciz	"$Id: os_solaris_ata.s,v 1.2 2004/02/13 17:29:09 ballen4705 Exp $"
-
-	.section	".data"
-	.align 4
-	.type	 os_solaris_ata_s_cvsid,#object
-	.size	 os_solaris_ata_s_cvsid,4
-os_solaris_ata_s_cvsid:
-	.uaword	.LLC0
-	
-	.section	".text"
-	.align 4
-	.type	ata_cmd, #function
-	.proc	04
-ata_cmd:
-	!#PROLOGUE# 0
-	save	%sp, -184, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	st	%i2, [%fp+76]
-	st	%i3, [%fp+80]
-	st	%i4, [%fp+84]
-	st	%i5, [%fp+88]
-	ld	[%fp+88], %g1
-	st	%g1, [%fp-76]
-	ld	[%fp-76], %g1
-	and	%g1, 3, %g1
-	cmp	%g1, 0
-	be	.LL2
-	nop
-	mov	-2, %g1
-	st	%g1, [%fp-80]
-	b	.LL1
-	 nop
-.LL2:
-	add	%fp, -56, %g1
-	mov	%g1, %o0
-	mov	0, %o1
-	mov	36, %o2
-	call	memset, 0
-	 nop
-	add	%fp, -72, %g1
-	mov	%g1, %o0
-	mov	0, %o1
-	mov	16, %o2
-	call	memset, 0
-	 nop
-	ldub	[%fp+75], %g1
-	stb	%g1, [%fp-72]
-	mov	1, %g1
-	stb	%g1, [%fp-71]
-	mov	1, %g1
-	stb	%g1, [%fp-70]
-	ldub	[%fp+79], %g1
-	stb	%g1, [%fp-69]
-	ld	[%fp+84], %g1
-	sll	%g1, 9, %g1
-	st	%g1, [%fp-68]
-	ld	[%fp+80], %g1
-	st	%g1, [%fp-60]
-	mov	10, %g1
-	sth	%g1, [%fp-52]
-	ld	[%fp+84], %g1
-	cmp	%g1, 0
-	be	.LL3
-	nop
-	mov	14, %g1
-	st	%g1, [%fp-84]
-	b	.LL4
-	 nop
-.LL3:
-	mov	6, %g1
-	st	%g1, [%fp-84]
-.LL4:
-	ld	[%fp-84], %g1
-	st	%g1, [%fp-48]
-	ld	[%fp+84], %g1
-	sll	%g1, 9, %g1
-	st	%g1, [%fp-44]
-	ld	[%fp+84], %g1
-	sll	%g1, 9, %g1
-	st	%g1, [%fp-40]
-	ld	[%fp+84], %g1
-	cmp	%g1, 0
-	be	.LL5
-	nop
-	ld	[%fp+88], %g1
-	st	%g1, [%fp-88]
-	b	.LL6
-	 nop
-.LL5:
-	st	%g0, [%fp-88]
-.LL6:
-	ld	[%fp-88], %g1
-	st	%g1, [%fp-36]
-	add	%fp, -72, %g1
-	st	%g1, [%fp-32]
-	add	%fp, -56, %g1
-	ld	[%fp+68], %o0
-	mov	1481, %o1
-	mov	%g1, %o2
-	call	ioctl, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-80]
-.LL1:
-	ld	[%fp-80], %i0
-	ret
-	restore
-	.size	ata_cmd, .-ata_cmd
-	.align 4
-	.global ata_identify
-	.type	ata_identify, #function
-	.proc	04
-ata_identify:
-	!#PROLOGUE# 0
-	save	%sp, -640, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	add	%fp, -536, %g1
-	ld	[%fp+68], %o0
-	mov	236, %o1
-	mov	0, %o2
-	mov	0, %o3
-	mov	1, %o4
-	mov	%g1, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	add	%fp, -536, %g1
-	ld	[%fp+72], %o0
-	mov	%g1, %o1
-	mov	512, %o2
-	call	memcpy, 0
-	 nop
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL8
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-540]
-	b	.LL9
-	 nop
-.LL8:
-	st	%g0, [%fp-540]
-.LL9:
-	ld	[%fp-540], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	ata_identify, .-ata_identify
-	.align 4
-	.global ata_pidentify
-	.type	ata_pidentify, #function
-	.proc	04
-ata_pidentify:
-	!#PROLOGUE# 0
-	save	%sp, -640, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	add	%fp, -536, %g1
-	ld	[%fp+68], %o0
-	mov	161, %o1
-	mov	0, %o2
-	mov	0, %o3
-	mov	1, %o4
-	mov	%g1, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	add	%fp, -536, %g1
-	ld	[%fp+72], %o0
-	mov	%g1, %o1
-	mov	512, %o2
-	call	memcpy, 0
-	 nop
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL11
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-540]
-	b	.LL12
-	 nop
-.LL11:
-	st	%g0, [%fp-540]
-.LL12:
-	ld	[%fp-540], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	ata_pidentify, .-ata_pidentify
-	.align 4
-	.global smart_read_data
-	.type	smart_read_data, #function
-	.proc	04
-smart_read_data:
-	!#PROLOGUE# 0
-	save	%sp, -640, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	add	%fp, -536, %o5
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	208, %o2
-	sethi	%hi(12733440), %g1
-	or	%g1, 769, %o3
-	mov	1, %o4
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	add	%fp, -536, %g1
-	ld	[%fp+72], %o0
-	mov	%g1, %o1
-	mov	512, %o2
-	call	memcpy, 0
-	 nop
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL14
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-540]
-	b	.LL15
-	 nop
-.LL14:
-	st	%g0, [%fp-540]
-.LL15:
-	ld	[%fp-540], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_read_data, .-smart_read_data
-	.align 4
-	.global smart_read_thresholds
-	.type	smart_read_thresholds, #function
-	.proc	04
-smart_read_thresholds:
-	!#PROLOGUE# 0
-	save	%sp, -640, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	add	%fp, -536, %o5
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	209, %o2
-	sethi	%hi(12733440), %g1
-	or	%g1, 769, %o3
-	mov	1, %o4
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	add	%fp, -536, %g1
-	ld	[%fp+72], %o0
-	mov	%g1, %o1
-	mov	512, %o2
-	call	memcpy, 0
-	 nop
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL17
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-540]
-	b	.LL18
-	 nop
-.LL17:
-	st	%g0, [%fp-540]
-.LL18:
-	ld	[%fp-540], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_read_thresholds, .-smart_read_thresholds
-	.align 4
-	.global smart_auto_save
-	.type	smart_auto_save, #function
-	.proc	04
-smart_auto_save:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	ld	[%fp+72], %g1
-	and	%g1, 255, %o5
-	sethi	%hi(12733440), %g1
-	or	%g1, 768, %g1
-	or	%o5, %g1, %g1
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	210, %o2
-	mov	%g1, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL20
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL21
-	 nop
-.LL20:
-	st	%g0, [%fp-24]
-.LL21:
-	ld	[%fp-24], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_auto_save, .-smart_auto_save
-	.align 4
-	.global smart_immediate_offline
-	.type	smart_immediate_offline, #function
-	.proc	04
-smart_immediate_offline:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	ld	[%fp+72], %g1
-	and	%g1, 255, %o5
-	sethi	%hi(12733440), %g1
-	or	%g1, 768, %g1
-	or	%o5, %g1, %g1
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	212, %o2
-	mov	%g1, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL23
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL24
-	 nop
-.LL23:
-	st	%g0, [%fp-24]
-.LL24:
-	ld	[%fp-24], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_immediate_offline, .-smart_immediate_offline
-	.align 4
-	.global smart_read_log
-	.type	smart_read_log, #function
-	.proc	04
-smart_read_log:
-	!#PROLOGUE# 0
-	save	%sp, -128, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	st	%i2, [%fp+76]
-	st	%i3, [%fp+80]
-	ld	[%fp+76], %g1
-	sll	%g1, 9, %g1
-	mov	%g1, %o0
-	call	malloc, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-24]
-	ld	[%fp-24], %g1
-	cmp	%g1, 0
-	bne	.LL26
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-28]
-	b	.LL25
-	 nop
-.LL26:
-	ld	[%fp+72], %g1
-	and	%g1, 255, %o5
-	sethi	%hi(12733440), %g1
-	or	%g1, 768, %g1
-	or	%o5, %g1, %g1
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	213, %o2
-	mov	%g1, %o3
-	ld	[%fp+76], %o4
-	ld	[%fp-24], %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp+76], %g1
-	sll	%g1, 9, %g1
-	ld	[%fp+80], %o0
-	ld	[%fp-24], %o1
-	mov	%g1, %o2
-	call	memcpy, 0
-	 nop
-	ld	[%fp-24], %o0
-	call	free, 0
-	 nop
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL27
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-32]
-	b	.LL28
-	 nop
-.LL27:
-	st	%g0, [%fp-32]
-.LL28:
-	ld	[%fp-32], %g1
-	st	%g1, [%fp-28]
-.LL25:
-	ld	[%fp-28], %i0
-	ret
-	restore
-	.size	smart_read_log, .-smart_read_log
-	.align 4
-	.global smart_enable
-	.type	smart_enable, #function
-	.proc	04
-smart_enable:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	216, %o2
-	sethi	%hi(12733440), %g1
-	or	%g1, 769, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL30
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL31
-	 nop
-.LL30:
-	st	%g0, [%fp-24]
-.LL31:
-	ld	[%fp-24], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_enable, .-smart_enable
-	.align 4
-	.global smart_disable
-	.type	smart_disable, #function
-	.proc	04
-smart_disable:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	217, %o2
-	sethi	%hi(12733440), %g1
-	or	%g1, 769, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL33
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL34
-	 nop
-.LL33:
-	st	%g0, [%fp-24]
-.LL34:
-	ld	[%fp-24], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_disable, .-smart_disable
-	.align 4
-	.global smart_status
-	.type	smart_status, #function
-	.proc	04
-smart_status:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	218, %o2
-	sethi	%hi(12733440), %g1
-	or	%g1, 769, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL36
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL37
-	 nop
-.LL36:
-	st	%g0, [%fp-24]
-.LL37:
-	ld	[%fp-24], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_status, .-smart_status
-	.align 4
-	.global smart_status_check
-	.type	smart_status_check, #function
-	.proc	04
-smart_status_check:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	218, %o2
-	sethi	%hi(12733440), %g1
-	or	%g1, 769, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL39
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL38
-	 nop
-.LL39:
-	st	%g0, [%fp-24]
-.LL38:
-	ld	[%fp-24], %i0
-	ret
-	restore
-	.size	smart_status_check, .-smart_status_check
-	.align 4
-	.global smart_auto_offline
-	.type	smart_auto_offline, #function
-	.proc	04
-smart_auto_offline:
-	!#PROLOGUE# 0
-	save	%sp, -120, %sp
-	!#PROLOGUE# 1
-	st	%i0, [%fp+68]
-	st	%i1, [%fp+72]
-	ld	[%fp+72], %g1
-	and	%g1, 255, %o5
-	sethi	%hi(12733440), %g1
-	or	%g1, 768, %g1
-	or	%o5, %g1, %g1
-	ld	[%fp+68], %o0
-	mov	176, %o1
-	mov	219, %o2
-	mov	%g1, %o3
-	mov	0, %o4
-	mov	0, %o5
-	call	ata_cmd, 0
-	 nop
-	mov	%o0, %g1
-	st	%g1, [%fp-20]
-	ld	[%fp-20], %g1
-	cmp	%g1, 0
-	be	.LL41
-	nop
-	mov	-1, %g1
-	st	%g1, [%fp-24]
-	b	.LL42
-	 nop
-.LL41:
-	st	%g0, [%fp-24]
-.LL42:
-	ld	[%fp-24], %g1
-	mov	%g1, %i0
-	ret
-	restore
-	.size	smart_auto_offline, .-smart_auto_offline
-	.ident	"GCC: (GNU) 3.3.2"
diff --git a/sm5/os_win32.c b/sm5/os_win32.c
deleted file mode 100644
index 7885eda26a09f294ef1503b94dd9dfd0b78568b3..0000000000000000000000000000000000000000
--- a/sm5/os_win32.c
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*
- * os_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "config.h"
-#include "atacmds.h"
-#include "extern.h"
-extern smartmonctrl * con; // con->permissive
-#include "int64.h"
-#include "scsicmds.h"
-#include "utility.h"
-extern int64_t bytes; // malloc() byte count
-
-#include <errno.h>
-#ifdef _DEBUG
-#include <assert.h>
-#else
-#define assert(x) /**/
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <stddef.h> // offsetof()
-#include <io.h> // access()
-
-#define ARGUSED(x) ((void)(x))
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_win32.c,v 1.16 2004/08/13 13:57:12 arvoreen Exp $"
-ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-
-static int ata_open(int drive);
-static void ata_close(int fd);
-static unsigned ata_scan(void);
-
-static int aspi_open(unsigned adapter, unsigned id);
-static void aspi_close(int fd);
-static unsigned long aspi_scan(void);
-
-
-static int is_permissive()
-{
-	if (con->permissive <= 0) {
-		pout("To continue, add one or more '-T permissive' options.\n");
-		return 0;
-	}
-	con->permissive--;
-	return 1;
-}
-
-static const char * skipdev(const char * s)
-{
-	return (!strncmp(s, "/dev/", 5) ? s + 5 : s);
-}
-
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char * dev_name)
-{
-	dev_name = skipdev(dev_name);
-	if (!strncmp(dev_name, "hd", 2))
-		return CONTROLLER_ATA;
-	if (!strncmp(dev_name, "scsi", 4))
-		return CONTROLLER_SCSI;
-	return CONTROLLER_UNKNOWN;
-}
-
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist), the
-// others each contain null-terminated character strings.
-int make_device_names (char*** devlist, const char* type)
-{
-	unsigned long drives;
-	int i, j, n, sz, scsi;
-	const char * path;
-
-	if (!strcmp(type, "ATA")) {
-		// bit i set => drive i present
-		drives = ata_scan();
-		path = "/dev/hda";
-		scsi = 0;
-	}
-	else if (!strcmp(type, "SCSI")) {
-		// bit i set => drive with ID (i & 0x7) on adapter (i >> 3) present
-		drives = aspi_scan();
-		path = "/dev/scsi00";
-		scsi = 1;
-	}
-	else
-		return -1;
-
-	if (!drives)
-		return 0;
-
-	// Count #drives
-	n = 0;
-	for (i = 0; i < 32; i++) {
-		if (drives & (1 << i))
-			n++;
-	}
-	assert(n > 0);
-	if (n == 0)
-		return 0;
-
-	// Alloc devlist
-	assert(scsi || n <= 9);
-	sz = n * sizeof(char **);
-	*devlist = (char **)malloc(sz); bytes += sz;
-
-	// Add devices
-	for (i = j = 0; i < n; i++) {
-		char * s;
-		sz = strlen(path)+1;
-		s = (char *)malloc(sz); bytes += sz;
-		strcpy(s, path);
-		while (j < 32 && !(drives & (1 << j)))
-			j++;
-		assert(j < 32);
-		if (!scsi) {
-			assert(j <= 9);
-			s[sz-2] += j; // /dev/hd[a-j]
-		}
-		else {
-			s[sz-3] += (j >> 3);  // /dev/scsi[0-3].
-			s[sz-2] += (j & 0x7); //          .....[0-7]
-		}
-		(*devlist)[i] = s;
-		j++;
-	}
-	return n;
-}
-
-
-// Like open().  Return positive integer handle, only used by
-// functions below.  type="ATA" or "SCSI".  If you need to store extra
-// information about your devices, create a private internal array
-// within this file (see os_freebsd.c for an example).
-int deviceopen(const char * pathname, char *type)
-{
-	int len;
-	pathname = skipdev(pathname);
-	len = strlen(pathname);
-
-	if (!strcmp(type, "ATA")) {
-		// hd[a-z] => ATA 0-9
-		if (!(len  == 3 && pathname[0] == 'h' && pathname[1] == 'd'
-			  && 'a' <= pathname[2] && pathname[2] <= 'j')) {
-			errno = ENOENT;
-			return -1;
-		}
-		return ata_open(pathname[2] - 'a');
-	}
-
-	if (!strcmp(type, "SCSI")) {
-		// scsi[0-9][0-f] => SCSI Adapter 0-9, ID 0-15, LUN 0
-		unsigned adapter = ~0, id = ~0; int n = -1;
-		if (!(sscanf(pathname,"scsi%1u%1x%n", &adapter, &id, &n) == 2 && n == len)) {
-			errno = ENOENT;
-			return -1;
-		}
-		return aspi_open(adapter, id);
-	}
-	errno = ENOENT;
-	return -1;
-}
-
-
-// Like close().  Acts only on handles returned by above function.
-// (Never called in smartctl!)
-int deviceclose(int fd)
-{
-	if (fd < 0x100) {
-		ata_close(fd);
-	}
-	else {
-		aspi_close(fd);
-	}
-	return 0;
-}
-
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n"
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
-#ifdef HAVE_GETOPT_LONG
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-#else
-         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-#endif
-         "  smartctl -a /dev/scsi21\n"
-         "             (Prints all information for SCSI disk on ASPI adapter 2, ID 1)\n"
-  );
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// ATA Interface
-/////////////////////////////////////////////////////////////////////////////
-
-// SMART_* IOCTLs, also known as DFP_* (Disk Fault Protection)
-
-// Deklarations from:
-// http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/ntdddisk.h?rev=1.3
-
-#define FILE_READ_ACCESS       0x0001
-#define FILE_WRITE_ACCESS      0x0002
-#define METHOD_BUFFERED             0
-#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
-
-#define FILE_DEVICE_DISK	   7
-#define IOCTL_DISK_BASE        FILE_DEVICE_DISK
-
-#define SMART_GET_VERSION \
-  CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
-
-#define SMART_RCV_DRIVE_DATA \
-  CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#define SMART_SEND_DRIVE_COMMAND \
-  CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#define SMART_CYL_LOW  0x4F
-#define SMART_CYL_HI   0xC2
-
-#pragma pack(1)
-
-typedef struct _GETVERSIONOUTPARAMS {
-	UCHAR  bVersion;
-	UCHAR  bRevision;
-	UCHAR  bReserved;
-	UCHAR  bIDEDeviceMap;
-	ULONG  fCapabilities;
-	ULONG  dwReserved[4];
-} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
-
-typedef struct _IDEREGS {
-	UCHAR  bFeaturesReg;
-	UCHAR  bSectorCountReg;
-	UCHAR  bSectorNumberReg;
-	UCHAR  bCylLowReg;
-	UCHAR  bCylHighReg;
-	UCHAR  bDriveHeadReg;
-	UCHAR  bCommandReg;
-	UCHAR  bReserved;
-} IDEREGS, *PIDEREGS, *LPIDEREGS;
-
-typedef struct _SENDCMDINPARAMS {
-	ULONG  cBufferSize;
-	IDEREGS  irDriveRegs;
-	UCHAR  bDriveNumber;
-	UCHAR  bReserved[3];
-	ULONG  dwReserved[4];
-	UCHAR  bBuffer[1];
-} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
-
-/* DRIVERSTATUS.bDriverError constants (just for info, not used)
-#define SMART_NO_ERROR                    0
-#define SMART_IDE_ERROR                   1
-#define SMART_INVALID_FLAG                2
-#define SMART_INVALID_COMMAND             3
-#define SMART_INVALID_BUFFER              4
-#define SMART_INVALID_DRIVE               5
-#define SMART_INVALID_IOCTL               6
-#define SMART_ERROR_NO_MEM                7
-#define SMART_INVALID_REGISTER            8
-#define SMART_NOT_SUPPORTED               9
-#define SMART_NO_IDE_DEVICE               10
-*/
-
-typedef struct _DRIVERSTATUS {
-	UCHAR  bDriverError;
-	UCHAR  bIDEError;
-	UCHAR  bReserved[2];
-	ULONG  dwReserved[2];
-} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
-
-typedef struct _SENDCMDOUTPARAMS {
-	ULONG  cBufferSize;
-	DRIVERSTATUS  DriverStatus;
-	UCHAR  bBuffer[1];
-} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
-
-#pragma pack()
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-static void print_ide_regs(const IDEREGS * r, int out)
-{
-	pout("%s=0x%02x,%s=0x%02x, SC=0x%02x, NS=0x%02x, CL=0x%02x, CH=0x%02x, SEL=0x%02x\n",
-	(out?"STS":"CMD"), r->bCommandReg, (out?"ERR":" FR"), r->bFeaturesReg,
-	r->bSectorCountReg, r->bSectorNumberReg, r->bCylLowReg, r->bCylHighReg, r->bDriveHeadReg);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// call SMART_* ioctl
-
-static int smart_ioctl(HANDLE hdevice, int drive, IDEREGS * regs, char * data, unsigned datasize)
-{
-	SENDCMDINPARAMS inpar;
-	unsigned char outbuf[sizeof(SENDCMDOUTPARAMS)-1 + 512];
-	const SENDCMDOUTPARAMS * outpar;
-	DWORD code, num_out;
-	unsigned int size_out;
-
-	assert(SMART_SEND_DRIVE_COMMAND == 0x07c084);
-	assert(SMART_RCV_DRIVE_DATA == 0x07c088);
-	assert(sizeof(SENDCMDINPARAMS)-1 == 32);
-	assert(sizeof(SENDCMDOUTPARAMS)-1 == 16);
-
-	memset(&inpar, 0, sizeof(inpar));
-	inpar.irDriveRegs = *regs;
-	// drive is set to 0-3 on Win9x only
-	inpar.irDriveRegs.bDriveHeadReg = 0xA0 | ((drive & 1) << 4);
-	inpar.bDriveNumber = drive;
-
-	assert(datasize == 0 || datasize == 512);
-	if (datasize) {
-		inpar.cBufferSize = size_out = 512;
-		code = SMART_RCV_DRIVE_DATA;
-	}
-	else if (regs->bFeaturesReg == ATA_SMART_STATUS) {
-		size_out = sizeof(IDEREGS); // ioctl returns new IDEREGS as data
-		code = SMART_SEND_DRIVE_COMMAND;
-	}
-	else {
-		size_out = 0;
-		code = SMART_SEND_DRIVE_COMMAND;
-	}
-
-	memset(&outbuf, 0, sizeof(outbuf));
-
-#ifdef _DEBUG
-	pout("DeviceIoControl(.,0x%lx,.,%lu,.,%lu,.,NULL)\n",
-		code, sizeof(SENDCMDINPARAMS)-1, sizeof(SENDCMDOUTPARAMS)-1 + size_out);
-	print_ide_regs(&inpar.irDriveRegs, 0);
-#endif
-	if (!DeviceIoControl(hdevice, code,
-             		&inpar, sizeof(SENDCMDINPARAMS)-1,
-               		outbuf, sizeof(SENDCMDOUTPARAMS)-1 + size_out,
-               		&num_out, NULL)) {
-		// CAUTION: DO NOT change "regs" Parameter in this case, see ata_command_interface()
-		long err = GetLastError();
-#ifdef _DEBUG
-		pout("DeviceIoControl failed, Error=%ld\n", err);
-#endif
-		errno = (   err == ERROR_INVALID_FUNCTION /*9x*/
-		         || err == ERROR_INVALID_PARAMETER/*NT/2K/XP*/ ? ENOSYS : EIO);
-		return -1;
-	}
-	// NOTE: On Win9x, inpar.irDriveRegs now contains the returned regs
-
-	outpar = (const SENDCMDOUTPARAMS *)outbuf;
-#ifdef _DEBUG
-	pout("DeviceIoControl returns %lu (%lu) bytes\n", num_out, outpar->cBufferSize);
-#endif
-
-	if (outpar->DriverStatus.bDriverError) {
-		pout("Error SMART IOCTL DriverError=0x%02x, IDEError=0x%02x\n",
-			outpar->DriverStatus.bDriverError, outpar->DriverStatus.bIDEError);
-		errno = EIO;
-		return -1;
-	}
-
-	if (datasize)
-		memcpy(data, outpar->bBuffer, 512);
-	else if (regs->bFeaturesReg == ATA_SMART_STATUS) {
-		*regs = *(const IDEREGS *)(outpar->bBuffer);
-#ifdef _DEBUG
-		print_ide_regs(regs, 1);
-#endif
-	}
-
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// IDE PASS THROUGH for W2K/XP (does not work on W9x/NT4)
-// Only used for SMART commands not supported by SMART_* IOCTLs
-//
-// Based on WinATA.cpp, 2002 c't/Matthias Withopf
-// ftp://ftp.heise.de/pub/ct/listings/0207-218.zip
-
-#define FILE_DEVICE_CONTROLLER  4
-#define IOCTL_SCSI_BASE         FILE_DEVICE_CONTROLLER
-
-#define IOCTL_IDE_PASS_THROUGH \
-  CTL_CODE(IOCTL_SCSI_BASE, 0x040A, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#pragma pack(1)
-
-typedef struct {
-	IDEREGS IdeReg;
-	ULONG   DataBufferSize;
-	UCHAR   DataBuffer[1];
-} ATA_PASS_THROUGH;
-
-#pragma pack()
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-static int ide_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, unsigned datasize)
-{ 
-	unsigned int size = sizeof(ATA_PASS_THROUGH)-1 + datasize;
-	ATA_PASS_THROUGH * buf = (ATA_PASS_THROUGH *)VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
-	DWORD num_out;
-	assert(sizeof(ATA_PASS_THROUGH)-1 == 12);
-	assert(IOCTL_IDE_PASS_THROUGH == 0x04d028);
-
-	buf->IdeReg = *regs;
-	buf->DataBufferSize = datasize;
-
-#ifdef _DEBUG
-	pout("DeviceIoControl(.,0x%x,.,%u,.,%u,.,NULL)\n",
-		IOCTL_IDE_PASS_THROUGH, size, size);
-	print_ide_regs(&buf->IdeReg, 0);
-#endif
-
-	if (!DeviceIoControl(hdevice, IOCTL_IDE_PASS_THROUGH, 
-		buf, size, buf, size, &num_out, NULL)) {
-		long err = GetLastError();
-#ifdef _DEBUG
-		pout("DeviceIoControl failed, Error=%ld\n", err);
-#endif
-		VirtualFree(buf, size, MEM_RELEASE);
-		errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);
-		return -1;
-	}
-
-#ifdef _DEBUG
-	pout("DeviceIoControl returns %lu (%lu) bytes\n", num_out, buf->DataBufferSize);
-	print_ide_regs(&buf->IdeReg, 1);
-#endif
-
-	if (datasize)
-		memcpy(data, buf->DataBuffer, datasize);
-	VirtualFree(buf, size, MEM_RELEASE);
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-static HANDLE h_ata_ioctl = 0;
-static int ide_pass_through_broken = 0;
-
-
-// Print SMARTVSD error message, return errno
-
-static int smartvsd_error()
-{
-	char path[MAX_PATH];
-	unsigned len;
-	if (!(5 <= (len = GetSystemDirectoryA(path, MAX_PATH)) && len < MAX_PATH/2))
-		return ENOENT;
-	strcpy(path+len, "\\IOSUBSYS\\SMARTVSD.VXD");
-	if (!access(path, 0)) {
-#ifdef _DEBUG
-		pout("Driver \"%s\" not loaded,\n"
-		     " possibly no IDE/ATA devices present.\n", path);
-#endif
-		return ENOENT;
-	}
-	// Some Windows versions install SMARTVSD.VXD in SYSTEM directory
-	// http://support.microsoft.com/default.aspx?scid=kb;en-us;265854
-	strcpy(path+len, "\\SMARTVSD.VXD");
-	if (!access(path, 0)) {
-		path[len] = 0;
-		pout("SMART driver is not properly installed,\n"
-		     " move SMARTVSD.VXD from \"%s\" to \"%s\\IOSUBSYS\"\n"
-		     " and reboot Windows.\n", path, path);
-		return ENOSYS;
-	}
-	path[len] = 0;
-	pout("SMARTVSD.VXD is missing in folder \"%s\\IOSUBSYS\".\n", path);
-	return ENOENT;
-}
-
-
-static int ata_open(int drive)
-{
-	int win9x;
-	char devpath[30];
-	GETVERSIONOUTPARAMS vers;
-	DWORD num_out;
-
-	assert(SMART_GET_VERSION == 0x074080);
-	assert(sizeof(GETVERSIONOUTPARAMS) == 24);
-
-	// TODO: This version does not allow to open more than 1 ATA devices
-	if (h_ata_ioctl) {
-		errno = ENFILE;
-		return -1;
-	}
-
-	win9x = ((GetVersion() & 0x80000000) != 0);
-
-	if (!(0 <= drive && drive <= (win9x ? 3 : 9))) {
-		errno = ENOENT;
-		return -1;
-	}
-	// path depends on Windows Version
-	if (win9x)
-		strcpy(devpath, "\\\\.\\SMARTVSD");
-	else
-		snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", drive);
-
-	// Open device
-	if ((h_ata_ioctl = CreateFileA(devpath,
-		GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
-		NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
-		long err = GetLastError();	
-		pout("Cannot open device %s, Error=%ld\n", devpath, err);
-		if (win9x && err == ERROR_FILE_NOT_FOUND)
-			errno = smartvsd_error();
-		else
-			errno = (err == ERROR_FILE_NOT_FOUND ? ENOENT : EPERM);
-		h_ata_ioctl = 0;
-		return -1;
-	}
-
-	// Get drive map
-	memset(&vers, 0, sizeof(vers));
-	if (!DeviceIoControl(h_ata_ioctl, SMART_GET_VERSION,
-		NULL, 0, &vers, sizeof(vers), &num_out, NULL)) {
-		pout("%s: SMART_GET_VERSION failed, Error=%ld\n", devpath, GetLastError());
-		if (!win9x)
-			pout("If this is a SCSI disk, try \"scsi<adapter><id>\".\n");
-		if (!is_permissive()) {
-			CloseHandle(h_ata_ioctl); h_ata_ioctl = 0;
-			errno = ENOSYS;
-			return -1;
-		}
-	}
-
-#ifdef _DEBUG
-	pout("SMART_GET_VERSION (%ld bytes): Vers = %d.%d, Caps = 0x%lx, DeviceMap = 0x%02x\n",
-		num_out, vers.bVersion, vers.bRevision, vers.fCapabilities, vers.bIDEDeviceMap);
-#endif
-
-	// TODO: Check vers.fCapabilities here?
-
-	if (!win9x)
-		// NT4/2K/XP: Drive exists, Drive number not necessary for ioctl
-		return 0;
-
-	// Win9x/ME: Check device presence & type
-	if (((vers.bIDEDeviceMap >> drive) & 0x11) != 0x01) {
-		unsigned char atapi = (vers.bIDEDeviceMap >> drive) & 0x10;
-		pout((  atapi
-		      ? "Drive %d is an ATAPI device (IDEDeviceMap=0x%02x).\n"
-			  : "Drive %d does not exist (IDEDeviceMap=0x%02x).\n"),
-			drive, vers.bIDEDeviceMap);
-		// Win9x Drive existence check may not work as expected
-		// The atapi.sys driver incorrectly fills in the bIDEDeviceMap with 0x01
-		// http://support.microsoft.com/support/kb/articles/Q196/1/20.ASP
-		if (!is_permissive()) {
-			CloseHandle(h_ata_ioctl); h_ata_ioctl = 0;
-			errno = (atapi ? ENOSYS : ENOENT);
-			return -1;
-		}
-	}
-	// Use drive number as fd for ioctl
-	return drive;
-}
-
-
-static void ata_close(int fd)
-{
-	ARGUSED(fd);
-	CloseHandle(h_ata_ioctl);
-	h_ata_ioctl = 0;
-}
-
-
-// Scan for ATA drives, return bitmask of drives present
-
-static unsigned ata_scan()
-{
-	unsigned drives = 0;
-	int win9x = ((GetVersion() & 0x80000000) != 0);
-	int i;
-
-	for (i = 0; i <= 9; i++) {
-		char devpath[30];
-		GETVERSIONOUTPARAMS vers;
-		DWORD num_out;
-		HANDLE h;
-		if (win9x)
-			strcpy(devpath, "\\\\.\\SMARTVSD");
-		else
-			snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", i);
-
-		// Open device
-		if ((h = CreateFileA(devpath,
-			GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
-			NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
-			if (win9x)
-				break; // SMARTVSD.VXD missing or no ATA devices
-			continue; // Disk not found or access denied (break;?)
-		}
-
-		// Get drive map
-		memset(&vers, 0, sizeof(vers));
-		if (!DeviceIoControl(h, SMART_GET_VERSION,
-			NULL, 0, &vers, sizeof(vers), &num_out, NULL)) {
-			CloseHandle(h);
-			if (win9x)
-				break; // Should not happen
-			continue; // Non ATA disk or no SMART ioctl support (possibly SCSI disk)
-		}
-		CloseHandle(h);
-
-		if (win9x) {
-			// Check ATA device presence, remove ATAPI devices
-			drives = (vers.bIDEDeviceMap & 0xf) & ~((vers.bIDEDeviceMap >> 4) & 0xf);
-			break;
-		}
-
-		// ATA drive exists and driver supports SMART ioctl
-		drives |= 1 << i;
-	}
-
-	return drives;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char * data)
-{
-	IDEREGS regs;
-	int copydata;
-
-	if (!(0 <= fd && fd <= 3)) {
-	  errno = EBADF;
-	  return -1;
-	}
-
-	// CMD,CYL default to SMART, changed by P?IDENTIFY
-	memset(&regs, 0, sizeof(regs));
-	regs.bCommandReg = ATA_SMART_CMD;
-	regs.bCylHighReg = SMART_CYL_HI; regs.bCylLowReg = SMART_CYL_LOW;
-	copydata = 0;
-
-	switch (command) {
-	  case CHECK_POWER_MODE:
-	  case WRITE_LOG:
-		// TODO. Not supported by SMART IOCTL
-		errno = ENOSYS;
-		return -1;
-	  case READ_VALUES:
-		regs.bFeaturesReg = ATA_SMART_READ_VALUES;
-		regs.bSectorNumberReg = regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case READ_THRESHOLDS:
-		regs.bFeaturesReg = ATA_SMART_READ_THRESHOLDS;
-		regs.bSectorNumberReg = regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case READ_LOG:
-		regs.bFeaturesReg = ATA_SMART_READ_LOG_SECTOR;
-		regs.bSectorNumberReg = select;
-		regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case IDENTIFY:
-		regs.bCommandReg = ATA_IDENTIFY_DEVICE;
-		regs.bCylLowReg = regs.bCylHighReg = 0;
-		regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case PIDENTIFY:
-		regs.bCommandReg = ATA_IDENTIFY_PACKET_DEVICE;
-		regs.bCylLowReg = regs.bCylHighReg = 0;
-		regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case ENABLE:
-		regs.bFeaturesReg = ATA_SMART_ENABLE;
-		regs.bSectorNumberReg = 1;
-		break;
-	  case DISABLE:
-		regs.bFeaturesReg = ATA_SMART_DISABLE;
-		regs.bSectorNumberReg = 1;
-		break;
-	  case STATUS:
-	  case STATUS_CHECK:
-		regs.bFeaturesReg = ATA_SMART_STATUS;
-		break;
-	  case AUTO_OFFLINE:
-		regs.bFeaturesReg = ATA_SMART_AUTO_OFFLINE;
-		regs.bSectorCountReg = select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-		break;
-	  case AUTOSAVE:
-		regs.bFeaturesReg = ATA_SMART_AUTOSAVE;
-		regs.bSectorCountReg = select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-		break;
-	  case IMMEDIATE_OFFLINE:
-		regs.bFeaturesReg = ATA_SMART_IMMEDIATE_OFFLINE;
-		regs.bSectorNumberReg = select;
-		break;
-	  default:
-		pout("Unrecognized command %d in win32_ata_command_interface()\n"
-		 "Please contact " PACKAGE_BUGREPORT "\n", command);
-		errno = ENOSYS;
-		return -1;
-	}
-
-	if (smart_ioctl(h_ata_ioctl, fd, &regs, data, (copydata?512:0))) {
-		// Read log only supported on Win9x, retry with pass through command
-		// CAUTION: smart_ioctl() MUST NOT change "regs" Parameter in this case
-		if (errno == ENOSYS && command == READ_LOG && !ide_pass_through_broken) {
-			errno = 0;
-			memset(data, 0, 512);
-			if (ide_pass_through_ioctl(h_ata_ioctl, &regs, data, 512))
-				return -1;
-			if (!nonempty(data, 512)) {
-				// Nothing useful returned => ioctl probably broken
-				pout("IOCTL_IDE_PASS_THROUGH does not work on your version of Windows\n");
-				ide_pass_through_broken = 1; // Do not retry (smartd)
-				errno = ENOSYS;
-				return -1;
-			}
-			return 0;
-		}
-		return -1;
-	}
-
-	if (command == STATUS_CHECK) {
-		// Cyl low and Cyl high unchanged means "Good SMART status"
-		if (regs.bCylHighReg == SMART_CYL_HI && regs.bCylLowReg == SMART_CYL_LOW)
-		  return 0;
-
-		// These values mean "Bad SMART status"
-		if (regs.bCylHighReg == 0x2c && regs.bCylLowReg == 0xf4)
-		  return 1;
-
-		// We haven't gotten output that makes sense; print out some debugging info
-		syserror("Error SMART Status command failed");
-		pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
-		print_ide_regs(&regs, 1);
-		errno = EIO;
-		return -1;
-	}
-
-	return 0;
-}
-
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data)
-{
-	static int warned = 0;
-	ARGUSED(fd); ARGUSED(disknum); ARGUSED(escalade_type); ARGUSED(command); ARGUSED(select); ARGUSED(data);
-	if (!warned) {
-		  pout(
-		"#######################################################################\n"
-		"3ware Escalade Controller command routine escalade_command_interface()\n"
-		"NOT IMPLEMENTED under Win32.\n"
-		"Please contact " PACKAGE_BUGREPORT " if\n"
-		"you want to help in porting smartmontools to Win32.\n"
-		"#######################################################################\n"
-		"\n");
-		warned = 1;
-	}
-	errno = ENOSYS;
-	return -1;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// ASPI Interface
-/////////////////////////////////////////////////////////////////////////////
-
-#pragma pack(1)
-
-#define ASPI_SENSE_SIZE 18
-
-// ASPI SCSI Request block header
-
-typedef struct {
-	unsigned char cmd;             // 00: Command code
-	unsigned char status;          // 01: ASPI status
-	unsigned char adapter;         // 02: Host adapter number
-	unsigned char flags;           // 03: Request flags
-	unsigned char reserved[4];     // 04: 0
-} ASPI_SRB_HEAD;
-
-// SRB for host adapter inquiry
-
-typedef struct {
-	ASPI_SRB_HEAD h;               // 00: Header
-	unsigned char adapters;        // 08: Number of adapters
-	unsigned char target_id;       // 09: Target ID ?
-	char manager_id[16];           // 10: SCSI manager ID
-	char adapter_id[16];           // 26: Host adapter ID
-	unsigned char parameters[16];  // 42: Host adapter unique parmameters
-} ASPI_SRB_INQUIRY;
-
-// SRB for get device type
-
-typedef struct {
-	ASPI_SRB_HEAD h;               // 00: Header
-	unsigned char target_id;       // 08: Target ID
-	unsigned char lun;             // 09: LUN
-	unsigned char devtype;         // 10: Device type
-	unsigned char reserved;        // 11: Reserved
-} ASPI_SRB_DEVTYPE;
-
-// SRB for SCSI I/O
-
-typedef struct {
-	ASPI_SRB_HEAD h;               // 00: Header
-	unsigned char target_id;       // 08: Target ID
-	unsigned char lun;             // 09: LUN
-	unsigned char reserved[2];     // 10: Reserved
-	unsigned long data_size;       // 12: Data alloc. lenght
-	void * data_addr;              // 16: Data buffer pointer
-	unsigned char sense_size;      // 20: Sense alloc. length
-	unsigned char cdb_size;        // 21: CDB length
-	unsigned char host_status;     // 22: Host status
-	unsigned char target_status;   // 23: Target status
-	void * event_handle;           // 24: Event handle
-	unsigned char workspace[20];   // 28: ASPI workspace
-	unsigned char cdb[16+ASPI_SENSE_SIZE];
-} ASPI_SRB_IO;
-
-// Macro to retrieve start of sense information
-#define ASPI_SRB_SENSE(srb,cdbsz) ((srb)->cdb + 16)
-
-// SRB union
-
-typedef union {
-	ASPI_SRB_HEAD h;       // Common header
-	ASPI_SRB_INQUIRY q;    // Inquiry
-	ASPI_SRB_DEVTYPE t;    // Device type
-	ASPI_SRB_IO i;         // I/O
-} ASPI_SRB;
-
-#pragma pack()
-
-// ASPI commands
-#define ASPI_CMD_ADAPTER_INQUIRE        0x00
-#define ASPI_CMD_GET_DEVICE_TYPE        0x01
-#define ASPI_CMD_EXECUTE_IO             0x02
-#define ASPI_CMD_ABORT_IO               0x03
-
-// Request flags
-#define ASPI_REQFLAG_DIR_TO_HOST        0x08
-#define ASPI_REQFLAG_DIR_TO_TARGET      0x10
-#define ASPI_REQFLAG_DIR_NO_XFER        0x18
-#define ASPI_REQFLAG_EVENT_NOTIFY       0x40
-
-// ASPI status
-#define ASPI_STATUS_IN_PROGRESS         0x00
-#define ASPI_STATUS_NO_ERROR            0x01
-#define ASPI_STATUS_ABORTED             0x02
-#define ASPI_STATUS_ABORT_ERR           0x03
-#define ASPI_STATUS_ERROR               0x04
-#define ASPI_STATUS_INVALID_COMMAND     0x80
-#define ASPI_STATUS_INVALID_ADAPTER     0x81
-#define ASPI_STATUS_INVALID_TARGET      0x82
-#define ASPI_STATUS_NO_ADAPTERS         0xE8
-
-// Adapter (host) status
-#define ASPI_HSTATUS_NO_ERROR           0x00
-#define ASPI_HSTATUS_SELECTION_TIMEOUT  0x11
-#define ASPI_HSTATUS_DATA_OVERRUN       0x12
-#define ASPI_HSTATUS_BUS_FREE           0x13
-#define ASPI_HSTATUS_BUS_PHASE_ERROR    0x14
-#define ASPI_HSTATUS_BAD_SGLIST         0x1A
-
-// Target status
-#define ASPI_TSTATUS_NO_ERROR           0x00
-#define ASPI_TSTATUS_CHECK_CONDITION    0x02
-#define ASPI_TSTATUS_BUSY               0x08
-#define ASPI_TSTATUS_RESERV_CONFLICT    0x18
-
-
-static HINSTANCE h_aspi_dll; // DLL handle
-static UINT (* aspi_entry)(ASPI_SRB * srb); // ASPI entrypoint
-static unsigned num_aspi_adapters;
-
-#ifdef __CYGWIN__
-// h_aspi_dll+aspi_entry is not inherited by Cygwin's fork()
-static DWORD aspi_dll_pid; // PID of DLL owner to detect fork()
-#define aspi_entry_valid() (aspi_entry && (aspi_dll_pid == GetCurrentProcessId()))
-#else
-#define aspi_entry_valid() (!!aspi_entry)
-#endif
-
-
-static int aspi_call(ASPI_SRB * srb)
-{
-	int i;
-	aspi_entry(srb);
-	i = 0;
-	while (((volatile ASPI_SRB *)srb)->h.status == ASPI_STATUS_IN_PROGRESS) {
-		if (++i > 100/*10sek*/) {
-			pout("ASPI Adapter %u: Timeout\n", srb->h.adapter);
-			aspi_entry = 0;
-			h_aspi_dll = INVALID_HANDLE_VALUE;
-			errno = EIO;
-			return -1;
-		}
-#ifdef _DEBUG
-		pout("ASPI Wait %d\n", i);
-#endif
-		Sleep(100);
-	}
-	return 0;
-}
-
-
-// Get ASPI entrypoint from wnaspi32.dll
-
-static FARPROC aspi_get_address(const char * name, int verbose)
-{
-	FARPROC addr;
-	assert(h_aspi_dll && h_aspi_dll != INVALID_HANDLE_VALUE);
-
-	if (!(addr = GetProcAddress(h_aspi_dll, name))) {
-		if (verbose)
-			pout("Missing %s() in WNASPI32.DLL\n", name);
-		aspi_entry = 0;
-		FreeLibrary(h_aspi_dll);
-		h_aspi_dll = INVALID_HANDLE_VALUE;
-		errno = ENOSYS;
-		return 0;
-	}
-	return addr;
-}
-
-
-static int aspi_open_dll(int verbose)
-{
-	UINT (*aspi_info)(void);
-	UINT info, rc;
-
-	assert(!aspi_entry_valid());
-
-	// Check structure layout
-	assert(sizeof(ASPI_SRB_HEAD) == 8);
-	assert(sizeof(ASPI_SRB_INQUIRY) == 58);
-	assert(sizeof(ASPI_SRB_DEVTYPE) == 12);
-	assert(sizeof(ASPI_SRB_IO) == 64+ASPI_SENSE_SIZE);
-	assert(offsetof(ASPI_SRB,h.cmd) == 0);
-	assert(offsetof(ASPI_SRB,h.flags) == 3);
-	assert(offsetof(ASPI_SRB_IO,lun) == 9);
-	assert(offsetof(ASPI_SRB_IO,data_addr) == 16);
-	assert(offsetof(ASPI_SRB_IO,workspace) == 28);
-	assert(offsetof(ASPI_SRB_IO,cdb) == 48);
-
-	if (h_aspi_dll == INVALID_HANDLE_VALUE) {
-		// do not retry
-		errno = ENOENT;
-		return -1;
-	}
-
-	// Load ASPI DLL
-	if (!(h_aspi_dll = LoadLibraryA("WNASPI32.DLL"))) {
-		if (verbose)
-			pout("Cannot load WNASPI32.DLL, Error=%ld\n", GetLastError());
-		h_aspi_dll = INVALID_HANDLE_VALUE;
-		errno = ENOENT;
-		return -1;
-	}
-
-	// Get ASPI entrypoints
-	if (!(aspi_info = (UINT (*)(void))aspi_get_address("GetASPI32SupportInfo", verbose)))
-		return -1;
-	if (!(aspi_entry = (UINT (*)(ASPI_SRB *))aspi_get_address("SendASPI32Command", verbose)))
-		return -1;
-
-	// Init ASPI manager and get number of adapters
-	info = (aspi_info)();
-#ifdef _DEBUG
-	pout("GetASPI32SupportInfo() returns 0x%04x\n", info);
-#endif
-	rc = (info >> 8) & 0xff;
-	if (rc == ASPI_STATUS_NO_ADAPTERS) {
-		num_aspi_adapters = 0;
-	}
-	else if (rc == ASPI_STATUS_NO_ERROR) {
-		num_aspi_adapters = info & 0xff;
-	}
-	else {
-		if (verbose)
-			pout("Got strange 0x%04x from GetASPI32SupportInfo()\n", info);
-		aspi_entry = 0;
-		FreeLibrary(h_aspi_dll);
-		h_aspi_dll = INVALID_HANDLE_VALUE;
-		errno = ENOENT;
-		return -1;
-	}
-
-#ifdef __CYGWIN__
-	// save PID to detect fork() in aspi_entry_valid()
-	aspi_dll_pid = GetCurrentProcessId();
-#endif
-	assert(aspi_entry_valid());
-	return 0;
-}
-
-
-static int aspi_io_call(ASPI_SRB * srb)
-{
-	HANDLE event;
-	// Create event
-	if (!(event = CreateEventA(NULL, FALSE, FALSE, NULL))) {
-		pout("CreateEvent(): Error=%ld\n", GetLastError()); return -EIO;
-	}
-	srb->i.event_handle = event;
-	srb->h.flags |= ASPI_REQFLAG_EVENT_NOTIFY;
-	// Start ASPI request
-	aspi_entry(srb);
-	if (((volatile ASPI_SRB *)srb)->h.status == ASPI_STATUS_IN_PROGRESS) {
-		// Wait for event
-		DWORD rc = WaitForSingleObject(event, 30*1000L);
-		if (rc != WAIT_OBJECT_0) {
-			if (rc == WAIT_TIMEOUT) {
-				pout("ASPI Timeout\n");
-			}
-			else {
-				pout("WaitForSingleObject(%lx) = 0x%lx,%ld, Error=%ld\n",
-					(unsigned long)event, rc, rc, GetLastError());
-			}
-			// TODO: ASPI_ABORT_IO command
-			aspi_entry = 0;
-			h_aspi_dll = INVALID_HANDLE_VALUE;
-			return -EIO;
-		}
-	}
-	CloseHandle(event);
-	return 0;
-}
-
-
-static int aspi_open(unsigned adapter, unsigned id)
-{
-	if (!(adapter <= 9 && id < 16)) {
-		errno = ENOENT;
-		return -1;
-	}
-
-	if (!aspi_entry_valid()) {
-		if (aspi_open_dll(1/*verbose*/))
-			return -1;
-	}
-
-	// Adapter OK?
-	if (adapter >= num_aspi_adapters) {
-		pout("ASPI Adapter %d does not exist (%d Adapter(s) detected).\n", adapter, num_aspi_adapters);
-		if (!is_permissive()) {
-			errno = ENOENT;
-			return -1;
-		}
-	}
-
-	return (0x0100 | ((adapter & 0xf)<<4) | (id & 0xf));
-}
-
-
-static void aspi_close(int fd)
-{
-	// No FreeLibrary(h_aspi_dll) to prevent problems with ASPI threads
-	ARGUSED(fd);
-}
-
-
-// Scan for SCSI drives, return bitmask [adapter:0-3][id:0-7] of drives present
-
-static unsigned long aspi_scan()
-{
-	unsigned long drives = 0;
-	unsigned ad, nad;
-
-	if (!aspi_entry_valid()) {
-		if (aspi_open_dll(0/*quiet*/))
-			return 0;
-	}
-
-	nad = num_aspi_adapters;
-	if (nad >= 4)
-		nad = 4;
-	for (ad = 0; ad < nad; ad++) {
-		ASPI_SRB srb; int id;
-		// Get adapter name
-		memset(&srb, 0, sizeof(srb));
-		srb.h.cmd = ASPI_CMD_ADAPTER_INQUIRE;
-		srb.h.adapter = ad;
-		if (aspi_call(&srb))
-			return 0;
-#ifdef _DEBUG
-		pout("ASPI Adapter %u: %02x,\"%.16s\"\n", ad, srb.h.status, srb.q.adapter_id);
-#endif
-		if (srb.h.status != ASPI_STATUS_NO_ERROR)
-			continue;
-
-		// Skip ATA/ATAPI devices
-		srb.q.adapter_id[sizeof(srb.q.adapter_id)-1] = 0;
-		if (strstr(srb.q.adapter_id, "ATAPI"))
-			continue;
-
-		for (id = 0; id <= 7; id++) {
-			// Get device type
-			memset(&srb, 0, sizeof(srb));
-			srb.h.cmd = ASPI_CMD_GET_DEVICE_TYPE;
-			srb.h.adapter = ad; srb.i.target_id = id;
-			if (aspi_call(&srb))
-				return 0;
-#ifdef _DEBUG
-			pout("Device type for scsi%u%x: %02x,%02x\n", ad, id, srb.h.status, srb.t.devtype);
-#endif
-			if (srb.h.status == ASPI_STATUS_NO_ERROR && srb.t.devtype == 0x00/*HDD*/)
-				drives |= 1 << ((ad<<3)+id);
-		}
-	}
-	return drives;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-	ASPI_SRB srb;
-
-	if (!aspi_entry_valid())
-		return -EBADF;
-	if (!((fd & ~0xff) == 0x100))
-		return -EBADF;
-
-	if (!(iop->cmnd_len == 6 || iop->cmnd_len == 10 || iop->cmnd_len == 12)) {
-		pout("do_scsi_cmnd_io: bad CDB length\n");
-		return -EINVAL;
-	}
-
-	if (report > 0) {
-		// From os_linux.c
-		int k, j;
-		const unsigned char * ucp = iop->cmnd;
-		const char * np;
-		char buff[256];
-		const int sz = (int)sizeof(buff);
-
-		np = scsi_get_opcode_name(ucp[0]);
-		j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
-		for (k = 0; k < (int)iop->cmnd_len; ++k)
-			j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
-		if ((report > 1) && 
-			(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-			int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-			j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
-						  "data, len=%d%s:\n", (int)iop->dxfer_len,
-						  (trunc ? " [only first 256 bytes shown]" : ""));
-			dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-		}
-		else
-			j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
-		pout(buff);
-	}
-
-	memset(&srb, 0, sizeof(srb));
-	srb.h.cmd = ASPI_CMD_EXECUTE_IO;
-	srb.h.adapter = ((fd >> 4) & 0xf);
-	srb.i.target_id = (fd & 0xf);
-	//srb.i.lun = 0;
-	srb.i.sense_size = ASPI_SENSE_SIZE;
-	srb.i.cdb_size = iop->cmnd_len;
-	memcpy(srb.i.cdb, iop->cmnd, iop->cmnd_len);
-
-	switch (iop->dxfer_dir) {
-		case DXFER_NONE:
-			srb.h.flags = ASPI_REQFLAG_DIR_NO_XFER;
-			break;
-		case DXFER_FROM_DEVICE:
-			srb.h.flags = ASPI_REQFLAG_DIR_TO_HOST;
-			srb.i.data_size = iop->dxfer_len;
-			srb.i.data_addr = iop->dxferp;
-			break;
-		case DXFER_TO_DEVICE:
-			srb.h.flags = ASPI_REQFLAG_DIR_TO_TARGET;
-			srb.i.data_size = iop->dxfer_len;
-			srb.i.data_addr = iop->dxferp;
-			break;
-		default:
-			pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-			return -EINVAL;
-	}
-
-	iop->resp_sense_len = 0;
-	iop->scsi_status = 0;
-	iop->resid = 0;
-
-	if (aspi_io_call(&srb)) {
-		// Timeout
-		return -EIO;
-	}
-
-	if (srb.h.status != ASPI_STATUS_NO_ERROR) {
-		if (   srb.h.status        == ASPI_STATUS_ERROR
-		    && srb.i.host_status   == ASPI_HSTATUS_NO_ERROR
-		    && srb.i.target_status == ASPI_TSTATUS_CHECK_CONDITION) {
-			// Sense valid
-			const unsigned char * sense = ASPI_SRB_SENSE(&srb.i, iop->cmnd_len);
-			int len = (ASPI_SENSE_SIZE < iop->max_sense_len ? ASPI_SENSE_SIZE : iop->max_sense_len);
-			iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-			if (len > 0 && iop->sensep) {
-				memcpy(iop->sensep, sense, len);
-				iop->resp_sense_len = len;
-				if (report > 1) {
-					pout("  >>> Sense buffer, len=%d:\n", (int)len);
-					dStrHex(iop->sensep, len , 1);
-				}
-			}
-			if (report) {
-				pout("  sense_key=%x asc=%x ascq=%x\n",
-				 sense[2] & 0xf, sense[12], sense[13]);
-			}
-			return 0;
-		}
-		else {
-			if (report)
-				pout("  ASPI call failed, (0x%02x,0x%02x,0x%02x)\n", srb.h.status, srb.i.host_status, srb.i.target_status);
-			return -EIO;
-		}
-	}
-
-	if (report > 0)
-		pout("  OK\n");
-
-	if (iop->dxfer_dir == DXFER_FROM_DEVICE && report > 1) {
-		 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-		 pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-			  (trunc ? " [only first 256 bytes shown]" : ""));
-				dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-	}
-
-	return 0;
-}
diff --git a/sm5/os_win32.cpp b/sm5/os_win32.cpp
deleted file mode 100644
index c21b201d1ed2cac78ccc60820e206d4619e1331c..0000000000000000000000000000000000000000
--- a/sm5/os_win32.cpp
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*
- * os_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "config.h"
-#include "atacmds.h"
-#include "extern.h"
-extern smartmonctrl * con; // con->permissive
-#include "int64.h"
-#include "scsicmds.h"
-#include "utility.h"
-extern int64_t bytes; // malloc() byte count
-
-#include <errno.h>
-#ifdef _DEBUG
-#include <assert.h>
-#else
-#define assert(x) /**/
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <stddef.h> // offsetof()
-#include <io.h> // access()
-
-#define ARGUSED(x) ((void)(x))
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.16 2004/08/13 13:57:12 arvoreen Exp $"
-ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-
-static int ata_open(int drive);
-static void ata_close(int fd);
-static unsigned ata_scan(void);
-
-static int aspi_open(unsigned adapter, unsigned id);
-static void aspi_close(int fd);
-static unsigned long aspi_scan(void);
-
-
-static int is_permissive()
-{
-	if (con->permissive <= 0) {
-		pout("To continue, add one or more '-T permissive' options.\n");
-		return 0;
-	}
-	con->permissive--;
-	return 1;
-}
-
-static const char * skipdev(const char * s)
-{
-	return (!strncmp(s, "/dev/", 5) ? s + 5 : s);
-}
-
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char * dev_name)
-{
-	dev_name = skipdev(dev_name);
-	if (!strncmp(dev_name, "hd", 2))
-		return CONTROLLER_ATA;
-	if (!strncmp(dev_name, "scsi", 4))
-		return CONTROLLER_SCSI;
-	return CONTROLLER_UNKNOWN;
-}
-
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist), the
-// others each contain null-terminated character strings.
-int make_device_names (char*** devlist, const char* type)
-{
-	unsigned long drives;
-	int i, j, n, sz, scsi;
-	const char * path;
-
-	if (!strcmp(type, "ATA")) {
-		// bit i set => drive i present
-		drives = ata_scan();
-		path = "/dev/hda";
-		scsi = 0;
-	}
-	else if (!strcmp(type, "SCSI")) {
-		// bit i set => drive with ID (i & 0x7) on adapter (i >> 3) present
-		drives = aspi_scan();
-		path = "/dev/scsi00";
-		scsi = 1;
-	}
-	else
-		return -1;
-
-	if (!drives)
-		return 0;
-
-	// Count #drives
-	n = 0;
-	for (i = 0; i < 32; i++) {
-		if (drives & (1 << i))
-			n++;
-	}
-	assert(n > 0);
-	if (n == 0)
-		return 0;
-
-	// Alloc devlist
-	assert(scsi || n <= 9);
-	sz = n * sizeof(char **);
-	*devlist = (char **)malloc(sz); bytes += sz;
-
-	// Add devices
-	for (i = j = 0; i < n; i++) {
-		char * s;
-		sz = strlen(path)+1;
-		s = (char *)malloc(sz); bytes += sz;
-		strcpy(s, path);
-		while (j < 32 && !(drives & (1 << j)))
-			j++;
-		assert(j < 32);
-		if (!scsi) {
-			assert(j <= 9);
-			s[sz-2] += j; // /dev/hd[a-j]
-		}
-		else {
-			s[sz-3] += (j >> 3);  // /dev/scsi[0-3].
-			s[sz-2] += (j & 0x7); //          .....[0-7]
-		}
-		(*devlist)[i] = s;
-		j++;
-	}
-	return n;
-}
-
-
-// Like open().  Return positive integer handle, only used by
-// functions below.  type="ATA" or "SCSI".  If you need to store extra
-// information about your devices, create a private internal array
-// within this file (see os_freebsd.c for an example).
-int deviceopen(const char * pathname, char *type)
-{
-	int len;
-	pathname = skipdev(pathname);
-	len = strlen(pathname);
-
-	if (!strcmp(type, "ATA")) {
-		// hd[a-z] => ATA 0-9
-		if (!(len  == 3 && pathname[0] == 'h' && pathname[1] == 'd'
-			  && 'a' <= pathname[2] && pathname[2] <= 'j')) {
-			errno = ENOENT;
-			return -1;
-		}
-		return ata_open(pathname[2] - 'a');
-	}
-
-	if (!strcmp(type, "SCSI")) {
-		// scsi[0-9][0-f] => SCSI Adapter 0-9, ID 0-15, LUN 0
-		unsigned adapter = ~0, id = ~0; int n = -1;
-		if (!(sscanf(pathname,"scsi%1u%1x%n", &adapter, &id, &n) == 2 && n == len)) {
-			errno = ENOENT;
-			return -1;
-		}
-		return aspi_open(adapter, id);
-	}
-	errno = ENOENT;
-	return -1;
-}
-
-
-// Like close().  Acts only on handles returned by above function.
-// (Never called in smartctl!)
-int deviceclose(int fd)
-{
-	if (fd < 0x100) {
-		ata_close(fd);
-	}
-	else {
-		aspi_close(fd);
-	}
-	return 0;
-}
-
-
-// print examples for smartctl
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n"
-         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
-#ifdef HAVE_GETOPT_LONG
-         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
-         "                                              (Enables SMART on first disk)\n\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
-         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-#else
-         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-         "                                      (Prints Self-Test & Attribute errors)\n"
-#endif
-         "  smartctl -a /dev/scsi21\n"
-         "             (Prints all information for SCSI disk on ASPI adapter 2, ID 1)\n"
-  );
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// ATA Interface
-/////////////////////////////////////////////////////////////////////////////
-
-// SMART_* IOCTLs, also known as DFP_* (Disk Fault Protection)
-
-// Deklarations from:
-// http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/ntdddisk.h?rev=1.3
-
-#define FILE_READ_ACCESS       0x0001
-#define FILE_WRITE_ACCESS      0x0002
-#define METHOD_BUFFERED             0
-#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
-
-#define FILE_DEVICE_DISK	   7
-#define IOCTL_DISK_BASE        FILE_DEVICE_DISK
-
-#define SMART_GET_VERSION \
-  CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
-
-#define SMART_RCV_DRIVE_DATA \
-  CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#define SMART_SEND_DRIVE_COMMAND \
-  CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#define SMART_CYL_LOW  0x4F
-#define SMART_CYL_HI   0xC2
-
-#pragma pack(1)
-
-typedef struct _GETVERSIONOUTPARAMS {
-	UCHAR  bVersion;
-	UCHAR  bRevision;
-	UCHAR  bReserved;
-	UCHAR  bIDEDeviceMap;
-	ULONG  fCapabilities;
-	ULONG  dwReserved[4];
-} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
-
-typedef struct _IDEREGS {
-	UCHAR  bFeaturesReg;
-	UCHAR  bSectorCountReg;
-	UCHAR  bSectorNumberReg;
-	UCHAR  bCylLowReg;
-	UCHAR  bCylHighReg;
-	UCHAR  bDriveHeadReg;
-	UCHAR  bCommandReg;
-	UCHAR  bReserved;
-} IDEREGS, *PIDEREGS, *LPIDEREGS;
-
-typedef struct _SENDCMDINPARAMS {
-	ULONG  cBufferSize;
-	IDEREGS  irDriveRegs;
-	UCHAR  bDriveNumber;
-	UCHAR  bReserved[3];
-	ULONG  dwReserved[4];
-	UCHAR  bBuffer[1];
-} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
-
-/* DRIVERSTATUS.bDriverError constants (just for info, not used)
-#define SMART_NO_ERROR                    0
-#define SMART_IDE_ERROR                   1
-#define SMART_INVALID_FLAG                2
-#define SMART_INVALID_COMMAND             3
-#define SMART_INVALID_BUFFER              4
-#define SMART_INVALID_DRIVE               5
-#define SMART_INVALID_IOCTL               6
-#define SMART_ERROR_NO_MEM                7
-#define SMART_INVALID_REGISTER            8
-#define SMART_NOT_SUPPORTED               9
-#define SMART_NO_IDE_DEVICE               10
-*/
-
-typedef struct _DRIVERSTATUS {
-	UCHAR  bDriverError;
-	UCHAR  bIDEError;
-	UCHAR  bReserved[2];
-	ULONG  dwReserved[2];
-} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
-
-typedef struct _SENDCMDOUTPARAMS {
-	ULONG  cBufferSize;
-	DRIVERSTATUS  DriverStatus;
-	UCHAR  bBuffer[1];
-} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
-
-#pragma pack()
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-static void print_ide_regs(const IDEREGS * r, int out)
-{
-	pout("%s=0x%02x,%s=0x%02x, SC=0x%02x, NS=0x%02x, CL=0x%02x, CH=0x%02x, SEL=0x%02x\n",
-	(out?"STS":"CMD"), r->bCommandReg, (out?"ERR":" FR"), r->bFeaturesReg,
-	r->bSectorCountReg, r->bSectorNumberReg, r->bCylLowReg, r->bCylHighReg, r->bDriveHeadReg);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// call SMART_* ioctl
-
-static int smart_ioctl(HANDLE hdevice, int drive, IDEREGS * regs, char * data, unsigned datasize)
-{
-	SENDCMDINPARAMS inpar;
-	unsigned char outbuf[sizeof(SENDCMDOUTPARAMS)-1 + 512];
-	const SENDCMDOUTPARAMS * outpar;
-	DWORD code, num_out;
-	unsigned int size_out;
-
-	assert(SMART_SEND_DRIVE_COMMAND == 0x07c084);
-	assert(SMART_RCV_DRIVE_DATA == 0x07c088);
-	assert(sizeof(SENDCMDINPARAMS)-1 == 32);
-	assert(sizeof(SENDCMDOUTPARAMS)-1 == 16);
-
-	memset(&inpar, 0, sizeof(inpar));
-	inpar.irDriveRegs = *regs;
-	// drive is set to 0-3 on Win9x only
-	inpar.irDriveRegs.bDriveHeadReg = 0xA0 | ((drive & 1) << 4);
-	inpar.bDriveNumber = drive;
-
-	assert(datasize == 0 || datasize == 512);
-	if (datasize) {
-		inpar.cBufferSize = size_out = 512;
-		code = SMART_RCV_DRIVE_DATA;
-	}
-	else if (regs->bFeaturesReg == ATA_SMART_STATUS) {
-		size_out = sizeof(IDEREGS); // ioctl returns new IDEREGS as data
-		code = SMART_SEND_DRIVE_COMMAND;
-	}
-	else {
-		size_out = 0;
-		code = SMART_SEND_DRIVE_COMMAND;
-	}
-
-	memset(&outbuf, 0, sizeof(outbuf));
-
-#ifdef _DEBUG
-	pout("DeviceIoControl(.,0x%lx,.,%lu,.,%lu,.,NULL)\n",
-		code, sizeof(SENDCMDINPARAMS)-1, sizeof(SENDCMDOUTPARAMS)-1 + size_out);
-	print_ide_regs(&inpar.irDriveRegs, 0);
-#endif
-	if (!DeviceIoControl(hdevice, code,
-             		&inpar, sizeof(SENDCMDINPARAMS)-1,
-               		outbuf, sizeof(SENDCMDOUTPARAMS)-1 + size_out,
-               		&num_out, NULL)) {
-		// CAUTION: DO NOT change "regs" Parameter in this case, see ata_command_interface()
-		long err = GetLastError();
-#ifdef _DEBUG
-		pout("DeviceIoControl failed, Error=%ld\n", err);
-#endif
-		errno = (   err == ERROR_INVALID_FUNCTION /*9x*/
-		         || err == ERROR_INVALID_PARAMETER/*NT/2K/XP*/ ? ENOSYS : EIO);
-		return -1;
-	}
-	// NOTE: On Win9x, inpar.irDriveRegs now contains the returned regs
-
-	outpar = (const SENDCMDOUTPARAMS *)outbuf;
-#ifdef _DEBUG
-	pout("DeviceIoControl returns %lu (%lu) bytes\n", num_out, outpar->cBufferSize);
-#endif
-
-	if (outpar->DriverStatus.bDriverError) {
-		pout("Error SMART IOCTL DriverError=0x%02x, IDEError=0x%02x\n",
-			outpar->DriverStatus.bDriverError, outpar->DriverStatus.bIDEError);
-		errno = EIO;
-		return -1;
-	}
-
-	if (datasize)
-		memcpy(data, outpar->bBuffer, 512);
-	else if (regs->bFeaturesReg == ATA_SMART_STATUS) {
-		*regs = *(const IDEREGS *)(outpar->bBuffer);
-#ifdef _DEBUG
-		print_ide_regs(regs, 1);
-#endif
-	}
-
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// IDE PASS THROUGH for W2K/XP (does not work on W9x/NT4)
-// Only used for SMART commands not supported by SMART_* IOCTLs
-//
-// Based on WinATA.cpp, 2002 c't/Matthias Withopf
-// ftp://ftp.heise.de/pub/ct/listings/0207-218.zip
-
-#define FILE_DEVICE_CONTROLLER  4
-#define IOCTL_SCSI_BASE         FILE_DEVICE_CONTROLLER
-
-#define IOCTL_IDE_PASS_THROUGH \
-  CTL_CODE(IOCTL_SCSI_BASE, 0x040A, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-
-#pragma pack(1)
-
-typedef struct {
-	IDEREGS IdeReg;
-	ULONG   DataBufferSize;
-	UCHAR   DataBuffer[1];
-} ATA_PASS_THROUGH;
-
-#pragma pack()
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-static int ide_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, unsigned datasize)
-{ 
-	unsigned int size = sizeof(ATA_PASS_THROUGH)-1 + datasize;
-	ATA_PASS_THROUGH * buf = (ATA_PASS_THROUGH *)VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
-	DWORD num_out;
-	assert(sizeof(ATA_PASS_THROUGH)-1 == 12);
-	assert(IOCTL_IDE_PASS_THROUGH == 0x04d028);
-
-	buf->IdeReg = *regs;
-	buf->DataBufferSize = datasize;
-
-#ifdef _DEBUG
-	pout("DeviceIoControl(.,0x%x,.,%u,.,%u,.,NULL)\n",
-		IOCTL_IDE_PASS_THROUGH, size, size);
-	print_ide_regs(&buf->IdeReg, 0);
-#endif
-
-	if (!DeviceIoControl(hdevice, IOCTL_IDE_PASS_THROUGH, 
-		buf, size, buf, size, &num_out, NULL)) {
-		long err = GetLastError();
-#ifdef _DEBUG
-		pout("DeviceIoControl failed, Error=%ld\n", err);
-#endif
-		VirtualFree(buf, size, MEM_RELEASE);
-		errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);
-		return -1;
-	}
-
-#ifdef _DEBUG
-	pout("DeviceIoControl returns %lu (%lu) bytes\n", num_out, buf->DataBufferSize);
-	print_ide_regs(&buf->IdeReg, 1);
-#endif
-
-	if (datasize)
-		memcpy(data, buf->DataBuffer, datasize);
-	VirtualFree(buf, size, MEM_RELEASE);
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-static HANDLE h_ata_ioctl = 0;
-static int ide_pass_through_broken = 0;
-
-
-// Print SMARTVSD error message, return errno
-
-static int smartvsd_error()
-{
-	char path[MAX_PATH];
-	unsigned len;
-	if (!(5 <= (len = GetSystemDirectoryA(path, MAX_PATH)) && len < MAX_PATH/2))
-		return ENOENT;
-	strcpy(path+len, "\\IOSUBSYS\\SMARTVSD.VXD");
-	if (!access(path, 0)) {
-#ifdef _DEBUG
-		pout("Driver \"%s\" not loaded,\n"
-		     " possibly no IDE/ATA devices present.\n", path);
-#endif
-		return ENOENT;
-	}
-	// Some Windows versions install SMARTVSD.VXD in SYSTEM directory
-	// http://support.microsoft.com/default.aspx?scid=kb;en-us;265854
-	strcpy(path+len, "\\SMARTVSD.VXD");
-	if (!access(path, 0)) {
-		path[len] = 0;
-		pout("SMART driver is not properly installed,\n"
-		     " move SMARTVSD.VXD from \"%s\" to \"%s\\IOSUBSYS\"\n"
-		     " and reboot Windows.\n", path, path);
-		return ENOSYS;
-	}
-	path[len] = 0;
-	pout("SMARTVSD.VXD is missing in folder \"%s\\IOSUBSYS\".\n", path);
-	return ENOENT;
-}
-
-
-static int ata_open(int drive)
-{
-	int win9x;
-	char devpath[30];
-	GETVERSIONOUTPARAMS vers;
-	DWORD num_out;
-
-	assert(SMART_GET_VERSION == 0x074080);
-	assert(sizeof(GETVERSIONOUTPARAMS) == 24);
-
-	// TODO: This version does not allow to open more than 1 ATA devices
-	if (h_ata_ioctl) {
-		errno = ENFILE;
-		return -1;
-	}
-
-	win9x = ((GetVersion() & 0x80000000) != 0);
-
-	if (!(0 <= drive && drive <= (win9x ? 3 : 9))) {
-		errno = ENOENT;
-		return -1;
-	}
-	// path depends on Windows Version
-	if (win9x)
-		strcpy(devpath, "\\\\.\\SMARTVSD");
-	else
-		snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", drive);
-
-	// Open device
-	if ((h_ata_ioctl = CreateFileA(devpath,
-		GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
-		NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
-		long err = GetLastError();	
-		pout("Cannot open device %s, Error=%ld\n", devpath, err);
-		if (win9x && err == ERROR_FILE_NOT_FOUND)
-			errno = smartvsd_error();
-		else
-			errno = (err == ERROR_FILE_NOT_FOUND ? ENOENT : EPERM);
-		h_ata_ioctl = 0;
-		return -1;
-	}
-
-	// Get drive map
-	memset(&vers, 0, sizeof(vers));
-	if (!DeviceIoControl(h_ata_ioctl, SMART_GET_VERSION,
-		NULL, 0, &vers, sizeof(vers), &num_out, NULL)) {
-		pout("%s: SMART_GET_VERSION failed, Error=%ld\n", devpath, GetLastError());
-		if (!win9x)
-			pout("If this is a SCSI disk, try \"scsi<adapter><id>\".\n");
-		if (!is_permissive()) {
-			CloseHandle(h_ata_ioctl); h_ata_ioctl = 0;
-			errno = ENOSYS;
-			return -1;
-		}
-	}
-
-#ifdef _DEBUG
-	pout("SMART_GET_VERSION (%ld bytes): Vers = %d.%d, Caps = 0x%lx, DeviceMap = 0x%02x\n",
-		num_out, vers.bVersion, vers.bRevision, vers.fCapabilities, vers.bIDEDeviceMap);
-#endif
-
-	// TODO: Check vers.fCapabilities here?
-
-	if (!win9x)
-		// NT4/2K/XP: Drive exists, Drive number not necessary for ioctl
-		return 0;
-
-	// Win9x/ME: Check device presence & type
-	if (((vers.bIDEDeviceMap >> drive) & 0x11) != 0x01) {
-		unsigned char atapi = (vers.bIDEDeviceMap >> drive) & 0x10;
-		pout((  atapi
-		      ? "Drive %d is an ATAPI device (IDEDeviceMap=0x%02x).\n"
-			  : "Drive %d does not exist (IDEDeviceMap=0x%02x).\n"),
-			drive, vers.bIDEDeviceMap);
-		// Win9x Drive existence check may not work as expected
-		// The atapi.sys driver incorrectly fills in the bIDEDeviceMap with 0x01
-		// http://support.microsoft.com/support/kb/articles/Q196/1/20.ASP
-		if (!is_permissive()) {
-			CloseHandle(h_ata_ioctl); h_ata_ioctl = 0;
-			errno = (atapi ? ENOSYS : ENOENT);
-			return -1;
-		}
-	}
-	// Use drive number as fd for ioctl
-	return drive;
-}
-
-
-static void ata_close(int fd)
-{
-	ARGUSED(fd);
-	CloseHandle(h_ata_ioctl);
-	h_ata_ioctl = 0;
-}
-
-
-// Scan for ATA drives, return bitmask of drives present
-
-static unsigned ata_scan()
-{
-	unsigned drives = 0;
-	int win9x = ((GetVersion() & 0x80000000) != 0);
-	int i;
-
-	for (i = 0; i <= 9; i++) {
-		char devpath[30];
-		GETVERSIONOUTPARAMS vers;
-		DWORD num_out;
-		HANDLE h;
-		if (win9x)
-			strcpy(devpath, "\\\\.\\SMARTVSD");
-		else
-			snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", i);
-
-		// Open device
-		if ((h = CreateFileA(devpath,
-			GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
-			NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
-			if (win9x)
-				break; // SMARTVSD.VXD missing or no ATA devices
-			continue; // Disk not found or access denied (break;?)
-		}
-
-		// Get drive map
-		memset(&vers, 0, sizeof(vers));
-		if (!DeviceIoControl(h, SMART_GET_VERSION,
-			NULL, 0, &vers, sizeof(vers), &num_out, NULL)) {
-			CloseHandle(h);
-			if (win9x)
-				break; // Should not happen
-			continue; // Non ATA disk or no SMART ioctl support (possibly SCSI disk)
-		}
-		CloseHandle(h);
-
-		if (win9x) {
-			// Check ATA device presence, remove ATAPI devices
-			drives = (vers.bIDEDeviceMap & 0xf) & ~((vers.bIDEDeviceMap >> 4) & 0xf);
-			break;
-		}
-
-		// ATA drive exists and driver supports SMART ioctl
-		drives |= 1 << i;
-	}
-
-	return drives;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char * data)
-{
-	IDEREGS regs;
-	int copydata;
-
-	if (!(0 <= fd && fd <= 3)) {
-	  errno = EBADF;
-	  return -1;
-	}
-
-	// CMD,CYL default to SMART, changed by P?IDENTIFY
-	memset(&regs, 0, sizeof(regs));
-	regs.bCommandReg = ATA_SMART_CMD;
-	regs.bCylHighReg = SMART_CYL_HI; regs.bCylLowReg = SMART_CYL_LOW;
-	copydata = 0;
-
-	switch (command) {
-	  case CHECK_POWER_MODE:
-	  case WRITE_LOG:
-		// TODO. Not supported by SMART IOCTL
-		errno = ENOSYS;
-		return -1;
-	  case READ_VALUES:
-		regs.bFeaturesReg = ATA_SMART_READ_VALUES;
-		regs.bSectorNumberReg = regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case READ_THRESHOLDS:
-		regs.bFeaturesReg = ATA_SMART_READ_THRESHOLDS;
-		regs.bSectorNumberReg = regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case READ_LOG:
-		regs.bFeaturesReg = ATA_SMART_READ_LOG_SECTOR;
-		regs.bSectorNumberReg = select;
-		regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case IDENTIFY:
-		regs.bCommandReg = ATA_IDENTIFY_DEVICE;
-		regs.bCylLowReg = regs.bCylHighReg = 0;
-		regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case PIDENTIFY:
-		regs.bCommandReg = ATA_IDENTIFY_PACKET_DEVICE;
-		regs.bCylLowReg = regs.bCylHighReg = 0;
-		regs.bSectorCountReg = 1;
-		copydata = 1;
-		break;
-	  case ENABLE:
-		regs.bFeaturesReg = ATA_SMART_ENABLE;
-		regs.bSectorNumberReg = 1;
-		break;
-	  case DISABLE:
-		regs.bFeaturesReg = ATA_SMART_DISABLE;
-		regs.bSectorNumberReg = 1;
-		break;
-	  case STATUS:
-	  case STATUS_CHECK:
-		regs.bFeaturesReg = ATA_SMART_STATUS;
-		break;
-	  case AUTO_OFFLINE:
-		regs.bFeaturesReg = ATA_SMART_AUTO_OFFLINE;
-		regs.bSectorCountReg = select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-		break;
-	  case AUTOSAVE:
-		regs.bFeaturesReg = ATA_SMART_AUTOSAVE;
-		regs.bSectorCountReg = select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-		break;
-	  case IMMEDIATE_OFFLINE:
-		regs.bFeaturesReg = ATA_SMART_IMMEDIATE_OFFLINE;
-		regs.bSectorNumberReg = select;
-		break;
-	  default:
-		pout("Unrecognized command %d in win32_ata_command_interface()\n"
-		 "Please contact " PACKAGE_BUGREPORT "\n", command);
-		errno = ENOSYS;
-		return -1;
-	}
-
-	if (smart_ioctl(h_ata_ioctl, fd, &regs, data, (copydata?512:0))) {
-		// Read log only supported on Win9x, retry with pass through command
-		// CAUTION: smart_ioctl() MUST NOT change "regs" Parameter in this case
-		if (errno == ENOSYS && command == READ_LOG && !ide_pass_through_broken) {
-			errno = 0;
-			memset(data, 0, 512);
-			if (ide_pass_through_ioctl(h_ata_ioctl, &regs, data, 512))
-				return -1;
-			if (!nonempty(data, 512)) {
-				// Nothing useful returned => ioctl probably broken
-				pout("IOCTL_IDE_PASS_THROUGH does not work on your version of Windows\n");
-				ide_pass_through_broken = 1; // Do not retry (smartd)
-				errno = ENOSYS;
-				return -1;
-			}
-			return 0;
-		}
-		return -1;
-	}
-
-	if (command == STATUS_CHECK) {
-		// Cyl low and Cyl high unchanged means "Good SMART status"
-		if (regs.bCylHighReg == SMART_CYL_HI && regs.bCylLowReg == SMART_CYL_LOW)
-		  return 0;
-
-		// These values mean "Bad SMART status"
-		if (regs.bCylHighReg == 0x2c && regs.bCylLowReg == 0xf4)
-		  return 1;
-
-		// We haven't gotten output that makes sense; print out some debugging info
-		syserror("Error SMART Status command failed");
-		pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
-		print_ide_regs(&regs, 1);
-		errno = EIO;
-		return -1;
-	}
-
-	return 0;
-}
-
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data)
-{
-	static int warned = 0;
-	ARGUSED(fd); ARGUSED(disknum); ARGUSED(escalade_type); ARGUSED(command); ARGUSED(select); ARGUSED(data);
-	if (!warned) {
-		  pout(
-		"#######################################################################\n"
-		"3ware Escalade Controller command routine escalade_command_interface()\n"
-		"NOT IMPLEMENTED under Win32.\n"
-		"Please contact " PACKAGE_BUGREPORT " if\n"
-		"you want to help in porting smartmontools to Win32.\n"
-		"#######################################################################\n"
-		"\n");
-		warned = 1;
-	}
-	errno = ENOSYS;
-	return -1;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// ASPI Interface
-/////////////////////////////////////////////////////////////////////////////
-
-#pragma pack(1)
-
-#define ASPI_SENSE_SIZE 18
-
-// ASPI SCSI Request block header
-
-typedef struct {
-	unsigned char cmd;             // 00: Command code
-	unsigned char status;          // 01: ASPI status
-	unsigned char adapter;         // 02: Host adapter number
-	unsigned char flags;           // 03: Request flags
-	unsigned char reserved[4];     // 04: 0
-} ASPI_SRB_HEAD;
-
-// SRB for host adapter inquiry
-
-typedef struct {
-	ASPI_SRB_HEAD h;               // 00: Header
-	unsigned char adapters;        // 08: Number of adapters
-	unsigned char target_id;       // 09: Target ID ?
-	char manager_id[16];           // 10: SCSI manager ID
-	char adapter_id[16];           // 26: Host adapter ID
-	unsigned char parameters[16];  // 42: Host adapter unique parmameters
-} ASPI_SRB_INQUIRY;
-
-// SRB for get device type
-
-typedef struct {
-	ASPI_SRB_HEAD h;               // 00: Header
-	unsigned char target_id;       // 08: Target ID
-	unsigned char lun;             // 09: LUN
-	unsigned char devtype;         // 10: Device type
-	unsigned char reserved;        // 11: Reserved
-} ASPI_SRB_DEVTYPE;
-
-// SRB for SCSI I/O
-
-typedef struct {
-	ASPI_SRB_HEAD h;               // 00: Header
-	unsigned char target_id;       // 08: Target ID
-	unsigned char lun;             // 09: LUN
-	unsigned char reserved[2];     // 10: Reserved
-	unsigned long data_size;       // 12: Data alloc. lenght
-	void * data_addr;              // 16: Data buffer pointer
-	unsigned char sense_size;      // 20: Sense alloc. length
-	unsigned char cdb_size;        // 21: CDB length
-	unsigned char host_status;     // 22: Host status
-	unsigned char target_status;   // 23: Target status
-	void * event_handle;           // 24: Event handle
-	unsigned char workspace[20];   // 28: ASPI workspace
-	unsigned char cdb[16+ASPI_SENSE_SIZE];
-} ASPI_SRB_IO;
-
-// Macro to retrieve start of sense information
-#define ASPI_SRB_SENSE(srb,cdbsz) ((srb)->cdb + 16)
-
-// SRB union
-
-typedef union {
-	ASPI_SRB_HEAD h;       // Common header
-	ASPI_SRB_INQUIRY q;    // Inquiry
-	ASPI_SRB_DEVTYPE t;    // Device type
-	ASPI_SRB_IO i;         // I/O
-} ASPI_SRB;
-
-#pragma pack()
-
-// ASPI commands
-#define ASPI_CMD_ADAPTER_INQUIRE        0x00
-#define ASPI_CMD_GET_DEVICE_TYPE        0x01
-#define ASPI_CMD_EXECUTE_IO             0x02
-#define ASPI_CMD_ABORT_IO               0x03
-
-// Request flags
-#define ASPI_REQFLAG_DIR_TO_HOST        0x08
-#define ASPI_REQFLAG_DIR_TO_TARGET      0x10
-#define ASPI_REQFLAG_DIR_NO_XFER        0x18
-#define ASPI_REQFLAG_EVENT_NOTIFY       0x40
-
-// ASPI status
-#define ASPI_STATUS_IN_PROGRESS         0x00
-#define ASPI_STATUS_NO_ERROR            0x01
-#define ASPI_STATUS_ABORTED             0x02
-#define ASPI_STATUS_ABORT_ERR           0x03
-#define ASPI_STATUS_ERROR               0x04
-#define ASPI_STATUS_INVALID_COMMAND     0x80
-#define ASPI_STATUS_INVALID_ADAPTER     0x81
-#define ASPI_STATUS_INVALID_TARGET      0x82
-#define ASPI_STATUS_NO_ADAPTERS         0xE8
-
-// Adapter (host) status
-#define ASPI_HSTATUS_NO_ERROR           0x00
-#define ASPI_HSTATUS_SELECTION_TIMEOUT  0x11
-#define ASPI_HSTATUS_DATA_OVERRUN       0x12
-#define ASPI_HSTATUS_BUS_FREE           0x13
-#define ASPI_HSTATUS_BUS_PHASE_ERROR    0x14
-#define ASPI_HSTATUS_BAD_SGLIST         0x1A
-
-// Target status
-#define ASPI_TSTATUS_NO_ERROR           0x00
-#define ASPI_TSTATUS_CHECK_CONDITION    0x02
-#define ASPI_TSTATUS_BUSY               0x08
-#define ASPI_TSTATUS_RESERV_CONFLICT    0x18
-
-
-static HINSTANCE h_aspi_dll; // DLL handle
-static UINT (* aspi_entry)(ASPI_SRB * srb); // ASPI entrypoint
-static unsigned num_aspi_adapters;
-
-#ifdef __CYGWIN__
-// h_aspi_dll+aspi_entry is not inherited by Cygwin's fork()
-static DWORD aspi_dll_pid; // PID of DLL owner to detect fork()
-#define aspi_entry_valid() (aspi_entry && (aspi_dll_pid == GetCurrentProcessId()))
-#else
-#define aspi_entry_valid() (!!aspi_entry)
-#endif
-
-
-static int aspi_call(ASPI_SRB * srb)
-{
-	int i;
-	aspi_entry(srb);
-	i = 0;
-	while (((volatile ASPI_SRB *)srb)->h.status == ASPI_STATUS_IN_PROGRESS) {
-		if (++i > 100/*10sek*/) {
-			pout("ASPI Adapter %u: Timeout\n", srb->h.adapter);
-			aspi_entry = 0;
-			h_aspi_dll = INVALID_HANDLE_VALUE;
-			errno = EIO;
-			return -1;
-		}
-#ifdef _DEBUG
-		pout("ASPI Wait %d\n", i);
-#endif
-		Sleep(100);
-	}
-	return 0;
-}
-
-
-// Get ASPI entrypoint from wnaspi32.dll
-
-static FARPROC aspi_get_address(const char * name, int verbose)
-{
-	FARPROC addr;
-	assert(h_aspi_dll && h_aspi_dll != INVALID_HANDLE_VALUE);
-
-	if (!(addr = GetProcAddress(h_aspi_dll, name))) {
-		if (verbose)
-			pout("Missing %s() in WNASPI32.DLL\n", name);
-		aspi_entry = 0;
-		FreeLibrary(h_aspi_dll);
-		h_aspi_dll = INVALID_HANDLE_VALUE;
-		errno = ENOSYS;
-		return 0;
-	}
-	return addr;
-}
-
-
-static int aspi_open_dll(int verbose)
-{
-	UINT (*aspi_info)(void);
-	UINT info, rc;
-
-	assert(!aspi_entry_valid());
-
-	// Check structure layout
-	assert(sizeof(ASPI_SRB_HEAD) == 8);
-	assert(sizeof(ASPI_SRB_INQUIRY) == 58);
-	assert(sizeof(ASPI_SRB_DEVTYPE) == 12);
-	assert(sizeof(ASPI_SRB_IO) == 64+ASPI_SENSE_SIZE);
-	assert(offsetof(ASPI_SRB,h.cmd) == 0);
-	assert(offsetof(ASPI_SRB,h.flags) == 3);
-	assert(offsetof(ASPI_SRB_IO,lun) == 9);
-	assert(offsetof(ASPI_SRB_IO,data_addr) == 16);
-	assert(offsetof(ASPI_SRB_IO,workspace) == 28);
-	assert(offsetof(ASPI_SRB_IO,cdb) == 48);
-
-	if (h_aspi_dll == INVALID_HANDLE_VALUE) {
-		// do not retry
-		errno = ENOENT;
-		return -1;
-	}
-
-	// Load ASPI DLL
-	if (!(h_aspi_dll = LoadLibraryA("WNASPI32.DLL"))) {
-		if (verbose)
-			pout("Cannot load WNASPI32.DLL, Error=%ld\n", GetLastError());
-		h_aspi_dll = INVALID_HANDLE_VALUE;
-		errno = ENOENT;
-		return -1;
-	}
-
-	// Get ASPI entrypoints
-	if (!(aspi_info = (UINT (*)(void))aspi_get_address("GetASPI32SupportInfo", verbose)))
-		return -1;
-	if (!(aspi_entry = (UINT (*)(ASPI_SRB *))aspi_get_address("SendASPI32Command", verbose)))
-		return -1;
-
-	// Init ASPI manager and get number of adapters
-	info = (aspi_info)();
-#ifdef _DEBUG
-	pout("GetASPI32SupportInfo() returns 0x%04x\n", info);
-#endif
-	rc = (info >> 8) & 0xff;
-	if (rc == ASPI_STATUS_NO_ADAPTERS) {
-		num_aspi_adapters = 0;
-	}
-	else if (rc == ASPI_STATUS_NO_ERROR) {
-		num_aspi_adapters = info & 0xff;
-	}
-	else {
-		if (verbose)
-			pout("Got strange 0x%04x from GetASPI32SupportInfo()\n", info);
-		aspi_entry = 0;
-		FreeLibrary(h_aspi_dll);
-		h_aspi_dll = INVALID_HANDLE_VALUE;
-		errno = ENOENT;
-		return -1;
-	}
-
-#ifdef __CYGWIN__
-	// save PID to detect fork() in aspi_entry_valid()
-	aspi_dll_pid = GetCurrentProcessId();
-#endif
-	assert(aspi_entry_valid());
-	return 0;
-}
-
-
-static int aspi_io_call(ASPI_SRB * srb)
-{
-	HANDLE event;
-	// Create event
-	if (!(event = CreateEventA(NULL, FALSE, FALSE, NULL))) {
-		pout("CreateEvent(): Error=%ld\n", GetLastError()); return -EIO;
-	}
-	srb->i.event_handle = event;
-	srb->h.flags |= ASPI_REQFLAG_EVENT_NOTIFY;
-	// Start ASPI request
-	aspi_entry(srb);
-	if (((volatile ASPI_SRB *)srb)->h.status == ASPI_STATUS_IN_PROGRESS) {
-		// Wait for event
-		DWORD rc = WaitForSingleObject(event, 30*1000L);
-		if (rc != WAIT_OBJECT_0) {
-			if (rc == WAIT_TIMEOUT) {
-				pout("ASPI Timeout\n");
-			}
-			else {
-				pout("WaitForSingleObject(%lx) = 0x%lx,%ld, Error=%ld\n",
-					(unsigned long)event, rc, rc, GetLastError());
-			}
-			// TODO: ASPI_ABORT_IO command
-			aspi_entry = 0;
-			h_aspi_dll = INVALID_HANDLE_VALUE;
-			return -EIO;
-		}
-	}
-	CloseHandle(event);
-	return 0;
-}
-
-
-static int aspi_open(unsigned adapter, unsigned id)
-{
-	if (!(adapter <= 9 && id < 16)) {
-		errno = ENOENT;
-		return -1;
-	}
-
-	if (!aspi_entry_valid()) {
-		if (aspi_open_dll(1/*verbose*/))
-			return -1;
-	}
-
-	// Adapter OK?
-	if (adapter >= num_aspi_adapters) {
-		pout("ASPI Adapter %d does not exist (%d Adapter(s) detected).\n", adapter, num_aspi_adapters);
-		if (!is_permissive()) {
-			errno = ENOENT;
-			return -1;
-		}
-	}
-
-	return (0x0100 | ((adapter & 0xf)<<4) | (id & 0xf));
-}
-
-
-static void aspi_close(int fd)
-{
-	// No FreeLibrary(h_aspi_dll) to prevent problems with ASPI threads
-	ARGUSED(fd);
-}
-
-
-// Scan for SCSI drives, return bitmask [adapter:0-3][id:0-7] of drives present
-
-static unsigned long aspi_scan()
-{
-	unsigned long drives = 0;
-	unsigned ad, nad;
-
-	if (!aspi_entry_valid()) {
-		if (aspi_open_dll(0/*quiet*/))
-			return 0;
-	}
-
-	nad = num_aspi_adapters;
-	if (nad >= 4)
-		nad = 4;
-	for (ad = 0; ad < nad; ad++) {
-		ASPI_SRB srb; int id;
-		// Get adapter name
-		memset(&srb, 0, sizeof(srb));
-		srb.h.cmd = ASPI_CMD_ADAPTER_INQUIRE;
-		srb.h.adapter = ad;
-		if (aspi_call(&srb))
-			return 0;
-#ifdef _DEBUG
-		pout("ASPI Adapter %u: %02x,\"%.16s\"\n", ad, srb.h.status, srb.q.adapter_id);
-#endif
-		if (srb.h.status != ASPI_STATUS_NO_ERROR)
-			continue;
-
-		// Skip ATA/ATAPI devices
-		srb.q.adapter_id[sizeof(srb.q.adapter_id)-1] = 0;
-		if (strstr(srb.q.adapter_id, "ATAPI"))
-			continue;
-
-		for (id = 0; id <= 7; id++) {
-			// Get device type
-			memset(&srb, 0, sizeof(srb));
-			srb.h.cmd = ASPI_CMD_GET_DEVICE_TYPE;
-			srb.h.adapter = ad; srb.i.target_id = id;
-			if (aspi_call(&srb))
-				return 0;
-#ifdef _DEBUG
-			pout("Device type for scsi%u%x: %02x,%02x\n", ad, id, srb.h.status, srb.t.devtype);
-#endif
-			if (srb.h.status == ASPI_STATUS_NO_ERROR && srb.t.devtype == 0x00/*HDD*/)
-				drives |= 1 << ((ad<<3)+id);
-		}
-	}
-	return drives;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-	ASPI_SRB srb;
-
-	if (!aspi_entry_valid())
-		return -EBADF;
-	if (!((fd & ~0xff) == 0x100))
-		return -EBADF;
-
-	if (!(iop->cmnd_len == 6 || iop->cmnd_len == 10 || iop->cmnd_len == 12)) {
-		pout("do_scsi_cmnd_io: bad CDB length\n");
-		return -EINVAL;
-	}
-
-	if (report > 0) {
-		// From os_linux.c
-		int k, j;
-		const unsigned char * ucp = iop->cmnd;
-		const char * np;
-		char buff[256];
-		const int sz = (int)sizeof(buff);
-
-		np = scsi_get_opcode_name(ucp[0]);
-		j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
-		for (k = 0; k < (int)iop->cmnd_len; ++k)
-			j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
-		if ((report > 1) && 
-			(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-			int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-			j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
-						  "data, len=%d%s:\n", (int)iop->dxfer_len,
-						  (trunc ? " [only first 256 bytes shown]" : ""));
-			dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-		}
-		else
-			j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
-		pout(buff);
-	}
-
-	memset(&srb, 0, sizeof(srb));
-	srb.h.cmd = ASPI_CMD_EXECUTE_IO;
-	srb.h.adapter = ((fd >> 4) & 0xf);
-	srb.i.target_id = (fd & 0xf);
-	//srb.i.lun = 0;
-	srb.i.sense_size = ASPI_SENSE_SIZE;
-	srb.i.cdb_size = iop->cmnd_len;
-	memcpy(srb.i.cdb, iop->cmnd, iop->cmnd_len);
-
-	switch (iop->dxfer_dir) {
-		case DXFER_NONE:
-			srb.h.flags = ASPI_REQFLAG_DIR_NO_XFER;
-			break;
-		case DXFER_FROM_DEVICE:
-			srb.h.flags = ASPI_REQFLAG_DIR_TO_HOST;
-			srb.i.data_size = iop->dxfer_len;
-			srb.i.data_addr = iop->dxferp;
-			break;
-		case DXFER_TO_DEVICE:
-			srb.h.flags = ASPI_REQFLAG_DIR_TO_TARGET;
-			srb.i.data_size = iop->dxfer_len;
-			srb.i.data_addr = iop->dxferp;
-			break;
-		default:
-			pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-			return -EINVAL;
-	}
-
-	iop->resp_sense_len = 0;
-	iop->scsi_status = 0;
-	iop->resid = 0;
-
-	if (aspi_io_call(&srb)) {
-		// Timeout
-		return -EIO;
-	}
-
-	if (srb.h.status != ASPI_STATUS_NO_ERROR) {
-		if (   srb.h.status        == ASPI_STATUS_ERROR
-		    && srb.i.host_status   == ASPI_HSTATUS_NO_ERROR
-		    && srb.i.target_status == ASPI_TSTATUS_CHECK_CONDITION) {
-			// Sense valid
-			const unsigned char * sense = ASPI_SRB_SENSE(&srb.i, iop->cmnd_len);
-			int len = (ASPI_SENSE_SIZE < iop->max_sense_len ? ASPI_SENSE_SIZE : iop->max_sense_len);
-			iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-			if (len > 0 && iop->sensep) {
-				memcpy(iop->sensep, sense, len);
-				iop->resp_sense_len = len;
-				if (report > 1) {
-					pout("  >>> Sense buffer, len=%d:\n", (int)len);
-					dStrHex(iop->sensep, len , 1);
-				}
-			}
-			if (report) {
-				pout("  sense_key=%x asc=%x ascq=%x\n",
-				 sense[2] & 0xf, sense[12], sense[13]);
-			}
-			return 0;
-		}
-		else {
-			if (report)
-				pout("  ASPI call failed, (0x%02x,0x%02x,0x%02x)\n", srb.h.status, srb.i.host_status, srb.i.target_status);
-			return -EIO;
-		}
-	}
-
-	if (report > 0)
-		pout("  OK\n");
-
-	if (iop->dxfer_dir == DXFER_FROM_DEVICE && report > 1) {
-		 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-		 pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-			  (trunc ? " [only first 256 bytes shown]" : ""));
-				dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-	}
-
-	return 0;
-}
diff --git a/sm5/os_win32/.cvsignore b/sm5/os_win32/.cvsignore
deleted file mode 100644
index c8ca8dab0918d88de313969d7275190a8e76bb97..0000000000000000000000000000000000000000
--- a/sm5/os_win32/.cvsignore
+++ /dev/null
@@ -1,16 +0,0 @@
-config.h
-smartctl.d
-smartctl.r
-smartctl.exe
-smartctl_vc6.plg
-smartd.d
-smartd.r
-smartd.exe
-smartd_vc6.plg
-smartmontools_vc6.ncb
-smartmontools_vc6.opt
-syslogevt.d
-syslogevt.r
-syslogevt.exe
-syslogevt.h
-syslogevt_vc6.plg
diff --git a/sm5/os_win32/config_vc6.h b/sm5/os_win32/config_vc6.h
deleted file mode 100644
index 46c1128e0f92279e5dada7d2d3031b8151e1b9b7..0000000000000000000000000000000000000000
--- a/sm5/os_win32/config_vc6.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* config.h for MSVC6, NOT Generated by configure.  */
-
-/* smartmontools CVS Tag */
-#define CONFIG_H_CVSID "$Id: config_vc6.h,v 1.2 2004/03/12 23:29:06 chrfranke Exp $"
-
-/* use mailx as default mailer */
-/* #undef DEFAULT_MAILER */
-
-/* Define to 1 if you have the <dev/ata/atavar.h> header file. */
-/* #undef HAVE_DEV_ATA_ATAVAR_H */
-
-/* Define to 1 if you have the `getdomainname' function. */
-#undef HAVE_GETDOMAINNAME
-
-/* Define to 1 if you have the `getopt' function. */
-#undef HAVE_GETOPT
-
-/* Define to 1 if you have the `getopt_long' function. */
-#define HAVE_GETOPT_LONG 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <linux/hdreg.h> header file. */
-/* #undef HAVE_LINUX_HDREG_H */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `sigset' function. */
-#undef HAVE_SIGSET
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the `uname' function. */
-#undef HAVE_UNAME
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* need assembly code os_solaris_ata.s */
-/* #undef NEED_SOLARIS_ATA_CODE */
-
-/* Name of package */
-#define PACKAGE "smartmontools"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "smartmontools-support@lists.sourceforge.net"
-
-/* smartmontools Home Page */
-#define PACKAGE_HOMEPAGE "http://smartmontools.sourceforge.net/"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "smartmontools"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "smartmontools "PACKAGE_VERSION
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "smartmontools"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION VERSION
-
-/* smartmontools Build Host */
-#define SMARTMONTOOLS_BUILD_HOST "i686-pc-win32"
-
-/* smartmontools Configure Arguments */
-#define SMARTMONTOOLS_CONFIGURE_ARGS ""
-
-/* smartmontools Configure Date */
-#define SMARTMONTOOLS_CONFIGURE_DATE "2004/03/12 18:42:00 UTC"
-
-/* smartmontools Release Date */
-#define SMARTMONTOOLS_RELEASE_DATE "2004/03/07"
-
-/* smartmontools Release Time */
-#define SMARTMONTOOLS_RELEASE_TIME "20:57:36 UTC"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "5.31"
diff --git a/sm5/os_win32/daemon_win32.c b/sm5/os_win32/daemon_win32.c
deleted file mode 100644
index c54caf75094c8c0c44956b167ba0c1049731eb39..0000000000000000000000000000000000000000
--- a/sm5/os_win32/daemon_win32.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * os_win32/daemon_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <io.h>
-
-#define WIN32_LEAN_AND_MEAN
-// Need MB_SERVICE_NOTIFICATION (NT4/2000/XP), IsDebuggerPresent() (Win98/ME/NT4/2000/XP)
-#define _WIN32_WINNT 0x0400 
-#include <windows.h>
-#ifdef _DEBUG
-#include <crtdbg.h>
-#endif
-
-#include "daemon_win32.h"
-
-const char *daemon_win32_c_cvsid = "$Id: daemon_win32.c,v 1.5 2004/08/09 14:35:59 chrfranke Exp $"
-DAEMON_WIN32_H_CVSID;
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-#define ARGUSED(x) ((void)(x))
-
-// Prevent spawning of child process if debugging
-#ifdef _DEBUG
-#define debugging() IsDebuggerPresent()
-#else
-#define debugging() FALSE
-#endif
-
-
-#define EVT_NAME_LEN 260
-
-// Internal events (must be > SIGUSRn)
-#define EVT_RUNNING   100 // Exists when running, signaled on creation
-#define EVT_DETACHED  101 // Signaled when child detaches from console
-#define EVT_RESTART   102 // Signaled when child should restart
-
-static void make_name(char * name, int sig)
-{
-	int i;
-	if (!GetModuleFileNameA(NULL, name, EVT_NAME_LEN-10))
-		strcpy(name, "DaemonEvent");
-	for (i = 0; name[i]; i++) {
-		char c = name[i];
-		if (!(   ('0' <= c && c <= '9')
-		      || ('A' <= c && c <= 'Z')
-		      || ('a' <= c && c <= 'z')))
-			  name[i] = '_';
-	}
-	sprintf(name+strlen(name), "-%d", sig);
-}
-
-
-static HANDLE create_event(int sig, BOOL initial, BOOL errmsg, BOOL * exists)
-{
-	char name[EVT_NAME_LEN];
-	HANDLE h;
-	make_name(name, sig);
-	if (exists)
-		*exists = FALSE;
-	if (!(h = CreateEventA(NULL, FALSE, initial, name))) {
-		if (errmsg)
-			fprintf(stderr, "CreateEvent(.,\"%s\"): Error=%ld\n", name, GetLastError());
-		return 0;
-	}
-
-	if (GetLastError() == ERROR_ALREADY_EXISTS) {
-		if (!exists) {
-			if (errmsg)
-				fprintf(stderr, "CreateEvent(.,\"%s\"): Exists\n", name);
-			CloseHandle(h);
-			return 0;
-		}
-		*exists = TRUE;
-	}
-	return h;
-}
-
-
-static HANDLE open_event(int sig)
-{
-	char name[EVT_NAME_LEN];
-	make_name(name, sig);
-	return OpenEventA(EVENT_MODIFY_STATE, FALSE, name);
-}
-
-
-static int event_exists(int sig)
-{
-	char name[EVT_NAME_LEN];
-	HANDLE h;
-	make_name(name, sig);
-	if (!(h = OpenEventA(EVENT_MODIFY_STATE, FALSE, name)))
-		return 0;
-	CloseHandle(h);
-	return 1;
-}
-
-
-static int sig_event(int sig)
-{
-	char name[EVT_NAME_LEN];
-	HANDLE h;
-	make_name(name, sig);
-	if (!(h = OpenEventA(EVENT_MODIFY_STATE, FALSE, name))) {
-		make_name(name, EVT_RUNNING);
-		if (!(h = OpenEvent(EVENT_MODIFY_STATE, FALSE, name)))
-			return -1;
-		CloseHandle(h);
-		return 0;
-	}
-	SetEvent(h);
-	CloseHandle(h);
-	return 1;
-}
-
-
-static void daemon_help(FILE * f, const char * ident, const char * message)
-{
-	fprintf(f,
-		"%s: %s.\n"
-		"Use \"%s status|stop|reload|restart|sigusr1|sigusr2\" to control daemon.\n",
-		ident, message, ident);
-	fflush(f);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Parent Process
-
-
-static BOOL WINAPI parent_console_handler(DWORD event)
-{
-	switch (event) {
-		case CTRL_C_EVENT:
-		case CTRL_BREAK_EVENT:
-			return TRUE; // Ignore
-	}
-	return FALSE; // continue with next handler ...
-}
-
-
-static int parent_main(HANDLE rev)
-{
-	HANDLE dev;
-	HANDLE ht[2];
-	char * cmdline;
-	STARTUPINFO si;
-	PROCESS_INFORMATION pi;
-	DWORD rc, exitcode;
-
-	// Ignore ^C, ^BREAK in parent
-	SetConsoleCtrlHandler(parent_console_handler, TRUE/*add*/);
-
-	// Create event used by child to signal daemon_detach()
-	if (!(dev = create_event(EVT_DETACHED, FALSE/*not signaled*/, TRUE, NULL/*must not exist*/))) {
-		CloseHandle(rev);
-		return 101;
-	}
-
-	// Restart process with same args
-	cmdline = GetCommandLineA();
-	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
-	
-	if (!CreateProcessA(
-		NULL, cmdline,
-		NULL, NULL, TRUE/*inherit*/,
-		0, NULL, NULL, &si, &pi)) {
-		fprintf(stderr, "CreateProcess(.,\"%s\",.) failed, Error=%ld\n", cmdline, GetLastError());
-		CloseHandle(rev); CloseHandle(dev);
-		return 101;
-	}
-	CloseHandle(pi.hThread);
-
-	// Wait for daemon_detach() or exit()
-	ht[0] = dev; ht[1] = pi.hProcess;
-	rc = WaitForMultipleObjects(2, ht, FALSE/*or*/, INFINITE);
-	if (!(/*WAIT_OBJECT_0(0) <= rc && */ rc < WAIT_OBJECT_0+2)) {
-		fprintf(stderr, "WaitForMultipleObjects returns %lX\n", rc);
-		TerminateProcess(pi.hProcess, 200);
-	}
-	CloseHandle(rev); CloseHandle(dev);
-
-	// Get exit code
-	if (!GetExitCodeProcess(pi.hProcess, &exitcode))
-		exitcode = 201;
-	else if (exitcode == STILL_ACTIVE) // detach()ed, assume OK
-		exitcode = 0;
-
-	CloseHandle(pi.hProcess);
-	return exitcode;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Child Process
-
-
-static int svc_mode;   // Running as service?
-static int svc_paused; // Service paused?
-
-static void service_report_status(int state, int waithint);
-
-
-// Tables of signal handler and corresponding events
-typedef void (*sigfunc_t)(int);
-
-#define MAX_SIG_HANDLERS 8
-
-static int num_sig_handlers = 0;
-static sigfunc_t sig_handlers[MAX_SIG_HANDLERS];
-static int sig_numbers[MAX_SIG_HANDLERS];
-static HANDLE sig_events[MAX_SIG_HANDLERS];
-
-static HANDLE sigint_handle, sigbreak_handle, sigterm_handle;
-
-static HANDLE running_event;
-
-static int reopen_stdin, reopen_stdout, reopen_stderr;
-
-
-// Handler for windows console events
-
-static BOOL WINAPI child_console_handler(DWORD event)
-{
-	// Caution: runs in a new thread
-	// TODO: Guard with a mutex
-	HANDLE h = 0;
-	switch (event) {
-		case CTRL_C_EVENT: // <CONTROL-C> (SIGINT)
-			h = sigint_handle; break;
-		case CTRL_BREAK_EVENT: // <CONTROL-Break> (SIGBREAK/SIGQUIT)
-		case CTRL_CLOSE_EVENT: // User closed console or abort via task manager
-			h = sigbreak_handle; break;
-		case CTRL_LOGOFF_EVENT: // Logout/Shutdown (SIGTERM)
-		case CTRL_SHUTDOWN_EVENT:
-			h = sigterm_handle; break;
-	}
-	if (!h)
-		return FALSE; // continue with next handler
-	// Signal event
-	if (!SetEvent(h))
-		return FALSE;
-	return TRUE;
-}
-
-
-static void child_exit(void)
-{
-	int i;
-	char * cmdline;
-	HANDLE rst;
-	STARTUPINFO si;
-	PROCESS_INFORMATION pi;
-
-	for (i = 0; i < num_sig_handlers; i++)
-		CloseHandle(sig_events[i]);
-	num_sig_handlers = 0;
-	CloseHandle(running_event); running_event = 0;
-
-	// Restart?
-	if (!(rst = open_event(EVT_RESTART)))
-		return; // No => normal exit
-
-	// Yes => Signal exit and restart process
-	Sleep(500);
-	SetEvent(rst);
-	CloseHandle(rst);
-	Sleep(500);
-
-	cmdline = GetCommandLineA();
-	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
-	si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;
-
-	if (!CreateProcessA(
-		NULL, cmdline,
-		NULL, NULL, TRUE/*inherit*/,
-		0, NULL, NULL, &si, &pi)) {
-		fprintf(stderr, "CreateProcess(.,\"%s\",.) failed, Error=%ld\n", cmdline, GetLastError());
-	}
-	CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
-}
-
-static int child_main(HANDLE hev,int (*main_func)(int, char **), int argc, char **argv)
-{
-	// Keep EVT_RUNNING open until exit
-	running_event = hev;
-
-	// Install console handler
-	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);
-
-	// Install restart handler
-	atexit(child_exit);
-
-	// Continue in main_func() to do the real work
-	return main_func(argc, argv);
-}
-
-
-// Simulate signal()
-
-sigfunc_t daemon_signal(int sig, sigfunc_t func)
-{
-	int i;
-	HANDLE h;
-	if (func == SIG_DFL || func == SIG_IGN)
-		return func; // TODO
-	for (i = 0; i < num_sig_handlers; i++) {
-		if (sig_numbers[i] == sig) {
-			sigfunc_t old = sig_handlers[i];
-			sig_handlers[i] = func;
-			return old;
-		}
-	}
-	if (num_sig_handlers >= MAX_SIG_HANDLERS)
-		return SIG_ERR;
-	if (!(h = create_event(sig, FALSE, TRUE, NULL)))
-		return SIG_ERR;
-	sig_events[num_sig_handlers]   = h;
-	sig_numbers[num_sig_handlers]  = sig;
-	sig_handlers[num_sig_handlers] = func;
-	switch (sig) {
-		case SIGINT:   sigint_handle   = h; break;
-		case SIGTERM:  sigterm_handle  = h; break;
-		case SIGBREAK: sigbreak_handle = h; break;
-	}
-	num_sig_handlers++;
-	return SIG_DFL;
-}
-
-
-// strsignal()
-
-const char * daemon_strsignal(int sig)
-{
-	switch (sig) {
-		case SIGHUP:  return "SIGHUP";
-		case SIGINT:  return "SIGINT";
-		case SIGTERM: return "SIGTERM";
-		case SIGBREAK:return "SIGBREAK";
-		case SIGUSR1: return "SIGUSR1";
-		case SIGUSR2: return "SIGUSR2";
-		default:      return "*UNKNOWN*";
-	}
-}
-
-
-// Simulate sleep()
-
-void daemon_sleep(int seconds)
-{
-	do {
-		if (num_sig_handlers <= 0) {
-			Sleep(seconds*1000L);
-		}
-		else {
-			// Wait for any signal or timeout
-			DWORD rc = WaitForMultipleObjects(num_sig_handlers, sig_events,
-				FALSE/*OR*/, seconds*1000L);
-			if (rc != WAIT_TIMEOUT) {
-				if (!(/*WAIT_OBJECT_0(0) <= rc && */ rc < WAIT_OBJECT_0+(unsigned)num_sig_handlers)) {
-					fprintf(stderr,"WaitForMultipleObjects returns %lu\n", rc);
-					Sleep(seconds*1000L);
-					return;
-				}
-				// Call Handler
-				sig_handlers[rc-WAIT_OBJECT_0](sig_numbers[rc-WAIT_OBJECT_0]);
-				break;
-			}
-		}
-	} while (svc_paused);
-}
-
-
-// Disable/Enable console
-
-void daemon_disable_console()
-{
-	SetConsoleCtrlHandler(child_console_handler, FALSE/*remove*/);
-	reopen_stdin = reopen_stdout = reopen_stderr = 0;
-	if (isatty(fileno(stdin))) {
-		fclose(stdin); reopen_stdin = 1;
-	}
-	if (isatty(fileno(stdout))) {
-		fclose(stdout); reopen_stdout = 1;
-	}
-	if (isatty(fileno(stderr))) {
-		fclose(stderr); reopen_stderr = 1;
-	}
-	FreeConsole();
-	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);
-}
-
-int daemon_enable_console(const char * title)
-{
-	BOOL ok;
-	SetConsoleCtrlHandler(child_console_handler, FALSE/*remove*/);
-	ok = AllocConsole();
-	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);
-	if (!ok)
-		return -1;
-	if (title)
-		SetConsoleTitleA(title);
-	if (reopen_stdin)
-		freopen("conin$",  "r", stdin);
-	if (reopen_stdout)
-		freopen("conout$", "w", stdout);
-	if (reopen_stderr)
-		freopen("conout$", "w", stderr);
-	reopen_stdin = reopen_stdout = reopen_stderr = 0;
-	return 0;
-}
-
-
-// Detach daemon from console & parent
-
-int daemon_detach(const char * ident)
-{
-	if (!svc_mode) {
-		if (ident) {
-			// Print help
-			FILE * f = ( isatty(fileno(stdout)) ? stdout
-					   : isatty(fileno(stderr)) ? stderr : NULL);
-			if (f)
-				daemon_help(f, ident, "now detaches from console into background mode");
-		}
-		// Signal detach to parent
-		if (sig_event(EVT_DETACHED) != 1) {
-			if (!debugging())
-				return -1;
-		}
-		daemon_disable_console();
-	}
-	else {
-		// Signal end of initialization to service control manager
-		service_report_status(SERVICE_RUNNING, 0);
-	}
-
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// MessageBox
-
-#ifndef _MT
-//MT runtime not necessary, because mbox_thread uses no unsafe lib functions
-//#error Program must be linked with multithreaded runtime library
-#endif
-
-static LONG mbox_count; // # mbox_thread()s
-static HANDLE mbox_mutex; // Show 1 box at a time (not necessary for service)
-
-typedef struct mbox_args_s {
-	HANDLE taken; const char * title, * text; int mode;
-} mbox_args;
-
-
-// Thread to display one message box
-
-static ULONG WINAPI mbox_thread(LPVOID arg)
-{
-	// Take args
-	mbox_args * mb = (mbox_args *)arg;
-	char title[100]; char text[1000]; int mode;
-	strncpy(title, mb->title, sizeof(title)-1); title[sizeof(title)-1] = 0;
-	strncpy(text , mb->text , sizeof(text )-1); text [sizeof(text )-1] = 0;
-	mode = mb->mode;
-	SetEvent(mb->taken);
-
-	// Show only one box at a time
-	WaitForSingleObject(mbox_mutex, INFINITE);
-	MessageBoxA(NULL, text, title, mode);
-	ReleaseMutex(mbox_mutex);
-
-	InterlockedDecrement(&mbox_count);
-	return 0;
-}
-
-
-// Display a message box
-int daemon_messagebox(int system, const char * title, const char * text)
-{
-	mbox_args mb;
-	HANDLE ht; DWORD tid;
-
-	// Create mutex during first call
-	if (!mbox_mutex)
-		mbox_mutex = CreateMutex(NULL/*!inherit*/, FALSE/*!owned*/, NULL/*unnamed*/);
-
-	// Allow at most 10 threads
-	if (InterlockedIncrement(&mbox_count) > 10) {
-		InterlockedDecrement(&mbox_count);
-		return -1;
-	}
-
-	// Create thread
-	mb.taken = CreateEvent(NULL/*!inherit*/, FALSE, FALSE/*!signaled*/, NULL/*unnamed*/);
-	mb.mode = MB_OK|MB_ICONWARNING
-	         |(svc_mode?MB_SERVICE_NOTIFICATION:0)
-	         |(system?MB_SYSTEMMODAL:MB_APPLMODAL);
-	mb.title = title; mb.text = text;
-	mb.text = text;
-	if (!(ht = CreateThread(NULL, 0, mbox_thread, &mb, 0, &tid)))
-		return -1;
-
-	// Wait for args taken
-	if (WaitForSingleObject(mb.taken, 10000) != WAIT_OBJECT_0)
-		TerminateThread(ht, 0);
-	CloseHandle(mb.taken);
-	CloseHandle(ht);
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// Spawn a command and redirect <inpbuf >outbuf
-// return command's exitcode or -1 on error
-
-int daemon_spawn(const char * cmd,
-                 const char * inpbuf, int inpsize,
-                 char *       outbuf, int outsize )
-{
-	HANDLE pipe_inp_r, pipe_inp_w, pipe_out_r, pipe_out_w, pipe_err_w, h;
-	DWORD num_io, exitcode; int i;
-	SECURITY_ATTRIBUTES sa;
-	STARTUPINFO si; PROCESS_INFORMATION pi;
-	HANDLE self = GetCurrentProcess();
-
-	// Create stdin pipe with inheritable read side
-	memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa);
-	sa.bInheritHandle = TRUE;
-	if (!CreatePipe(&pipe_inp_r, &h, &sa, inpsize*2+13))
-		return -1;
-	if (!DuplicateHandle(self, h, self, &pipe_inp_w,
-		0, FALSE/*!inherit*/, DUPLICATE_SAME_ACCESS)) {
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	CloseHandle(h);
-
-	// Create stdout pipe with inheritable write side
-	memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa);
-	sa.bInheritHandle = TRUE;
-	if (!CreatePipe(&h, &pipe_out_w, &sa, outsize)) {
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	if (!DuplicateHandle(self, h, self, &pipe_out_r,
-		0, FALSE/*!inherit*/, DUPLICATE_SAME_ACCESS)) {
-		CloseHandle(h);          CloseHandle(pipe_out_w);
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	CloseHandle(h);
-
-	// Create stderr handle as dup of stdout write side
-	if (!DuplicateHandle(self, pipe_out_w, self, &pipe_err_w,
-		0, TRUE/*inherit*/, DUPLICATE_SAME_ACCESS)) {
-		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-
-	// Create process with pipes as stdio
-	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
-	si.hStdInput  = pipe_inp_r;
-	si.hStdOutput = pipe_out_w;
-	si.hStdError  = pipe_err_w;
-	si.dwFlags = STARTF_USESTDHANDLES;
-	if (!CreateProcessA(
-		NULL, (char*)cmd,
-		NULL, NULL, TRUE/*inherit*/,
-		DETACHED_PROCESS/*no new console*/,
-		NULL, NULL, &si, &pi)) {
-		CloseHandle(pipe_err_w);
-		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	CloseHandle(pi.hThread);
-	// Close inherited handles
-	CloseHandle(pipe_inp_r);
-	CloseHandle(pipe_out_w);
-	CloseHandle(pipe_err_w);
-
-	// Copy inpbuf to stdin
-	// convert \n => \r\n 
-	for (i = 0; i < inpsize; ) {
-		int len = 0;
-		while (i+len < inpsize && inpbuf[i+len] != '\n')
-			len++;
-		if (len > 0)
-			WriteFile(pipe_inp_w, inpbuf+i, len, &num_io, NULL);
-		i += len;
-		if (i < inpsize) {
-			WriteFile(pipe_inp_w, "\r\n", 2, &num_io, NULL);
-			i++;
-		}
-	}
-	CloseHandle(pipe_inp_w);
-
-	// Copy stdout to output buffer until full, rest to /dev/null
-	// convert \r\n => \n
-	for (i = 0; ; ) {
-		char buf[256];
-		int j;
-		if (!ReadFile(pipe_out_r, buf, sizeof(buf), &num_io, NULL) || num_io == 0)
-			break;
-		for (j = 0; i < outsize-1 && j < (int)num_io; j++) {
-			if (buf[j] != '\r')
-				outbuf[i++] = buf[j];
-		}	
-	}
-	outbuf[i] = 0;
-	CloseHandle(pipe_out_r);
-
-	// Wait for process exitcode
-	WaitForSingleObject(pi.hProcess, INFINITE);
-	exitcode = 42;
-	GetExitCodeProcess(pi.hProcess, &exitcode);
-	CloseHandle(pi.hProcess);
-	return exitcode;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Initd Functions
-
-static int wait_signaled(HANDLE h, int seconds)
-{
-	int i;
-	for (i = 0; ; ) {
-		if (WaitForSingleObject(h, 1000L) == WAIT_OBJECT_0)
-			return 0;
-		if (++i >= seconds)
-			return -1;
-		fputchar('.'); fflush(stdout);
-	}
-}
-
-
-static int wait_evt_running(int seconds, int exists)
-{
-	int i;
-	if (event_exists(EVT_RUNNING) == exists)
-		return 0;
-	for (i = 0; ; ) {
-		Sleep(1000);
-		if (event_exists(EVT_RUNNING) == exists)
-			return 0;
-		if (++i >= seconds)
-			return -1;
-		fputchar('.'); fflush(stdout);
-	}
-}
-
-
-static int is_initd_command(char * s)
-{
-	if (!strcmp(s, "status"))
-		return EVT_RUNNING;
-	if (!strcmp(s, "stop"))
-		return SIGTERM;
-	if (!strcmp(s, "reload"))
-		return SIGHUP;
-	if (!strcmp(s, "sigusr1"))
-		return SIGUSR1;
-	if (!strcmp(s, "sigusr2"))
-		return SIGUSR2;
-	if (!strcmp(s, "restart"))
-		return EVT_RESTART;
-	return -1;
-}
-
-
-static int initd_main(const char * ident, int argc, char **argv)
-{
-	int rc;
-	if (argc < 2)
-		return -1;
-	if ((rc = is_initd_command(argv[1])) < 0)
-		return -1;
-	if (argc != 2) {
-		printf("%s: no arguments allowed for command %s\n", ident, argv[1]);
-		return 1;
-	}
-
-	switch (rc) {
-		default:
-		case EVT_RUNNING:
-			printf("Checking for %s:", ident); fflush(stdout);
-			rc = event_exists(EVT_RUNNING);
-			puts(rc ? " running" : " not running");
-			return (rc ? 0 : 1);
-
-		case SIGTERM:
-			printf("Stopping %s:", ident); fflush(stdout);
-			rc = sig_event(SIGTERM);
-			if (rc <= 0) {
-				puts(rc < 0 ? " not running" : " error");
-				return (rc < 0 ? 0 : 1);
-			}
-			rc = wait_evt_running(10, 0);
-			puts(!rc ? " done" : " timeout");
-			return (!rc ? 0 : 1);
-
-		case SIGHUP:
-			printf("Reloading %s:", ident); fflush(stdout);
-			rc = sig_event(SIGHUP);
-			puts(rc > 0 ? " done" : rc == 0 ? " error" : " not running");
-			return (rc > 0 ? 0 : 1);
-
-		case SIGUSR1:
-		case SIGUSR2:
-			printf("Sending SIGUSR%d to %s:", (rc-SIGUSR1+1), ident); fflush(stdout);
-			rc = sig_event(rc);
-			puts(rc > 0 ? " done" : rc == 0 ? " error" : " not running");
-			return (rc > 0 ? 0 : 1);
-
-		case EVT_RESTART:
-			{
-				HANDLE rst;
-				printf("Stopping %s:", ident); fflush(stdout);
-				if (event_exists(EVT_DETACHED)) {
-					puts(" not detached, cannot restart");
-					return 1;
-				}
-				if (!(rst = create_event(EVT_RESTART, FALSE, FALSE, NULL))) {
-					puts(" error");
-					return 1;
-				}
-				rc = sig_event(SIGTERM);
-				if (rc <= 0) {
-					puts(rc < 0 ? " not running" : " error");
-					CloseHandle(rst);
-					return 1;
-				}
-				rc = wait_signaled(rst, 10);
-				CloseHandle(rst);
-				if (rc) {
-					puts(" timeout");
-					return 1;
-				}
-				puts(" done");
-				Sleep(100);
-
-				printf("Starting %s:", ident); fflush(stdout);
-				rc = wait_evt_running(10, 1);
-				puts(!rc ? " done" : " error");
-				return (!rc ? 0 : 1);
-			}
-	}
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Windows Service Functions
-
-int daemon_winsvc_exitcode; // Set by app to exit(code)
-
-static SERVICE_STATUS_HANDLE svc_handle;
-static SERVICE_STATUS svc_status;
-
-
-// Report status to SCM
-
-static void service_report_status(int state, int seconds)
-{
-	// TODO: Avoid race
-	static DWORD checkpoint = 1;
-	svc_status.dwCurrentState = state;
-	svc_status.dwWaitHint = seconds*1000;
-	switch (state) {
-		default:
-			svc_status.dwCheckPoint = checkpoint++;
-			break;
-		case SERVICE_RUNNING:
-		case SERVICE_STOPPED:
-			svc_status.dwCheckPoint = 0;
-	}
-	switch (state) {
-		case SERVICE_START_PENDING:
-		case SERVICE_STOP_PENDING:
-			svc_status.dwControlsAccepted = 0;
-			break;
-		default:
-			svc_status.dwControlsAccepted =
-				SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|
-				SERVICE_ACCEPT_PAUSE_CONTINUE|SERVICE_ACCEPT_PARAMCHANGE;
-			break;
-	}
-	SetServiceStatus(svc_handle, &svc_status);
-}
-
-
-// Control the service, called by SCM
-
-static void WINAPI service_control(DWORD ctrlcode)
-{
-	switch (ctrlcode) {
-		case SERVICE_CONTROL_STOP:
-		case SERVICE_CONTROL_SHUTDOWN:
-			service_report_status(SERVICE_STOP_PENDING, 30);
-			svc_paused = 0;
-			sig_event(SIGTERM);
-			break;
-		case SERVICE_CONTROL_PARAMCHANGE: // Win2000/XP
-			service_report_status(svc_status.dwCurrentState, 0);
-			svc_paused = 0;
-			sig_event(SIGHUP); // reload
-			break;
-		case SERVICE_CONTROL_PAUSE:
-			service_report_status(SERVICE_PAUSED, 0);
-			svc_paused = 1;
-			break;
-		case SERVICE_CONTROL_CONTINUE:
-			service_report_status(SERVICE_RUNNING, 0);
-			{
-				int was_paused = svc_paused;
-				svc_paused = 0;
-				sig_event(was_paused ? SIGHUP : SIGUSR1); // reload:recheck
-			}
-			break;
-		case SERVICE_CONTROL_INTERROGATE:
-		default: // unknown
-			service_report_status(svc_status.dwCurrentState, 0);
-			break;
-	}
-}
-
-
-// Exit handler for service
-
-static void service_exit(void)
-{
-	// Close signal events
-	int i;
-	for (i = 0; i < num_sig_handlers; i++)
-		CloseHandle(sig_events[i]);
-	num_sig_handlers = 0;
-
-	// Set exitcode
-	if (daemon_winsvc_exitcode) {
-		svc_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
-		svc_status.dwServiceSpecificExitCode = daemon_winsvc_exitcode;
-	}
-	// Report stopped
-	service_report_status(SERVICE_STOPPED, 0);
-}
-
-
-// Variables for passing main(argc, argv) from daemon_main to service_main()
-static int (*svc_main_func)(int, char **);
-static int svc_main_argc;
-static char ** svc_main_argv;
-
-// Main function for service, called by service dispatcher
-
-static void WINAPI service_main(DWORD argc, LPSTR * argv)
-{
-	char path[MAX_PATH], *p;
-	ARGUSED(argc);
-
-	// Register control handler
-	svc_handle = RegisterServiceCtrlHandler(argv[0], service_control);
-
-	// Init service status
-	svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
-	service_report_status(SERVICE_START_PENDING, 10);
-
-	// Service started in \windows\system32, change to .exe directory
-	if (GetModuleFileNameA(NULL, path, sizeof(path)) && (p = strrchr(path, '\\'))) {
-		*p = 0;	SetCurrentDirectoryA(path);
-	}
-	
-	// Install exit handler
-	atexit(service_exit);
-
-	// Do the real work, service status later updated by daemon_detach()
-	daemon_winsvc_exitcode = svc_main_func(svc_main_argc, svc_main_argv);
-
-	exit(daemon_winsvc_exitcode);
-	// ... continued in service_exit()
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Windows Service Admin Functions
-
-// Set Service description (Win2000/XP)
-
-static int svcadm_setdesc(SC_HANDLE hs, const char * desc)
-{
-	HANDLE hdll;
-	BOOL (WINAPI * ChangeServiceConfig2A_p)(SC_HANDLE, DWORD, LPVOID);
-	BOOL ret;
-	if (!(hdll = LoadLibraryA("ADVAPI32.DLL")))
-		return FALSE;
-	if (!((ChangeServiceConfig2A_p = (BOOL (WINAPI *)(SC_HANDLE, DWORD, LPVOID))GetProcAddress(hdll, "ChangeServiceConfig2A"))))
-		ret = FALSE;
-	else {
-		SERVICE_DESCRIPTIONA sd = { (char *)desc };
-		ret = ChangeServiceConfig2A_p(hs, SERVICE_CONFIG_DESCRIPTION, &sd);
-	}
-	FreeLibrary(hdll);
-	return ret;
-}
-
-
-// Service install/remove commands
-
-static int svcadm_main(const char * ident, const daemon_winsvc_options * svc_opts,
-                       int argc, char **argv                                      )
-{
-	int remove;
-	SC_HANDLE hm, hs;
-
-	if (argc < 2)
-		return -1;
-	if (!strcmp(argv[1], "install"))
-		remove = 0;
-	else if (!strcmp(argv[1], "remove")) {
-		if (argc != 2) {
-			printf("%s: no arguments allowed for command remove\n", ident);
-			return 1;
-		}
-		remove = 1;
-	}
-	else
-		return -1;
-
-	printf("%s service %s:", (!remove?"Installing":"Removing"), ident); fflush(stdout);
-
-	// Open SCM
-	if (!(hm = OpenSCManager(NULL/*local*/, NULL/*default*/, SC_MANAGER_ALL_ACCESS))) {
-		printf(" cannot open SCManager, Error=%ld\n", GetLastError());
-		return 1;
-	}
-
-	if (!remove) {
-		char path[MAX_PATH+100];
-		int i;
-		// Get program path
-		if (!GetModuleFileNameA(NULL, path, MAX_PATH)) {
-			printf(" unknown program path, Error=%ld\n", GetLastError());
-			CloseServiceHandle(hm);
-			return 1;
-		}
-		// Append options
-		strcat(path, " "); strcat(path, svc_opts->cmd_opt);
-		for (i = 2; i < argc; i++) {
-			const char * s = argv[i];
-			if (strlen(path)+strlen(s)+1 >= sizeof(path))
-				break;
-			strcat(path, " "); strcat(path, s);
-		}
-		// Create
-		if (!(hs = CreateService(hm,
-			svc_opts->svcname, svc_opts->dispname,
-			SERVICE_ALL_ACCESS,
-			SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
-			SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, path,
-			NULL/*no load ordering*/, NULL/*no tag id*/,
-			""/*no depedencies*/, NULL/*local system account*/, NULL/*no pw*/))) {
-			printf(" failed, Error=%ld\n", GetLastError());
-			CloseServiceHandle(hm);
-			return 1;
-		}
-		// Set optional description
-		if (svc_opts->descript)
-			svcadm_setdesc(hs, svc_opts->descript);
-	}
-	else {
-		// Open
-		if (!(hs = OpenService(hm, ident, SERVICE_ALL_ACCESS))) {
-			puts(" not found");
-			CloseServiceHandle(hm);
-			return 1;
-		}
-		// TODO: Stop service if running
-		// Remove
-		if (!DeleteService(hs)) {
-			printf(" failed, Error=%ld\n", GetLastError());
-			CloseServiceHandle(hs); CloseServiceHandle(hm);
-			return 1;
-		}
-	}
-	puts(" done");
-	CloseServiceHandle(hs); CloseServiceHandle(hm);
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Main Function
-
-// This function must be called from main()
-// main_func is the function doing the real work
-
-int daemon_main(const char * ident, const daemon_winsvc_options * svc_opts,
-                int (*main_func)(int, char **), int argc, char **argv      )
-{
-	int rc;
-#ifdef _DEBUG
-	// Enable Debug heap checks
-	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
-		|_CRTDBG_ALLOC_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF);
-#endif
-
-	// Check for [status|stop|reload|restart|sigusr1|sigusr2] parameters
-	if ((rc = initd_main(ident, argc, argv)) >= 0)
-		return rc;
-	// Check for [install|remove] parameters
-	if (svc_opts && (rc = svcadm_main(ident, svc_opts, argc, argv)) >= 0)
-		return rc;
-
-	// Run as service if svc_opts.cmd_opt is given as first(!) argument
-	svc_mode = (svc_opts && argc >= 2 && !strcmp(argv[1], svc_opts->cmd_opt));
-
-	if (!svc_mode) {
-		// Daemon: Try to simulate a Unix-like daemon
-		HANDLE rev;
-		BOOL exists;
-
-		// Create main event to detect process type:
-		// 1. new: parent process => start child and wait for detach() or exit() of child.
-		// 2. exists && signaled: child process => do the real work, signal detach() to parent
-		// 3. exists && !signaled: already running => exit()
-		if (!(rev = create_event(EVT_RUNNING, TRUE/*signaled*/, TRUE, &exists)))
-			return 100;
-
-		if (!exists && !debugging()) {
-			// Event new => parent process
-			return parent_main(rev);
-		}
-
-		if (WaitForSingleObject(rev, 0) == WAIT_OBJECT_0) {
-			// Event was signaled => In child process
-			return child_main(rev, main_func, argc, argv);
-		}
-
-		// Event no longer signaled => Already running!
-		daemon_help(stdout, ident, "already running");
-		CloseHandle(rev);
-		return 1;
-	}
-	else {
-		// Service: Start service_main() via SCM
-		SERVICE_TABLE_ENTRY service_table[] = {
-			{ (char*)svc_opts->svcname, service_main }, { NULL, NULL }
-		};
-
-		svc_main_func = main_func;
-		svc_main_argc = argc;
-		svc_main_argv = argv;
-		if (!StartServiceCtrlDispatcher(service_table)) {
-			fprintf(stderr, "%s: cannot dispatch service, Error=%ld\n", ident, GetLastError());
-#ifdef _DEBUG
-			if (debugging())
-				service_main(argc, argv);
-#endif
-			return 100;
-		}
-		Sleep(1000);
-		ExitThread(0); // Do not redo exit() processing
-		/*NOTREACHED*/
-		return 0;
-	}
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Test Program
-
-#ifdef TEST
-
-static volatile sig_atomic_t caughtsig = 0;
-
-static void sig_handler(int sig)
-{
-	caughtsig = sig;
-}
-
-static void test_exit(void)
-{
-	printf("Main exit\n");
-}
-
-int test_main(int argc, char **argv)
-{
-	int i;
-	int debug = 0;
-
-	printf("PID=%ld\n", GetCurrentProcessId());
-	for (i = 0; i < argc; i++) {
-		printf("%d: \"%s\"\n", i, argv[i]);
-		if (!strcmp(argv[i],"-d"))
-			debug = 1;
-	}
-
-	daemon_signal(SIGINT, sig_handler);
-	daemon_signal(SIGBREAK, sig_handler);
-	daemon_signal(SIGTERM, sig_handler);
-	daemon_signal(SIGHUP, sig_handler);
-	daemon_signal(SIGUSR2, sig_handler);
-
-	atexit(test_exit);
-
-	if (!debug) {
-		printf("Preparing to detach...\n");
-		Sleep(2000);
-		daemon_detach("test");
-		printf("Detached!\n");
-	}
-
-	for (;;) {
-		daemon_sleep(1);
-		printf("."); fflush(stdout);
-		if (caughtsig) {
-			if (caughtsig == SIGUSR2) {
-				debug ^= 1;
-				if (debug)
-					daemon_enable_console("Daemon[Debug]");
-				else
-					daemon_disable_console();
-			}
-			printf("[PID=%ld: Signal=%d]", GetCurrentProcessId(), caughtsig); fflush(stdout);
-			if (caughtsig == SIGTERM || caughtsig == SIGBREAK)
-				break;
-			caughtsig = 0;
-		}
-	}
-	printf("\nExiting on signal %d\n", caughtsig);
-	return 0;
-}
-
-
-int main(int argc, char **argv)
-{
-	static const daemon_winsvc_options svc_opts = {
-	"-s", "test", "Test Service", "Service to test daemon_win32.c Module"
-	};
-
-	return daemon_main("testd", &svc_opts, test_main, argc, argv);
-}
-
-#endif
diff --git a/sm5/os_win32/daemon_win32.cpp b/sm5/os_win32/daemon_win32.cpp
deleted file mode 100644
index 5220f40cd31184186e85e7c811c9ed1bf2018d05..0000000000000000000000000000000000000000
--- a/sm5/os_win32/daemon_win32.cpp
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * os_win32/daemon_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <io.h>
-
-#define WIN32_LEAN_AND_MEAN
-// Need MB_SERVICE_NOTIFICATION (NT4/2000/XP), IsDebuggerPresent() (Win98/ME/NT4/2000/XP)
-#define _WIN32_WINNT 0x0400 
-#include <windows.h>
-#ifdef _DEBUG
-#include <crtdbg.h>
-#endif
-
-#include "daemon_win32.h"
-
-const char *daemon_win32_c_cvsid = "$Id: daemon_win32.cpp,v 1.5 2004/08/09 14:35:59 chrfranke Exp $"
-DAEMON_WIN32_H_CVSID;
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-#define ARGUSED(x) ((void)(x))
-
-// Prevent spawning of child process if debugging
-#ifdef _DEBUG
-#define debugging() IsDebuggerPresent()
-#else
-#define debugging() FALSE
-#endif
-
-
-#define EVT_NAME_LEN 260
-
-// Internal events (must be > SIGUSRn)
-#define EVT_RUNNING   100 // Exists when running, signaled on creation
-#define EVT_DETACHED  101 // Signaled when child detaches from console
-#define EVT_RESTART   102 // Signaled when child should restart
-
-static void make_name(char * name, int sig)
-{
-	int i;
-	if (!GetModuleFileNameA(NULL, name, EVT_NAME_LEN-10))
-		strcpy(name, "DaemonEvent");
-	for (i = 0; name[i]; i++) {
-		char c = name[i];
-		if (!(   ('0' <= c && c <= '9')
-		      || ('A' <= c && c <= 'Z')
-		      || ('a' <= c && c <= 'z')))
-			  name[i] = '_';
-	}
-	sprintf(name+strlen(name), "-%d", sig);
-}
-
-
-static HANDLE create_event(int sig, BOOL initial, BOOL errmsg, BOOL * exists)
-{
-	char name[EVT_NAME_LEN];
-	HANDLE h;
-	make_name(name, sig);
-	if (exists)
-		*exists = FALSE;
-	if (!(h = CreateEventA(NULL, FALSE, initial, name))) {
-		if (errmsg)
-			fprintf(stderr, "CreateEvent(.,\"%s\"): Error=%ld\n", name, GetLastError());
-		return 0;
-	}
-
-	if (GetLastError() == ERROR_ALREADY_EXISTS) {
-		if (!exists) {
-			if (errmsg)
-				fprintf(stderr, "CreateEvent(.,\"%s\"): Exists\n", name);
-			CloseHandle(h);
-			return 0;
-		}
-		*exists = TRUE;
-	}
-	return h;
-}
-
-
-static HANDLE open_event(int sig)
-{
-	char name[EVT_NAME_LEN];
-	make_name(name, sig);
-	return OpenEventA(EVENT_MODIFY_STATE, FALSE, name);
-}
-
-
-static int event_exists(int sig)
-{
-	char name[EVT_NAME_LEN];
-	HANDLE h;
-	make_name(name, sig);
-	if (!(h = OpenEventA(EVENT_MODIFY_STATE, FALSE, name)))
-		return 0;
-	CloseHandle(h);
-	return 1;
-}
-
-
-static int sig_event(int sig)
-{
-	char name[EVT_NAME_LEN];
-	HANDLE h;
-	make_name(name, sig);
-	if (!(h = OpenEventA(EVENT_MODIFY_STATE, FALSE, name))) {
-		make_name(name, EVT_RUNNING);
-		if (!(h = OpenEvent(EVENT_MODIFY_STATE, FALSE, name)))
-			return -1;
-		CloseHandle(h);
-		return 0;
-	}
-	SetEvent(h);
-	CloseHandle(h);
-	return 1;
-}
-
-
-static void daemon_help(FILE * f, const char * ident, const char * message)
-{
-	fprintf(f,
-		"%s: %s.\n"
-		"Use \"%s status|stop|reload|restart|sigusr1|sigusr2\" to control daemon.\n",
-		ident, message, ident);
-	fflush(f);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Parent Process
-
-
-static BOOL WINAPI parent_console_handler(DWORD event)
-{
-	switch (event) {
-		case CTRL_C_EVENT:
-		case CTRL_BREAK_EVENT:
-			return TRUE; // Ignore
-	}
-	return FALSE; // continue with next handler ...
-}
-
-
-static int parent_main(HANDLE rev)
-{
-	HANDLE dev;
-	HANDLE ht[2];
-	char * cmdline;
-	STARTUPINFO si;
-	PROCESS_INFORMATION pi;
-	DWORD rc, exitcode;
-
-	// Ignore ^C, ^BREAK in parent
-	SetConsoleCtrlHandler(parent_console_handler, TRUE/*add*/);
-
-	// Create event used by child to signal daemon_detach()
-	if (!(dev = create_event(EVT_DETACHED, FALSE/*not signaled*/, TRUE, NULL/*must not exist*/))) {
-		CloseHandle(rev);
-		return 101;
-	}
-
-	// Restart process with same args
-	cmdline = GetCommandLineA();
-	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
-	
-	if (!CreateProcessA(
-		NULL, cmdline,
-		NULL, NULL, TRUE/*inherit*/,
-		0, NULL, NULL, &si, &pi)) {
-		fprintf(stderr, "CreateProcess(.,\"%s\",.) failed, Error=%ld\n", cmdline, GetLastError());
-		CloseHandle(rev); CloseHandle(dev);
-		return 101;
-	}
-	CloseHandle(pi.hThread);
-
-	// Wait for daemon_detach() or exit()
-	ht[0] = dev; ht[1] = pi.hProcess;
-	rc = WaitForMultipleObjects(2, ht, FALSE/*or*/, INFINITE);
-	if (!(/*WAIT_OBJECT_0(0) <= rc && */ rc < WAIT_OBJECT_0+2)) {
-		fprintf(stderr, "WaitForMultipleObjects returns %lX\n", rc);
-		TerminateProcess(pi.hProcess, 200);
-	}
-	CloseHandle(rev); CloseHandle(dev);
-
-	// Get exit code
-	if (!GetExitCodeProcess(pi.hProcess, &exitcode))
-		exitcode = 201;
-	else if (exitcode == STILL_ACTIVE) // detach()ed, assume OK
-		exitcode = 0;
-
-	CloseHandle(pi.hProcess);
-	return exitcode;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Child Process
-
-
-static int svc_mode;   // Running as service?
-static int svc_paused; // Service paused?
-
-static void service_report_status(int state, int waithint);
-
-
-// Tables of signal handler and corresponding events
-typedef void (*sigfunc_t)(int);
-
-#define MAX_SIG_HANDLERS 8
-
-static int num_sig_handlers = 0;
-static sigfunc_t sig_handlers[MAX_SIG_HANDLERS];
-static int sig_numbers[MAX_SIG_HANDLERS];
-static HANDLE sig_events[MAX_SIG_HANDLERS];
-
-static HANDLE sigint_handle, sigbreak_handle, sigterm_handle;
-
-static HANDLE running_event;
-
-static int reopen_stdin, reopen_stdout, reopen_stderr;
-
-
-// Handler for windows console events
-
-static BOOL WINAPI child_console_handler(DWORD event)
-{
-	// Caution: runs in a new thread
-	// TODO: Guard with a mutex
-	HANDLE h = 0;
-	switch (event) {
-		case CTRL_C_EVENT: // <CONTROL-C> (SIGINT)
-			h = sigint_handle; break;
-		case CTRL_BREAK_EVENT: // <CONTROL-Break> (SIGBREAK/SIGQUIT)
-		case CTRL_CLOSE_EVENT: // User closed console or abort via task manager
-			h = sigbreak_handle; break;
-		case CTRL_LOGOFF_EVENT: // Logout/Shutdown (SIGTERM)
-		case CTRL_SHUTDOWN_EVENT:
-			h = sigterm_handle; break;
-	}
-	if (!h)
-		return FALSE; // continue with next handler
-	// Signal event
-	if (!SetEvent(h))
-		return FALSE;
-	return TRUE;
-}
-
-
-static void child_exit(void)
-{
-	int i;
-	char * cmdline;
-	HANDLE rst;
-	STARTUPINFO si;
-	PROCESS_INFORMATION pi;
-
-	for (i = 0; i < num_sig_handlers; i++)
-		CloseHandle(sig_events[i]);
-	num_sig_handlers = 0;
-	CloseHandle(running_event); running_event = 0;
-
-	// Restart?
-	if (!(rst = open_event(EVT_RESTART)))
-		return; // No => normal exit
-
-	// Yes => Signal exit and restart process
-	Sleep(500);
-	SetEvent(rst);
-	CloseHandle(rst);
-	Sleep(500);
-
-	cmdline = GetCommandLineA();
-	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
-	si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;
-
-	if (!CreateProcessA(
-		NULL, cmdline,
-		NULL, NULL, TRUE/*inherit*/,
-		0, NULL, NULL, &si, &pi)) {
-		fprintf(stderr, "CreateProcess(.,\"%s\",.) failed, Error=%ld\n", cmdline, GetLastError());
-	}
-	CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
-}
-
-static int child_main(HANDLE hev,int (*main_func)(int, char **), int argc, char **argv)
-{
-	// Keep EVT_RUNNING open until exit
-	running_event = hev;
-
-	// Install console handler
-	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);
-
-	// Install restart handler
-	atexit(child_exit);
-
-	// Continue in main_func() to do the real work
-	return main_func(argc, argv);
-}
-
-
-// Simulate signal()
-
-sigfunc_t daemon_signal(int sig, sigfunc_t func)
-{
-	int i;
-	HANDLE h;
-	if (func == SIG_DFL || func == SIG_IGN)
-		return func; // TODO
-	for (i = 0; i < num_sig_handlers; i++) {
-		if (sig_numbers[i] == sig) {
-			sigfunc_t old = sig_handlers[i];
-			sig_handlers[i] = func;
-			return old;
-		}
-	}
-	if (num_sig_handlers >= MAX_SIG_HANDLERS)
-		return SIG_ERR;
-	if (!(h = create_event(sig, FALSE, TRUE, NULL)))
-		return SIG_ERR;
-	sig_events[num_sig_handlers]   = h;
-	sig_numbers[num_sig_handlers]  = sig;
-	sig_handlers[num_sig_handlers] = func;
-	switch (sig) {
-		case SIGINT:   sigint_handle   = h; break;
-		case SIGTERM:  sigterm_handle  = h; break;
-		case SIGBREAK: sigbreak_handle = h; break;
-	}
-	num_sig_handlers++;
-	return SIG_DFL;
-}
-
-
-// strsignal()
-
-const char * daemon_strsignal(int sig)
-{
-	switch (sig) {
-		case SIGHUP:  return "SIGHUP";
-		case SIGINT:  return "SIGINT";
-		case SIGTERM: return "SIGTERM";
-		case SIGBREAK:return "SIGBREAK";
-		case SIGUSR1: return "SIGUSR1";
-		case SIGUSR2: return "SIGUSR2";
-		default:      return "*UNKNOWN*";
-	}
-}
-
-
-// Simulate sleep()
-
-void daemon_sleep(int seconds)
-{
-	do {
-		if (num_sig_handlers <= 0) {
-			Sleep(seconds*1000L);
-		}
-		else {
-			// Wait for any signal or timeout
-			DWORD rc = WaitForMultipleObjects(num_sig_handlers, sig_events,
-				FALSE/*OR*/, seconds*1000L);
-			if (rc != WAIT_TIMEOUT) {
-				if (!(/*WAIT_OBJECT_0(0) <= rc && */ rc < WAIT_OBJECT_0+(unsigned)num_sig_handlers)) {
-					fprintf(stderr,"WaitForMultipleObjects returns %lu\n", rc);
-					Sleep(seconds*1000L);
-					return;
-				}
-				// Call Handler
-				sig_handlers[rc-WAIT_OBJECT_0](sig_numbers[rc-WAIT_OBJECT_0]);
-				break;
-			}
-		}
-	} while (svc_paused);
-}
-
-
-// Disable/Enable console
-
-void daemon_disable_console()
-{
-	SetConsoleCtrlHandler(child_console_handler, FALSE/*remove*/);
-	reopen_stdin = reopen_stdout = reopen_stderr = 0;
-	if (isatty(fileno(stdin))) {
-		fclose(stdin); reopen_stdin = 1;
-	}
-	if (isatty(fileno(stdout))) {
-		fclose(stdout); reopen_stdout = 1;
-	}
-	if (isatty(fileno(stderr))) {
-		fclose(stderr); reopen_stderr = 1;
-	}
-	FreeConsole();
-	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);
-}
-
-int daemon_enable_console(const char * title)
-{
-	BOOL ok;
-	SetConsoleCtrlHandler(child_console_handler, FALSE/*remove*/);
-	ok = AllocConsole();
-	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);
-	if (!ok)
-		return -1;
-	if (title)
-		SetConsoleTitleA(title);
-	if (reopen_stdin)
-		freopen("conin$",  "r", stdin);
-	if (reopen_stdout)
-		freopen("conout$", "w", stdout);
-	if (reopen_stderr)
-		freopen("conout$", "w", stderr);
-	reopen_stdin = reopen_stdout = reopen_stderr = 0;
-	return 0;
-}
-
-
-// Detach daemon from console & parent
-
-int daemon_detach(const char * ident)
-{
-	if (!svc_mode) {
-		if (ident) {
-			// Print help
-			FILE * f = ( isatty(fileno(stdout)) ? stdout
-					   : isatty(fileno(stderr)) ? stderr : NULL);
-			if (f)
-				daemon_help(f, ident, "now detaches from console into background mode");
-		}
-		// Signal detach to parent
-		if (sig_event(EVT_DETACHED) != 1) {
-			if (!debugging())
-				return -1;
-		}
-		daemon_disable_console();
-	}
-	else {
-		// Signal end of initialization to service control manager
-		service_report_status(SERVICE_RUNNING, 0);
-	}
-
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// MessageBox
-
-#ifndef _MT
-//MT runtime not necessary, because mbox_thread uses no unsafe lib functions
-//#error Program must be linked with multithreaded runtime library
-#endif
-
-static LONG mbox_count; // # mbox_thread()s
-static HANDLE mbox_mutex; // Show 1 box at a time (not necessary for service)
-
-typedef struct mbox_args_s {
-	HANDLE taken; const char * title, * text; int mode;
-} mbox_args;
-
-
-// Thread to display one message box
-
-static ULONG WINAPI mbox_thread(LPVOID arg)
-{
-	// Take args
-	mbox_args * mb = (mbox_args *)arg;
-	char title[100]; char text[1000]; int mode;
-	strncpy(title, mb->title, sizeof(title)-1); title[sizeof(title)-1] = 0;
-	strncpy(text , mb->text , sizeof(text )-1); text [sizeof(text )-1] = 0;
-	mode = mb->mode;
-	SetEvent(mb->taken);
-
-	// Show only one box at a time
-	WaitForSingleObject(mbox_mutex, INFINITE);
-	MessageBoxA(NULL, text, title, mode);
-	ReleaseMutex(mbox_mutex);
-
-	InterlockedDecrement(&mbox_count);
-	return 0;
-}
-
-
-// Display a message box
-int daemon_messagebox(int system, const char * title, const char * text)
-{
-	mbox_args mb;
-	HANDLE ht; DWORD tid;
-
-	// Create mutex during first call
-	if (!mbox_mutex)
-		mbox_mutex = CreateMutex(NULL/*!inherit*/, FALSE/*!owned*/, NULL/*unnamed*/);
-
-	// Allow at most 10 threads
-	if (InterlockedIncrement(&mbox_count) > 10) {
-		InterlockedDecrement(&mbox_count);
-		return -1;
-	}
-
-	// Create thread
-	mb.taken = CreateEvent(NULL/*!inherit*/, FALSE, FALSE/*!signaled*/, NULL/*unnamed*/);
-	mb.mode = MB_OK|MB_ICONWARNING
-	         |(svc_mode?MB_SERVICE_NOTIFICATION:0)
-	         |(system?MB_SYSTEMMODAL:MB_APPLMODAL);
-	mb.title = title; mb.text = text;
-	mb.text = text;
-	if (!(ht = CreateThread(NULL, 0, mbox_thread, &mb, 0, &tid)))
-		return -1;
-
-	// Wait for args taken
-	if (WaitForSingleObject(mb.taken, 10000) != WAIT_OBJECT_0)
-		TerminateThread(ht, 0);
-	CloseHandle(mb.taken);
-	CloseHandle(ht);
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-// Spawn a command and redirect <inpbuf >outbuf
-// return command's exitcode or -1 on error
-
-int daemon_spawn(const char * cmd,
-                 const char * inpbuf, int inpsize,
-                 char *       outbuf, int outsize )
-{
-	HANDLE pipe_inp_r, pipe_inp_w, pipe_out_r, pipe_out_w, pipe_err_w, h;
-	DWORD num_io, exitcode; int i;
-	SECURITY_ATTRIBUTES sa;
-	STARTUPINFO si; PROCESS_INFORMATION pi;
-	HANDLE self = GetCurrentProcess();
-
-	// Create stdin pipe with inheritable read side
-	memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa);
-	sa.bInheritHandle = TRUE;
-	if (!CreatePipe(&pipe_inp_r, &h, &sa, inpsize*2+13))
-		return -1;
-	if (!DuplicateHandle(self, h, self, &pipe_inp_w,
-		0, FALSE/*!inherit*/, DUPLICATE_SAME_ACCESS)) {
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	CloseHandle(h);
-
-	// Create stdout pipe with inheritable write side
-	memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa);
-	sa.bInheritHandle = TRUE;
-	if (!CreatePipe(&h, &pipe_out_w, &sa, outsize)) {
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	if (!DuplicateHandle(self, h, self, &pipe_out_r,
-		0, FALSE/*!inherit*/, DUPLICATE_SAME_ACCESS)) {
-		CloseHandle(h);          CloseHandle(pipe_out_w);
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	CloseHandle(h);
-
-	// Create stderr handle as dup of stdout write side
-	if (!DuplicateHandle(self, pipe_out_w, self, &pipe_err_w,
-		0, TRUE/*inherit*/, DUPLICATE_SAME_ACCESS)) {
-		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-
-	// Create process with pipes as stdio
-	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
-	si.hStdInput  = pipe_inp_r;
-	si.hStdOutput = pipe_out_w;
-	si.hStdError  = pipe_err_w;
-	si.dwFlags = STARTF_USESTDHANDLES;
-	if (!CreateProcessA(
-		NULL, (char*)cmd,
-		NULL, NULL, TRUE/*inherit*/,
-		DETACHED_PROCESS/*no new console*/,
-		NULL, NULL, &si, &pi)) {
-		CloseHandle(pipe_err_w);
-		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);
-		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);
-		return -1;
-	}
-	CloseHandle(pi.hThread);
-	// Close inherited handles
-	CloseHandle(pipe_inp_r);
-	CloseHandle(pipe_out_w);
-	CloseHandle(pipe_err_w);
-
-	// Copy inpbuf to stdin
-	// convert \n => \r\n 
-	for (i = 0; i < inpsize; ) {
-		int len = 0;
-		while (i+len < inpsize && inpbuf[i+len] != '\n')
-			len++;
-		if (len > 0)
-			WriteFile(pipe_inp_w, inpbuf+i, len, &num_io, NULL);
-		i += len;
-		if (i < inpsize) {
-			WriteFile(pipe_inp_w, "\r\n", 2, &num_io, NULL);
-			i++;
-		}
-	}
-	CloseHandle(pipe_inp_w);
-
-	// Copy stdout to output buffer until full, rest to /dev/null
-	// convert \r\n => \n
-	for (i = 0; ; ) {
-		char buf[256];
-		int j;
-		if (!ReadFile(pipe_out_r, buf, sizeof(buf), &num_io, NULL) || num_io == 0)
-			break;
-		for (j = 0; i < outsize-1 && j < (int)num_io; j++) {
-			if (buf[j] != '\r')
-				outbuf[i++] = buf[j];
-		}	
-	}
-	outbuf[i] = 0;
-	CloseHandle(pipe_out_r);
-
-	// Wait for process exitcode
-	WaitForSingleObject(pi.hProcess, INFINITE);
-	exitcode = 42;
-	GetExitCodeProcess(pi.hProcess, &exitcode);
-	CloseHandle(pi.hProcess);
-	return exitcode;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Initd Functions
-
-static int wait_signaled(HANDLE h, int seconds)
-{
-	int i;
-	for (i = 0; ; ) {
-		if (WaitForSingleObject(h, 1000L) == WAIT_OBJECT_0)
-			return 0;
-		if (++i >= seconds)
-			return -1;
-		fputchar('.'); fflush(stdout);
-	}
-}
-
-
-static int wait_evt_running(int seconds, int exists)
-{
-	int i;
-	if (event_exists(EVT_RUNNING) == exists)
-		return 0;
-	for (i = 0; ; ) {
-		Sleep(1000);
-		if (event_exists(EVT_RUNNING) == exists)
-			return 0;
-		if (++i >= seconds)
-			return -1;
-		fputchar('.'); fflush(stdout);
-	}
-}
-
-
-static int is_initd_command(char * s)
-{
-	if (!strcmp(s, "status"))
-		return EVT_RUNNING;
-	if (!strcmp(s, "stop"))
-		return SIGTERM;
-	if (!strcmp(s, "reload"))
-		return SIGHUP;
-	if (!strcmp(s, "sigusr1"))
-		return SIGUSR1;
-	if (!strcmp(s, "sigusr2"))
-		return SIGUSR2;
-	if (!strcmp(s, "restart"))
-		return EVT_RESTART;
-	return -1;
-}
-
-
-static int initd_main(const char * ident, int argc, char **argv)
-{
-	int rc;
-	if (argc < 2)
-		return -1;
-	if ((rc = is_initd_command(argv[1])) < 0)
-		return -1;
-	if (argc != 2) {
-		printf("%s: no arguments allowed for command %s\n", ident, argv[1]);
-		return 1;
-	}
-
-	switch (rc) {
-		default:
-		case EVT_RUNNING:
-			printf("Checking for %s:", ident); fflush(stdout);
-			rc = event_exists(EVT_RUNNING);
-			puts(rc ? " running" : " not running");
-			return (rc ? 0 : 1);
-
-		case SIGTERM:
-			printf("Stopping %s:", ident); fflush(stdout);
-			rc = sig_event(SIGTERM);
-			if (rc <= 0) {
-				puts(rc < 0 ? " not running" : " error");
-				return (rc < 0 ? 0 : 1);
-			}
-			rc = wait_evt_running(10, 0);
-			puts(!rc ? " done" : " timeout");
-			return (!rc ? 0 : 1);
-
-		case SIGHUP:
-			printf("Reloading %s:", ident); fflush(stdout);
-			rc = sig_event(SIGHUP);
-			puts(rc > 0 ? " done" : rc == 0 ? " error" : " not running");
-			return (rc > 0 ? 0 : 1);
-
-		case SIGUSR1:
-		case SIGUSR2:
-			printf("Sending SIGUSR%d to %s:", (rc-SIGUSR1+1), ident); fflush(stdout);
-			rc = sig_event(rc);
-			puts(rc > 0 ? " done" : rc == 0 ? " error" : " not running");
-			return (rc > 0 ? 0 : 1);
-
-		case EVT_RESTART:
-			{
-				HANDLE rst;
-				printf("Stopping %s:", ident); fflush(stdout);
-				if (event_exists(EVT_DETACHED)) {
-					puts(" not detached, cannot restart");
-					return 1;
-				}
-				if (!(rst = create_event(EVT_RESTART, FALSE, FALSE, NULL))) {
-					puts(" error");
-					return 1;
-				}
-				rc = sig_event(SIGTERM);
-				if (rc <= 0) {
-					puts(rc < 0 ? " not running" : " error");
-					CloseHandle(rst);
-					return 1;
-				}
-				rc = wait_signaled(rst, 10);
-				CloseHandle(rst);
-				if (rc) {
-					puts(" timeout");
-					return 1;
-				}
-				puts(" done");
-				Sleep(100);
-
-				printf("Starting %s:", ident); fflush(stdout);
-				rc = wait_evt_running(10, 1);
-				puts(!rc ? " done" : " error");
-				return (!rc ? 0 : 1);
-			}
-	}
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Windows Service Functions
-
-int daemon_winsvc_exitcode; // Set by app to exit(code)
-
-static SERVICE_STATUS_HANDLE svc_handle;
-static SERVICE_STATUS svc_status;
-
-
-// Report status to SCM
-
-static void service_report_status(int state, int seconds)
-{
-	// TODO: Avoid race
-	static DWORD checkpoint = 1;
-	svc_status.dwCurrentState = state;
-	svc_status.dwWaitHint = seconds*1000;
-	switch (state) {
-		default:
-			svc_status.dwCheckPoint = checkpoint++;
-			break;
-		case SERVICE_RUNNING:
-		case SERVICE_STOPPED:
-			svc_status.dwCheckPoint = 0;
-	}
-	switch (state) {
-		case SERVICE_START_PENDING:
-		case SERVICE_STOP_PENDING:
-			svc_status.dwControlsAccepted = 0;
-			break;
-		default:
-			svc_status.dwControlsAccepted =
-				SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|
-				SERVICE_ACCEPT_PAUSE_CONTINUE|SERVICE_ACCEPT_PARAMCHANGE;
-			break;
-	}
-	SetServiceStatus(svc_handle, &svc_status);
-}
-
-
-// Control the service, called by SCM
-
-static void WINAPI service_control(DWORD ctrlcode)
-{
-	switch (ctrlcode) {
-		case SERVICE_CONTROL_STOP:
-		case SERVICE_CONTROL_SHUTDOWN:
-			service_report_status(SERVICE_STOP_PENDING, 30);
-			svc_paused = 0;
-			sig_event(SIGTERM);
-			break;
-		case SERVICE_CONTROL_PARAMCHANGE: // Win2000/XP
-			service_report_status(svc_status.dwCurrentState, 0);
-			svc_paused = 0;
-			sig_event(SIGHUP); // reload
-			break;
-		case SERVICE_CONTROL_PAUSE:
-			service_report_status(SERVICE_PAUSED, 0);
-			svc_paused = 1;
-			break;
-		case SERVICE_CONTROL_CONTINUE:
-			service_report_status(SERVICE_RUNNING, 0);
-			{
-				int was_paused = svc_paused;
-				svc_paused = 0;
-				sig_event(was_paused ? SIGHUP : SIGUSR1); // reload:recheck
-			}
-			break;
-		case SERVICE_CONTROL_INTERROGATE:
-		default: // unknown
-			service_report_status(svc_status.dwCurrentState, 0);
-			break;
-	}
-}
-
-
-// Exit handler for service
-
-static void service_exit(void)
-{
-	// Close signal events
-	int i;
-	for (i = 0; i < num_sig_handlers; i++)
-		CloseHandle(sig_events[i]);
-	num_sig_handlers = 0;
-
-	// Set exitcode
-	if (daemon_winsvc_exitcode) {
-		svc_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
-		svc_status.dwServiceSpecificExitCode = daemon_winsvc_exitcode;
-	}
-	// Report stopped
-	service_report_status(SERVICE_STOPPED, 0);
-}
-
-
-// Variables for passing main(argc, argv) from daemon_main to service_main()
-static int (*svc_main_func)(int, char **);
-static int svc_main_argc;
-static char ** svc_main_argv;
-
-// Main function for service, called by service dispatcher
-
-static void WINAPI service_main(DWORD argc, LPSTR * argv)
-{
-	char path[MAX_PATH], *p;
-	ARGUSED(argc);
-
-	// Register control handler
-	svc_handle = RegisterServiceCtrlHandler(argv[0], service_control);
-
-	// Init service status
-	svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
-	service_report_status(SERVICE_START_PENDING, 10);
-
-	// Service started in \windows\system32, change to .exe directory
-	if (GetModuleFileNameA(NULL, path, sizeof(path)) && (p = strrchr(path, '\\'))) {
-		*p = 0;	SetCurrentDirectoryA(path);
-	}
-	
-	// Install exit handler
-	atexit(service_exit);
-
-	// Do the real work, service status later updated by daemon_detach()
-	daemon_winsvc_exitcode = svc_main_func(svc_main_argc, svc_main_argv);
-
-	exit(daemon_winsvc_exitcode);
-	// ... continued in service_exit()
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Windows Service Admin Functions
-
-// Set Service description (Win2000/XP)
-
-static int svcadm_setdesc(SC_HANDLE hs, const char * desc)
-{
-	HANDLE hdll;
-	BOOL (WINAPI * ChangeServiceConfig2A_p)(SC_HANDLE, DWORD, LPVOID);
-	BOOL ret;
-	if (!(hdll = LoadLibraryA("ADVAPI32.DLL")))
-		return FALSE;
-	if (!((ChangeServiceConfig2A_p = (BOOL (WINAPI *)(SC_HANDLE, DWORD, LPVOID))GetProcAddress(hdll, "ChangeServiceConfig2A"))))
-		ret = FALSE;
-	else {
-		SERVICE_DESCRIPTIONA sd = { (char *)desc };
-		ret = ChangeServiceConfig2A_p(hs, SERVICE_CONFIG_DESCRIPTION, &sd);
-	}
-	FreeLibrary(hdll);
-	return ret;
-}
-
-
-// Service install/remove commands
-
-static int svcadm_main(const char * ident, const daemon_winsvc_options * svc_opts,
-                       int argc, char **argv                                      )
-{
-	int remove;
-	SC_HANDLE hm, hs;
-
-	if (argc < 2)
-		return -1;
-	if (!strcmp(argv[1], "install"))
-		remove = 0;
-	else if (!strcmp(argv[1], "remove")) {
-		if (argc != 2) {
-			printf("%s: no arguments allowed for command remove\n", ident);
-			return 1;
-		}
-		remove = 1;
-	}
-	else
-		return -1;
-
-	printf("%s service %s:", (!remove?"Installing":"Removing"), ident); fflush(stdout);
-
-	// Open SCM
-	if (!(hm = OpenSCManager(NULL/*local*/, NULL/*default*/, SC_MANAGER_ALL_ACCESS))) {
-		printf(" cannot open SCManager, Error=%ld\n", GetLastError());
-		return 1;
-	}
-
-	if (!remove) {
-		char path[MAX_PATH+100];
-		int i;
-		// Get program path
-		if (!GetModuleFileNameA(NULL, path, MAX_PATH)) {
-			printf(" unknown program path, Error=%ld\n", GetLastError());
-			CloseServiceHandle(hm);
-			return 1;
-		}
-		// Append options
-		strcat(path, " "); strcat(path, svc_opts->cmd_opt);
-		for (i = 2; i < argc; i++) {
-			const char * s = argv[i];
-			if (strlen(path)+strlen(s)+1 >= sizeof(path))
-				break;
-			strcat(path, " "); strcat(path, s);
-		}
-		// Create
-		if (!(hs = CreateService(hm,
-			svc_opts->svcname, svc_opts->dispname,
-			SERVICE_ALL_ACCESS,
-			SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
-			SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, path,
-			NULL/*no load ordering*/, NULL/*no tag id*/,
-			""/*no depedencies*/, NULL/*local system account*/, NULL/*no pw*/))) {
-			printf(" failed, Error=%ld\n", GetLastError());
-			CloseServiceHandle(hm);
-			return 1;
-		}
-		// Set optional description
-		if (svc_opts->descript)
-			svcadm_setdesc(hs, svc_opts->descript);
-	}
-	else {
-		// Open
-		if (!(hs = OpenService(hm, ident, SERVICE_ALL_ACCESS))) {
-			puts(" not found");
-			CloseServiceHandle(hm);
-			return 1;
-		}
-		// TODO: Stop service if running
-		// Remove
-		if (!DeleteService(hs)) {
-			printf(" failed, Error=%ld\n", GetLastError());
-			CloseServiceHandle(hs); CloseServiceHandle(hm);
-			return 1;
-		}
-	}
-	puts(" done");
-	CloseServiceHandle(hs); CloseServiceHandle(hm);
-	return 0;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Main Function
-
-// This function must be called from main()
-// main_func is the function doing the real work
-
-int daemon_main(const char * ident, const daemon_winsvc_options * svc_opts,
-                int (*main_func)(int, char **), int argc, char **argv      )
-{
-	int rc;
-#ifdef _DEBUG
-	// Enable Debug heap checks
-	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
-		|_CRTDBG_ALLOC_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF);
-#endif
-
-	// Check for [status|stop|reload|restart|sigusr1|sigusr2] parameters
-	if ((rc = initd_main(ident, argc, argv)) >= 0)
-		return rc;
-	// Check for [install|remove] parameters
-	if (svc_opts && (rc = svcadm_main(ident, svc_opts, argc, argv)) >= 0)
-		return rc;
-
-	// Run as service if svc_opts.cmd_opt is given as first(!) argument
-	svc_mode = (svc_opts && argc >= 2 && !strcmp(argv[1], svc_opts->cmd_opt));
-
-	if (!svc_mode) {
-		// Daemon: Try to simulate a Unix-like daemon
-		HANDLE rev;
-		BOOL exists;
-
-		// Create main event to detect process type:
-		// 1. new: parent process => start child and wait for detach() or exit() of child.
-		// 2. exists && signaled: child process => do the real work, signal detach() to parent
-		// 3. exists && !signaled: already running => exit()
-		if (!(rev = create_event(EVT_RUNNING, TRUE/*signaled*/, TRUE, &exists)))
-			return 100;
-
-		if (!exists && !debugging()) {
-			// Event new => parent process
-			return parent_main(rev);
-		}
-
-		if (WaitForSingleObject(rev, 0) == WAIT_OBJECT_0) {
-			// Event was signaled => In child process
-			return child_main(rev, main_func, argc, argv);
-		}
-
-		// Event no longer signaled => Already running!
-		daemon_help(stdout, ident, "already running");
-		CloseHandle(rev);
-		return 1;
-	}
-	else {
-		// Service: Start service_main() via SCM
-		SERVICE_TABLE_ENTRY service_table[] = {
-			{ (char*)svc_opts->svcname, service_main }, { NULL, NULL }
-		};
-
-		svc_main_func = main_func;
-		svc_main_argc = argc;
-		svc_main_argv = argv;
-		if (!StartServiceCtrlDispatcher(service_table)) {
-			fprintf(stderr, "%s: cannot dispatch service, Error=%ld\n", ident, GetLastError());
-#ifdef _DEBUG
-			if (debugging())
-				service_main(argc, argv);
-#endif
-			return 100;
-		}
-		Sleep(1000);
-		ExitThread(0); // Do not redo exit() processing
-		/*NOTREACHED*/
-		return 0;
-	}
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Test Program
-
-#ifdef TEST
-
-static volatile sig_atomic_t caughtsig = 0;
-
-static void sig_handler(int sig)
-{
-	caughtsig = sig;
-}
-
-static void test_exit(void)
-{
-	printf("Main exit\n");
-}
-
-int test_main(int argc, char **argv)
-{
-	int i;
-	int debug = 0;
-
-	printf("PID=%ld\n", GetCurrentProcessId());
-	for (i = 0; i < argc; i++) {
-		printf("%d: \"%s\"\n", i, argv[i]);
-		if (!strcmp(argv[i],"-d"))
-			debug = 1;
-	}
-
-	daemon_signal(SIGINT, sig_handler);
-	daemon_signal(SIGBREAK, sig_handler);
-	daemon_signal(SIGTERM, sig_handler);
-	daemon_signal(SIGHUP, sig_handler);
-	daemon_signal(SIGUSR2, sig_handler);
-
-	atexit(test_exit);
-
-	if (!debug) {
-		printf("Preparing to detach...\n");
-		Sleep(2000);
-		daemon_detach("test");
-		printf("Detached!\n");
-	}
-
-	for (;;) {
-		daemon_sleep(1);
-		printf("."); fflush(stdout);
-		if (caughtsig) {
-			if (caughtsig == SIGUSR2) {
-				debug ^= 1;
-				if (debug)
-					daemon_enable_console("Daemon[Debug]");
-				else
-					daemon_disable_console();
-			}
-			printf("[PID=%ld: Signal=%d]", GetCurrentProcessId(), caughtsig); fflush(stdout);
-			if (caughtsig == SIGTERM || caughtsig == SIGBREAK)
-				break;
-			caughtsig = 0;
-		}
-	}
-	printf("\nExiting on signal %d\n", caughtsig);
-	return 0;
-}
-
-
-int main(int argc, char **argv)
-{
-	static const daemon_winsvc_options svc_opts = {
-	"-s", "test", "Test Service", "Service to test daemon_win32.c Module"
-	};
-
-	return daemon_main("testd", &svc_opts, test_main, argc, argv);
-}
-
-#endif
diff --git a/sm5/os_win32/daemon_win32.h b/sm5/os_win32/daemon_win32.h
deleted file mode 100644
index 58a26895f3ece159f6b3113cb109d88354b352d1..0000000000000000000000000000000000000000
--- a/sm5/os_win32/daemon_win32.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * os_win32/daemon_win32.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef DAEMON_WIN32_H
-#define DAEMON_WIN32_H
-
-#define DAEMON_WIN32_H_CVSID "$Id: daemon_win32.h,v 1.4 2004/08/06 13:08:45 chrfranke Exp $\n"
-
-#include <signal.h>
-
-// Additional non-ANSI signals
-#define SIGHUP  (NSIG+1)
-#define SIGUSR1 (NSIG+2)
-#define SIGUSR2 (NSIG+3)
-
-
-// Options for Windows service
-typedef struct daemon_winsvc_options_s {
-	const char * cmd_opt;  // argv[1] option for services
-	// For service "install" command only:
-	const char * svcname;  // Service name
-	const char * dispname; // Service display name
-	const char * descript; // Service description
-} daemon_winsvc_options;
-
-
-// This function must be called from main()
-int daemon_main(const char * ident, const daemon_winsvc_options * svc_opts,
-                int (*main_func)(int, char **), int argc, char **argv      );
-
-// exit(code) returned by a service
-extern int daemon_winsvc_exitcode;
-
-// Simulate signal()
-void (*daemon_signal(int sig, void (*func)(int)))(int);
-const char * daemon_strsignal(int sig);
-
-// Simulate sleep()
-void daemon_sleep(int seconds);
-
-// Disable/Enable console
-void daemon_disable_console(void);
-int daemon_enable_console(const char * title);
-
-// Detach from console
-int daemon_detach(const char * ident);
-
-// Display a message box
-int daemon_messagebox(int system, const char * title, const char * text);
-
-// Spawn a process and redirect stdio
-int daemon_spawn(const char * cmd,
-                 const char * inpbuf, int inpsize,
-                 char *       outbuf, int outsize );
-
-#endif // DAEMON_WIN32_H
diff --git a/sm5/os_win32/hostname_win32.c b/sm5/os_win32/hostname_win32.c
deleted file mode 100644
index 21928adf4da274e13cfc960b27f81150233b5bd7..0000000000000000000000000000000000000000
--- a/sm5/os_win32/hostname_win32.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * os_win32/hostname_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "hostname_win32.h"
-
-const char * hostname_win32_c_cvsid = "$Id: hostname_win32.c,v 1.1 2004/07/31 19:18:54 chrfranke Exp $" HOSTNAME_WIN32_H_CVSID;
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <string.h>
-
-#ifndef MAX_HOSTNAME_LEN
-
-// From IPHlpApi.dll:
-
-#define MAX_HOSTNAME_LEN    132
-#define MAX_DOMAIN_NAME_LEN 132
-#define MAX_SCOPE_ID_LEN    260
-
-typedef struct {
-  char String[4 * 4];
-} IP_ADDRESS_STRING, 
-*PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
-
-typedef struct _IP_ADDR_STRING {
-  struct _IP_ADDR_STRING* Next;
-  IP_ADDRESS_STRING IpAddress;
-  IP_MASK_STRING IpMask;
-  DWORD Context;
-} IP_ADDR_STRING, 
-*PIP_ADDR_STRING;
-
-typedef struct {
-  char HostName[MAX_HOSTNAME_LEN];
-  char DomainName[MAX_DOMAIN_NAME_LEN];
-  PIP_ADDR_STRING CurrentDnsServer;
-  IP_ADDR_STRING DnsServerList;
-  UINT NodeType;
-  char ScopeId[MAX_SCOPE_ID_LEN];
-  UINT EnableRouting;
-  UINT EnableProxy;
-  UINT EnableDns;
-} FIXED_INFO,
-*PFIXED_INFO;
-
-DWORD WINAPI GetNetworkParams(PFIXED_INFO info, PULONG size);
-
-#endif // MAX_HOSTNAME_LEN
-
-
-// Call GetComputerNameEx() if available (Win2000/XP)
-
-static BOOL CallGetComputerNameExA(int type, LPSTR name, LPDWORD size)
-{
-	HANDLE hdll;
-	BOOL (WINAPI * GetComputerNameExA_p)(int/*enum COMPUTER_NAME_FORMAT*/, LPSTR, LPDWORD);
-	BOOL ret;
-	if (!(hdll = LoadLibraryA("KERNEL32.DLL")))
-		return FALSE;
-	if (!((FARPROC)GetComputerNameExA_p = GetProcAddress(hdll, "GetComputerNameExA")))
-		ret = FALSE;
-	else
-		ret = GetComputerNameExA_p(type, name, size);
-	FreeLibrary(hdll);
-	return ret;
-}
-
-
-// Call GetNetworkParams() if available (Win98/ME/2000/XP)
-
-static DWORD CallGetNetworkParams(PFIXED_INFO info, PULONG size)
-{
-	HANDLE hdll;
-	DWORD (WINAPI * GetNetworkParams_p)(PFIXED_INFO info, PULONG size);
-	DWORD ret;
-	if (!(hdll = LoadLibraryA("IPHlpApi.dll")))
-		return ERROR_NOT_SUPPORTED;
-	if (!((FARPROC)GetNetworkParams_p = GetProcAddress(hdll, "GetNetworkParams")))
-		ret = ERROR_NOT_SUPPORTED;
-	else
-		ret = GetNetworkParams_p(info, size);
-	FreeLibrary(hdll);
-	return ret;
-}
-
-
-// Get host/domainname from registry (Win98/ME/NT4/2000/XP)
-
-static DWORD GetNamesFromRegistry(BOOL domain, char * name, int len)
-{
-	HKEY hk; DWORD size, type;
-	if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-	    (GetVersion() & 0x80000000
-	     ? "System\\CurrentControlSet\\Services\\VxD\\MSTCP" //Win9x/ME
-	     : "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
-	    0, KEY_READ, &hk) != ERROR_SUCCESS)
-		return 0;
-	size = len-1;
-	if (!(RegQueryValueExA(hk, (!domain?"HostName":"Domain"), 0, &type, name, &size) == ERROR_SUCCESS && type == REG_SZ))
-		size = 0;
-	if (size == 0 && domain) {
-		size = len-1;
-		if (!(RegQueryValueExA(hk, "DhcpDomain", 0, &type, name, &size) == ERROR_SUCCESS && type == REG_SZ))
-			size = 0;
-	}
-	RegCloseKey(hk);
-	return size;
-}
-
-
-static int gethostdomname(int domain, char * name, int len)
-{
-	DWORD size; FIXED_INFO info;
-
-	// try KERNEL32.dll::GetComputerNameEx()
-	size = len - 1;
-	if (CallGetComputerNameExA((!domain ? 1:2/*ComputerNameDnsHost:Domain*/), name, &size))
-		return 0;
-
-	// try IPHlpApi.dll::GetNetworkParams() 
-	size = sizeof(info);
-	if (CallGetNetworkParams(&info, &size) == ERROR_SUCCESS) {
-		strncpy(name, (!domain?info.HostName:info.DomainName), len-1); name[len-1] = 0;
-		return 0;
-	}
-
-	// try registry
-	if (GetNamesFromRegistry(domain, name, len))
-		return 0;
-
-	if (domain)
-		return -1;
-
-	// last resort: get NETBIOS name
-	size = len - 1;
-	if (GetComputerNameA(name, &size))
-		return 0;
-
-	return -1;
-}
-
-
-int gethostname(char * name, int len)
-{
-	return gethostdomname(0, name, len);
-}
-
-
-int getdomainname(char * name, int len)
-{
-	return gethostdomname(1, name, len);
-}
-
-
-#ifdef TEST
-
-#include <stdio.h>
-
-main()
-{
-	char name[256];
-	if (gethostname(name, sizeof(name)))
-		strcpy(name, "Error");
-	printf("hostname=\"%s\"\n", name);
-	if (getdomainname(name, sizeof(name)))
-		strcpy(name, "Error");
-	printf("domainname=\"%s\"\n", name);
-	return 0;
-}
-
-#endif
diff --git a/sm5/os_win32/hostname_win32.cpp b/sm5/os_win32/hostname_win32.cpp
deleted file mode 100644
index 439017d441e792031f70760a818c05edca87f2a6..0000000000000000000000000000000000000000
--- a/sm5/os_win32/hostname_win32.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * os_win32/hostname_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "hostname_win32.h"
-
-const char * hostname_win32_c_cvsid = "$Id: hostname_win32.cpp,v 1.1 2004/07/31 19:18:54 chrfranke Exp $" HOSTNAME_WIN32_H_CVSID;
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <string.h>
-
-#ifndef MAX_HOSTNAME_LEN
-
-// From IPHlpApi.dll:
-
-#define MAX_HOSTNAME_LEN    132
-#define MAX_DOMAIN_NAME_LEN 132
-#define MAX_SCOPE_ID_LEN    260
-
-typedef struct {
-  char String[4 * 4];
-} IP_ADDRESS_STRING, 
-*PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
-
-typedef struct _IP_ADDR_STRING {
-  struct _IP_ADDR_STRING* Next;
-  IP_ADDRESS_STRING IpAddress;
-  IP_MASK_STRING IpMask;
-  DWORD Context;
-} IP_ADDR_STRING, 
-*PIP_ADDR_STRING;
-
-typedef struct {
-  char HostName[MAX_HOSTNAME_LEN];
-  char DomainName[MAX_DOMAIN_NAME_LEN];
-  PIP_ADDR_STRING CurrentDnsServer;
-  IP_ADDR_STRING DnsServerList;
-  UINT NodeType;
-  char ScopeId[MAX_SCOPE_ID_LEN];
-  UINT EnableRouting;
-  UINT EnableProxy;
-  UINT EnableDns;
-} FIXED_INFO,
-*PFIXED_INFO;
-
-DWORD WINAPI GetNetworkParams(PFIXED_INFO info, PULONG size);
-
-#endif // MAX_HOSTNAME_LEN
-
-
-// Call GetComputerNameEx() if available (Win2000/XP)
-
-static BOOL CallGetComputerNameExA(int type, LPSTR name, LPDWORD size)
-{
-	HANDLE hdll;
-	BOOL (WINAPI * GetComputerNameExA_p)(int/*enum COMPUTER_NAME_FORMAT*/, LPSTR, LPDWORD);
-	BOOL ret;
-	if (!(hdll = LoadLibraryA("KERNEL32.DLL")))
-		return FALSE;
-	if (!((FARPROC)GetComputerNameExA_p = GetProcAddress(hdll, "GetComputerNameExA")))
-		ret = FALSE;
-	else
-		ret = GetComputerNameExA_p(type, name, size);
-	FreeLibrary(hdll);
-	return ret;
-}
-
-
-// Call GetNetworkParams() if available (Win98/ME/2000/XP)
-
-static DWORD CallGetNetworkParams(PFIXED_INFO info, PULONG size)
-{
-	HANDLE hdll;
-	DWORD (WINAPI * GetNetworkParams_p)(PFIXED_INFO info, PULONG size);
-	DWORD ret;
-	if (!(hdll = LoadLibraryA("IPHlpApi.dll")))
-		return ERROR_NOT_SUPPORTED;
-	if (!((FARPROC)GetNetworkParams_p = GetProcAddress(hdll, "GetNetworkParams")))
-		ret = ERROR_NOT_SUPPORTED;
-	else
-		ret = GetNetworkParams_p(info, size);
-	FreeLibrary(hdll);
-	return ret;
-}
-
-
-// Get host/domainname from registry (Win98/ME/NT4/2000/XP)
-
-static DWORD GetNamesFromRegistry(BOOL domain, char * name, int len)
-{
-	HKEY hk; DWORD size, type;
-	if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-	    (GetVersion() & 0x80000000
-	     ? "System\\CurrentControlSet\\Services\\VxD\\MSTCP" //Win9x/ME
-	     : "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
-	    0, KEY_READ, &hk) != ERROR_SUCCESS)
-		return 0;
-	size = len-1;
-	if (!(RegQueryValueExA(hk, (!domain?"HostName":"Domain"), 0, &type, name, &size) == ERROR_SUCCESS && type == REG_SZ))
-		size = 0;
-	if (size == 0 && domain) {
-		size = len-1;
-		if (!(RegQueryValueExA(hk, "DhcpDomain", 0, &type, name, &size) == ERROR_SUCCESS && type == REG_SZ))
-			size = 0;
-	}
-	RegCloseKey(hk);
-	return size;
-}
-
-
-static int gethostdomname(int domain, char * name, int len)
-{
-	DWORD size; FIXED_INFO info;
-
-	// try KERNEL32.dll::GetComputerNameEx()
-	size = len - 1;
-	if (CallGetComputerNameExA((!domain ? 1:2/*ComputerNameDnsHost:Domain*/), name, &size))
-		return 0;
-
-	// try IPHlpApi.dll::GetNetworkParams() 
-	size = sizeof(info);
-	if (CallGetNetworkParams(&info, &size) == ERROR_SUCCESS) {
-		strncpy(name, (!domain?info.HostName:info.DomainName), len-1); name[len-1] = 0;
-		return 0;
-	}
-
-	// try registry
-	if (GetNamesFromRegistry(domain, name, len))
-		return 0;
-
-	if (domain)
-		return -1;
-
-	// last resort: get NETBIOS name
-	size = len - 1;
-	if (GetComputerNameA(name, &size))
-		return 0;
-
-	return -1;
-}
-
-
-int gethostname(char * name, int len)
-{
-	return gethostdomname(0, name, len);
-}
-
-
-int getdomainname(char * name, int len)
-{
-	return gethostdomname(1, name, len);
-}
-
-
-#ifdef TEST
-
-#include <stdio.h>
-
-main()
-{
-	char name[256];
-	if (gethostname(name, sizeof(name)))
-		strcpy(name, "Error");
-	printf("hostname=\"%s\"\n", name);
-	if (getdomainname(name, sizeof(name)))
-		strcpy(name, "Error");
-	printf("domainname=\"%s\"\n", name);
-	return 0;
-}
-
-#endif
diff --git a/sm5/os_win32/hostname_win32.h b/sm5/os_win32/hostname_win32.h
deleted file mode 100644
index 3198cb1e9aa0236ad7c05ff75648eb6e44e9d883..0000000000000000000000000000000000000000
--- a/sm5/os_win32/hostname_win32.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * os_win32/hostname_win32.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef HOSTNAME_WIN32_H
-#define HOSTNAME_WIN32_H
-
-#define HOSTNAME_WIN32_H_CVSID "$Id: hostname_win32.h,v 1.1 2004/07/31 19:18:54 chrfranke Exp $\n"
-
-int gethostname(char * name, int len);
-int getdomainname(char * name, int len);
-
-#endif // HOSTNAME_WIN32_H
diff --git a/sm5/os_win32/int64_vc6.c b/sm5/os_win32/int64_vc6.c
deleted file mode 100644
index a31078a0f22dd7f511f8a8182f2c7d04b9a3ec40..0000000000000000000000000000000000000000
--- a/sm5/os_win32/int64_vc6.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * os_win32/int64_vc6.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "int64.h"
-
-#include <stdio.h>
-#include <errno.h>
-
-const char *int64_vc6_c_cvsid = "$Id: int64_vc6.c,v 1.3 2004/07/29 21:05:26 chrfranke Exp $" \
-INT64_H_CVSID;
-
-
-// Missing (why?-) "unsigned __int64 -> double" conversion
-
-double uint64_to_double(unsigned __int64 ull)
-{
-	if ((__int64)ull >= 0)
-		return (double)(__int64)ull;
-	else
-		return (double)(__int64)(ull - 9223372036854775808I64)
-		                             + 9223372036854775808.0;
-		//    ~((~(uint64_t)0) >> 1) == 0x8000000000000000I64
-}
-
diff --git a/sm5/os_win32/smartctl_vc6.dsp b/sm5/os_win32/smartctl_vc6.dsp
deleted file mode 100644
index 310497f3c446f40b832df03779dbd34d731ad5de..0000000000000000000000000000000000000000
--- a/sm5/os_win32/smartctl_vc6.dsp
+++ /dev/null
@@ -1,240 +0,0 @@
-# Microsoft Developer Studio Project File - Name="smartctl_vc6" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** NICHT BEARBEITEN **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=smartctl_vc6 - Win32 Debug
-!MESSAGE Dies ist kein g�ltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
-!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und f�hren Sie den Befehl
-!MESSAGE 
-!MESSAGE NMAKE /f "smartctl_vc6.mak".
-!MESSAGE 
-!MESSAGE Sie k�nnen beim Ausf�hren von NMAKE eine Konfiguration angeben
-!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
-!MESSAGE 
-!MESSAGE NMAKE /f "smartctl_vc6.mak" CFG="smartctl_vc6 - Win32 Debug"
-!MESSAGE 
-!MESSAGE F�r die Konfiguration stehen zur Auswahl:
-!MESSAGE 
-!MESSAGE "smartctl_vc6 - Win32 Release" (basierend auf  "Win32 (x86) Console Application")
-!MESSAGE "smartctl_vc6 - Win32 Debug" (basierend auf  "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "smartctl_vc6 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "smartctl.r"
-# PROP Intermediate_Dir "smartctl.r"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O1 /I "." /I ".." /I "..\posix" /D "NDEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x407 /d "NDEBUG"
-# ADD RSC /l 0x407 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"smartctl.exe"
-
-!ELSEIF  "$(CFG)" == "smartctl_vc6 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "smartctl.d"
-# PROP Intermediate_Dir "smartctl.d"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".." /I "..\posix" /D "_DEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x407 /d "_DEBUG"
-# ADD RSC /l 0x407 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "smartctl_vc6 - Win32 Release"
-# Name "smartctl_vc6 - Win32 Debug"
-# Begin Group "posix"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\posix\getopt.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\getopt.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\getopt1.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regcomp.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex.c
-# ADD CPP /w /W0
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex_internal.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex_internal.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regexec.c
-# PROP Exclude_From_Build 1
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\atacmdnames.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\atacmdnames.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\atacmds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\atacmds.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\ataprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\ataprint.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\config_vc6.h
-
-!IF  "$(CFG)" == "smartctl_vc6 - Win32 Release"
-
-# Begin Custom Build - Copy $(InputPath) config.h
-InputPath=.\config_vc6.h
-
-"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	copy $(InputPath) config.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "smartctl_vc6 - Win32 Debug"
-
-# Begin Custom Build - Copy $(InputPath) config.h
-InputPath=.\config_vc6.h
-
-"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	copy $(InputPath) config.h
-
-# End Custom Build
-
-!ENDIF 
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\extern.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\int64.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\int64_vc6.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\knowndrives.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\knowndrives.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\os_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsicmds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsicmds.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsiprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsiprint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\smartctl.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\smartctl.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\syslog.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\utility.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\utility.h
-# End Source File
-# End Target
-# End Project
diff --git a/sm5/os_win32/smartd_vc6.dsp b/sm5/os_win32/smartd_vc6.dsp
deleted file mode 100644
index 64f13524101d0df6a892a2abe4350ce6d2ccb09f..0000000000000000000000000000000000000000
--- a/sm5/os_win32/smartd_vc6.dsp
+++ /dev/null
@@ -1,264 +0,0 @@
-# Microsoft Developer Studio Project File - Name="smartd_vc6" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** NICHT BEARBEITEN **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=smartd_vc6 - Win32 Debug
-!MESSAGE Dies ist kein g�ltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
-!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und f�hren Sie den Befehl
-!MESSAGE 
-!MESSAGE NMAKE /f "smartd_vc6.mak".
-!MESSAGE 
-!MESSAGE Sie k�nnen beim Ausf�hren von NMAKE eine Konfiguration angeben
-!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
-!MESSAGE 
-!MESSAGE NMAKE /f "smartd_vc6.mak" CFG="smartd_vc6 - Win32 Debug"
-!MESSAGE 
-!MESSAGE F�r die Konfiguration stehen zur Auswahl:
-!MESSAGE 
-!MESSAGE "smartd_vc6 - Win32 Release" (basierend auf  "Win32 (x86) Console Application")
-!MESSAGE "smartd_vc6 - Win32 Debug" (basierend auf  "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "smartd_vc6 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "smartd.r"
-# PROP Intermediate_Dir "smartd.r"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O1 /I "." /I ".." /I "..\posix" /D "NDEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x407 /d "NDEBUG"
-# ADD RSC /l 0x407 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"smartd.exe"
-
-!ELSEIF  "$(CFG)" == "smartd_vc6 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "smartd.d"
-# PROP Intermediate_Dir "smartd.d"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".." /I "..\posix" /D "_DEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x407 /d "_DEBUG"
-# ADD RSC /l 0x407 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "smartd_vc6 - Win32 Release"
-# Name "smartd_vc6 - Win32 Debug"
-# Begin Group "posix"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\posix\getopt.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\getopt.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\getopt1.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regcomp.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex.c
-# ADD CPP /w /W0
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex_internal.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regex_internal.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\posix\regexec.c
-# PROP Exclude_From_Build 1
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\atacmdnames.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\atacmdnames.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\atacmds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\atacmds.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\ataprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\ataprint.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\config_vc6.h
-
-!IF  "$(CFG)" == "smartd_vc6 - Win32 Release"
-
-# Begin Custom Build - Copy $(InputPath) config.h
-InputPath=.\config_vc6.h
-
-"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	copy $(InputPath) config.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "smartd_vc6 - Win32 Debug"
-
-# Begin Custom Build - Copy $(InputPath) config.h
-InputPath=.\config_vc6.h
-
-"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	copy $(InputPath) config.h
-
-# End Custom Build
-
-!ENDIF 
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\daemon_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\daemon_win32.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\extern.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\hostname_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hostname_win32.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\int64.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\int64_vc6.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\knowndrives.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\knowndrives.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\os_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsicmds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsicmds.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsiprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\scsiprint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\smartctl.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\smartd.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\smartd.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\syslog.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\syslog_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\utility.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\utility.h
-# End Source File
-# End Target
-# End Project
diff --git a/sm5/os_win32/smartmontools_vc6.dsw b/sm5/os_win32/smartmontools_vc6.dsw
deleted file mode 100644
index 76e451e63a7815998f482c1bbfecf3f449332969..0000000000000000000000000000000000000000
--- a/sm5/os_win32/smartmontools_vc6.dsw
+++ /dev/null
@@ -1,53 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GEL�SCHT WERDEN!
-
-###############################################################################
-
-Project: "smartctl_vc6"=.\smartctl_vc6.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "smartd_vc6"=.\smartd_vc6.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "syslogevt_vc6"=.\syslogevt_vc6.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/sm5/os_win32/syslog.h b/sm5/os_win32/syslog.h
deleted file mode 100644
index 4c403cefe4385f4d1427f51a54ce61b7a4daf042..0000000000000000000000000000000000000000
--- a/sm5/os_win32/syslog.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * os_win32/syslog.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef SYSLOG_H
-#define SYSLOG_H
-
-#define SYSLOG_H_CVSID "$Id: syslog.h,v 1.2 2004/03/24 21:08:44 chrfranke Exp $\n"
-
-#include <stdarg.h>
-
-/* EVENTLOG_ERROR_TYPE: */
-#define LOG_EMERG       0
-#define LOG_ALERT       1
-#define LOG_CRIT        2
-#define LOG_ERR         3
-/* EVENTLOG_WARNING_TYPE: */
-#define LOG_WARNING     4
-/* EVENTLOG_INFORMATION_TYPE: */
-#define LOG_NOTICE      5
-#define LOG_INFO        6
-#define LOG_DEBUG       7
-
-/* event log: */
-#define LOG_DAEMON      ( 3<<3)
-/* ident.log: */
-#define LOG_LOCAL0      (16<<3)
-/* ident1-7.log: */
-#define LOG_LOCAL1      (17<<3)
-#define LOG_LOCAL2      (18<<3)
-#define LOG_LOCAL3      (19<<3)
-#define LOG_LOCAL4      (20<<3)
-#define LOG_LOCAL5      (21<<3)
-#define LOG_LOCAL6      (22<<3)
-#define LOG_LOCAL7      (23<<3)
-
-#define LOG_FACMASK     0x03f8
-#define LOG_FAC(f)      (((f) & LOG_FACMASK) >> 3)
- 
-#define LOG_PID         0x01
-
-void openlog(const char * ident, int option, int facility);
-
-void closelog(void);
-
-void vsyslog(int priority, const char * message, va_list args);
-
-#endif /* SYSLOG_H */
diff --git a/sm5/os_win32/syslog_win32.c b/sm5/os_win32/syslog_win32.c
deleted file mode 100644
index 832854f8a9df1ffa14e9cce040a605f1232caaed..0000000000000000000000000000000000000000
--- a/sm5/os_win32/syslog_win32.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * os_win32/syslog_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-// Win32 Emulation of syslog() for smartd
-// Writes to windows event log on NT4/2000/XP
-// (Register syslogevt.exe as event message file)
-// Writes to file "<ident>.log" on 9x/ME.
-// If facility is set to LOG_LOCAL[0-7], log is written to
-// file "<ident>.log", stdout, stderr, "<ident>[1-5].log".
-
-
-#include "syslog.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-#include <process.h> // getpid()
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> // RegisterEventSourceA(), ReportEventA(), ...
-
-const char *syslog_win32_c_cvsid = "$Id: syslog_win32.c,v 1.4 2004/04/07 11:17:08 chrfranke Exp $"
-SYSLOG_H_CVSID;
-
-#ifdef _MSC_VER
-// MSVC
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#endif
-
-#define ARGUSED(x) ((void)(x))
-
-
-#ifndef _MT
-//MT runtime not necessary, because thread uses no unsafe lib functions
-//#error Program must be linked with multithreaded runtime library
-#endif
-
-
-#ifdef TESTEVT
-// Redirect event log to stdout for testing
-
-static BOOL Test_ReportEventA(HANDLE h, WORD type, WORD cat, DWORD id, PSID usid,
-						WORD nstrings, WORD datasize, LPCTSTR * strings, LPVOID data)
-{
-	int i;
-	printf("%u %lu:%s", type, id, nstrings != 1?"\n":"");
-	for (i = 0; i < nstrings; i++)
-		printf(" \"%s\"\n", strings[i]);
-	fflush(stdout);
-	return TRUE;
-}
-
-HANDLE Test_RegisterEventSourceA(LPCTSTR server, LPCTSTR source)
-{
-	return (HANDLE)42;
-}
-
-#define ReportEventA Test_ReportEventA
-#define RegisterEventSourceA Test_RegisterEventSourceA
-#endif // TESTEVT
-
-
-// Event message ids,
-// should be identical to MSG_SYSLOG* in "syslogevt.h"
-// (generated by "mc" from "syslogevt.mc")
-#define MSG_SYSLOG                       0x00000000L
-#define MSG_SYSLOG_01                    0x00000001L
-// ...
-#define MSG_SYSLOG_10                    0x0000000AL
-
-static char sl_ident[100];
-static char sl_logpath[sizeof(sl_ident) + sizeof("0.log")-1];
-static FILE * sl_logfile;
-static char sl_pidstr[16];
-static HANDLE sl_hevtsrc;
-
-
-// Ring buffer for event log output via thread
-#define MAXLINES 10
-#define LINELEN 200
-
-static HANDLE evt_hthread;
-static char evt_lines[MAXLINES][LINELEN+1];
-static int evt_priorities[MAXLINES];
-static volatile int evt_timeout;
-static int evt_index_in, evt_index_out;
-static HANDLE evt_wait_in, evt_wait_out;
-
-
-// Map syslog priority to event type
-
-static WORD pri2evtype(int priority)
-{
-	switch (priority) {
-		default:
-		case LOG_EMERG: case LOG_ALERT:
-		case LOG_CRIT:  case LOG_ERR:
-			return EVENTLOG_ERROR_TYPE;
-		case LOG_WARNING:
-			return EVENTLOG_WARNING_TYPE;
-		case LOG_NOTICE: case LOG_INFO:
-		case LOG_DEBUG:
-			return EVENTLOG_INFORMATION_TYPE;
-	}
-}
-
-
-// Map syslog priority to string
-
-static const char * pri2text(int priority)
-{
-	switch (priority) {
-		case LOG_EMERG:   return "EMERG";
-		case LOG_ALERT:   return "ALERT";
-		case LOG_CRIT:    return "CRIT";
-		default:
-		case LOG_ERR:     return "ERROR";
-		case LOG_WARNING: return "Warn";
-		case LOG_NOTICE:  return "Note";
-		case LOG_INFO:    return "Info";
-		case LOG_DEBUG:   return "Debug";
-	}
-}
-
-
-// Output cnt events from ring buffer
-
-static void report_events(int cnt)
-{
-	const char * msgs[3+MAXLINES];
-
-	int i, pri;
-	if (cnt <= 0)
-		return;
-	if (cnt > MAXLINES)
-		cnt = MAXLINES;
-
-	pri = evt_priorities[evt_index_out];
-
-	msgs[0] = sl_ident;
-	msgs[1] = sl_pidstr;
-	msgs[2] = pri2text(pri);
-	for (i = 0; i < cnt; i++) {
-		//assert(evt_priorities[evt_index_out] == pri);
-		msgs[3+i] = evt_lines[evt_index_out];
-		if (++evt_index_out >= MAXLINES)
-			evt_index_out = 0;
-	}
-	ReportEventA(sl_hevtsrc,
-		pri2evtype(pri), // type
-		0, MSG_SYSLOG+cnt,    // category, message id
-		NULL,                 // no security id
-		(WORD)(3+cnt), 0,     // 3+cnt strings, ...
-		msgs, NULL);          // ...          , no data
-}
-
-
-// Thread to combine several syslog lines into one event log entry
-
-static ULONG WINAPI event_logger_thread(LPVOID arg)
-{
-	int cnt;
-	ARGUSED(arg);
-
-	cnt = 0;
-	for (;;) {
-		// Wait for first line ...
-		int prior, i, rest;
-		if (cnt == 0) {
-			if (WaitForSingleObject(evt_wait_out, (evt_timeout? INFINITE : 0)) != WAIT_OBJECT_0)
-				break;
-			cnt = 1;
-		}
-
-		// ... wait some time for more lines with same prior
-		i = evt_index_out;
-		prior = evt_priorities[i];
-		rest = 0;
-		while (cnt < MAXLINES) {
-			long timeout =
-				evt_timeout * ((1000L * (MAXLINES-cnt+1))/MAXLINES);
-			if (WaitForSingleObject(evt_wait_out, timeout) != WAIT_OBJECT_0)
-				break;
-			if (++i >= MAXLINES)
-				i = 0;
-			if (evt_priorities[i] != prior) {
-				rest = 1;
-				break;
-			}
-			cnt++;
-		}
-
-		// Output all in one event log entry
-		report_events(cnt);
-
-		// Signal space
-		if (!ReleaseSemaphore(evt_wait_in, cnt, NULL))
-			break;
-		cnt = rest;
-	}
-	return 0;
-}
-
-
-static void on_exit_event_logger(void)
-{
-	// Output lines immediate if exiting
-	evt_timeout = 0; 
-	// Wait for thread to finish
-	WaitForSingleObject(evt_hthread, 1000L);
-	CloseHandle(evt_hthread);
-#if 0
-	if (sl_hevtsrc) {
-		DeregisterEventSource(sl_hevtsrc); sl_hevtsrc = 0;
-	}
-#else
-	// Leave event message source open to prevent losing messages during shutdown
-#endif
-}
-
-
-static int start_event_logger()
-{
-	DWORD tid;
-	evt_timeout = 1;
-	if (   !(evt_wait_in  = CreateSemaphore(NULL,  MAXLINES, MAXLINES, NULL))
-		|| !(evt_wait_out = CreateSemaphore(NULL,         0, MAXLINES, NULL))) {
-		fprintf(stderr,"CreateSemaphore failed, Error=%ld\n", GetLastError());
-		return -1;
-	}
-	if (!(evt_hthread = CreateThread(NULL, 0, event_logger_thread, NULL, 0, &tid))) {
-		fprintf(stderr,"CreateThread failed, Error=%ld\n", GetLastError());
-		return -1;
-	}
-	atexit(on_exit_event_logger);
-	return 0;
-}
-
-
-// Write lines to event log ring buffer
-
-static void write_event_log(int priority, const char * lines)
-{
-	int cnt = 0;
-	int i;
-	for (i = 0; lines[i]; i++) {
-		int len = 0;
-		while (lines[i+len] && lines[i+len] != '\n')
-			len++;
-			;
-		if (len > 0) {
-			// Wait for space
-			if (WaitForSingleObject(evt_wait_in, INFINITE) != WAIT_OBJECT_0)
-				return;
-			// Copy line
-			evt_priorities[evt_index_in] = priority;
-			memcpy(evt_lines[evt_index_in], lines+i, (len < LINELEN ? len : LINELEN));
-			if (len < LINELEN)
-				evt_lines[evt_index_in][len] = 0;
-			if (++evt_index_in >= MAXLINES)
-				evt_index_in = 0;
-			// Signal avail if ring buffer full
-			if (++cnt >= MAXLINES) {
-				ReleaseSemaphore(evt_wait_out, cnt, NULL);
-				cnt = 0;
-			}
-			i += len;
-		}
-		if (!lines[i])
-			break;
-	}
-
-	// Signal avail
-	if (cnt > 0)
-		ReleaseSemaphore(evt_wait_out, cnt, NULL);
-	Sleep(1);
-}
-
-
-// Write lines to logfile
-
-static void write_logfile(FILE * f, int priority, const char * lines)
-{
-	time_t now; char stamp[sizeof("2004-04-04 10:00:00")+13];
-	int i;
-
-	now = time((time_t*)0);
-	if (!strftime(stamp, sizeof(stamp)-1, "%Y-%m-%d %H:%M:%S", localtime(&now)))
-		strcpy(stamp,"?");
-
-	for (i = 0; lines[i]; i++) {
-		int len = 0;
-		while (lines[i+len] && lines[i+len] != '\n')
-			len++;
-		if (len > 0) {
-			fprintf(f, "%s %s[%s]: %-5s: ",
-				stamp, sl_ident, sl_pidstr, pri2text(priority));
-			fwrite(lines+i, len, 1, f);
-			fputc('\n', f);
-			i += len;
-		}
-		if (!lines[i])
-			break;
-	}
-}
-
-
-void openlog(const char *ident, int logopt, int facility)
-{
-	int pid;
-	if (sl_logpath[0] || sl_logfile || sl_hevtsrc)
-		return; // Already open
-
-	strncpy(sl_ident, ident, sizeof(sl_ident)-1);
-	// logopt==LOG_PID assumed
-	ARGUSED(logopt);
-	pid = getpid();
-	if (snprintf(sl_pidstr, sizeof(sl_pidstr)-1, (pid >= 0 ? "%d" : "0x%X"), pid) < 0)
-		strcpy(sl_pidstr,"?");
-
-	if (facility == LOG_LOCAL0) // "ident.log"
-		strcat(strcpy(sl_logpath, sl_ident), ".log");
-	else if (facility == LOG_LOCAL1) // stdout
-		sl_logfile = stdout;
-	else if (facility == LOG_LOCAL2) // stderr
-		sl_logfile = stderr;
-	else if (LOG_LOCAL2 < facility && facility <= LOG_LOCAL7) { // "ident[1-5].log"
-		snprintf(sl_logpath, sizeof(sl_logpath)-1, "%s%d.log",
-			sl_ident, LOG_FAC(facility)-LOG_FAC(LOG_LOCAL2));
-	}
-	else // Assume LOG_DAEMON, use event log if possible, else "ident.log"
-	if (!(sl_hevtsrc = RegisterEventSourceA(NULL/*localhost*/, sl_ident))) {
-		// Cannot open => Use logfile
-		long err = GetLastError();
-		strcat(strcpy(sl_logpath, sl_ident), ".log");
-		if (GetVersion() & 0x80000000)
-			fprintf(stderr, "%s: No event log on Win9x/ME, writing to %s\n",
-				sl_ident, sl_logpath);
-		else
-			fprintf(stderr, "%s: Cannot register event source (Error=%ld), writing to %s\n",
-				sl_ident, err, sl_logpath);
-	}
-	else {
-		// Start event log thread
-		start_event_logger();
-	}
-	//assert(sl_logpath[0] || sl_logfile || sl_hevtsrc);
-
-}
-
-
-void closelog()
-{
-}
-
-
-void vsyslog(int priority, const char * message, va_list args)
-{
-	char buffer[1000];
-
-	// Translation of %m to error text not supported yet
-	if (strstr(message, "%m"))
-		message = "Internal error: \"%%m\" in log message";
-
-	// Format message
-	if (vsnprintf(buffer, sizeof(buffer)-1, message, args) < 0)
-		strcpy(buffer, "Internal Error: buffer overflow");
-
-	if (sl_hevtsrc) {
-		// Write to event log
-		write_event_log(priority, buffer);
-	}
-	else if (sl_logfile) {
-		// Write to stdout/err
-		write_logfile(sl_logfile, priority, buffer);
-		fflush(sl_logfile);
-	}
-	else if (sl_logpath[0]) {
-		// Append to logfile
-		FILE * f;
-		if (!(f = fopen(sl_logpath, "a")))
-			return;
-		write_logfile(f, priority, buffer);
-		fclose(f);
-	}
-}
-
-
-#ifdef TEST
-// Test program
-
-void syslog(int priority, const char *message, ...)
-{
-	va_list args;
-	va_start(args, message);
-	vsyslog(priority, message, args);
-	va_end(args);
-}
-
-int main(int argc, char* argv[])
-{
-	int i;
-	openlog(argc < 2 ? "test" : argv[1], LOG_PID, (argc < 3 ? LOG_DAEMON : LOG_LOCAL1));
-	syslog(LOG_INFO,    "Info\n");
-	syslog(LOG_WARNING, "Warning %d\n\n", 42);
-	syslog(LOG_ERR,     "Error %s", "Fatal");
-	for (i = 0; i < 100; i++) {
-		char buf[LINELEN];
-		if (i % 13 == 0)
-			Sleep(1000L);
-		sprintf(buf, "Log Line %d\n", i);
-		syslog(i % 17 ? LOG_INFO : LOG_ERR, buf);
-	}
-	closelog();
-	return 0;
-}
-
-#endif
diff --git a/sm5/os_win32/syslog_win32.cpp b/sm5/os_win32/syslog_win32.cpp
deleted file mode 100644
index 2bb4da9ae83991fb7edb91b850e167cbad4a8f45..0000000000000000000000000000000000000000
--- a/sm5/os_win32/syslog_win32.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * os_win32/syslog_win32.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-// Win32 Emulation of syslog() for smartd
-// Writes to windows event log on NT4/2000/XP
-// (Register syslogevt.exe as event message file)
-// Writes to file "<ident>.log" on 9x/ME.
-// If facility is set to LOG_LOCAL[0-7], log is written to
-// file "<ident>.log", stdout, stderr, "<ident>[1-5].log".
-
-
-#include "syslog.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-#include <process.h> // getpid()
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> // RegisterEventSourceA(), ReportEventA(), ...
-
-const char *syslog_win32_c_cvsid = "$Id: syslog_win32.cpp,v 1.4 2004/04/07 11:17:08 chrfranke Exp $"
-SYSLOG_H_CVSID;
-
-#ifdef _MSC_VER
-// MSVC
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#endif
-
-#define ARGUSED(x) ((void)(x))
-
-
-#ifndef _MT
-//MT runtime not necessary, because thread uses no unsafe lib functions
-//#error Program must be linked with multithreaded runtime library
-#endif
-
-
-#ifdef TESTEVT
-// Redirect event log to stdout for testing
-
-static BOOL Test_ReportEventA(HANDLE h, WORD type, WORD cat, DWORD id, PSID usid,
-						WORD nstrings, WORD datasize, LPCTSTR * strings, LPVOID data)
-{
-	int i;
-	printf("%u %lu:%s", type, id, nstrings != 1?"\n":"");
-	for (i = 0; i < nstrings; i++)
-		printf(" \"%s\"\n", strings[i]);
-	fflush(stdout);
-	return TRUE;
-}
-
-HANDLE Test_RegisterEventSourceA(LPCTSTR server, LPCTSTR source)
-{
-	return (HANDLE)42;
-}
-
-#define ReportEventA Test_ReportEventA
-#define RegisterEventSourceA Test_RegisterEventSourceA
-#endif // TESTEVT
-
-
-// Event message ids,
-// should be identical to MSG_SYSLOG* in "syslogevt.h"
-// (generated by "mc" from "syslogevt.mc")
-#define MSG_SYSLOG                       0x00000000L
-#define MSG_SYSLOG_01                    0x00000001L
-// ...
-#define MSG_SYSLOG_10                    0x0000000AL
-
-static char sl_ident[100];
-static char sl_logpath[sizeof(sl_ident) + sizeof("0.log")-1];
-static FILE * sl_logfile;
-static char sl_pidstr[16];
-static HANDLE sl_hevtsrc;
-
-
-// Ring buffer for event log output via thread
-#define MAXLINES 10
-#define LINELEN 200
-
-static HANDLE evt_hthread;
-static char evt_lines[MAXLINES][LINELEN+1];
-static int evt_priorities[MAXLINES];
-static volatile int evt_timeout;
-static int evt_index_in, evt_index_out;
-static HANDLE evt_wait_in, evt_wait_out;
-
-
-// Map syslog priority to event type
-
-static WORD pri2evtype(int priority)
-{
-	switch (priority) {
-		default:
-		case LOG_EMERG: case LOG_ALERT:
-		case LOG_CRIT:  case LOG_ERR:
-			return EVENTLOG_ERROR_TYPE;
-		case LOG_WARNING:
-			return EVENTLOG_WARNING_TYPE;
-		case LOG_NOTICE: case LOG_INFO:
-		case LOG_DEBUG:
-			return EVENTLOG_INFORMATION_TYPE;
-	}
-}
-
-
-// Map syslog priority to string
-
-static const char * pri2text(int priority)
-{
-	switch (priority) {
-		case LOG_EMERG:   return "EMERG";
-		case LOG_ALERT:   return "ALERT";
-		case LOG_CRIT:    return "CRIT";
-		default:
-		case LOG_ERR:     return "ERROR";
-		case LOG_WARNING: return "Warn";
-		case LOG_NOTICE:  return "Note";
-		case LOG_INFO:    return "Info";
-		case LOG_DEBUG:   return "Debug";
-	}
-}
-
-
-// Output cnt events from ring buffer
-
-static void report_events(int cnt)
-{
-	const char * msgs[3+MAXLINES];
-
-	int i, pri;
-	if (cnt <= 0)
-		return;
-	if (cnt > MAXLINES)
-		cnt = MAXLINES;
-
-	pri = evt_priorities[evt_index_out];
-
-	msgs[0] = sl_ident;
-	msgs[1] = sl_pidstr;
-	msgs[2] = pri2text(pri);
-	for (i = 0; i < cnt; i++) {
-		//assert(evt_priorities[evt_index_out] == pri);
-		msgs[3+i] = evt_lines[evt_index_out];
-		if (++evt_index_out >= MAXLINES)
-			evt_index_out = 0;
-	}
-	ReportEventA(sl_hevtsrc,
-		pri2evtype(pri), // type
-		0, MSG_SYSLOG+cnt,    // category, message id
-		NULL,                 // no security id
-		(WORD)(3+cnt), 0,     // 3+cnt strings, ...
-		msgs, NULL);          // ...          , no data
-}
-
-
-// Thread to combine several syslog lines into one event log entry
-
-static ULONG WINAPI event_logger_thread(LPVOID arg)
-{
-	int cnt;
-	ARGUSED(arg);
-
-	cnt = 0;
-	for (;;) {
-		// Wait for first line ...
-		int prior, i, rest;
-		if (cnt == 0) {
-			if (WaitForSingleObject(evt_wait_out, (evt_timeout? INFINITE : 0)) != WAIT_OBJECT_0)
-				break;
-			cnt = 1;
-		}
-
-		// ... wait some time for more lines with same prior
-		i = evt_index_out;
-		prior = evt_priorities[i];
-		rest = 0;
-		while (cnt < MAXLINES) {
-			long timeout =
-				evt_timeout * ((1000L * (MAXLINES-cnt+1))/MAXLINES);
-			if (WaitForSingleObject(evt_wait_out, timeout) != WAIT_OBJECT_0)
-				break;
-			if (++i >= MAXLINES)
-				i = 0;
-			if (evt_priorities[i] != prior) {
-				rest = 1;
-				break;
-			}
-			cnt++;
-		}
-
-		// Output all in one event log entry
-		report_events(cnt);
-
-		// Signal space
-		if (!ReleaseSemaphore(evt_wait_in, cnt, NULL))
-			break;
-		cnt = rest;
-	}
-	return 0;
-}
-
-
-static void on_exit_event_logger(void)
-{
-	// Output lines immediate if exiting
-	evt_timeout = 0; 
-	// Wait for thread to finish
-	WaitForSingleObject(evt_hthread, 1000L);
-	CloseHandle(evt_hthread);
-#if 0
-	if (sl_hevtsrc) {
-		DeregisterEventSource(sl_hevtsrc); sl_hevtsrc = 0;
-	}
-#else
-	// Leave event message source open to prevent losing messages during shutdown
-#endif
-}
-
-
-static int start_event_logger()
-{
-	DWORD tid;
-	evt_timeout = 1;
-	if (   !(evt_wait_in  = CreateSemaphore(NULL,  MAXLINES, MAXLINES, NULL))
-		|| !(evt_wait_out = CreateSemaphore(NULL,         0, MAXLINES, NULL))) {
-		fprintf(stderr,"CreateSemaphore failed, Error=%ld\n", GetLastError());
-		return -1;
-	}
-	if (!(evt_hthread = CreateThread(NULL, 0, event_logger_thread, NULL, 0, &tid))) {
-		fprintf(stderr,"CreateThread failed, Error=%ld\n", GetLastError());
-		return -1;
-	}
-	atexit(on_exit_event_logger);
-	return 0;
-}
-
-
-// Write lines to event log ring buffer
-
-static void write_event_log(int priority, const char * lines)
-{
-	int cnt = 0;
-	int i;
-	for (i = 0; lines[i]; i++) {
-		int len = 0;
-		while (lines[i+len] && lines[i+len] != '\n')
-			len++;
-			;
-		if (len > 0) {
-			// Wait for space
-			if (WaitForSingleObject(evt_wait_in, INFINITE) != WAIT_OBJECT_0)
-				return;
-			// Copy line
-			evt_priorities[evt_index_in] = priority;
-			memcpy(evt_lines[evt_index_in], lines+i, (len < LINELEN ? len : LINELEN));
-			if (len < LINELEN)
-				evt_lines[evt_index_in][len] = 0;
-			if (++evt_index_in >= MAXLINES)
-				evt_index_in = 0;
-			// Signal avail if ring buffer full
-			if (++cnt >= MAXLINES) {
-				ReleaseSemaphore(evt_wait_out, cnt, NULL);
-				cnt = 0;
-			}
-			i += len;
-		}
-		if (!lines[i])
-			break;
-	}
-
-	// Signal avail
-	if (cnt > 0)
-		ReleaseSemaphore(evt_wait_out, cnt, NULL);
-	Sleep(1);
-}
-
-
-// Write lines to logfile
-
-static void write_logfile(FILE * f, int priority, const char * lines)
-{
-	time_t now; char stamp[sizeof("2004-04-04 10:00:00")+13];
-	int i;
-
-	now = time((time_t*)0);
-	if (!strftime(stamp, sizeof(stamp)-1, "%Y-%m-%d %H:%M:%S", localtime(&now)))
-		strcpy(stamp,"?");
-
-	for (i = 0; lines[i]; i++) {
-		int len = 0;
-		while (lines[i+len] && lines[i+len] != '\n')
-			len++;
-		if (len > 0) {
-			fprintf(f, "%s %s[%s]: %-5s: ",
-				stamp, sl_ident, sl_pidstr, pri2text(priority));
-			fwrite(lines+i, len, 1, f);
-			fputc('\n', f);
-			i += len;
-		}
-		if (!lines[i])
-			break;
-	}
-}
-
-
-void openlog(const char *ident, int logopt, int facility)
-{
-	int pid;
-	if (sl_logpath[0] || sl_logfile || sl_hevtsrc)
-		return; // Already open
-
-	strncpy(sl_ident, ident, sizeof(sl_ident)-1);
-	// logopt==LOG_PID assumed
-	ARGUSED(logopt);
-	pid = getpid();
-	if (snprintf(sl_pidstr, sizeof(sl_pidstr)-1, (pid >= 0 ? "%d" : "0x%X"), pid) < 0)
-		strcpy(sl_pidstr,"?");
-
-	if (facility == LOG_LOCAL0) // "ident.log"
-		strcat(strcpy(sl_logpath, sl_ident), ".log");
-	else if (facility == LOG_LOCAL1) // stdout
-		sl_logfile = stdout;
-	else if (facility == LOG_LOCAL2) // stderr
-		sl_logfile = stderr;
-	else if (LOG_LOCAL2 < facility && facility <= LOG_LOCAL7) { // "ident[1-5].log"
-		snprintf(sl_logpath, sizeof(sl_logpath)-1, "%s%d.log",
-			sl_ident, LOG_FAC(facility)-LOG_FAC(LOG_LOCAL2));
-	}
-	else // Assume LOG_DAEMON, use event log if possible, else "ident.log"
-	if (!(sl_hevtsrc = RegisterEventSourceA(NULL/*localhost*/, sl_ident))) {
-		// Cannot open => Use logfile
-		long err = GetLastError();
-		strcat(strcpy(sl_logpath, sl_ident), ".log");
-		if (GetVersion() & 0x80000000)
-			fprintf(stderr, "%s: No event log on Win9x/ME, writing to %s\n",
-				sl_ident, sl_logpath);
-		else
-			fprintf(stderr, "%s: Cannot register event source (Error=%ld), writing to %s\n",
-				sl_ident, err, sl_logpath);
-	}
-	else {
-		// Start event log thread
-		start_event_logger();
-	}
-	//assert(sl_logpath[0] || sl_logfile || sl_hevtsrc);
-
-}
-
-
-void closelog()
-{
-}
-
-
-void vsyslog(int priority, const char * message, va_list args)
-{
-	char buffer[1000];
-
-	// Translation of %m to error text not supported yet
-	if (strstr(message, "%m"))
-		message = "Internal error: \"%%m\" in log message";
-
-	// Format message
-	if (vsnprintf(buffer, sizeof(buffer)-1, message, args) < 0)
-		strcpy(buffer, "Internal Error: buffer overflow");
-
-	if (sl_hevtsrc) {
-		// Write to event log
-		write_event_log(priority, buffer);
-	}
-	else if (sl_logfile) {
-		// Write to stdout/err
-		write_logfile(sl_logfile, priority, buffer);
-		fflush(sl_logfile);
-	}
-	else if (sl_logpath[0]) {
-		// Append to logfile
-		FILE * f;
-		if (!(f = fopen(sl_logpath, "a")))
-			return;
-		write_logfile(f, priority, buffer);
-		fclose(f);
-	}
-}
-
-
-#ifdef TEST
-// Test program
-
-void syslog(int priority, const char *message, ...)
-{
-	va_list args;
-	va_start(args, message);
-	vsyslog(priority, message, args);
-	va_end(args);
-}
-
-int main(int argc, char* argv[])
-{
-	int i;
-	openlog(argc < 2 ? "test" : argv[1], LOG_PID, (argc < 3 ? LOG_DAEMON : LOG_LOCAL1));
-	syslog(LOG_INFO,    "Info\n");
-	syslog(LOG_WARNING, "Warning %d\n\n", 42);
-	syslog(LOG_ERR,     "Error %s", "Fatal");
-	for (i = 0; i < 100; i++) {
-		char buf[LINELEN];
-		if (i % 13 == 0)
-			Sleep(1000L);
-		sprintf(buf, "Log Line %d\n", i);
-		syslog(i % 17 ? LOG_INFO : LOG_ERR, buf);
-	}
-	closelog();
-	return 0;
-}
-
-#endif
diff --git a/sm5/os_win32/syslogevt.c b/sm5/os_win32/syslogevt.c
deleted file mode 100644
index 65f8565f1e4e3e5aca8d215d710b7c2ed69bdd57..0000000000000000000000000000000000000000
--- a/sm5/os_win32/syslogevt.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * os_win32/syslogevt.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-static char rcsid[] = "$Id: syslogevt.c,v 1.2 2004/04/07 11:17:08 chrfranke Exp $";
-
-#include <stdio.h>
-#include <string.h>
-#include <process.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#ifdef _DEBUG
-#include "syslogevt.h"
-#endif
-
-
-static int usage()
-{
-	puts(
-		"syslogevt $Revision: 1.2 $ Copyright (C) 2004 Christian Franke\n"
-		"Home page is http://smartmontools.sourceforge.net/\n"
-		"\n"
-		"Usage: syslogevt [-ru] name [ident ...]\n"
-		"\n"
-		"Creates registry files \"name-r.reg\" and \"name-u.reg\" to (un)register\n"
-		"this program as an event message file for message source(s) \"ident\".\n"
-		"If \"ident\" is ommited, \"name\" is used. Options:\n"
-		"\n"
-		"    -r    run \"regedit name-r.reg\" after creating files\n"
-		"    -u    run \"regedit name-u.reg\" after creating files\n"
-		"\n"
-		"Examples:\n"
-		"\n"
-		"syslogevt smartd                     (Create smartd-r.reg and smartd-u.reg)\n"
-		"regedit smartd-r.reg           (Register syslogevt.exe for smartd messages)\n"
-		"\n"
-		"syslogevt -r smartd                             (Same as above in one step)\n"
-		"\n"
-		"regedit smartd-u.reg                                (Undo the registration)\n"
-		"\n"
-		"CAUTION: A registry entry of an existing event source with the same \"ident\"\n"
-		"         will be overwritten by regedit without notice."
-	);
-	return 1;
-}
-
-main(int argc, char ** argv)
-{
-	int regedit, a1, ai;
-	char name1[30+1], name2[30+1], mypath[MAX_PATH+1];
-	const char * ident;
-	FILE * f1, * f2;
-
-#ifdef _DEBUG
-	if (!(MSG_SYSLOG == 0 && MSG_SYSLOG_01 == 1 && MSG_SYSLOG_10 == 10)) {
-		puts("Internal error: MSG_SYSLOG_n != n"); return 1;
-	}
-#endif
-
-	if (argc < 2)
-		return usage();
-
-	a1 = 1;
-	regedit = 0;
-	if (!strcmp(argv[a1], "-r")) {
-		regedit = 1; a1++;
-	}
-	else if (!strcmp(argv[a1], "-u")) {
-		regedit = -1; a1++;
-	}
-
-	for (ai = a1; ai < argc; ai++) {
-		ident = argv[ai];
-		if (!(ident[0] && strlen(ident) < sizeof(name1)-10
-			  && strcspn(ident, "-.:/\\") == strlen(ident) )) {
-			return usage();
-		}
-	}
-
-	if (!GetModuleFileName(NULL, mypath, sizeof(mypath)-1)) {
-		fputs("GetModuleFileName failed\n", stderr);
-		return 1;
-	}
-
-	ident = argv[a1];
-	strcpy(name1, ident); strcat(name1, "-r.reg");
-	strcpy(name2, ident); strcat(name2, "-u.reg");
-
-	if (!(f1 = fopen(name1, "w"))) {
-		perror(name1); return 1;
-	}
-	if (!(f2 = fopen(name2, "w"))) {
-		perror(name2); unlink(name1); return 1;
-	}
-
-	fputs("REGEDIT4\n\n", f1);
-	fputs("REGEDIT4\n\n", f2);
-
-	for (ai = (argc > a1+1 ? a1+1 : a1); ai < argc; ai++) {
-		int i;
-		ident = argv[ai];
-		fputs("[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\", f1);
-		fputs(ident, f1); fputs("]\n\"EventMessageFile\"=\"", f1);
-		for (i = 0; mypath[i]; i++) {
-			if (mypath[i] == '\\')
-				fputc('\\', f1);
-			fputc(mypath[i], f1);
-		}
-		fputs("\"\n\"TypesSupported\"=dword:00000007\n\n", f1);
-
-		fputs("[-HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\", f2);
-		fputs(ident, f2); fputs("]\n\n", f2);
-	}
-
-	fclose(f1);
-	fclose(f2);
-
-	if (GetVersion() & 0x80000000) {
-		puts("Warning: Event log not supported on Win9x/ME\n");
-		if (regedit)
-			return 1;
-	}
-
-	if (regedit) {
-		if (spawnlp(P_WAIT, "regedit", "regedit", (regedit > 0 ? name1 : name2), (const char *)0) == -1) {
-			fputs("regedit: cannot execute\n", stderr);
-			return 1;
-		}
-	}
-	else {
-		fputs("Files generated. Use\n\n    regedit ", stdout);
-		puts(name1);
-		fputs("\nto register event message file, and\n\n    regedit ", stdout);
-		puts(name2);
-		fputs("\nto remove registration later.\n\n"
-			  "Do not remove this program when registered.\n", stdout);
-	}
-
-	return 0;
-}
diff --git a/sm5/os_win32/syslogevt.mc b/sm5/os_win32/syslogevt.mc
deleted file mode 100644
index 049f2eb5a2c2e79772cd9aeb41fd6a0f40ef39ae..0000000000000000000000000000000000000000
--- a/sm5/os_win32/syslogevt.mc
+++ /dev/null
@@ -1,161 +0,0 @@
-;/*
-; * os_win32/syslogevt.mc
-; *
-; * Home page of code is: http://smartmontools.sourceforge.net
-; *
-; * Copyright (C) 2004 Christian Franke <smartmontools-support@lists.sourceforge.net>
-; *
-; * 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, write to the Free
-; * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-; *
-; */
-;
-;// $Id: syslogevt.mc,v 1.2 2004/04/07 11:17:08 chrfranke Exp $
-;
-;// Use message compiler "mc" to generate
-;//   syslogevt.rc, syslogevt.h, msg00001.bin
-;// from this file.
-;// MSG_SYSLOG in syslogmsg.h must be zero
-;// MSG_SYSLOG_nn must be == nn
-;
-;
-
-MessageId=0x0
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG
-Language=English
-%1
-.
-;// 1-10 Line SYSLOG Messages
-;// %1=Ident, %2=PID, %3=Severity, %[4-13]=Line 1-10
-MessageId=0x1
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_01
-Language=English
-%1[%2]:%3: %4
-.
-MessageId=0x2
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_02
-Language=English
-%1[%2]:%3%n
-%4%n
-%5
-.
-MessageId=0x3
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_03
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6
-.
-MessageId=0x4
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_04
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7
-.
-MessageId=0x5
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_05
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7%n
-%8
-.
-MessageId=0x6
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_06
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7%n
-%8%n
-%9
-.
-MessageId=0x7
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_07
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7%n
-%8%n
-%9%n
-%10
-.
-MessageId=0x8
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_08
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7%n
-%8%n
-%9%n
-%10%n
-%11
-.
-MessageId=0x9
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_09
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7%n
-%8%n
-%9%n
-%10%n
-%11%n
-%12
-.
-MessageId=0xa
-Severity=Success
-Facility=Application
-SymbolicName=MSG_SYSLOG_10
-Language=English
-%1[%2]:%3%n
-%4%n
-%5%n
-%6%n
-%7%n
-%8%n
-%9%n
-%10%n
-%11%n
-%12%n
-%13
-.
diff --git a/sm5/os_win32/syslogevt_vc6.dsp b/sm5/os_win32/syslogevt_vc6.dsp
deleted file mode 100644
index 3f8a8af44f28dc8e78138e8a51f79202ec8ae129..0000000000000000000000000000000000000000
--- a/sm5/os_win32/syslogevt_vc6.dsp
+++ /dev/null
@@ -1,148 +0,0 @@
-# Microsoft Developer Studio Project File - Name="syslogevt_vc6" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** NICHT BEARBEITEN **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=syslogevt_vc6 - Win32 Debug
-!MESSAGE Dies ist kein g�ltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
-!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und f�hren Sie den Befehl
-!MESSAGE 
-!MESSAGE NMAKE /f "syslogevt_vc6.mak".
-!MESSAGE 
-!MESSAGE Sie k�nnen beim Ausf�hren von NMAKE eine Konfiguration angeben
-!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
-!MESSAGE 
-!MESSAGE NMAKE /f "syslogevt_vc6.mak" CFG="syslogevt_vc6 - Win32 Debug"
-!MESSAGE 
-!MESSAGE F�r die Konfiguration stehen zur Auswahl:
-!MESSAGE 
-!MESSAGE "syslogevt_vc6 - Win32 Release" (basierend auf  "Win32 (x86) Console Application")
-!MESSAGE "syslogevt_vc6 - Win32 Debug" (basierend auf  "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "syslogevt_vc6 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "syslogevt.r"
-# PROP Intermediate_Dir "syslogevt.r"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x407 /d "NDEBUG"
-# ADD RSC /l 0x407 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 $(IntDir)\syslogevt.res kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"syslogevt.exe"
-# SUBTRACT LINK32 /pdb:none
-# Begin Special Build Tool
-IntDir=.\syslogevt.r
-SOURCE="$(InputPath)"
-PreLink_Desc=Compiling Resources
-PreLink_Cmds=rc $(IntDir)\syslogevt.rc
-# End Special Build Tool
-
-!ELSEIF  "$(CFG)" == "syslogevt_vc6 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "syslogevt.d"
-# PROP Intermediate_Dir "syslogevt.d"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x407 /d "_DEBUG"
-# ADD RSC /l 0x407 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 $(IntDir)\syslogevt.res kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# Begin Special Build Tool
-IntDir=.\syslogevt.d
-SOURCE="$(InputPath)"
-PreLink_Desc=Compiling Resources
-PreLink_Cmds=rc $(IntDir)\syslogevt.rc
-# End Special Build Tool
-
-!ENDIF 
-
-# Begin Target
-
-# Name "syslogevt_vc6 - Win32 Release"
-# Name "syslogevt_vc6 - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\syslogevt.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\syslogevt.mc
-
-!IF  "$(CFG)" == "syslogevt_vc6 - Win32 Release"
-
-# Begin Custom Build - Compiling Messages
-IntDir=.\syslogevt.r
-InputPath=.\syslogevt.mc
-
-BuildCmds= \
-	mc -r $(IntDir) syslogevt.mc
-
-"$(IntDir)\syslogevt.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-   $(BuildCmds)
-
-"$(IntDir)\msg00001.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-   $(BuildCmds)
-
-"syslogevt.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-   $(BuildCmds)
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "syslogevt_vc6 - Win32 Debug"
-
-# Begin Custom Build - Compiling Messages
-IntDir=.\syslogevt.d
-InputPath=.\syslogevt.mc
-
-BuildCmds= \
-	mc -r $(IntDir) syslogevt.mc
-
-"$(IntDir)\syslogevt.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-   $(BuildCmds)
-
-"$(IntDir)\msg00001.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-   $(BuildCmds)
-
-"syslogevt.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-   $(BuildCmds)
-# End Custom Build
-
-!ENDIF 
-
-# End Source File
-# End Target
-# End Project
diff --git a/sm5/posix/getopt.c b/sm5/posix/getopt.c
deleted file mode 100644
index 289d137e20babf967f75a5baa19c904b2ff5b68a..0000000000000000000000000000000000000000
--- a/sm5/posix/getopt.c
+++ /dev/null
@@ -1,1277 +0,0 @@
-/* Getopt for GNU.
-   NOTE: getopt is now part of the C library, so if you don't know what
-   "Keep this file name-space clean" means, talk to drepper@gnu.org
-   before changing it!
-   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002
-   	Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
-   Ditto for AIX 3.2 and <stdlib.h>.  */
-#ifndef _NO_PROTO
-# define _NO_PROTO
-#endif
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-# ifndef const
-#  define const
-# endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-# include <gnu-versions.h>
-# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#  define ELIDE_CODE
-# endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef	__GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
-   contain conflicting prototypes for getopt.  */
-# include <stdlib.h>
-# include <unistd.h>
-#endif	/* GNU C library.  */
-
-#ifdef VMS
-# include <unixlib.h>
-# if HAVE_STRING_H - 0
-#  include <string.h>
-# endif
-#endif
-
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.  */
-# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
-#  include <libintl.h>
-#  ifndef _
-#   define _(msgid)	gettext (msgid)
-#  endif
-# else
-#  define _(msgid)	(msgid)
-# endif
-# if defined _LIBC && defined USE_IN_LIBIO
-#  include <wchar.h>
-# endif
-#endif
-
-#ifndef attribute_hidden
-# define attribute_hidden
-#endif
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
-   but it behaves differently for the user, since it allows the user
-   to intersperse the options with the other arguments.
-
-   As `getopt' works, it permutes the elements of ARGV so that,
-   when it is done, all the options precede everything else.  Thus
-   all application programs are extended to handle flexible argument order.
-
-   Setting the environment variable POSIXLY_CORRECT disables permutation.
-   Then the behavior is completely standard.
-
-   GNU application programs can use a third alternative mode in which
-   they can distinguish the relative order of options and other arguments.  */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns -1, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-/* 1003.2 says this must be 1 before any call.  */
-int optind = 1;
-
-/* Formerly, initialization of getopt depended on optind==0, which
-   causes problems with re-calling getopt as programs generally don't
-   know that. */
-
-int __getopt_initialized attribute_hidden;
-
-/* The next char to be scanned in the option-element
-   in which the last option character we returned was found.
-   This allows us to pick up the scan where we left off.
-
-   If this is zero, or a null string, it means resume the scan
-   by advancing to the next ARGV-element.  */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
-   for unrecognized options.  */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
-   This must be initialized on some systems to avoid linking in the
-   system's own getopt implementation.  */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
-   If the caller did not specify anything,
-   the default is REQUIRE_ORDER if the environment variable
-   POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
-   REQUIRE_ORDER means don't recognize them as options;
-   stop option processing when the first non-option is seen.
-   This is what Unix does.
-   This mode of operation is selected by either setting the environment
-   variable POSIXLY_CORRECT, or using `+' as the first character
-   of the list of option characters.
-
-   PERMUTE is the default.  We permute the contents of ARGV as we scan,
-   so that eventually all the non-options are at the end.  This allows options
-   to be given in any order, even with programs that were not written to
-   expect this.
-
-   RETURN_IN_ORDER is an option available to programs that were written
-   to expect options and other ARGV-elements in any order and that care about
-   the ordering of the two.  We describe each non-option ARGV-element
-   as if it were the argument of an option with character code 1.
-   Using `-' as the first character of the list of option characters
-   selects this mode of operation.
-
-   The special argument `--' forces an end of option-scanning regardless
-   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
-   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
-
-static enum
-{
-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable.  */
-static char *posixly_correct;
-
-#ifdef	__GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
-   because there are many ways it can cause trouble.
-   On some systems, it contains special magic macros that don't work
-   in GCC.  */
-# include <string.h>
-# define my_index	strchr
-#else
-
-# if HAVE_STRING_H
-#  include <string.h>
-# else
-#  include <strings.h>
-# endif
-
-/* Avoid depending on library functions or files
-   whose names are inconsistent.  */
-
-#ifndef getenv
-extern char *getenv ();
-#endif
-
-static char *
-my_index (str, chr)
-     const char *str;
-     int chr;
-{
-  while (*str)
-    {
-      if (*str == chr)
-	return (char *) str;
-      str++;
-    }
-  return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
-   If not using GCC, it is ok not to declare it.  */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
-   That was relevant to code that was here before.  */
-# if (!defined __STDC__ || !__STDC__) && !defined strlen
-/* gcc with -traditional declares the built-in strlen to return int,
-   and has done so at least since version 2.4.5. -- rms.  */
-extern int strlen (const char *);
-# endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments.  */
-
-/* Describe the part of ARGV that contains non-options that have
-   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
-   `last_nonopt' is the index after the last of them.  */
-
-static int first_nonopt;
-static int last_nonopt;
-
-#ifdef _LIBC
-/* Stored original parameters.
-   XXX This is no good solution.  We should rather copy the args so
-   that we can compare them later.  But we must not use malloc(3).  */
-extern int __libc_argc;
-extern char **__libc_argv;
-
-/* Bash 2.0 gives us an environment variable containing flags
-   indicating ARGV elements that should not be considered arguments.  */
-
-# ifdef USE_NONOPTION_FLAGS
-/* Defined in getopt_init.c  */
-extern char *__getopt_nonoption_flags;
-
-static int nonoption_flags_max_len;
-static int nonoption_flags_len;
-# endif
-
-# ifdef USE_NONOPTION_FLAGS
-#  define SWAP_FLAGS(ch1, ch2) \
-  if (nonoption_flags_len > 0)						      \
-    {									      \
-      char __tmp = __getopt_nonoption_flags[ch1];			      \
-      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
-      __getopt_nonoption_flags[ch2] = __tmp;				      \
-    }
-# else
-#  define SWAP_FLAGS(ch1, ch2)
-# endif
-#else	/* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif	/* _LIBC */
-
-/* Exchange two adjacent subsequences of ARGV.
-   One subsequence is elements [first_nonopt,last_nonopt)
-   which contains all the non-options that have been skipped so far.
-   The other is elements [last_nonopt,optind), which contains all
-   the options processed since those non-options were skipped.
-
-   `first_nonopt' and `last_nonopt' are relocated so that they describe
-   the new indices of the non-options in ARGV after they are moved.  */
-
-#if defined __STDC__ && __STDC__
-static void exchange (char **);
-#endif
-
-static void
-exchange (argv)
-     char **argv;
-{
-  int bottom = first_nonopt;
-  int middle = last_nonopt;
-  int top = optind;
-  char *tem;
-
-  /* Exchange the shorter segment with the far end of the longer segment.
-     That puts the shorter segment into the right place.
-     It leaves the longer segment in the right place overall,
-     but it consists of two parts that need to be swapped next.  */
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-  /* First make sure the handling of the `__getopt_nonoption_flags'
-     string can work normally.  Our top argument must be in the range
-     of the string.  */
-  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
-    {
-      /* We must extend the array.  The user plays games with us and
-	 presents new arguments.  */
-      char *new_str = malloc (top + 1);
-      if (new_str == NULL)
-	nonoption_flags_len = nonoption_flags_max_len = 0;
-      else
-	{
-	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
-			     nonoption_flags_max_len),
-		  '\0', top + 1 - nonoption_flags_max_len);
-	  nonoption_flags_max_len = top + 1;
-	  __getopt_nonoption_flags = new_str;
-	}
-    }
-#endif
-
-  while (top > middle && middle > bottom)
-    {
-      if (top - middle > middle - bottom)
-	{
-	  /* Bottom segment is the short one.  */
-	  int len = middle - bottom;
-	  register int i;
-
-	  /* Swap it with the top part of the top segment.  */
-	  for (i = 0; i < len; i++)
-	    {
-	      tem = argv[bottom + i];
-	      argv[bottom + i] = argv[top - (middle - bottom) + i];
-	      argv[top - (middle - bottom) + i] = tem;
-	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
-	    }
-	  /* Exclude the moved bottom segment from further swapping.  */
-	  top -= len;
-	}
-      else
-	{
-	  /* Top segment is the short one.  */
-	  int len = top - middle;
-	  register int i;
-
-	  /* Swap it with the bottom part of the bottom segment.  */
-	  for (i = 0; i < len; i++)
-	    {
-	      tem = argv[bottom + i];
-	      argv[bottom + i] = argv[middle + i];
-	      argv[middle + i] = tem;
-	      SWAP_FLAGS (bottom + i, middle + i);
-	    }
-	  /* Exclude the moved top segment from further swapping.  */
-	  bottom += len;
-	}
-    }
-
-  /* Update records for the slots the non-options now occupy.  */
-
-  first_nonopt += (optind - last_nonopt);
-  last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made.  */
-
-#if defined __STDC__ && __STDC__
-static const char *_getopt_initialize (int, char *const *, const char *);
-#endif
-static const char *
-_getopt_initialize (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-{
-  /* Start processing options with ARGV-element 1 (since ARGV-element 0
-     is the program name); the sequence of previously skipped
-     non-option ARGV-elements is empty.  */
-
-  first_nonopt = last_nonopt = optind;
-
-  nextchar = NULL;
-
-  posixly_correct = getenv ("POSIXLY_CORRECT");
-
-  /* Determine how to handle the ordering of options and nonoptions.  */
-
-  if (optstring[0] == '-')
-    {
-      ordering = RETURN_IN_ORDER;
-      ++optstring;
-    }
-  else if (optstring[0] == '+')
-    {
-      ordering = REQUIRE_ORDER;
-      ++optstring;
-    }
-  else if (posixly_correct != NULL)
-    ordering = REQUIRE_ORDER;
-  else
-    ordering = PERMUTE;
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-  if (posixly_correct == NULL
-      && argc == __libc_argc && argv == __libc_argv)
-    {
-      if (nonoption_flags_max_len == 0)
-	{
-	  if (__getopt_nonoption_flags == NULL
-	      || __getopt_nonoption_flags[0] == '\0')
-	    nonoption_flags_max_len = -1;
-	  else
-	    {
-	      const char *orig_str = __getopt_nonoption_flags;
-	      int len = nonoption_flags_max_len = strlen (orig_str);
-	      if (nonoption_flags_max_len < argc)
-		nonoption_flags_max_len = argc;
-	      __getopt_nonoption_flags =
-		(char *) malloc (nonoption_flags_max_len);
-	      if (__getopt_nonoption_flags == NULL)
-		nonoption_flags_max_len = -1;
-	      else
-		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
-			'\0', nonoption_flags_max_len - len);
-	    }
-	}
-      nonoption_flags_len = nonoption_flags_max_len;
-    }
-  else
-    nonoption_flags_len = 0;
-#endif
-
-  return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
-   given in OPTSTRING.
-
-   If an element of ARGV starts with '-', and is not exactly "-" or "--",
-   then it is an option element.  The characters of this element
-   (aside from the initial '-') are option characters.  If `getopt'
-   is called repeatedly, it returns successively each of the option characters
-   from each of the option elements.
-
-   If `getopt' finds another option character, it returns that character,
-   updating `optind' and `nextchar' so that the next call to `getopt' can
-   resume the scan with the following option character or ARGV-element.
-
-   If there are no more option characters, `getopt' returns -1.
-   Then `optind' is the index in ARGV of the first ARGV-element
-   that is not an option.  (The ARGV-elements have been permuted
-   so that those that are not options now come last.)
-
-   OPTSTRING is a string containing the legitimate option characters.
-   If an option character is seen that is not listed in OPTSTRING,
-   return '?' after printing an error message.  If you set `opterr' to
-   zero, the error message is suppressed but we still return '?'.
-
-   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
-   so the following text in the same ARGV-element, or the text of the following
-   ARGV-element, is returned in `optarg'.  Two colons mean an option that
-   wants an optional arg; if there is text in the current ARGV-element,
-   it is returned in `optarg', otherwise `optarg' is set to zero.
-
-   If OPTSTRING starts with `-' or `+', it requests different methods of
-   handling the non-option ARGV-elements.
-   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
-   Long-named options begin with `--' instead of `-'.
-   Their names may be abbreviated as long as the abbreviation is unique
-   or is an exact match for some defined option.  If they have an
-   argument, it follows the option name in the same ARGV-element, separated
-   from the option name by a `=', or else the in next ARGV-element.
-   When `getopt' finds a long-named option, it returns 0 if that option's
-   `flag' field is nonzero, the value of the option's `val' field
-   if the `flag' field is zero.
-
-   The elements of ARGV aren't really const, because we permute them.
-   But we pretend they're const in the prototype to be compatible
-   with other systems.
-
-   LONGOPTS is a vector of `struct option' terminated by an
-   element containing a name which is zero.
-
-   LONGIND returns the index in LONGOPT of the long-named option found.
-   It is only valid when a long-named option has been found by the most
-   recent call.
-
-   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
-   long-named options.  */
-
-int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-     const struct option *longopts;
-     int *longind;
-     int long_only;
-{
-  int print_errors = opterr;
-  if (optstring[0] == ':')
-    print_errors = 0;
-
-  if (argc < 1)
-    return -1;
-
-  optarg = NULL;
-
-  if (optind == 0 || !__getopt_initialized)
-    {
-      if (optind == 0)
-	optind = 1;	/* Don't scan ARGV[0], the program name.  */
-      optstring = _getopt_initialize (argc, argv, optstring);
-      __getopt_initialized = 1;
-    }
-
-  /* Test whether ARGV[optind] points to a non-option argument.
-     Either it does not have option syntax, or there is an environment flag
-     from the shell indicating it is not an option.  The later information
-     is only used when the used in the GNU libc.  */
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
-		      || (optind < nonoption_flags_len			      \
-			  && __getopt_nonoption_flags[optind] == '1'))
-#else
-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#endif
-
-  if (nextchar == NULL || *nextchar == '\0')
-    {
-      /* Advance to the next ARGV-element.  */
-
-      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
-	 moved back by the user (who may also have changed the arguments).  */
-      if (last_nonopt > optind)
-	last_nonopt = optind;
-      if (first_nonopt > optind)
-	first_nonopt = optind;
-
-      if (ordering == PERMUTE)
-	{
-	  /* If we have just processed some options following some non-options,
-	     exchange them so that the options come first.  */
-
-	  if (first_nonopt != last_nonopt && last_nonopt != optind)
-	    exchange ((char **) argv);
-	  else if (last_nonopt != optind)
-	    first_nonopt = optind;
-
-	  /* Skip any additional non-options
-	     and extend the range of non-options previously skipped.  */
-
-	  while (optind < argc && NONOPTION_P)
-	    optind++;
-	  last_nonopt = optind;
-	}
-
-      /* The special ARGV-element `--' means premature end of options.
-	 Skip it like a null option,
-	 then exchange with previous non-options as if it were an option,
-	 then skip everything else like a non-option.  */
-
-      if (optind != argc && !strcmp (argv[optind], "--"))
-	{
-	  optind++;
-
-	  if (first_nonopt != last_nonopt && last_nonopt != optind)
-	    exchange ((char **) argv);
-	  else if (first_nonopt == last_nonopt)
-	    first_nonopt = optind;
-	  last_nonopt = argc;
-
-	  optind = argc;
-	}
-
-      /* If we have done all the ARGV-elements, stop the scan
-	 and back over any non-options that we skipped and permuted.  */
-
-      if (optind == argc)
-	{
-	  /* Set the next-arg-index to point at the non-options
-	     that we previously skipped, so the caller will digest them.  */
-	  if (first_nonopt != last_nonopt)
-	    optind = first_nonopt;
-	  return -1;
-	}
-
-      /* If we have come to a non-option and did not permute it,
-	 either stop the scan or describe it to the caller and pass it by.  */
-
-      if (NONOPTION_P)
-	{
-	  if (ordering == REQUIRE_ORDER)
-	    return -1;
-	  optarg = argv[optind++];
-	  return 1;
-	}
-
-      /* We have found another option-ARGV-element.
-	 Skip the initial punctuation.  */
-
-      nextchar = (argv[optind] + 1
-		  + (longopts != NULL && argv[optind][1] == '-'));
-    }
-
-  /* Decode the current option-ARGV-element.  */
-
-  /* Check whether the ARGV-element is a long option.
-
-     If long_only and the ARGV-element has the form "-f", where f is
-     a valid short option, don't consider it an abbreviated form of
-     a long option that starts with f.  Otherwise there would be no
-     way to give the -f short option.
-
-     On the other hand, if there's a long option "fubar" and
-     the ARGV-element is "-fu", do consider that an abbreviation of
-     the long option, just like "--fu", and not "-f" with arg "u".
-
-     This distinction seems to be the most useful approach.  */
-
-  if (longopts != NULL
-      && (argv[optind][1] == '-'
-	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
-    {
-      char *nameend;
-      const struct option *p;
-      const struct option *pfound = NULL;
-      int exact = 0;
-      int ambig = 0;
-      int indfound = -1;
-      int option_index;
-
-      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
-	/* Do nothing.  */ ;
-
-      /* Test all long options for either exact match
-	 or abbreviated matches.  */
-      for (p = longopts, option_index = 0; p->name; p++, option_index++)
-	if (!strncmp (p->name, nextchar, nameend - nextchar))
-	  {
-	    if ((unsigned int) (nameend - nextchar)
-		== (unsigned int) strlen (p->name))
-	      {
-		/* Exact match found.  */
-		pfound = p;
-		indfound = option_index;
-		exact = 1;
-		break;
-	      }
-	    else if (pfound == NULL)
-	      {
-		/* First nonexact match found.  */
-		pfound = p;
-		indfound = option_index;
-	      }
-	    else if (long_only
-		     || pfound->has_arg != p->has_arg
-		     || pfound->flag != p->flag
-		     || pfound->val != p->val)
-	      /* Second or later nonexact match found.  */
-	      ambig = 1;
-	  }
-
-      if (ambig && !exact)
-	{
-	  if (print_errors)
-	    {
-#if defined _LIBC && defined USE_IN_LIBIO
-	      char *buf;
-
-	      if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
-			      argv[0], argv[optind]) >= 0)
-		{
-
-		  if (_IO_fwide (stderr, 0) > 0)
-		    __fwprintf (stderr, L"%s", buf);
-		  else
-		    fputs (buf, stderr);
-
-		  free (buf);
-		}
-#else
-	      fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
-		       argv[0], argv[optind]);
-#endif
-	    }
-	  nextchar += strlen (nextchar);
-	  optind++;
-	  optopt = 0;
-	  return '?';
-	}
-
-      if (pfound != NULL)
-	{
-	  option_index = indfound;
-	  optind++;
-	  if (*nameend)
-	    {
-	      /* Don't test has_arg with >, because some C compilers don't
-		 allow it to be used on enums.  */
-	      if (pfound->has_arg)
-		optarg = nameend + 1;
-	      else
-		{
-		  if (print_errors)
-		    {
-#if defined _LIBC && defined USE_IN_LIBIO
-		      char *buf;
-		      int n;
-#endif
-
-		      if (argv[optind - 1][1] == '-')
-			{
-			  /* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
-			  n = __asprintf (&buf, _("\
-%s: option `--%s' doesn't allow an argument\n"),
-					  argv[0], pfound->name);
-#else
-			  fprintf (stderr, _("\
-%s: option `--%s' doesn't allow an argument\n"),
-				   argv[0], pfound->name);
-#endif
-			}
-		      else
-			{
-			  /* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
-			  n = __asprintf (&buf, _("\
-%s: option `%c%s' doesn't allow an argument\n"),
-					  argv[0], argv[optind - 1][0],
-					  pfound->name);
-#else
-			  fprintf (stderr, _("\
-%s: option `%c%s' doesn't allow an argument\n"),
-				   argv[0], argv[optind - 1][0], pfound->name);
-#endif
-			}
-
-#if defined _LIBC && defined USE_IN_LIBIO
-		      if (n >= 0)
-			{
-			  if (_IO_fwide (stderr, 0) > 0)
-			    __fwprintf (stderr, L"%s", buf);
-			  else
-			    fputs (buf, stderr);
-
-			  free (buf);
-			}
-#endif
-		    }
-
-		  nextchar += strlen (nextchar);
-
-		  optopt = pfound->val;
-		  return '?';
-		}
-	    }
-	  else if (pfound->has_arg == 1)
-	    {
-	      if (optind < argc)
-		optarg = argv[optind++];
-	      else
-		{
-		  if (print_errors)
-		    {
-#if defined _LIBC && defined USE_IN_LIBIO
-		      char *buf;
-
-		      if (__asprintf (&buf, _("\
-%s: option `%s' requires an argument\n"),
-				      argv[0], argv[optind - 1]) >= 0)
-			{
-			  if (_IO_fwide (stderr, 0) > 0)
-			    __fwprintf (stderr, L"%s", buf);
-			  else
-			    fputs (buf, stderr);
-
-			  free (buf);
-			}
-#else
-		      fprintf (stderr,
-			       _("%s: option `%s' requires an argument\n"),
-			       argv[0], argv[optind - 1]);
-#endif
-		    }
-		  nextchar += strlen (nextchar);
-		  optopt = pfound->val;
-		  return optstring[0] == ':' ? ':' : '?';
-		}
-	    }
-	  nextchar += strlen (nextchar);
-	  if (longind != NULL)
-	    *longind = option_index;
-	  if (pfound->flag)
-	    {
-	      *(pfound->flag) = pfound->val;
-	      return 0;
-	    }
-	  return pfound->val;
-	}
-
-      /* Can't find it as a long option.  If this is not getopt_long_only,
-	 or the option starts with '--' or is not a valid short
-	 option, then it's an error.
-	 Otherwise interpret it as a short option.  */
-      if (!long_only || argv[optind][1] == '-'
-	  || my_index (optstring, *nextchar) == NULL)
-	{
-	  if (print_errors)
-	    {
-#if defined _LIBC && defined USE_IN_LIBIO
-	      char *buf;
-	      int n;
-#endif
-
-	      if (argv[optind][1] == '-')
-		{
-		  /* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
-		  n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
-				  argv[0], nextchar);
-#else
-		  fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
-			   argv[0], nextchar);
-#endif
-		}
-	      else
-		{
-		  /* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
-		  n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
-				  argv[0], argv[optind][0], nextchar);
-#else
-		  fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
-			   argv[0], argv[optind][0], nextchar);
-#endif
-		}
-
-#if defined _LIBC && defined USE_IN_LIBIO
-	      if (n >= 0)
-		{
-		  if (_IO_fwide (stderr, 0) > 0)
-		    __fwprintf (stderr, L"%s", buf);
-		  else
-		    fputs (buf, stderr);
-
-		  free (buf);
-		}
-#endif
-	    }
-	  nextchar = (char *) "";
-	  optind++;
-	  optopt = 0;
-	  return '?';
-	}
-    }
-
-  /* Look at and handle the next short option-character.  */
-
-  {
-    char c = *nextchar++;
-    char *temp = my_index (optstring, c);
-
-    /* Increment `optind' when we start to process its last character.  */
-    if (*nextchar == '\0')
-      ++optind;
-
-    if (temp == NULL || c == ':')
-      {
-	if (print_errors)
-	  {
-#if defined _LIBC && defined USE_IN_LIBIO
-	      char *buf;
-	      int n;
-#endif
-
-	    if (posixly_correct)
-	      {
-		/* 1003.2 specifies the format of this message.  */
-#if defined _LIBC && defined USE_IN_LIBIO
-		n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
-				argv[0], c);
-#else
-		fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
-#endif
-	      }
-	    else
-	      {
-#if defined _LIBC && defined USE_IN_LIBIO
-		n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
-				argv[0], c);
-#else
-		fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
-#endif
-	      }
-
-#if defined _LIBC && defined USE_IN_LIBIO
-	    if (n >= 0)
-	      {
-		if (_IO_fwide (stderr, 0) > 0)
-		  __fwprintf (stderr, L"%s", buf);
-		else
-		  fputs (buf, stderr);
-
-		free (buf);
-	      }
-#endif
-	  }
-	optopt = c;
-	return '?';
-      }
-    /* Convenience. Treat POSIX -W foo same as long option --foo */
-    if (temp[0] == 'W' && temp[1] == ';')
-      {
-	char *nameend;
-	const struct option *p;
-	const struct option *pfound = NULL;
-	int exact = 0;
-	int ambig = 0;
-	int indfound = 0;
-	int option_index;
-
-	/* This is an option that requires an argument.  */
-	if (*nextchar != '\0')
-	  {
-	    optarg = nextchar;
-	    /* If we end this ARGV-element by taking the rest as an arg,
-	       we must advance to the next element now.  */
-	    optind++;
-	  }
-	else if (optind == argc)
-	  {
-	    if (print_errors)
-	      {
-		/* 1003.2 specifies the format of this message.  */
-#if defined _LIBC && defined USE_IN_LIBIO
-		char *buf;
-
-		if (__asprintf (&buf,
-				_("%s: option requires an argument -- %c\n"),
-				argv[0], c) >= 0)
-		  {
-		    if (_IO_fwide (stderr, 0) > 0)
-		      __fwprintf (stderr, L"%s", buf);
-		    else
-		      fputs (buf, stderr);
-
-		    free (buf);
-		  }
-#else
-		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
-			 argv[0], c);
-#endif
-	      }
-	    optopt = c;
-	    if (optstring[0] == ':')
-	      c = ':';
-	    else
-	      c = '?';
-	    return c;
-	  }
-	else
-	  /* We already incremented `optind' once;
-	     increment it again when taking next ARGV-elt as argument.  */
-	  optarg = argv[optind++];
-
-	/* optarg is now the argument, see if it's in the
-	   table of longopts.  */
-
-	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
-	  /* Do nothing.  */ ;
-
-	/* Test all long options for either exact match
-	   or abbreviated matches.  */
-	for (p = longopts, option_index = 0; p->name; p++, option_index++)
-	  if (!strncmp (p->name, nextchar, nameend - nextchar))
-	    {
-	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
-		{
-		  /* Exact match found.  */
-		  pfound = p;
-		  indfound = option_index;
-		  exact = 1;
-		  break;
-		}
-	      else if (pfound == NULL)
-		{
-		  /* First nonexact match found.  */
-		  pfound = p;
-		  indfound = option_index;
-		}
-	      else
-		/* Second or later nonexact match found.  */
-		ambig = 1;
-	    }
-	if (ambig && !exact)
-	  {
-	    if (print_errors)
-	      {
-#if defined _LIBC && defined USE_IN_LIBIO
-		char *buf;
-
-		if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
-				argv[0], argv[optind]) >= 0)
-		  {
-		    if (_IO_fwide (stderr, 0) > 0)
-		      __fwprintf (stderr, L"%s", buf);
-		    else
-		      fputs (buf, stderr);
-
-		    free (buf);
-		  }
-#else
-		fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
-			 argv[0], argv[optind]);
-#endif
-	      }
-	    nextchar += strlen (nextchar);
-	    optind++;
-	    return '?';
-	  }
-	if (pfound != NULL)
-	  {
-	    option_index = indfound;
-	    if (*nameend)
-	      {
-		/* Don't test has_arg with >, because some C compilers don't
-		   allow it to be used on enums.  */
-		if (pfound->has_arg)
-		  optarg = nameend + 1;
-		else
-		  {
-		    if (print_errors)
-		      {
-#if defined _LIBC && defined USE_IN_LIBIO
-			char *buf;
-
-			if (__asprintf (&buf, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
-					argv[0], pfound->name) >= 0)
-			  {
-			    if (_IO_fwide (stderr, 0) > 0)
-			      __fwprintf (stderr, L"%s", buf);
-			    else
-			      fputs (buf, stderr);
-
-			    free (buf);
-			  }
-#else
-			fprintf (stderr, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
-				 argv[0], pfound->name);
-#endif
-		      }
-
-		    nextchar += strlen (nextchar);
-		    return '?';
-		  }
-	      }
-	    else if (pfound->has_arg == 1)
-	      {
-		if (optind < argc)
-		  optarg = argv[optind++];
-		else
-		  {
-		    if (print_errors)
-		      {
-#if defined _LIBC && defined USE_IN_LIBIO
-			char *buf;
-
-			if (__asprintf (&buf, _("\
-%s: option `%s' requires an argument\n"),
-					argv[0], argv[optind - 1]) >= 0)
-			  {
-			    if (_IO_fwide (stderr, 0) > 0)
-			      __fwprintf (stderr, L"%s", buf);
-			    else
-			      fputs (buf, stderr);
-
-			    free (buf);
-			  }
-#else
-			fprintf (stderr,
-				 _("%s: option `%s' requires an argument\n"),
-				 argv[0], argv[optind - 1]);
-#endif
-		      }
-		    nextchar += strlen (nextchar);
-		    return optstring[0] == ':' ? ':' : '?';
-		  }
-	      }
-	    nextchar += strlen (nextchar);
-	    if (longind != NULL)
-	      *longind = option_index;
-	    if (pfound->flag)
-	      {
-		*(pfound->flag) = pfound->val;
-		return 0;
-	      }
-	    return pfound->val;
-	  }
-	  nextchar = NULL;
-	  return 'W';	/* Let the application handle it.   */
-      }
-    if (temp[1] == ':')
-      {
-	if (temp[2] == ':')
-	  {
-	    /* This is an option that accepts an argument optionally.  */
-	    if (*nextchar != '\0')
-	      {
-		optarg = nextchar;
-		optind++;
-	      }
-	    else
-	      optarg = NULL;
-	    nextchar = NULL;
-	  }
-	else
-	  {
-	    /* This is an option that requires an argument.  */
-	    if (*nextchar != '\0')
-	      {
-		optarg = nextchar;
-		/* If we end this ARGV-element by taking the rest as an arg,
-		   we must advance to the next element now.  */
-		optind++;
-	      }
-	    else if (optind == argc)
-	      {
-		if (print_errors)
-		  {
-		    /* 1003.2 specifies the format of this message.  */
-#if defined _LIBC && defined USE_IN_LIBIO
-		    char *buf;
-
-		    if (__asprintf (&buf, _("\
-%s: option requires an argument -- %c\n"),
-				    argv[0], c) >= 0)
-		      {
-			if (_IO_fwide (stderr, 0) > 0)
-			  __fwprintf (stderr, L"%s", buf);
-			else
-			  fputs (buf, stderr);
-
-			free (buf);
-		      }
-#else
-		    fprintf (stderr,
-			     _("%s: option requires an argument -- %c\n"),
-			     argv[0], c);
-#endif
-		  }
-		optopt = c;
-		if (optstring[0] == ':')
-		  c = ':';
-		else
-		  c = '?';
-	      }
-	    else
-	      /* We already incremented `optind' once;
-		 increment it again when taking next ARGV-elt as argument.  */
-	      optarg = argv[optind++];
-	    nextchar = NULL;
-	  }
-      }
-    return c;
-  }
-}
-
-int
-getopt (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-{
-  return _getopt_internal (argc, argv, optstring,
-			   (const struct option *) 0,
-			   (int *) 0,
-			   0);
-}
-
-#endif	/* Not ELIDE_CODE.  */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
-   the above definition of `getopt'.  */
-
-int
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-
-      c = getopt (argc, argv, "abc:d:0123456789");
-      if (c == -1)
-	break;
-
-      switch (c)
-	{
-	case '0':
-	case '1':
-	case '2':
-	case '3':
-	case '4':
-	case '5':
-	case '6':
-	case '7':
-	case '8':
-	case '9':
-	  if (digit_optind != 0 && digit_optind != this_option_optind)
-	    printf ("digits occur in two different argv-elements.\n");
-	  digit_optind = this_option_optind;
-	  printf ("option %c\n", c);
-	  break;
-
-	case 'a':
-	  printf ("option a\n");
-	  break;
-
-	case 'b':
-	  printf ("option b\n");
-	  break;
-
-	case 'c':
-	  printf ("option c with value `%s'\n", optarg);
-	  break;
-
-	case '?':
-	  break;
-
-	default:
-	  printf ("?? getopt returned character code 0%o ??\n", c);
-	}
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-	printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
-}
-
-#endif /* TEST */
diff --git a/sm5/posix/getopt.h b/sm5/posix/getopt.h
deleted file mode 100644
index 4283c35b168acb3a4a4770cd6f646797478128ab..0000000000000000000000000000000000000000
--- a/sm5/posix/getopt.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* Declarations for getopt.
-   Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifndef _GETOPT_H
-
-#ifndef __need_getopt
-# define _GETOPT_H 1
-#endif
-
-/* If __GNU_LIBRARY__ is not already defined, either we are being used
-   standalone, or this is the first header included in the source file.
-   If we are being used with glibc, we need to include <features.h>, but
-   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
-   not defined, include <ctype.h>, which will pull in <features.h> for us
-   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
-   doesn't flood the namespace with stuff the way some other headers do.)  */
-#if !defined __GNU_LIBRARY__
-# include <ctype.h>
-#endif
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns -1, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
-   for unrecognized options.  */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized.  */
-
-extern int optopt;
-
-#ifndef __need_getopt
-/* Describe the long-named options requested by the application.
-   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
-   of `struct option' terminated by an element containing a name which is
-   zero.
-
-   The field `has_arg' is:
-   no_argument		(or 0) if the option does not take an argument,
-   required_argument	(or 1) if the option requires an argument,
-   optional_argument 	(or 2) if the option takes an optional argument.
-
-   If the field `flag' is not NULL, it points to a variable that is set
-   to the value given in the field `val' when the option is found, but
-   left unchanged if the option is not found.
-
-   To have a long-named option do something other than set an `int' to
-   a compiled-in constant, such as set a value from `optarg', set the
-   option's `flag' field to zero and its `val' field to a nonzero
-   value (the equivalent single-letter option character, if there is
-   one).  For long options that have a zero `flag' field, `getopt'
-   returns the contents of the `val' field.  */
-
-struct option
-{
-# if (defined __STDC__ && __STDC__) || defined __cplusplus
-  const char *name;
-# else
-  char *name;
-# endif
-  /* has_arg can't be an enum because some compilers complain about
-     type mismatches in all the code that assumes it is an int.  */
-  int has_arg;
-  int *flag;
-  int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'.  */
-
-# define no_argument		0
-# define required_argument	1
-# define optional_argument	2
-#endif	/* need getopt */
-
-
-/* Get definitions and prototypes for functions to process the
-   arguments in ARGV (ARGC of them, minus the program name) for
-   options given in OPTS.
-
-   Return the option character from OPTS just read.  Return -1 when
-   there are no more options.  For unrecognized options, or options
-   missing arguments, `optopt' is set to the option letter, and '?' is
-   returned.
-
-   The OPTS string is a list of characters which are recognized option
-   letters, optionally followed by colons, specifying that that letter
-   takes an argument, to be placed in `optarg'.
-
-   If a letter in OPTS is followed by two colons, its argument is
-   optional.  This behavior is specific to the GNU `getopt'.
-
-   The argument `--' causes premature termination of argument
-   scanning, explicitly telling `getopt' that there are no more
-   options.
-
-   If OPTS begins with `--', then non-option arguments are treated as
-   arguments to the option '\0'.  This behavior is specific to the GNU
-   `getopt'.  */
-
-#if (defined __STDC__ && __STDC__) || defined __cplusplus
-# ifdef __GNU_LIBRARY__
-/* Many other libraries have conflicting prototypes for getopt, with
-   differences in the consts, in stdlib.h.  To avoid compilation
-   errors, only prototype getopt for the GNU C library.  */
-extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
-# else /* not __GNU_LIBRARY__ */
-extern int getopt ();
-# endif /* __GNU_LIBRARY__ */
-
-# ifndef __need_getopt
-extern int getopt_long (int ___argc, char *const *___argv,
-			const char *__shortopts,
-		        const struct option *__longopts, int *__longind);
-extern int getopt_long_only (int ___argc, char *const *___argv,
-			     const char *__shortopts,
-		             const struct option *__longopts, int *__longind);
-
-/* Internal only.  Users should not call this directly.  */
-extern int _getopt_internal (int ___argc, char *const *___argv,
-			     const char *__shortopts,
-		             const struct option *__longopts, int *__longind,
-			     int __long_only);
-# endif
-#else /* not __STDC__ */
-extern int getopt ();
-# ifndef __need_getopt
-extern int getopt_long ();
-extern int getopt_long_only ();
-
-extern int _getopt_internal ();
-# endif
-#endif /* __STDC__ */
-
-#ifdef	__cplusplus
-}
-#endif
-
-/* Make sure we later can get all the definitions and declarations.  */
-#undef __need_getopt
-
-#endif /* getopt.h */
diff --git a/sm5/posix/getopt1.c b/sm5/posix/getopt1.c
deleted file mode 100644
index ad06cc7f9e84b3ee030c454f85805dbd290e06cf..0000000000000000000000000000000000000000
--- a/sm5/posix/getopt1.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
-   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
-     Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef _LIBC
-# include <getopt.h>
-#else
-# include "getopt.h"
-#endif
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
-   reject `defined (const)'.  */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#endif
-
-#ifndef	NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct option *long_options;
-     int *opt_index;
-{
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
-   If an option that starts with '-' (not '--') doesn't match a long option,
-   but does match a short option, it is parsed as a short option
-   instead.  */
-
-int
-getopt_long_only (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct option *long_options;
-     int *opt_index;
-{
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
-}
-
-# ifdef _LIBC
-libc_hidden_def (getopt_long)
-libc_hidden_def (getopt_long_only)
-# endif
-
-#endif	/* Not ELIDE_CODE.  */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-      int option_index = 0;
-      static struct option long_options[] =
-      {
-	{"add", 1, 0, 0},
-	{"append", 0, 0, 0},
-	{"delete", 1, 0, 0},
-	{"verbose", 0, 0, 0},
-	{"create", 0, 0, 0},
-	{"file", 1, 0, 0},
-	{0, 0, 0, 0}
-      };
-
-      c = getopt_long (argc, argv, "abc:d:0123456789",
-		       long_options, &option_index);
-      if (c == -1)
-	break;
-
-      switch (c)
-	{
-	case 0:
-	  printf ("option %s", long_options[option_index].name);
-	  if (optarg)
-	    printf (" with arg %s", optarg);
-	  printf ("\n");
-	  break;
-
-	case '0':
-	case '1':
-	case '2':
-	case '3':
-	case '4':
-	case '5':
-	case '6':
-	case '7':
-	case '8':
-	case '9':
-	  if (digit_optind != 0 && digit_optind != this_option_optind)
-	    printf ("digits occur in two different argv-elements.\n");
-	  digit_optind = this_option_optind;
-	  printf ("option %c\n", c);
-	  break;
-
-	case 'a':
-	  printf ("option a\n");
-	  break;
-
-	case 'b':
-	  printf ("option b\n");
-	  break;
-
-	case 'c':
-	  printf ("option c with value `%s'\n", optarg);
-	  break;
-
-	case 'd':
-	  printf ("option d with value `%s'\n", optarg);
-	  break;
-
-	case '?':
-	  break;
-
-	default:
-	  printf ("?? getopt returned character code 0%o ??\n", c);
-	}
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-	printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
-}
-
-#endif /* TEST */
diff --git a/sm5/posix/regcomp.c b/sm5/posix/regcomp.c
deleted file mode 100644
index f25ecae5fd7a966d0c7235cb7410680e43cca59b..0000000000000000000000000000000000000000
--- a/sm5/posix/regcomp.c
+++ /dev/null
@@ -1,3544 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
-					  int length, reg_syntax_t syntax);
-static void re_compile_fastmap_iter (regex_t *bufp,
-				     const re_dfastate_t *init_state,
-				     char *fastmap);
-static reg_errcode_t init_dfa (re_dfa_t *dfa, int pat_len);
-static reg_errcode_t init_word_char (re_dfa_t *dfa);
-#ifdef RE_ENABLE_I18N
-static void free_charset (re_charset_t *cset);
-#endif /* RE_ENABLE_I18N */
-static void free_workarea_compile (regex_t *preg);
-static reg_errcode_t create_initial_state (re_dfa_t *dfa);
-static reg_errcode_t analyze (re_dfa_t *dfa);
-static reg_errcode_t analyze_tree (re_dfa_t *dfa, bin_tree_t *node);
-static void calc_first (re_dfa_t *dfa, bin_tree_t *node);
-static void calc_next (re_dfa_t *dfa, bin_tree_t *node);
-static void calc_epsdest (re_dfa_t *dfa, bin_tree_t *node);
-static reg_errcode_t duplicate_node_closure (re_dfa_t *dfa, int top_org_node,
-					     int top_clone_node, int root_node,
-					     unsigned int constraint);
-static reg_errcode_t duplicate_node (int *new_idx, re_dfa_t *dfa, int org_idx,
-				     unsigned int constraint);
-static int search_duplicated_node (re_dfa_t *dfa, int org_node,
-				   unsigned int constraint);
-static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
-static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
-					 int node, int root);
-static void calc_inveclosure (re_dfa_t *dfa);
-static int fetch_number (re_string_t *input, re_token_t *token,
-			 reg_syntax_t syntax);
-static re_token_t fetch_token (re_string_t *input, reg_syntax_t syntax);
-static int peek_token (re_token_t *token, re_string_t *input,
-			reg_syntax_t syntax);
-static int peek_token_bracket (re_token_t *token, re_string_t *input,
-			       reg_syntax_t syntax);
-static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
-			  reg_syntax_t syntax, reg_errcode_t *err);
-static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
-				  re_token_t *token, reg_syntax_t syntax,
-				  int nest, reg_errcode_t *err);
-static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
-				 re_token_t *token, reg_syntax_t syntax,
-				 int nest, reg_errcode_t *err);
-static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
-				     re_token_t *token, reg_syntax_t syntax,
-				     int nest, reg_errcode_t *err);
-static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
-				  re_token_t *token, reg_syntax_t syntax,
-				  int nest, reg_errcode_t *err);
-static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
-				 re_dfa_t *dfa, re_token_t *token,
-				 reg_syntax_t syntax, reg_errcode_t *err);
-static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,
-				      re_token_t *token, reg_syntax_t syntax,
-				      reg_errcode_t *err);
-static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
-					    re_string_t *regexp,
-					    re_token_t *token, int token_len,
-					    re_dfa_t *dfa,
-					    reg_syntax_t syntax);
-static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
-					  re_string_t *regexp,
-					  re_token_t *token);
-#ifndef _LIBC
-# ifdef RE_ENABLE_I18N
-static reg_errcode_t build_range_exp (re_bitset_ptr_t sbcset,
-				      re_charset_t *mbcset, int *range_alloc,
-				      bracket_elem_t *start_elem,
-				      bracket_elem_t *end_elem);
-static reg_errcode_t build_collating_symbol (re_bitset_ptr_t sbcset,
-					     re_charset_t *mbcset,
-					     int *coll_sym_alloc,
-					     const unsigned char *name);
-# else /* not RE_ENABLE_I18N */
-static reg_errcode_t build_range_exp (re_bitset_ptr_t sbcset,
-				      bracket_elem_t *start_elem,
-				      bracket_elem_t *end_elem);
-static reg_errcode_t build_collating_symbol (re_bitset_ptr_t sbcset,
-					     const unsigned char *name);
-# endif /* not RE_ENABLE_I18N */
-#endif /* not _LIBC */
-#ifdef RE_ENABLE_I18N
-static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,
-					re_charset_t *mbcset,
-					int *equiv_class_alloc,
-					const unsigned char *name);
-static reg_errcode_t build_charclass (re_bitset_ptr_t sbcset,
-				      re_charset_t *mbcset,
-				      int *char_class_alloc,
-				      const unsigned char *class_name,
-				      reg_syntax_t syntax);
-#else  /* not RE_ENABLE_I18N */
-static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,
-					const unsigned char *name);
-static reg_errcode_t build_charclass (re_bitset_ptr_t sbcset,
-				      const unsigned char *class_name,
-				      reg_syntax_t syntax);
-#endif /* not RE_ENABLE_I18N */
-static bin_tree_t *build_word_op (re_dfa_t *dfa, int not, reg_errcode_t *err);
-static void free_bin_tree (bin_tree_t *tree);
-static bin_tree_t *create_tree (bin_tree_t *left, bin_tree_t *right,
-				re_token_type_t type, int index);
-static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
-
-/* This table gives an error message for each of the error codes listed
-   in regex.h.  Obviously the order here has to be same as there.
-   POSIX doesn't require that we do anything for REG_NOERROR,
-   but why not be nice?  */
-
-const char __re_error_msgid[] attribute_hidden =
-  {
-#define REG_NOERROR_IDX	0
-    gettext_noop ("Success")	/* REG_NOERROR */
-    "\0"
-#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
-    gettext_noop ("No match")	/* REG_NOMATCH */
-    "\0"
-#define REG_BADPAT_IDX	(REG_NOMATCH_IDX + sizeof "No match")
-    gettext_noop ("Invalid regular expression") /* REG_BADPAT */
-    "\0"
-#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
-    gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
-    "\0"
-#define REG_ECTYPE_IDX	(REG_ECOLLATE_IDX + sizeof "Invalid collation character")
-    gettext_noop ("Invalid character class name") /* REG_ECTYPE */
-    "\0"
-#define REG_EESCAPE_IDX	(REG_ECTYPE_IDX + sizeof "Invalid character class name")
-    gettext_noop ("Trailing backslash") /* REG_EESCAPE */
-    "\0"
-#define REG_ESUBREG_IDX	(REG_EESCAPE_IDX + sizeof "Trailing backslash")
-    gettext_noop ("Invalid back reference") /* REG_ESUBREG */
-    "\0"
-#define REG_EBRACK_IDX	(REG_ESUBREG_IDX + sizeof "Invalid back reference")
-    gettext_noop ("Unmatched [ or [^")	/* REG_EBRACK */
-    "\0"
-#define REG_EPAREN_IDX	(REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
-    gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
-    "\0"
-#define REG_EBRACE_IDX	(REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
-    gettext_noop ("Unmatched \\{") /* REG_EBRACE */
-    "\0"
-#define REG_BADBR_IDX	(REG_EBRACE_IDX + sizeof "Unmatched \\{")
-    gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
-    "\0"
-#define REG_ERANGE_IDX	(REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
-    gettext_noop ("Invalid range end")	/* REG_ERANGE */
-    "\0"
-#define REG_ESPACE_IDX	(REG_ERANGE_IDX + sizeof "Invalid range end")
-    gettext_noop ("Memory exhausted") /* REG_ESPACE */
-    "\0"
-#define REG_BADRPT_IDX	(REG_ESPACE_IDX + sizeof "Memory exhausted")
-    gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
-    "\0"
-#define REG_EEND_IDX	(REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
-    gettext_noop ("Premature end of regular expression") /* REG_EEND */
-    "\0"
-#define REG_ESIZE_IDX	(REG_EEND_IDX + sizeof "Premature end of regular expression")
-    gettext_noop ("Regular expression too big") /* REG_ESIZE */
-    "\0"
-#define REG_ERPAREN_IDX	(REG_ESIZE_IDX + sizeof "Regular expression too big")
-    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
-  };
-
-const size_t __re_error_msgid_idx[] attribute_hidden =
-  {
-    REG_NOERROR_IDX,
-    REG_NOMATCH_IDX,
-    REG_BADPAT_IDX,
-    REG_ECOLLATE_IDX,
-    REG_ECTYPE_IDX,
-    REG_EESCAPE_IDX,
-    REG_ESUBREG_IDX,
-    REG_EBRACK_IDX,
-    REG_EPAREN_IDX,
-    REG_EBRACE_IDX,
-    REG_BADBR_IDX,
-    REG_ERANGE_IDX,
-    REG_ESPACE_IDX,
-    REG_BADRPT_IDX,
-    REG_EEND_IDX,
-    REG_ESIZE_IDX,
-    REG_ERPAREN_IDX
-  };
-
-/* Entry points for GNU code.  */
-
-/* re_compile_pattern is the GNU regular expression compiler: it
-   compiles PATTERN (of length LENGTH) and puts the result in BUFP.
-   Returns 0 if the pattern was valid, otherwise an error string.
-
-   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
-   are set in BUFP on entry.  */
-
-const char *
-re_compile_pattern (pattern, length, bufp)
-    const char *pattern;
-    size_t length;
-    struct re_pattern_buffer *bufp;
-{
-  reg_errcode_t ret;
-
-  /* And GNU code determines whether or not to get register information
-     by passing null for the REGS argument to re_match, etc., not by
-     setting no_sub.  */
-  bufp->no_sub = 0;
-
-  /* Match anchors at newline.  */
-  bufp->newline_anchor = 1;
-
-  ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
-
-  if (!ret)
-    return NULL;
-  return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
-}
-#ifdef _LIBC
-weak_alias (__re_compile_pattern, re_compile_pattern)
-#endif
-
-/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
-   also be assigned to arbitrarily: each pattern buffer stores its own
-   syntax, so it can be changed between regex compilations.  */
-/* This has no initializer because initialized variables in Emacs
-   become read-only after dumping.  */
-reg_syntax_t re_syntax_options;
-
-
-/* Specify the precise syntax of regexps for compilation.  This provides
-   for compatibility for various utilities which historically have
-   different, incompatible syntaxes.
-
-   The argument SYNTAX is a bit mask comprised of the various bits
-   defined in regex.h.  We return the old syntax.  */
-
-reg_syntax_t
-re_set_syntax (syntax)
-    reg_syntax_t syntax;
-{
-  reg_syntax_t ret = re_syntax_options;
-
-  re_syntax_options = syntax;
-  return ret;
-}
-#ifdef _LIBC
-weak_alias (__re_set_syntax, re_set_syntax)
-#endif
-
-int
-re_compile_fastmap (bufp)
-    struct re_pattern_buffer *bufp;
-{
-  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
-  char *fastmap = bufp->fastmap;
-
-  memset (fastmap, '\0', sizeof (char) * SBC_MAX);
-  re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
-  if (dfa->init_state != dfa->init_state_word)
-    re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);
-  if (dfa->init_state != dfa->init_state_nl)
-    re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
-  if (dfa->init_state != dfa->init_state_begbuf)
-    re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
-  bufp->fastmap_accurate = 1;
-  return 0;
-}
-#ifdef _LIBC
-weak_alias (__re_compile_fastmap, re_compile_fastmap)
-#endif
-
-static inline void
-re_set_fastmap (char *fastmap, int icase, int ch)
-{
-  fastmap[ch] = 1;
-  if (icase)
-    fastmap[tolower (ch)] = 1;
-}
-
-/* Helper function for re_compile_fastmap.
-   Compile fastmap for the initial_state INIT_STATE.  */
-
-static void
-re_compile_fastmap_iter (bufp, init_state, fastmap)
-     regex_t *bufp;
-     const re_dfastate_t *init_state;
-     char *fastmap;
-{
-  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
-  int node_cnt;
-  int icase = (MB_CUR_MAX == 1 && (bufp->syntax & RE_ICASE));
-  for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
-    {
-      int node = init_state->nodes.elems[node_cnt];
-      re_token_type_t type = dfa->nodes[node].type;
-
-      if (type == CHARACTER)
-	re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
-      else if (type == SIMPLE_BRACKET)
-	{
-	  int i, j, ch;
-	  for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
-	    for (j = 0; j < UINT_BITS; ++j, ++ch)
-	      if (dfa->nodes[node].opr.sbcset[i] & (1 << j))
-		re_set_fastmap (fastmap, icase, ch);
-	}
-#ifdef RE_ENABLE_I18N
-      else if (type == COMPLEX_BRACKET)
-	{
-	  int i;
-	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
-	  if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes
-	      || cset->nranges || cset->nchar_classes)
-	    {
-# ifdef _LIBC
-	      if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0)
-		{
-		  /* In this case we want to catch the bytes which are
-		     the first byte of any collation elements.
-		     e.g. In da_DK, we want to catch 'a' since "aa"
-			  is a valid collation element, and don't catch
-			  'b' since 'b' is the only collation element
-			  which starts from 'b'.  */
-		  int j, ch;
-		  const int32_t *table = (const int32_t *)
-		    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-		  for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
-		    for (j = 0; j < UINT_BITS; ++j, ++ch)
-		      if (table[ch] < 0)
-			re_set_fastmap (fastmap, icase, ch);
-		}
-# else
-	      if (MB_CUR_MAX > 1)
-		for (i = 0; i < SBC_MAX; ++i)
-		  if (__btowc (i) == WEOF)
-		    re_set_fastmap (fastmap, icase, i);
-# endif /* not _LIBC */
-	    }
-	  for (i = 0; i < cset->nmbchars; ++i)
-	    {
-	      char buf[256];
-	      mbstate_t state;
-	      memset (&state, '\0', sizeof (state));
-	      __wcrtomb (buf, cset->mbchars[i], &state);
-	      re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
-	    }
-	}
-#endif /* RE_ENABLE_I18N */
-      else if (type == END_OF_RE || type == OP_PERIOD)
-	{
-	  memset (fastmap, '\1', sizeof (char) * SBC_MAX);
-	  if (type == END_OF_RE)
-	    bufp->can_be_null = 1;
-	  return;
-	}
-    }
-}
-
-/* Entry point for POSIX code.  */
-/* regcomp takes a regular expression as a string and compiles it.
-
-   PREG is a regex_t *.  We do not expect any fields to be initialized,
-   since POSIX says we shouldn't.  Thus, we set
-
-     `buffer' to the compiled pattern;
-     `used' to the length of the compiled pattern;
-     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
-       REG_EXTENDED bit in CFLAGS is set; otherwise, to
-       RE_SYNTAX_POSIX_BASIC;
-     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
-     `fastmap' to an allocated space for the fastmap;
-     `fastmap_accurate' to zero;
-     `re_nsub' to the number of subexpressions in PATTERN.
-
-   PATTERN is the address of the pattern string.
-
-   CFLAGS is a series of bits which affect compilation.
-
-     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
-     use POSIX basic syntax.
-
-     If REG_NEWLINE is set, then . and [^...] don't match newline.
-     Also, regexec will try a match beginning after every newline.
-
-     If REG_ICASE is set, then we considers upper- and lowercase
-     versions of letters to be equivalent when matching.
-
-     If REG_NOSUB is set, then when PREG is passed to regexec, that
-     routine will report only success or failure, and nothing about the
-     registers.
-
-   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
-   the return codes and their meanings.)  */
-
-int
-regcomp (preg, pattern, cflags)
-    regex_t *__restrict preg;
-    const char *__restrict pattern;
-    int cflags;
-{
-  reg_errcode_t ret;
-  reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
-			 : RE_SYNTAX_POSIX_BASIC);
-
-  preg->buffer = NULL;
-  preg->allocated = 0;
-  preg->used = 0;
-
-  /* Try to allocate space for the fastmap.  */
-  preg->fastmap = re_malloc (char, SBC_MAX);
-  if (BE (preg->fastmap == NULL, 0))
-    return REG_ESPACE;
-
-  syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
-
-  /* If REG_NEWLINE is set, newlines are treated differently.  */
-  if (cflags & REG_NEWLINE)
-    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
-      syntax &= ~RE_DOT_NEWLINE;
-      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
-      /* It also changes the matching behavior.  */
-      preg->newline_anchor = 1;
-    }
-  else
-    preg->newline_anchor = 0;
-  preg->no_sub = !!(cflags & REG_NOSUB);
-  preg->translate = NULL;
-
-  ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
-
-  /* POSIX doesn't distinguish between an unmatched open-group and an
-     unmatched close-group: both are REG_EPAREN.  */
-  if (ret == REG_ERPAREN)
-    ret = REG_EPAREN;
-
-  /* We have already checked preg->fastmap != NULL.  */
-  if (BE (ret == REG_NOERROR, 1))
-    /* Compute the fastmap now, since regexec cannot modify the pattern
-       buffer.  This function nevers fails in this implementation.  */
-    (void) re_compile_fastmap (preg);
-  else
-    {
-      /* Some error occurred while compiling the expression.  */
-      re_free (preg->fastmap);
-      preg->fastmap = NULL;
-    }
-
-  return (int) ret;
-}
-#ifdef _LIBC
-weak_alias (__regcomp, regcomp)
-#endif
-
-/* Returns a message corresponding to an error code, ERRCODE, returned
-   from either regcomp or regexec.   We don't use PREG here.  */
-
-size_t
-regerror (errcode, preg, errbuf, errbuf_size)
-    int errcode;
-    const regex_t *preg;
-    char *errbuf;
-    size_t errbuf_size;
-{
-  const char *msg;
-  size_t msg_size;
-
-  if (BE (errcode < 0
-	  || errcode >= (int) (sizeof (__re_error_msgid_idx)
-			       / sizeof (__re_error_msgid_idx[0])), 0))
-    /* Only error codes returned by the rest of the code should be passed
-       to this routine.  If we are given anything else, or if other regex
-       code generates an invalid error code, then the program has a bug.
-       Dump core so we can fix it.  */
-    abort ();
-
-  msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]);
-
-  msg_size = strlen (msg) + 1; /* Includes the null.  */
-
-  if (BE (errbuf_size != 0, 1))
-    {
-      if (BE (msg_size > errbuf_size, 0))
-	{
-#if defined HAVE_MEMPCPY || defined _LIBC
-	  *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
-#else
-	  memcpy (errbuf, msg, errbuf_size - 1);
-	  errbuf[errbuf_size - 1] = 0;
-#endif
-	}
-      else
-	memcpy (errbuf, msg, msg_size);
-    }
-
-  return msg_size;
-}
-#ifdef _LIBC
-weak_alias (__regerror, regerror)
-#endif
-
-
-static void
-free_dfa_content (re_dfa_t *dfa)
-{
-  int i, j;
-
-  re_free (dfa->subexps);
-
-  for (i = 0; i < dfa->nodes_len; ++i)
-    {
-      re_token_t *node = dfa->nodes + i;
-#ifdef RE_ENABLE_I18N
-      if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
-	free_charset (node->opr.mbcset);
-      else
-#endif /* RE_ENABLE_I18N */
-	if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
-	  re_free (node->opr.sbcset);
-    }
-  re_free (dfa->nexts);
-  for (i = 0; i < dfa->nodes_len; ++i)
-    {
-      if (dfa->eclosures != NULL)
-	re_node_set_free (dfa->eclosures + i);
-      if (dfa->inveclosures != NULL)
-	re_node_set_free (dfa->inveclosures + i);
-      if (dfa->edests != NULL)
-	re_node_set_free (dfa->edests + i);
-    }
-  re_free (dfa->edests);
-  re_free (dfa->eclosures);
-  re_free (dfa->inveclosures);
-  re_free (dfa->nodes);
-
-  for (i = 0; i <= dfa->state_hash_mask; ++i)
-    {
-      struct re_state_table_entry *entry = dfa->state_table + i;
-      for (j = 0; j < entry->num; ++j)
-	{
-	  re_dfastate_t *state = entry->array[j];
-	  free_state (state);
-	}
-      re_free (entry->array);
-    }
-  re_free (dfa->state_table);
-
-  if (dfa->word_char != NULL)
-    re_free (dfa->word_char);
-#ifdef DEBUG
-  re_free (dfa->re_str);
-#endif
-
-  re_free (dfa);
-}
-
-
-/* Free dynamically allocated space used by PREG.  */
-
-void
-regfree (preg)
-    regex_t *preg;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  if (BE (dfa != NULL, 1))
-    free_dfa_content (dfa);
-
-  re_free (preg->fastmap);
-}
-#ifdef _LIBC
-weak_alias (__regfree, regfree)
-#endif
-
-/* Entry points compatible with 4.2 BSD regex library.  We don't define
-   them unless specifically requested.  */
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-
-/* BSD has one and only one pattern buffer.  */
-static struct re_pattern_buffer re_comp_buf;
-
-char *
-# ifdef _LIBC
-/* Make these definitions weak in libc, so POSIX programs can redefine
-   these names if they don't use our functions, and still use
-   regcomp/regexec above without link errors.  */
-weak_function
-# endif
-re_comp (s)
-     const char *s;
-{
-  reg_errcode_t ret;
-  char *fastmap;
-
-  if (!s)
-    {
-      if (!re_comp_buf.buffer)
-	return gettext ("No previous regular expression");
-      return 0;
-    }
-
-  if (re_comp_buf.buffer)
-    {
-      fastmap = re_comp_buf.fastmap;
-      re_comp_buf.fastmap = NULL;
-      __regfree (&re_comp_buf);
-      memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
-      re_comp_buf.fastmap = fastmap;
-    }
-
-  if (re_comp_buf.fastmap == NULL)
-    {
-      re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
-      if (re_comp_buf.fastmap == NULL)
-	return (char *) gettext (__re_error_msgid
-				 + __re_error_msgid_idx[(int) REG_ESPACE]);
-    }
-
-  /* Since `re_exec' always passes NULL for the `regs' argument, we
-     don't need to initialize the pattern buffer fields which affect it.  */
-
-  /* Match anchors at newlines.  */
-  re_comp_buf.newline_anchor = 1;
-
-  ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
-
-  if (!ret)
-    return NULL;
-
-  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
-  return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
-}
-
-#ifdef _LIBC
-libc_freeres_fn (free_mem)
-{
-  __regfree (&re_comp_buf);
-}
-#endif
-
-#endif /* _REGEX_RE_COMP */
-
-/* Internal entry point.
-   Compile the regular expression PATTERN, whose length is LENGTH.
-   SYNTAX indicate regular expression's syntax.  */
-
-static reg_errcode_t
-re_compile_internal (preg, pattern, length, syntax)
-     regex_t *preg;
-     const char * pattern;
-     int length;
-     reg_syntax_t syntax;
-{
-  reg_errcode_t err = REG_NOERROR;
-  re_dfa_t *dfa;
-  re_string_t regexp;
-
-  /* Initialize the pattern buffer.  */
-  preg->fastmap_accurate = 0;
-  preg->syntax = syntax;
-  preg->not_bol = preg->not_eol = 0;
-  preg->used = 0;
-  preg->re_nsub = 0;
-  preg->can_be_null = 0;
-  preg->regs_allocated = REGS_UNALLOCATED;
-
-  /* Initialize the dfa.  */
-  dfa = (re_dfa_t *) preg->buffer;
-  if (preg->allocated < sizeof (re_dfa_t))
-    {
-      /* If zero allocated, but buffer is non-null, try to realloc
-	 enough space.  This loses if buffer's address is bogus, but
-	 that is the user's responsibility.  If ->buffer is NULL this
-	 is a simple allocation.  */
-      dfa = re_realloc (preg->buffer, re_dfa_t, 1);
-      if (dfa == NULL)
-	return REG_ESPACE;
-      preg->allocated = sizeof (re_dfa_t);
-    }
-  preg->buffer = (unsigned char *) dfa;
-  preg->used = sizeof (re_dfa_t);
-
-  err = init_dfa (dfa, length);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      re_free (dfa);
-      preg->buffer = NULL;
-      preg->allocated = 0;
-      return err;
-    }
-#ifdef DEBUG
-  dfa->re_str = re_malloc (char, length + 1);
-  strncpy (dfa->re_str, pattern, length + 1);
-#endif
-
-  err = re_string_construct (&regexp, pattern, length, preg->translate,
-			     syntax & RE_ICASE);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      re_free (dfa);
-      preg->buffer = NULL;
-      preg->allocated = 0;
-      return err;
-    }
-
-  /* Parse the regular expression, and build a structure tree.  */
-  preg->re_nsub = 0;
-  dfa->str_tree = parse (&regexp, preg, syntax, &err);
-  if (BE (dfa->str_tree == NULL, 0))
-    goto re_compile_internal_free_return;
-
-  /* Analyze the tree and collect information which is necessary to
-     create the dfa.  */
-  err = analyze (dfa);
-  if (BE (err != REG_NOERROR, 0))
-    goto re_compile_internal_free_return;
-
-  /* Then create the initial state of the dfa.  */
-  err = create_initial_state (dfa);
-
-  /* Release work areas.  */
-  free_workarea_compile (preg);
-  re_string_destruct (&regexp);
-
-  if (BE (err != REG_NOERROR, 0))
-    {
-    re_compile_internal_free_return:
-      free_dfa_content (dfa);
-      preg->buffer = NULL;
-      preg->allocated = 0;
-    }
-
-  return err;
-}
-
-/* Initialize DFA.  We use the length of the regular expression PAT_LEN
-   as the initial length of some arrays.  */
-
-static reg_errcode_t
-init_dfa (dfa, pat_len)
-     re_dfa_t *dfa;
-     int pat_len;
-{
-  int table_size;
-
-  memset (dfa, '\0', sizeof (re_dfa_t));
-
-  dfa->nodes_alloc = pat_len + 1;
-  dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
-
-  dfa->states_alloc = pat_len + 1;
-
-  /*  table_size = 2 ^ ceil(log pat_len) */
-  for (table_size = 1; table_size > 0; table_size <<= 1)
-    if (table_size > pat_len)
-      break;
-
-  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
-  dfa->state_hash_mask = table_size - 1;
-
-  dfa->subexps_alloc = 1;
-  dfa->subexps = re_malloc (re_subexp_t, dfa->subexps_alloc);
-  dfa->word_char = NULL;
-
-  if (BE (dfa->nodes == NULL || dfa->state_table == NULL
-	  || dfa->subexps == NULL, 0))
-    {
-      /* We don't bother to free anything which was allocated.  Very
-	 soon the process will go down anyway.  */
-      dfa->subexps = NULL;
-      dfa->state_table = NULL;
-      dfa->nodes = NULL;
-      return REG_ESPACE;
-    }
-  return REG_NOERROR;
-}
-
-/* Initialize WORD_CHAR table, which indicate which character is
-   "word".  In this case "word" means that it is the word construction
-   character used by some operators like "\<", "\>", etc.  */
-
-static reg_errcode_t
-init_word_char (dfa)
-     re_dfa_t *dfa;
-{
-  int i, j, ch;
-  dfa->word_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);
-  if (BE (dfa->word_char == NULL, 0))
-    return REG_ESPACE;
-  for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
-    for (j = 0; j < UINT_BITS; ++j, ++ch)
-      if (isalnum (ch) || ch == '_')
-	dfa->word_char[i] |= 1 << j;
-  return REG_NOERROR;
-}
-
-/* Free the work area which are only used while compiling.  */
-
-static void
-free_workarea_compile (preg)
-     regex_t *preg;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  free_bin_tree (dfa->str_tree);
-  dfa->str_tree = NULL;
-  re_free (dfa->org_indices);
-  dfa->org_indices = NULL;
-}
-
-/* Create initial states for all contexts.  */
-
-static reg_errcode_t
-create_initial_state (dfa)
-     re_dfa_t *dfa;
-{
-  int first, i;
-  reg_errcode_t err;
-  re_node_set init_nodes;
-
-  /* Initial states have the epsilon closure of the node which is
-     the first node of the regular expression.  */
-  first = dfa->str_tree->first;
-  dfa->init_node = first;
-  err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-
-  /* The back-references which are in initial states can epsilon transit,
-     since in this case all of the subexpressions can be null.
-     Then we add epsilon closures of the nodes which are the next nodes of
-     the back-references.  */
-  if (dfa->nbackref > 0)
-    for (i = 0; i < init_nodes.nelem; ++i)
-      {
-	int node_idx = init_nodes.elems[i];
-	re_token_type_t type = dfa->nodes[node_idx].type;
-
-	int clexp_idx;
-	if (type != OP_BACK_REF)
-	  continue;
-	for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
-	  {
-	    re_token_t *clexp_node;
-	    clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
-	    if (clexp_node->type == OP_CLOSE_SUBEXP
-		&& clexp_node->opr.idx + 1 == dfa->nodes[node_idx].opr.idx)
-	      break;
-	  }
-	if (clexp_idx == init_nodes.nelem)
-	  continue;
-
-	if (type == OP_BACK_REF)
-	  {
-	    int dest_idx = dfa->edests[node_idx].elems[0];
-	    if (!re_node_set_contains (&init_nodes, dest_idx))
-	      {
-		re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
-		i = 0;
-	      }
-	  }
-      }
-
-  /* It must be the first time to invoke acquire_state.  */
-  dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
-  /* We don't check ERR here, since the initial state must not be NULL.  */
-  if (BE (dfa->init_state == NULL, 0))
-    return err;
-  if (dfa->init_state->has_constraint)
-    {
-      dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
-						       CONTEXT_WORD);
-      dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,
-						     CONTEXT_NEWLINE);
-      dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,
-							 &init_nodes,
-							 CONTEXT_NEWLINE
-							 | CONTEXT_BEGBUF);
-      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-	      || dfa->init_state_begbuf == NULL, 0))
-	return err;
-    }
-  else
-    dfa->init_state_word = dfa->init_state_nl
-      = dfa->init_state_begbuf = dfa->init_state;
-
-  re_node_set_free (&init_nodes);
-  return REG_NOERROR;
-}
-
-/* Analyze the structure tree, and calculate "first", "next", "edest",
-   "eclosure", and "inveclosure".  */
-
-static reg_errcode_t
-analyze (dfa)
-     re_dfa_t *dfa;
-{
-  int i;
-  reg_errcode_t ret;
-
-  /* Allocate arrays.  */
-  dfa->nexts = re_malloc (int, dfa->nodes_alloc);
-  dfa->org_indices = re_malloc (int, dfa->nodes_alloc);
-  dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
-  dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
-	  || dfa->eclosures == NULL || dfa->inveclosures == NULL, 0))
-    return REG_ESPACE;
-  /* Initialize them.  */
-  for (i = 0; i < dfa->nodes_len; ++i)
-    {
-      dfa->nexts[i] = -1;
-      re_node_set_init_empty (dfa->edests + i);
-      re_node_set_init_empty (dfa->eclosures + i);
-      re_node_set_init_empty (dfa->inveclosures + i);
-    }
-
-  ret = analyze_tree (dfa, dfa->str_tree);
-  if (BE (ret == REG_NOERROR, 1))
-    {
-      ret = calc_eclosure (dfa);
-      if (ret == REG_NOERROR)
-	calc_inveclosure (dfa);
-    }
-  return ret;
-}
-
-/* Helper functions for analyze.
-   This function calculate "first", "next", and "edest" for the subtree
-   whose root is NODE.  */
-
-static reg_errcode_t
-analyze_tree (dfa, node)
-     re_dfa_t *dfa;
-     bin_tree_t *node;
-{
-  reg_errcode_t ret;
-  if (node->first == -1)
-    calc_first (dfa, node);
-  if (node->next == -1)
-    calc_next (dfa, node);
-  if (node->eclosure.nelem == 0)
-    calc_epsdest (dfa, node);
-  /* Calculate "first" etc. for the left child.  */
-  if (node->left != NULL)
-    {
-      ret = analyze_tree (dfa, node->left);
-      if (BE (ret != REG_NOERROR, 0))
-	return ret;
-    }
-  /* Calculate "first" etc. for the right child.  */
-  if (node->right != NULL)
-    {
-      ret = analyze_tree (dfa, node->right);
-      if (BE (ret != REG_NOERROR, 0))
-	return ret;
-    }
-  return REG_NOERROR;
-}
-
-/* Calculate "first" for the node NODE.  */
-static void
-calc_first (dfa, node)
-     re_dfa_t *dfa;
-     bin_tree_t *node;
-{
-  int idx, type;
-  idx = node->node_idx;
-  type = (node->type == 0) ? dfa->nodes[idx].type : node->type;
-
-  switch (type)
-    {
-#ifdef DEBUG
-    case OP_OPEN_BRACKET:
-    case OP_CLOSE_BRACKET:
-    case OP_OPEN_DUP_NUM:
-    case OP_CLOSE_DUP_NUM:
-    case OP_NON_MATCH_LIST:
-    case OP_OPEN_COLL_ELEM:
-    case OP_CLOSE_COLL_ELEM:
-    case OP_OPEN_EQUIV_CLASS:
-    case OP_CLOSE_EQUIV_CLASS:
-    case OP_OPEN_CHAR_CLASS:
-    case OP_CLOSE_CHAR_CLASS:
-      /* These must not be appeared here.  */
-      assert (0);
-#endif
-    case END_OF_RE:
-    case CHARACTER:
-    case OP_PERIOD:
-    case OP_DUP_ASTERISK:
-    case OP_DUP_QUESTION:
-#ifdef RE_ENABLE_I18N
-    case COMPLEX_BRACKET:
-#endif /* RE_ENABLE_I18N */
-    case SIMPLE_BRACKET:
-    case OP_BACK_REF:
-    case ANCHOR:
-    case OP_OPEN_SUBEXP:
-    case OP_CLOSE_SUBEXP:
-      node->first = idx;
-      break;
-    case OP_DUP_PLUS:
-#ifdef DEBUG
-      assert (node->left != NULL);
-#endif
-      if (node->left->first == -1)
-	calc_first (dfa, node->left);
-      node->first = node->left->first;
-      break;
-    case OP_ALT:
-      node->first = idx;
-      break;
-      /* else fall through */
-    default:
-#ifdef DEBUG
-      assert (node->left != NULL);
-#endif
-      if (node->left->first == -1)
-	calc_first (dfa, node->left);
-      node->first = node->left->first;
-      break;
-    }
-}
-
-/* Calculate "next" for the node NODE.  */
-
-static void
-calc_next (dfa, node)
-     re_dfa_t *dfa;
-     bin_tree_t *node;
-{
-  int idx, type;
-  bin_tree_t *parent = node->parent;
-  if (parent == NULL)
-    {
-      node->next = -1;
-      idx = node->node_idx;
-      if (node->type == 0)
-	dfa->nexts[idx] = node->next;
-      return;
-    }
-
-  idx = parent->node_idx;
-  type = (parent->type == 0) ? dfa->nodes[idx].type : parent->type;
-
-  switch (type)
-    {
-    case OP_DUP_ASTERISK:
-    case OP_DUP_PLUS:
-      node->next = idx;
-      break;
-    case CONCAT:
-      if (parent->left == node)
-	{
-	  if (parent->right->first == -1)
-	    calc_first (dfa, parent->right);
-	  node->next = parent->right->first;
-	  break;
-	}
-      /* else fall through */
-    default:
-      if (parent->next == -1)
-	calc_next (dfa, parent);
-      node->next = parent->next;
-      break;
-    }
-  idx = node->node_idx;
-  if (node->type == 0)
-    dfa->nexts[idx] = node->next;
-}
-
-/* Calculate "edest" for the node NODE.  */
-
-static void
-calc_epsdest (dfa, node)
-     re_dfa_t *dfa;
-     bin_tree_t *node;
-{
-  int idx;
-  idx = node->node_idx;
-  if (node->type == 0)
-    {
-      if (dfa->nodes[idx].type == OP_DUP_ASTERISK
-	  || dfa->nodes[idx].type == OP_DUP_PLUS
-	  || dfa->nodes[idx].type == OP_DUP_QUESTION)
-	{
-	  if (node->left->first == -1)
-	    calc_first (dfa, node->left);
-	  if (node->next == -1)
-	    calc_next (dfa, node);
-	  re_node_set_init_2 (dfa->edests + idx, node->left->first,
-			      node->next);
-	}
-      else if (dfa->nodes[idx].type == OP_ALT)
-	{
-	  int left, right;
-	  if (node->left != NULL)
-	    {
-	      if (node->left->first == -1)
-		calc_first (dfa, node->left);
-	      left = node->left->first;
-	    }
-	  else
-	    {
-	      if (node->next == -1)
-		calc_next (dfa, node);
-	      left = node->next;
-	    }
-	  if (node->right != NULL)
-	    {
-	      if (node->right->first == -1)
-		calc_first (dfa, node->right);
-	      right = node->right->first;
-	    }
-	  else
-	    {
-	      if (node->next == -1)
-		calc_next (dfa, node);
-	      right = node->next;
-	    }
-	  re_node_set_init_2 (dfa->edests + idx, left, right);
-	}
-      else if (dfa->nodes[idx].type == ANCHOR
-	       || dfa->nodes[idx].type == OP_OPEN_SUBEXP
-	       || dfa->nodes[idx].type == OP_CLOSE_SUBEXP
-	       || dfa->nodes[idx].type == OP_BACK_REF)
-	re_node_set_init_1 (dfa->edests + idx, node->next);
-    }
-}
-
-/* Duplicate the epsilon closure of the node ROOT_NODE.
-   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
-   to their own constraint.  */
-
-static reg_errcode_t
-duplicate_node_closure (dfa, top_org_node, top_clone_node, root_node,
-			init_constraint)
-     re_dfa_t *dfa;
-     int top_org_node, top_clone_node, root_node;
-     unsigned int init_constraint;
-{
-  reg_errcode_t err;
-  int org_node, clone_node, ret;
-  unsigned int constraint = init_constraint;
-  for (org_node = top_org_node, clone_node = top_clone_node;;)
-    {
-      int org_dest, clone_dest;
-      if (dfa->nodes[org_node].type == OP_BACK_REF)
-	{
-	  /* If the back reference epsilon-transit, its destination must
-	     also have the constraint.  Then duplicate the epsilon closure
-	     of the destination of the back reference, and store it in
-	     edests of the back reference.  */
-	  org_dest = dfa->nexts[org_node];
-	  re_node_set_empty (dfa->edests + clone_node);
-	  err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	  dfa->nexts[clone_node] = dfa->nexts[org_node];
-	  ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-	  if (BE (ret < 0, 0))
-	    return REG_ESPACE;
-	}
-      else if (dfa->edests[org_node].nelem == 0)
-	{
-	  /* In case of the node can't epsilon-transit, don't duplicate the
-	     destination and store the original destination as the
-	     destination of the node.  */
-	  dfa->nexts[clone_node] = dfa->nexts[org_node];
-	  break;
-	}
-      else if (dfa->edests[org_node].nelem == 1)
-	{
-	  /* In case of the node can epsilon-transit, and it has only one
-	     destination.  */
-	  org_dest = dfa->edests[org_node].elems[0];
-	  re_node_set_empty (dfa->edests + clone_node);
-	  if (dfa->nodes[org_node].type == ANCHOR)
-	    {
-	      /* In case of the node has another constraint, append it.  */
-	      if (org_node == root_node && clone_node != org_node)
-		{
-		  /* ...but if the node is root_node itself, it means the
-		     epsilon closure have a loop, then tie it to the
-		     destination of the root_node.  */
-		  ret = re_node_set_insert (dfa->edests + clone_node,
-					    org_dest);
-		  if (BE (ret < 0, 0))
-		    return REG_ESPACE;
-		  break;
-		}
-	      constraint |= dfa->nodes[org_node].opr.ctx_type;
-	    }
-	  err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	  ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-	  if (BE (ret < 0, 0))
-	    return REG_ESPACE;
-	}
-      else /* dfa->edests[org_node].nelem == 2 */
-	{
-	  /* In case of the node can epsilon-transit, and it has two
-	     destinations. E.g. '|', '*', '+', '?'.   */
-	  org_dest = dfa->edests[org_node].elems[0];
-	  re_node_set_empty (dfa->edests + clone_node);
-	  /* Search for a duplicated node which satisfies the constraint.  */
-	  clone_dest = search_duplicated_node (dfa, org_dest, constraint);
-	  if (clone_dest == -1)
-	    {
-	      /* There are no such a duplicated node, create a new one.  */
-	      err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
-	      if (BE (err != REG_NOERROR, 0))
-		return err;
-	      ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-	      if (BE (ret < 0, 0))
-		return REG_ESPACE;
-	      err = duplicate_node_closure (dfa, org_dest, clone_dest,
-					    root_node, constraint);
-	      if (BE (err != REG_NOERROR, 0))
-		return err;
-	    }
-	  else
-	    {
-	      /* There are a duplicated node which satisfy the constraint,
-		 use it to avoid infinite loop.  */
-	      ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-	      if (BE (ret < 0, 0))
-		return REG_ESPACE;
-	    }
-
-	  org_dest = dfa->edests[org_node].elems[1];
-	  err = duplicate_node (&clone_dest, dfa, org_dest, constraint);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	  ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-	  if (BE (ret < 0, 0))
-	    return REG_ESPACE;
-	}
-      org_node = org_dest;
-      clone_node = clone_dest;
-    }
-  return REG_NOERROR;
-}
-
-/* Search for a node which is duplicated from the node ORG_NODE, and
-   satisfies the constraint CONSTRAINT.  */
-
-static int
-search_duplicated_node (dfa, org_node, constraint)
-     re_dfa_t *dfa;
-     int org_node;
-     unsigned int constraint;
-{
-  int idx;
-  for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
-    {
-      if (org_node == dfa->org_indices[idx]
-	  && constraint == dfa->nodes[idx].constraint)
-	return idx; /* Found.  */
-    }
-  return -1; /* Not found.  */
-}
-
-/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
-   The new index will be stored in NEW_IDX and return REG_NOERROR if succeeded,
-   otherwise return the error code.  */
-
-static reg_errcode_t
-duplicate_node (new_idx, dfa, org_idx, constraint)
-     re_dfa_t *dfa;
-     int *new_idx, org_idx;
-     unsigned int constraint;
-{
-  re_token_t dup;
-  int dup_idx;
-
-  dup = dfa->nodes[org_idx];
-  dup_idx = re_dfa_add_node (dfa, dup, 1);
-  if (BE (dup_idx == -1, 0))
-    return REG_ESPACE;
-  dfa->nodes[dup_idx].constraint = constraint;
-  if (dfa->nodes[org_idx].type == ANCHOR)
-    dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type;
-  dfa->nodes[dup_idx].duplicated = 1;
-  re_node_set_init_empty (dfa->edests + dup_idx);
-  re_node_set_init_empty (dfa->eclosures + dup_idx);
-  re_node_set_init_empty (dfa->inveclosures + dup_idx);
-
-  /* Store the index of the original node.  */
-  dfa->org_indices[dup_idx] = org_idx;
-  *new_idx = dup_idx;
-  return REG_NOERROR;
-}
-
-static void
-calc_inveclosure (dfa)
-     re_dfa_t *dfa;
-{
-  int src, idx, dest;
-  for (src = 0; src < dfa->nodes_len; ++src)
-    {
-      for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
-	{
-	  dest = dfa->eclosures[src].elems[idx];
-	  re_node_set_insert (dfa->inveclosures + dest, src);
-	}
-    }
-}
-
-/* Calculate "eclosure" for all the node in DFA.  */
-
-static reg_errcode_t
-calc_eclosure (dfa)
-     re_dfa_t *dfa;
-{
-  int node_idx, incomplete;
-#ifdef DEBUG
-  assert (dfa->nodes_len > 0);
-#endif
-  incomplete = 0;
-  /* For each nodes, calculate epsilon closure.  */
-  for (node_idx = 0; ; ++node_idx)
-    {
-      reg_errcode_t err;
-      re_node_set eclosure_elem;
-      if (node_idx == dfa->nodes_len)
-	{
-	  if (!incomplete)
-	    break;
-	  incomplete = 0;
-	  node_idx = 0;
-	}
-
-#ifdef DEBUG
-      assert (dfa->eclosures[node_idx].nelem != -1);
-#endif
-      /* If we have already calculated, skip it.  */
-      if (dfa->eclosures[node_idx].nelem != 0)
-	continue;
-      /* Calculate epsilon closure of `node_idx'.  */
-      err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-
-      if (dfa->eclosures[node_idx].nelem == 0)
-	{
-	  incomplete = 1;
-	  re_node_set_free (&eclosure_elem);
-	}
-    }
-  return REG_NOERROR;
-}
-
-/* Calculate epsilon closure of NODE.  */
-
-static reg_errcode_t
-calc_eclosure_iter (new_set, dfa, node, root)
-     re_node_set *new_set;
-     re_dfa_t *dfa;
-     int node, root;
-{
-  reg_errcode_t err;
-  unsigned int constraint;
-  int i, incomplete;
-  re_node_set eclosure;
-  incomplete = 0;
-  err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-
-  /* This indicates that we are calculating this node now.
-     We reference this value to avoid infinite loop.  */
-  dfa->eclosures[node].nelem = -1;
-
-  constraint = ((dfa->nodes[node].type == ANCHOR)
-		? dfa->nodes[node].opr.ctx_type : 0);
-  /* If the current node has constraints, duplicate all nodes.
-     Since they must inherit the constraints.  */
-  if (constraint && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
-    {
-      int org_node, cur_node;
-      org_node = cur_node = node;
-      err = duplicate_node_closure (dfa, node, node, node, constraint);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-
-  /* Expand each epsilon destination nodes.  */
-  if (IS_EPSILON_NODE(dfa->nodes[node].type))
-    for (i = 0; i < dfa->edests[node].nelem; ++i)
-      {
-	re_node_set eclosure_elem;
-	int edest = dfa->edests[node].elems[i];
-	/* If calculating the epsilon closure of `edest' is in progress,
-	   return intermediate result.  */
-	if (dfa->eclosures[edest].nelem == -1)
-	  {
-	    incomplete = 1;
-	    continue;
-	  }
-	/* If we haven't calculated the epsilon closure of `edest' yet,
-	   calculate now. Otherwise use calculated epsilon closure.  */
-	if (dfa->eclosures[edest].nelem == 0)
-	  {
-	    err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);
-	    if (BE (err != REG_NOERROR, 0))
-	      return err;
-	  }
-	else
-	  eclosure_elem = dfa->eclosures[edest];
-	/* Merge the epsilon closure of `edest'.  */
-	re_node_set_merge (&eclosure, &eclosure_elem);
-	/* If the epsilon closure of `edest' is incomplete,
-	   the epsilon closure of this node is also incomplete.  */
-	if (dfa->eclosures[edest].nelem == 0)
-	  {
-	    incomplete = 1;
-	    re_node_set_free (&eclosure_elem);
-	  }
-      }
-
-  /* Epsilon closures include itself.  */
-  re_node_set_insert (&eclosure, node);
-  if (incomplete && !root)
-    dfa->eclosures[node].nelem = 0;
-  else
-    dfa->eclosures[node] = eclosure;
-  *new_set = eclosure;
-  return REG_NOERROR;
-}
-
-/* Functions for token which are used in the parser.  */
-
-/* Fetch a token from INPUT.
-   We must not use this function inside bracket expressions.  */
-
-static re_token_t
-fetch_token (input, syntax)
-     re_string_t *input;
-     reg_syntax_t syntax;
-{
-  re_token_t token;
-  int consumed_byte;
-  consumed_byte = peek_token (&token, input, syntax);
-  re_string_skip_bytes (input, consumed_byte);
-  return token;
-}
-
-/* Peek a token from INPUT, and return the length of the token.
-   We must not use this function inside bracket expressions.  */
-
-static int
-peek_token (token, input, syntax)
-     re_token_t *token;
-     re_string_t *input;
-     reg_syntax_t syntax;
-{
-  unsigned char c;
-
-  if (re_string_eoi (input))
-    {
-      token->type = END_OF_RE;
-      return 0;
-    }
-
-  c = re_string_peek_byte (input, 0);
-  token->opr.c = c;
-
-#ifdef RE_ENABLE_I18N
-  token->mb_partial = 0;
-  if (MB_CUR_MAX > 1 &&
-      !re_string_first_byte (input, re_string_cur_idx (input)))
-    {
-      token->type = CHARACTER;
-      token->mb_partial = 1;
-      return 1;
-    }
-#endif
-  if (c == '\\')
-    {
-      unsigned char c2;
-      if (re_string_cur_idx (input) + 1 >= re_string_length (input))
-	{
-	  token->type = BACK_SLASH;
-	  return 1;
-	}
-
-      c2 = re_string_peek_byte_case (input, 1);
-      token->opr.c = c2;
-      token->type = CHARACTER;
-      switch (c2)
-	{
-	case '|':
-	  if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
-	    token->type = OP_ALT;
-	  break;
-	case '1': case '2': case '3': case '4': case '5':
-	case '6': case '7': case '8': case '9':
-	  if (!(syntax & RE_NO_BK_REFS))
-	    {
-	      token->type = OP_BACK_REF;
-	      token->opr.idx = c2 - '0';
-	    }
-	  break;
-	case '<':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    {
-	      token->type = ANCHOR;
-	      token->opr.idx = WORD_FIRST;
-	    }
-	  break;
-	case '>':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    {
-	      token->type = ANCHOR;
-	      token->opr.idx = WORD_LAST;
-	    }
-	  break;
-	case 'b':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    {
-	      token->type = ANCHOR;
-	      token->opr.idx = WORD_DELIM;
-	    }
-	  break;
-	case 'B':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    {
-	      token->type = ANCHOR;
-	      token->opr.idx = INSIDE_WORD;
-	    }
-	  break;
-	case 'w':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    token->type = OP_WORD;
-	  break;
-	case 'W':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    token->type = OP_NOTWORD;
-	  break;
-	case '`':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    {
-	      token->type = ANCHOR;
-	      token->opr.idx = BUF_FIRST;
-	    }
-	  break;
-	case '\'':
-	  if (!(syntax & RE_NO_GNU_OPS))
-	    {
-	      token->type = ANCHOR;
-	      token->opr.idx = BUF_LAST;
-	    }
-	  break;
-	case '(':
-	  if (!(syntax & RE_NO_BK_PARENS))
-	    token->type = OP_OPEN_SUBEXP;
-	  break;
-	case ')':
-	  if (!(syntax & RE_NO_BK_PARENS))
-	    token->type = OP_CLOSE_SUBEXP;
-	  break;
-	case '+':
-	  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
-	    token->type = OP_DUP_PLUS;
-	  break;
-	case '?':
-	  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
-	    token->type = OP_DUP_QUESTION;
-	  break;
-	case '{':
-	  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
-	    token->type = OP_OPEN_DUP_NUM;
-	  break;
-	case '}':
-	  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
-	    token->type = OP_CLOSE_DUP_NUM;
-	  break;
-	default:
-	  break;
-	}
-      return 2;
-    }
-
-  token->type = CHARACTER;
-  switch (c)
-    {
-    case '\n':
-      if (syntax & RE_NEWLINE_ALT)
-	token->type = OP_ALT;
-      break;
-    case '|':
-      if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
-	token->type = OP_ALT;
-      break;
-    case '*':
-      token->type = OP_DUP_ASTERISK;
-      break;
-    case '+':
-      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
-	token->type = OP_DUP_PLUS;
-      break;
-    case '?':
-      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
-	token->type = OP_DUP_QUESTION;
-      break;
-    case '{':
-      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
-	token->type = OP_OPEN_DUP_NUM;
-      break;
-    case '}':
-      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
-	token->type = OP_CLOSE_DUP_NUM;
-      break;
-    case '(':
-      if (syntax & RE_NO_BK_PARENS)
-	token->type = OP_OPEN_SUBEXP;
-      break;
-    case ')':
-      if (syntax & RE_NO_BK_PARENS)
-	token->type = OP_CLOSE_SUBEXP;
-      break;
-    case '[':
-      token->type = OP_OPEN_BRACKET;
-      break;
-    case '.':
-      token->type = OP_PERIOD;
-      break;
-    case '^':
-      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
-	  re_string_cur_idx (input) != 0)
-	{
-	  char prev = re_string_peek_byte (input, -1);
-	  if (prev != '|' && prev != '(' &&
-	      (!(syntax & RE_NEWLINE_ALT) || prev != '\n'))
-	    break;
-	}
-      token->type = ANCHOR;
-      token->opr.idx = LINE_FIRST;
-      break;
-    case '$':
-      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
-	  re_string_cur_idx (input) + 1 != re_string_length (input))
-	{
-	  re_token_t next;
-	  re_string_skip_bytes (input, 1);
-	  peek_token (&next, input, syntax);
-	  re_string_skip_bytes (input, -1);
-	  if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
-	    break;
-	}
-      token->type = ANCHOR;
-      token->opr.idx = LINE_LAST;
-      break;
-    default:
-      break;
-    }
-  return 1;
-}
-
-/* Peek a token from INPUT, and return the length of the token.
-   We must not use this function out of bracket expressions.  */
-
-static int
-peek_token_bracket (token, input, syntax)
-     re_token_t *token;
-     re_string_t *input;
-     reg_syntax_t syntax;
-{
-  unsigned char c;
-  if (re_string_eoi (input))
-    {
-      token->type = END_OF_RE;
-      return 0;
-    }
-  c = re_string_peek_byte (input, 0);
-  token->opr.c = c;
-
-#ifdef RE_ENABLE_I18N
-  if (MB_CUR_MAX > 1 &&
-      !re_string_first_byte (input, re_string_cur_idx (input)))
-    {
-      token->type = CHARACTER;
-      return 1;
-    }
-#endif /* RE_ENABLE_I18N */
-
-  if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS))
-    {
-      /* In this case, '\' escape a character.  */
-      unsigned char c2;
-      re_string_skip_bytes (input, 1);
-      c2 = re_string_peek_byte (input, 0);
-      token->opr.c = c2;
-      token->type = CHARACTER;
-      return 1;
-    }
-  if (c == '[') /* '[' is a special char in a bracket exps.  */
-    {
-      unsigned char c2;
-      int token_len;
-      c2 = re_string_peek_byte (input, 1);
-      token->opr.c = c2;
-      token_len = 2;
-      switch (c2)
-	{
-	case '.':
-	  token->type = OP_OPEN_COLL_ELEM;
-	  break;
-	case '=':
-	  token->type = OP_OPEN_EQUIV_CLASS;
-	  break;
-	case ':':
-	  if (syntax & RE_CHAR_CLASSES)
-	    {
-	      token->type = OP_OPEN_CHAR_CLASS;
-	      break;
-	    }
-	  /* else fall through.  */
-	default:
-	  token->type = CHARACTER;
-	  token->opr.c = c;
-	  token_len = 1;
-	  break;
-	}
-      return token_len;
-    }
-  switch (c)
-    {
-    case '-':
-      token->type = OP_CHARSET_RANGE;
-      break;
-    case ']':
-      token->type = OP_CLOSE_BRACKET;
-      break;
-    case '^':
-      token->type = OP_NON_MATCH_LIST;
-      break;
-    default:
-      token->type = CHARACTER;
-    }
-  return 1;
-}
-
-/* Functions for parser.  */
-
-/* Entry point of the parser.
-   Parse the regular expression REGEXP and return the structure tree.
-   If an error is occured, ERR is set by error code, and return NULL.
-   This function build the following tree, from regular expression <reg_exp>:
-	   CAT
-	   / \
-	  /   \
-   <reg_exp>  EOR
-
-   CAT means concatenation.
-   EOR means end of regular expression.  */
-
-static bin_tree_t *
-parse (regexp, preg, syntax, err)
-     re_string_t *regexp;
-     regex_t *preg;
-     reg_syntax_t syntax;
-     reg_errcode_t *err;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree, *eor, *root;
-  re_token_t current_token;
-  int new_idx;
-  current_token = fetch_token (regexp, syntax);
-  tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
-    return NULL;
-  new_idx = re_dfa_add_node (dfa, current_token, 0);
-  eor = create_tree (NULL, NULL, 0, new_idx);
-  if (tree != NULL)
-    root = create_tree (tree, eor, CONCAT, 0);
-  else
-    root = eor;
-  if (BE (new_idx == -1 || eor == NULL || root == NULL, 0))
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-  return root;
-}
-
-/* This function build the following tree, from regular expression
-   <branch1>|<branch2>:
-	   ALT
-	   / \
-	  /   \
-   <branch1> <branch2>
-
-   ALT means alternative, which represents the operator `|'.  */
-
-static bin_tree_t *
-parse_reg_exp (regexp, preg, token, syntax, nest, err)
-     re_string_t *regexp;
-     regex_t *preg;
-     re_token_t *token;
-     reg_syntax_t syntax;
-     int nest;
-     reg_errcode_t *err;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree, *branch = NULL;
-  int new_idx;
-  tree = parse_branch (regexp, preg, token, syntax, nest, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
-    return NULL;
-
-  while (token->type == OP_ALT)
-    {
-      re_token_t alt_token = *token;
-      new_idx = re_dfa_add_node (dfa, alt_token, 0);
-      *token = fetch_token (regexp, syntax);
-      if (token->type != OP_ALT && token->type != END_OF_RE
-	  && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
-	{
-	  branch = parse_branch (regexp, preg, token, syntax, nest, err);
-	  if (BE (*err != REG_NOERROR && branch == NULL, 0))
-	    {
-	      free_bin_tree (tree);
-	      return NULL;
-	    }
-	}
-      else
-	branch = NULL;
-      tree = create_tree (tree, branch, 0, new_idx);
-      if (BE (new_idx == -1 || tree == NULL, 0))
-	{
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-      dfa->has_plural_match = 1;
-    }
-  return tree;
-}
-
-/* This function build the following tree, from regular expression
-   <exp1><exp2>:
-	CAT
-	/ \
-       /   \
-   <exp1> <exp2>
-
-   CAT means concatenation.  */
-
-static bin_tree_t *
-parse_branch (regexp, preg, token, syntax, nest, err)
-     re_string_t *regexp;
-     regex_t *preg;
-     re_token_t *token;
-     reg_syntax_t syntax;
-     int nest;
-     reg_errcode_t *err;
-{
-  bin_tree_t *tree, *exp;
-  tree = parse_expression (regexp, preg, token, syntax, nest, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
-    return NULL;
-
-  while (token->type != OP_ALT && token->type != END_OF_RE
-	 && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
-    {
-      exp = parse_expression (regexp, preg, token, syntax, nest, err);
-      if (BE (*err != REG_NOERROR && exp == NULL, 0))
-	{
-	  free_bin_tree (tree);
-	  return NULL;
-	}
-      if (tree != NULL && exp != NULL)
-	{
-	  tree = create_tree (tree, exp, CONCAT, 0);
-	  if (tree == NULL)
-	    {
-	      *err = REG_ESPACE;
-	      return NULL;
-	    }
-	}
-      else if (tree == NULL)
-	tree = exp;
-      /* Otherwise exp == NULL, we don't need to create new tree.  */
-    }
-  return tree;
-}
-
-/* This function build the following tree, from regular expression a*:
-	 *
-	 |
-	 a
-*/
-
-static bin_tree_t *
-parse_expression (regexp, preg, token, syntax, nest, err)
-     re_string_t *regexp;
-     regex_t *preg;
-     re_token_t *token;
-     reg_syntax_t syntax;
-     int nest;
-     reg_errcode_t *err;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree;
-  int new_idx;
-  switch (token->type)
-    {
-    case CHARACTER:
-      new_idx = re_dfa_add_node (dfa, *token, 0);
-      tree = create_tree (NULL, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || tree == NULL, 0))
-	{
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	{
-	  while (!re_string_eoi (regexp)
-		 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
-	    {
-	      bin_tree_t *mbc_remain;
-	      *token = fetch_token (regexp, syntax);
-	      new_idx = re_dfa_add_node (dfa, *token, 0);
-	      mbc_remain = create_tree (NULL, NULL, 0, new_idx);
-	      tree = create_tree (tree, mbc_remain, CONCAT, 0);
-	      if (BE (new_idx == -1 || mbc_remain == NULL || tree == NULL, 0))
-		{
-		  *err = REG_ESPACE;
-		  return NULL;
-		}
-	    }
-	}
-#endif
-      break;
-    case OP_OPEN_SUBEXP:
-      tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
-      break;
-    case OP_OPEN_BRACKET:
-      tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
-      break;
-    case OP_BACK_REF:
-      if (BE (preg->re_nsub < token->opr.idx
-	      || dfa->subexps[token->opr.idx - 1].end == -1, 0))
-	{
-	  *err = REG_ESUBREG;
-	  return NULL;
-	}
-      dfa->used_bkref_map |= 1 << (token->opr.idx - 1);
-      new_idx = re_dfa_add_node (dfa, *token, 0);
-      tree = create_tree (NULL, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || tree == NULL, 0))
-	{
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-      ++dfa->nbackref;
-      dfa->has_mb_node = 1;
-      break;
-    case OP_DUP_ASTERISK:
-    case OP_DUP_PLUS:
-    case OP_DUP_QUESTION:
-    case OP_OPEN_DUP_NUM:
-      if (syntax & RE_CONTEXT_INVALID_OPS)
-	{
-	  *err = REG_BADRPT;
-	  return NULL;
-	}
-      else if (syntax & RE_CONTEXT_INDEP_OPS)
-	{
-	  *token = fetch_token (regexp, syntax);
-	  return parse_expression (regexp, preg, token, syntax, nest, err);
-	}
-      /* else fall through  */
-    case OP_CLOSE_SUBEXP:
-      if ((token->type == OP_CLOSE_SUBEXP) &&
-	  !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))
-	{
-	  *err = REG_ERPAREN;
-	  return NULL;
-	}
-      /* else fall through  */
-    case OP_CLOSE_DUP_NUM:
-      /* We treat it as a normal character.  */
-
-      /* Then we can these characters as normal characters.  */
-      token->type = CHARACTER;
-      new_idx = re_dfa_add_node (dfa, *token, 0);
-      tree = create_tree (NULL, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || tree == NULL, 0))
-	{
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-      break;
-    case ANCHOR:
-      if (dfa->word_char == NULL)
-	{
-	  *err = init_word_char (dfa);
-	  if (BE (*err != REG_NOERROR, 0))
-	    return NULL;
-	}
-      if (token->opr.ctx_type == WORD_DELIM)
-	{
-	  bin_tree_t *tree_first, *tree_last;
-	  int idx_first, idx_last;
-	  token->opr.ctx_type = WORD_FIRST;
-	  idx_first = re_dfa_add_node (dfa, *token, 0);
-	  tree_first = create_tree (NULL, NULL, 0, idx_first);
-	  token->opr.ctx_type = WORD_LAST;
-	  idx_last = re_dfa_add_node (dfa, *token, 0);
-	  tree_last = create_tree (NULL, NULL, 0, idx_last);
-	  token->type = OP_ALT;
-	  new_idx = re_dfa_add_node (dfa, *token, 0);
-	  tree = create_tree (tree_first, tree_last, 0, new_idx);
-	  if (BE (idx_first == -1 || idx_last == -1 || new_idx == -1
-		  || tree_first == NULL || tree_last == NULL
-		  || tree == NULL, 0))
-	    {
-	      *err = REG_ESPACE;
-	      return NULL;
-	    }
-	}
-      else
-	{
-	  new_idx = re_dfa_add_node (dfa, *token, 0);
-	  tree = create_tree (NULL, NULL, 0, new_idx);
-	  if (BE (new_idx == -1 || tree == NULL, 0))
-	    {
-	      *err = REG_ESPACE;
-	      return NULL;
-	    }
-	}
-      /* We must return here, since ANCHORs can't be followed
-	 by repetition operators.
-	 eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
-	     it must not be "<ANCHOR(^)><REPEAT(*)>".  */
-      *token = fetch_token (regexp, syntax);
-      return tree;
-    case OP_PERIOD:
-      new_idx = re_dfa_add_node (dfa, *token, 0);
-      tree = create_tree (NULL, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || tree == NULL, 0))
-	{
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-      if (MB_CUR_MAX > 1)
-	dfa->has_mb_node = 1;
-      break;
-    case OP_WORD:
-      tree = build_word_op (dfa, 0, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
-      break;
-    case OP_NOTWORD:
-      tree = build_word_op (dfa, 1, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
-      break;
-    case OP_ALT:
-    case END_OF_RE:
-      return NULL;
-    case BACK_SLASH:
-      *err = REG_EESCAPE;
-      return NULL;
-    default:
-      /* Must not happen?  */
-#ifdef DEBUG
-      assert (0);
-#endif
-      return NULL;
-    }
-  *token = fetch_token (regexp, syntax);
-
-  while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
-	 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
-    {
-      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
-      dfa->has_plural_match = 1;
-    }
-
-  return tree;
-}
-
-/* This function build the following tree, from regular expression
-   (<reg_exp>):
-	 SUBEXP
-	    |
-	<reg_exp>
-*/
-
-static bin_tree_t *
-parse_sub_exp (regexp, preg, token, syntax, nest, err)
-     re_string_t *regexp;
-     regex_t *preg;
-     re_token_t *token;
-     reg_syntax_t syntax;
-     int nest;
-     reg_errcode_t *err;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree, *left_par, *right_par;
-  size_t cur_nsub;
-  int new_idx;
-  cur_nsub = preg->re_nsub++;
-  if (dfa->subexps_alloc < preg->re_nsub)
-    {
-      re_subexp_t *new_array;
-      dfa->subexps_alloc *= 2;
-      new_array = re_realloc (dfa->subexps, re_subexp_t, dfa->subexps_alloc);
-      if (BE (new_array == NULL, 0))
-	{
-	  dfa->subexps_alloc /= 2;
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-      dfa->subexps = new_array;
-    }
-  dfa->subexps[cur_nsub].start = dfa->nodes_len;
-  dfa->subexps[cur_nsub].end = -1;
-
-  new_idx = re_dfa_add_node (dfa, *token, 0);
-  left_par = create_tree (NULL, NULL, 0, new_idx);
-  if (BE (new_idx == -1 || left_par == NULL, 0))
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-  dfa->nodes[new_idx].opr.idx = cur_nsub;
-  *token = fetch_token (regexp, syntax);
-
-  /* The subexpression may be a null string.  */
-  if (token->type == OP_CLOSE_SUBEXP)
-    tree = NULL;
-  else
-    {
-      tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
-    }
-  if (BE (token->type != OP_CLOSE_SUBEXP, 0))
-    {
-      free_bin_tree (tree);
-      *err = REG_BADPAT;
-      return NULL;
-    }
-  new_idx = re_dfa_add_node (dfa, *token, 0);
-  dfa->subexps[cur_nsub].end = dfa->nodes_len;
-  right_par = create_tree (NULL, NULL, 0, new_idx);
-  tree = ((tree == NULL) ? right_par
-	  : create_tree (tree, right_par, CONCAT, 0));
-  tree = create_tree (left_par, tree, CONCAT, 0);
-  if (BE (new_idx == -1 || right_par == NULL || tree == NULL, 0))
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-  dfa->nodes[new_idx].opr.idx = cur_nsub;
-
-  return tree;
-}
-
-/* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
-
-static bin_tree_t *
-parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
-     bin_tree_t *dup_elem;
-     re_string_t *regexp;
-     re_dfa_t *dfa;
-     re_token_t *token;
-     reg_syntax_t syntax;
-     reg_errcode_t *err;
-{
-  re_token_t dup_token;
-  bin_tree_t *tree = dup_elem, *work_tree;
-  int new_idx, start_idx = re_string_cur_idx (regexp);
-  re_token_t start_token = *token;
-  if (token->type == OP_OPEN_DUP_NUM)
-    {
-      int i;
-      int end = 0;
-      int start = fetch_number (regexp, token, syntax);
-      bin_tree_t *elem;
-      if (start == -1)
-	{
-	  if (token->type == CHARACTER && token->opr.c == ',')
-	    start = 0; /* We treat "{,m}" as "{0,m}".  */
-	  else
-	    {
-	      *err = REG_BADBR; /* <re>{} is invalid.  */
-	      return NULL;
-	    }
-	}
-      if (BE (start != -2, 1))
-	{
-	  /* We treat "{n}" as "{n,n}".  */
-	  end = ((token->type == OP_CLOSE_DUP_NUM) ? start
-		 : ((token->type == CHARACTER && token->opr.c == ',')
-		    ? fetch_number (regexp, token, syntax) : -2));
-	}
-      if (BE (start == -2 || end == -2, 0))
-	{
-	  /* Invalid sequence.  */
-	  if (token->type == OP_CLOSE_DUP_NUM)
-	    goto parse_dup_op_invalid_interval;
-	  else
-	    goto parse_dup_op_ebrace;
-	}
-      if (BE (start == 0 && end == 0, 0))
-	{
-	  /* We treat "<re>{0}" and "<re>{0,0}" as null string.  */
-	  *token = fetch_token (regexp, syntax);
-	  free_bin_tree (dup_elem);
-	  return NULL;
-	}
-
-      /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
-      elem = tree;
-      for (i = 0; i < start; ++i)
-	if (i != 0)
-	  {
-	    work_tree = duplicate_tree (elem, dfa);
-	    tree = create_tree (tree, work_tree, CONCAT, 0);
-	    if (BE (work_tree == NULL || tree == NULL, 0))
-	      goto parse_dup_op_espace;
-	  }
-
-      if (end == -1)
-	{
-	  /* We treat "<re>{0,}" as "<re>*".  */
-	  dup_token.type = OP_DUP_ASTERISK;
-	  if (start > 0)
-	    {
-	      elem = duplicate_tree (elem, dfa);
-	      new_idx = re_dfa_add_node (dfa, dup_token, 0);
-	      work_tree = create_tree (elem, NULL, 0, new_idx);
-	      tree = create_tree (tree, work_tree, CONCAT, 0);
-	      if (BE (elem == NULL || new_idx == -1 || work_tree == NULL
-		      || tree == NULL, 0))
-		goto parse_dup_op_espace;
-	    }
-	  else
-	    {
-	      new_idx = re_dfa_add_node (dfa, dup_token, 0);
-	      tree = create_tree (elem, NULL, 0, new_idx);
-	      if (BE (new_idx == -1 || tree == NULL, 0))
-		goto parse_dup_op_espace;
-	    }
-	}
-      else if (end - start > 0)
-	{
-	  /* Then extract "<re>{0,m}" to "<re>?<re>?...<re>?".  */
-	  dup_token.type = OP_DUP_QUESTION;
-	  if (start > 0)
-	    {
-	      elem = duplicate_tree (elem, dfa);
-	      new_idx = re_dfa_add_node (dfa, dup_token, 0);
-	      elem = create_tree (elem, NULL, 0, new_idx);
-	      tree = create_tree (tree, elem, CONCAT, 0);
-	      if (BE (elem == NULL || new_idx == -1 || tree == NULL, 0))
-		goto parse_dup_op_espace;
-	    }
-	  else
-	    {
-	      new_idx = re_dfa_add_node (dfa, dup_token, 0);
-	      tree = elem = create_tree (elem, NULL, 0, new_idx);
-	      if (BE (new_idx == -1 || tree == NULL, 0))
-		goto parse_dup_op_espace;
-	    }
-	  for (i = 1; i < end - start; ++i)
-	    {
-	      work_tree = duplicate_tree (elem, dfa);
-	      tree = create_tree (tree, work_tree, CONCAT, 0);
-	      if (BE (work_tree == NULL || tree == NULL, 0))
-		{
-		  *err = REG_ESPACE;
-		  return NULL;
-		}
-	    }
-	}
-    }
-  else
-    {
-      new_idx = re_dfa_add_node (dfa, *token, 0);
-      tree = create_tree (tree, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || tree == NULL, 0))
-	{
-	  *err = REG_ESPACE;
-	  return NULL;
-	}
-    }
-  *token = fetch_token (regexp, syntax);
-  return tree;
-
- parse_dup_op_espace:
-  free_bin_tree (tree);
-  *err = REG_ESPACE;
-  return NULL;
-
- parse_dup_op_ebrace:
-  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
-    {
-      *err = REG_EBRACE;
-      return NULL;
-    }
-  goto parse_dup_op_rollback;
- parse_dup_op_invalid_interval:
-  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
-    {
-      *err = REG_BADBR;
-      return NULL;
-    }
- parse_dup_op_rollback:
-  re_string_set_index (regexp, start_idx);
-  *token = start_token;
-  token->type = CHARACTER;
-  return dup_elem;
-}
-
-/* Size of the names for collating symbol/equivalence_class/character_class.
-   I'm not sure, but maybe enough.  */
-#define BRACKET_NAME_BUF_SIZE 32
-
-#ifndef _LIBC
-  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
-     Build the range expression which starts from START_ELEM, and ends
-     at END_ELEM.  The result are written to MBCSET and SBCSET.
-     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
-     mbcset->range_ends, is a pointer argument sinse we may
-     update it.  */
-
-static reg_errcode_t
-# ifdef RE_ENABLE_I18N
-build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
-     re_charset_t *mbcset;
-     int *range_alloc;
-# else /* not RE_ENABLE_I18N */
-build_range_exp (sbcset, start_elem, end_elem)
-# endif /* not RE_ENABLE_I18N */
-     re_bitset_ptr_t sbcset;
-     bracket_elem_t *start_elem, *end_elem;
-{
-  unsigned int start_ch, end_ch;
-  /* Equivalence Classes and Character Classes can't be a range start/end.  */
-  if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-	  || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
-	  0))
-    return REG_ERANGE;
-
-  /* We can handle no multi character collating elements without libc
-     support.  */
-  if (BE ((start_elem->type == COLL_SYM
-	   && strlen ((char *) start_elem->opr.name) > 1)
-	  || (end_elem->type == COLL_SYM
-	      && strlen ((char *) end_elem->opr.name) > 1), 0))
-    return REG_ECOLLATE;
-
-# ifdef RE_ENABLE_I18N
-  {
-    wchar_t wc, start_wc, end_wc;
-    wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
-
-    start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
-		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
-		   : 0));
-    end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
-	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
-		 : 0));
-    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
-		? __btowc (start_ch) : start_elem->opr.wch);
-    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
-	      ? __btowc (end_ch) : end_elem->opr.wch);
-    cmp_buf[0] = start_wc;
-    cmp_buf[4] = end_wc;
-    if (wcscoll (cmp_buf, cmp_buf + 4) > 0)
-      return REG_ERANGE;
-
-    /* Check the space of the arrays.  */
-    if (*range_alloc == mbcset->nranges)
-      {
-	/* There are not enough space, need realloc.  */
-	wchar_t *new_array_start, *new_array_end;
-	int new_nranges;
-
-	/* +1 in case of mbcset->nranges is 0.  */
-	new_nranges = 2 * mbcset->nranges + 1;
-	/* Use realloc since mbcset->range_starts and mbcset->range_ends
-	   are NULL if *range_alloc == 0.  */
-	new_array_start = re_realloc (mbcset->range_starts, wchar_t,
-				      new_nranges);
-	new_array_end = re_realloc (mbcset->range_ends, wchar_t,
-				    new_nranges);
-
-	if (BE (new_array_start == NULL || new_array_end == NULL, 0))
-	  return REG_ESPACE;
-
-	mbcset->range_starts = new_array_start;
-	mbcset->range_ends = new_array_end;
-	*range_alloc = new_nranges;
-      }
-
-    mbcset->range_starts[mbcset->nranges] = start_wc;
-    mbcset->range_ends[mbcset->nranges++] = end_wc;
-
-    /* Build the table for single byte characters.  */
-    for (wc = 0; wc <= SBC_MAX; ++wc)
-      {
-	cmp_buf[2] = wc;
-	if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
-	    && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
-	  bitset_set (sbcset, wc);
-      }
-  }
-# else /* not RE_ENABLE_I18N */
-  {
-    unsigned int ch;
-    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
-		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
-		   : 0));
-    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
-	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
-		 : 0));
-    if (start_ch > end_ch)
-      return REG_ERANGE;
-    /* Build the table for single byte characters.  */
-    for (ch = 0; ch <= SBC_MAX; ++ch)
-      if (start_ch <= ch  && ch <= end_ch)
-	bitset_set (sbcset, ch);
-  }
-# endif /* not RE_ENABLE_I18N */
-  return REG_NOERROR;
-}
-#endif /* not _LIBC */
-
-#ifndef _LIBC
-/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
-   Build the collating element which is represented by NAME.
-   The result are written to MBCSET and SBCSET.
-   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
-   pointer argument since we may update it.  */
-
-static reg_errcode_t
-# ifdef RE_ENABLE_I18N
-build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
-     re_charset_t *mbcset;
-     int *coll_sym_alloc;
-# else /* not RE_ENABLE_I18N */
-build_collating_symbol (sbcset, name)
-# endif /* not RE_ENABLE_I18N */
-     re_bitset_ptr_t sbcset;
-     const unsigned char *name;
-{
-  size_t name_len = strlen ((const char *) name);
-  if (BE (name_len != 1, 0))
-    return REG_ECOLLATE;
-  else
-    {
-      bitset_set (sbcset, name[0]);
-      return REG_NOERROR;
-    }
-}
-#endif /* not _LIBC */
-
-/* This function parse bracket expression like "[abc]", "[a-c]",
-   "[[.a-a.]]" etc.  */
-
-static bin_tree_t *
-parse_bracket_exp (regexp, dfa, token, syntax, err)
-     re_string_t *regexp;
-     re_dfa_t *dfa;
-     re_token_t *token;
-     reg_syntax_t syntax;
-     reg_errcode_t *err;
-{
-#ifdef _LIBC
-  const unsigned char *collseqmb;
-  const char *collseqwc;
-  uint32_t nrules;
-  int32_t table_size;
-  const int32_t *symb_table;
-  const unsigned char *extra;
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Seek the collating symbol entry correspondings to NAME.
-     Return the index of the symbol in the SYMB_TABLE.  */
-
-  static inline int32_t
-  seek_collating_symbol_entry (name, name_len)
-	 const unsigned char *name;
-	 size_t name_len;
-    {
-      int32_t hash = elem_hash ((const char *) name, name_len);
-      int32_t elem = hash % table_size;
-      int32_t second = hash % (table_size - 2);
-      while (symb_table[2 * elem] != 0)
-	{
-	  /* First compare the hashing value.  */
-	  if (symb_table[2 * elem] == hash
-	      /* Compare the length of the name.  */
-	      && name_len == extra[symb_table[2 * elem + 1]]
-	      /* Compare the name.  */
-	      && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
-			 name_len) == 0)
-	    {
-	      /* Yep, this is the entry.  */
-	      break;
-	    }
-
-	  /* Next entry.  */
-	  elem += second;
-	}
-      return elem;
-    }
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Look up the collation sequence value of BR_ELEM.
-     Return the value if succeeded, UINT_MAX otherwise.  */
-
-  static inline unsigned int
-  lookup_collation_sequence_value (br_elem)
-	 bracket_elem_t *br_elem;
-    {
-      if (br_elem->type == SB_CHAR)
-	{
-	  /*
-	  if (MB_CUR_MAX == 1)
-	  */
-	  if (nrules == 0)
-	    return collseqmb[br_elem->opr.ch];
-	  else
-	    {
-	      wint_t wc = __btowc (br_elem->opr.ch);
-	      return collseq_table_lookup (collseqwc, wc);
-	    }
-	}
-      else if (br_elem->type == MB_CHAR)
-	{
-	  return collseq_table_lookup (collseqwc, br_elem->opr.wch);
-	}
-      else if (br_elem->type == COLL_SYM)
-	{
-	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
-	  if (nrules != 0)
-	    {
-	      int32_t elem, idx;
-	      elem = seek_collating_symbol_entry (br_elem->opr.name,
-						  sym_name_len);
-	      if (symb_table[2 * elem] != 0)
-		{
-		  /* We found the entry.  */
-		  idx = symb_table[2 * elem + 1];
-		  /* Skip the name of collating element name.  */
-		  idx += 1 + extra[idx];
-		  /* Skip the byte sequence of the collating element.  */
-		  idx += 1 + extra[idx];
-		  /* Adjust for the alignment.  */
-		  idx = (idx + 3) & ~3;
-		  /* Skip the multibyte collation sequence value.  */
-		  idx += sizeof (unsigned int);
-		  /* Skip the wide char sequence of the collating element.  */
-		  idx += sizeof (unsigned int) *
-		    (1 + *(unsigned int *) (extra + idx));
-		  /* Return the collation sequence value.  */
-		  return *(unsigned int *) (extra + idx);
-		}
-	      else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
-		{
-		  /* No valid character.  Match it as a single byte
-		     character.  */
-		  return collseqmb[br_elem->opr.name[0]];
-		}
-	    }
-	  else if (sym_name_len == 1)
-	    return collseqmb[br_elem->opr.name[0]];
-	}
-      return UINT_MAX;
-    }
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Build the range expression which starts from START_ELEM, and ends
-     at END_ELEM.  The result are written to MBCSET and SBCSET.
-     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
-     mbcset->range_ends, is a pointer argument sinse we may
-     update it.  */
-
-  static inline reg_errcode_t
-# ifdef RE_ENABLE_I18N
-  build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
-	 re_charset_t *mbcset;
-	 int *range_alloc;
-# else /* not RE_ENABLE_I18N */
-  build_range_exp (sbcset, start_elem, end_elem)
-# endif /* not RE_ENABLE_I18N */
-	 re_bitset_ptr_t sbcset;
-	 bracket_elem_t *start_elem, *end_elem;
-    {
-      unsigned int ch;
-      uint32_t start_collseq;
-      uint32_t end_collseq;
-
-# ifdef RE_ENABLE_I18N
-      /* Check the space of the arrays.  */
-      if (*range_alloc == mbcset->nranges)
-	{
-	  /* There are not enough space, need realloc.  */
-	  uint32_t *new_array_start;
-	  uint32_t *new_array_end;
-	  int new_nranges;
-
-	  /* +1 in case of mbcset->nranges is 0.  */
-	  new_nranges = 2 * mbcset->nranges + 1;
-	  /* Use realloc since mbcset->range_starts and mbcset->range_ends
-	     are NULL if *range_alloc == 0.  */
-	  new_array_start = re_realloc (mbcset->range_starts, uint32_t,
-					new_nranges);
-	  new_array_end = re_realloc (mbcset->range_ends, uint32_t,
-				      new_nranges);
-
-	  if (BE (new_array_start == NULL || new_array_end == NULL, 0))
-	    return REG_ESPACE;
-
-	  mbcset->range_starts = new_array_start;
-	  mbcset->range_ends = new_array_end;
-	  *range_alloc = new_nranges;
-	}
-# endif /* RE_ENABLE_I18N */
-
-      /* Equivalence Classes and Character Classes can't be a range
-	 start/end.  */
-      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-	      || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
-	      0))
-	return REG_ERANGE;
-
-      start_collseq = lookup_collation_sequence_value (start_elem);
-      end_collseq = lookup_collation_sequence_value (end_elem);
-      /* Check start/end collation sequence values.  */
-      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
-	return REG_ECOLLATE;
-      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
-	return REG_ERANGE;
-
-# ifdef RE_ENABLE_I18N
-      /* Got valid collation sequence values, add them as a new entry.  */
-      mbcset->range_starts[mbcset->nranges] = start_collseq;
-      mbcset->range_ends[mbcset->nranges++] = end_collseq;
-# endif /* RE_ENABLE_I18N */
-
-      /* Build the table for single byte characters.  */
-      for (ch = 0; ch <= SBC_MAX; ch++)
-	{
-	  uint32_t ch_collseq;
-	  /*
-	  if (MB_CUR_MAX == 1)
-	  */
-	  if (nrules == 0)
-	    ch_collseq = collseqmb[ch];
-	  else
-	    ch_collseq = collseq_table_lookup (collseqwc, __btowc (ch));
-	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
-	    bitset_set (sbcset, ch);
-	}
-      return REG_NOERROR;
-    }
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Build the collating element which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
-     pointer argument sinse we may update it.  */
-
-  static inline reg_errcode_t
-# ifdef RE_ENABLE_I18N
-  build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
-	 re_charset_t *mbcset;
-	 int *coll_sym_alloc;
-# else /* not RE_ENABLE_I18N */
-  build_collating_symbol (sbcset, name)
-# endif /* not RE_ENABLE_I18N */
-	 re_bitset_ptr_t sbcset;
-	 const unsigned char *name;
-    {
-      int32_t elem, idx;
-      size_t name_len = strlen ((const char *) name);
-      if (nrules != 0)
-	{
-	  elem = seek_collating_symbol_entry (name, name_len);
-	  if (symb_table[2 * elem] != 0)
-	    {
-	      /* We found the entry.  */
-	      idx = symb_table[2 * elem + 1];
-	      /* Skip the name of collating element name.  */
-	      idx += 1 + extra[idx];
-	    }
-	  else if (symb_table[2 * elem] == 0 && name_len == 1)
-	    {
-	      /* No valid character, treat it as a normal
-		 character.  */
-	      bitset_set (sbcset, name[0]);
-	      return REG_NOERROR;
-	    }
-	  else
-	    return REG_ECOLLATE;
-
-# ifdef RE_ENABLE_I18N
-	  /* Got valid collation sequence, add it as a new entry.  */
-	  /* Check the space of the arrays.  */
-	  if (*coll_sym_alloc == mbcset->ncoll_syms)
-	    {
-	      /* Not enough, realloc it.  */
-	      /* +1 in case of mbcset->ncoll_syms is 0.  */
-	      *coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
-	      /* Use realloc since mbcset->coll_syms is NULL
-		 if *alloc == 0.  */
-	      mbcset->coll_syms = re_realloc (mbcset->coll_syms, int32_t,
-					      *coll_sym_alloc);
-	      if (BE (mbcset->coll_syms == NULL, 0))
-		return REG_ESPACE;
-	    }
-	  mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
-# endif /* RE_ENABLE_I18N */
-	  return REG_NOERROR;
-	}
-      else
-	{
-	  if (BE (name_len != 1, 0))
-	    return REG_ECOLLATE;
-	  else
-	    {
-	      bitset_set (sbcset, name[0]);
-	      return REG_NOERROR;
-	    }
-	}
-    }
-#endif
-
-  re_token_t br_token;
-  re_bitset_ptr_t sbcset;
-#ifdef RE_ENABLE_I18N
-  re_charset_t *mbcset;
-  int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
-  int equiv_class_alloc = 0, char_class_alloc = 0;
-#else /* not RE_ENABLE_I18N */
-  int non_match = 0;
-#endif /* not RE_ENABLE_I18N */
-  bin_tree_t *work_tree;
-  int token_len, new_idx;
-#ifdef _LIBC
-  collseqmb = (const unsigned char *)
-    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
-  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-  if (nrules)
-    {
-      /*
-      if (MB_CUR_MAX > 1)
-      */
-	collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
-      table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
-      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-						  _NL_COLLATE_SYMB_TABLEMB);
-      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-						   _NL_COLLATE_SYMB_EXTRAMB);
-    }
-#endif
-  sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
-#ifdef RE_ENABLE_I18N
-  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
-#ifdef RE_ENABLE_I18N
-  if (BE (sbcset == NULL || mbcset == NULL, 0))
-#else
-  if (BE (sbcset == NULL, 0))
-#endif /* RE_ENABLE_I18N */
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-
-  token_len = peek_token_bracket (token, regexp, syntax);
-  if (BE (token->type == END_OF_RE, 0))
-    {
-      *err = REG_BADPAT;
-      goto parse_bracket_exp_free_return;
-    }
-  if (token->type == OP_NON_MATCH_LIST)
-    {
-#ifdef RE_ENABLE_I18N
-      int i;
-      mbcset->non_match = 1;
-#else /* not RE_ENABLE_I18N */
-      non_match = 1;
-#endif /* not RE_ENABLE_I18N */
-      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
-	bitset_set (sbcset, '\0');
-      re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
-      token_len = peek_token_bracket (token, regexp, syntax);
-      if (BE (token->type == END_OF_RE, 0))
-	{
-	  *err = REG_BADPAT;
-	  goto parse_bracket_exp_free_return;
-	}
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	for (i = 0; i < SBC_MAX; ++i)
-	  if (__btowc (i) == WEOF)
-	    bitset_set (sbcset, i);
-#endif /* RE_ENABLE_I18N */
-    }
-
-  /* We treat the first ']' as a normal character.  */
-  if (token->type == OP_CLOSE_BRACKET)
-    token->type = CHARACTER;
-
-  while (1)
-    {
-      bracket_elem_t start_elem, end_elem;
-      unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
-      unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
-      reg_errcode_t ret;
-      int token_len2 = 0, is_range_exp = 0;
-      re_token_t token2;
-
-      start_elem.opr.name = start_name_buf;
-      ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
-				   syntax);
-      if (BE (ret != REG_NOERROR, 0))
-	{
-	  *err = ret;
-	  goto parse_bracket_exp_free_return;
-	}
-
-      token_len = peek_token_bracket (token, regexp, syntax);
-      if (BE (token->type == END_OF_RE, 0))
-	{
-	  *err = REG_BADPAT;
-	  goto parse_bracket_exp_free_return;
-	}
-      if (token->type == OP_CHARSET_RANGE)
-	{
-	  re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
-	  token_len2 = peek_token_bracket (&token2, regexp, syntax);
-	  if (BE (token->type == END_OF_RE, 0))
-	    {
-	      *err = REG_BADPAT;
-	      goto parse_bracket_exp_free_return;
-	    }
-	  if (token2.type == OP_CLOSE_BRACKET)
-	    {
-	      /* We treat the last '-' as a normal character.  */
-	      re_string_skip_bytes (regexp, -token_len);
-	      token->type = CHARACTER;
-	    }
-	  else
-	    is_range_exp = 1;
-	}
-
-      if (is_range_exp == 1)
-	{
-	  end_elem.opr.name = end_name_buf;
-	  ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
-				       dfa, syntax);
-	  if (BE (ret != REG_NOERROR, 0))
-	    {
-	      *err = ret;
-	      goto parse_bracket_exp_free_return;
-	    }
-
-	  token_len = peek_token_bracket (token, regexp, syntax);
-	  if (BE (token->type == END_OF_RE, 0))
-	    {
-	      *err = REG_BADPAT;
-	      goto parse_bracket_exp_free_return;
-	    }
-	  *err = build_range_exp (sbcset,
-#ifdef RE_ENABLE_I18N
-				  mbcset, &range_alloc,
-#endif /* RE_ENABLE_I18N */
-				  &start_elem, &end_elem);
-	  if (BE (*err != REG_NOERROR, 0))
-	    goto parse_bracket_exp_free_return;
-	}
-      else
-	{
-	  switch (start_elem.type)
-	    {
-	    case SB_CHAR:
-	      bitset_set (sbcset, start_elem.opr.ch);
-	      break;
-#ifdef RE_ENABLE_I18N
-	    case MB_CHAR:
-	      /* Check whether the array has enough space.  */
-	      if (mbchar_alloc == mbcset->nmbchars)
-		{
-		  /* Not enough, realloc it.  */
-		  /* +1 in case of mbcset->nmbchars is 0.  */
-		  mbchar_alloc = 2 * mbcset->nmbchars + 1;
-		  /* Use realloc since array is NULL if *alloc == 0.  */
-		  mbcset->mbchars = re_realloc (mbcset->mbchars, wchar_t,
-						mbchar_alloc);
-		  if (BE (mbcset->mbchars == NULL, 0))
-		    goto parse_bracket_exp_espace;
-		}
-	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
-	      break;
-#endif /* RE_ENABLE_I18N */
-	    case EQUIV_CLASS:
-	      *err = build_equiv_class (sbcset,
-#ifdef RE_ENABLE_I18N
-					mbcset, &equiv_class_alloc,
-#endif /* RE_ENABLE_I18N */
-					start_elem.opr.name);
-	      if (BE (*err != REG_NOERROR, 0))
-		goto parse_bracket_exp_free_return;
-	      break;
-	    case COLL_SYM:
-	      *err = build_collating_symbol (sbcset,
-#ifdef RE_ENABLE_I18N
-					     mbcset, &coll_sym_alloc,
-#endif /* RE_ENABLE_I18N */
-					     start_elem.opr.name);
-	      if (BE (*err != REG_NOERROR, 0))
-		goto parse_bracket_exp_free_return;
-	      break;
-	    case CHAR_CLASS:
-	      *err = build_charclass (sbcset,
-#ifdef RE_ENABLE_I18N
-				      mbcset, &char_class_alloc,
-#endif /* RE_ENABLE_I18N */
-				      start_elem.opr.name, syntax);
-	      if (BE (*err != REG_NOERROR, 0))
-	       goto parse_bracket_exp_free_return;
-	      break;
-	    default:
-	      assert (0);
-	      break;
-	    }
-	}
-      if (token->type == OP_CLOSE_BRACKET)
-	break;
-    }
-
-  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
-
-  /* If it is non-matching list.  */
-#ifdef RE_ENABLE_I18N
-  if (mbcset->non_match)
-#else /* not RE_ENABLE_I18N */
-  if (non_match)
-#endif /* not RE_ENABLE_I18N */
-    bitset_not (sbcset);
-
-  /* Build a tree for simple bracket.  */
-  br_token.type = SIMPLE_BRACKET;
-  br_token.opr.sbcset = sbcset;
-  new_idx = re_dfa_add_node (dfa, br_token, 0);
-  work_tree = create_tree (NULL, NULL, 0, new_idx);
-  if (BE (new_idx == -1 || work_tree == NULL, 0))
-    goto parse_bracket_exp_espace;
-
-#ifdef RE_ENABLE_I18N
-  if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
-      || mbcset->nranges || (MB_CUR_MAX > 1 && (mbcset->nchar_classes
-						|| mbcset->non_match)))
-    {
-      re_token_t alt_token;
-      bin_tree_t *mbc_tree;
-      /* Build a tree for complex bracket.  */
-      br_token.type = COMPLEX_BRACKET;
-      br_token.opr.mbcset = mbcset;
-      dfa->has_mb_node = 1;
-      new_idx = re_dfa_add_node (dfa, br_token, 0);
-      mbc_tree = create_tree (NULL, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || mbc_tree == NULL, 0))
-	goto parse_bracket_exp_espace;
-      /* Then join them by ALT node.  */
-      dfa->has_plural_match = 1;
-      alt_token.type = OP_ALT;
-      new_idx = re_dfa_add_node (dfa, alt_token, 0);
-      work_tree = create_tree (work_tree, mbc_tree, 0, new_idx);
-      if (BE (new_idx != -1 && mbc_tree != NULL, 1))
-	return work_tree;
-    }
-  else
-    {
-      free_charset (mbcset);
-      return work_tree;
-    }
-#else /* not RE_ENABLE_I18N */
-  return work_tree;
-#endif /* not RE_ENABLE_I18N */
-
- parse_bracket_exp_espace:
-  *err = REG_ESPACE;
- parse_bracket_exp_free_return:
-  re_free (sbcset);
-#ifdef RE_ENABLE_I18N
-  free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
-  return NULL;
-}
-
-/* Parse an element in the bracket expression.  */
-
-static reg_errcode_t
-parse_bracket_element (elem, regexp, token, token_len, dfa, syntax)
-     bracket_elem_t *elem;
-     re_string_t *regexp;
-     re_token_t *token;
-     int token_len;
-     re_dfa_t *dfa;
-     reg_syntax_t syntax;
-{
-#ifdef RE_ENABLE_I18N
-  int cur_char_size;
-  cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
-  if (cur_char_size > 1)
-    {
-      elem->type = MB_CHAR;
-      elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));
-      re_string_skip_bytes (regexp, cur_char_size);
-      return REG_NOERROR;
-    }
-#endif /* RE_ENABLE_I18N */
-  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
-  if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
-      || token->type == OP_OPEN_EQUIV_CLASS)
-    return parse_bracket_symbol (elem, regexp, token);
-  elem->type = SB_CHAR;
-  elem->opr.ch = token->opr.c;
-  return REG_NOERROR;
-}
-
-/* Parse a bracket symbol in the bracket expression.  Bracket symbols are
-   such as [:<character_class>:], [.<collating_element>.], and
-   [=<equivalent_class>=].  */
-
-static reg_errcode_t
-parse_bracket_symbol (elem, regexp, token)
-     bracket_elem_t *elem;
-     re_string_t *regexp;
-     re_token_t *token;
-{
-  unsigned char ch, delim = token->opr.c;
-  int i = 0;
-  for (;; ++i)
-    {
-      if (re_string_eoi(regexp) || i >= BRACKET_NAME_BUF_SIZE)
-	return REG_EBRACK;
-      if (token->type == OP_OPEN_CHAR_CLASS)
-	ch = re_string_fetch_byte_case (regexp);
-      else
-	ch = re_string_fetch_byte (regexp);
-      if (ch == delim && re_string_peek_byte (regexp, 0) == ']')
-	break;
-      elem->opr.name[i] = ch;
-    }
-  re_string_skip_bytes (regexp, 1);
-  elem->opr.name[i] = '\0';
-  switch (token->type)
-    {
-    case OP_OPEN_COLL_ELEM:
-      elem->type = COLL_SYM;
-      break;
-    case OP_OPEN_EQUIV_CLASS:
-      elem->type = EQUIV_CLASS;
-      break;
-    case OP_OPEN_CHAR_CLASS:
-      elem->type = CHAR_CLASS;
-      break;
-    default:
-      break;
-    }
-  return REG_NOERROR;
-}
-
-  /* Helper function for parse_bracket_exp.
-     Build the equivalence class which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
-     is a pointer argument sinse we may update it.  */
-
-static reg_errcode_t
-#ifdef RE_ENABLE_I18N
-build_equiv_class (sbcset, mbcset, equiv_class_alloc, name)
-     re_charset_t *mbcset;
-     int *equiv_class_alloc;
-#else /* not RE_ENABLE_I18N */
-build_equiv_class (sbcset, name)
-#endif /* not RE_ENABLE_I18N */
-     re_bitset_ptr_t sbcset;
-     const unsigned char *name;
-{
-#if defined _LIBC && defined RE_ENABLE_I18N
-  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-  if (nrules != 0)
-    {
-      const int32_t *table, *indirect;
-      const unsigned char *weights, *extra, *cp;
-      unsigned char char_buf[2];
-      int32_t idx1, idx2;
-      unsigned int ch;
-      size_t len;
-      /* This #include defines a local function!  */
-# include <locale/weight.h>
-      /* Calculate the index for equivalence class.  */
-      cp = name;
-      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-      weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-					       _NL_COLLATE_WEIGHTMB);
-      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-						   _NL_COLLATE_EXTRAMB);
-      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-						_NL_COLLATE_INDIRECTMB);
-      idx1 = findidx (&cp);
-      if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
-	/* This isn't a valid character.  */
-	return REG_ECOLLATE;
-
-      /* Build single byte matcing table for this equivalence class.  */
-      char_buf[1] = (unsigned char) '\0';
-      len = weights[idx1];
-      for (ch = 0; ch < SBC_MAX; ++ch)
-	{
-	  char_buf[0] = ch;
-	  cp = char_buf;
-	  idx2 = findidx (&cp);
-/*
-	  idx2 = table[ch];
-*/
-	  if (idx2 == 0)
-	    /* This isn't a valid character.  */
-	    continue;
-	  if (len == weights[idx2])
-	    {
-	      int cnt = 0;
-	      while (cnt <= len &&
-		     weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt])
-		++cnt;
-
-	      if (cnt > len)
-		bitset_set (sbcset, ch);
-	    }
-	}
-      /* Check whether the array has enough space.  */
-      if (*equiv_class_alloc == mbcset->nequiv_classes)
-	{
-	  /* Not enough, realloc it.  */
-	  /* +1 in case of mbcset->nequiv_classes is 0.  */
-	  *equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
-	  /* Use realloc since the array is NULL if *alloc == 0.  */
-	  mbcset->equiv_classes = re_realloc (mbcset->equiv_classes, int32_t,
-					      *equiv_class_alloc);
-	  if (BE (mbcset->equiv_classes == NULL, 0))
-	    return REG_ESPACE;
-	}
-      mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
-    }
-  else
-#endif /* _LIBC && RE_ENABLE_I18N */
-    {
-      if (BE (strlen ((const char *) name) != 1, 0))
-	return REG_ECOLLATE;
-      bitset_set (sbcset, *name);
-    }
-  return REG_NOERROR;
-}
-
-  /* Helper function for parse_bracket_exp.
-     Build the character class which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
-     is a pointer argument sinse we may update it.  */
-
-static reg_errcode_t
-#ifdef RE_ENABLE_I18N
-build_charclass (sbcset, mbcset, char_class_alloc, class_name, syntax)
-     re_charset_t *mbcset;
-     int *char_class_alloc;
-#else /* not RE_ENABLE_I18N */
-build_charclass (sbcset, class_name, syntax)
-#endif /* not RE_ENABLE_I18N */
-     re_bitset_ptr_t sbcset;
-     const unsigned char *class_name;
-     reg_syntax_t syntax;
-{
-  int i;
-  const char *name = (const char *) class_name;
-
-  /* In case of REG_ICASE "upper" and "lower" match the both of
-     upper and lower cases.  */
-  if ((syntax & RE_ICASE)
-      && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
-    name = "alpha";
-
-#ifdef RE_ENABLE_I18N
-  /* Check the space of the arrays.  */
-  if (*char_class_alloc == mbcset->nchar_classes)
-    {
-      /* Not enough, realloc it.  */
-      /* +1 in case of mbcset->nchar_classes is 0.  */
-      *char_class_alloc = 2 * mbcset->nchar_classes + 1;
-      /* Use realloc since array is NULL if *alloc == 0.  */
-      mbcset->char_classes = re_realloc (mbcset->char_classes, wctype_t,
-					 *char_class_alloc);
-      if (BE (mbcset->char_classes == NULL, 0))
-	return REG_ESPACE;
-    }
-  mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
-#endif /* RE_ENABLE_I18N */
-
-#define BUILD_CHARCLASS_LOOP(ctype_func)\
-    for (i = 0; i < SBC_MAX; ++i)	\
-      {					\
-	if (ctype_func (i))		\
-	  bitset_set (sbcset, i);	\
-      }
-
-  if (strcmp (name, "alnum") == 0)
-    BUILD_CHARCLASS_LOOP (isalnum)
-  else if (strcmp (name, "cntrl") == 0)
-    BUILD_CHARCLASS_LOOP (iscntrl)
-  else if (strcmp (name, "lower") == 0)
-    BUILD_CHARCLASS_LOOP (islower)
-  else if (strcmp (name, "space") == 0)
-    BUILD_CHARCLASS_LOOP (isspace)
-  else if (strcmp (name, "alpha") == 0)
-    BUILD_CHARCLASS_LOOP (isalpha)
-  else if (strcmp (name, "digit") == 0)
-    BUILD_CHARCLASS_LOOP (isdigit)
-  else if (strcmp (name, "print") == 0)
-    BUILD_CHARCLASS_LOOP (isprint)
-  else if (strcmp (name, "upper") == 0)
-    BUILD_CHARCLASS_LOOP (isupper)
-  else if (strcmp (name, "blank") == 0)
-    BUILD_CHARCLASS_LOOP (isblank)
-  else if (strcmp (name, "graph") == 0)
-    BUILD_CHARCLASS_LOOP (isgraph)
-  else if (strcmp (name, "punct") == 0)
-    BUILD_CHARCLASS_LOOP (ispunct)
-  else if (strcmp (name, "xdigit") == 0)
-    BUILD_CHARCLASS_LOOP (isxdigit)
-  else
-    return REG_ECTYPE;
-
-  return REG_NOERROR;
-}
-
-static bin_tree_t *
-build_word_op (dfa, not, err)
-     re_dfa_t *dfa;
-     int not;
-     reg_errcode_t *err;
-{
-  re_bitset_ptr_t sbcset;
-#ifdef RE_ENABLE_I18N
-  re_charset_t *mbcset;
-  int alloc = 0;
-#else /* not RE_ENABLE_I18N */
-  int non_match = 0;
-#endif /* not RE_ENABLE_I18N */
-  reg_errcode_t ret;
-  re_token_t br_token;
-  bin_tree_t *tree;
-  int new_idx;
-
-  sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
-#ifdef RE_ENABLE_I18N
-  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
-
-#ifdef RE_ENABLE_I18N
-  if (BE (sbcset == NULL || mbcset == NULL, 0))
-#else /* not RE_ENABLE_I18N */
-  if (BE (sbcset == NULL, 0))
-#endif /* not RE_ENABLE_I18N */
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-
-  if (not)
-    {
-#ifdef RE_ENABLE_I18N
-      int i;
-      /*
-      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
-	bitset_set(cset->sbcset, '\0');
-      */
-      mbcset->non_match = 1;
-      if (MB_CUR_MAX > 1)
-	for (i = 0; i < SBC_MAX; ++i)
-	  if (__btowc (i) == WEOF)
-	    bitset_set (sbcset, i);
-#else /* not RE_ENABLE_I18N */
-      non_match = 1;
-#endif /* not RE_ENABLE_I18N */
-    }
-
-  /* We don't care the syntax in this case.  */
-  ret = build_charclass (sbcset,
-#ifdef RE_ENABLE_I18N
-			 mbcset, &alloc,
-#endif /* RE_ENABLE_I18N */
-			 (const unsigned char *) "alpha", 0);
-
-  if (BE (ret != REG_NOERROR, 0))
-    {
-      re_free (sbcset);
-#ifdef RE_ENABLE_I18N
-      free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
-      *err = ret;
-      return NULL;
-    }
-  /* \w match '_' also.  */
-  bitset_set (sbcset, '_');
-
-  /* If it is non-matching list.  */
-#ifdef RE_ENABLE_I18N
-  if (mbcset->non_match)
-#else /* not RE_ENABLE_I18N */
-  if (non_match)
-#endif /* not RE_ENABLE_I18N */
-    bitset_not (sbcset);
-
-  /* Build a tree for simple bracket.  */
-  br_token.type = SIMPLE_BRACKET;
-  br_token.opr.sbcset = sbcset;
-  new_idx = re_dfa_add_node (dfa, br_token, 0);
-  tree = create_tree (NULL, NULL, 0, new_idx);
-  if (BE (new_idx == -1 || tree == NULL, 0))
-    goto build_word_op_espace;
-
-#ifdef RE_ENABLE_I18N
-  if (MB_CUR_MAX > 1)
-    {
-      re_token_t alt_token;
-      bin_tree_t *mbc_tree;
-      /* Build a tree for complex bracket.  */
-      br_token.type = COMPLEX_BRACKET;
-      br_token.opr.mbcset = mbcset;
-      dfa->has_mb_node = 1;
-      new_idx = re_dfa_add_node (dfa, br_token, 0);
-      mbc_tree = create_tree (NULL, NULL, 0, new_idx);
-      if (BE (new_idx == -1 || mbc_tree == NULL, 0))
-	goto build_word_op_espace;
-      /* Then join them by ALT node.  */
-      alt_token.type = OP_ALT;
-      new_idx = re_dfa_add_node (dfa, alt_token, 0);
-      tree = create_tree (tree, mbc_tree, 0, new_idx);
-      if (BE (new_idx != -1 && mbc_tree != NULL, 1))
-	return tree;
-    }
-  else
-    {
-      free_charset (mbcset);
-      return tree;
-    }
-#else /* not RE_ENABLE_I18N */
-  return tree;
-#endif /* not RE_ENABLE_I18N */
-
- build_word_op_espace:
-  re_free (sbcset);
-#ifdef RE_ENABLE_I18N
-  free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
-  *err = REG_ESPACE;
-  return NULL;
-}
-
-/* This is intended for the expressions like "a{1,3}".
-   Fetch a number from `input', and return the number.
-   Return -1, if the number field is empty like "{,1}".
-   Return -2, If an error is occured.  */
-
-static int
-fetch_number (input, token, syntax)
-     re_string_t *input;
-     re_token_t *token;
-     reg_syntax_t syntax;
-{
-  int num = -1;
-  unsigned char c;
-  while (1)
-    {
-      *token = fetch_token (input, syntax);
-      c = token->opr.c;
-      if (BE (token->type == END_OF_RE, 0))
-	return -2;
-      if (token->type == OP_CLOSE_DUP_NUM || c == ',')
-	break;
-      num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2)
-	     ? -2 : ((num == -1) ? c - '0' : num * 10 + c - '0'));
-      num = (num > RE_DUP_MAX) ? -2 : num;
-    }
-  return num;
-}
-
-#ifdef RE_ENABLE_I18N
-static void
-free_charset (re_charset_t *cset)
-{
-  re_free (cset->mbchars);
-# ifdef _LIBC
-  re_free (cset->coll_syms);
-  re_free (cset->equiv_classes);
-  re_free (cset->range_starts);
-  re_free (cset->range_ends);
-# endif
-  re_free (cset->char_classes);
-  re_free (cset);
-}
-#endif /* RE_ENABLE_I18N */
-
-/* Functions for binary tree operation.  */
-
-/* Create a node of tree.
-   Note: This function automatically free left and right if malloc fails.  */
-
-static bin_tree_t *
-create_tree (left, right, type, index)
-     bin_tree_t *left;
-     bin_tree_t *right;
-     re_token_type_t type;
-     int index;
-{
-  bin_tree_t *tree;
-  tree = re_malloc (bin_tree_t, 1);
-  if (BE (tree == NULL, 0))
-    {
-      free_bin_tree (left);
-      free_bin_tree (right);
-      return NULL;
-    }
-  tree->parent = NULL;
-  tree->left = left;
-  tree->right = right;
-  tree->type = type;
-  tree->node_idx = index;
-  tree->first = -1;
-  tree->next = -1;
-  re_node_set_init_empty (&tree->eclosure);
-
-  if (left != NULL)
-    left->parent = tree;
-  if (right != NULL)
-    right->parent = tree;
-  return tree;
-}
-
-/* Free the sub tree pointed by TREE.  */
-
-static void
-free_bin_tree (tree)
-     bin_tree_t *tree;
-{
-  if (tree == NULL)
-    return;
-  /*re_node_set_free (&tree->eclosure);*/
-  free_bin_tree (tree->left);
-  free_bin_tree (tree->right);
-  re_free (tree);
-}
-
-/* Duplicate the node SRC, and return new node.  */
-
-static bin_tree_t *
-duplicate_tree (src, dfa)
-     const bin_tree_t *src;
-     re_dfa_t *dfa;
-{
-  bin_tree_t *left = NULL, *right = NULL, *new_tree;
-  int new_node_idx;
-  /* Since node indies must be according to Post-order of the tree,
-     we must duplicate the left at first.  */
-  if (src->left != NULL)
-    {
-      left = duplicate_tree (src->left, dfa);
-      if (left == NULL)
-	return NULL;
-    }
-
-  /* Secondaly, duplicate the right.  */
-  if (src->right != NULL)
-    {
-      right = duplicate_tree (src->right, dfa);
-      if (right == NULL)
-	{
-	  free_bin_tree (left);
-	  return NULL;
-	}
-    }
-
-  /* At last, duplicate itself.  */
-  if (src->type == NON_TYPE)
-    {
-      new_node_idx = re_dfa_add_node (dfa, dfa->nodes[src->node_idx], 0);
-      dfa->nodes[new_node_idx].duplicated = 1;
-      if (BE (new_node_idx == -1, 0))
-	{
-	  free_bin_tree (left);
-	  free_bin_tree (right);
-	  return NULL;
-	}
-    }
-  else
-    new_node_idx = src->type;
-
-  new_tree = create_tree (left, right, src->type, new_node_idx);
-  if (BE (new_tree == NULL, 0))
-    {
-      free_bin_tree (left);
-      free_bin_tree (right);
-    }
-  return new_tree;
-}
diff --git a/sm5/posix/regex.c b/sm5/posix/regex.c
deleted file mode 100644
index 98d86e1b8059fe3e061e53f4df02e53acacccf38..0000000000000000000000000000000000000000
--- a/sm5/posix/regex.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifdef _LIBC
-/* We have to keep the namespace clean.  */
-#  define regfree(preg) __regfree (preg)
-#  define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
-#  define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
-#  define regerror(errcode, preg, errbuf, errbuf_size) \
-	__regerror(errcode, preg, errbuf, errbuf_size)
-#  define re_set_registers(bu, re, nu, st, en) \
-	__re_set_registers (bu, re, nu, st, en)
-#  define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
-	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
-#  define re_match(bufp, string, size, pos, regs) \
-	__re_match (bufp, string, size, pos, regs)
-#  define re_search(bufp, string, size, startpos, range, regs) \
-	__re_search (bufp, string, size, startpos, range, regs)
-#  define re_compile_pattern(pattern, length, bufp) \
-	__re_compile_pattern (pattern, length, bufp)
-#  define re_set_syntax(syntax) __re_set_syntax (syntax)
-#  define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
-	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
-#  define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
-#endif
-
-/* POSIX says that <sys/types.h> must be included (by the caller) before
-   <regex.h>.  */
-#include <sys/types.h>
-#include <regex.h>
-#include "regex_internal.h"
-
-#include "regex_internal.c"
-#include "regcomp.c"
-#include "regexec.c"
-
-/* Binary backward compatibility.  */
-#if _LIBC
-# include <shlib-compat.h>
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
-link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
-int re_max_failures = 2000;
-# endif
-#endif
diff --git a/sm5/posix/regex.h b/sm5/posix/regex.h
deleted file mode 100644
index 314292b69645111a0a46e89a5ccf1a830ccd9b64..0000000000000000000000000000000000000000
--- a/sm5/posix/regex.h
+++ /dev/null
@@ -1,574 +0,0 @@
-/* Definitions for data structures and routines for the regular
-   expression library.
-   Copyright (C) 1985,1989-93,1995-98,2000,2001,2002
-   Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifndef _REGEX_H
-#define _REGEX_H 1
-
-/* Allow the use in C++ code.  */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* POSIX says that <sys/types.h> must be included (by the caller) before
-   <regex.h>.  */
-
-#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && (defined VMS || defined _MSC_VER)
-/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
-   should be there. Same for Microsoft Visual C++ 6.0 */
-# include <stddef.h>
-#endif
-
-/* The following two types have to be signed and unsigned integer type
-   wide enough to hold a value of a pointer.  For most ANSI compilers
-   ptrdiff_t and size_t should be likely OK.  Still size of these two
-   types is 2 for Microsoft C.  Ugh... */
-typedef long int s_reg_t;
-typedef unsigned long int active_reg_t;
-
-/* The following bits are used to determine the regexp syntax we
-   recognize.  The set/not-set meanings are chosen so that Emacs syntax
-   remains the value 0.  The bits are given in alphabetical order, and
-   the definitions shifted by one from the previous bit; thus, when we
-   add or remove a bit, only one other definition need change.  */
-typedef unsigned long int reg_syntax_t;
-
-/* If this bit is not set, then \ inside a bracket expression is literal.
-   If set, then such a \ quotes the following character.  */
-#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
-
-/* If this bit is not set, then + and ? are operators, and \+ and \? are
-     literals.
-   If set, then \+ and \? are operators and + and ? are literals.  */
-#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
-
-/* If this bit is set, then character classes are supported.  They are:
-     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
-     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
-   If not set, then character classes are not supported.  */
-#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
-
-/* If this bit is set, then ^ and $ are always anchors (outside bracket
-     expressions, of course).
-   If this bit is not set, then it depends:
-        ^  is an anchor if it is at the beginning of a regular
-           expression or after an open-group or an alternation operator;
-        $  is an anchor if it is at the end of a regular expression, or
-           before a close-group or an alternation operator.
-
-   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
-   POSIX draft 11.2 says that * etc. in leading positions is undefined.
-   We already implemented a previous draft which made those constructs
-   invalid, though, so we haven't changed the code back.  */
-#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
-
-/* If this bit is set, then special characters are always special
-     regardless of where they are in the pattern.
-   If this bit is not set, then special characters are special only in
-     some contexts; otherwise they are ordinary.  Specifically,
-     * + ? and intervals are only special when not after the beginning,
-     open-group, or alternation operator.  */
-#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
-
-/* If this bit is set, then *, +, ?, and { cannot be first in an re or
-     immediately after an alternation or begin-group operator.  */
-#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
-
-/* If this bit is set, then . matches newline.
-   If not set, then it doesn't.  */
-#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
-
-/* If this bit is set, then . doesn't match NUL.
-   If not set, then it does.  */
-#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
-
-/* If this bit is set, nonmatching lists [^...] do not match newline.
-   If not set, they do.  */
-#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
-
-/* If this bit is set, either \{...\} or {...} defines an
-     interval, depending on RE_NO_BK_BRACES.
-   If not set, \{, \}, {, and } are literals.  */
-#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
-
-/* If this bit is set, +, ? and | aren't recognized as operators.
-   If not set, they are.  */
-#define RE_LIMITED_OPS (RE_INTERVALS << 1)
-
-/* If this bit is set, newline is an alternation operator.
-   If not set, newline is literal.  */
-#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
-
-/* If this bit is set, then `{...}' defines an interval, and \{ and \}
-     are literals.
-  If not set, then `\{...\}' defines an interval.  */
-#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
-
-/* If this bit is set, (...) defines a group, and \( and \) are literals.
-   If not set, \(...\) defines a group, and ( and ) are literals.  */
-#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
-
-/* If this bit is set, then \<digit> matches <digit>.
-   If not set, then \<digit> is a back-reference.  */
-#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
-
-/* If this bit is set, then | is an alternation operator, and \| is literal.
-   If not set, then \| is an alternation operator, and | is literal.  */
-#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
-
-/* If this bit is set, then an ending range point collating higher
-     than the starting range point, as in [z-a], is invalid.
-   If not set, then when ending range point collates higher than the
-     starting range point, the range is ignored.  */
-#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
-
-/* If this bit is set, then an unmatched ) is ordinary.
-   If not set, then an unmatched ) is invalid.  */
-#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
-
-/* If this bit is set, succeed as soon as we match the whole pattern,
-   without further backtracking.  */
-#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
-
-/* If this bit is set, do not process the GNU regex operators.
-   If not set, then the GNU regex operators are recognized. */
-#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
-
-/* If this bit is set, turn on internal regex debugging.
-   If not set, and debugging was on, turn it off.
-   This only works if regex.c is compiled -DDEBUG.
-   We define this bit always, so that all that's needed to turn on
-   debugging is to recompile regex.c; the calling code can always have
-   this bit set, and it won't affect anything in the normal case. */
-#define RE_DEBUG (RE_NO_GNU_OPS << 1)
-
-/* If this bit is set, a syntactically invalid interval is treated as
-   a string of ordinary characters.  For example, the ERE 'a{1' is
-   treated as 'a\{1'.  */
-#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
-
-/* If this bit is set, then ignore case when matching.
-   If not set, then case is significant.  */
-#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
-
-/* This global variable defines the particular regexp syntax to use (for
-   some interfaces).  When a regexp is compiled, the syntax used is
-   stored in the pattern buffer, so changing this does not affect
-   already-compiled regexps.  */
-extern reg_syntax_t re_syntax_options;
-
-/* Define combinations of the above bits for the standard possibilities.
-   (The [[[ comments delimit what gets put into the Texinfo file, so
-   don't delete them!)  */
-/* [[[begin syntaxes]]] */
-#define RE_SYNTAX_EMACS 0
-
-#define RE_SYNTAX_AWK							\
-  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL			\
-   | RE_NO_BK_PARENS              | RE_NO_BK_REFS			\
-   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES			\
-   | RE_DOT_NEWLINE		  | RE_CONTEXT_INDEP_ANCHORS		\
-   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
-
-#define RE_SYNTAX_GNU_AWK						\
-  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG)	\
-   & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS		\
-       | RE_CONTEXT_INVALID_OPS ))
-
-#define RE_SYNTAX_POSIX_AWK 						\
-  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
-   | RE_INTERVALS	    | RE_NO_GNU_OPS)
-
-#define RE_SYNTAX_GREP							\
-  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES				\
-   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS				\
-   | RE_NEWLINE_ALT)
-
-#define RE_SYNTAX_EGREP							\
-  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS			\
-   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE			\
-   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS				\
-   | RE_NO_BK_VBAR)
-
-#define RE_SYNTAX_POSIX_EGREP						\
-  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES			\
-   | RE_INVALID_INTERVAL_ORD)
-
-/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
-#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
-
-#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
-
-/* Syntax bits common to both basic and extended POSIX regex syntax.  */
-#define _RE_SYNTAX_POSIX_COMMON						\
-  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
-   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
-
-#define RE_SYNTAX_POSIX_BASIC						\
-  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
-
-/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
-   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
-   isn't minimal, since other operators, such as \`, aren't disabled.  */
-#define RE_SYNTAX_POSIX_MINIMAL_BASIC					\
-  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
-
-#define RE_SYNTAX_POSIX_EXTENDED					\
-  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
-   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES				\
-   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR				\
-   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
-   removed and RE_NO_BK_REFS is added.  */
-#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED				\
-  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
-   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES				\
-   | RE_NO_BK_PARENS        | RE_NO_BK_REFS				\
-   | RE_NO_BK_VBAR	    | RE_UNMATCHED_RIGHT_PAREN_ORD)
-/* [[[end syntaxes]]] */
-
-/* Maximum number of duplicates an interval can allow.  Some systems
-   (erroneously) define this in other header files, but we want our
-   value, so remove any previous define.  */
-#ifdef RE_DUP_MAX
-# undef RE_DUP_MAX
-#endif
-/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows.  */
-#define RE_DUP_MAX (0x7fff)
-
-
-/* POSIX `cflags' bits (i.e., information for `regcomp').  */
-
-/* If this bit is set, then use extended regular expression syntax.
-   If not set, then use basic regular expression syntax.  */
-#define REG_EXTENDED 1
-
-/* If this bit is set, then ignore case when matching.
-   If not set, then case is significant.  */
-#define REG_ICASE (REG_EXTENDED << 1)
-
-/* If this bit is set, then anchors do not match at newline
-     characters in the string.
-   If not set, then anchors do match at newlines.  */
-#define REG_NEWLINE (REG_ICASE << 1)
-
-/* If this bit is set, then report only success or fail in regexec.
-   If not set, then returns differ between not matching and errors.  */
-#define REG_NOSUB (REG_NEWLINE << 1)
-
-
-/* POSIX `eflags' bits (i.e., information for regexec).  */
-
-/* If this bit is set, then the beginning-of-line operator doesn't match
-     the beginning of the string (presumably because it's not the
-     beginning of a line).
-   If not set, then the beginning-of-line operator does match the
-     beginning of the string.  */
-#define REG_NOTBOL 1
-
-/* Like REG_NOTBOL, except for the end-of-line.  */
-#define REG_NOTEOL (1 << 1)
-
-
-/* If any error codes are removed, changed, or added, update the
-   `re_error_msg' table in regex.c.  */
-typedef enum
-{
-#ifdef _XOPEN_SOURCE
-  REG_ENOSYS = -1,	/* This will never happen for this implementation.  */
-#endif
-
-  REG_NOERROR = 0,	/* Success.  */
-  REG_NOMATCH,		/* Didn't find a match (for regexec).  */
-
-  /* POSIX regcomp return error codes.  (In the order listed in the
-     standard.)  */
-  REG_BADPAT,		/* Invalid pattern.  */
-  REG_ECOLLATE,		/* Not implemented.  */
-  REG_ECTYPE,		/* Invalid character class name.  */
-  REG_EESCAPE,		/* Trailing backslash.  */
-  REG_ESUBREG,		/* Invalid back reference.  */
-  REG_EBRACK,		/* Unmatched left bracket.  */
-  REG_EPAREN,		/* Parenthesis imbalance.  */
-  REG_EBRACE,		/* Unmatched \{.  */
-  REG_BADBR,		/* Invalid contents of \{\}.  */
-  REG_ERANGE,		/* Invalid range end.  */
-  REG_ESPACE,		/* Ran out of memory.  */
-  REG_BADRPT,		/* No preceding re for repetition op.  */
-
-  /* Error codes we've added.  */
-  REG_EEND,		/* Premature end.  */
-  REG_ESIZE,		/* Compiled pattern bigger than 2^16 bytes.  */
-  REG_ERPAREN		/* Unmatched ) or \); not returned from regcomp.  */
-} reg_errcode_t;
-
-/* This data structure represents a compiled pattern.  Before calling
-   the pattern compiler, the fields `buffer', `allocated', `fastmap',
-   `translate', and `no_sub' can be set.  After the pattern has been
-   compiled, the `re_nsub' field is available.  All other fields are
-   private to the regex routines.  */
-
-#ifndef RE_TRANSLATE_TYPE
-# define RE_TRANSLATE_TYPE char *
-#endif
-
-struct re_pattern_buffer
-{
-/* [[[begin pattern_buffer]]] */
-	/* Space that holds the compiled pattern.  It is declared as
-          `unsigned char *' because its elements are
-           sometimes used as array indexes.  */
-  unsigned char *buffer;
-
-	/* Number of bytes to which `buffer' points.  */
-  unsigned long int allocated;
-
-	/* Number of bytes actually used in `buffer'.  */
-  unsigned long int used;
-
-        /* Syntax setting with which the pattern was compiled.  */
-  reg_syntax_t syntax;
-
-        /* Pointer to a fastmap, if any, otherwise zero.  re_search uses
-           the fastmap, if there is one, to skip over impossible
-           starting points for matches.  */
-  char *fastmap;
-
-        /* Either a translate table to apply to all characters before
-           comparing them, or zero for no translation.  The translation
-           is applied to a pattern when it is compiled and to a string
-           when it is matched.  */
-  RE_TRANSLATE_TYPE translate;
-
-	/* Number of subexpressions found by the compiler.  */
-  size_t re_nsub;
-
-        /* Zero if this pattern cannot match the empty string, one else.
-           Well, in truth it's used only in `re_search_2', to see
-           whether or not we should use the fastmap, so we don't set
-           this absolutely perfectly; see `re_compile_fastmap' (the
-           `duplicate' case).  */
-  unsigned can_be_null : 1;
-
-        /* If REGS_UNALLOCATED, allocate space in the `regs' structure
-             for `max (RE_NREGS, re_nsub + 1)' groups.
-           If REGS_REALLOCATE, reallocate space if necessary.
-           If REGS_FIXED, use what's there.  */
-#define REGS_UNALLOCATED 0
-#define REGS_REALLOCATE 1
-#define REGS_FIXED 2
-  unsigned regs_allocated : 2;
-
-        /* Set to zero when `regex_compile' compiles a pattern; set to one
-           by `re_compile_fastmap' if it updates the fastmap.  */
-  unsigned fastmap_accurate : 1;
-
-        /* If set, `re_match_2' does not return information about
-           subexpressions.  */
-  unsigned no_sub : 1;
-
-        /* If set, a beginning-of-line anchor doesn't match at the
-           beginning of the string.  */
-  unsigned not_bol : 1;
-
-        /* Similarly for an end-of-line anchor.  */
-  unsigned not_eol : 1;
-
-        /* If true, an anchor at a newline matches.  */
-  unsigned newline_anchor : 1;
-
-/* [[[end pattern_buffer]]] */
-};
-
-typedef struct re_pattern_buffer regex_t;
-
-/* Type for byte offsets within the string.  POSIX mandates this.  */
-typedef int regoff_t;
-
-
-/* This is the structure we store register match data in.  See
-   regex.texinfo for a full description of what registers match.  */
-struct re_registers
-{
-  unsigned num_regs;
-  regoff_t *start;
-  regoff_t *end;
-};
-
-
-/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
-   `re_match_2' returns information about at least this many registers
-   the first time a `regs' structure is passed.  */
-#ifndef RE_NREGS
-# define RE_NREGS 30
-#endif
-
-
-/* POSIX specification for registers.  Aside from the different names than
-   `re_registers', POSIX uses an array of structures, instead of a
-   structure of arrays.  */
-typedef struct
-{
-  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
-  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
-} regmatch_t;
-
-/* Declarations for routines.  */
-
-/* To avoid duplicating every routine declaration -- once with a
-   prototype (if we are ANSI), and once without (if we aren't) -- we
-   use the following macro to declare argument types.  This
-   unfortunately clutters up the declarations a bit, but I think it's
-   worth it.  */
-
-#if __STDC__
-
-# define _RE_ARGS(args) args
-
-#else /* not __STDC__ */
-
-# define _RE_ARGS(args) ()
-
-#endif /* not __STDC__ */
-
-/* Sets the current default syntax to SYNTAX, and return the old syntax.
-   You can also simply assign to the `re_syntax_options' variable.  */
-extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
-
-/* Compile the regular expression PATTERN, with length LENGTH
-   and syntax given by the global `re_syntax_options', into the buffer
-   BUFFER.  Return NULL if successful, and an error string if not.  */
-extern const char *re_compile_pattern
-  _RE_ARGS ((const char *pattern, size_t length,
-             struct re_pattern_buffer *buffer));
-
-
-/* Compile a fastmap for the compiled pattern in BUFFER; used to
-   accelerate searches.  Return 0 if successful and -2 if was an
-   internal error.  */
-extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
-
-
-/* Search in the string STRING (with length LENGTH) for the pattern
-   compiled into BUFFER.  Start searching at position START, for RANGE
-   characters.  Return the starting position of the match, -1 for no
-   match, or -2 for an internal error.  Also return register
-   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
-extern int re_search
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
-            int length, int start, int range, struct re_registers *regs));
-
-
-/* Like `re_search', but search in the concatenation of STRING1 and
-   STRING2.  Also, stop searching at index START + STOP.  */
-extern int re_search_2
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
-             int length1, const char *string2, int length2,
-             int start, int range, struct re_registers *regs, int stop));
-
-
-/* Like `re_search', but return how many characters in STRING the regexp
-   in BUFFER matched, starting at position START.  */
-extern int re_match
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
-             int length, int start, struct re_registers *regs));
-
-
-/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
-extern int re_match_2
-  _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
-             int length1, const char *string2, int length2,
-             int start, struct re_registers *regs, int stop));
-
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
-   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
-   for recording register information.  STARTS and ENDS must be
-   allocated with malloc, and must each be at least `NUM_REGS * sizeof
-   (regoff_t)' bytes long.
-
-   If NUM_REGS == 0, then subsequent matches should allocate their own
-   register data.
-
-   Unless this function is called, the first search or match using
-   PATTERN_BUFFER will allocate its own register data, without
-   freeing the old data.  */
-extern void re_set_registers
-  _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
-             unsigned num_regs, regoff_t *starts, regoff_t *ends));
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-# ifndef _CRAY
-/* 4.2 bsd compatibility.  */
-extern char *re_comp _RE_ARGS ((const char *));
-extern int re_exec _RE_ARGS ((const char *));
-# endif
-#endif
-
-/* GCC 2.95 and later have "__restrict"; C99 compilers have
-   "restrict", and "configure" may have defined "restrict".  */
-#ifndef __restrict
-# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
-#  if defined restrict || 199901L <= __STDC_VERSION__
-#   define __restrict restrict
-#  else
-#   define __restrict
-#  endif
-# endif
-#endif
-/* gcc 3.1 and up support the [restrict] syntax.  */
-#ifndef __restrict_arr
-# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-#  define __restrict_arr __restrict
-# else
-#  define __restrict_arr
-# endif
-#endif
-
-/* POSIX compatibility.  */
-extern int regcomp _RE_ARGS ((regex_t *__restrict __preg,
-			      const char *__restrict __pattern,
-			      int __cflags));
-
-extern int regexec _RE_ARGS ((const regex_t *__restrict __preg,
-			      const char *__restrict __string, size_t __nmatch,
-			      regmatch_t __pmatch[__restrict_arr],
-			      int __eflags));
-
-extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
-				  char *__errbuf, size_t __errbuf_size));
-
-extern void regfree _RE_ARGS ((regex_t *__preg));
-
-
-#ifdef __cplusplus
-}
-#endif	/* C++ */
-
-#endif /* regex.h */
-
-/*
-Local variables:
-make-backup-files: t
-version-control: t
-trim-versions-without-asking: nil
-End:
-*/
diff --git a/sm5/posix/regex_internal.c b/sm5/posix/regex_internal.c
deleted file mode 100644
index f969c7c89fd3d61a2f0a8096d33d2038bdc945f3..0000000000000000000000000000000000000000
--- a/sm5/posix/regex_internal.c
+++ /dev/null
@@ -1,1263 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-static void re_string_construct_common (const char *str, int len,
-					re_string_t *pstr,
-					RE_TRANSLATE_TYPE trans, int icase);
-#ifdef RE_ENABLE_I18N
-static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx,
-				 wint_t *last_wc);
-#endif /* RE_ENABLE_I18N */
-static re_dfastate_t *create_newstate_common (re_dfa_t *dfa,
-					      const re_node_set *nodes,
-					      unsigned int hash);
-static reg_errcode_t register_state (re_dfa_t *dfa, re_dfastate_t *newstate,
-				     unsigned int hash);
-static re_dfastate_t *create_ci_newstate (re_dfa_t *dfa,
-					  const re_node_set *nodes,
-					  unsigned int hash);
-static re_dfastate_t *create_cd_newstate (re_dfa_t *dfa,
-					  const re_node_set *nodes,
-					  unsigned int context,
-					  unsigned int hash);
-static unsigned int inline calc_state_hash (const re_node_set *nodes,
-					    unsigned int context);
-
-/* Functions for string operation.  */
-
-/* This function allocate the buffers.  It is necessary to call
-   re_string_reconstruct before using the object.  */
-
-static reg_errcode_t
-re_string_allocate (pstr, str, len, init_len, trans, icase)
-     re_string_t *pstr;
-     const char *str;
-     int len, init_len, icase;
-     RE_TRANSLATE_TYPE trans;
-{
-  reg_errcode_t ret;
-  int init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
-  re_string_construct_common (str, len, pstr, trans, icase);
-  pstr->stop = pstr->len;
-
-  ret = re_string_realloc_buffers (pstr, init_buf_len);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-
-  pstr->mbs_case = (MBS_CASE_ALLOCATED (pstr) ? pstr->mbs_case
-		    : (unsigned char *) str);
-  pstr->mbs = MBS_ALLOCATED (pstr) ? pstr->mbs : pstr->mbs_case;
-  pstr->valid_len = (MBS_CASE_ALLOCATED (pstr) || MBS_ALLOCATED (pstr)
-		     || MB_CUR_MAX > 1) ? pstr->valid_len : len;
-  return REG_NOERROR;
-}
-
-/* This function allocate the buffers, and initialize them.  */
-
-static reg_errcode_t
-re_string_construct (pstr, str, len, trans, icase)
-     re_string_t *pstr;
-     const char *str;
-     int len, icase;
-     RE_TRANSLATE_TYPE trans;
-{
-  reg_errcode_t ret;
-  re_string_construct_common (str, len, pstr, trans, icase);
-  pstr->stop = pstr->len;
-  /* Set 0 so that this function can initialize whole buffers.  */
-  pstr->valid_len = 0;
-
-  if (len > 0)
-    {
-      ret = re_string_realloc_buffers (pstr, len + 1);
-      if (BE (ret != REG_NOERROR, 0))
-	return ret;
-    }
-  pstr->mbs_case = (MBS_CASE_ALLOCATED (pstr) ? pstr->mbs_case
-		    : (unsigned char *) str);
-  pstr->mbs = MBS_ALLOCATED (pstr) ? pstr->mbs : pstr->mbs_case;
-
-  if (icase)
-    {
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	build_wcs_upper_buffer (pstr);
-      else
-#endif /* RE_ENABLE_I18N  */
-	build_upper_buffer (pstr);
-    }
-  else
-    {
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	build_wcs_buffer (pstr);
-      else
-#endif /* RE_ENABLE_I18N  */
-	{
-	  if (trans != NULL)
-	    re_string_translate_buffer (pstr);
-	  else
-	    pstr->valid_len = len;
-	}
-    }
-
-  /* Initialized whole buffers, then valid_len == bufs_len.  */
-  pstr->valid_len = pstr->bufs_len;
-  return REG_NOERROR;
-}
-
-/* Helper functions for re_string_allocate, and re_string_construct.  */
-
-static reg_errcode_t
-re_string_realloc_buffers (pstr, new_buf_len)
-     re_string_t *pstr;
-     int new_buf_len;
-{
-#ifdef RE_ENABLE_I18N
-  if (MB_CUR_MAX > 1)
-    {
-      wint_t *new_array = re_realloc (pstr->wcs, wint_t, new_buf_len);
-      if (BE (new_array == NULL, 0))
-	return REG_ESPACE;
-      pstr->wcs = new_array;
-    }
-#endif /* RE_ENABLE_I18N  */
-  if (MBS_ALLOCATED (pstr))
-    {
-      unsigned char *new_array = re_realloc (pstr->mbs, unsigned char,
-					     new_buf_len);
-      if (BE (new_array == NULL, 0))
-	return REG_ESPACE;
-      pstr->mbs = new_array;
-    }
-  if (MBS_CASE_ALLOCATED (pstr))
-    {
-      unsigned char *new_array = re_realloc (pstr->mbs_case, unsigned char,
-					     new_buf_len);
-      if (BE (new_array == NULL, 0))
-	return REG_ESPACE;
-      pstr->mbs_case = new_array;
-      if (!MBS_ALLOCATED (pstr))
-	pstr->mbs = pstr->mbs_case;
-    }
-  pstr->bufs_len = new_buf_len;
-  return REG_NOERROR;
-}
-
-
-static void
-re_string_construct_common (str, len, pstr, trans, icase)
-     const char *str;
-     int len;
-     re_string_t *pstr;
-     RE_TRANSLATE_TYPE trans;
-     int icase;
-{
-  memset (pstr, '\0', sizeof (re_string_t));
-  pstr->raw_mbs = (const unsigned char *) str;
-  pstr->len = len;
-  pstr->trans = trans;
-  pstr->icase = icase ? 1 : 0;
-}
-
-#ifdef RE_ENABLE_I18N
-
-/* Build wide character buffer PSTR->WCS.
-   If the byte sequence of the string are:
-     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
-   Then wide character buffer will be:
-     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>
-   We use WEOF for padding, they indicate that the position isn't
-   a first byte of a multibyte character.
-
-   Note that this function assumes PSTR->VALID_LEN elements are already
-   built and starts from PSTR->VALID_LEN.  */
-
-static void
-build_wcs_buffer (pstr)
-     re_string_t *pstr;
-{
-  mbstate_t prev_st;
-  int byte_idx, end_idx, mbclen, remain_len;
-  /* Build the buffers from pstr->valid_len to either pstr->len or
-     pstr->bufs_len.  */
-  end_idx = (pstr->bufs_len > pstr->len)? pstr->len : pstr->bufs_len;
-  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
-    {
-      wchar_t wc;
-      remain_len = end_idx - byte_idx;
-      prev_st = pstr->cur_state;
-      mbclen = mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
-			      + byte_idx), remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2, 0))
-	{
-	  /* The buffer doesn't have enough space, finish to build.  */
-	  pstr->cur_state = prev_st;
-	  break;
-	}
-      else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
-	{
-	  /* We treat these cases as a singlebyte character.  */
-	  mbclen = 1;
-	  wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
-	  pstr->cur_state = prev_st;
-	}
-
-      /* Apply the translateion if we need.  */
-      if (pstr->trans != NULL && mbclen == 1)
-	{
-	  int ch = pstr->trans[pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]];
-	  pstr->mbs_case[byte_idx] = ch;
-	}
-      /* Write wide character and padding.  */
-      pstr->wcs[byte_idx++] = wc;
-      /* Write paddings.  */
-      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
-	pstr->wcs[byte_idx++] = WEOF;
-    }
-  pstr->valid_len = byte_idx;
-}
-
-/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
-   but for REG_ICASE.  */
-
-static void
-build_wcs_upper_buffer (pstr)
-     re_string_t *pstr;
-{
-  mbstate_t prev_st;
-  int byte_idx, end_idx, mbclen, remain_len;
-  /* Build the buffers from pstr->valid_len to either pstr->len or
-     pstr->bufs_len.  */
-  end_idx = (pstr->bufs_len > pstr->len)? pstr->len : pstr->bufs_len;
-  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
-    {
-      wchar_t wc;
-      remain_len = end_idx - byte_idx;
-      prev_st = pstr->cur_state;
-      mbclen = mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
-			      + byte_idx), remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2, 0))
-	{
-	  /* The buffer doesn't have enough space, finish to build.  */
-	  pstr->cur_state = prev_st;
-	  break;
-	}
-      else if (mbclen == 1 || mbclen == (size_t) -1 || mbclen == 0)
-	{
-	  /* In case of a singlebyte character.  */
-	  int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
-	  /* Apply the translateion if we need.  */
-	  if (pstr->trans != NULL && mbclen == 1)
-	    {
-	      ch = pstr->trans[ch];
-	      pstr->mbs_case[byte_idx] = ch;
-	    }
-	  pstr->wcs[byte_idx] = iswlower (wc) ? toupper (wc) : wc;
-	  pstr->mbs[byte_idx++] = islower (ch) ? toupper (ch) : ch;
-	  if (BE (mbclen == (size_t) -1, 0))
-	    pstr->cur_state = prev_st;
-	}
-      else /* mbclen > 1 */
-	{
-	  if (iswlower (wc))
-	    wcrtomb ((char *) pstr->mbs + byte_idx, towupper (wc), &prev_st);
-	  else
-	    memcpy (pstr->mbs + byte_idx,
-		    pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
-	  pstr->wcs[byte_idx++] = iswlower (wc) ? toupper (wc) : wc;
-	  /* Write paddings.  */
-	  for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
-	    pstr->wcs[byte_idx++] = WEOF;
-	}
-    }
-  pstr->valid_len = byte_idx;
-}
-
-/* Skip characters until the index becomes greater than NEW_RAW_IDX.
-   Return the index.  */
-
-static int
-re_string_skip_chars (pstr, new_raw_idx, last_wc)
-     re_string_t *pstr;
-     int new_raw_idx;
-     wint_t *last_wc;
-{
-  mbstate_t prev_st;
-  int rawbuf_idx, mbclen;
-  wchar_t wc = 0;
-
-  /* Skip the characters which are not necessary to check.  */
-  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_len;
-       rawbuf_idx < new_raw_idx;)
-    {
-      int remain_len;
-      remain_len = pstr->len - rawbuf_idx;
-      prev_st = pstr->cur_state;
-      mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,
-			remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
-	{
-	  /* We treat these cases as a singlebyte character.  */
-	  mbclen = 1;
-	  pstr->cur_state = prev_st;
-	}
-      /* Then proceed the next character.  */
-      rawbuf_idx += mbclen;
-    }
-  *last_wc = (wint_t) wc;
-  return rawbuf_idx;
-}
-#endif /* RE_ENABLE_I18N  */
-
-/* Build the buffer PSTR->MBS, and apply the translation if we need.
-   This function is used in case of REG_ICASE.  */
-
-static void
-build_upper_buffer (pstr)
-     re_string_t *pstr;
-{
-  int char_idx, end_idx;
-  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
-
-  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
-    {
-      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
-      if (pstr->trans != NULL)
-	{
-	  ch =  pstr->trans[ch];
-	  pstr->mbs_case[char_idx] = ch;
-	}
-      if (islower (ch))
-	pstr->mbs[char_idx] = toupper (ch);
-      else
-	pstr->mbs[char_idx] = ch;
-    }
-  pstr->valid_len = char_idx;
-}
-
-/* Apply TRANS to the buffer in PSTR.  */
-
-static void
-re_string_translate_buffer (pstr)
-     re_string_t *pstr;
-{
-  int buf_idx, end_idx;
-  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
-
-  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
-    {
-      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
-      pstr->mbs_case[buf_idx] = pstr->trans[ch];
-    }
-
-  pstr->valid_len = buf_idx;
-}
-
-/* This function re-construct the buffers.
-   Concretely, convert to wide character in case of MB_CUR_MAX > 1,
-   convert to upper case in case of REG_ICASE, apply translation.  */
-
-static reg_errcode_t
-re_string_reconstruct (pstr, idx, eflags, newline)
-     re_string_t *pstr;
-     int idx, eflags, newline;
-{
-  int offset = idx - pstr->raw_mbs_idx;
-  if (offset < 0)
-    {
-      /* Reset buffer.  */
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
-#endif /* RE_ENABLE_I18N */
-      pstr->len += pstr->raw_mbs_idx;
-      pstr->stop += pstr->raw_mbs_idx;
-      pstr->valid_len = pstr->raw_mbs_idx = 0;
-      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
-			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
-      if (!MBS_CASE_ALLOCATED (pstr))
-	pstr->mbs_case = (unsigned char *) pstr->raw_mbs;
-      if (!MBS_ALLOCATED (pstr) && !MBS_CASE_ALLOCATED (pstr))
-	pstr->mbs = (unsigned char *) pstr->raw_mbs;
-      offset = idx;
-    }
-
-  if (offset != 0)
-    {
-      /* Are the characters which are already checked remain?  */
-      if (offset < pstr->valid_len)
-	{
-	  /* Yes, move them to the front of the buffer.  */
-	  pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags,
-						    newline);
-#ifdef RE_ENABLE_I18N
-	  if (MB_CUR_MAX > 1)
-	    memmove (pstr->wcs, pstr->wcs + offset,
-		     (pstr->valid_len - offset) * sizeof (wint_t));
-#endif /* RE_ENABLE_I18N */
-	  if (MBS_ALLOCATED (pstr))
-	    memmove (pstr->mbs, pstr->mbs + offset,
-		     pstr->valid_len - offset);
-	  if (MBS_CASE_ALLOCATED (pstr))
-	    memmove (pstr->mbs_case, pstr->mbs_case + offset,
-		     pstr->valid_len - offset);
-	  pstr->valid_len -= offset;
-#if DEBUG
-	  assert (pstr->valid_len > 0);
-#endif
-	}
-      else
-	{
-	  /* No, skip all characters until IDX.  */
-	  pstr->valid_len = 0;
-#ifdef RE_ENABLE_I18N
-	  if (MB_CUR_MAX > 1)
-	    {
-	      int wcs_idx;
-	      wint_t wc;
-	      pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
-	      for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
-		pstr->wcs[wcs_idx] = WEOF;
-	      if (pstr->trans && wc <= 0xff)
-		wc = pstr->trans[wc];
-	      pstr->tip_context = (IS_WIDE_WORD_CHAR (wc) ? CONTEXT_WORD
-				   : ((newline && IS_WIDE_NEWLINE (wc))
-				      ? CONTEXT_NEWLINE : 0));
-	    }
-	  else
-#endif /* RE_ENABLE_I18N */
-	    {
-	      int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
-	      if (pstr->trans)
-		c = pstr->trans[c];
-	      pstr->tip_context = (IS_WORD_CHAR (c) ? CONTEXT_WORD
-				   : ((newline && IS_NEWLINE (c))
-				      ? CONTEXT_NEWLINE : 0));
-	    }
-	}
-      if (!MBS_CASE_ALLOCATED (pstr))
-	{
-	  pstr->mbs_case += offset;
-	  /* In case of !MBS_ALLOCATED && !MBS_CASE_ALLOCATED.  */
-	  if (!MBS_ALLOCATED (pstr))
-	    pstr->mbs += offset;
-	}
-    }
-  pstr->raw_mbs_idx = idx;
-  pstr->len -= offset;
-  pstr->stop -= offset;
-
-  /* Then build the buffers.  */
-#ifdef RE_ENABLE_I18N
-  if (MB_CUR_MAX > 1)
-    {
-      if (pstr->icase)
-	build_wcs_upper_buffer (pstr);
-      else
-	build_wcs_buffer (pstr);
-    }
-  else
-#endif /* RE_ENABLE_I18N */
-    {
-      if (pstr->icase)
-	build_upper_buffer (pstr);
-      else if (pstr->trans != NULL)
-	re_string_translate_buffer (pstr);
-    }
-  pstr->cur_idx = 0;
-
-  return REG_NOERROR;
-}
-
-static void
-re_string_destruct (pstr)
-     re_string_t *pstr;
-{
-#ifdef RE_ENABLE_I18N
-  re_free (pstr->wcs);
-#endif /* RE_ENABLE_I18N  */
-  if (MBS_ALLOCATED (pstr))
-    re_free (pstr->mbs);
-  if (MBS_CASE_ALLOCATED (pstr))
-    re_free (pstr->mbs_case);
-}
-
-/* Return the context at IDX in INPUT.  */
-
-static unsigned int
-re_string_context_at (input, idx, eflags, newline_anchor)
-     const re_string_t *input;
-     int idx, eflags, newline_anchor;
-{
-  int c;
-  if (idx < 0 || idx == input->len)
-    {
-      if (idx < 0)
-	/* In this case, we use the value stored in input->tip_context,
-	   since we can't know the character in input->mbs[-1] here.  */
-	return input->tip_context;
-      else /* (idx == input->len) */
-	return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
-		: CONTEXT_NEWLINE | CONTEXT_ENDBUF);
-    }
-#ifdef RE_ENABLE_I18N
-  if (MB_CUR_MAX > 1)
-    {
-      wint_t wc;
-      int wc_idx = idx;
-      while(input->wcs[wc_idx] == WEOF)
-	{
-#ifdef DEBUG
-	  /* It must not happen.  */
-	  assert (wc_idx >= 0);
-#endif
-	  --wc_idx;
-	  if (wc_idx < 0)
-	    return input->tip_context;
-	}
-      wc = input->wcs[wc_idx];
-      if (IS_WIDE_WORD_CHAR (wc))
-	return CONTEXT_WORD;
-      return (newline_anchor && IS_WIDE_NEWLINE (wc)) ? CONTEXT_NEWLINE : 0;
-    }
-  else
-#endif
-    {
-      c = re_string_byte_at (input, idx);
-      if (IS_WORD_CHAR (c))
-	return CONTEXT_WORD;
-      return (newline_anchor && IS_NEWLINE (c)) ? CONTEXT_NEWLINE : 0;
-    }
-}
-
-/* Functions for set operation.  */
-
-static reg_errcode_t
-re_node_set_alloc (set, size)
-     re_node_set *set;
-     int size;
-{
-  set->alloc = size;
-  set->nelem = 0;
-  set->elems = re_malloc (int, size);
-  if (BE (set->elems == NULL, 0))
-    return REG_ESPACE;
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-re_node_set_init_1 (set, elem)
-     re_node_set *set;
-     int elem;
-{
-  set->alloc = 1;
-  set->nelem = 1;
-  set->elems = re_malloc (int, 1);
-  if (BE (set->elems == NULL, 0))
-    {
-      set->alloc = set->nelem = 0;
-      return REG_ESPACE;
-    }
-  set->elems[0] = elem;
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-re_node_set_init_2 (set, elem1, elem2)
-     re_node_set *set;
-     int elem1, elem2;
-{
-  set->alloc = 2;
-  set->elems = re_malloc (int, 2);
-  if (BE (set->elems == NULL, 0))
-    return REG_ESPACE;
-  if (elem1 == elem2)
-    {
-      set->nelem = 1;
-      set->elems[0] = elem1;
-    }
-  else
-    {
-      set->nelem = 2;
-      if (elem1 < elem2)
-	{
-	  set->elems[0] = elem1;
-	  set->elems[1] = elem2;
-	}
-      else
-	{
-	  set->elems[0] = elem2;
-	  set->elems[1] = elem1;
-	}
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-re_node_set_init_copy (dest, src)
-     re_node_set *dest;
-     const re_node_set *src;
-{
-  dest->nelem = src->nelem;
-  if (src->nelem > 0)
-    {
-      dest->alloc = dest->nelem;
-      dest->elems = re_malloc (int, dest->alloc);
-      if (BE (dest->elems == NULL, 0))
-	{
-	  dest->alloc = dest->nelem = 0;
-	  return REG_ESPACE;
-	}
-      memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
-    }
-  else
-    re_node_set_init_empty (dest);
-  return REG_NOERROR;
-}
-
-/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
-   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
-
-static reg_errcode_t
-re_node_set_add_intersect (dest, src1, src2)
-     re_node_set *dest;
-     const re_node_set *src1, *src2;
-{
-  int i1, i2, id;
-  if (src1->nelem > 0 && src2->nelem > 0)
-    {
-      if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
-	{
-	  dest->alloc = src1->nelem + src2->nelem + dest->nelem;
-	  dest->elems = re_realloc (dest->elems, int, dest->alloc);
-	  if (BE (dest->elems == NULL, 0))
-	    return REG_ESPACE;
-	}
-    }
-  else
-    return REG_NOERROR;
-
-  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
-    {
-      if (src1->elems[i1] > src2->elems[i2])
-	{
-	  ++i2;
-	  continue;
-	}
-      if (src1->elems[i1] == src2->elems[i2])
-	{
-	  while (id < dest->nelem && dest->elems[id] < src2->elems[i2])
-	    ++id;
-	  if (id < dest->nelem && dest->elems[id] == src2->elems[i2])
-	    ++id;
-	  else
-	    {
-	      memmove (dest->elems + id + 1, dest->elems + id,
-		       sizeof (int) * (dest->nelem - id));
-	      dest->elems[id++] = src2->elems[i2++];
-	      ++dest->nelem;
-	    }
-	}
-      ++i1;
-    }
-  return REG_NOERROR;
-}
-
-/* Calculate the union set of the sets SRC1 and SRC2. And store it to
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
-
-static reg_errcode_t
-re_node_set_init_union (dest, src1, src2)
-     re_node_set *dest;
-     const re_node_set *src1, *src2;
-{
-  int i1, i2, id;
-  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
-    {
-      dest->alloc = src1->nelem + src2->nelem;
-      dest->elems = re_malloc (int, dest->alloc);
-      if (BE (dest->elems == NULL, 0))
-	return REG_ESPACE;
-    }
-  else
-    {
-      if (src1 != NULL && src1->nelem > 0)
-	return re_node_set_init_copy (dest, src1);
-      else if (src2 != NULL && src2->nelem > 0)
-	return re_node_set_init_copy (dest, src2);
-      else
-	re_node_set_init_empty (dest);
-      return REG_NOERROR;
-    }
-  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
-    {
-      if (src1->elems[i1] > src2->elems[i2])
-	{
-	  dest->elems[id++] = src2->elems[i2++];
-	  continue;
-	}
-      if (src1->elems[i1] == src2->elems[i2])
-	++i2;
-      dest->elems[id++] = src1->elems[i1++];
-    }
-  if (i1 < src1->nelem)
-    {
-      memcpy (dest->elems + id, src1->elems + i1,
-	     (src1->nelem - i1) * sizeof (int));
-      id += src1->nelem - i1;
-    }
-  else if (i2 < src2->nelem)
-    {
-      memcpy (dest->elems + id, src2->elems + i2,
-	     (src2->nelem - i2) * sizeof (int));
-      id += src2->nelem - i2;
-    }
-  dest->nelem = id;
-  return REG_NOERROR;
-}
-
-/* Calculate the union set of the sets DEST and SRC. And store it to
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
-
-static reg_errcode_t
-re_node_set_merge (dest, src)
-     re_node_set *dest;
-     const re_node_set *src;
-{
-  int si, di;
-  if (src == NULL || src->nelem == 0)
-    return REG_NOERROR;
-  if (dest->alloc < src->nelem + dest->nelem)
-    {
-      int *new_buffer;
-      dest->alloc = 2 * (src->nelem + dest->alloc);
-      new_buffer = re_realloc (dest->elems, int, dest->alloc);
-      if (BE (new_buffer == NULL, 0))
-	return REG_ESPACE;
-      dest->elems = new_buffer;
-    }
-
-  for (si = 0, di = 0 ; si < src->nelem && di < dest->nelem ;)
-    {
-      int cp_from, ncp, mid, right, src_elem = src->elems[si];
-      /* Binary search the spot we will add the new element.  */
-      right = dest->nelem;
-      while (di < right)
-	{
-	  mid = (di + right) / 2;
-	  if (dest->elems[mid] < src_elem)
-	    di = mid + 1;
-	  else
-	    right = mid;
-	}
-      if (di >= dest->nelem)
-	break;
-
-      if (dest->elems[di] == src_elem)
-	{
-	  /* Skip since, DEST already has the element.  */
-	  ++di;
-	  ++si;
-	  continue;
-	}
-
-      /* Skip the src elements which are less than dest->elems[di].  */
-      cp_from = si;
-      while (si < src->nelem && src->elems[si] < dest->elems[di])
-	++si;
-      /* Copy these src elements.  */
-      ncp = si - cp_from;
-      memmove (dest->elems + di + ncp, dest->elems + di,
-	       sizeof (int) * (dest->nelem - di));
-      memcpy (dest->elems + di, src->elems + cp_from,
-	      sizeof (int) * ncp);
-      /* Update counters.  */
-      di += ncp;
-      dest->nelem += ncp;
-    }
-
-  /* Copy remaining src elements.  */
-  if (si < src->nelem)
-    {
-      memcpy (dest->elems + di, src->elems + si,
-	      sizeof (int) * (src->nelem - si));
-      dest->nelem += src->nelem - si;
-    }
-  return REG_NOERROR;
-}
-
-/* Insert the new element ELEM to the re_node_set* SET.
-   return 0 if SET already has ELEM,
-   return -1 if an error is occured, return 1 otherwise.  */
-
-static int
-re_node_set_insert (set, elem)
-     re_node_set *set;
-     int elem;
-{
-  int idx, right, mid;
-  /* In case of the set is empty.  */
-  if (set->elems == NULL || set->alloc == 0)
-    {
-      if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
-	return 1;
-      else
-	return -1;
-    }
-
-  /* Binary search the spot we will add the new element.  */
-  idx = 0;
-  right = set->nelem;
-  while (idx < right)
-    {
-      mid = (idx + right) / 2;
-      if (set->elems[mid] < elem)
-	idx = mid + 1;
-      else
-	right = mid;
-    }
-
-  /* Realloc if we need.  */
-  if (set->alloc < set->nelem + 1)
-    {
-      int *new_array;
-      set->alloc = set->alloc * 2;
-      new_array = re_malloc (int, set->alloc);
-      if (BE (new_array == NULL, 0))
-	return -1;
-      /* Copy the elements they are followed by the new element.  */
-      if (idx > 0)
-	memcpy (new_array, set->elems, sizeof (int) * (idx));
-      /* Copy the elements which follows the new element.  */
-      if (set->nelem - idx > 0)
-	memcpy (new_array + idx + 1, set->elems + idx,
-		sizeof (int) * (set->nelem - idx));
-      re_free (set->elems);
-      set->elems = new_array;
-    }
-  else
-    {
-      /* Move the elements which follows the new element.  */
-      if (set->nelem - idx > 0)
-	memmove (set->elems + idx + 1, set->elems + idx,
-		 sizeof (int) * (set->nelem - idx));
-    }
-  /* Insert the new element.  */
-  set->elems[idx] = elem;
-  ++set->nelem;
-  return 1;
-}
-
-/* Compare two node sets SET1 and SET2.
-   return 1 if SET1 and SET2 are equivalent, retrun 0 otherwise.  */
-
-static int
-re_node_set_compare (set1, set2)
-     const re_node_set *set1, *set2;
-{
-  int i;
-  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
-    return 0;
-  for (i = 0 ; i < set1->nelem ; i++)
-    if (set1->elems[i] != set2->elems[i])
-      return 0;
-  return 1;
-}
-
-/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
-
-static int
-re_node_set_contains (set, elem)
-     const re_node_set *set;
-     int elem;
-{
-  int idx, right, mid;
-  if (set->nelem <= 0)
-    return 0;
-
-  /* Binary search the element.  */
-  idx = 0;
-  right = set->nelem - 1;
-  while (idx < right)
-    {
-      mid = (idx + right) / 2;
-      if (set->elems[mid] < elem)
-	idx = mid + 1;
-      else
-	right = mid;
-    }
-  return set->elems[idx] == elem ? idx + 1 : 0;
-}
-
-static void
-re_node_set_remove_at (set, idx)
-     re_node_set *set;
-     int idx;
-{
-  if (idx < 0 || idx >= set->nelem)
-    return;
-  if (idx < set->nelem - 1)
-    memmove (set->elems + idx, set->elems + idx + 1,
-	     sizeof (int) * (set->nelem - idx - 1));
-  --set->nelem;
-}
-
-
-/* Add the token TOKEN to dfa->nodes, and return the index of the token.
-   Or return -1, if an error will be occured.  */
-
-static int
-re_dfa_add_node (dfa, token, mode)
-     re_dfa_t *dfa;
-     re_token_t token;
-     int mode;
-{
-  if (dfa->nodes_len >= dfa->nodes_alloc)
-    {
-      re_token_t *new_array;
-      dfa->nodes_alloc *= 2;
-      new_array = re_realloc (dfa->nodes, re_token_t, dfa->nodes_alloc);
-      if (BE (new_array == NULL, 0))
-	return -1;
-      else
-	dfa->nodes = new_array;
-      if (mode)
-	{
-	  int *new_nexts, *new_indices;
-	  re_node_set *new_edests, *new_eclosures, *new_inveclosures;
-
-	  new_nexts = re_realloc (dfa->nexts, int, dfa->nodes_alloc);
-	  new_indices = re_realloc (dfa->org_indices, int, dfa->nodes_alloc);
-	  new_edests = re_realloc (dfa->edests, re_node_set, dfa->nodes_alloc);
-	  new_eclosures = re_realloc (dfa->eclosures, re_node_set,
-				      dfa->nodes_alloc);
-	  new_inveclosures = re_realloc (dfa->inveclosures, re_node_set,
-					 dfa->nodes_alloc);
-	  if (BE (new_nexts == NULL || new_indices == NULL
-		  || new_edests == NULL || new_eclosures == NULL
-		  || new_inveclosures == NULL, 0))
-	    return -1;
-	  dfa->nexts = new_nexts;
-	  dfa->org_indices = new_indices;
-	  dfa->edests = new_edests;
-	  dfa->eclosures = new_eclosures;
-	  dfa->inveclosures = new_inveclosures;
-	}
-    }
-  dfa->nodes[dfa->nodes_len] = token;
-  dfa->nodes[dfa->nodes_len].duplicated = 0;
-  dfa->nodes[dfa->nodes_len].constraint = 0;
-  return dfa->nodes_len++;
-}
-
-static unsigned int inline
-calc_state_hash (nodes, context)
-     const re_node_set *nodes;
-     unsigned int context;
-{
-  unsigned int hash = nodes->nelem + context;
-  int i;
-  for (i = 0 ; i < nodes->nelem ; i++)
-    hash += nodes->elems[i];
-  return hash;
-}
-
-/* Search for the state whose node_set is equivalent to NODES.
-   Return the pointer to the state, if we found it in the DFA.
-   Otherwise create the new one and return it.  In case of an error
-   return NULL and set the error code in ERR.
-   Note: - We assume NULL as the invalid state, then it is possible that
-	   return value is NULL and ERR is REG_NOERROR.
-	 - We never return non-NULL value in case of any errors, it is for
-	   optimization.  */
-
-static re_dfastate_t*
-re_acquire_state (err, dfa, nodes)
-     reg_errcode_t *err;
-     re_dfa_t *dfa;
-     const re_node_set *nodes;
-{
-  unsigned int hash;
-  re_dfastate_t *new_state;
-  struct re_state_table_entry *spot;
-  int i;
-  if (BE (nodes->nelem == 0, 0))
-    {
-      *err = REG_NOERROR;
-      return NULL;
-    }
-  hash = calc_state_hash (nodes, 0);
-  spot = dfa->state_table + (hash & dfa->state_hash_mask);
-
-  for (i = 0 ; i < spot->num ; i++)
-    {
-      re_dfastate_t *state = spot->array[i];
-      if (hash != state->hash)
-	continue;
-      if (re_node_set_compare (&state->nodes, nodes))
-	return state;
-    }
-
-  /* There are no appropriate state in the dfa, create the new one.  */
-  new_state = create_ci_newstate (dfa, nodes, hash);
-  if (BE (new_state != NULL, 1))
-    return new_state;
-  else
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-}
-
-/* Search for the state whose node_set is equivalent to NODES and
-   whose context is equivalent to CONTEXT.
-   Return the pointer to the state, if we found it in the DFA.
-   Otherwise create the new one and return it.  In case of an error
-   return NULL and set the error code in ERR.
-   Note: - We assume NULL as the invalid state, then it is possible that
-	   return value is NULL and ERR is REG_NOERROR.
-	 - We never return non-NULL value in case of any errors, it is for
-	   optimization.  */
-
-static re_dfastate_t*
-re_acquire_state_context (err, dfa, nodes, context)
-     reg_errcode_t *err;
-     re_dfa_t *dfa;
-     const re_node_set *nodes;
-     unsigned int context;
-{
-  unsigned int hash;
-  re_dfastate_t *new_state;
-  struct re_state_table_entry *spot;
-  int i;
-  if (nodes->nelem == 0)
-    {
-      *err = REG_NOERROR;
-      return NULL;
-    }
-  hash = calc_state_hash (nodes, context);
-  spot = dfa->state_table + (hash & dfa->state_hash_mask);
-
-  for (i = 0 ; i < spot->num ; i++)
-    {
-      re_dfastate_t *state = spot->array[i];
-      if (hash != state->hash)
-	continue;
-      if (re_node_set_compare (state->entrance_nodes, nodes)
-	  && state->context == context)
-	return state;
-    }
-  /* There are no appropriate state in `dfa', create the new one.  */
-  new_state = create_cd_newstate (dfa, nodes, context, hash);
-  if (BE (new_state != NULL, 1))
-    return new_state;
-  else
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-}
-
-/* Allocate memory for DFA state and initialize common properties.
-   Return the new state if succeeded, otherwise return NULL.  */
-
-static re_dfastate_t *
-create_newstate_common (dfa, nodes, hash)
-     re_dfa_t *dfa;
-     const re_node_set *nodes;
-     unsigned int hash;
-{
-  re_dfastate_t *newstate;
-  reg_errcode_t err;
-  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (BE (newstate == NULL, 0))
-    return NULL;
-  err = re_node_set_init_copy (&newstate->nodes, nodes);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      re_free (newstate);
-      return NULL;
-    }
-  newstate->trtable = NULL;
-  newstate->trtable_search = NULL;
-  newstate->hash = hash;
-  return newstate;
-}
-
-/* Store the new state NEWSTATE whose hash value is HASH in appropriate
-   position.  Return value indicate the error code if failed.  */
-
-static reg_errcode_t
-register_state (dfa, newstate, hash)
-     re_dfa_t *dfa;
-     re_dfastate_t *newstate;
-     unsigned int hash;
-{
-  struct re_state_table_entry *spot;
-  spot = dfa->state_table + (hash & dfa->state_hash_mask);
-
-  if (spot->alloc <= spot->num)
-    {
-      re_dfastate_t **new_array;
-      spot->alloc = 2 * spot->num + 2;
-      new_array = re_realloc (spot->array, re_dfastate_t *, spot->alloc);
-      if (BE (new_array == NULL, 0))
-	return REG_ESPACE;
-      spot->array = new_array;
-    }
-  spot->array[spot->num++] = newstate;
-  return REG_NOERROR;
-}
-
-/* Create the new state which is independ of contexts.
-   Return the new state if succeeded, otherwise return NULL.  */
-
-static re_dfastate_t *
-create_ci_newstate (dfa, nodes, hash)
-     re_dfa_t *dfa;
-     const re_node_set *nodes;
-     unsigned int hash;
-{
-  int i;
-  reg_errcode_t err;
-  re_dfastate_t *newstate;
-  newstate = create_newstate_common (dfa, nodes, hash);
-  if (BE (newstate == NULL, 0))
-    return NULL;
-  newstate->entrance_nodes = &newstate->nodes;
-
-  for (i = 0 ; i < nodes->nelem ; i++)
-    {
-      re_token_t *node = dfa->nodes + nodes->elems[i];
-      re_token_type_t type = node->type;
-      if (type == CHARACTER && !node->constraint)
-	continue;
-
-      /* If the state has the halt node, the state is a halt state.  */
-      else if (type == END_OF_RE)
-	newstate->halt = 1;
-#ifdef RE_ENABLE_I18N
-      else if (type == COMPLEX_BRACKET
-	       || (type == OP_PERIOD && MB_CUR_MAX > 1))
-	newstate->accept_mb = 1;
-#endif /* RE_ENABLE_I18N */
-      else if (type == OP_BACK_REF)
-	newstate->has_backref = 1;
-      else if (type == ANCHOR || node->constraint)
-	newstate->has_constraint = 1;
-    }
-  err = register_state (dfa, newstate, hash);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      free_state (newstate);
-      newstate = NULL;
-    }
-  return newstate;
-}
-
-/* Create the new state which is depend on the context CONTEXT.
-   Return the new state if succeeded, otherwise return NULL.  */
-
-static re_dfastate_t *
-create_cd_newstate (dfa, nodes, context, hash)
-     re_dfa_t *dfa;
-     const re_node_set *nodes;
-     unsigned int context, hash;
-{
-  int i, nctx_nodes = 0;
-  reg_errcode_t err;
-  re_dfastate_t *newstate;
-
-  newstate = create_newstate_common (dfa, nodes, hash);
-  if (BE (newstate == NULL, 0))
-    return NULL;
-  newstate->context = context;
-  newstate->entrance_nodes = &newstate->nodes;
-
-  for (i = 0 ; i < nodes->nelem ; i++)
-    {
-      unsigned int constraint = 0;
-      re_token_t *node = dfa->nodes + nodes->elems[i];
-      re_token_type_t type = node->type;
-      if (node->constraint)
-	constraint = node->constraint;
-
-      if (type == CHARACTER && !constraint)
-	continue;
-      /* If the state has the halt node, the state is a halt state.  */
-      else if (type == END_OF_RE)
-	newstate->halt = 1;
-#ifdef RE_ENABLE_I18N
-      else if (type == COMPLEX_BRACKET
-	       || (type == OP_PERIOD && MB_CUR_MAX > 1))
-	newstate->accept_mb = 1;
-#endif /* RE_ENABLE_I18N */
-      else if (type == OP_BACK_REF)
-	newstate->has_backref = 1;
-      else if (type == ANCHOR)
-	constraint = node->opr.ctx_type;
-
-      if (constraint)
-	{
-	  if (newstate->entrance_nodes == &newstate->nodes)
-	    {
-	      newstate->entrance_nodes = re_malloc (re_node_set, 1);
-	      if (BE (newstate->entrance_nodes == NULL, 0))
-		{
-		  free_state (newstate);
-		  return NULL;
-		}
-	      re_node_set_init_copy (newstate->entrance_nodes, nodes);
-	      nctx_nodes = 0;
-	      newstate->has_constraint = 1;
-	    }
-
-	  if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
-	    {
-	      re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
-	      ++nctx_nodes;
-	    }
-	}
-    }
-  err = register_state (dfa, newstate, hash);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      free_state (newstate);
-      newstate = NULL;
-    }
-  return  newstate;
-}
-
-static void
-free_state (state)
-     re_dfastate_t *state;
-{
-  if (state->entrance_nodes != &state->nodes)
-    {
-      re_node_set_free (state->entrance_nodes);
-      re_free (state->entrance_nodes);
-    }
-  re_node_set_free (&state->nodes);
-  re_free (state->trtable);
-  re_free (state->trtable_search);
-  re_free (state);
-}
diff --git a/sm5/posix/regex_internal.h b/sm5/posix/regex_internal.h
deleted file mode 100644
index bf84ad6270f5d06ada1cf10e82f8517ebec3a00f..0000000000000000000000000000000000000000
--- a/sm5/posix/regex_internal.h
+++ /dev/null
@@ -1,742 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifndef _REGEX_INTERNAL_H
-#define _REGEX_INTERNAL_H 1
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined HAVE_LOCALE_H || defined _LIBC
-# include <locale.h>
-#endif
-#if defined HAVE_WCHAR_H || defined _LIBC
-# include <wchar.h>
-#endif /* HAVE_WCHAR_H || _LIBC */
-#if defined HAVE_WCTYPE_H || defined _LIBC
-# include <wctype.h>
-#endif /* HAVE_WCTYPE_H || _LIBC */
-
-/* In case that the system doesn't have isblank().  */
-#if !defined _LIBC && !defined HAVE_ISBLANK && !defined isblank
-# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
-#endif
-
-#ifdef _LIBC
-# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
-#  define _RE_DEFINE_LOCALE_FUNCTIONS 1
-#   include <locale/localeinfo.h>
-#   include <locale/elem-hash.h>
-#   include <locale/coll-lookup.h>
-# endif
-#endif
-
-/* This is for other GNU distributions with internationalized messages.  */
-#if HAVE_LIBINTL_H || defined _LIBC
-# include <libintl.h>
-# ifdef _LIBC
-#  undef gettext
-#  define gettext(msgid) \
-  INTUSE(__dcgettext) (INTUSE(_libc_intl_domainname), msgid, LC_MESSAGES)
-# endif
-#else
-# define gettext(msgid) (msgid)
-#endif
-
-#ifndef gettext_noop
-/* This define is so xgettext can find the internationalizable
-   strings.  */
-# define gettext_noop(String) String
-#endif
-
-#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL) || _LIBC
-# define RE_ENABLE_I18N
-#endif
-
-#if __GNUC__ >= 3
-# define BE(expr, val) __builtin_expect (expr, val)
-#else
-# define BE(expr, val) (expr)
-# define inline
-#endif
-
-/* Number of bits in a byte.  */
-#define BYTE_BITS 8
-/* Number of single byte character.  */
-#define SBC_MAX 256
-
-#define COLL_ELEM_LEN_MAX 8
-
-/* The character which represents newline.  */
-#define NEWLINE_CHAR '\n'
-#define WIDE_NEWLINE_CHAR L'\n'
-
-/* Rename to standard API for using out of glibc.  */
-#ifndef _LIBC
-# define __wctype wctype
-# define __iswctype iswctype
-# define __btowc btowc
-# define __mempcpy mempcpy
-# define __wcrtomb wcrtomb
-# define attribute_hidden
-#endif /* not _LIBC */
-
-extern const char __re_error_msgid[] attribute_hidden;
-extern const size_t __re_error_msgid_idx[] attribute_hidden;
-
-/* Number of bits in an unsinged int.  */
-#define UINT_BITS (sizeof (unsigned int) * BYTE_BITS)
-/* Number of unsigned int in an bit_set.  */
-#define BITSET_UINTS ((SBC_MAX + UINT_BITS - 1) / UINT_BITS)
-typedef unsigned int bitset[BITSET_UINTS];
-typedef unsigned int *re_bitset_ptr_t;
-
-#define bitset_set(set,i) (set[i / UINT_BITS] |= 1 << i % UINT_BITS)
-#define bitset_clear(set,i) (set[i / UINT_BITS] &= ~(1 << i % UINT_BITS))
-#define bitset_contain(set,i) (set[i / UINT_BITS] & (1 << i % UINT_BITS))
-#define bitset_empty(set) memset (set, 0, sizeof (unsigned int) * BITSET_UINTS)
-#define bitset_set_all(set) \
-  memset (set, 255, sizeof (unsigned int) * BITSET_UINTS)
-#define bitset_copy(dest,src) \
-  memcpy (dest, src, sizeof (unsigned int) * BITSET_UINTS)
-static inline void bitset_not (bitset set);
-static inline void bitset_merge (bitset dest, const bitset src);
-static inline void bitset_not_merge (bitset dest, const bitset src);
-
-#define PREV_WORD_CONSTRAINT 0x0001
-#define PREV_NOTWORD_CONSTRAINT 0x0002
-#define NEXT_WORD_CONSTRAINT 0x0004
-#define NEXT_NOTWORD_CONSTRAINT 0x0008
-#define PREV_NEWLINE_CONSTRAINT 0x0010
-#define NEXT_NEWLINE_CONSTRAINT 0x0020
-#define PREV_BEGBUF_CONSTRAINT 0x0040
-#define NEXT_ENDBUF_CONSTRAINT 0x0080
-#define DUMMY_CONSTRAINT 0x0100
-
-typedef enum
-{
-  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
-  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
-  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
-  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
-  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
-  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
-  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
-  WORD_DELIM = DUMMY_CONSTRAINT
-} re_context_type;
-
-typedef struct
-{
-  int alloc;
-  int nelem;
-  int *elems;
-} re_node_set;
-
-typedef enum
-{
-  NON_TYPE = 0,
-
-  /* Token type, these are used only by token.  */
-  OP_OPEN_BRACKET,
-  OP_CLOSE_BRACKET,
-  OP_CHARSET_RANGE,
-  OP_OPEN_DUP_NUM,
-  OP_CLOSE_DUP_NUM,
-  OP_NON_MATCH_LIST,
-  OP_OPEN_COLL_ELEM,
-  OP_CLOSE_COLL_ELEM,
-  OP_OPEN_EQUIV_CLASS,
-  OP_CLOSE_EQUIV_CLASS,
-  OP_OPEN_CHAR_CLASS,
-  OP_CLOSE_CHAR_CLASS,
-  OP_WORD,
-  OP_NOTWORD,
-  BACK_SLASH,
-
-  /* Tree type, these are used only by tree. */
-  CONCAT,
-  ALT,
-  SUBEXP,
-  SIMPLE_BRACKET,
-#ifdef RE_ENABLE_I18N
-  COMPLEX_BRACKET,
-#endif /* RE_ENABLE_I18N */
-
-  /* Node type, These are used by token, node, tree.  */
-  OP_OPEN_SUBEXP,
-  OP_CLOSE_SUBEXP,
-  OP_PERIOD,
-  CHARACTER,
-  END_OF_RE,
-  OP_ALT,
-  OP_DUP_ASTERISK,
-  OP_DUP_PLUS,
-  OP_DUP_QUESTION,
-  OP_BACK_REF,
-  ANCHOR,
-
-  /* Dummy marker.  */
-  END_OF_RE_TOKEN_T
-} re_token_type_t;
-
-#ifdef RE_ENABLE_I18N
-typedef struct
-{
-  /* Multibyte characters.  */
-  wchar_t *mbchars;
-
-  /* Collating symbols.  */
-# ifdef _LIBC
-  int32_t *coll_syms;
-# endif
-
-  /* Equivalence classes. */
-# ifdef _LIBC
-  int32_t *equiv_classes;
-# endif
-
-  /* Range expressions. */
-# ifdef _LIBC
-  uint32_t *range_starts;
-  uint32_t *range_ends;
-# else /* not _LIBC */
-  wchar_t *range_starts;
-  wchar_t *range_ends;
-# endif /* not _LIBC */
-
-  /* Character classes. */
-  wctype_t *char_classes;
-
-  /* If this character set is the non-matching list.  */
-  unsigned int non_match : 1;
-
-  /* # of multibyte characters.  */
-  int nmbchars;
-
-  /* # of collating symbols.  */
-  int ncoll_syms;
-
-  /* # of equivalence classes. */
-  int nequiv_classes;
-
-  /* # of range expressions. */
-  int nranges;
-
-  /* # of character classes. */
-  int nchar_classes;
-} re_charset_t;
-#endif /* RE_ENABLE_I18N */
-
-typedef struct
-{
-  union
-  {
-    unsigned char c;		/* for CHARACTER */
-    re_bitset_ptr_t sbcset;	/* for SIMPLE_BRACKET */
-#ifdef RE_ENABLE_I18N
-    re_charset_t *mbcset;	/* for COMPLEX_BRACKET */
-#endif /* RE_ENABLE_I18N */
-    int idx;			/* for BACK_REF */
-    re_context_type ctx_type;	/* for ANCHOR */
-  } opr;
-#if __GNUC__ >= 2
-  re_token_type_t type : 8;
-#else
-  re_token_type_t type;
-#endif
-  unsigned int constraint : 10;	/* context constraint */
-  unsigned int duplicated : 1;
-#ifdef RE_ENABLE_I18N
-  unsigned int mb_partial : 1;
-#endif
-} re_token_t;
-
-#define IS_EPSILON_NODE(type) \
-  ((type) == OP_ALT || (type) == OP_DUP_ASTERISK || (type) == OP_DUP_PLUS \
-   || (type) == OP_DUP_QUESTION || (type) == ANCHOR \
-   || (type) == OP_OPEN_SUBEXP || (type) == OP_CLOSE_SUBEXP)
-
-#define ACCEPT_MB_NODE(type) \
-  ((type) == COMPLEX_BRACKET || (type) == OP_PERIOD)
-
-struct re_string_t
-{
-  /* Indicate the raw buffer which is the original string passed as an
-     argument of regexec(), re_search(), etc..  */
-  const unsigned char *raw_mbs;
-  /* Store the multibyte string.  In case of "case insensitive mode" like
-     REG_ICASE, upper cases of the string are stored, otherwise MBS points
-     the same address that RAW_MBS points.  */
-  unsigned char *mbs;
-  /* Store the case sensitive multibyte string.  In case of
-     "case insensitive mode", the original string are stored,
-     otherwise MBS_CASE points the same address that MBS points.  */
-  unsigned char *mbs_case;
-#ifdef RE_ENABLE_I18N
-  /* Store the wide character string which is corresponding to MBS.  */
-  wint_t *wcs;
-  mbstate_t cur_state;
-#endif
-  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
-     raw_mbs[raw_mbs_idx + i].  */
-  int raw_mbs_idx;
-  /* The length of the valid characters in the buffers.  */
-  int valid_len;
-  /* The length of the buffers MBS, MBS_CASE, and WCS.  */
-  int bufs_len;
-  /* The index in MBS, which is updated by re_string_fetch_byte.  */
-  int cur_idx;
-  /* This is length_of_RAW_MBS - RAW_MBS_IDX.  */
-  int len;
-  /* End of the buffer may be shorter than its length in the cases such
-     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
-     instead of LEN.  */
-  int stop;
-
-  /* The context of mbs[0].  We store the context independently, since
-     the context of mbs[0] may be different from raw_mbs[0], which is
-     the beginning of the input string.  */
-  unsigned int tip_context;
-  /* The translation passed as a part of an argument of re_compile_pattern.  */
-  RE_TRANSLATE_TYPE trans;
-  /* 1 if REG_ICASE.  */
-  unsigned int icase : 1;
-};
-typedef struct re_string_t re_string_t;
-/* In case of REG_ICASE, we allocate the buffer dynamically for mbs.  */
-#define MBS_ALLOCATED(pstr) (pstr->icase)
-/* In case that we need translation, we allocate the buffer dynamically
-   for mbs_case.  Note that mbs == mbs_case if not REG_ICASE.  */
-#define MBS_CASE_ALLOCATED(pstr) (pstr->trans != NULL)
-
-
-static reg_errcode_t re_string_allocate (re_string_t *pstr, const char *str,
-					 int len, int init_len,
-					 RE_TRANSLATE_TYPE trans, int icase);
-static reg_errcode_t re_string_construct (re_string_t *pstr, const char *str,
-					  int len, RE_TRANSLATE_TYPE trans,
-					  int icase);
-static reg_errcode_t re_string_reconstruct (re_string_t *pstr, int idx,
-					    int eflags, int newline);
-static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
-						int new_buf_len);
-#ifdef RE_ENABLE_I18N
-static void build_wcs_buffer (re_string_t *pstr);
-static void build_wcs_upper_buffer (re_string_t *pstr);
-#endif /* RE_ENABLE_I18N */
-static void build_upper_buffer (re_string_t *pstr);
-static void re_string_translate_buffer (re_string_t *pstr);
-static void re_string_destruct (re_string_t *pstr);
-#ifdef RE_ENABLE_I18N
-static int re_string_elem_size_at (const re_string_t *pstr, int idx);
-static inline int re_string_char_size_at (const re_string_t *pstr, int idx);
-static inline wint_t re_string_wchar_at (const re_string_t *pstr, int idx);
-#endif /* RE_ENABLE_I18N */
-static unsigned int re_string_context_at (const re_string_t *input, int idx,
-					  int eflags, int newline_anchor);
-#define re_string_peek_byte(pstr, offset) \
-  ((pstr)->mbs[(pstr)->cur_idx + offset])
-#define re_string_peek_byte_case(pstr, offset) \
-  ((pstr)->mbs_case[(pstr)->cur_idx + offset])
-#define re_string_fetch_byte(pstr) \
-  ((pstr)->mbs[(pstr)->cur_idx++])
-#define re_string_fetch_byte_case(pstr) \
-  ((pstr)->mbs_case[(pstr)->cur_idx++])
-#define re_string_first_byte(pstr, idx) \
-  ((idx) == (pstr)->len || (pstr)->wcs[idx] != WEOF)
-#define re_string_is_single_byte_char(pstr, idx) \
-  ((pstr)->wcs[idx] != WEOF && ((pstr)->len == (idx) \
-				|| (pstr)->wcs[(idx) + 1] != WEOF))
-#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
-#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
-#define re_string_get_buffer(pstr) ((pstr)->mbs)
-#define re_string_length(pstr) ((pstr)->len)
-#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
-#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
-#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
-
-#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
-#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
-#define re_free(p) free (p)
-
-struct bin_tree_t
-{
-  struct bin_tree_t *parent;
-  struct bin_tree_t *left;
-  struct bin_tree_t *right;
-
-  /* `node_idx' is the index in dfa->nodes, if `type' == 0.
-     Otherwise `type' indicate the type of this node.  */
-  re_token_type_t type;
-  int node_idx;
-
-  int first;
-  int next;
-  re_node_set eclosure;
-};
-typedef struct bin_tree_t bin_tree_t;
-
-
-#define CONTEXT_WORD 1
-#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
-#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
-#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
-
-#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
-#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
-#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
-#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
-#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
-
-#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
-#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
-#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
-#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
-
-#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
- ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
-  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
-  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
-  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
-
-#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
- ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
-  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
-  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
-  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
-
-struct re_dfastate_t
-{
-  unsigned int hash;
-  re_node_set nodes;
-  re_node_set *entrance_nodes;
-  struct re_dfastate_t **trtable;
-  struct re_dfastate_t **trtable_search;
-  /* If this state is a special state.
-     A state is a special state if the state is the halt state, or
-     a anchor.  */
-  unsigned int context : 2;
-  unsigned int halt : 1;
-  /* If this state can accept `multi byte'.
-     Note that we refer to multibyte characters, and multi character
-     collating elements as `multi byte'.  */
-  unsigned int accept_mb : 1;
-  /* If this state has backreference node(s).  */
-  unsigned int has_backref : 1;
-  unsigned int has_constraint : 1;
-};
-typedef struct re_dfastate_t re_dfastate_t;
-
-typedef struct
-{
-  /* start <= node < end  */
-  int start;
-  int end;
-} re_subexp_t;
-
-struct re_state_table_entry
-{
-  int num;
-  int alloc;
-  re_dfastate_t **array;
-};
-
-/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */
-
-typedef struct
-{
-  int next_idx;
-  int alloc;
-  re_dfastate_t **array;
-} state_array_t;
-
-/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */
-
-typedef struct
-{
-  int node;
-  int str_idx; /* The position NODE match at.  */
-  state_array_t path;
-} re_sub_match_last_t;
-
-/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
-   And information about the node, whose type is OP_CLOSE_SUBEXP,
-   corresponding to NODE is stored in LASTS.  */
-
-typedef struct
-{
-  int str_idx;
-  int node;
-  int next_last_offset;
-  state_array_t *path;
-  int alasts; /* Allocation size of LASTS.  */
-  int nlasts; /* The number of LASTS.  */
-  re_sub_match_last_t **lasts;
-} re_sub_match_top_t;
-
-struct re_backref_cache_entry
-{
-  int node;
-  int str_idx;
-  int subexp_from;
-  int subexp_to;
-  int flag;
-};
-
-typedef struct
-{
-  /* EFLAGS of the argument of regexec.  */
-  int eflags;
-  /* Where the matching ends.  */
-  int match_last;
-  int last_node;
-  /* The string object corresponding to the input string.  */
-  re_string_t *input;
-  /* The state log used by the matcher.  */
-  re_dfastate_t **state_log;
-  int state_log_top;
-  /* Back reference cache.  */
-  int nbkref_ents;
-  int abkref_ents;
-  struct re_backref_cache_entry *bkref_ents;
-  int max_mb_elem_len;
-  int nsub_tops;
-  int asub_tops;
-  re_sub_match_top_t **sub_tops;
-} re_match_context_t;
-
-typedef struct
-{
-  int cur_bkref;
-  int cls_subexp_idx;
-
-  re_dfastate_t **sifted_states;
-  re_dfastate_t **limited_states;
-
-  re_node_set limits;
-
-  int last_node;
-  int last_str_idx;
-  int check_subexp;
-} re_sift_context_t;
-
-struct re_fail_stack_ent_t
-{
-  int idx;
-  int node;
-  regmatch_t *regs;
-  re_node_set eps_via_nodes;
-};
-
-struct re_fail_stack_t
-{
-  int num;
-  int alloc;
-  struct re_fail_stack_ent_t *stack;
-};
-
-struct re_dfa_t
-{
-  re_bitset_ptr_t word_char;
-
-  /* number of subexpressions `re_nsub' is in regex_t.  */
-  int subexps_alloc;
-  re_subexp_t *subexps;
-
-  re_token_t *nodes;
-  int nodes_alloc;
-  int nodes_len;
-  bin_tree_t *str_tree;
-  int *nexts;
-  int *org_indices;
-  re_node_set *edests;
-  re_node_set *eclosures;
-  re_node_set *inveclosures;
-  struct re_state_table_entry *state_table;
-  unsigned int state_hash_mask;
-  re_dfastate_t *init_state;
-  re_dfastate_t *init_state_word;
-  re_dfastate_t *init_state_nl;
-  re_dfastate_t *init_state_begbuf;
-  int states_alloc;
-  int init_node;
-  int nbackref; /* The number of backreference in this dfa.  */
-  /* Bitmap expressing which backreference is used.  */
-  unsigned int used_bkref_map;
-#ifdef DEBUG
-  char* re_str;
-#endif
-  unsigned int has_plural_match : 1;
-  /* If this dfa has "multibyte node", which is a backreference or
-     a node which can accept multibyte character or multi character
-     collating element.  */
-  unsigned int has_mb_node : 1;
-};
-typedef struct re_dfa_t re_dfa_t;
-
-static reg_errcode_t re_node_set_alloc (re_node_set *set, int size);
-static reg_errcode_t re_node_set_init_1 (re_node_set *set, int elem);
-static reg_errcode_t re_node_set_init_2 (re_node_set *set, int elem1,
-					 int elem2);
-#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
-static reg_errcode_t re_node_set_init_copy (re_node_set *dest,
-					    const re_node_set *src);
-static reg_errcode_t re_node_set_add_intersect (re_node_set *dest,
-						const re_node_set *src1,
-						const re_node_set *src2);
-static reg_errcode_t re_node_set_init_union (re_node_set *dest,
-					     const re_node_set *src1,
-					     const re_node_set *src2);
-static reg_errcode_t re_node_set_merge (re_node_set *dest,
-					const re_node_set *src);
-static int re_node_set_insert (re_node_set *set, int elem);
-static int re_node_set_compare (const re_node_set *set1,
-				const re_node_set *set2);
-static int re_node_set_contains (const re_node_set *set, int elem);
-static void re_node_set_remove_at (re_node_set *set, int idx);
-#define re_node_set_remove(set,id) \
-  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
-#define re_node_set_empty(p) ((p)->nelem = 0)
-#define re_node_set_free(set) re_free ((set)->elems)
-static int re_dfa_add_node (re_dfa_t *dfa, re_token_t token, int mode);
-static re_dfastate_t *re_acquire_state (reg_errcode_t *err, re_dfa_t *dfa,
-					const re_node_set *nodes);
-static re_dfastate_t *re_acquire_state_context (reg_errcode_t *err,
-						re_dfa_t *dfa,
-						const re_node_set *nodes,
-						unsigned int context);
-static void free_state (re_dfastate_t *state);
-
-
-typedef enum
-{
-  SB_CHAR,
-  MB_CHAR,
-  EQUIV_CLASS,
-  COLL_SYM,
-  CHAR_CLASS
-} bracket_elem_type;
-
-typedef struct
-{
-  bracket_elem_type type;
-  union
-  {
-    unsigned char ch;
-    unsigned char *name;
-    wchar_t wch;
-  } opr;
-} bracket_elem_t;
-
-
-/* Inline functions for bitset operation.  */
-static inline void
-bitset_not (set)
-     bitset set;
-{
-  int bitset_i;
-  for (bitset_i = 0; bitset_i < BITSET_UINTS; ++bitset_i)
-    set[bitset_i] = ~set[bitset_i];
-}
-
-static inline void
-bitset_merge (dest, src)
-     bitset dest;
-     const bitset src;
-{
-  int bitset_i;
-  for (bitset_i = 0; bitset_i < BITSET_UINTS; ++bitset_i)
-    dest[bitset_i] |= src[bitset_i];
-}
-
-static inline void
-bitset_not_merge (dest, src)
-     bitset dest;
-     const bitset src;
-{
-  int i;
-  for (i = 0; i < BITSET_UINTS; ++i)
-    dest[i] |= ~src[i];
-}
-
-#ifdef RE_ENABLE_I18N
-/* Inline functions for re_string.  */
-static inline int
-re_string_char_size_at (pstr, idx)
-     const re_string_t *pstr;
-     int idx;
-{
-  int byte_idx;
-  if (MB_CUR_MAX == 1)
-    return 1;
-  for (byte_idx = 1; idx + byte_idx < pstr->len; ++byte_idx)
-    if (pstr->wcs[idx + byte_idx] != WEOF)
-      break;
-  return byte_idx;
-}
-
-static inline wint_t
-re_string_wchar_at (pstr, idx)
-     const re_string_t *pstr;
-     int idx;
-{
-  if (MB_CUR_MAX == 1)
-    return (wint_t) pstr->mbs[idx];
-  return (wint_t) pstr->wcs[idx];
-}
-
-static int
-re_string_elem_size_at (pstr, idx)
-     const re_string_t *pstr;
-     int idx;
-{
-#ifdef _LIBC
-  const unsigned char *p, *extra;
-  const int32_t *table, *indirect;
-  int32_t tmp;
-# include <locale/weight.h>
-  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-
-  if (nrules != 0)
-    {
-      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-      extra = (const unsigned char *)
-	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
-      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-						_NL_COLLATE_INDIRECTMB);
-      p = pstr->mbs + idx;
-      tmp = findidx (&p);
-      return p - pstr->mbs - idx;
-    }
-  else
-#endif /* _LIBC */
-    return 1;
-}
-#endif /* RE_ENABLE_I18N */
-
-#endif /*  _REGEX_INTERNAL_H */
diff --git a/sm5/posix/regexec.c b/sm5/posix/regexec.c
deleted file mode 100644
index 6ea14a6c480335feb0a1d11c4572a5edc6960c58..0000000000000000000000000000000000000000
--- a/sm5/posix/regexec.c
+++ /dev/null
@@ -1,3977 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
-				     re_string_t *input, int n);
-static void match_ctx_clean (re_match_context_t *mctx);
-static void match_ctx_free (re_match_context_t *cache);
-static void match_ctx_free_subtops (re_match_context_t *mctx);
-static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node,
-					  int str_idx, int from, int to);
-static int search_cur_bkref_entry (re_match_context_t *mctx, int str_idx);
-static void match_ctx_clear_flag (re_match_context_t *mctx);
-static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, int node,
-					   int str_idx);
-static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
-						   int node, int str_idx);
-static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
-			   re_dfastate_t **limited_sts, int last_node,
-			   int last_str_idx, int check_subexp);
-static reg_errcode_t re_search_internal (const regex_t *preg,
-					 const char *string, int length,
-					 int start, int range, int stop,
-					 size_t nmatch, regmatch_t pmatch[],
-					 int eflags);
-static int re_search_2_stub (struct re_pattern_buffer *bufp,
-			     const char *string1, int length1,
-			     const char *string2, int length2,
-			     int start, int range, struct re_registers *regs,
-			     int stop, int ret_len);
-static int re_search_stub (struct re_pattern_buffer *bufp,
-			   const char *string, int length, int start,
-			   int range, int stop, struct re_registers *regs,
-			   int ret_len);
-static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
-			      int nregs, int regs_allocated);
-static inline re_dfastate_t *acquire_init_state_context (reg_errcode_t *err,
-							 const regex_t *preg,
-							 const re_match_context_t *mctx,
-							 int idx);
-static reg_errcode_t prune_impossible_nodes (const regex_t *preg,
-					     re_match_context_t *mctx);
-static int check_matching (const regex_t *preg, re_match_context_t *mctx,
-			   int fl_search, int fl_longest_match);
-static int check_halt_node_context (const re_dfa_t *dfa, int node,
-				    unsigned int context);
-static int check_halt_state_context (const regex_t *preg,
-				     const re_dfastate_t *state,
-				     const re_match_context_t *mctx, int idx);
-static void update_regs (re_dfa_t *dfa, regmatch_t *pmatch, int cur_node,
-			 int cur_idx, int nmatch);
-static int proceed_next_node (const regex_t *preg, int nregs, regmatch_t *regs,
-			      const re_match_context_t *mctx,
-			      int *pidx, int node, re_node_set *eps_via_nodes,
-			      struct re_fail_stack_t *fs);
-static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
-				      int str_idx, int *dests, int nregs,
-				      regmatch_t *regs,
-				      re_node_set *eps_via_nodes);
-static int pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,
-			   regmatch_t *regs, re_node_set *eps_via_nodes);
-static reg_errcode_t set_regs (const regex_t *preg,
-			       const re_match_context_t *mctx,
-			       size_t nmatch, regmatch_t *pmatch,
-			       int fl_backtrack);
-static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs);
-
-#ifdef RE_ENABLE_I18N
-static int sift_states_iter_mb (const regex_t *preg,
-				const re_match_context_t *mctx,
-				re_sift_context_t *sctx,
-				int node_idx, int str_idx, int max_str_idx);
-#endif /* RE_ENABLE_I18N */
-static reg_errcode_t sift_states_backward (const regex_t *preg,
-					   re_match_context_t *mctx,
-					   re_sift_context_t *sctx);
-static reg_errcode_t update_cur_sifted_state (const regex_t *preg,
-					      re_match_context_t *mctx,
-					      re_sift_context_t *sctx,
-					      int str_idx,
-					      re_node_set *dest_nodes);
-static reg_errcode_t add_epsilon_src_nodes (re_dfa_t *dfa,
-					    re_node_set *dest_nodes,
-					    const re_node_set *candidates);
-static reg_errcode_t sub_epsilon_src_nodes (re_dfa_t *dfa, int node,
-					    re_node_set *dest_nodes,
-					    const re_node_set *and_nodes);
-static int check_dst_limits (re_dfa_t *dfa, re_node_set *limits,
-			     re_match_context_t *mctx, int dst_node,
-			     int dst_idx, int src_node, int src_idx);
-static int check_dst_limits_calc_pos (re_dfa_t *dfa, re_match_context_t *mctx,
-				      int limit, re_node_set *eclosures,
-				      int subexp_idx, int node, int str_idx);
-static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,
-					  re_node_set *dest_nodes,
-					  const re_node_set *candidates,
-					  re_node_set *limits,
-					  struct re_backref_cache_entry *bkref_ents,
-					  int str_idx);
-static reg_errcode_t sift_states_bkref (const regex_t *preg,
-					re_match_context_t *mctx,
-					re_sift_context_t *sctx,
-					int str_idx, re_node_set *dest_nodes);
-static reg_errcode_t clean_state_log_if_need (re_match_context_t *mctx,
-					      int next_state_log_idx);
-static reg_errcode_t merge_state_array (re_dfa_t *dfa, re_dfastate_t **dst,
-					re_dfastate_t **src, int num);
-static re_dfastate_t *transit_state (reg_errcode_t *err, const regex_t *preg,
-				     re_match_context_t *mctx,
-				     re_dfastate_t *state, int fl_search);
-static reg_errcode_t check_subexp_matching_top (re_dfa_t *dfa,
-						re_match_context_t *mctx,
-						re_node_set *cur_nodes,
-						int str_idx);
-static re_dfastate_t *transit_state_sb (reg_errcode_t *err, const regex_t *preg,
-					re_dfastate_t *pstate,
-					int fl_search,
-					re_match_context_t *mctx);
-#ifdef RE_ENABLE_I18N
-static reg_errcode_t transit_state_mb (const regex_t *preg,
-				       re_dfastate_t *pstate,
-				       re_match_context_t *mctx);
-#endif /* RE_ENABLE_I18N */
-static reg_errcode_t transit_state_bkref (const regex_t *preg,
-					  re_node_set *nodes,
-					  re_match_context_t *mctx);
-static reg_errcode_t get_subexp (const regex_t *preg, re_match_context_t *mctx,
-				 int bkref_node, int bkref_str_idx);
-static reg_errcode_t get_subexp_sub (const regex_t *preg,
-				     re_match_context_t *mctx,
-				     re_sub_match_top_t *sub_top,
-				     re_sub_match_last_t *sub_last,
-				     int bkref_node, int bkref_str);
-static int find_subexp_node (re_dfa_t *dfa, re_node_set *nodes,
-			     int subexp_idx, int fl_open);
-static reg_errcode_t check_arrival (const regex_t *preg,
-				    re_match_context_t *mctx,
-				    state_array_t *path, int top_node,
-				    int top_str, int last_node, int last_str,
-				    int fl_open);
-static reg_errcode_t check_arrival_add_next_nodes (const regex_t *preg,
-						   re_dfa_t *dfa,
-						   re_match_context_t *mctx,
-						   int str_idx,
-						   re_node_set *cur_nodes,
-						   re_node_set *next_nodes);
-static reg_errcode_t check_arrival_expand_ecl (re_dfa_t *dfa,
-					       re_node_set *cur_nodes,
-					       int ex_subexp, int fl_open);
-static reg_errcode_t check_arrival_expand_ecl_sub (re_dfa_t *dfa,
-						   re_node_set *dst_nodes,
-						   int target, int ex_subexp,
-						   int fl_open);
-static reg_errcode_t expand_bkref_cache (const regex_t *preg,
-					 re_match_context_t *mctx,
-					 re_node_set *cur_nodes, int cur_str,
-					 int last_str, int subexp_num,
-					 int fl_open);
-static re_dfastate_t **build_trtable (const regex_t *dfa,
-				      const re_dfastate_t *state,
-				      int fl_search);
-#ifdef RE_ENABLE_I18N
-static int check_node_accept_bytes (const regex_t *preg, int node_idx,
-				    const re_string_t *input, int idx);
-# ifdef _LIBC
-static unsigned int find_collation_sequence_value (const unsigned char *mbs,
-						   size_t name_len);
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
-static int group_nodes_into_DFAstates (const regex_t *dfa,
-				       const re_dfastate_t *state,
-				       re_node_set *states_node,
-				       bitset *states_ch);
-static int check_node_accept (const regex_t *preg, const re_token_t *node,
-			      const re_match_context_t *mctx, int idx);
-static reg_errcode_t extend_buffers (re_match_context_t *mctx);
-
-/* Entry point for POSIX code.  */
-
-/* regexec searches for a given pattern, specified by PREG, in the
-   string STRING.
-
-   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
-   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
-   least NMATCH elements, and we set them to the offsets of the
-   corresponding matched substrings.
-
-   EFLAGS specifies `execution flags' which affect matching: if
-   REG_NOTBOL is set, then ^ does not match at the beginning of the
-   string; if REG_NOTEOL is set, then $ does not match at the end.
-
-   We return 0 if we find a match and REG_NOMATCH if not.  */
-
-int
-regexec (preg, string, nmatch, pmatch, eflags)
-    const regex_t *__restrict preg;
-    const char *__restrict string;
-    size_t nmatch;
-    regmatch_t pmatch[];
-    int eflags;
-{
-  reg_errcode_t err;
-  int length = strlen (string);
-  if (preg->no_sub)
-    err = re_search_internal (preg, string, length, 0, length, length, 0,
-			      NULL, eflags);
-  else
-    err = re_search_internal (preg, string, length, 0, length, length, nmatch,
-			      pmatch, eflags);
-  return err != REG_NOERROR;
-}
-#ifdef _LIBC
-weak_alias (__regexec, regexec)
-#endif
-
-/* Entry points for GNU code.  */
-
-/* re_match, re_search, re_match_2, re_search_2
-
-   The former two functions operate on STRING with length LENGTH,
-   while the later two operate on concatenation of STRING1 and STRING2
-   with lengths LENGTH1 and LENGTH2, respectively.
-
-   re_match() matches the compiled pattern in BUFP against the string,
-   starting at index START.
-
-   re_search() first tries matching at index START, then it tries to match
-   starting from index START + 1, and so on.  The last start position tried
-   is START + RANGE.  (Thus RANGE = 0 forces re_search to operate the same
-   way as re_match().)
-
-   The parameter STOP of re_{match,search}_2 specifies that no match exceeding
-   the first STOP characters of the concatenation of the strings should be
-   concerned.
-
-   If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
-   and all groups is stroed in REGS.  (For the "_2" variants, the offsets are
-   computed relative to the concatenation, not relative to the individual
-   strings.)
-
-   On success, re_match* functions return the length of the match, re_search*
-   return the position of the start of the match.  Return value -1 means no
-   match was found and -2 indicates an internal error.  */
-
-int
-re_match (bufp, string, length, start, regs)
-    struct re_pattern_buffer *bufp;
-    const char *string;
-    int length, start;
-    struct re_registers *regs;
-{
-  return re_search_stub (bufp, string, length, start, 0, length, regs, 1);
-}
-#ifdef _LIBC
-weak_alias (__re_match, re_match)
-#endif
-
-int
-re_search (bufp, string, length, start, range, regs)
-    struct re_pattern_buffer *bufp;
-    const char *string;
-    int length, start, range;
-    struct re_registers *regs;
-{
-  return re_search_stub (bufp, string, length, start, range, length, regs, 0);
-}
-#ifdef _LIBC
-weak_alias (__re_search, re_search)
-#endif
-
-int
-re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)
-    struct re_pattern_buffer *bufp;
-    const char *string1, *string2;
-    int length1, length2, start, stop;
-    struct re_registers *regs;
-{
-  return re_search_2_stub (bufp, string1, length1, string2, length2,
-			   start, 0, regs, stop, 1);
-}
-#ifdef _LIBC
-weak_alias (__re_match_2, re_match_2)
-#endif
-
-int
-re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)
-    struct re_pattern_buffer *bufp;
-    const char *string1, *string2;
-    int length1, length2, start, range, stop;
-    struct re_registers *regs;
-{
-  return re_search_2_stub (bufp, string1, length1, string2, length2,
-			   start, range, regs, stop, 0);
-}
-#ifdef _LIBC
-weak_alias (__re_search_2, re_search_2)
-#endif
-
-static int
-re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
-		  stop, ret_len)
-    struct re_pattern_buffer *bufp;
-    const char *string1, *string2;
-    int length1, length2, start, range, stop, ret_len;
-    struct re_registers *regs;
-{
-  const char *str;
-  int rval;
-  int len = length1 + length2;
-  int free_str = 0;
-
-  if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
-    return -2;
-
-  /* Concatenate the strings.  */
-  if (length2 > 0)
-    if (length1 > 0)
-      {
-	char *s = re_malloc (char, len);
-
-	if (BE (s == NULL, 0))
-	  return -2;
-	memcpy (s, string1, length1);
-	memcpy (s + length1, string2, length2);
-	str = s;
-	free_str = 1;
-      }
-    else
-      str = string2;
-  else
-    str = string1;
-
-  rval = re_search_stub (bufp, str, len, start, range, stop, regs,
-			 ret_len);
-  if (free_str)
-    re_free ((char *) str);
-  return rval;
-}
-
-/* The parameters have the same meaning as those of re_search.
-   Additional parameters:
-   If RET_LEN is nonzero the length of the match is returned (re_match style);
-   otherwise the position of the match is returned.  */
-
-static int
-re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)
-    struct re_pattern_buffer *bufp;
-    const char *string;
-    int length, start, range, stop, ret_len;
-    struct re_registers *regs;
-{
-  reg_errcode_t result;
-  regmatch_t *pmatch;
-  int nregs, rval;
-  int eflags = 0;
-
-  /* Check for out-of-range.  */
-  if (BE (start < 0 || start > length, 0))
-    return -1;
-  if (BE (start + range > length, 0))
-    range = length - start;
-  else if (BE (start + range < 0, 0))
-    range = -start;
-
-  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
-  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
-
-  /* Compile fastmap if we haven't yet.  */
-  if (range > 0 && bufp->fastmap != NULL && !bufp->fastmap_accurate)
-    re_compile_fastmap (bufp);
-
-  if (BE (bufp->no_sub, 0))
-    regs = NULL;
-
-  /* We need at least 1 register.  */
-  if (regs == NULL)
-    nregs = 1;
-  else if (BE (bufp->regs_allocated == REGS_FIXED &&
-	       regs->num_regs < bufp->re_nsub + 1, 0))
-    {
-      nregs = regs->num_regs;
-      if (BE (nregs < 1, 0))
-	{
-	  /* Nothing can be copied to regs.  */
-	  regs = NULL;
-	  nregs = 1;
-	}
-    }
-  else
-    nregs = bufp->re_nsub + 1;
-  pmatch = re_malloc (regmatch_t, nregs);
-  if (BE (pmatch == NULL, 0))
-    return -2;
-
-  result = re_search_internal (bufp, string, length, start, range, stop,
-			       nregs, pmatch, eflags);
-
-  rval = 0;
-
-  /* I hope we needn't fill ther regs with -1's when no match was found.  */
-  if (result != REG_NOERROR)
-    rval = -1;
-  else if (regs != NULL)
-    {
-      /* If caller wants register contents data back, copy them.  */
-      bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
-					   bufp->regs_allocated);
-      if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
-	rval = -2;
-    }
-
-  if (BE (rval == 0, 1))
-    {
-      if (ret_len)
-	{
-	  assert (pmatch[0].rm_so == start);
-	  rval = pmatch[0].rm_eo - start;
-	}
-      else
-	rval = pmatch[0].rm_so;
-    }
-  re_free (pmatch);
-  return rval;
-}
-
-static unsigned
-re_copy_regs (regs, pmatch, nregs, regs_allocated)
-    struct re_registers *regs;
-    regmatch_t *pmatch;
-    int nregs, regs_allocated;
-{
-  int rval = REGS_REALLOCATE;
-  int i;
-  int need_regs = nregs + 1;
-  /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
-     uses.  */
-
-  /* Have the register data arrays been allocated?  */
-  if (regs_allocated == REGS_UNALLOCATED)
-    { /* No.  So allocate them with malloc.  */
-      regs->start = re_malloc (regoff_t, need_regs);
-      if (BE (regs->start == NULL, 0))
-	return REGS_UNALLOCATED;
-      regs->end = re_malloc (regoff_t, need_regs);
-      if (BE (regs->end == NULL, 0))
-	{
-	  re_free (regs->start);
-	  return REGS_UNALLOCATED;
-	}
-      regs->num_regs = need_regs;
-    }
-  else if (regs_allocated == REGS_REALLOCATE)
-    { /* Yes.  If we need more elements than were already
-	 allocated, reallocate them.  If we need fewer, just
-	 leave it alone.  */
-      if (need_regs > regs->num_regs)
-	{
-	  regs->start = re_realloc (regs->start, regoff_t, need_regs);
-	  if (BE (regs->start == NULL, 0))
-	    {
-	      if (regs->end != NULL)
-		re_free (regs->end);
-	      return REGS_UNALLOCATED;
-	    }
-	  regs->end = re_realloc (regs->end, regoff_t, need_regs);
-	  if (BE (regs->end == NULL, 0))
-	    {
-	      re_free (regs->start);
-	      return REGS_UNALLOCATED;
-	    }
-	  regs->num_regs = need_regs;
-	}
-    }
-  else
-    {
-      assert (regs_allocated == REGS_FIXED);
-      /* This function may not be called with REGS_FIXED and nregs too big.  */
-      assert (regs->num_regs >= nregs);
-      rval = REGS_FIXED;
-    }
-
-  /* Copy the regs.  */
-  for (i = 0; i < nregs; ++i)
-    {
-      regs->start[i] = pmatch[i].rm_so;
-      regs->end[i] = pmatch[i].rm_eo;
-    }
-  for ( ; i < regs->num_regs; ++i)
-    regs->start[i] = regs->end[i] = -1;
-
-  return rval;
-}
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
-   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
-   this memory for recording register information.  STARTS and ENDS
-   must be allocated using the malloc library routine, and must each
-   be at least NUM_REGS * sizeof (regoff_t) bytes long.
-
-   If NUM_REGS == 0, then subsequent matches should allocate their own
-   register data.
-
-   Unless this function is called, the first search or match using
-   PATTERN_BUFFER will allocate its own register data, without
-   freeing the old data.  */
-
-void
-re_set_registers (bufp, regs, num_regs, starts, ends)
-    struct re_pattern_buffer *bufp;
-    struct re_registers *regs;
-    unsigned num_regs;
-    regoff_t *starts, *ends;
-{
-  if (num_regs)
-    {
-      bufp->regs_allocated = REGS_REALLOCATE;
-      regs->num_regs = num_regs;
-      regs->start = starts;
-      regs->end = ends;
-    }
-  else
-    {
-      bufp->regs_allocated = REGS_UNALLOCATED;
-      regs->num_regs = 0;
-      regs->start = regs->end = (regoff_t *) 0;
-    }
-}
-#ifdef _LIBC
-weak_alias (__re_set_registers, re_set_registers)
-#endif
-
-/* Entry points compatible with 4.2 BSD regex library.  We don't define
-   them unless specifically requested.  */
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-int
-# ifdef _LIBC
-weak_function
-# endif
-re_exec (s)
-     const char *s;
-{
-  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
-}
-#endif /* _REGEX_RE_COMP */
-
-static re_node_set empty_set;
-
-/* Internal entry point.  */
-
-/* Searches for a compiled pattern PREG in the string STRING, whose
-   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
-   mingings with regexec.  START, and RANGE have the same meanings
-   with re_search.
-   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
-   otherwise return the error code.
-   Note: We assume front end functions already check ranges.
-   (START + RANGE >= 0 && START + RANGE <= LENGTH)  */
-
-static reg_errcode_t
-re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
-		    eflags)
-    const regex_t *preg;
-    const char *string;
-    int length, start, range, stop, eflags;
-    size_t nmatch;
-    regmatch_t pmatch[];
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  re_string_t input;
-  int left_lim, right_lim, incr;
-  int fl_longest_match, match_first, match_last = -1;
-  int fast_translate, sb;
-  re_match_context_t mctx;
-  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
-		    && range && !preg->can_be_null) ? preg->fastmap : NULL);
-
-  /* Check if the DFA haven't been compiled.  */
-  if (BE (preg->used == 0 || dfa->init_state == NULL
-	  || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-	  || dfa->init_state_begbuf == NULL, 0))
-    return REG_NOMATCH;
-
-  re_node_set_init_empty (&empty_set);
-  memset (&mctx, '\0', sizeof (re_match_context_t));
-
-  /* We must check the longest matching, if nmatch > 0.  */
-  fl_longest_match = (nmatch != 0 || dfa->nbackref);
-
-  err = re_string_allocate (&input, string, length, dfa->nodes_len + 1,
-			    preg->translate, preg->syntax & RE_ICASE);
-  if (BE (err != REG_NOERROR, 0))
-    goto free_return;
-  input.stop = stop;
-
-  err = match_ctx_init (&mctx, eflags, &input, dfa->nbackref * 2);
-  if (BE (err != REG_NOERROR, 0))
-    goto free_return;
-
-  /* We will log all the DFA states through which the dfa pass,
-     if nmatch > 1, or this dfa has "multibyte node", which is a
-     back-reference or a node which can accept multibyte character or
-     multi character collating element.  */
-  if (nmatch > 1 || dfa->has_mb_node)
-    {
-      mctx.state_log = re_malloc (re_dfastate_t *, dfa->nodes_len + 1);
-      if (BE (mctx.state_log == NULL, 0))
-	{
-	  err = REG_ESPACE;
-	  goto free_return;
-	}
-    }
-  else
-    mctx.state_log = NULL;
-
-#ifdef DEBUG
-  /* We assume front-end functions already check them.  */
-  assert (start + range >= 0 && start + range <= length);
-#endif
-
-  match_first = start;
-  input.tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
-		       : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
-
-  /* Check incrementally whether of not the input string match.  */
-  incr = (range < 0) ? -1 : 1;
-  left_lim = (range < 0) ? start + range : start;
-  right_lim = (range < 0) ? start : start + range;
-  sb = MB_CUR_MAX == 1;
-  fast_translate = sb || !(preg->syntax & RE_ICASE || preg->translate);
-
-  for (;;)
-    {
-      /* At first get the current byte from input string.  */
-      if (fastmap)
-	{
-	  if (BE (fast_translate, 1))
-	    {
-	      unsigned RE_TRANSLATE_TYPE t
-		= (unsigned RE_TRANSLATE_TYPE) preg->translate;
-	      if (BE (range >= 0, 1))
-		{
-		  if (BE (t != NULL, 0))
-		    {
-		      while (BE (match_first < right_lim, 1)
-			     && !fastmap[t[(unsigned char) string[match_first]]])
-			++match_first;
-		    }
-		  else
-		    {
-		      while (BE (match_first < right_lim, 1)
-			     && !fastmap[(unsigned char) string[match_first]])
-			++match_first;
-		    }
-		  if (BE (match_first == right_lim, 0))
-		    {
-		      int ch = match_first >= length
-			       ? 0 : (unsigned char) string[match_first];
-		      if (!fastmap[t ? t[ch] : ch])
-			break;
-		    }
-		}
-	      else
-		{
-		  while (match_first >= left_lim)
-		    {
-		      int ch = match_first >= length
-			       ? 0 : (unsigned char) string[match_first];
-		      if (fastmap[t ? t[ch] : ch])
-			break;
-		      --match_first;
-		    }
-		  if (match_first < left_lim)
-		    break;
-		}
-	    }
-	  else
-	    {
-	      int ch;
-
-	      do
-		{
-		  /* In this case, we can't determine easily the current byte,
-		     since it might be a component byte of a multibyte
-		     character.  Then we use the constructed buffer
-		     instead.  */
-		  /* If MATCH_FIRST is out of the valid range, reconstruct the
-		     buffers.  */
-		  if (input.raw_mbs_idx + input.valid_len <= match_first
-		      || match_first < input.raw_mbs_idx)
-		    {
-		      err = re_string_reconstruct (&input, match_first, eflags,
-						   preg->newline_anchor);
-		      if (BE (err != REG_NOERROR, 0))
-			goto free_return;
-		    }
-		  /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
-		     Note that MATCH_FIRST must not be smaller than 0.  */
-		  ch = ((match_first >= length) ? 0
-		       : re_string_byte_at (&input,
-					    match_first - input.raw_mbs_idx));
-		  if (fastmap[ch])
-		    break;
-		  match_first += incr;
-		}
-	      while (match_first >= left_lim && match_first <= right_lim);
-	      if (! fastmap[ch])
-		break;
-	    }
-	}
-
-      /* Reconstruct the buffers so that the matcher can assume that
-	 the matching starts from the begining of the buffer.  */
-      err = re_string_reconstruct (&input, match_first, eflags,
-				   preg->newline_anchor);
-      if (BE (err != REG_NOERROR, 0))
-	goto free_return;
-#ifdef RE_ENABLE_I18N
-     /* Eliminate it when it is a component of a multibyte character
-	 and isn't the head of a multibyte character.  */
-      if (sb || re_string_first_byte (&input, 0))
-#endif
-	{
-	  /* It seems to be appropriate one, then use the matcher.  */
-	  /* We assume that the matching starts from 0.  */
-	  mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
-	  match_last = check_matching (preg, &mctx, 0, fl_longest_match);
-	  if (match_last != -1)
-	    {
-	      if (BE (match_last == -2, 0))
-		{
-		  err = REG_ESPACE;
-		  goto free_return;
-		}
-	      else
-		{
-		  mctx.match_last = match_last;
-		  if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
-		    {
-		      re_dfastate_t *pstate = mctx.state_log[match_last];
-		      mctx.last_node = check_halt_state_context (preg, pstate,
-								 &mctx, match_last);
-		    }
-		  if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
-		      || dfa->nbackref)
-		    {
-		      err = prune_impossible_nodes (preg, &mctx);
-		      if (err == REG_NOERROR)
-			break;
-		      if (BE (err != REG_NOMATCH, 0))
-			goto free_return;
-		    }
-		  else
-		    break; /* We found a matching.  */
-		}
-	    }
-	  match_ctx_clean (&mctx);
-	}
-      /* Update counter.  */
-      match_first += incr;
-      if (match_first < left_lim || right_lim < match_first)
-	break;
-    }
-
-  /* Set pmatch[] if we need.  */
-  if (match_last != -1 && nmatch > 0)
-    {
-      int reg_idx;
-
-      /* Initialize registers.  */
-      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
-	pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
-
-      /* Set the points where matching start/end.  */
-      pmatch[0].rm_so = 0;
-      pmatch[0].rm_eo = mctx.match_last;
-
-      if (!preg->no_sub && nmatch > 1)
-	{
-	  err = set_regs (preg, &mctx, nmatch, pmatch,
-			  dfa->has_plural_match && dfa->nbackref > 0);
-	  if (BE (err != REG_NOERROR, 0))
-	    goto free_return;
-	}
-
-      /* At last, add the offset to the each registers, since we slided
-	 the buffers so that We can assume that the matching starts from 0.  */
-      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
-	if (pmatch[reg_idx].rm_so != -1)
-	  {
-	    pmatch[reg_idx].rm_so += match_first;
-	    pmatch[reg_idx].rm_eo += match_first;
-	  }
-    }
-  err = (match_last == -1) ? REG_NOMATCH : REG_NOERROR;
- free_return:
-  re_free (mctx.state_log);
-  if (dfa->nbackref)
-    match_ctx_free (&mctx);
-  re_string_destruct (&input);
-  return err;
-}
-
-static reg_errcode_t
-prune_impossible_nodes (preg, mctx)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-{
-  int halt_node, match_last;
-  reg_errcode_t ret;
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  re_dfastate_t **sifted_states;
-  re_dfastate_t **lim_states = NULL;
-  re_sift_context_t sctx;
-#ifdef DEBUG
-  assert (mctx->state_log != NULL);
-#endif
-  match_last = mctx->match_last;
-  halt_node = mctx->last_node;
-  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
-  if (BE (sifted_states == NULL, 0))
-    {
-      ret = REG_ESPACE;
-      goto free_return;
-    }
-  if (dfa->nbackref)
-    {
-      lim_states = re_malloc (re_dfastate_t *, match_last + 1);
-      if (BE (lim_states == NULL, 0))
-	{
-	  ret = REG_ESPACE;
-	  goto free_return;
-	}
-      while (1)
-	{
-	  memset (lim_states, '\0',
-		  sizeof (re_dfastate_t *) * (match_last + 1));
-	  match_ctx_clear_flag (mctx);
-	  sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
-			 match_last, 0);
-	  ret = sift_states_backward (preg, mctx, &sctx);
-	  re_node_set_free (&sctx.limits);
-	  if (BE (ret != REG_NOERROR, 0))
-	      goto free_return;
-	  if (sifted_states[0] != NULL || lim_states[0] != NULL)
-	    break;
-	  do
-	    {
-	      --match_last;
-	      if (match_last < 0)
-		{
-		  ret = REG_NOMATCH;
-		  goto free_return;
-		}
-	    } while (!mctx->state_log[match_last]->halt);
-	  halt_node = check_halt_state_context (preg,
-						mctx->state_log[match_last],
-						mctx, match_last);
-	}
-      ret = merge_state_array (dfa, sifted_states, lim_states,
-			       match_last + 1);
-      re_free (lim_states);
-      lim_states = NULL;
-      if (BE (ret != REG_NOERROR, 0))
-	goto free_return;
-    }
-  else
-    {
-      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
-		     match_last, 0);
-      ret = sift_states_backward (preg, mctx, &sctx);
-      re_node_set_free (&sctx.limits);
-      if (BE (ret != REG_NOERROR, 0))
-	goto free_return;
-    }
-  re_free (mctx->state_log);
-  mctx->state_log = sifted_states;
-  sifted_states = NULL;
-  mctx->last_node = halt_node;
-  mctx->match_last = match_last;
-  ret = REG_NOERROR;
- free_return:
-  re_free (sifted_states);
-  re_free (lim_states);
-  return ret;
-}
-
-/* Acquire an initial state and return it.
-   We must select appropriate initial state depending on the context,
-   since initial states may have constraints like "\<", "^", etc..  */
-
-static inline re_dfastate_t *
-acquire_init_state_context (err, preg, mctx, idx)
-     reg_errcode_t *err;
-     const regex_t *preg;
-     const re_match_context_t *mctx;
-     int idx;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-
-  *err = REG_NOERROR;
-  if (dfa->init_state->has_constraint)
-    {
-      unsigned int context;
-      context =  re_string_context_at (mctx->input, idx - 1, mctx->eflags,
-				       preg->newline_anchor);
-      if (IS_WORD_CONTEXT (context))
-	return dfa->init_state_word;
-      else if (IS_ORDINARY_CONTEXT (context))
-	return dfa->init_state;
-      else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))
-	return dfa->init_state_begbuf;
-      else if (IS_NEWLINE_CONTEXT (context))
-	return dfa->init_state_nl;
-      else if (IS_BEGBUF_CONTEXT (context))
-	{
-	  /* It is relatively rare case, then calculate on demand.  */
-	  return  re_acquire_state_context (err, dfa,
-					    dfa->init_state->entrance_nodes,
-					    context);
-	}
-      else
-	/* Must not happen?  */
-	return dfa->init_state;
-    }
-  else
-    return dfa->init_state;
-}
-
-/* Check whether the regular expression match input string INPUT or not,
-   and return the index where the matching end, return -1 if not match,
-   or return -2 in case of an error.
-   FL_SEARCH means we must search where the matching starts,
-   FL_LONGEST_MATCH means we want the POSIX longest matching.
-   Note that the matcher assume that the maching starts from the current
-   index of the buffer.  */
-
-static int
-check_matching (preg, mctx, fl_search, fl_longest_match)
-    const regex_t *preg;
-    re_match_context_t *mctx;
-    int fl_search, fl_longest_match;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  reg_errcode_t err;
-  int match = 0;
-  int match_last = -1;
-  int cur_str_idx = re_string_cur_idx (mctx->input);
-  re_dfastate_t *cur_state;
-
-  cur_state = acquire_init_state_context (&err, preg, mctx, cur_str_idx);
-  /* An initial state must not be NULL(invalid state).  */
-  if (BE (cur_state == NULL, 0))
-    return -2;
-  if (mctx->state_log != NULL)
-    mctx->state_log[cur_str_idx] = cur_state;
-
-  /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
-     later.  E.g. Processing back references.  */
-  if (dfa->nbackref)
-    {
-      err = check_subexp_matching_top (dfa, mctx, &cur_state->nodes, 0);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-
-  if (cur_state->has_backref)
-    {
-      err = transit_state_bkref (preg, &cur_state->nodes, mctx);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-
-  /* If the RE accepts NULL string.  */
-  if (cur_state->halt)
-    {
-      if (!cur_state->has_constraint
-	  || check_halt_state_context (preg, cur_state, mctx, cur_str_idx))
-	{
-	  if (!fl_longest_match)
-	    return cur_str_idx;
-	  else
-	    {
-	      match_last = cur_str_idx;
-	      match = 1;
-	    }
-	}
-    }
-
-  while (!re_string_eoi (mctx->input))
-    {
-      cur_state = transit_state (&err, preg, mctx, cur_state,
-				 fl_search && !match);
-      if (cur_state == NULL) /* Reached at the invalid state or an error.  */
-	{
-	  cur_str_idx = re_string_cur_idx (mctx->input);
-	  if (BE (err != REG_NOERROR, 0))
-	    return -2;
-	  if (fl_search && !match)
-	    {
-	      /* Restart from initial state, since we are searching
-		 the point from where matching start.  */
-#ifdef RE_ENABLE_I18N
-	      if (MB_CUR_MAX == 1
-		  || re_string_first_byte (mctx->input, cur_str_idx))
-#endif /* RE_ENABLE_I18N */
-		cur_state = acquire_init_state_context (&err, preg, mctx,
-							cur_str_idx);
-	      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
-		return -2;
-	      if (mctx->state_log != NULL)
-		mctx->state_log[cur_str_idx] = cur_state;
-	    }
-	  else if (!fl_longest_match && match)
-	    break;
-	  else /* (fl_longest_match && match) || (!fl_search && !match)  */
-	    {
-	      if (mctx->state_log == NULL)
-		break;
-	      else
-		{
-		  int max = mctx->state_log_top;
-		  for (; cur_str_idx <= max; ++cur_str_idx)
-		    if (mctx->state_log[cur_str_idx] != NULL)
-		      break;
-		  if (cur_str_idx > max)
-		    break;
-		}
-	    }
-	}
-
-      if (cur_state != NULL && cur_state->halt)
-	{
-	  /* Reached at a halt state.
-	     Check the halt state can satisfy the current context.  */
-	  if (!cur_state->has_constraint
-	      || check_halt_state_context (preg, cur_state, mctx,
-					   re_string_cur_idx (mctx->input)))
-	    {
-	      /* We found an appropriate halt state.  */
-	      match_last = re_string_cur_idx (mctx->input);
-	      match = 1;
-	      if (!fl_longest_match)
-		break;
-	    }
-	}
-   }
-  return match_last;
-}
-
-/* Check NODE match the current context.  */
-
-static int check_halt_node_context (dfa, node, context)
-    const re_dfa_t *dfa;
-    int node;
-    unsigned int context;
-{
-  re_token_type_t type = dfa->nodes[node].type;
-  unsigned int constraint = dfa->nodes[node].constraint;
-  if (type != END_OF_RE)
-    return 0;
-  if (!constraint)
-    return 1;
-  if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
-    return 0;
-  return 1;
-}
-
-/* Check the halt state STATE match the current context.
-   Return 0 if not match, if the node, STATE has, is a halt node and
-   match the context, return the node.  */
-
-static int
-check_halt_state_context (preg, state, mctx, idx)
-    const regex_t *preg;
-    const re_dfastate_t *state;
-    const re_match_context_t *mctx;
-    int idx;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int i;
-  unsigned int context;
-#ifdef DEBUG
-  assert (state->halt);
-#endif
-  context = re_string_context_at (mctx->input, idx, mctx->eflags,
-				  preg->newline_anchor);
-  for (i = 0; i < state->nodes.nelem; ++i)
-    if (check_halt_node_context (dfa, state->nodes.elems[i], context))
-      return state->nodes.elems[i];
-  return 0;
-}
-
-/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
-   corresponding to the DFA).
-   Return the destination node, and update EPS_VIA_NODES, return -1 in case
-   of errors.  */
-
-static int
-proceed_next_node (preg, nregs, regs, mctx, pidx, node, eps_via_nodes, fs)
-    const regex_t *preg;
-    regmatch_t *regs;
-    const re_match_context_t *mctx;
-    int nregs, *pidx, node;
-    re_node_set *eps_via_nodes;
-    struct re_fail_stack_t *fs;
-{
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  int i, err, dest_node;
-  dest_node = -1;
-  if (IS_EPSILON_NODE (dfa->nodes[node].type))
-    {
-      re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
-      int ndest, dest_nodes[2];
-      err = re_node_set_insert (eps_via_nodes, node);
-      if (BE (err < 0, 0))
-	return -1;
-      /* Pick up valid destinations.  */
-      for (ndest = 0, i = 0; i < dfa->edests[node].nelem; ++i)
-	{
-	  int candidate = dfa->edests[node].elems[i];
-	  if (!re_node_set_contains (cur_nodes, candidate))
-	    continue;
-	  dest_nodes[0] = (ndest == 0) ? candidate : dest_nodes[0];
-	  dest_nodes[1] = (ndest == 1) ? candidate : dest_nodes[1];
-	  ++ndest;
-	}
-      if (ndest <= 1)
-	return ndest == 0 ? -1 : (ndest == 1 ? dest_nodes[0] : 0);
-      /* In order to avoid infinite loop like "(a*)*".  */
-      if (re_node_set_contains (eps_via_nodes, dest_nodes[0]))
-	return dest_nodes[1];
-      if (fs != NULL)
-	push_fail_stack (fs, *pidx, dest_nodes, nregs, regs, eps_via_nodes);
-      return dest_nodes[0];
-    }
-  else
-    {
-      int naccepted = 0;
-      re_token_type_t type = dfa->nodes[node].type;
-
-#ifdef RE_ENABLE_I18N
-      if (ACCEPT_MB_NODE (type))
-	naccepted = check_node_accept_bytes (preg, node, mctx->input, *pidx);
-      else
-#endif /* RE_ENABLE_I18N */
-      if (type == OP_BACK_REF)
-	{
-	  int subexp_idx = dfa->nodes[node].opr.idx;
-	  naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
-	  if (fs != NULL)
-	    {
-	      if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
-		return -1;
-	      else if (naccepted)
-		{
-		  char *buf = (char *) re_string_get_buffer (mctx->input);
-		  if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
-			      naccepted) != 0)
-		    return -1;
-		}
-	    }
-
-	  if (naccepted == 0)
-	    {
-	      err = re_node_set_insert (eps_via_nodes, node);
-	      if (BE (err < 0, 0))
-		return -2;
-	      dest_node = dfa->edests[node].elems[0];
-	      if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
-					dest_node))
-		return dest_node;
-	    }
-	}
-
-      if (naccepted != 0
-	  || check_node_accept (preg, dfa->nodes + node, mctx, *pidx))
-	{
-	  dest_node = dfa->nexts[node];
-	  *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
-	  if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
-		     || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
-					       dest_node)))
-	    return -1;
-	  re_node_set_empty (eps_via_nodes);
-	  return dest_node;
-	}
-    }
-  return -1;
-}
-
-static reg_errcode_t
-push_fail_stack (fs, str_idx, dests, nregs, regs, eps_via_nodes)
-     struct re_fail_stack_t *fs;
-     int str_idx, *dests, nregs;
-     regmatch_t *regs;
-     re_node_set *eps_via_nodes;
-{
-  reg_errcode_t err;
-  int num = fs->num++;
-  if (fs->num == fs->alloc)
-    {
-      struct re_fail_stack_ent_t *new_array;
-      fs->alloc *= 2;
-      new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
-				       * fs->alloc));
-      if (new_array == NULL)
-	return REG_ESPACE;
-      fs->stack = new_array;
-    }
-  fs->stack[num].idx = str_idx;
-  fs->stack[num].node = dests[1];
-  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
-  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
-  err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
-  return err;
-}
-
-static int
-pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes)
-     struct re_fail_stack_t *fs;
-     int *pidx, nregs;
-     regmatch_t *regs;
-     re_node_set *eps_via_nodes;
-{
-  int num = --fs->num;
-  assert (num >= 0);
- *pidx = fs->stack[num].idx;
-  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
-  re_node_set_free (eps_via_nodes);
-  re_free (fs->stack[num].regs);
-  *eps_via_nodes = fs->stack[num].eps_via_nodes;
-  return fs->stack[num].node;
-}
-
-/* Set the positions where the subexpressions are starts/ends to registers
-   PMATCH.
-   Note: We assume that pmatch[0] is already set, and
-   pmatch[i].rm_so == pmatch[i].rm_eo == -1 (i > 1).  */
-
-static reg_errcode_t
-set_regs (preg, mctx, nmatch, pmatch, fl_backtrack)
-     const regex_t *preg;
-     const re_match_context_t *mctx;
-     size_t nmatch;
-     regmatch_t *pmatch;
-     int fl_backtrack;
-{
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  int idx, cur_node, real_nmatch;
-  re_node_set eps_via_nodes;
-  struct re_fail_stack_t *fs;
-  struct re_fail_stack_t fs_body = {0, 2, NULL};
-#ifdef DEBUG
-  assert (nmatch > 1);
-  assert (mctx->state_log != NULL);
-#endif
-  if (fl_backtrack)
-    {
-      fs = &fs_body;
-      fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
-    }
-  else
-    fs = NULL;
-  cur_node = dfa->init_node;
-  real_nmatch = (nmatch <= preg->re_nsub) ? nmatch : preg->re_nsub + 1;
-  re_node_set_init_empty (&eps_via_nodes);
-  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
-    {
-      update_regs (dfa, pmatch, cur_node, idx, real_nmatch);
-      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
-	{
-	  int reg_idx;
-	  if (fs)
-	    {
-	      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
-		if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
-		  break;
-	      if (reg_idx == nmatch)
-		{
-		  re_node_set_free (&eps_via_nodes);
-		  return free_fail_stack_return (fs);
-		}
-	      cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
-					 &eps_via_nodes);
-	    }
-	  else
-	    {
-	      re_node_set_free (&eps_via_nodes);
-	      return REG_NOERROR;
-	    }
-	}
-
-      /* Proceed to next node.  */
-      cur_node = proceed_next_node (preg, nmatch, pmatch, mctx, &idx, cur_node,
-				    &eps_via_nodes, fs);
-
-      if (BE (cur_node < 0, 0))
-	{
-	  if (cur_node == -2)
-	    return REG_ESPACE;
-	  if (fs)
-	    cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
-				       &eps_via_nodes);
-	  else
-	    {
-	      re_node_set_free (&eps_via_nodes);
-	      return REG_NOMATCH;
-	    }
-	}
-    }
-  re_node_set_free (&eps_via_nodes);
-  return free_fail_stack_return (fs);
-}
-
-static reg_errcode_t
-free_fail_stack_return (fs)
-     struct re_fail_stack_t *fs;
-{
-  if (fs)
-    {
-      int fs_idx;
-      for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
-	{
-	  re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
-	  re_free (fs->stack[fs_idx].regs);
-	}
-      re_free (fs->stack);
-    }
-  return REG_NOERROR;
-}
-
-static void
-update_regs (dfa, pmatch, cur_node, cur_idx, nmatch)
-     re_dfa_t *dfa;
-     regmatch_t *pmatch;
-     int cur_node, cur_idx, nmatch;
-{
-  int type = dfa->nodes[cur_node].type;
-  int reg_num;
-  if (type != OP_OPEN_SUBEXP && type != OP_CLOSE_SUBEXP)
-    return;
-  reg_num = dfa->nodes[cur_node].opr.idx + 1;
-  if (reg_num >= nmatch)
-    return;
-  if (type == OP_OPEN_SUBEXP)
-    {
-      /* We are at the first node of this sub expression.  */
-      pmatch[reg_num].rm_so = cur_idx;
-      pmatch[reg_num].rm_eo = -1;
-    }
-  else if (type == OP_CLOSE_SUBEXP)
-    /* We are at the first node of this sub expression.  */
-    pmatch[reg_num].rm_eo = cur_idx;
-}
-
-#define NUMBER_OF_STATE 1
-
-/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
-   and sift the nodes in each states according to the following rules.
-   Updated state_log will be wrote to STATE_LOG.
-
-   Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
-     1. When STR_IDX == MATCH_LAST(the last index in the state_log):
-	If `a' isn't the LAST_NODE and `a' can't epsilon transit to
-	the LAST_NODE, we throw away the node `a'.
-     2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
-	string `s' and transit to `b':
-	i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
-	   away the node `a'.
-	ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
-	    throwed away, we throw away the node `a'.
-     3. When 0 <= STR_IDX < n and 'a' epsilon transit to 'b':
-	i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
-	   node `a'.
-	ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is throwed away,
-	    we throw away the node `a'.  */
-
-#define STATE_NODE_CONTAINS(state,node) \
-  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
-
-static reg_errcode_t
-sift_states_backward (preg, mctx, sctx)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     re_sift_context_t *sctx;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  int null_cnt = 0;
-  int str_idx = sctx->last_str_idx;
-  re_node_set cur_dest;
-  re_node_set *cur_src; /* Points the state_log[str_idx]->nodes  */
-
-#ifdef DEBUG
-  assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
-#endif
-  cur_src = &mctx->state_log[str_idx]->nodes;
-
-  /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
-     transit to the last_node and the last_node itself.  */
-  err = re_node_set_init_1 (&cur_dest, sctx->last_node);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  err = update_cur_sifted_state (preg, mctx, sctx, str_idx, &cur_dest);
-  if (BE (err != REG_NOERROR, 0))
-    goto free_return;
-
-  /* Then check each states in the state_log.  */
-  while (str_idx > 0)
-    {
-      int i, ret;
-      /* Update counters.  */
-      null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
-      if (null_cnt > mctx->max_mb_elem_len)
-	{
-	  memset (sctx->sifted_states, '\0',
-		  sizeof (re_dfastate_t *) * str_idx);
-	  re_node_set_free (&cur_dest);
-	  return REG_NOERROR;
-	}
-      re_node_set_empty (&cur_dest);
-      --str_idx;
-      cur_src = ((mctx->state_log[str_idx] == NULL) ? &empty_set
-		 : &mctx->state_log[str_idx]->nodes);
-
-      /* Then build the next sifted state.
-	 We build the next sifted state on `cur_dest', and update
-	 `sifted_states[str_idx]' with `cur_dest'.
-	 Note:
-	 `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
-	 `cur_src' points the node_set of the old `state_log[str_idx]'.  */
-      for (i = 0; i < cur_src->nelem; i++)
-	{
-	  int prev_node = cur_src->elems[i];
-	  int naccepted = 0;
-	  re_token_type_t type = dfa->nodes[prev_node].type;
-
-	  if (IS_EPSILON_NODE(type))
-	    continue;
-#ifdef RE_ENABLE_I18N
-	  /* If the node may accept `multi byte'.  */
-	  if (ACCEPT_MB_NODE (type))
-	    naccepted = sift_states_iter_mb (preg, mctx, sctx, prev_node,
-					     str_idx, sctx->last_str_idx);
-
-#endif /* RE_ENABLE_I18N */
-	  /* We don't check backreferences here.
-	     See update_cur_sifted_state().  */
-
-	  if (!naccepted
-	      && check_node_accept (preg, dfa->nodes + prev_node, mctx,
-				    str_idx)
-	      && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
-				      dfa->nexts[prev_node]))
-	    naccepted = 1;
-
-	  if (naccepted == 0)
-	    continue;
-
-	  if (sctx->limits.nelem)
-	    {
-	      int to_idx = str_idx + naccepted;
-	      if (check_dst_limits (dfa, &sctx->limits, mctx,
-				    dfa->nexts[prev_node], to_idx,
-				    prev_node, str_idx))
-		continue;
-	    }
-	  ret = re_node_set_insert (&cur_dest, prev_node);
-	  if (BE (ret == -1, 0))
-	    {
-	      err = REG_ESPACE;
-	      goto free_return;
-	    }
-	}
-
-      /* Add all the nodes which satisfy the following conditions:
-	 - It can epsilon transit to a node in CUR_DEST.
-	 - It is in CUR_SRC.
-	 And update state_log.  */
-      err = update_cur_sifted_state (preg, mctx, sctx, str_idx, &cur_dest);
-      if (BE (err != REG_NOERROR, 0))
-	goto free_return;
-    }
-  err = REG_NOERROR;
- free_return:
-  re_node_set_free (&cur_dest);
-  return err;
-}
-
-/* Helper functions.  */
-
-static inline reg_errcode_t
-clean_state_log_if_need (mctx, next_state_log_idx)
-    re_match_context_t *mctx;
-    int next_state_log_idx;
-{
-  int top = mctx->state_log_top;
-
-  if (next_state_log_idx >= mctx->input->bufs_len
-      || (next_state_log_idx >= mctx->input->valid_len
-	  && mctx->input->valid_len < mctx->input->len))
-    {
-      reg_errcode_t err;
-      err = extend_buffers (mctx);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-
-  if (top < next_state_log_idx)
-    {
-      memset (mctx->state_log + top + 1, '\0',
-	      sizeof (re_dfastate_t *) * (next_state_log_idx - top));
-      mctx->state_log_top = next_state_log_idx;
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-merge_state_array (dfa, dst, src, num)
-     re_dfa_t *dfa;
-     re_dfastate_t **dst;
-     re_dfastate_t **src;
-     int num;
-{
-  int st_idx;
-  reg_errcode_t err;
-  for (st_idx = 0; st_idx < num; ++st_idx)
-    {
-      if (dst[st_idx] == NULL)
-	dst[st_idx] = src[st_idx];
-      else if (src[st_idx] != NULL)
-	{
-	  re_node_set merged_set;
-	  err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
-					&src[st_idx]->nodes);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	  dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
-	  re_node_set_free (&merged_set);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	}
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-update_cur_sifted_state (preg, mctx, sctx, str_idx, dest_nodes)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     re_sift_context_t *sctx;
-     int str_idx;
-     re_node_set *dest_nodes;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  const re_node_set *candidates;
-  candidates = ((mctx->state_log[str_idx] == NULL) ? &empty_set
-		: &mctx->state_log[str_idx]->nodes);
-
-  /* At first, add the nodes which can epsilon transit to a node in
-     DEST_NODE.  */
-  if (dest_nodes->nelem)
-    {
-      err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-
-  /* Then, check the limitations in the current sift_context.  */
-  if (dest_nodes->nelem && sctx->limits.nelem)
-    {
-      err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
-				 mctx->bkref_ents, str_idx);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-
-  /* Update state_log.  */
-  sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
-  if (BE (sctx->sifted_states[str_idx] == NULL && err != REG_NOERROR, 0))
-    return err;
-
-  if ((mctx->state_log[str_idx] != NULL
-       && mctx->state_log[str_idx]->has_backref))
-    {
-      err = sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-add_epsilon_src_nodes (dfa, dest_nodes, candidates)
-     re_dfa_t *dfa;
-     re_node_set *dest_nodes;
-     const re_node_set *candidates;
-{
-  reg_errcode_t err;
-  int src_idx;
-  re_node_set src_copy;
-
-  err = re_node_set_init_copy (&src_copy, dest_nodes);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  for (src_idx = 0; src_idx < src_copy.nelem; ++src_idx)
-    {
-      err = re_node_set_add_intersect (dest_nodes, candidates,
-				       dfa->inveclosures
-				       + src_copy.elems[src_idx]);
-      if (BE (err != REG_NOERROR, 0))
-	{
-	  re_node_set_free (&src_copy);
-	  return err;
-	}
-    }
-  re_node_set_free (&src_copy);
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates)
-     re_dfa_t *dfa;
-     int node;
-     re_node_set *dest_nodes;
-     const re_node_set *candidates;
-{
-    int ecl_idx;
-    reg_errcode_t err;
-    re_node_set *inv_eclosure = dfa->inveclosures + node;
-    re_node_set except_nodes;
-    re_node_set_init_empty (&except_nodes);
-    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
-      {
-	int cur_node = inv_eclosure->elems[ecl_idx];
-	if (cur_node == node)
-	  continue;
-	if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
-	  {
-	    int edst1 = dfa->edests[cur_node].elems[0];
-	    int edst2 = ((dfa->edests[cur_node].nelem > 1)
-			 ? dfa->edests[cur_node].elems[1] : -1);
-	    if ((!re_node_set_contains (inv_eclosure, edst1)
-		 && re_node_set_contains (dest_nodes, edst1))
-		|| (edst2 > 0
-		    && !re_node_set_contains (inv_eclosure, edst2)
-		    && re_node_set_contains (dest_nodes, edst2)))
-	      {
-		err = re_node_set_add_intersect (&except_nodes, candidates,
-						 dfa->inveclosures + cur_node);
-		if (BE (err != REG_NOERROR, 0))
-		  {
-		    re_node_set_free (&except_nodes);
-		    return err;
-		  }
-	      }
-	  }
-      }
-    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
-      {
-	int cur_node = inv_eclosure->elems[ecl_idx];
-	if (!re_node_set_contains (&except_nodes, cur_node))
-	  {
-	    int idx = re_node_set_contains (dest_nodes, cur_node) - 1;
-	    re_node_set_remove_at (dest_nodes, idx);
-	  }
-      }
-    re_node_set_free (&except_nodes);
-    return REG_NOERROR;
-}
-
-static int
-check_dst_limits (dfa, limits, mctx, dst_node, dst_idx, src_node, src_idx)
-     re_dfa_t *dfa;
-     re_node_set *limits;
-     re_match_context_t *mctx;
-     int dst_node, dst_idx, src_node, src_idx;
-{
-  int lim_idx, src_pos, dst_pos;
-
-  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
-    {
-      int subexp_idx;
-      struct re_backref_cache_entry *ent;
-      ent = mctx->bkref_ents + limits->elems[lim_idx];
-      subexp_idx = dfa->nodes[ent->node].opr.idx - 1;
-
-      dst_pos = check_dst_limits_calc_pos (dfa, mctx, limits->elems[lim_idx],
-					   dfa->eclosures + dst_node,
-					   subexp_idx, dst_node, dst_idx);
-      src_pos = check_dst_limits_calc_pos (dfa, mctx, limits->elems[lim_idx],
-					   dfa->eclosures + src_node,
-					   subexp_idx, src_node, src_idx);
-
-      /* In case of:
-	 <src> <dst> ( <subexp> )
-	 ( <subexp> ) <src> <dst>
-	 ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */
-      if (src_pos == dst_pos)
-	continue; /* This is unrelated limitation.  */
-      else
-	return 1;
-    }
-  return 0;
-}
-
-static int
-check_dst_limits_calc_pos (dfa, mctx, limit, eclosures, subexp_idx, node,
-			   str_idx)
-     re_dfa_t *dfa;
-     re_match_context_t *mctx;
-     re_node_set *eclosures;
-     int limit, subexp_idx, node, str_idx;
-{
-  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
-  int pos = (str_idx < lim->subexp_from ? -1
-	     : (lim->subexp_to < str_idx ? 1 : 0));
-  if (pos == 0
-      && (str_idx == lim->subexp_from || str_idx == lim->subexp_to))
-    {
-      int node_idx;
-      for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
-	{
-	  int node = eclosures->elems[node_idx];
-	  re_token_type_t type= dfa->nodes[node].type;
-	  if (type == OP_BACK_REF)
-	    {
-	      int bi = search_cur_bkref_entry (mctx, str_idx);
-	      for (; bi < mctx->nbkref_ents; ++bi)
-		{
-		  struct re_backref_cache_entry *ent = mctx->bkref_ents + bi;
-		  if (ent->str_idx > str_idx)
-		    break;
-		  if (ent->node == node && ent->subexp_from == ent->subexp_to)
-		    {
-		      int cpos, dst;
-		      dst = dfa->edests[node].elems[0];
-		      cpos = check_dst_limits_calc_pos (dfa, mctx, limit,
-							dfa->eclosures + dst,
-							subexp_idx, dst,
-							str_idx);
-		      if ((str_idx == lim->subexp_from && cpos == -1)
-			  || (str_idx == lim->subexp_to && cpos == 0))
-			return cpos;
-		    }
-		}
-	    }
-	  if (type == OP_OPEN_SUBEXP && subexp_idx == dfa->nodes[node].opr.idx
-	      && str_idx == lim->subexp_from)
-	    {
-	      pos = -1;
-	      break;
-	    }
-	  if (type == OP_CLOSE_SUBEXP && subexp_idx == dfa->nodes[node].opr.idx
-	      && str_idx == lim->subexp_to)
-	    break;
-	}
-      if (node_idx == eclosures->nelem && str_idx == lim->subexp_to)
-	pos = 1;
-    }
-  return pos;
-}
-
-/* Check the limitations of sub expressions LIMITS, and remove the nodes
-   which are against limitations from DEST_NODES. */
-
-static reg_errcode_t
-check_subexp_limits (dfa, dest_nodes, candidates, limits, bkref_ents, str_idx)
-     re_dfa_t *dfa;
-     re_node_set *dest_nodes;
-     const re_node_set *candidates;
-     re_node_set *limits;
-     struct re_backref_cache_entry *bkref_ents;
-     int str_idx;
-{
-  reg_errcode_t err;
-  int node_idx, lim_idx;
-
-  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
-    {
-      int subexp_idx;
-      struct re_backref_cache_entry *ent;
-      ent = bkref_ents + limits->elems[lim_idx];
-
-      if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
-	continue; /* This is unrelated limitation.  */
-
-      subexp_idx = dfa->nodes[ent->node].opr.idx - 1;
-      if (ent->subexp_to == str_idx)
-	{
-	  int ops_node = -1;
-	  int cls_node = -1;
-	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
-	    {
-	      int node = dest_nodes->elems[node_idx];
-	      re_token_type_t type= dfa->nodes[node].type;
-	      if (type == OP_OPEN_SUBEXP
-		  && subexp_idx == dfa->nodes[node].opr.idx)
-		ops_node = node;
-	      else if (type == OP_CLOSE_SUBEXP
-		       && subexp_idx == dfa->nodes[node].opr.idx)
-		cls_node = node;
-	    }
-
-	  /* Check the limitation of the open subexpression.  */
-	  /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
-	  if (ops_node >= 0)
-	    {
-	      err = sub_epsilon_src_nodes(dfa, ops_node, dest_nodes,
-					  candidates);
-	      if (BE (err != REG_NOERROR, 0))
-		return err;
-	    }
-	  /* Check the limitation of the close subexpression.  */
-	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
-	    {
-	      int node = dest_nodes->elems[node_idx];
-	      if (!re_node_set_contains (dfa->inveclosures + node, cls_node)
-		  && !re_node_set_contains (dfa->eclosures + node, cls_node))
-		{
-		  /* It is against this limitation.
-		     Remove it form the current sifted state.  */
-		  err = sub_epsilon_src_nodes(dfa, node, dest_nodes,
-					      candidates);
-		  if (BE (err != REG_NOERROR, 0))
-		    return err;
-		  --node_idx;
-		}
-	    }
-	}
-      else /* (ent->subexp_to != str_idx)  */
-	{
-	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
-	    {
-	      int node = dest_nodes->elems[node_idx];
-	      re_token_type_t type= dfa->nodes[node].type;
-	      if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
-		{
-		  if (subexp_idx != dfa->nodes[node].opr.idx)
-		    continue;
-		  if ((type == OP_CLOSE_SUBEXP && ent->subexp_to != str_idx)
-		      || (type == OP_OPEN_SUBEXP))
-		    {
-		      /* It is against this limitation.
-			 Remove it form the current sifted state.  */
-		      err = sub_epsilon_src_nodes(dfa, node, dest_nodes,
-						  candidates);
-		      if (BE (err != REG_NOERROR, 0))
-			return err;
-		    }
-		}
-	    }
-	}
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     re_sift_context_t *sctx;
-     int str_idx;
-     re_node_set *dest_nodes;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
-  int node_idx, node;
-  re_sift_context_t local_sctx;
-  const re_node_set *candidates;
-  candidates = ((mctx->state_log[str_idx] == NULL) ? &empty_set
-		: &mctx->state_log[str_idx]->nodes);
-  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
-
-  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
-    {
-      int cur_bkref_idx = re_string_cur_idx (mctx->input);
-      re_token_type_t type;
-      node = candidates->elems[node_idx];
-      type = dfa->nodes[node].type;
-      if (node == sctx->cur_bkref && str_idx == cur_bkref_idx)
-	continue;
-      /* Avoid infinite loop for the REs like "()\1+".  */
-      if (node == sctx->last_node && str_idx == sctx->last_str_idx)
-	continue;
-      if (type == OP_BACK_REF)
-	{
-	  int enabled_idx = search_cur_bkref_entry (mctx, str_idx);
-	  for (; enabled_idx < mctx->nbkref_ents; ++enabled_idx)
-	    {
-	      int disabled_idx, subexp_len, to_idx, dst_node;
-	      struct re_backref_cache_entry *entry;
-	      entry = mctx->bkref_ents + enabled_idx;
-	      if (entry->str_idx > str_idx)
-		break;
-	      if (entry->node != node)
-		  continue;
-	      subexp_len = entry->subexp_to - entry->subexp_from;
-	      to_idx = str_idx + subexp_len;
-	      dst_node = (subexp_len ? dfa->nexts[node]
-			  : dfa->edests[node].elems[0]);
-
-	      if (to_idx > sctx->last_str_idx
-		  || sctx->sifted_states[to_idx] == NULL
-		  || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx],
-					   dst_node)
-		  || check_dst_limits (dfa, &sctx->limits, mctx, node,
-				       str_idx, dst_node, to_idx))
-		continue;
-		{
-		  re_dfastate_t *cur_state;
-		  entry->flag = 0;
-		  for (disabled_idx = enabled_idx + 1;
-		       disabled_idx < mctx->nbkref_ents; ++disabled_idx)
-		    {
-		      struct re_backref_cache_entry *entry2;
-		      entry2 = mctx->bkref_ents + disabled_idx;
-		      if (entry2->str_idx > str_idx)
-			break;
-		      entry2->flag = (entry2->node == node) ? 1 : entry2->flag;
-		    }
-
-		  if (local_sctx.sifted_states == NULL)
-		    {
-		      local_sctx = *sctx;
-		      err = re_node_set_init_copy (&local_sctx.limits,
-						   &sctx->limits);
-		      if (BE (err != REG_NOERROR, 0))
-			goto free_return;
-		    }
-		  local_sctx.last_node = node;
-		  local_sctx.last_str_idx = str_idx;
-		  err = re_node_set_insert (&local_sctx.limits, enabled_idx);
-		  if (BE (err < 0, 0))
-		    {
-		      err = REG_ESPACE;
-		      goto free_return;
-		    }
-		  cur_state = local_sctx.sifted_states[str_idx];
-		  err = sift_states_backward (preg, mctx, &local_sctx);
-		  if (BE (err != REG_NOERROR, 0))
-		    goto free_return;
-		  if (sctx->limited_states != NULL)
-		    {
-		      err = merge_state_array (dfa, sctx->limited_states,
-					       local_sctx.sifted_states,
-					       str_idx + 1);
-		      if (BE (err != REG_NOERROR, 0))
-			goto free_return;
-		    }
-		  local_sctx.sifted_states[str_idx] = cur_state;
-		  re_node_set_remove (&local_sctx.limits, enabled_idx);
-		  /* We must not use the variable entry here, since
-		     mctx->bkref_ents might be realloced.  */
-		  mctx->bkref_ents[enabled_idx].flag = 1;
-		}
-	    }
-	  enabled_idx = search_cur_bkref_entry (mctx, str_idx);
-	  for (; enabled_idx < mctx->nbkref_ents; ++enabled_idx)
-	    {
-	      struct re_backref_cache_entry *entry;
-	      entry = mctx->bkref_ents + enabled_idx;
-	      if (entry->str_idx > str_idx)
-		break;
-	      if (entry->node == node)
-		entry->flag = 0;
-	    }
-	}
-    }
-  err = REG_NOERROR;
- free_return:
-  if (local_sctx.sifted_states != NULL)
-    {
-      re_node_set_free (&local_sctx.limits);
-    }
-
-  return err;
-}
-
-
-#ifdef RE_ENABLE_I18N
-static int
-sift_states_iter_mb (preg, mctx, sctx, node_idx, str_idx, max_str_idx)
-    const regex_t *preg;
-    const re_match_context_t *mctx;
-    re_sift_context_t *sctx;
-    int node_idx, str_idx, max_str_idx;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int naccepted;
-  /* Check the node can accept `multi byte'.  */
-  naccepted = check_node_accept_bytes (preg, node_idx, mctx->input, str_idx);
-  if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
-      !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
-			    dfa->nexts[node_idx]))
-    /* The node can't accept the `multi byte', or the
-       destination was already throwed away, then the node
-       could't accept the current input `multi byte'.   */
-    naccepted = 0;
-  /* Otherwise, it is sure that the node could accept
-     `naccepted' bytes input.  */
-  return naccepted;
-}
-#endif /* RE_ENABLE_I18N */
-
-
-/* Functions for state transition.  */
-
-/* Return the next state to which the current state STATE will transit by
-   accepting the current input byte, and update STATE_LOG if necessary.
-   If STATE can accept a multibyte char/collating element/back reference
-   update the destination of STATE_LOG.  */
-
-static re_dfastate_t *
-transit_state (err, preg, mctx, state, fl_search)
-     reg_errcode_t *err;
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     re_dfastate_t *state;
-     int fl_search;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  re_dfastate_t **trtable, *next_state;
-  unsigned char ch;
-  int cur_idx;
-
-  if (re_string_cur_idx (mctx->input) + 1 >= mctx->input->bufs_len
-      || (re_string_cur_idx (mctx->input) + 1 >= mctx->input->valid_len
-	  && mctx->input->valid_len < mctx->input->len))
-    {
-      *err = extend_buffers (mctx);
-      if (BE (*err != REG_NOERROR, 0))
-	return NULL;
-    }
-
-  *err = REG_NOERROR;
-  if (state == NULL)
-    {
-      next_state = state;
-      re_string_skip_bytes (mctx->input, 1);
-    }
-  else
-    {
-#ifdef RE_ENABLE_I18N
-      /* If the current state can accept multibyte.  */
-      if (state->accept_mb)
-	{
-	  *err = transit_state_mb (preg, state, mctx);
-	  if (BE (*err != REG_NOERROR, 0))
-	    return NULL;
-	}
-#endif /* RE_ENABLE_I18N */
-
-      /* Then decide the next state with the single byte.  */
-      if (1)
-	{
-	  /* Use transition table  */
-	  ch = re_string_fetch_byte (mctx->input);
-	  trtable = fl_search ? state->trtable_search : state->trtable;
-	  if (trtable == NULL)
-	    {
-	      trtable = build_trtable (preg, state, fl_search);
-	      if (fl_search)
-		state->trtable_search = trtable;
-	      else
-		state->trtable = trtable;
-	    }
-	  next_state = trtable[ch];
-	}
-      else
-	{
-	  /* don't use transition table  */
-	  next_state = transit_state_sb (err, preg, state, fl_search, mctx);
-	  if (BE (next_state == NULL && err != REG_NOERROR, 0))
-	    return NULL;
-	}
-    }
-
-  cur_idx = re_string_cur_idx (mctx->input);
-  /* Update the state_log if we need.  */
-  if (mctx->state_log != NULL)
-    {
-      if (cur_idx > mctx->state_log_top)
-	{
-	  mctx->state_log[cur_idx] = next_state;
-	  mctx->state_log_top = cur_idx;
-	}
-      else if (mctx->state_log[cur_idx] == 0)
-	{
-	  mctx->state_log[cur_idx] = next_state;
-	}
-      else
-	{
-	  re_dfastate_t *pstate;
-	  unsigned int context;
-	  re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
-	  /* If (state_log[cur_idx] != 0), it implies that cur_idx is
-	     the destination of a multibyte char/collating element/
-	     back reference.  Then the next state is the union set of
-	     these destinations and the results of the transition table.  */
-	  pstate = mctx->state_log[cur_idx];
-	  log_nodes = pstate->entrance_nodes;
-	  if (next_state != NULL)
-	    {
-	      table_nodes = next_state->entrance_nodes;
-	      *err = re_node_set_init_union (&next_nodes, table_nodes,
-					     log_nodes);
-	      if (BE (*err != REG_NOERROR, 0))
-		return NULL;
-	    }
-	  else
-	    next_nodes = *log_nodes;
-	  /* Note: We already add the nodes of the initial state,
-		   then we don't need to add them here.  */
-
-	  context = re_string_context_at (mctx->input,
-					  re_string_cur_idx (mctx->input) - 1,
-					  mctx->eflags, preg->newline_anchor);
-	  next_state = mctx->state_log[cur_idx]
-	    = re_acquire_state_context (err, dfa, &next_nodes, context);
-	  /* We don't need to check errors here, since the return value of
-	     this function is next_state and ERR is already set.  */
-
-	  if (table_nodes != NULL)
-	    re_node_set_free (&next_nodes);
-	}
-    }
-
-  /* Check OP_OPEN_SUBEXP in the current state in case that we use them
-     later.  We must check them here, since the back references in the
-     next state might use them.  */
-  if (dfa->nbackref && next_state/* && fl_process_bkref */)
-    {
-      *err = check_subexp_matching_top (dfa, mctx, &next_state->nodes,
-					cur_idx);
-      if (BE (*err != REG_NOERROR, 0))
-	return NULL;
-    }
-
-  /* If the next state has back references.  */
-  if (next_state != NULL && next_state->has_backref)
-    {
-      *err = transit_state_bkref (preg, &next_state->nodes, mctx);
-      if (BE (*err != REG_NOERROR, 0))
-	return NULL;
-      next_state = mctx->state_log[cur_idx];
-    }
-  return next_state;
-}
-
-/* Helper functions for transit_state.  */
-
-/* From the node set CUR_NODES, pick up the nodes whose types are
-   OP_OPEN_SUBEXP and which have corresponding back references in the regular
-   expression. And register them to use them later for evaluating the
-   correspoding back references.  */
-
-static reg_errcode_t
-check_subexp_matching_top (dfa, mctx, cur_nodes, str_idx)
-     re_dfa_t *dfa;
-     re_match_context_t *mctx;
-     re_node_set *cur_nodes;
-     int str_idx;
-{
-  int node_idx;
-  reg_errcode_t err;
-
-  /* TODO: This isn't efficient.
-	   Because there might be more than one nodes whose types are
-	   OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
-	   nodes.
-	   E.g. RE: (a){2}  */
-  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
-    {
-      int node = cur_nodes->elems[node_idx];
-      if (dfa->nodes[node].type == OP_OPEN_SUBEXP
-	  && dfa->used_bkref_map & (1 << dfa->nodes[node].opr.idx))
-	{
-	  err = match_ctx_add_subtop (mctx, node, str_idx);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	}
-    }
-  return REG_NOERROR;
-}
-
-/* Return the next state to which the current state STATE will transit by
-   accepting the current input byte.  */
-
-static re_dfastate_t *
-transit_state_sb (err, preg, state, fl_search, mctx)
-     reg_errcode_t *err;
-     const regex_t *preg;
-     re_dfastate_t *state;
-     int fl_search;
-     re_match_context_t *mctx;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  re_node_set next_nodes;
-  re_dfastate_t *next_state;
-  int node_cnt, cur_str_idx = re_string_cur_idx (mctx->input);
-  unsigned int context;
-
-  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
-  if (BE (*err != REG_NOERROR, 0))
-    return NULL;
-  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
-    {
-      int cur_node = state->nodes.elems[node_cnt];
-      if (check_node_accept (preg, dfa->nodes + cur_node, mctx, cur_str_idx))
-	{
-	  *err = re_node_set_merge (&next_nodes,
-				    dfa->eclosures + dfa->nexts[cur_node]);
-	  if (BE (*err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return NULL;
-	    }
-	}
-    }
-  if (fl_search)
-    {
-#ifdef RE_ENABLE_I18N
-      int not_initial = 0;
-      if (MB_CUR_MAX > 1)
-	for (node_cnt = 0; node_cnt < next_nodes.nelem; ++node_cnt)
-	  if (dfa->nodes[next_nodes.elems[node_cnt]].type == CHARACTER)
-	    {
-	      not_initial = dfa->nodes[next_nodes.elems[node_cnt]].mb_partial;
-	      break;
-	    }
-      if (!not_initial)
-#endif
-	{
-	  *err = re_node_set_merge (&next_nodes,
-				    dfa->init_state->entrance_nodes);
-	  if (BE (*err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return NULL;
-	    }
-	}
-    }
-  context = re_string_context_at (mctx->input, cur_str_idx, mctx->eflags,
-				  preg->newline_anchor);
-  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
-  /* We don't need to check errors here, since the return value of
-     this function is next_state and ERR is already set.  */
-
-  re_node_set_free (&next_nodes);
-  re_string_skip_bytes (mctx->input, 1);
-  return next_state;
-}
-
-#ifdef RE_ENABLE_I18N
-static reg_errcode_t
-transit_state_mb (preg, pstate, mctx)
-    const regex_t *preg;
-    re_dfastate_t *pstate;
-    re_match_context_t *mctx;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int i;
-
-  for (i = 0; i < pstate->nodes.nelem; ++i)
-    {
-      re_node_set dest_nodes, *new_nodes;
-      int cur_node_idx = pstate->nodes.elems[i];
-      int naccepted = 0, dest_idx;
-      unsigned int context;
-      re_dfastate_t *dest_state;
-
-      if (dfa->nodes[cur_node_idx].constraint)
-	{
-	  context = re_string_context_at (mctx->input,
-					  re_string_cur_idx (mctx->input),
-					  mctx->eflags, preg->newline_anchor);
-	  if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
-					   context))
-	    continue;
-	}
-
-      /* How many bytes the node can accepts?  */
-      if (ACCEPT_MB_NODE (dfa->nodes[cur_node_idx].type))
-	naccepted = check_node_accept_bytes (preg, cur_node_idx, mctx->input,
-					     re_string_cur_idx (mctx->input));
-      if (naccepted == 0)
-	continue;
-
-      /* The node can accepts `naccepted' bytes.  */
-      dest_idx = re_string_cur_idx (mctx->input) + naccepted;
-      mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
-			       : mctx->max_mb_elem_len);
-      err = clean_state_log_if_need (mctx, dest_idx);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-#ifdef DEBUG
-      assert (dfa->nexts[cur_node_idx] != -1);
-#endif
-      /* `cur_node_idx' may point the entity of the OP_CONTEXT_NODE,
-	 then we use pstate->nodes.elems[i] instead.  */
-      new_nodes = dfa->eclosures + dfa->nexts[pstate->nodes.elems[i]];
-
-      dest_state = mctx->state_log[dest_idx];
-      if (dest_state == NULL)
-	dest_nodes = *new_nodes;
-      else
-	{
-	  err = re_node_set_init_union (&dest_nodes,
-					dest_state->entrance_nodes, new_nodes);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	}
-      context = re_string_context_at (mctx->input, dest_idx - 1, mctx->eflags,
-				      preg->newline_anchor);
-      mctx->state_log[dest_idx]
-	= re_acquire_state_context (&err, dfa, &dest_nodes, context);
-      if (dest_state != NULL)
-	re_node_set_free (&dest_nodes);
-      if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
-	return err;
-    }
-  return REG_NOERROR;
-}
-#endif /* RE_ENABLE_I18N */
-
-static reg_errcode_t
-transit_state_bkref (preg, nodes, mctx)
-    const regex_t *preg;
-    re_node_set *nodes;
-    re_match_context_t *mctx;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int i;
-  int cur_str_idx = re_string_cur_idx (mctx->input);
-
-  for (i = 0; i < nodes->nelem; ++i)
-    {
-      int dest_str_idx, prev_nelem, bkc_idx;
-      int node_idx = nodes->elems[i];
-      unsigned int context;
-      re_token_t *node = dfa->nodes + node_idx;
-      re_node_set *new_dest_nodes;
-
-      /* Check whether `node' is a backreference or not.  */
-      if (node->type != OP_BACK_REF)
-	continue;
-
-      if (node->constraint)
-	{
-	  context = re_string_context_at (mctx->input, cur_str_idx,
-					  mctx->eflags, preg->newline_anchor);
-	  if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
-	    continue;
-	}
-
-      /* `node' is a backreference.
-	 Check the substring which the substring matched.  */
-      bkc_idx = mctx->nbkref_ents;
-      err = get_subexp (preg, mctx, node_idx, cur_str_idx);
-      if (BE (err != REG_NOERROR, 0))
-	goto free_return;
-
-      /* And add the epsilon closures (which is `new_dest_nodes') of
-	 the backreference to appropriate state_log.  */
-#ifdef DEBUG
-      assert (dfa->nexts[node_idx] != -1);
-#endif
-      for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
-	{
-	  int subexp_len;
-	  re_dfastate_t *dest_state;
-	  struct re_backref_cache_entry *bkref_ent;
-	  bkref_ent = mctx->bkref_ents + bkc_idx;
-	  if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
-	    continue;
-	  subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
-	  new_dest_nodes = (subexp_len == 0
-			    ? dfa->eclosures + dfa->edests[node_idx].elems[0]
-			    : dfa->eclosures + dfa->nexts[node_idx]);
-	  dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
-			  - bkref_ent->subexp_from);
-	  context = re_string_context_at (mctx->input, dest_str_idx - 1,
-					  mctx->eflags, preg->newline_anchor);
-	  dest_state = mctx->state_log[dest_str_idx];
-	  prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
-			: mctx->state_log[cur_str_idx]->nodes.nelem);
-	  /* Add `new_dest_node' to state_log.  */
-	  if (dest_state == NULL)
-	    {
-	      mctx->state_log[dest_str_idx]
-		= re_acquire_state_context (&err, dfa, new_dest_nodes,
-					    context);
-	      if (BE (mctx->state_log[dest_str_idx] == NULL
-		      && err != REG_NOERROR, 0))
-		goto free_return;
-	    }
-	  else
-	    {
-	      re_node_set dest_nodes;
-	      err = re_node_set_init_union (&dest_nodes,
-					    dest_state->entrance_nodes,
-					    new_dest_nodes);
-	      if (BE (err != REG_NOERROR, 0))
-		{
-		  re_node_set_free (&dest_nodes);
-		  goto free_return;
-		}
-	      mctx->state_log[dest_str_idx]
-		= re_acquire_state_context (&err, dfa, &dest_nodes, context);
-	      re_node_set_free (&dest_nodes);
-	      if (BE (mctx->state_log[dest_str_idx] == NULL
-		      && err != REG_NOERROR, 0))
-		goto free_return;
-	    }
-	  /* We need to check recursively if the backreference can epsilon
-	     transit.  */
-	  if (subexp_len == 0
-	      && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
-	    {
-	      err = check_subexp_matching_top (dfa, mctx, new_dest_nodes,
-					       cur_str_idx);
-	      if (BE (err != REG_NOERROR, 0))
-		goto free_return;
-	      err = transit_state_bkref (preg, new_dest_nodes, mctx);
-	      if (BE (err != REG_NOERROR, 0))
-		goto free_return;
-	    }
-	}
-    }
-  err = REG_NOERROR;
- free_return:
-  return err;
-}
-
-/* Enumerate all the candidates which the backreference BKREF_NODE can match
-   at BKREF_STR_IDX, and register them by match_ctx_add_entry().
-   Note that we might collect inappropriate candidates here.
-   However, the cost of checking them strictly here is too high, then we
-   delay these checking for prune_impossible_nodes().  */
-
-static reg_errcode_t
-get_subexp (preg, mctx, bkref_node, bkref_str_idx)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     int bkref_node, bkref_str_idx;
-{
-  int subexp_num, sub_top_idx;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  char *buf = (char *) re_string_get_buffer (mctx->input);
-  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
-  int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
-  for (; cache_idx < mctx->nbkref_ents; ++cache_idx)
-    {
-      struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx;
-      if (entry->str_idx > bkref_str_idx)
-	break;
-      if (entry->node == bkref_node)
-	return REG_NOERROR; /* We already checked it.  */
-    }
-  subexp_num = dfa->nodes[bkref_node].opr.idx - 1;
-
-  /* For each sub expression  */
-  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
-    {
-      reg_errcode_t err;
-      re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
-      re_sub_match_last_t *sub_last;
-      int sub_last_idx, sl_str;
-      char *bkref_str;
-
-      if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
-	continue; /* It isn't related.  */
-
-      sl_str = sub_top->str_idx;
-      bkref_str = buf + bkref_str_idx;
-      /* At first, check the last node of sub expressions we already
-	 evaluated.  */
-      for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
-	{
-	  int sl_str_diff;
-	  sub_last = sub_top->lasts[sub_last_idx];
-	  sl_str_diff = sub_last->str_idx - sl_str;
-	  /* The matched string by the sub expression match with the substring
-	     at the back reference?  */
-	  if (sl_str_diff > 0
-	      && memcmp (bkref_str, buf + sl_str, sl_str_diff) != 0)
-	    break; /* We don't need to search this sub expression any more.  */
-	  bkref_str += sl_str_diff;
-	  sl_str += sl_str_diff;
-	  err = get_subexp_sub (preg, mctx, sub_top, sub_last, bkref_node,
-				bkref_str_idx);
-	  if (err == REG_NOMATCH)
-	    continue;
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	}
-      if (sub_last_idx < sub_top->nlasts)
-	continue;
-      if (sub_last_idx > 0)
-	++sl_str;
-      /* Then, search for the other last nodes of the sub expression.  */
-      for (; sl_str <= bkref_str_idx; ++sl_str)
-	{
-	  int cls_node, sl_str_off;
-	  re_node_set *nodes;
-	  sl_str_off = sl_str - sub_top->str_idx;
-	  /* The matched string by the sub expression match with the substring
-	     at the back reference?  */
-	  if (sl_str_off > 0
-	      && memcmp (bkref_str++, buf + sl_str - 1, 1) != 0)
-	    break; /* We don't need to search this sub expression any more.  */
-	  if (mctx->state_log[sl_str] == NULL)
-	    continue;
-	  /* Does this state have a ')' of the sub expression?  */
-	  nodes = &mctx->state_log[sl_str]->nodes;
-	  cls_node = find_subexp_node (dfa, nodes, subexp_num, 0);
-	  if (cls_node == -1)
-	    continue; /* No.  */
-	  if (sub_top->path == NULL)
-	    {
-	      sub_top->path = calloc (sizeof (state_array_t),
-				      sl_str - sub_top->str_idx + 1);
-	      if (sub_top->path == NULL)
-		return REG_ESPACE;
-	    }
-	  /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
-	     in the current context?  */
-	  err = check_arrival (preg, mctx, sub_top->path, sub_top->node,
-			       sub_top->str_idx, cls_node, sl_str, 0);
-	  if (err == REG_NOMATCH)
-	      continue;
-	  if (BE (err != REG_NOERROR, 0))
-	      return err;
-	  sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
-	  if (BE (sub_last == NULL, 0))
-	    return REG_ESPACE;
-	  err = get_subexp_sub (preg, mctx, sub_top, sub_last, bkref_node,
-				bkref_str_idx);
-	  if (err == REG_NOMATCH)
-	    continue;
-	}
-    }
-  return REG_NOERROR;
-}
-
-/* Helper functions for get_subexp().  */
-
-/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
-   If it can arrive, register the sub expression expressed with SUB_TOP
-   and SUB_LAST.  */
-
-static reg_errcode_t
-get_subexp_sub (preg, mctx, sub_top, sub_last, bkref_node, bkref_str)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     re_sub_match_top_t *sub_top;
-     re_sub_match_last_t *sub_last;
-     int bkref_node, bkref_str;
-{
-  reg_errcode_t err;
-  int to_idx;
-  /* Can the subexpression arrive the back reference?  */
-  err = check_arrival (preg, mctx, &sub_last->path, sub_last->node,
-		       sub_last->str_idx, bkref_node, bkref_str, 1);
-  if (err != REG_NOERROR)
-    return err;
-  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
-			     sub_last->str_idx);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
-  clean_state_log_if_need (mctx, to_idx);
-  return REG_NOERROR;
-}
-
-/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
-   Search '(' if FL_OPEN, or search ')' otherwise.
-   TODO: This function isn't efficient...
-	 Because there might be more than one nodes whose types are
-	 OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
-	 nodes.
-	 E.g. RE: (a){2}  */
-
-static int
-find_subexp_node (dfa, nodes, subexp_idx, fl_open)
-     re_dfa_t *dfa;
-     re_node_set *nodes;
-     int subexp_idx, fl_open;
-{
-  int cls_idx;
-  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
-    {
-      int cls_node = nodes->elems[cls_idx];
-      re_token_t *node = dfa->nodes + cls_node;
-      if (((fl_open && node->type == OP_OPEN_SUBEXP)
-	  || (!fl_open && node->type == OP_CLOSE_SUBEXP))
-	  && node->opr.idx == subexp_idx)
-	return cls_node;
-    }
-  return -1;
-}
-
-/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
-   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
-   heavily reused.
-   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
-
-static reg_errcode_t
-check_arrival (preg, mctx, path, top_node, top_str, last_node, last_str,
-	       fl_open)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     state_array_t *path;
-     int top_node, top_str, last_node, last_str, fl_open;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  reg_errcode_t err;
-  int subexp_num, backup_cur_idx, str_idx, null_cnt;
-  re_dfastate_t *cur_state = NULL;
-  re_node_set *cur_nodes, next_nodes;
-  re_dfastate_t **backup_state_log;
-  unsigned int context;
-
-  subexp_num = dfa->nodes[top_node].opr.idx;
-  /* Extend the buffer if we need.  */
-  if (path->alloc < last_str + mctx->max_mb_elem_len + 1)
-    {
-      re_dfastate_t **new_array;
-      int old_alloc = path->alloc;
-      path->alloc += last_str + mctx->max_mb_elem_len + 1;
-      new_array = re_realloc (path->array, re_dfastate_t *, path->alloc);
-      if (new_array == NULL)
-	return REG_ESPACE;
-      path->array = new_array;
-      memset (new_array + old_alloc, '\0',
-	      sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
-    }
-
-  str_idx = path->next_idx == 0 ? top_str : path->next_idx;
-
-  /* Temporary modify MCTX.  */
-  backup_state_log = mctx->state_log;
-  backup_cur_idx = mctx->input->cur_idx;
-  mctx->state_log = path->array;
-  mctx->input->cur_idx = str_idx;
-
-  /* Setup initial node set.  */
-  context = re_string_context_at (mctx->input, str_idx - 1, mctx->eflags,
-				  preg->newline_anchor);
-  if (str_idx == top_str)
-    {
-      err = re_node_set_init_1 (&next_nodes, top_node);
-      if (BE (err != REG_NOERROR, 0))
-	return err;
-      err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, fl_open);
-      if (BE (err != REG_NOERROR, 0))
-	{
-	  re_node_set_free (&next_nodes);
-	  return err;
-	}
-    }
-  else
-    {
-      cur_state = mctx->state_log[str_idx];
-      if (cur_state && cur_state->has_backref)
-	{
-	  err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
-	  if (BE ( err != REG_NOERROR, 0))
-	    return err;
-	}
-      else
-	re_node_set_init_empty (&next_nodes);
-    }
-  if (str_idx == top_str || (cur_state && cur_state->has_backref))
-    {
-      if (next_nodes.nelem)
-	{
-	  err = expand_bkref_cache (preg, mctx, &next_nodes, str_idx, last_str,
-				    subexp_num, fl_open);
-	  if (BE ( err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return err;
-	    }
-	}
-      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
-      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
-	{
-	  re_node_set_free (&next_nodes);
-	  return err;
-	}
-      mctx->state_log[str_idx] = cur_state;
-    }
-
-  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
-    {
-      re_node_set_empty (&next_nodes);
-      if (mctx->state_log[str_idx + 1])
-	{
-	  err = re_node_set_merge (&next_nodes,
-				   &mctx->state_log[str_idx + 1]->nodes);
-	  if (BE (err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return err;
-	    }
-	}
-      if (cur_state)
-	{
-	  err = check_arrival_add_next_nodes(preg, dfa, mctx, str_idx,
-					     &cur_state->nodes, &next_nodes);
-	  if (BE (err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return err;
-	    }
-	}
-      ++str_idx;
-      if (next_nodes.nelem)
-	{
-	  err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num,
-					  fl_open);
-	  if (BE (err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return err;
-	    }
-	  err = expand_bkref_cache (preg, mctx, &next_nodes, str_idx, last_str,
-				    subexp_num, fl_open);
-	  if (BE ( err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&next_nodes);
-	      return err;
-	    }
-	}
-      context = re_string_context_at (mctx->input, str_idx - 1, mctx->eflags,
-				      preg->newline_anchor);
-      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
-      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
-	{
-	  re_node_set_free (&next_nodes);
-	  return err;
-	}
-      mctx->state_log[str_idx] = cur_state;
-      null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
-    }
-  re_node_set_free (&next_nodes);
-  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
-	       : &mctx->state_log[last_str]->nodes);
-  path->next_idx = str_idx;
-
-  /* Fix MCTX.  */
-  mctx->state_log = backup_state_log;
-  mctx->input->cur_idx = backup_cur_idx;
-
-  if (cur_nodes == NULL)
-    return REG_NOMATCH;
-  /* Then check the current node set has the node LAST_NODE.  */
-  return (re_node_set_contains (cur_nodes, last_node)
-	  || re_node_set_contains (cur_nodes, last_node) ? REG_NOERROR
-	  : REG_NOMATCH);
-}
-
-/* Helper functions for check_arrival.  */
-
-/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
-   to NEXT_NODES.
-   TODO: This function is similar to the functions transit_state*(),
-	 however this function has many additional works.
-	 Can't we unify them?  */
-
-static reg_errcode_t
-check_arrival_add_next_nodes (preg, dfa, mctx, str_idx, cur_nodes, next_nodes)
-     const regex_t *preg;
-     re_dfa_t *dfa;
-     re_match_context_t *mctx;
-     int str_idx;
-     re_node_set *cur_nodes, *next_nodes;
-{
-  int cur_idx;
-  reg_errcode_t err;
-  re_node_set union_set;
-  re_node_set_init_empty (&union_set);
-  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
-    {
-      int naccepted = 0;
-      int cur_node = cur_nodes->elems[cur_idx];
-      re_token_type_t type = dfa->nodes[cur_node].type;
-      if (IS_EPSILON_NODE(type))
-	continue;
-#ifdef RE_ENABLE_I18N
-      /* If the node may accept `multi byte'.  */
-      if (ACCEPT_MB_NODE (type))
-	{
-	  naccepted = check_node_accept_bytes (preg, cur_node, mctx->input,
-					       str_idx);
-	  if (naccepted > 1)
-	    {
-	      re_dfastate_t *dest_state;
-	      int next_node = dfa->nexts[cur_node];
-	      int next_idx = str_idx + naccepted;
-	      dest_state = mctx->state_log[next_idx];
-	      re_node_set_empty (&union_set);
-	      if (dest_state)
-		{
-		  err = re_node_set_merge (&union_set, &dest_state->nodes);
-		  if (BE (err != REG_NOERROR, 0))
-		    {
-		      re_node_set_free (&union_set);
-		      return err;
-		    }
-		  err = re_node_set_insert (&union_set, next_node);
-		  if (BE (err < 0, 0))
-		    {
-		      re_node_set_free (&union_set);
-		      return REG_ESPACE;
-		    }
-		}
-	      else
-		{
-		  err = re_node_set_insert (&union_set, next_node);
-		  if (BE (err < 0, 0))
-		    {
-		      re_node_set_free (&union_set);
-		      return REG_ESPACE;
-		    }
-		}
-	      mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
-							    &union_set);
-	      if (BE (mctx->state_log[next_idx] == NULL
-		      && err != REG_NOERROR, 0))
-		{
-		  re_node_set_free (&union_set);
-		  return err;
-		}
-	    }
-	}
-#endif /* RE_ENABLE_I18N */
-      if (naccepted
-	  || check_node_accept (preg, dfa->nodes + cur_node, mctx,
-				str_idx))
-	{
-	  err = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
-	  if (BE (err < 0, 0))
-	    {
-	      re_node_set_free (&union_set);
-	      return REG_ESPACE;
-	    }
-	}
-    }
-  re_node_set_free (&union_set);
-  return REG_NOERROR;
-}
-
-/* For all the nodes in CUR_NODES, add the epsilon closures of them to
-   CUR_NODES, however exclude the nodes which are:
-    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
-    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
-*/
-
-static reg_errcode_t
-check_arrival_expand_ecl (dfa, cur_nodes, ex_subexp, fl_open)
-     re_dfa_t *dfa;
-     re_node_set *cur_nodes;
-     int ex_subexp, fl_open;
-{
-  reg_errcode_t err;
-  int idx, outside_node;
-  re_node_set new_nodes;
-#ifdef DEBUG
-  assert (cur_nodes->nelem);
-#endif
-  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  /* Create a new node set NEW_NODES with the nodes which are epsilon
-     closures of the node in CUR_NODES.  */
-
-  for (idx = 0; idx < cur_nodes->nelem; ++idx)
-    {
-      int cur_node = cur_nodes->elems[idx];
-      re_node_set *eclosure = dfa->eclosures + cur_node;
-      outside_node = find_subexp_node (dfa, eclosure, ex_subexp, fl_open);
-      if (outside_node == -1)
-	{
-	  /* There are no problematic nodes, just merge them.  */
-	  err = re_node_set_merge (&new_nodes, eclosure);
-	  if (BE (err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&new_nodes);
-	      return err;
-	    }
-	}
-      else
-	{
-	  /* There are problematic nodes, re-calculate incrementally.  */
-	  err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
-					      ex_subexp, fl_open);
-	  if (BE (err != REG_NOERROR, 0))
-	    {
-	      re_node_set_free (&new_nodes);
-	      return err;
-	    }
-	}
-    }
-  re_node_set_free (cur_nodes);
-  *cur_nodes = new_nodes;
-  return REG_NOERROR;
-}
-
-/* Helper function for check_arrival_expand_ecl.
-   Check incrementally the epsilon closure of TARGET, and if it isn't
-   problematic append it to DST_NODES.  */
-
-static reg_errcode_t
-check_arrival_expand_ecl_sub (dfa, dst_nodes, target, ex_subexp, fl_open)
-     re_dfa_t *dfa;
-     int target, ex_subexp, fl_open;
-     re_node_set *dst_nodes;
-{
-  int cur_node, type;
-  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
-    {
-      int err;
-      type = dfa->nodes[cur_node].type;
-
-      if (((type == OP_OPEN_SUBEXP && fl_open)
-	   || (type == OP_CLOSE_SUBEXP && !fl_open))
-	  && dfa->nodes[cur_node].opr.idx == ex_subexp)
-	{
-	  if (!fl_open)
-	    {
-	      err = re_node_set_insert (dst_nodes, cur_node);
-	      if (BE (err == -1, 0))
-		return REG_ESPACE;
-	    }
-	  break;
-	}
-      err = re_node_set_insert (dst_nodes, cur_node);
-      if (BE (err == -1, 0))
-	return REG_ESPACE;
-      if (dfa->edests[cur_node].nelem == 0)
-	break;
-      if (dfa->edests[cur_node].nelem == 2)
-	{
-	  err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
-					      dfa->edests[cur_node].elems[1],
-					      ex_subexp, fl_open);
-	  if (BE (err != REG_NOERROR, 0))
-	    return err;
-	}
-      cur_node = dfa->edests[cur_node].elems[0];
-    }
-  return REG_NOERROR;
-}
-
-
-/* For all the back references in the current state, calculate the
-   destination of the back references by the appropriate entry
-   in MCTX->BKREF_ENTS.  */
-
-static reg_errcode_t
-expand_bkref_cache (preg, mctx, cur_nodes, cur_str, last_str, subexp_num,
-		    fl_open)
-     const regex_t *preg;
-     re_match_context_t *mctx;
-     int cur_str, last_str, subexp_num, fl_open;
-     re_node_set *cur_nodes;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int cache_idx, cache_idx_start;
-  /* The current state.  */
-
-  cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
-  for (cache_idx = cache_idx_start; cache_idx < mctx->nbkref_ents; ++cache_idx)
-    {
-      int to_idx, next_node;
-      struct re_backref_cache_entry *ent = mctx->bkref_ents + cache_idx;
-      if (ent->str_idx > cur_str)
-	break;
-      /* Is this entry ENT is appropriate?  */
-      if (!re_node_set_contains (cur_nodes, ent->node))
-	continue; /* No.  */
-
-      to_idx = cur_str + ent->subexp_to - ent->subexp_from;
-      /* Calculate the destination of the back reference, and append it
-	 to MCTX->STATE_LOG.  */
-      if (to_idx == cur_str)
-	{
-	  /* The backreference did epsilon transit, we must re-check all the
-	     node in the current state.  */
-	  re_node_set new_dests;
-	  reg_errcode_t err2, err3;
-	  next_node = dfa->edests[ent->node].elems[0];
-	  if (re_node_set_contains (cur_nodes, next_node))
-	    continue;
-	  err = re_node_set_init_1 (&new_dests, next_node);
-	  err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num,
-					   fl_open);
-	  err3 = re_node_set_merge (cur_nodes, &new_dests);
-	  re_node_set_free (&new_dests);
-	  if (BE (err != REG_NOERROR || err2 != REG_NOERROR
-		  || err3 != REG_NOERROR, 0))
-	    {
-	      err = (err != REG_NOERROR ? err
-		     : (err2 != REG_NOERROR ? err2 : err3));
-	      return err;
-	    }
-	  /* TODO: It is still inefficient...  */
-	  cache_idx = cache_idx_start - 1;
-	  continue;
-	}
-      else
-	{
-	  re_node_set union_set;
-	  next_node = dfa->nexts[ent->node];
-	  if (mctx->state_log[to_idx])
-	    {
-	      int ret;
-	      if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
-					next_node))
-		continue;
-	      err = re_node_set_init_copy (&union_set,
-					   &mctx->state_log[to_idx]->nodes);
-	      ret = re_node_set_insert (&union_set, next_node);
-	      if (BE (err != REG_NOERROR || ret < 0, 0))
-		{
-		  re_node_set_free (&union_set);
-		  err = err != REG_NOERROR ? err : REG_ESPACE;
-		  return err;
-		}
-	    }
-	  else
-	    {
-	      err = re_node_set_init_1 (&union_set, next_node);
-	      if (BE (err != REG_NOERROR, 0))
-		return err;
-	    }
-	  mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
-	  re_node_set_free (&union_set);
-	  if (BE (mctx->state_log[to_idx] == NULL
-		  && err != REG_NOERROR, 0))
-	    return err;
-	}
-    }
-  return REG_NOERROR;
-}
-
-/* Build transition table for the state.
-   Return the new table if succeeded, otherwise return NULL.  */
-
-static re_dfastate_t **
-build_trtable (preg, state, fl_search)
-    const regex_t *preg;
-    const re_dfastate_t *state;
-    int fl_search;
-{
-  reg_errcode_t err;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int i, j, k, ch;
-  int dests_node_malloced = 0, dest_states_malloced = 0;
-  int ndests; /* Number of the destination states from `state'.  */
-  re_dfastate_t **trtable;
-  re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
-  re_node_set follows, *dests_node;
-  bitset *dests_ch;
-  bitset acceptable;
-
-  /* We build DFA states which corresponds to the destination nodes
-     from `state'.  `dests_node[i]' represents the nodes which i-th
-     destination state contains, and `dests_ch[i]' represents the
-     characters which i-th destination state accepts.  */
-#ifdef _LIBC
-  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX))
-    dests_node = (re_node_set *)
-		 alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
-  else
-#endif
-    {
-      dests_node = (re_node_set *)
-		   malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
-      if (BE (dests_node == NULL, 0))
-	return NULL;
-      dests_node_malloced = 1;
-    }
-  dests_ch = (bitset *) (dests_node + SBC_MAX);
-
-  /* Initialize transiton table.  */
-  trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
-  if (BE (trtable == NULL, 0))
-    {
-      if (dests_node_malloced)
-	free (dests_node);
-      return NULL;
-    }
-
-  /* At first, group all nodes belonging to `state' into several
-     destinations.  */
-  ndests = group_nodes_into_DFAstates (preg, state, dests_node, dests_ch);
-  if (BE (ndests <= 0, 0))
-    {
-      if (dests_node_malloced)
-	free (dests_node);
-      /* Return NULL in case of an error, trtable otherwise.  */
-      if (ndests == 0)
-	return trtable;
-      free (trtable);
-      return NULL;
-    }
-
-  err = re_node_set_alloc (&follows, ndests + 1);
-  if (BE (err != REG_NOERROR, 0))
-    goto out_free;
-
-#ifdef _LIBC
-  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX
-			 + ndests * 3 * sizeof (re_dfastate_t *)))
-    dest_states = (re_dfastate_t **)
-		  alloca (ndests * 3 * sizeof (re_dfastate_t *));
-  else
-#endif
-    {
-      dest_states = (re_dfastate_t **)
-		    malloc (ndests * 3 * sizeof (re_dfastate_t *));
-      if (BE (dest_states == NULL, 0))
-	{
-out_free:
-	  if (dest_states_malloced)
-	    free (dest_states);
-	  re_node_set_free (&follows);
-	  for (i = 0; i < ndests; ++i)
-	    re_node_set_free (dests_node + i);
-	  free (trtable);
-	  if (dests_node_malloced)
-	    free (dests_node);
-	  return NULL;
-	}
-      dest_states_malloced = 1;
-    }
-  dest_states_word = dest_states + ndests;
-  dest_states_nl = dest_states_word + ndests;
-  bitset_empty (acceptable);
-
-  /* Then build the states for all destinations.  */
-  for (i = 0; i < ndests; ++i)
-    {
-      int next_node;
-      re_node_set_empty (&follows);
-      /* Merge the follows of this destination states.  */
-      for (j = 0; j < dests_node[i].nelem; ++j)
-	{
-	  next_node = dfa->nexts[dests_node[i].elems[j]];
-	  if (next_node != -1)
-	    {
-	      err = re_node_set_merge (&follows, dfa->eclosures + next_node);
-	      if (BE (err != REG_NOERROR, 0))
-		goto out_free;
-	    }
-	}
-      /* If search flag is set, merge the initial state.  */
-      if (fl_search)
-	{
-#ifdef RE_ENABLE_I18N
-	  int not_initial = 0;
-	  for (j = 0; j < follows.nelem; ++j)
-	    if (dfa->nodes[follows.elems[j]].type == CHARACTER)
-	      {
-		not_initial = dfa->nodes[follows.elems[j]].mb_partial;
-		break;
-	      }
-	  if (!not_initial)
-#endif
-	    {
-	      err = re_node_set_merge (&follows,
-				       dfa->init_state->entrance_nodes);
-	      if (BE (err != REG_NOERROR, 0))
-		goto out_free;
-	    }
-	}
-      dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
-      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
-	goto out_free;
-      /* If the new state has context constraint,
-	 build appropriate states for these contexts.  */
-      if (dest_states[i]->has_constraint)
-	{
-	  dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
-							  CONTEXT_WORD);
-	  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
-	    goto out_free;
-	  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
-							CONTEXT_NEWLINE);
-	  if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
-	    goto out_free;
-	}
-      else
-	{
-	  dest_states_word[i] = dest_states[i];
-	  dest_states_nl[i] = dest_states[i];
-	}
-      bitset_merge (acceptable, dests_ch[i]);
-    }
-
-  /* Update the transition table.  */
-  /* For all characters ch...:  */
-  for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
-    for (j = 0; j < UINT_BITS; ++j, ++ch)
-      if ((acceptable[i] >> j) & 1)
-	{
-	  /* The current state accepts the character ch.  */
-	  if (IS_WORD_CHAR (ch))
-	    {
-	      for (k = 0; k < ndests; ++k)
-		if ((dests_ch[k][i] >> j) & 1)
-		  {
-		    /* k-th destination accepts the word character ch.  */
-		    trtable[ch] = dest_states_word[k];
-		    /* There must be only one destination which accepts
-		       character ch.  See group_nodes_into_DFAstates.  */
-		    break;
-		  }
-	    }
-	  else /* not WORD_CHAR */
-	    {
-	      for (k = 0; k < ndests; ++k)
-		if ((dests_ch[k][i] >> j) & 1)
-		  {
-		    /* k-th destination accepts the non-word character ch.  */
-		    trtable[ch] = dest_states[k];
-		    /* There must be only one destination which accepts
-		       character ch.  See group_nodes_into_DFAstates.  */
-		    break;
-		  }
-	    }
-	}
-  /* new line */
-  if (bitset_contain (acceptable, NEWLINE_CHAR))
-    {
-      /* The current state accepts newline character.  */
-      for (k = 0; k < ndests; ++k)
-	if (bitset_contain (dests_ch[k], NEWLINE_CHAR))
-	  {
-	    /* k-th destination accepts newline character.  */
-	    trtable[NEWLINE_CHAR] = dest_states_nl[k];
-	    /* There must be only one destination which accepts
-	       newline.  See group_nodes_into_DFAstates.  */
-	    break;
-	  }
-    }
-
-  if (dest_states_malloced)
-    free (dest_states);
-
-  re_node_set_free (&follows);
-  for (i = 0; i < ndests; ++i)
-    re_node_set_free (dests_node + i);
-
-  if (dests_node_malloced)
-    free (dests_node);
-
-  return trtable;
-}
-
-/* Group all nodes belonging to STATE into several destinations.
-   Then for all destinations, set the nodes belonging to the destination
-   to DESTS_NODE[i] and set the characters accepted by the destination
-   to DEST_CH[i].  This function return the number of destinations.  */
-
-static int
-group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
-    const regex_t *preg;
-    const re_dfastate_t *state;
-    re_node_set *dests_node;
-    bitset *dests_ch;
-{
-  reg_errcode_t err;
-  const re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  int i, j, k;
-  int ndests; /* Number of the destinations from `state'.  */
-  bitset accepts; /* Characters a node can accept.  */
-  const re_node_set *cur_nodes = &state->nodes;
-  bitset_empty (accepts);
-  ndests = 0;
-
-  /* For all the nodes belonging to `state',  */
-  for (i = 0; i < cur_nodes->nelem; ++i)
-    {
-      re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
-      re_token_type_t type = node->type;
-      unsigned int constraint = node->constraint;
-
-      /* Enumerate all single byte character this node can accept.  */
-      if (type == CHARACTER)
-	bitset_set (accepts, node->opr.c);
-      else if (type == SIMPLE_BRACKET)
-	{
-	  bitset_merge (accepts, node->opr.sbcset);
-	}
-      else if (type == OP_PERIOD)
-	{
-	  bitset_set_all (accepts);
-	  if (!(preg->syntax & RE_DOT_NEWLINE))
-	    bitset_clear (accepts, '\n');
-	  if (preg->syntax & RE_DOT_NOT_NULL)
-	    bitset_clear (accepts, '\0');
-	}
-      else
-	continue;
-
-      /* Check the `accepts' and sift the characters which are not
-	 match it the context.  */
-      if (constraint)
-	{
-	  if (constraint & NEXT_WORD_CONSTRAINT)
-	    for (j = 0; j < BITSET_UINTS; ++j)
-	      accepts[j] &= dfa->word_char[j];
-	  if (constraint & NEXT_NOTWORD_CONSTRAINT)
-	    for (j = 0; j < BITSET_UINTS; ++j)
-	      accepts[j] &= ~dfa->word_char[j];
-	  if (constraint & NEXT_NEWLINE_CONSTRAINT)
-	    {
-	      int accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
-	      bitset_empty (accepts);
-	      if (accepts_newline)
-		bitset_set (accepts, NEWLINE_CHAR);
-	      else
-		continue;
-	    }
-	}
-
-      /* Then divide `accepts' into DFA states, or create a new
-	 state.  */
-      for (j = 0; j < ndests; ++j)
-	{
-	  bitset intersec; /* Intersection sets, see below.  */
-	  bitset remains;
-	  /* Flags, see below.  */
-	  int has_intersec, not_subset, not_consumed;
-
-	  /* Optimization, skip if this state doesn't accept the character.  */
-	  if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
-	    continue;
-
-	  /* Enumerate the intersection set of this state and `accepts'.  */
-	  has_intersec = 0;
-	  for (k = 0; k < BITSET_UINTS; ++k)
-	    has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
-	  /* And skip if the intersection set is empty.  */
-	  if (!has_intersec)
-	    continue;
-
-	  /* Then check if this state is a subset of `accepts'.  */
-	  not_subset = not_consumed = 0;
-	  for (k = 0; k < BITSET_UINTS; ++k)
-	    {
-	      not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
-	      not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
-	    }
-
-	  /* If this state isn't a subset of `accepts', create a
-	     new group state, which has the `remains'. */
-	  if (not_subset)
-	    {
-	      bitset_copy (dests_ch[ndests], remains);
-	      bitset_copy (dests_ch[j], intersec);
-	      err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
-	      if (BE (err != REG_NOERROR, 0))
-		goto error_return;
-	      ++ndests;
-	    }
-
-	  /* Put the position in the current group. */
-	  err = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
-	  if (BE (err < 0, 0))
-	    goto error_return;
-
-	  /* If all characters are consumed, go to next node. */
-	  if (!not_consumed)
-	    break;
-	}
-      /* Some characters remain, create a new group. */
-      if (j == ndests)
-	{
-	  bitset_copy (dests_ch[ndests], accepts);
-	  err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
-	  if (BE (err != REG_NOERROR, 0))
-	    goto error_return;
-	  ++ndests;
-	  bitset_empty (accepts);
-	}
-    }
-  return ndests;
- error_return:
-  for (j = 0; j < ndests; ++j)
-    re_node_set_free (dests_node + j);
-  return -1;
-}
-
-#ifdef RE_ENABLE_I18N
-/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
-   Return the number of the bytes the node accepts.
-   STR_IDX is the current index of the input string.
-
-   This function handles the nodes which can accept one character, or
-   one collating element like '.', '[a-z]', opposite to the other nodes
-   can only accept one byte.  */
-
-static int
-check_node_accept_bytes (preg, node_idx, input, str_idx)
-    const regex_t *preg;
-    int node_idx, str_idx;
-    const re_string_t *input;
-{
-  const re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  const re_token_t *node = dfa->nodes + node_idx;
-  int elem_len = re_string_elem_size_at (input, str_idx);
-  int char_len = re_string_char_size_at (input, str_idx);
-  int i;
-# ifdef _LIBC
-  int j;
-  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-# endif /* _LIBC */
-  if (elem_len <= 1 && char_len <= 1)
-    return 0;
-  if (node->type == OP_PERIOD)
-    {
-      /* '.' accepts any one character except the following two cases.  */
-      if ((!(preg->syntax & RE_DOT_NEWLINE) &&
-	   re_string_byte_at (input, str_idx) == '\n') ||
-	  ((preg->syntax & RE_DOT_NOT_NULL) &&
-	   re_string_byte_at (input, str_idx) == '\0'))
-	return 0;
-      return char_len;
-    }
-  else if (node->type == COMPLEX_BRACKET)
-    {
-      const re_charset_t *cset = node->opr.mbcset;
-# ifdef _LIBC
-      const unsigned char *pin = ((char *) re_string_get_buffer (input)
-				  + str_idx);
-# endif /* _LIBC */
-      int match_len = 0;
-      wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
-		    ? re_string_wchar_at (input, str_idx) : 0);
-
-      /* match with multibyte character?  */
-      for (i = 0; i < cset->nmbchars; ++i)
-	if (wc == cset->mbchars[i])
-	  {
-	    match_len = char_len;
-	    goto check_node_accept_bytes_match;
-	  }
-      /* match with character_class?  */
-      for (i = 0; i < cset->nchar_classes; ++i)
-	{
-	  wctype_t wt = cset->char_classes[i];
-	  if (__iswctype (wc, wt))
-	    {
-	      match_len = char_len;
-	      goto check_node_accept_bytes_match;
-	    }
-	}
-
-# ifdef _LIBC
-      if (nrules != 0)
-	{
-	  unsigned int in_collseq = 0;
-	  const int32_t *table, *indirect;
-	  const unsigned char *weights, *extra;
-	  const char *collseqwc;
-	  int32_t idx;
-	  /* This #include defines a local function!  */
-#  include <locale/weight.h>
-
-	  /* match with collating_symbol?  */
-	  if (cset->ncoll_syms)
-	    extra = (const unsigned char *)
-	      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
-	  for (i = 0; i < cset->ncoll_syms; ++i)
-	    {
-	      const unsigned char *coll_sym = extra + cset->coll_syms[i];
-	      /* Compare the length of input collating element and
-		 the length of current collating element.  */
-	      if (*coll_sym != elem_len)
-		continue;
-	      /* Compare each bytes.  */
-	      for (j = 0; j < *coll_sym; j++)
-		if (pin[j] != coll_sym[1 + j])
-		  break;
-	      if (j == *coll_sym)
-		{
-		  /* Match if every bytes is equal.  */
-		  match_len = j;
-		  goto check_node_accept_bytes_match;
-		}
-	    }
-
-	  if (cset->nranges)
-	    {
-	      if (elem_len <= char_len)
-		{
-		  collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
-		  in_collseq = collseq_table_lookup (collseqwc, wc);
-		}
-	      else
-		in_collseq = find_collation_sequence_value (pin, elem_len);
-	    }
-	  /* match with range expression?  */
-	  for (i = 0; i < cset->nranges; ++i)
-	    if (cset->range_starts[i] <= in_collseq
-		&& in_collseq <= cset->range_ends[i])
-	      {
-		match_len = elem_len;
-		goto check_node_accept_bytes_match;
-	      }
-
-	  /* match with equivalence_class?  */
-	  if (cset->nequiv_classes)
-	    {
-	      const unsigned char *cp = pin;
-	      table = (const int32_t *)
-		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-	      weights = (const unsigned char *)
-		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
-	      extra = (const unsigned char *)
-		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
-	      indirect = (const int32_t *)
-		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
-	      idx = findidx (&cp);
-	      if (idx > 0)
-		for (i = 0; i < cset->nequiv_classes; ++i)
-		  {
-		    int32_t equiv_class_idx = cset->equiv_classes[i];
-		    size_t weight_len = weights[idx];
-		    if (weight_len == weights[equiv_class_idx])
-		      {
-			int cnt = 0;
-			while (cnt <= weight_len
-			       && (weights[equiv_class_idx + 1 + cnt]
-				   == weights[idx + 1 + cnt]))
-			  ++cnt;
-			if (cnt > weight_len)
-			  {
-			    match_len = elem_len;
-			    goto check_node_accept_bytes_match;
-			  }
-		      }
-		  }
-	    }
-	}
-      else
-# endif /* _LIBC */
-	{
-	  /* match with range expression?  */
-#if __GNUC__ >= 2
-	  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
-#else
-	  wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
-	  cmp_buf[2] = wc;
-#endif
-	  for (i = 0; i < cset->nranges; ++i)
-	    {
-	      cmp_buf[0] = cset->range_starts[i];
-	      cmp_buf[4] = cset->range_ends[i];
-	      if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
-		  && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
-		{
-		  match_len = char_len;
-		  goto check_node_accept_bytes_match;
-		}
-	    }
-	}
-    check_node_accept_bytes_match:
-      if (!cset->non_match)
-	return match_len;
-      else
-	{
-	  if (match_len > 0)
-	    return 0;
-	  else
-	    return (elem_len > char_len) ? elem_len : char_len;
-	}
-    }
-  return 0;
-}
-
-# ifdef _LIBC
-static unsigned int
-find_collation_sequence_value (mbs, mbs_len)
-    const unsigned char *mbs;
-    size_t mbs_len;
-{
-  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-  if (nrules == 0)
-    {
-      if (mbs_len == 1)
-	{
-	  /* No valid character.  Match it as a single byte character.  */
-	  const unsigned char *collseq = (const unsigned char *)
-	    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
-	  return collseq[mbs[0]];
-	}
-      return UINT_MAX;
-    }
-  else
-    {
-      int32_t idx;
-      const unsigned char *extra = (const unsigned char *)
-	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
-
-      for (idx = 0; ;)
-	{
-	  int mbs_cnt, found = 0;
-	  int32_t elem_mbs_len;
-	  /* Skip the name of collating element name.  */
-	  idx = idx + extra[idx] + 1;
-	  elem_mbs_len = extra[idx++];
-	  if (mbs_len == elem_mbs_len)
-	    {
-	      for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
-		if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
-		  break;
-	      if (mbs_cnt == elem_mbs_len)
-		/* Found the entry.  */
-		found = 1;
-	    }
-	  /* Skip the byte sequence of the collating element.  */
-	  idx += elem_mbs_len;
-	  /* Adjust for the alignment.  */
-	  idx = (idx + 3) & ~3;
-	  /* Skip the collation sequence value.  */
-	  idx += sizeof (uint32_t);
-	  /* Skip the wide char sequence of the collating element.  */
-	  idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
-	  /* If we found the entry, return the sequence value.  */
-	  if (found)
-	    return *(uint32_t *) (extra + idx);
-	  /* Skip the collation sequence value.  */
-	  idx += sizeof (uint32_t);
-	}
-    }
-}
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
-
-/* Check whether the node accepts the byte which is IDX-th
-   byte of the INPUT.  */
-
-static int
-check_node_accept (preg, node, mctx, idx)
-    const regex_t *preg;
-    const re_token_t *node;
-    const re_match_context_t *mctx;
-    int idx;
-{
-  unsigned char ch;
-  if (node->constraint)
-    {
-      /* The node has constraints.  Check whether the current context
-	 satisfies the constraints.  */
-      unsigned int context = re_string_context_at (mctx->input, idx,
-						   mctx->eflags,
-						   preg->newline_anchor);
-      if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
-	return 0;
-    }
-  ch = re_string_byte_at (mctx->input, idx);
-  if (node->type == CHARACTER)
-    return node->opr.c == ch;
-  else if (node->type == SIMPLE_BRACKET)
-    return bitset_contain (node->opr.sbcset, ch);
-  else if (node->type == OP_PERIOD)
-    return !((ch == '\n' && !(preg->syntax & RE_DOT_NEWLINE))
-	     || (ch == '\0' && (preg->syntax & RE_DOT_NOT_NULL)));
-  else
-    return 0;
-}
-
-/* Extend the buffers, if the buffers have run out.  */
-
-static reg_errcode_t
-extend_buffers (mctx)
-     re_match_context_t *mctx;
-{
-  reg_errcode_t ret;
-  re_string_t *pstr = mctx->input;
-
-  /* Double the lengthes of the buffers.  */
-  ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-
-  if (mctx->state_log != NULL)
-    {
-      /* And double the length of state_log.  */
-      re_dfastate_t **new_array;
-      new_array = re_realloc (mctx->state_log, re_dfastate_t *,
-			      pstr->bufs_len * 2);
-      if (BE (new_array == NULL, 0))
-	return REG_ESPACE;
-      mctx->state_log = new_array;
-    }
-
-  /* Then reconstruct the buffers.  */
-  if (pstr->icase)
-    {
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	build_wcs_upper_buffer (pstr);
-      else
-#endif /* RE_ENABLE_I18N  */
-	build_upper_buffer (pstr);
-    }
-  else
-    {
-#ifdef RE_ENABLE_I18N
-      if (MB_CUR_MAX > 1)
-	build_wcs_buffer (pstr);
-      else
-#endif /* RE_ENABLE_I18N  */
-	{
-	  if (pstr->trans != NULL)
-	    re_string_translate_buffer (pstr);
-	  else
-	    pstr->valid_len = pstr->bufs_len;
-	}
-    }
-  return REG_NOERROR;
-}
-
-
-/* Functions for matching context.  */
-
-/* Initialize MCTX.  */
-
-static reg_errcode_t
-match_ctx_init (mctx, eflags, input, n)
-    re_match_context_t *mctx;
-    int eflags, n;
-    re_string_t *input;
-{
-  mctx->eflags = eflags;
-  mctx->input = input;
-  mctx->match_last = -1;
-  if (n > 0)
-    {
-      mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
-      mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
-      if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
-	return REG_ESPACE;
-    }
-  else
-    mctx->bkref_ents = NULL;
-  mctx->nbkref_ents = 0;
-  mctx->abkref_ents = n;
-  mctx->max_mb_elem_len = 1;
-  mctx->nsub_tops = 0;
-  mctx->asub_tops = n;
-  return REG_NOERROR;
-}
-
-/* Clean the entries which depend on the current input in MCTX.
-   This function must be invoked when the matcher changes the start index
-   of the input, or changes the input string.  */
-
-static void
-match_ctx_clean (mctx)
-    re_match_context_t *mctx;
-{
-  match_ctx_free_subtops (mctx);
-  mctx->nsub_tops = 0;
-  mctx->nbkref_ents = 0;
-}
-
-/* Free all the memory associated with MCTX.  */
-
-static void
-match_ctx_free (mctx)
-    re_match_context_t *mctx;
-{
-  match_ctx_free_subtops (mctx);
-  re_free (mctx->sub_tops);
-  re_free (mctx->bkref_ents);
-}
-
-/* Free all the memory associated with MCTX->SUB_TOPS.  */
-
-static void
-match_ctx_free_subtops (mctx)
-     re_match_context_t *mctx;
-{
-  int st_idx;
-  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
-    {
-      int sl_idx;
-      re_sub_match_top_t *top = mctx->sub_tops[st_idx];
-      for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
-	{
-	  re_sub_match_last_t *last = top->lasts[sl_idx];
-	  re_free (last->path.array);
-	  re_free (last);
-	}
-      re_free (top->lasts);
-      if (top->path)
-	{
-	  re_free (top->path->array);
-	  re_free (top->path);
-	}
-      free (top);
-    }
-}
-
-/* Add a new backreference entry to MCTX.
-   Note that we assume that caller never call this function with duplicate
-   entry, and call with STR_IDX which isn't smaller than any existing entry.
-*/
-
-static reg_errcode_t
-match_ctx_add_entry (mctx, node, str_idx, from, to)
-     re_match_context_t *mctx;
-     int node, str_idx, from, to;
-{
-  if (mctx->nbkref_ents >= mctx->abkref_ents)
-    {
-      struct re_backref_cache_entry* new_entry;
-      new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
-			      mctx->abkref_ents * 2);
-      if (BE (new_entry == NULL, 0))
-	{
-	  re_free (mctx->bkref_ents);
-	  return REG_ESPACE;
-	}
-      mctx->bkref_ents = new_entry;
-      memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
-	      sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
-      mctx->abkref_ents *= 2;
-    }
-  mctx->bkref_ents[mctx->nbkref_ents].node = node;
-  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
-  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
-  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
-  mctx->bkref_ents[mctx->nbkref_ents++].flag = 0;
-  if (mctx->max_mb_elem_len < to - from)
-    mctx->max_mb_elem_len = to - from;
-  return REG_NOERROR;
-}
-
-/* Search for the first entry which has the same str_idx.
-   Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
-
-static int
-search_cur_bkref_entry (mctx, str_idx)
-     re_match_context_t *mctx;
-     int str_idx;
-{
-  int left, right, mid;
-  right = mctx->nbkref_ents;
-  for (left = 0; left < right;)
-    {
-      mid = (left + right) / 2;
-      if (mctx->bkref_ents[mid].str_idx < str_idx)
-	left = mid + 1;
-      else
-	right = mid;
-    }
-  return left;
-}
-
-static void
-match_ctx_clear_flag (mctx)
-     re_match_context_t *mctx;
-{
-  int i;
-  for (i = 0; i < mctx->nbkref_ents; ++i)
-    {
-      mctx->bkref_ents[i].flag = 0;
-    }
-}
-
-/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
-   at STR_IDX.  */
-
-static reg_errcode_t
-match_ctx_add_subtop (mctx, node, str_idx)
-     re_match_context_t *mctx;
-     int node, str_idx;
-{
-#ifdef DEBUG
-  assert (mctx->sub_tops != NULL);
-  assert (mctx->asub_tops > 0);
-#endif
-  if (mctx->nsub_tops == mctx->asub_tops)
-    {
-      re_sub_match_top_t **new_array;
-      mctx->asub_tops *= 2;
-      new_array = re_realloc (mctx->sub_tops, re_sub_match_top_t *,
-			      mctx->asub_tops);
-      if (BE (new_array == NULL, 0))
-	return REG_ESPACE;
-      mctx->sub_tops = new_array;
-    }
-  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
-  if (mctx->sub_tops[mctx->nsub_tops] == NULL)
-    return REG_ESPACE;
-  mctx->sub_tops[mctx->nsub_tops]->node = node;
-  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
-  return REG_NOERROR;
-}
-
-/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
-   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
-
-static re_sub_match_last_t *
-match_ctx_add_sublast (subtop, node, str_idx)
-     re_sub_match_top_t *subtop;
-     int node, str_idx;
-{
-  re_sub_match_last_t *new_entry;
-  if (subtop->nlasts == subtop->alasts)
-    {
-      re_sub_match_last_t **new_array;
-      subtop->alasts = 2 * subtop->alasts + 1;
-      new_array = re_realloc (subtop->lasts, re_sub_match_last_t *,
-			      subtop->alasts);
-      if (BE (new_array == NULL, 0))
-	return NULL;
-      subtop->lasts = new_array;
-    }
-  new_entry = calloc (1, sizeof (re_sub_match_last_t));
-  if (BE (new_entry == NULL, 0))
-    return NULL;
-  subtop->lasts[subtop->nlasts] = new_entry;
-  new_entry->node = node;
-  new_entry->str_idx = str_idx;
-  ++subtop->nlasts;
-  return new_entry;
-}
-
-static void
-sift_ctx_init (sctx, sifted_sts, limited_sts, last_node, last_str_idx,
-	       check_subexp)
-    re_sift_context_t *sctx;
-    re_dfastate_t **sifted_sts, **limited_sts;
-    int last_node, last_str_idx, check_subexp;
-{
-  sctx->sifted_states = sifted_sts;
-  sctx->limited_states = limited_sts;
-  sctx->last_node = last_node;
-  sctx->last_str_idx = last_str_idx;
-  sctx->check_subexp = check_subexp;
-  sctx->cur_bkref = -1;
-  sctx->cls_subexp_idx = -1;
-  re_node_set_init_empty (&sctx->limits);
-}
diff --git a/sm5/scsicmds.c b/sm5/scsicmds.c
deleted file mode 100644
index 19c55a198c8cf7c4bd2c2e13c74bbb3cf87a5daa..0000000000000000000000000000000000000000
--- a/sm5/scsicmds.c
+++ /dev/null
@@ -1,1942 +0,0 @@
-/*
- * scsicmds.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003-4 Douglas Gilbert <dougg@torque.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- *
- * In the SCSI world "SMART" is a dead or withdrawn standard. In recent
- * SCSI standards (since SCSI-3) it goes under the awkward name of
- * "Informational Exceptions" ["IE" or "IEC" (with the "C" for "control")].
- * The relevant information is spread around several SCSI draft
- * standards available at http://www.t10.org . Reference is made in the
- * code to the following acronyms:
- *      - SAM [SCSI Architectural model, versions 2 or 3]
- *      - SPC [SCSI Primary commands, versions 2 or 3]
- *      - SBC [SCSI Block commands, versions 2]
- *
- * Some SCSI disk vendors have snippets of "SMART" information in their
- * product manuals.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "config.h"
-#include "int64.h"
-#include "extern.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-const char *scsicmds_c_cvsid="$Id: scsicmds.c,v 1.76 2004/07/11 15:16:31 dpgilbert Exp $"
-CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-/* for passing global control variables */
-extern smartmonctrl *con;
-
-/* output binary in hex and optionally ascii */
-void dStrHex(const char* str, int len, int no_ascii)
-{
-    const char* p = str;
-    unsigned char c;
-    char buff[82];
-    int a = 0;
-    const int bpstart = 5;
-    const int cpstart = 60;
-    int cpos = cpstart;
-    int bpos = bpstart;
-    int i, k;
-    
-    if (len <= 0) return;
-    memset(buff,' ',80);
-    buff[80]='\0';
-    k = sprintf(buff + 1, "%.2x", a);
-    buff[k + 1] = ' ';
-    if (bpos >= ((bpstart + (9 * 3))))
-        bpos++;
-
-    for(i = 0; i < len; i++)
-    {
-        c = *p++;
-        bpos += 3;
-        if (bpos == (bpstart + (9 * 3)))
-            bpos++;
-        sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c);
-        buff[bpos + 2] = ' ';
-        if (no_ascii)
-            buff[cpos++] = ' ';
-        else {
-            if ((c < ' ') || (c >= 0x7f))
-                c='.';
-            buff[cpos++] = c;
-        }
-        if (cpos > (cpstart+15))
-        {
-            pout("%s\n", buff);
-            bpos = bpstart;
-            cpos = cpstart;
-            a += 16;
-            memset(buff,' ',80);
-            k = sprintf(buff + 1, "%.2x", a);
-            buff[k + 1] = ' ';
-        }
-    }
-    if (cpos > cpstart)
-    {
-        pout("%s\n", buff);
-    }
-}
-
-struct scsi_opcode_name {
-    UINT8 opcode;
-    const char * name;
-};
-
-static struct scsi_opcode_name opcode_name_arr[] = {
-    /* in ascending opcode order */
-    {TEST_UNIT_READY, "test unit ready"},       /* 0x00 */
-    {REQUEST_SENSE, "request sense"},           /* 0x03 */
-    {INQUIRY, "inquiry"},                       /* 0x12 */
-    {MODE_SELECT, "mode select"},               /* 0x15 */
-    {MODE_SENSE, "mode sense"},                 /* 0x1a */
-    {RECEIVE_DIAGNOSTIC, "receive diagnostic"}, /* 0x1c */
-    {SEND_DIAGNOSTIC, "send diagnostic"},       /* 0x1d */
-    {LOG_SENSE, "log sense"},                   /* 0x4d */
-    {MODE_SELECT_10, "mode select(10)"},        /* 0x55 */
-    {MODE_SENSE_10, "mode sense(10)"},          /* 0x5a */
-};
-
-const char * scsi_get_opcode_name(UINT8 opcode)
-{
-    int k;
-    int len = sizeof(opcode_name_arr) / sizeof(opcode_name_arr[0]);
-    struct scsi_opcode_name * onp;
-
-    for (k = 0; k < len; ++k) {
-        onp = &opcode_name_arr[k];
-        if (opcode == onp->opcode)
-            return onp->name;
-        else if (opcode < onp->opcode)
-            return NULL;
-    }
-    return NULL;
-}
-
-
-void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
-                          struct scsi_sense_disect * out)
-{
-    memset(out, 0, sizeof(struct scsi_sense_disect));
-    if ((SCSI_STATUS_CHECK_CONDITION == io_buf->scsi_status) && 
-        (io_buf->resp_sense_len > 7)) {  
-        out->error_code = (io_buf->sensep[0] & 0x7f);
-        out->sense_key = (io_buf->sensep[2] & 0xf);
-        if (io_buf->resp_sense_len > 13) {
-            out->asc = io_buf->sensep[12];
-            out->ascq = io_buf->sensep[13];
-        }
-    }
-}
-
-static int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo)
-{
-    if (SCSI_SK_NOT_READY == sinfo->sense_key) {
-        if (SCSI_ASC_NO_MEDIUM == sinfo->asc) 
-            return SIMPLE_ERR_NO_MEDIUM;
-        else if (SCSI_ASC_NOT_READY == sinfo->asc) {
-            if (0x1 == sinfo->ascq)
-                return SIMPLE_ERR_BECOMING_READY;
-            else
-                return SIMPLE_ERR_NOT_READY;
-        } else
-            return SIMPLE_ERR_NOT_READY;
-    } else if (SCSI_SK_ILLEGAL_REQUEST == sinfo->sense_key) {
-        if (SCSI_ASC_UNKNOWN_OPCODE == sinfo->asc)
-            return SIMPLE_ERR_BAD_OPCODE;
-        else if (SCSI_ASC_UNKNOWN_FIELD == sinfo->asc)
-            return SIMPLE_ERR_BAD_FIELD;
-        else if (SCSI_ASC_UNKNOWN_PARAM == sinfo->asc)
-            return SIMPLE_ERR_BAD_PARAM;
-    } else if (SCSI_SK_UNIT_ATTENTION == sinfo->sense_key)
-        return SIMPLE_ERR_TRY_AGAIN;
-    return SIMPLE_NO_ERROR;
-}
-
-const char * scsiErrString(int scsiErr)
-{
-    if (scsiErr < 0)
-        return strerror(-scsiErr);
-    switch (scsiErr) {
-        case SIMPLE_NO_ERROR: 
-            return "no error";
-        case SIMPLE_ERR_NOT_READY: 
-            return "device not ready";
-        case SIMPLE_ERR_BAD_OPCODE: 
-            return "unsupported scsi opcode";
-        case SIMPLE_ERR_BAD_FIELD: 
-            return "unsupported field in scsi command";
-        case SIMPLE_ERR_BAD_PARAM: 
-            return "badly formed scsi parameters";
-        case SIMPLE_ERR_BAD_RESP: 
-            return "scsi response fails sanity test";
-        case SIMPLE_ERR_NO_MEDIUM: 
-            return "no medium present";
-        case SIMPLE_ERR_BECOMING_READY: 
-            return "device will be ready soon";
-        case SIMPLE_ERR_TRY_AGAIN: 
-            return "unit attention reported, try again";
-        default:
-            return "unknown error";
-    }
-}
-
-/* Sends LOG SENSE command. Returns 0 if ok, 1 if device NOT READY, 2 if
-   command not supported, 3 if field (within command) not supported or
-   returns negated errno.  SPC sections 7.6 and 8.2 N.B. Sets PC==1
-   to fetch "current cumulative" log pages.
-   If known_resp_len > 0 then a single fetch is done for this response
-   length. If known_resp_len == 0 then twin fetches are performed, the
-   first to deduce the response length, then send the same command again
-   requesting the deduced response length. This protects certain fragile 
-   HBAs. The twin fetch technique should not be used with the TapeAlert
-   log page since it clears its state flags after each fetch. */
-int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
-                 int known_resp_len)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int pageLen;
-    int status, res;
-
-    if (known_resp_len > bufLen)
-        return -EIO;
-    if (known_resp_len > 0)
-        pageLen = known_resp_len;
-    else {
-        /* Starting twin fetch strategy: first fetch to find respone length */
-        pageLen = 4;
-        if (pageLen > bufLen)
-            return -EIO;
-        else
-            memset(pBuf, 0, pageLen);
-
-        memset(&io_hdr, 0, sizeof(io_hdr));
-        memset(cdb, 0, sizeof(cdb));
-        io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-        io_hdr.dxfer_len = pageLen;
-        io_hdr.dxferp = pBuf;
-        cdb[0] = LOG_SENSE;
-        cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-        cdb[7] = (pageLen >> 8) & 0xff;
-        cdb[8] = pageLen & 0xff;
-        io_hdr.cmnd = cdb;
-        io_hdr.cmnd_len = sizeof(cdb);
-        io_hdr.sensep = sense;
-        io_hdr.max_sense_len = sizeof(sense);
-        io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-    
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-            return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        if ((res = scsiSimpleSenseFilter(&sinfo)))
-            return res;
-        /* sanity check on response */
-        if ((SUPPORTED_LPAGES != pagenum) && (pBuf[0] != pagenum))
-            return SIMPLE_ERR_BAD_RESP;
-        if (0 == ((pBuf[2] << 8) + pBuf[3]))
-            return SIMPLE_ERR_BAD_RESP;
-        pageLen = (pBuf[2] << 8) + pBuf[3] + 4;
-        /* some SCSI HBA don't like "odd" length transfers */
-        if (pageLen % 2)
-            pageLen += 1;   
-        if (pageLen > bufLen)
-            pageLen = bufLen;
-    }
-    memset(pBuf, 0, 4);
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = pageLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = LOG_SENSE;
-    cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-    cdb[7] = (pageLen >> 8) & 0xff;
-    cdb[8] = pageLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (0 != status)
-        return status;
-    /* sanity check on response */
-    if ((SUPPORTED_LPAGES != pagenum) && (pBuf[0] != pagenum))
-        return SIMPLE_ERR_BAD_RESP;
-    if (0 == ((pBuf[2] << 8) + pBuf[3]))
-        return SIMPLE_ERR_BAD_RESP;
-    return 0;
-}
-
-/* Send MODE SENSE (6 byte) command. Returns 0 if ok, 1 if NOT READY,
- * 2 if command not supported (then MODE SENSE(10) should be supported),
- * 3 if field in command not supported or returns negated errno. 
- * SPC sections 7.9 and 8.4 [mode subpage==0] */
-int scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SENSE;
-    cdb[2] = (pc << 6) | (pagenum & 0x3f);
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-	return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (SIMPLE_ERR_TRY_AGAIN == status) {
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-	    return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        status = scsiSimpleSenseFilter(&sinfo);
-    }
-    if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {
-        int offset;
-
-        offset = scsiModePageOffset(pBuf, bufLen, 0);
-        if (offset < 0)
-            return SIMPLE_ERR_BAD_RESP;
-        else if (pagenum != (pBuf[offset] & 0x3f))
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return status;
-}
-
-/* Sends a 6 byte MODE SELECT command. Assumes given pBuf is the response
- * from a corresponding 6 byte MODE SENSE command. Such a response should
- * have a 4 byte header followed by 0 or more 8 byte block descriptors
- * (normally 1) and then 1 mode page. Returns 0 if ok, 1 if NOT READY,
- * 2 if command not supported (then MODE SELECT(10) may be supported), 
- * 3 if field in command not supported, 4 if bad parameter to command
- * or returns negated errno. SPC sections 7.7 and 8.4 */
-int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status, pg_offset, pg_len, hdr_plus_1_pg;
-
-    pg_offset = 4 + pBuf[3];
-    if (pg_offset + 2 >= bufLen)
-        return -EINVAL;
-    pg_len = pBuf[pg_offset + 1] + 2;
-    hdr_plus_1_pg = pg_offset + pg_len;
-    if (hdr_plus_1_pg > bufLen)
-        return -EINVAL;
-    pBuf[0] = 0;    /* Length of returned mode sense data reserved for SELECT */
-    pBuf[pg_offset] &= 0x3f;    /* Mask of PS bit from byte 0 of page data */
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_TO_DEVICE;
-    io_hdr.dxfer_len = hdr_plus_1_pg;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SELECT;
-    cdb[1] = 0x10 | (sp & 1);      /* set PF (page format) bit always */
-    cdb[4] = hdr_plus_1_pg; /* make sure only one page sent */
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* MODE SENSE (10 byte). Returns 0 if ok, 1 if NOT READY, 2 if command 
- * not supported (then MODE SENSE(6) might be supported), 3 if field in
- * command not supported or returns negated errno.  
- * SPC sections 7.10 and 8.4 [mode subpage==0] */
-int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SENSE_10;
-    cdb[2] = (pc << 6) | (pagenum & 0x3f);
-    cdb[7] = (bufLen >> 8) & 0xff;
-    cdb[8] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-	return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (SIMPLE_ERR_TRY_AGAIN == status) {
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-	    return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        status = scsiSimpleSenseFilter(&sinfo);
-    }
-    if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {
-        int offset;
-
-        offset = scsiModePageOffset(pBuf, bufLen, 1);
-        if (offset < 0)
-            return SIMPLE_ERR_BAD_RESP;
-        else if (pagenum != (pBuf[offset] & 0x3f))
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return status;
-}
-
-/* Sends a 10 byte MODE SELECT command. Assumes given pBuf is the response
- * from a corresponding 10 byte MODE SENSE command. Such a response should
- * have a 8 byte header followed by 0 or more 8 byte block descriptors
- * (normally 1) and then 1 mode page. Returns 0 if ok, 1 NOT REAFY, 2 if 
- * command not supported (then MODE SELECT(6) may be supported), 3 if field
- * in command not supported, 4 if bad parameter to command or returns
- * negated errno. SAM sections 7.8 and 8.4 */
-int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status, pg_offset, pg_len, hdr_plus_1_pg;
-
-    pg_offset = 8 + (pBuf[6] << 8) + pBuf[7];
-    if (pg_offset + 2 >= bufLen)
-        return -EINVAL;
-    pg_len = pBuf[pg_offset + 1] + 2;
-    hdr_plus_1_pg = pg_offset + pg_len;
-    if (hdr_plus_1_pg > bufLen)
-        return -EINVAL;
-    pBuf[0] = 0;    
-    pBuf[1] = 0; /* Length of returned mode sense data reserved for SELECT */
-    pBuf[pg_offset] &= 0x3f;    /* Mask of PS bit from byte 0 of page data */
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_TO_DEVICE;
-    io_hdr.dxfer_len = hdr_plus_1_pg;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SELECT_10;
-    cdb[1] = 0x10 | (sp & 1);      /* set PF (page format) bit always */
-    cdb[8] = hdr_plus_1_pg; /* make sure only one page sent */
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* Standard INQUIRY returns 0 for ok, anything else is a major problem.
- * bufLen should be 36 for unsafe devices (like USB mass storage stuff)
- * otherwise they can lock up! SPC sections 7.4 and 8.6 */
-int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_sense_disect sinfo;
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    int status;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = INQUIRY;
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* INQUIRY to fetch Vital Page Data.  Returns 0 if ok, 1 if NOT READY
- * (unlikely), 2 if command not supported, 3 if field in command not 
- * supported, 5 if response indicates that EVPD bit ignored or returns
- * negated errno. SPC section 7.4 and 8.6 */
-int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status, res;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    if (bufLen > 1)
-        pBuf[1] = 0x0;
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = INQUIRY;
-    cdb[1] = 0x1;       /* set EVPD bit (enable Vital Product Data) */
-    cdb[2] = vpd_page;
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    /* Guard against devices that ignore EVPD bit and do standard INQUIRY */
-    if (bufLen > 1) {
-        if (vpd_page == pBuf[1]) {
-            if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))
-                return SIMPLE_ERR_BAD_RESP;
-        } else
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return 0;
-}
-
-/* REQUEST SENSE command. Returns 0 if ok, anything else major problem.
- * SPC section 7.24 */
-int scsiRequestSense(int device, struct scsi_sense_disect * sense_info)
-{
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    UINT8 buff[18];
-    int status, len;
-    UINT8 ecode;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = sizeof(buff);
-    io_hdr.dxferp = buff;
-    cdb[0] = REQUEST_SENSE;
-    cdb[4] = sizeof(buff);
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if ((0 == status) && (sense_info)) {
-        ecode = buff[0] & 0x7f;
-        sense_info->error_code = ecode;
-        sense_info->sense_key = buff[2] & 0xf;
-        sense_info->asc = 0;
-        sense_info->ascq = 0;
-        if ((0x70 == ecode) || (0x71 == ecode)) {
-            len = buff[7] + 8;
-            if (len > 13) {
-                sense_info->asc = buff[12];
-                sense_info->ascq = buff[13];
-            }
-        }
-    }
-    return status;
-}
-
-/* SEND DIAGNOSTIC command.  Returns 0 if ok, 1 if NOT READY, 2 if command
- * not supported, 3 if field in command not supported or returns negated
- * errno. SPC section 7.25 */
-int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = bufLen ? DXFER_TO_DEVICE: DXFER_NONE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = SEND_DIAGNOSTIC;
-    if (SCSI_DIAG_DEF_SELF_TEST == functioncode)
-        cdb[1] = 0x4;  /* SelfTest bit */
-    else if (SCSI_DIAG_NO_SELF_TEST != functioncode)
-        cdb[1] = (functioncode & 0x7) << 5; /* SelfTest _code_ */
-    else   /* SCSI_DIAG_NO_SELF_TEST == functioncode */
-        cdb[1] = 0x10;  /* PF bit */
-    cdb[3] = (bufLen >> 8) & 0xff;
-    cdb[4] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_SELF_TEST;
-    /* worst case is an extended foreground self test on a big disk */
-    
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* RECEIVE DIAGNOSTIC command. Returns 0 if ok, 1 if NOT READY, 2 if
- * command not supported, 3 if field in command not supported or returns
- * negated errno. SPC section 7.17 */
-int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf, 
-                      int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = RECEIVE_DIAGNOSTIC;
-    cdb[1] = pcv;
-    cdb[2] = pagenum;
-    cdb[3] = (bufLen >> 8) & 0xff;
-    cdb[4] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* TEST UNIT READY command. SPC section 7.28 (probably in SBC as well) */
-static int _testunitready(int device, struct scsi_sense_disect * sinfo)
-{
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_NONE;
-    io_hdr.dxfer_len = 0;
-    io_hdr.dxferp = NULL;
-    cdb[0] = TEST_UNIT_READY;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, sinfo);
-    return 0;
-}
-
-/* Returns 0 for device responds and media ready, 1 for device responds and
-   media not ready, or returns a negated errno value */
-int scsiTestUnitReady(int device)
-{
-    struct scsi_sense_disect sinfo;
-    int status;
-
-    status = _testunitready(device, &sinfo);
-    if (0 != status)
-        return status;
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (SIMPLE_ERR_TRY_AGAIN == status) {
-        /* power on reset, media changed, ok ... try again */
-        status = _testunitready(device, &sinfo);        
-        if (0 != status)
-            return status;
-        status = scsiSimpleSenseFilter(&sinfo);
-    }
-    return status;
-}
-
-/* Offset into mode sense (6 or 10 byte) response that actual mode page
- * starts at (relative to resp[0]). Returns -1 if problem */
-int scsiModePageOffset(const UINT8 * resp, int len, int modese_len)
-{
-    int resp_len, bd_len;
-    int offset = -1;
-
-    if (resp) {
-        if (10 == modese_len) {
-            resp_len = (resp[0] << 8) + resp[1] + 2;
-            bd_len = (resp[6] << 8) + resp[7];
-            offset = bd_len + 8;
-        } else {
-            resp_len = resp[0] + 1;
-            bd_len = resp[3];
-            offset = bd_len + 4;
-        }
-        if ((offset + 2) > len) {
-            pout("scsiModePageOffset: raw_curr too small, offset=%d "
-                 "resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);
-            offset = -1;
-        } else if ((offset + 2) > resp_len) {
-            pout("scsiModePageOffset: response length too short, resp_len=%d"
-                 " offset=%d bd_len=%d\n", resp_len, offset, bd_len);
-            offset = -1;
-        }
-    }
-    return offset;
-}
-
-/* IEC mode page byte 2 bit masks */
-#define DEXCPT_ENABLE   0x08
-#define EWASC_ENABLE    0x10
-#define DEXCPT_DISABLE  0xf7
-#define EWASC_DISABLE   0xef
-#define TEST_DISABLE    0xfb
-
-/* Fetches the Informational Exceptions Control mode page. First tries
- * the 6 byte MODE SENSE command and if that fails with an illegal opcode
- * tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive
- * number if a known error (see  SIMPLE_ERR_ ...) or a negative errno
- * value. */
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_len)
-{
-    int err = 0;
-
-    memset(iecp, 0, sizeof(*iecp));
-    iecp->modese_len = modese_len;
-    iecp->requestedCurrent = 1;
-    if (iecp->modese_len <= 6) {
-        if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 iecp->raw_curr, sizeof(iecp->raw_curr)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                iecp->modese_len = 10;
-            else {
-                iecp->modese_len = 0;
-                return err;
-            }
-        } else if (0 == iecp->modese_len)
-            iecp->modese_len = 6;
-    }
-    if (10 == iecp->modese_len) {
-        err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
-                              MPAGE_CONTROL_CURRENT, 
-                              iecp->raw_curr, sizeof(iecp->raw_curr));
-        if (err) {
-            iecp->modese_len = 0;
-            return err;
-        }
-    } 
-    iecp->gotCurrent = 1;
-    iecp->requestedChangeable = 1;
-    if (10 == iecp->modese_len)
-        err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
-                                 MPAGE_CONTROL_CHANGEABLE,
-                                 iecp->raw_chg, sizeof(iecp->raw_chg));
-    else if (6 == iecp->modese_len)
-        err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE, 
-                            MPAGE_CONTROL_CHANGEABLE, 
-                            iecp->raw_chg, sizeof(iecp->raw_chg));
-    if (err)
-        return err;
-    iecp->gotChangeable = 1;
-    return 0;
-}
-
-int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp)
-{
-    int offset;
-
-    if (iecp && iecp->gotCurrent) {
-        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                    iecp->modese_len);
-        if (offset >= 0)
-            return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;
-        else
-            return 0;
-    } else
-        return 0;
-}
-
-int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
-{
-    int offset;
-
-    if (iecp && iecp->gotCurrent) {
-        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                    iecp->modese_len);
-        if (offset >= 0)
-            return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0;
-        else
-            return 0;
-    } else
-        return 0;
-}
-
-/* set EWASC and clear PERF, EBF, DEXCPT TEST and LOGERR */
-#define SCSI_IEC_MP_BYTE2_ENABLED 0x10 
-#define SCSI_IEC_MP_BYTE2_TEST_MASK 0x4
-/* exception/warning via an unrequested REQUEST SENSE command */
-#define SCSI_IEC_MP_MRIE 6      
-#define SCSI_IEC_MP_INTERVAL_T 0
-#define SCSI_IEC_MP_REPORT_COUNT 1
-
-/* Try to set (or clear) both Exception Control and Warning in the IE
- * mode page subject to the "changeable" mask. The object pointed to
- * by iecp is (possibly) inaccurate after this call, therefore
- * scsiFetchIECmpage() should be called again if the IEC mode page
- * is to be re-examined.
- * When -r ioctl is invoked 3 or more time on 'smartctl -s on ...'
- * then set the TEST bit (causes asc,ascq pair of 0x5d,0xff). */
-int scsiSetExceptionControlAndWarning(int device, int enabled,
-                                      const struct scsi_iec_mode_page *iecp)
-{
-    int k, offset, resp_len;
-    int err = 0;
-    UINT8 rout[SCSI_IECMP_RAW_LEN];
-    int sp, eCEnabled, wEnabled;
-
-    if ((! iecp) || (! iecp->gotCurrent))
-        return -EINVAL;
-    offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                iecp->modese_len);
-    if (offset < 0)
-        return -EINVAL;
-    memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
-    if (10 == iecp->modese_len) {
-            resp_len = (rout[0] << 8) + rout[1] + 2;
-            memset(rout, 0, 2); /* mode data length==0 for mode select */
-    } else {
-            resp_len = rout[0] + 1;
-            memset(rout, 0, 1); /* mode data length==0 for mode select */
-    }
-    sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
-    rout[offset] &= 0x7f;     /* mask off PS bit */
-    if (enabled) {
-        rout[offset + 2] = SCSI_IEC_MP_BYTE2_ENABLED;
-        if (con->reportscsiioctl > 2)
-            rout[offset + 2] |= SCSI_IEC_MP_BYTE2_TEST_MASK;
-        rout[offset + 3] = SCSI_IEC_MP_MRIE;
-        rout[offset + 4] = (SCSI_IEC_MP_INTERVAL_T >> 24) & 0xff;
-        rout[offset + 5] = (SCSI_IEC_MP_INTERVAL_T >> 16) & 0xff;
-        rout[offset + 6] = (SCSI_IEC_MP_INTERVAL_T >> 8) & 0xff;
-        rout[offset + 7] = SCSI_IEC_MP_INTERVAL_T & 0xff;
-        rout[offset + 8] = (SCSI_IEC_MP_REPORT_COUNT >> 24) & 0xff;
-        rout[offset + 9] = (SCSI_IEC_MP_REPORT_COUNT >> 16) & 0xff;
-        rout[offset + 10] = (SCSI_IEC_MP_REPORT_COUNT >> 8) & 0xff;
-        rout[offset + 11] = SCSI_IEC_MP_REPORT_COUNT & 0xff;
-        if (iecp->gotChangeable) {
-            UINT8 chg2 = iecp->raw_chg[offset + 2];
-
-            rout[offset + 2] = chg2 ? (rout[offset + 2] & chg2) :
-                                      iecp->raw_curr[offset + 2];
-            for (k = 3; k < 12; ++k) {
-                if (0 == iecp->raw_chg[offset + k])
-                    rout[offset + k] = iecp->raw_curr[offset + k];
-            }
-        }
-        if (0 == memcmp(&rout[offset + 2], &iecp->raw_chg[offset + 2], 10)) {
-            if (con->reportscsiioctl > 0)
-                pout("scsiSetExceptionControlAndWarning: already enabled\n");
-            return 0;
-        }
-    } else { /* disabling Exception Control and (temperature) Warnings */
-        eCEnabled = (rout[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;
-        wEnabled = (rout[offset + 2] & EWASC_ENABLE) ? 1 : 0;
-        if ((! eCEnabled) && (! wEnabled)) {
-            if (con->reportscsiioctl > 0)
-                pout("scsiSetExceptionControlAndWarning: already disabled\n");
-            return 0;   /* nothing to do, leave other setting alone */
-        }
-        if (wEnabled) 
-            rout[offset + 2] &= EWASC_DISABLE;
-        if (eCEnabled) {
-            if (iecp->gotChangeable && 
-                (iecp->raw_chg[offset + 2] & DEXCPT_ENABLE))
-                rout[offset + 2] |= DEXCPT_ENABLE;
-                rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */
-        }
-    }
-    if (10 == iecp->modese_len)
-        err = scsiModeSelect10(device, sp, rout, resp_len);
-    else if (6 == iecp->modese_len)
-        err = scsiModeSelect(device, sp, rout, resp_len);
-    return err;
-}
-
-int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
-{
-    UINT8 tBuf[252];
-    int err;
-
-    memset(tBuf, 0, sizeof(tBuf));
-    if ((err = scsiLogSense(device, TEMPERATURE_LPAGE, tBuf, 
-                            sizeof(tBuf), 0))) {
-        *currenttemp = 0;
-        *triptemp = 0;
-        pout("Log Sense for temperature failed [%s]\n", scsiErrString(err));
-        return err;
-    }
-    *currenttemp = tBuf[9];
-    *triptemp = tBuf[15];
-    return 0;
-}
-
-/* Read informational exception log page or Request Sense response.
- * Fetching asc/ascq code potentially flagging an exception or warning.
- * Returns 0 if ok, else error number. A current temperature of 255
- * (Celsius) implies that the temperature not available. */
-int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
-                UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp,
-                UINT8 *triptemp)
-{
-    UINT8 tBuf[252];
-    struct scsi_sense_disect sense_info;
-    int err;
-    int temperatureSet = 0;
-    unsigned short pagesize;
-    UINT8 currTemp, trTemp;
- 
-    *asc = 0;
-    *ascq = 0;
-    *currenttemp = 0;
-    *triptemp = 0;
-    memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk
-    memset(&sense_info, 0, sizeof(sense_info));
-    if (hasIELogPage) {
-        if ((err = scsiLogSense(device, IE_LPAGE, tBuf, 
-                                sizeof(tBuf), 0))) {
-            pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
-            return err;
-        }
-        // pull out page size from response, don't forget to add 4
-        pagesize = (unsigned short) ((tBuf[2] << 8) | tBuf[3]) + 4; 
-        if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
-            pout("Log Sense failed, IE page, bad parameter code or length\n");
-            return SIMPLE_ERR_BAD_PARAM;
-        }
-        if (tBuf[7] > 1) {
-            sense_info.asc = tBuf[8]; 
-            sense_info.ascq = tBuf[9];
-            if (! hasTempLogPage) {
-                if (tBuf[7] > 2) 
-                    *currenttemp = tBuf[10];
-                if (tBuf[7] > 3)        /* IBM extension in SMART (IE) lpage */
-                    *triptemp = tBuf[11];
-            }
-        } 
-    }
-    if (0 == sense_info.asc) {    
-        /* ties in with MRIE field of 6 in IEC mode page (0x1c) */
-        if ((err = scsiRequestSense(device, &sense_info))) {
-            pout("Request Sense failed, [%s]\n", scsiErrString(err));
-            return err;
-        }
-    }
-    *asc = sense_info.asc;
-    *ascq = sense_info.ascq;
-    if ((! temperatureSet) && hasTempLogPage) {
-        if (0 == scsiGetTemp(device, &currTemp, &trTemp)) {
-            *currenttemp = currTemp;
-            *triptemp = trTemp;
-        }
-    }
-    return 0;
-}
-
-// The first character (W, C, I) tells the severity
-static const char * TapeAlertsMessageTable[]= {  
-    " ",
-    /* 0x01 */
-   "W: The tape drive is having problems reading data. No data has been lost,\n"
-       "  but there has been a reduction in the performance of the tape.",
-    /* 0x02 */
-   "W: The tape drive is having problems writing data. No data has been lost,\n"
-       "  but there has been a reduction in the capacity of the tape.",
-    /* 0x03 */
-   "W: The operation has stopped because an error has occurred while reading\n"
-       "  or writing data that the drive cannot correct.",
-    /* 0x04 */
-   "C: Your data is at risk:\n"
-       "  1. Copy any data you require from this tape. \n"
-       "  2. Do not use this tape again.\n"
-       "  3. Restart the operation with a different tape.",
-    /* 0x05 */
-   "C: The tape is damaged or the drive is faulty. Call the tape drive\n"
-       "  supplier helpline.",
-    /* 0x06 */
-   "C: The tape is from a faulty batch or the tape drive is faulty:\n"
-       "  1. Use a good tape to test the drive.\n"
-       "  2. If problem persists, call the tape drive supplier helpline.",
-    /* 0x07 */
-   "W: The tape cartridge has reached the end of its calculated useful life:\n"
-       "  1. Copy data you need to another tape.\n"
-       "  2. Discard the old tape.",
-    /* 0x08 */
-   "W: The tape cartridge is not data-grade. Any data you back up to the tape\n"
-       "  is at risk. Replace the cartridge with a data-grade tape.",
-    /* 0x09 */
-   "C: You are trying to write to a write-protected cartridge. Remove the\n"
-       "  write-protection or use another tape.",
-    /* 0x0a */
-   "I: You cannot eject the cartridge because the tape drive is in use. Wait\n"
-       "  until the operation is complete before ejecting the cartridge.",
-    /* 0x0b */
-   "I: The tape in the drive is a cleaning cartridge.",
-    /* 0x0c */
-   "I: You have tried to load a cartridge of a type which is not supported\n"
-       "  by this drive.",
-    /* 0x0d */
-   "C: The operation has failed because the tape in the drive has experienced\n"
-       "  a mechanical failure:\n"
-       "  1. Discard the old tape.\n"
-       "  2. Restart the operation with a different tape.",
-    /* 0x0e */
-   "C: The operation has failed because the tape in the drive has experienced\n"
-       "  a mechanical failure:\n"
-       "  1. Do not attempt to extract the tape cartridge\n"
-       "  2. Call the tape drive supplier helpline.",
-    /* 0x0f */
-   "W: The memory in the tape cartridge has failed, which reduces\n"
-       "  performance. Do not use the cartridge for further write operations.",
-    /* 0x10 */
-   "C: The operation has failed because the tape cartridge was manually\n"
-       "  de-mounted while the tape drive was actively writing or reading.",
-    /* 0x11 */
-   "W: You have loaded a cartridge of a type that is read-only in this drive.\n"
-       "  The cartridge will appear as write-protected.",
-    /* 0x12 */
-   "W: The tape directory on the tape cartridge has been corrupted. File\n"
-       "  search performance will be degraded. The tape directory can be rebuilt\n"
-       "  by reading all the data on the cartridge.",
-    /* 0x13 */
-   "I: The tape cartridge is nearing the end of its calculated life. It is\n"
-       "  recommended that you:\n"
-       "  1. Use another tape cartridge for your next backup.\n"
-       "  2. Store this tape in a safe place in case you need to restore "
-       "  data from it.",
-    /* 0x14 */
-   "C: The tape drive needs cleaning:\n"
-       "  1. If the operation has stopped, eject the tape and clean the drive.\n"
-       "  2. If the operation has not stopped, wait for it to finish and then\n"
-       "  clean the drive.\n"
-       "  Check the tape drive users manual for device specific cleaning instructions.",
-    /* 0x15 */
-   "W: The tape drive is due for routine cleaning:\n"
-       "  1. Wait for the current operation to finish.\n"
-       "  2. The use a cleaning cartridge.\n"
-       "  Check the tape drive users manual for device specific cleaning instructions.",
-    /* 0x16 */
-   "C: The last cleaning cartridge used in the tape drive has worn out:\n"
-       "  1. Discard the worn out cleaning cartridge.\n"
-       "  2. Wait for the current operation to finish.\n"
-       "  3. Then use a new cleaning cartridge.",
-    /* 0x17 */
-   "C: The last cleaning cartridge used in the tape drive was an invalid\n"
-       "  type:\n"
-       "  1. Do not use this cleaning cartridge in this drive.\n"
-       "  2. Wait for the current operation to finish.\n"
-       "  3. Then use a new cleaning cartridge.",
-    /* 0x18 */
-   "W: The tape drive has requested a retention operation",
-    /* 0x19 */
-   "W: A redundant interface port on the tape drive has failed",
-    /* 0x1a */
-   "W: A tape drive cooling fan has failed",
-    /* 0x1b */
-   "W: A redundant power supply has failed inside the tape drive enclosure.\n"
-       "  Check the enclosure users manual for instructions on replacing the\n"
-       "  failed power supply.",
-    /* 0x1c */
-   "W: The tape drive power consumption is outside the specified range.",
-    /* 0x1d */
-   "W: Preventive maintenance of the tape drive is required. Check the tape\n"
-       "  drive users manual for device specific preventive maintenance\n"
-       "  tasks or call the tape drive supplier helpline.",
-    /* 0x1e */
-   "C: The tape drive has a hardware fault:\n"
-       "  1. Eject the tape or magazine.\n"
-       "  2. Reset the drive.\n"
-       "  3. Restart the operation.",
-    /* 0x1f */
-   "C: The tape drive has a hardware fault:\n"
-       "  1. Turn the tape drive off and then on again.\n"
-       "  2. Restart the operation.\n"
-    "  3. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x20 */
-   "W: The tape drive has a problem with the application client interface:\n"
-       "  1. Check the cables and cable connections.\n"
-       "  2. Restart the operation.",
-    /* 0x21 */
-   "C: The operation has failed:\n"
-       "  1. Eject the tape or magazine.\n"
-       "  2. Insert the tape or magazine again.\n"
-       "  3. Restart the operation.",
-    /* 0x22 */
-   "W: The firmware download has failed because you have tried to use the\n"
-       "  incorrect firmware for this tape drive. Obtain the correct\n"
-       "  firmware and try again.",
-    /* 0x23 */
-   "W: Environmental conditions inside the tape drive are outside the\n"
-       "  specified humidity range.",
-    /* 0x24 */
-   "W: Environmental conditions inside the tape drive are outside the\n"
-       "  specified temperature range.",
-    /* 0x25 */
-   "W: The voltage supply to the tape drive is outside the specified range.",
-    /* 0x26 */
-   "C: A hardware failure of the tape drive is predicted. Call the tape\n"
-       "  drive supplier helpline.",
-    /* 0x27 */
-   "W: The tape drive may have a hardware fault. Run extended diagnostics to\n"
-       "  verify and diagnose the problem. Check the tape drive users manual for\n"
-       "  device specific instructions on running extended diagnostic tests.",
-    /* 0x28 */
-   "C: The changer mechanism is having difficulty communicating with the tape\n"
-       "  drive:\n"
-       "  1. Turn the autoloader off then on.\n"
-       "  2. Restart the operation.\n"
-       "  3. If problem persists, call the tape drive supplier helpline.",
-    /* 0x29 */
-   "C: A tape has been left in the autoloader by a previous hardware fault:\n"
-       "  1. Insert an empty magazine to clear the fault.\n"
-       "  2. If the fault does not clear, turn the autoloader off and then\n"
-       "  on again.\n"
-       "  3. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x2a */
-   "W: There is a problem with the autoloader mechanism.",
-    /* 0x2b */
-   "C: The operation has failed because the autoloader door is open:\n"
-       "  1. Clear any obstructions from the autoloader door.\n"
-       "  2. Eject the magazine and then insert it again.\n"
-       "  3. If the fault does not clear, turn the autoloader off and then\n"
-       "  on again.\n"
-       "  4. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x2c */
-   "C: The autoloader has a hardware fault:\n"
-       "  1. Turn the autoloader off and then on again.\n"
-       "  2. Restart the operation.\n"
-       "  3. If the problem persists, call the tape drive supplier helpline.\n"
-       "  Check the autoloader users manual for device specific instructions\n"
-       "  on turning the device power on and off.",
-    /* 0x2d */
-   "C: The autoloader cannot operate without the magazine,\n"
-       "  1. Insert the magazine into the autoloader.\n"
-       "  2. Restart the operation.",
-    /* 0x2e */
-   "W: A hardware failure of the changer mechanism is predicted. Call the\n"
-       "  tape drive supplier helpline.",
-    /* 0x2f */
-   "I: Reserved.",
-    /* 0x30 */
-   "I: Reserved.",
-    /* 0x31 */
-   "I: Reserved.",
-    /* 0x32 */
-   "W: Media statistics have been lost at some time in the past",
-    /* 0x33 */
-   "W: The tape directory on the tape cartridge just unloaded has been\n"
-       "  corrupted. File search performance will be degraded. The tape\n"
-       "  directory can be rebuilt by reading all the data.",
-    /* 0x34 */
-   "C: The tape just unloaded could not write its system area successfully:\n"
-       "  1. Copy data to another tape cartridge.\n"
-       "  2. Discard the old cartridge.",
-    /* 0x35 */
-   "C: The tape system are could not be read successfully at load time:\n"
-    "  1. Copy data to another tape cartridge.\n",
-    /* 0x36 */
-   "C: The start or data could not be found on the tape:\n"
-       "  1. Check you are using the correct format tape.\n"
-       "  2. Discard the tape or return the tape to your supplier",
-    /* 0x37 */
-    "C: The operation has failed because the media cannot be loaded\n"
-        "  and threaded.\n"
-        "  1. Remove the cartridge, inspect it as specified in the product\n"
-        "  manual, and retry the operation.\n"
-        "  2. If the problem persists, call the tape drive supplier help line.",
-    /* 0x38 */
-    "C: The operation has failed because the medium cannot be unloaded:\n"
-        "  1. Do not attempt to extract the tape cartridge.\n"
-        "  2. Call the tape driver supplier help line.",
-    /* 0x39 */
-    "C: The tape drive has a problem with the automation interface:\n"
-        "  1. Check the power to the automation system.\n"
-        "  2. Check the cables and cable connections.\n"
-        "  3. Call the supplier help line if problem persists.",
-    /* 0x3a */
-    "W: The tape drive has reset itself due to a detected firmware\n"
-        "  fault. If problem persists, call the supplier help line.",
-    };
-
-const char * scsiTapeAlertsTapeDevice(unsigned short code)
-{
-    const int num = sizeof(TapeAlertsMessageTable) /
-                        sizeof(TapeAlertsMessageTable[0]);
-
-    return (code < num) ?  TapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-// The first character (W, C, I) tells the severity
-static const char * ChangerTapeAlertsMessageTable[]= {  
-    " ",
-    /* 0x01 */
-    "C: The library mechanism is having difficulty communicating with the\n"
-        "  drive:\n"
-        "  1. Turn the library off then on.\n"
-        "  2. Restart the operation.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x02 */
-    "W: There is a problem with the library mechanism. If problem persists,\n"
-        "  call the library supplier help line.",
-    /* 0x03 */
-    "C: The library has a hardware fault:\n"
-        "  1. Reset the library.\n"
-        "  2. Restart the operation.\n"
-        "  Check the library users manual for device specific instructions on resetting\n"
-        "  the device.",
-    /* 0x04 */
-    "C: The library has a hardware fault:\n"
-        "  1. Turn the library off then on again.\n"
-        "  2. Restart the operation.\n"
-        "  3. If the problem persists, call the library supplier help line.\n"
-        "  Check the library users manual for device specific instructions on turning the\n"
-        "  device power on and off.",
-    /* 0x05 */
-    "W: The library mechanism may have a hardware fault.\n"
-        "  Run extended diagnostics to verify and diagnose the problem. Check the library\n"
-        "  users manual for device specific instructions on running extended diagnostic\n"
-        "  tests.",
-    /* 0x06 */
-    "C: The library has a problem with the host interface:\n"
-        "  1. Check the cables and connections.\n"
-        "  2. Restart the operation.",
-    /* 0x07 */
-    "W: A hardware failure of the library is predicted. Call the library\n"
-        "  supplier help line.",
-    /* 0x08 */
-    "W: Preventive maintenance of the library is required.\n"
-        "  Check the library users manual for device specific preventative maintenance\n"
-        "  tasks, or call your library supplier help line.",
-    /* 0x09 */
-    "C: General environmental conditions inside the library are outside the\n"
-        "  specified humidity range.",
-    /* 0x0a */
-    "C: General environmental conditions inside the library are outside the\n"
-        "  specified temperature range.",
-    /* 0x0b */
-    "C: The voltage supply to the library is outside the specified range.\n"
-        "  There is a potential problem with the power supply or failure of\n"
-        "  a redundant power supply.",
-    /* 0x0c */
-    "C: A cartridge has been left inside the library by a previous hardware\n"
-        "  fault:\n"
-        "  1. Insert an empty magazine to clear the fault.\n"
-        "  2. If the fault does not clear, turn the library off and then on again.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x0d */
-    "W: There is a potential problem with the drive ejecting cartridges or\n"
-        "  with the library mechanism picking a cartridge from a slot.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x0e */
-    "W: There is a potential problem with the library mechanism placing a\n"
-        "  cartridge into a slot.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x0f */
-    "W: There is a potential problem with the drive or the library mechanism\n"
-        "  loading cartridges, or an incompatible cartridge.",
-    /* 0x10 */
-    "C: The library has failed because the door is open:\n"
-        "  1. Clear any obstructions from the library door.\n"
-        "  2. Close the library door.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x11 */
-    "C: There is a mechanical problem with the library media import/export\n"
-        "  mailslot.",
-    /* 0x12 */
-    "C: The library cannot operate without the magazine.\n"
-        "  1. Insert the magazine into the library.\n"
-        "  2. Restart the operation.",
-    /* 0x13 */
-    "W: Library security has been compromised.",
-    /* 0x14 */
-    "I: The library security mode has been changed.\n"
-        "  The library has either been put into secure mode, or the library has exited\n"
-        "  the secure mode.\n"
-        "  This is for information purposes only. No action is required.",
-    /* 0x15 */
-    "I: The library has been manually turned offline and is unavailable for use.",
-    /* 0x16 */
-    "I: A drive inside the library has been taken offline.\n"
-        "  This is for information purposes only. No action is required.",
-    /* 0x17 */
-    "W: There is a potential problem with the bar code label or the scanner\n"
-        "  hardware in the library mechanism.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x18 */
-    "C: The library has detected an inconsistency in its inventory.\n"
-        "  1. Redo the library inventory to correct inconsistency.\n"
-        "  2. Restart the operation.\n"
-        "  Check the applications users manual or the hardware users manual for\n"
-        "  specific instructions on redoing the library inventory.",
-    /* 0x19 */
-    "W: A library operation has been attempted that is invalid at this time.",
-    /* 0x1a */
-    "W: A redundant interface port on the library has failed.",
-    /* 0x1b */
-    "W: A library cooling fan has failed.",
-    /* 0x1c */
-    "W: A redundant power supply has failed inside the library. Check the\n"
-        "  library users manual for instructions on replacing the failed power supply.",
-    /* 0x1d */
-    "W: The library power consumption is outside the specified range.",
-    /* 0x1e */
-    "C: A failure has occurred in the cartridge pass-through mechanism between\n"
-        "  two library modules.",
-    /* 0x1f */
-    "C: A cartridge has been left in the pass-through mechanism from a\n"
-        "  previous hardware fault. Check the library users guide for instructions on\n"
-        "  clearing this fault.",
-    /* 0x20 */
-    "I: The library was unable to read the bar code on a cartridge.",
-};
-
-const char * scsiTapeAlertsChangerDevice(unsigned short code)
-{
-    const int num = sizeof(ChangerTapeAlertsMessageTable) /
-                        sizeof(ChangerTapeAlertsMessageTable[0]);
-
-    return (code < num) ?  ChangerTapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-
-/* this is a subset of the SCSI additional sense code strings indexed
- * by "ascq" for the case when asc==SCSI_ASC_IMPENDING_FAILURE (0x5d)
- */
-static const char * strs_for_asc_5d[] = {
-   /* 0x00 */   "FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-   /* 0x10 */   "HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "HARDWARE IMPENDING FAILURE CONTROLLER DETECTED",
-        "HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x20 */   "CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED",
-        "CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x30 */   "DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED",
-        "DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x40 */   "SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "SERVO IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "SERVO IMPENDING FAILURE CONTROLLER DETECTED",
-        "SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x50 */   "SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "SPINDLE IMPENDING FAILURE CONTROLLER DETECTED",
-        "SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x60 */   "FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED",
-        "FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-   /* 0x6c */   "FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"};
-
-
-/* this is a subset of the SCSI additional sense code strings indexed
- *  * by "ascq" for the case when asc==SCSI_ASC_WARNING (0xb)
- *   */
-static const char * strs_for_asc_b[] = {
-       /* 0x00 */   "WARNING",
-               "WARNING - SPECIFIED TEMPERATURE EXCEEDED",
-               "WARNING - ENCLOSURE DEGRADED"};
-
-static char spare_buff[128];
-
-const char * scsiGetIEString(UINT8 asc, UINT8 ascq)
-{
-    const char * rp;
-
-    if (SCSI_ASC_IMPENDING_FAILURE == asc) {
-        if (ascq == 0xff)
-            return "FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)";
-        else if (ascq < 
-                 (sizeof(strs_for_asc_5d) / sizeof(strs_for_asc_5d[0]))) {
-            rp = strs_for_asc_5d[ascq];
-            if (strlen(rp) > 0)
-                return rp;
-        }
-        snprintf(spare_buff, sizeof(spare_buff),
-                 "FAILURE PREDICTION THRESHOLD EXCEEDED: ascq=0x%x", ascq);
-        return spare_buff;
-    } else if (SCSI_ASC_WARNING == asc) {
-        if (ascq < (sizeof(strs_for_asc_b) / sizeof(strs_for_asc_b[0]))) {
-            rp = strs_for_asc_b[ascq];
-            if (strlen(rp) > 0)
-                return rp;
-        }
-        snprintf(spare_buff, sizeof(spare_buff), "WARNING: ascq=0x%x", ascq);
-        return spare_buff;
-    }
-    return NULL;        /* not a IE additional sense code */
-}
-
-
-/* This is not documented in t10.org, page 0x80 is vendor specific */
-/* Some IBM disks do an offline read-scan when they get this command. */
-int scsiSmartIBMOfflineTest(int device)
-{       
-    UINT8 tBuf[256];
-        
-    memset(tBuf, 0, sizeof(tBuf));
-    /* Build SMART Off-line Immediate Diag Header */
-    tBuf[0] = 0x80; /* Page Code */
-    tBuf[1] = 0x00; /* Reserved */
-    tBuf[2] = 0x00; /* Page Length MSB */
-    tBuf[3] = 0x04; /* Page Length LSB */
-    tBuf[4] = 0x03; /* SMART Revision */
-    tBuf[5] = 0x00; /* Reserved */
-    tBuf[6] = 0x00; /* Off-line Immediate Time MSB */
-    tBuf[7] = 0x00; /* Off-line Immediate Time LSB */
-    return scsiSendDiagnostic(device, SCSI_DIAG_NO_SELF_TEST, tBuf, 8);
-}
-
-int scsiSmartDefaultSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_DEF_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartShortSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_BG_SHORT_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartExtendSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_BG_EXTENDED_SELF_TEST, 
-                              NULL, 0);
-}
-
-int scsiSmartShortCapSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_FG_SHORT_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartExtendCapSelfTest(int device)
-{
-    return scsiSendDiagnostic(device, SCSI_DIAG_FG_EXTENDED_SELF_TEST, 
-                              NULL, 0);
-}
-
-int scsiSmartSelfTestAbort(int device)
-{
-    return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0);
-}
-
-/* Returns 0 and the expected duration of an extended self test (in seconds)
-   if successful; any other return value indicates a failure. */
-int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
-{
-    int err, offset, res;
-    UINT8 buff[64];
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return err;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, 
-                              MPAGE_CONTROL_CURRENT, 
-                              buff, sizeof(buff));
-        if (err)
-            return err;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if (offset < 0)
-        return -EINVAL;
-    if (buff[offset + 1] >= 0xa) {
-        res = (buff[offset + 10] << 8) | buff[offset + 11];
-        *durationSec = res;
-        return 0;
-    }
-    else
-        return -EINVAL;
-}
-
-void scsiDecodeErrCounterPage(unsigned char * resp, 
-                              struct scsiErrorCounter *ecp)
-{
-    int k, j, num, pl, pc;
-    unsigned char * ucp;
-    unsigned char * xp;
-    uint64_t * ullp;
-
-    memset(ecp, 0, sizeof(*ecp));
-    num = (resp[2] << 8) | resp[3];
-    ucp = &resp[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-            case 0: 
-            case 1: 
-            case 2: 
-            case 3: 
-            case 4: 
-            case 5: 
-            case 6: 
-                ecp->gotPC[pc] = 1;
-                ullp = &ecp->counter[pc];
-                break;
-        default: 
-                ecp->gotExtraPC = 1;
-                ullp = &ecp->counter[7];
-                break;
-        }
-        k = pl - 4;
-        xp = ucp + 4;
-        if (k > (int)sizeof(*ullp)) {
-            xp += (k - sizeof(*ullp));
-            k = sizeof(*ullp);
-        }
-        *ullp = 0;
-        for (j = 0; j < k; ++j) {
-            if (j > 0)
-                *ullp <<= 8;
-            *ullp |= xp[j];
-        }
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-void scsiDecodeNonMediumErrPage(unsigned char *resp, 
-                                struct scsiNonMediumError *nmep)
-{
-    int k, j, num, pl, pc, szof;
-    unsigned char * ucp;
-    unsigned char * xp;
-
-    memset(nmep, 0, sizeof(*nmep));
-    num = (resp[2] << 8) | resp[3];
-    ucp = &resp[0] + 4;
-    szof = sizeof(nmep->counterPC0);
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-            case 0: 
-                nmep->gotPC0 = 1;
-                k = pl - 4;
-                xp = ucp + 4;
-                if (k > szof) {
-                    xp += (k - szof);
-                    k = szof;
-                }
-                nmep->counterPC0 = 0;
-                for (j = 0; j < k; ++j) {
-                    if (j > 0)
-                        nmep->counterPC0 <<= 8;
-                    nmep->counterPC0 |= xp[j];
-                }
-                break;
-        default: 
-                nmep->gotExtraPC = 1;
-                break;
-        }
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-/* Counts number of failed self-tests. Also encodes the poweron_hour
-   of the most recent failed self-test. Return value is negative if
-   this function has a problem (typically -1), otherwise the bottom 8
-   bits are the number of failed self tests and the 16 bits above that
-   are the poweron hour of the most recent failure. Note: aborted self
-   tests (typically by the user) and self tests in progress are not 
-   considered failures. See Working Draft SCSI Primary Commands - 3 
-   (SPC-3) section 7.2.10 T10/1416-D Rev 15 */
-int scsiCountFailedSelfTests(int fd, int noisy)
-{
-    int num, k, n, err, res, fails, fail_hour;
-    UINT8 * ucp;
-    unsigned char resp[LOG_RESP_SELF_TEST_LEN];
-
-    if ((err = scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, resp, 
-                            LOG_RESP_SELF_TEST_LEN, 0))) {
-        if (noisy)
-            pout("scsiCountSelfTests Failed [%s]\n", scsiErrString(err));
-        return -1;
-    }
-    if (resp[0] != SELFTEST_RESULTS_LPAGE) {
-        if (noisy)
-            pout("Self-test Log Sense Failed, page mismatch\n");
-        return -1;
-    }
-    // compute page length
-    num = (resp[2] << 8) + resp[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        if (noisy)
-            pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n", num);
-        return -1;
-    }
-    fails = 0;
-    fail_hour = 0;
-    // loop through the twenty possible entries
-    for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
-
-        // timestamp in power-on hours (or zero if test in progress)
-        n = (ucp[6] << 8) | ucp[7];
-
-        // The spec says "all 20 bytes will be zero if no test" but
-        // DG has found otherwise.  So this is a heuristic.
-        if ((0 == n) && (0 == ucp[4]))
-            break;
-        res = ucp[4] & 0xf;
-        if ((res > 2) && (res < 8)) {
-            fails++;
-            if (1 == fails) 
-                fail_hour = (ucp[6] << 8) + ucp[7];
-        }
-    }
-    return (fail_hour << 8) + fails;
-}
-
-/* Returns 0 if able to read self test log page; then outputs 1 into
-   *inProgress if self test still in progress, else outputs 0. */
-int scsiSelfTestInProgress(int fd, int * inProgress)
-{
-    int num;
-    UINT8 * ucp;
-    unsigned char resp[LOG_RESP_SELF_TEST_LEN];
-
-    if (scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, resp, 
-                     LOG_RESP_SELF_TEST_LEN, 0))
-        return -1;
-    if (resp[0] != SELFTEST_RESULTS_LPAGE)
-        return -1;
-    // compute page length
-    num = (resp[2] << 8) + resp[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        return -1;
-    }
-    ucp = resp + 4;
-    if (inProgress)
-        *inProgress = (0xf == (ucp[4] & 0xf)) ? 1 : 0;
-    return 0;
-}
-
-/* Returns a negative value if failed to fetch Contol mode page or it was
-   malformed. Returns 0 if GLTSD bit is zero and returns 1 if the GLTSD
-   bit is set. Examines default mode page when current==0 else examines
-   current mode page. */
-int scsiFetchControlGLTSD(int device, int modese_len, int current)
-{
-    int err, offset;
-    UINT8 buff[64];
-    int pc = current ? MPAGE_CONTROL_CURRENT : MPAGE_CONTROL_DEFAULT;
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, pc, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return -EINVAL;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, pc,
-                              buff, sizeof(buff));
-        if (err)
-            return -EINVAL;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if ((offset >= 0) && (buff[offset + 1] >= 0xa))
-        return (buff[offset + 2] & 2) ? 1 : 0;
-    return -EINVAL;
-}
-
-/* Attempts to set or clear GLTSD bit in Control mode page. If enabled is
-   0 attempts to clear GLTSD otherwise it attempts to set it. Returns 0 if
-   successful, negative if low level error, > 0 if higher level error (e.g.
-   SIMPLE_ERR_BAD_PARAM if GLTSD bit is not changeable). */
-int scsiSetControlGLTSD(int device, int enabled, int modese_len)
-{
-    int err, offset, resp_len, sp;
-    UINT8 buff[64];
-    UINT8 ch_buff[64];
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return err;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, 
-                              MPAGE_CONTROL_CURRENT, 
-                              buff, sizeof(buff));
-        if (err)
-            return err;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if ((offset < 0) || (buff[offset + 1] < 0xa))
-        return SIMPLE_ERR_BAD_RESP;
-
-    if (enabled)
-        enabled = 2;
-    if (enabled == (buff[offset + 2] & 2))
-        return 0;       /* GLTSD already in wanted state so nothing to do */
-
-    if (modese_len == 6)
-        err = scsiModeSense(device, CONTROL_MODE_PAGE, 
-                            MPAGE_CONTROL_CHANGEABLE, 
-                            ch_buff, sizeof(ch_buff));
-    else
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, 
-                              MPAGE_CONTROL_CHANGEABLE, 
-                              ch_buff, sizeof(ch_buff));
-    if (err)
-        return err;
-    if (0 == (ch_buff[offset + 2] & 2))
-        return SIMPLE_ERR_BAD_PARAM;  /* GLTSD bit not chageable */
-    
-    if (10 == modese_len) {
-            resp_len = (buff[0] << 8) + buff[1] + 2;
-            memset(buff, 0, 2);
-    } else {
-            resp_len = buff[0] + 1;
-            memset(buff, 0, 1);
-    }
-    sp = (buff[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
-    buff[offset] &= 0x7f;     /* mask off PS bit */
-    if (enabled)
-        buff[offset + 2] |= 0x2;    /* set GLTSD bit */
-    else
-        buff[offset + 2] &= 0xfd;   /* clear GLTSD bit */
-    if (10 == modese_len)
-        err = scsiModeSelect10(device, sp, buff, resp_len);
-    else if (6 == modese_len)
-        err = scsiModeSelect(device, sp, buff, resp_len);
-    return err;
-}
-
-/* Returns a negative value if failed to fetch Protocol specific port mode 
-   page or it was malformed. Returns transport protocol identifier when
-   value >= 0 . */
-int scsiFetchTransportProtocol(int device, int modese_len)
-{
-    int err, offset;
-    UINT8 buff[64];
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, PROTOCOL_SPECIFIC_PORT_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return -EINVAL;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, PROTOCOL_SPECIFIC_PORT_PAGE, 
-                              MPAGE_CONTROL_CURRENT, 
-                              buff, sizeof(buff));
-        if (err)
-            return -EINVAL;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if ((offset >= 0) && (buff[offset + 1] > 1)) {
-        if ((0 == (buff[offset] & 0x40)) &&       /* SPF==0 */
-            (PROTOCOL_SPECIFIC_PORT_PAGE == (buff[offset] & 0x3f))) 
-                return (buff[offset + 2] & 0xf);
-    }
-    return -EINVAL;
-}
-
diff --git a/sm5/scsicmds.cpp b/sm5/scsicmds.cpp
deleted file mode 100644
index 6672a95e034d1d0f6ee5ebefa0c93a78978e49eb..0000000000000000000000000000000000000000
--- a/sm5/scsicmds.cpp
+++ /dev/null
@@ -1,1942 +0,0 @@
-/*
- * scsicmds.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003-4 Douglas Gilbert <dougg@torque.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- *
- * In the SCSI world "SMART" is a dead or withdrawn standard. In recent
- * SCSI standards (since SCSI-3) it goes under the awkward name of
- * "Informational Exceptions" ["IE" or "IEC" (with the "C" for "control")].
- * The relevant information is spread around several SCSI draft
- * standards available at http://www.t10.org . Reference is made in the
- * code to the following acronyms:
- *      - SAM [SCSI Architectural model, versions 2 or 3]
- *      - SPC [SCSI Primary commands, versions 2 or 3]
- *      - SBC [SCSI Block commands, versions 2]
- *
- * Some SCSI disk vendors have snippets of "SMART" information in their
- * product manuals.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "config.h"
-#include "int64.h"
-#include "extern.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.76 2004/07/11 15:16:31 dpgilbert Exp $"
-CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-/* for passing global control variables */
-extern smartmonctrl *con;
-
-/* output binary in hex and optionally ascii */
-void dStrHex(const char* str, int len, int no_ascii)
-{
-    const char* p = str;
-    unsigned char c;
-    char buff[82];
-    int a = 0;
-    const int bpstart = 5;
-    const int cpstart = 60;
-    int cpos = cpstart;
-    int bpos = bpstart;
-    int i, k;
-    
-    if (len <= 0) return;
-    memset(buff,' ',80);
-    buff[80]='\0';
-    k = sprintf(buff + 1, "%.2x", a);
-    buff[k + 1] = ' ';
-    if (bpos >= ((bpstart + (9 * 3))))
-        bpos++;
-
-    for(i = 0; i < len; i++)
-    {
-        c = *p++;
-        bpos += 3;
-        if (bpos == (bpstart + (9 * 3)))
-            bpos++;
-        sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c);
-        buff[bpos + 2] = ' ';
-        if (no_ascii)
-            buff[cpos++] = ' ';
-        else {
-            if ((c < ' ') || (c >= 0x7f))
-                c='.';
-            buff[cpos++] = c;
-        }
-        if (cpos > (cpstart+15))
-        {
-            pout("%s\n", buff);
-            bpos = bpstart;
-            cpos = cpstart;
-            a += 16;
-            memset(buff,' ',80);
-            k = sprintf(buff + 1, "%.2x", a);
-            buff[k + 1] = ' ';
-        }
-    }
-    if (cpos > cpstart)
-    {
-        pout("%s\n", buff);
-    }
-}
-
-struct scsi_opcode_name {
-    UINT8 opcode;
-    const char * name;
-};
-
-static struct scsi_opcode_name opcode_name_arr[] = {
-    /* in ascending opcode order */
-    {TEST_UNIT_READY, "test unit ready"},       /* 0x00 */
-    {REQUEST_SENSE, "request sense"},           /* 0x03 */
-    {INQUIRY, "inquiry"},                       /* 0x12 */
-    {MODE_SELECT, "mode select"},               /* 0x15 */
-    {MODE_SENSE, "mode sense"},                 /* 0x1a */
-    {RECEIVE_DIAGNOSTIC, "receive diagnostic"}, /* 0x1c */
-    {SEND_DIAGNOSTIC, "send diagnostic"},       /* 0x1d */
-    {LOG_SENSE, "log sense"},                   /* 0x4d */
-    {MODE_SELECT_10, "mode select(10)"},        /* 0x55 */
-    {MODE_SENSE_10, "mode sense(10)"},          /* 0x5a */
-};
-
-const char * scsi_get_opcode_name(UINT8 opcode)
-{
-    int k;
-    int len = sizeof(opcode_name_arr) / sizeof(opcode_name_arr[0]);
-    struct scsi_opcode_name * onp;
-
-    for (k = 0; k < len; ++k) {
-        onp = &opcode_name_arr[k];
-        if (opcode == onp->opcode)
-            return onp->name;
-        else if (opcode < onp->opcode)
-            return NULL;
-    }
-    return NULL;
-}
-
-
-void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
-                          struct scsi_sense_disect * out)
-{
-    memset(out, 0, sizeof(struct scsi_sense_disect));
-    if ((SCSI_STATUS_CHECK_CONDITION == io_buf->scsi_status) && 
-        (io_buf->resp_sense_len > 7)) {  
-        out->error_code = (io_buf->sensep[0] & 0x7f);
-        out->sense_key = (io_buf->sensep[2] & 0xf);
-        if (io_buf->resp_sense_len > 13) {
-            out->asc = io_buf->sensep[12];
-            out->ascq = io_buf->sensep[13];
-        }
-    }
-}
-
-static int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo)
-{
-    if (SCSI_SK_NOT_READY == sinfo->sense_key) {
-        if (SCSI_ASC_NO_MEDIUM == sinfo->asc) 
-            return SIMPLE_ERR_NO_MEDIUM;
-        else if (SCSI_ASC_NOT_READY == sinfo->asc) {
-            if (0x1 == sinfo->ascq)
-                return SIMPLE_ERR_BECOMING_READY;
-            else
-                return SIMPLE_ERR_NOT_READY;
-        } else
-            return SIMPLE_ERR_NOT_READY;
-    } else if (SCSI_SK_ILLEGAL_REQUEST == sinfo->sense_key) {
-        if (SCSI_ASC_UNKNOWN_OPCODE == sinfo->asc)
-            return SIMPLE_ERR_BAD_OPCODE;
-        else if (SCSI_ASC_UNKNOWN_FIELD == sinfo->asc)
-            return SIMPLE_ERR_BAD_FIELD;
-        else if (SCSI_ASC_UNKNOWN_PARAM == sinfo->asc)
-            return SIMPLE_ERR_BAD_PARAM;
-    } else if (SCSI_SK_UNIT_ATTENTION == sinfo->sense_key)
-        return SIMPLE_ERR_TRY_AGAIN;
-    return SIMPLE_NO_ERROR;
-}
-
-const char * scsiErrString(int scsiErr)
-{
-    if (scsiErr < 0)
-        return strerror(-scsiErr);
-    switch (scsiErr) {
-        case SIMPLE_NO_ERROR: 
-            return "no error";
-        case SIMPLE_ERR_NOT_READY: 
-            return "device not ready";
-        case SIMPLE_ERR_BAD_OPCODE: 
-            return "unsupported scsi opcode";
-        case SIMPLE_ERR_BAD_FIELD: 
-            return "unsupported field in scsi command";
-        case SIMPLE_ERR_BAD_PARAM: 
-            return "badly formed scsi parameters";
-        case SIMPLE_ERR_BAD_RESP: 
-            return "scsi response fails sanity test";
-        case SIMPLE_ERR_NO_MEDIUM: 
-            return "no medium present";
-        case SIMPLE_ERR_BECOMING_READY: 
-            return "device will be ready soon";
-        case SIMPLE_ERR_TRY_AGAIN: 
-            return "unit attention reported, try again";
-        default:
-            return "unknown error";
-    }
-}
-
-/* Sends LOG SENSE command. Returns 0 if ok, 1 if device NOT READY, 2 if
-   command not supported, 3 if field (within command) not supported or
-   returns negated errno.  SPC sections 7.6 and 8.2 N.B. Sets PC==1
-   to fetch "current cumulative" log pages.
-   If known_resp_len > 0 then a single fetch is done for this response
-   length. If known_resp_len == 0 then twin fetches are performed, the
-   first to deduce the response length, then send the same command again
-   requesting the deduced response length. This protects certain fragile 
-   HBAs. The twin fetch technique should not be used with the TapeAlert
-   log page since it clears its state flags after each fetch. */
-int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
-                 int known_resp_len)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int pageLen;
-    int status, res;
-
-    if (known_resp_len > bufLen)
-        return -EIO;
-    if (known_resp_len > 0)
-        pageLen = known_resp_len;
-    else {
-        /* Starting twin fetch strategy: first fetch to find respone length */
-        pageLen = 4;
-        if (pageLen > bufLen)
-            return -EIO;
-        else
-            memset(pBuf, 0, pageLen);
-
-        memset(&io_hdr, 0, sizeof(io_hdr));
-        memset(cdb, 0, sizeof(cdb));
-        io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-        io_hdr.dxfer_len = pageLen;
-        io_hdr.dxferp = pBuf;
-        cdb[0] = LOG_SENSE;
-        cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-        cdb[7] = (pageLen >> 8) & 0xff;
-        cdb[8] = pageLen & 0xff;
-        io_hdr.cmnd = cdb;
-        io_hdr.cmnd_len = sizeof(cdb);
-        io_hdr.sensep = sense;
-        io_hdr.max_sense_len = sizeof(sense);
-        io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-    
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-            return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        if ((res = scsiSimpleSenseFilter(&sinfo)))
-            return res;
-        /* sanity check on response */
-        if ((SUPPORTED_LPAGES != pagenum) && (pBuf[0] != pagenum))
-            return SIMPLE_ERR_BAD_RESP;
-        if (0 == ((pBuf[2] << 8) + pBuf[3]))
-            return SIMPLE_ERR_BAD_RESP;
-        pageLen = (pBuf[2] << 8) + pBuf[3] + 4;
-        /* some SCSI HBA don't like "odd" length transfers */
-        if (pageLen % 2)
-            pageLen += 1;   
-        if (pageLen > bufLen)
-            pageLen = bufLen;
-    }
-    memset(pBuf, 0, 4);
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = pageLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = LOG_SENSE;
-    cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-    cdb[7] = (pageLen >> 8) & 0xff;
-    cdb[8] = pageLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (0 != status)
-        return status;
-    /* sanity check on response */
-    if ((SUPPORTED_LPAGES != pagenum) && (pBuf[0] != pagenum))
-        return SIMPLE_ERR_BAD_RESP;
-    if (0 == ((pBuf[2] << 8) + pBuf[3]))
-        return SIMPLE_ERR_BAD_RESP;
-    return 0;
-}
-
-/* Send MODE SENSE (6 byte) command. Returns 0 if ok, 1 if NOT READY,
- * 2 if command not supported (then MODE SENSE(10) should be supported),
- * 3 if field in command not supported or returns negated errno. 
- * SPC sections 7.9 and 8.4 [mode subpage==0] */
-int scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SENSE;
-    cdb[2] = (pc << 6) | (pagenum & 0x3f);
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-	return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (SIMPLE_ERR_TRY_AGAIN == status) {
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-	    return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        status = scsiSimpleSenseFilter(&sinfo);
-    }
-    if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {
-        int offset;
-
-        offset = scsiModePageOffset(pBuf, bufLen, 0);
-        if (offset < 0)
-            return SIMPLE_ERR_BAD_RESP;
-        else if (pagenum != (pBuf[offset] & 0x3f))
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return status;
-}
-
-/* Sends a 6 byte MODE SELECT command. Assumes given pBuf is the response
- * from a corresponding 6 byte MODE SENSE command. Such a response should
- * have a 4 byte header followed by 0 or more 8 byte block descriptors
- * (normally 1) and then 1 mode page. Returns 0 if ok, 1 if NOT READY,
- * 2 if command not supported (then MODE SELECT(10) may be supported), 
- * 3 if field in command not supported, 4 if bad parameter to command
- * or returns negated errno. SPC sections 7.7 and 8.4 */
-int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status, pg_offset, pg_len, hdr_plus_1_pg;
-
-    pg_offset = 4 + pBuf[3];
-    if (pg_offset + 2 >= bufLen)
-        return -EINVAL;
-    pg_len = pBuf[pg_offset + 1] + 2;
-    hdr_plus_1_pg = pg_offset + pg_len;
-    if (hdr_plus_1_pg > bufLen)
-        return -EINVAL;
-    pBuf[0] = 0;    /* Length of returned mode sense data reserved for SELECT */
-    pBuf[pg_offset] &= 0x3f;    /* Mask of PS bit from byte 0 of page data */
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_TO_DEVICE;
-    io_hdr.dxfer_len = hdr_plus_1_pg;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SELECT;
-    cdb[1] = 0x10 | (sp & 1);      /* set PF (page format) bit always */
-    cdb[4] = hdr_plus_1_pg; /* make sure only one page sent */
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* MODE SENSE (10 byte). Returns 0 if ok, 1 if NOT READY, 2 if command 
- * not supported (then MODE SENSE(6) might be supported), 3 if field in
- * command not supported or returns negated errno.  
- * SPC sections 7.10 and 8.4 [mode subpage==0] */
-int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SENSE_10;
-    cdb[2] = (pc << 6) | (pagenum & 0x3f);
-    cdb[7] = (bufLen >> 8) & 0xff;
-    cdb[8] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-	return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (SIMPLE_ERR_TRY_AGAIN == status) {
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-	    return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        status = scsiSimpleSenseFilter(&sinfo);
-    }
-    if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {
-        int offset;
-
-        offset = scsiModePageOffset(pBuf, bufLen, 1);
-        if (offset < 0)
-            return SIMPLE_ERR_BAD_RESP;
-        else if (pagenum != (pBuf[offset] & 0x3f))
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return status;
-}
-
-/* Sends a 10 byte MODE SELECT command. Assumes given pBuf is the response
- * from a corresponding 10 byte MODE SENSE command. Such a response should
- * have a 8 byte header followed by 0 or more 8 byte block descriptors
- * (normally 1) and then 1 mode page. Returns 0 if ok, 1 NOT REAFY, 2 if 
- * command not supported (then MODE SELECT(6) may be supported), 3 if field
- * in command not supported, 4 if bad parameter to command or returns
- * negated errno. SAM sections 7.8 and 8.4 */
-int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status, pg_offset, pg_len, hdr_plus_1_pg;
-
-    pg_offset = 8 + (pBuf[6] << 8) + pBuf[7];
-    if (pg_offset + 2 >= bufLen)
-        return -EINVAL;
-    pg_len = pBuf[pg_offset + 1] + 2;
-    hdr_plus_1_pg = pg_offset + pg_len;
-    if (hdr_plus_1_pg > bufLen)
-        return -EINVAL;
-    pBuf[0] = 0;    
-    pBuf[1] = 0; /* Length of returned mode sense data reserved for SELECT */
-    pBuf[pg_offset] &= 0x3f;    /* Mask of PS bit from byte 0 of page data */
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_TO_DEVICE;
-    io_hdr.dxfer_len = hdr_plus_1_pg;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SELECT_10;
-    cdb[1] = 0x10 | (sp & 1);      /* set PF (page format) bit always */
-    cdb[8] = hdr_plus_1_pg; /* make sure only one page sent */
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* Standard INQUIRY returns 0 for ok, anything else is a major problem.
- * bufLen should be 36 for unsafe devices (like USB mass storage stuff)
- * otherwise they can lock up! SPC sections 7.4 and 8.6 */
-int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_sense_disect sinfo;
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    int status;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = INQUIRY;
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* INQUIRY to fetch Vital Page Data.  Returns 0 if ok, 1 if NOT READY
- * (unlikely), 2 if command not supported, 3 if field in command not 
- * supported, 5 if response indicates that EVPD bit ignored or returns
- * negated errno. SPC section 7.4 and 8.6 */
-int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status, res;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    if (bufLen > 1)
-        pBuf[1] = 0x0;
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = INQUIRY;
-    cdb[1] = 0x1;       /* set EVPD bit (enable Vital Product Data) */
-    cdb[2] = vpd_page;
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    /* Guard against devices that ignore EVPD bit and do standard INQUIRY */
-    if (bufLen > 1) {
-        if (vpd_page == pBuf[1]) {
-            if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))
-                return SIMPLE_ERR_BAD_RESP;
-        } else
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return 0;
-}
-
-/* REQUEST SENSE command. Returns 0 if ok, anything else major problem.
- * SPC section 7.24 */
-int scsiRequestSense(int device, struct scsi_sense_disect * sense_info)
-{
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    UINT8 buff[18];
-    int status, len;
-    UINT8 ecode;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = sizeof(buff);
-    io_hdr.dxferp = buff;
-    cdb[0] = REQUEST_SENSE;
-    cdb[4] = sizeof(buff);
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if ((0 == status) && (sense_info)) {
-        ecode = buff[0] & 0x7f;
-        sense_info->error_code = ecode;
-        sense_info->sense_key = buff[2] & 0xf;
-        sense_info->asc = 0;
-        sense_info->ascq = 0;
-        if ((0x70 == ecode) || (0x71 == ecode)) {
-            len = buff[7] + 8;
-            if (len > 13) {
-                sense_info->asc = buff[12];
-                sense_info->ascq = buff[13];
-            }
-        }
-    }
-    return status;
-}
-
-/* SEND DIAGNOSTIC command.  Returns 0 if ok, 1 if NOT READY, 2 if command
- * not supported, 3 if field in command not supported or returns negated
- * errno. SPC section 7.25 */
-int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = bufLen ? DXFER_TO_DEVICE: DXFER_NONE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = SEND_DIAGNOSTIC;
-    if (SCSI_DIAG_DEF_SELF_TEST == functioncode)
-        cdb[1] = 0x4;  /* SelfTest bit */
-    else if (SCSI_DIAG_NO_SELF_TEST != functioncode)
-        cdb[1] = (functioncode & 0x7) << 5; /* SelfTest _code_ */
-    else   /* SCSI_DIAG_NO_SELF_TEST == functioncode */
-        cdb[1] = 0x10;  /* PF bit */
-    cdb[3] = (bufLen >> 8) & 0xff;
-    cdb[4] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_SELF_TEST;
-    /* worst case is an extended foreground self test on a big disk */
-    
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* RECEIVE DIAGNOSTIC command. Returns 0 if ok, 1 if NOT READY, 2 if
- * command not supported, 3 if field in command not supported or returns
- * negated errno. SPC section 7.17 */
-int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf, 
-                      int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = RECEIVE_DIAGNOSTIC;
-    cdb[1] = pcv;
-    cdb[2] = pagenum;
-    cdb[3] = (bufLen >> 8) & 0xff;
-    cdb[4] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* TEST UNIT READY command. SPC section 7.28 (probably in SBC as well) */
-static int _testunitready(int device, struct scsi_sense_disect * sinfo)
-{
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_NONE;
-    io_hdr.dxfer_len = 0;
-    io_hdr.dxferp = NULL;
-    cdb[0] = TEST_UNIT_READY;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, sinfo);
-    return 0;
-}
-
-/* Returns 0 for device responds and media ready, 1 for device responds and
-   media not ready, or returns a negated errno value */
-int scsiTestUnitReady(int device)
-{
-    struct scsi_sense_disect sinfo;
-    int status;
-
-    status = _testunitready(device, &sinfo);
-    if (0 != status)
-        return status;
-    status = scsiSimpleSenseFilter(&sinfo);
-    if (SIMPLE_ERR_TRY_AGAIN == status) {
-        /* power on reset, media changed, ok ... try again */
-        status = _testunitready(device, &sinfo);        
-        if (0 != status)
-            return status;
-        status = scsiSimpleSenseFilter(&sinfo);
-    }
-    return status;
-}
-
-/* Offset into mode sense (6 or 10 byte) response that actual mode page
- * starts at (relative to resp[0]). Returns -1 if problem */
-int scsiModePageOffset(const UINT8 * resp, int len, int modese_len)
-{
-    int resp_len, bd_len;
-    int offset = -1;
-
-    if (resp) {
-        if (10 == modese_len) {
-            resp_len = (resp[0] << 8) + resp[1] + 2;
-            bd_len = (resp[6] << 8) + resp[7];
-            offset = bd_len + 8;
-        } else {
-            resp_len = resp[0] + 1;
-            bd_len = resp[3];
-            offset = bd_len + 4;
-        }
-        if ((offset + 2) > len) {
-            pout("scsiModePageOffset: raw_curr too small, offset=%d "
-                 "resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);
-            offset = -1;
-        } else if ((offset + 2) > resp_len) {
-            pout("scsiModePageOffset: response length too short, resp_len=%d"
-                 " offset=%d bd_len=%d\n", resp_len, offset, bd_len);
-            offset = -1;
-        }
-    }
-    return offset;
-}
-
-/* IEC mode page byte 2 bit masks */
-#define DEXCPT_ENABLE   0x08
-#define EWASC_ENABLE    0x10
-#define DEXCPT_DISABLE  0xf7
-#define EWASC_DISABLE   0xef
-#define TEST_DISABLE    0xfb
-
-/* Fetches the Informational Exceptions Control mode page. First tries
- * the 6 byte MODE SENSE command and if that fails with an illegal opcode
- * tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive
- * number if a known error (see  SIMPLE_ERR_ ...) or a negative errno
- * value. */
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_len)
-{
-    int err = 0;
-
-    memset(iecp, 0, sizeof(*iecp));
-    iecp->modese_len = modese_len;
-    iecp->requestedCurrent = 1;
-    if (iecp->modese_len <= 6) {
-        if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 iecp->raw_curr, sizeof(iecp->raw_curr)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                iecp->modese_len = 10;
-            else {
-                iecp->modese_len = 0;
-                return err;
-            }
-        } else if (0 == iecp->modese_len)
-            iecp->modese_len = 6;
-    }
-    if (10 == iecp->modese_len) {
-        err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
-                              MPAGE_CONTROL_CURRENT, 
-                              iecp->raw_curr, sizeof(iecp->raw_curr));
-        if (err) {
-            iecp->modese_len = 0;
-            return err;
-        }
-    } 
-    iecp->gotCurrent = 1;
-    iecp->requestedChangeable = 1;
-    if (10 == iecp->modese_len)
-        err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
-                                 MPAGE_CONTROL_CHANGEABLE,
-                                 iecp->raw_chg, sizeof(iecp->raw_chg));
-    else if (6 == iecp->modese_len)
-        err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE, 
-                            MPAGE_CONTROL_CHANGEABLE, 
-                            iecp->raw_chg, sizeof(iecp->raw_chg));
-    if (err)
-        return err;
-    iecp->gotChangeable = 1;
-    return 0;
-}
-
-int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp)
-{
-    int offset;
-
-    if (iecp && iecp->gotCurrent) {
-        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                    iecp->modese_len);
-        if (offset >= 0)
-            return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;
-        else
-            return 0;
-    } else
-        return 0;
-}
-
-int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
-{
-    int offset;
-
-    if (iecp && iecp->gotCurrent) {
-        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                    iecp->modese_len);
-        if (offset >= 0)
-            return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0;
-        else
-            return 0;
-    } else
-        return 0;
-}
-
-/* set EWASC and clear PERF, EBF, DEXCPT TEST and LOGERR */
-#define SCSI_IEC_MP_BYTE2_ENABLED 0x10 
-#define SCSI_IEC_MP_BYTE2_TEST_MASK 0x4
-/* exception/warning via an unrequested REQUEST SENSE command */
-#define SCSI_IEC_MP_MRIE 6      
-#define SCSI_IEC_MP_INTERVAL_T 0
-#define SCSI_IEC_MP_REPORT_COUNT 1
-
-/* Try to set (or clear) both Exception Control and Warning in the IE
- * mode page subject to the "changeable" mask. The object pointed to
- * by iecp is (possibly) inaccurate after this call, therefore
- * scsiFetchIECmpage() should be called again if the IEC mode page
- * is to be re-examined.
- * When -r ioctl is invoked 3 or more time on 'smartctl -s on ...'
- * then set the TEST bit (causes asc,ascq pair of 0x5d,0xff). */
-int scsiSetExceptionControlAndWarning(int device, int enabled,
-                                      const struct scsi_iec_mode_page *iecp)
-{
-    int k, offset, resp_len;
-    int err = 0;
-    UINT8 rout[SCSI_IECMP_RAW_LEN];
-    int sp, eCEnabled, wEnabled;
-
-    if ((! iecp) || (! iecp->gotCurrent))
-        return -EINVAL;
-    offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                iecp->modese_len);
-    if (offset < 0)
-        return -EINVAL;
-    memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
-    if (10 == iecp->modese_len) {
-            resp_len = (rout[0] << 8) + rout[1] + 2;
-            memset(rout, 0, 2); /* mode data length==0 for mode select */
-    } else {
-            resp_len = rout[0] + 1;
-            memset(rout, 0, 1); /* mode data length==0 for mode select */
-    }
-    sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
-    rout[offset] &= 0x7f;     /* mask off PS bit */
-    if (enabled) {
-        rout[offset + 2] = SCSI_IEC_MP_BYTE2_ENABLED;
-        if (con->reportscsiioctl > 2)
-            rout[offset + 2] |= SCSI_IEC_MP_BYTE2_TEST_MASK;
-        rout[offset + 3] = SCSI_IEC_MP_MRIE;
-        rout[offset + 4] = (SCSI_IEC_MP_INTERVAL_T >> 24) & 0xff;
-        rout[offset + 5] = (SCSI_IEC_MP_INTERVAL_T >> 16) & 0xff;
-        rout[offset + 6] = (SCSI_IEC_MP_INTERVAL_T >> 8) & 0xff;
-        rout[offset + 7] = SCSI_IEC_MP_INTERVAL_T & 0xff;
-        rout[offset + 8] = (SCSI_IEC_MP_REPORT_COUNT >> 24) & 0xff;
-        rout[offset + 9] = (SCSI_IEC_MP_REPORT_COUNT >> 16) & 0xff;
-        rout[offset + 10] = (SCSI_IEC_MP_REPORT_COUNT >> 8) & 0xff;
-        rout[offset + 11] = SCSI_IEC_MP_REPORT_COUNT & 0xff;
-        if (iecp->gotChangeable) {
-            UINT8 chg2 = iecp->raw_chg[offset + 2];
-
-            rout[offset + 2] = chg2 ? (rout[offset + 2] & chg2) :
-                                      iecp->raw_curr[offset + 2];
-            for (k = 3; k < 12; ++k) {
-                if (0 == iecp->raw_chg[offset + k])
-                    rout[offset + k] = iecp->raw_curr[offset + k];
-            }
-        }
-        if (0 == memcmp(&rout[offset + 2], &iecp->raw_chg[offset + 2], 10)) {
-            if (con->reportscsiioctl > 0)
-                pout("scsiSetExceptionControlAndWarning: already enabled\n");
-            return 0;
-        }
-    } else { /* disabling Exception Control and (temperature) Warnings */
-        eCEnabled = (rout[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;
-        wEnabled = (rout[offset + 2] & EWASC_ENABLE) ? 1 : 0;
-        if ((! eCEnabled) && (! wEnabled)) {
-            if (con->reportscsiioctl > 0)
-                pout("scsiSetExceptionControlAndWarning: already disabled\n");
-            return 0;   /* nothing to do, leave other setting alone */
-        }
-        if (wEnabled) 
-            rout[offset + 2] &= EWASC_DISABLE;
-        if (eCEnabled) {
-            if (iecp->gotChangeable && 
-                (iecp->raw_chg[offset + 2] & DEXCPT_ENABLE))
-                rout[offset + 2] |= DEXCPT_ENABLE;
-                rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */
-        }
-    }
-    if (10 == iecp->modese_len)
-        err = scsiModeSelect10(device, sp, rout, resp_len);
-    else if (6 == iecp->modese_len)
-        err = scsiModeSelect(device, sp, rout, resp_len);
-    return err;
-}
-
-int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
-{
-    UINT8 tBuf[252];
-    int err;
-
-    memset(tBuf, 0, sizeof(tBuf));
-    if ((err = scsiLogSense(device, TEMPERATURE_LPAGE, tBuf, 
-                            sizeof(tBuf), 0))) {
-        *currenttemp = 0;
-        *triptemp = 0;
-        pout("Log Sense for temperature failed [%s]\n", scsiErrString(err));
-        return err;
-    }
-    *currenttemp = tBuf[9];
-    *triptemp = tBuf[15];
-    return 0;
-}
-
-/* Read informational exception log page or Request Sense response.
- * Fetching asc/ascq code potentially flagging an exception or warning.
- * Returns 0 if ok, else error number. A current temperature of 255
- * (Celsius) implies that the temperature not available. */
-int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
-                UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp,
-                UINT8 *triptemp)
-{
-    UINT8 tBuf[252];
-    struct scsi_sense_disect sense_info;
-    int err;
-    int temperatureSet = 0;
-    unsigned short pagesize;
-    UINT8 currTemp, trTemp;
- 
-    *asc = 0;
-    *ascq = 0;
-    *currenttemp = 0;
-    *triptemp = 0;
-    memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk
-    memset(&sense_info, 0, sizeof(sense_info));
-    if (hasIELogPage) {
-        if ((err = scsiLogSense(device, IE_LPAGE, tBuf, 
-                                sizeof(tBuf), 0))) {
-            pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
-            return err;
-        }
-        // pull out page size from response, don't forget to add 4
-        pagesize = (unsigned short) ((tBuf[2] << 8) | tBuf[3]) + 4; 
-        if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
-            pout("Log Sense failed, IE page, bad parameter code or length\n");
-            return SIMPLE_ERR_BAD_PARAM;
-        }
-        if (tBuf[7] > 1) {
-            sense_info.asc = tBuf[8]; 
-            sense_info.ascq = tBuf[9];
-            if (! hasTempLogPage) {
-                if (tBuf[7] > 2) 
-                    *currenttemp = tBuf[10];
-                if (tBuf[7] > 3)        /* IBM extension in SMART (IE) lpage */
-                    *triptemp = tBuf[11];
-            }
-        } 
-    }
-    if (0 == sense_info.asc) {    
-        /* ties in with MRIE field of 6 in IEC mode page (0x1c) */
-        if ((err = scsiRequestSense(device, &sense_info))) {
-            pout("Request Sense failed, [%s]\n", scsiErrString(err));
-            return err;
-        }
-    }
-    *asc = sense_info.asc;
-    *ascq = sense_info.ascq;
-    if ((! temperatureSet) && hasTempLogPage) {
-        if (0 == scsiGetTemp(device, &currTemp, &trTemp)) {
-            *currenttemp = currTemp;
-            *triptemp = trTemp;
-        }
-    }
-    return 0;
-}
-
-// The first character (W, C, I) tells the severity
-static const char * TapeAlertsMessageTable[]= {  
-    " ",
-    /* 0x01 */
-   "W: The tape drive is having problems reading data. No data has been lost,\n"
-       "  but there has been a reduction in the performance of the tape.",
-    /* 0x02 */
-   "W: The tape drive is having problems writing data. No data has been lost,\n"
-       "  but there has been a reduction in the capacity of the tape.",
-    /* 0x03 */
-   "W: The operation has stopped because an error has occurred while reading\n"
-       "  or writing data that the drive cannot correct.",
-    /* 0x04 */
-   "C: Your data is at risk:\n"
-       "  1. Copy any data you require from this tape. \n"
-       "  2. Do not use this tape again.\n"
-       "  3. Restart the operation with a different tape.",
-    /* 0x05 */
-   "C: The tape is damaged or the drive is faulty. Call the tape drive\n"
-       "  supplier helpline.",
-    /* 0x06 */
-   "C: The tape is from a faulty batch or the tape drive is faulty:\n"
-       "  1. Use a good tape to test the drive.\n"
-       "  2. If problem persists, call the tape drive supplier helpline.",
-    /* 0x07 */
-   "W: The tape cartridge has reached the end of its calculated useful life:\n"
-       "  1. Copy data you need to another tape.\n"
-       "  2. Discard the old tape.",
-    /* 0x08 */
-   "W: The tape cartridge is not data-grade. Any data you back up to the tape\n"
-       "  is at risk. Replace the cartridge with a data-grade tape.",
-    /* 0x09 */
-   "C: You are trying to write to a write-protected cartridge. Remove the\n"
-       "  write-protection or use another tape.",
-    /* 0x0a */
-   "I: You cannot eject the cartridge because the tape drive is in use. Wait\n"
-       "  until the operation is complete before ejecting the cartridge.",
-    /* 0x0b */
-   "I: The tape in the drive is a cleaning cartridge.",
-    /* 0x0c */
-   "I: You have tried to load a cartridge of a type which is not supported\n"
-       "  by this drive.",
-    /* 0x0d */
-   "C: The operation has failed because the tape in the drive has experienced\n"
-       "  a mechanical failure:\n"
-       "  1. Discard the old tape.\n"
-       "  2. Restart the operation with a different tape.",
-    /* 0x0e */
-   "C: The operation has failed because the tape in the drive has experienced\n"
-       "  a mechanical failure:\n"
-       "  1. Do not attempt to extract the tape cartridge\n"
-       "  2. Call the tape drive supplier helpline.",
-    /* 0x0f */
-   "W: The memory in the tape cartridge has failed, which reduces\n"
-       "  performance. Do not use the cartridge for further write operations.",
-    /* 0x10 */
-   "C: The operation has failed because the tape cartridge was manually\n"
-       "  de-mounted while the tape drive was actively writing or reading.",
-    /* 0x11 */
-   "W: You have loaded a cartridge of a type that is read-only in this drive.\n"
-       "  The cartridge will appear as write-protected.",
-    /* 0x12 */
-   "W: The tape directory on the tape cartridge has been corrupted. File\n"
-       "  search performance will be degraded. The tape directory can be rebuilt\n"
-       "  by reading all the data on the cartridge.",
-    /* 0x13 */
-   "I: The tape cartridge is nearing the end of its calculated life. It is\n"
-       "  recommended that you:\n"
-       "  1. Use another tape cartridge for your next backup.\n"
-       "  2. Store this tape in a safe place in case you need to restore "
-       "  data from it.",
-    /* 0x14 */
-   "C: The tape drive needs cleaning:\n"
-       "  1. If the operation has stopped, eject the tape and clean the drive.\n"
-       "  2. If the operation has not stopped, wait for it to finish and then\n"
-       "  clean the drive.\n"
-       "  Check the tape drive users manual for device specific cleaning instructions.",
-    /* 0x15 */
-   "W: The tape drive is due for routine cleaning:\n"
-       "  1. Wait for the current operation to finish.\n"
-       "  2. The use a cleaning cartridge.\n"
-       "  Check the tape drive users manual for device specific cleaning instructions.",
-    /* 0x16 */
-   "C: The last cleaning cartridge used in the tape drive has worn out:\n"
-       "  1. Discard the worn out cleaning cartridge.\n"
-       "  2. Wait for the current operation to finish.\n"
-       "  3. Then use a new cleaning cartridge.",
-    /* 0x17 */
-   "C: The last cleaning cartridge used in the tape drive was an invalid\n"
-       "  type:\n"
-       "  1. Do not use this cleaning cartridge in this drive.\n"
-       "  2. Wait for the current operation to finish.\n"
-       "  3. Then use a new cleaning cartridge.",
-    /* 0x18 */
-   "W: The tape drive has requested a retention operation",
-    /* 0x19 */
-   "W: A redundant interface port on the tape drive has failed",
-    /* 0x1a */
-   "W: A tape drive cooling fan has failed",
-    /* 0x1b */
-   "W: A redundant power supply has failed inside the tape drive enclosure.\n"
-       "  Check the enclosure users manual for instructions on replacing the\n"
-       "  failed power supply.",
-    /* 0x1c */
-   "W: The tape drive power consumption is outside the specified range.",
-    /* 0x1d */
-   "W: Preventive maintenance of the tape drive is required. Check the tape\n"
-       "  drive users manual for device specific preventive maintenance\n"
-       "  tasks or call the tape drive supplier helpline.",
-    /* 0x1e */
-   "C: The tape drive has a hardware fault:\n"
-       "  1. Eject the tape or magazine.\n"
-       "  2. Reset the drive.\n"
-       "  3. Restart the operation.",
-    /* 0x1f */
-   "C: The tape drive has a hardware fault:\n"
-       "  1. Turn the tape drive off and then on again.\n"
-       "  2. Restart the operation.\n"
-    "  3. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x20 */
-   "W: The tape drive has a problem with the application client interface:\n"
-       "  1. Check the cables and cable connections.\n"
-       "  2. Restart the operation.",
-    /* 0x21 */
-   "C: The operation has failed:\n"
-       "  1. Eject the tape or magazine.\n"
-       "  2. Insert the tape or magazine again.\n"
-       "  3. Restart the operation.",
-    /* 0x22 */
-   "W: The firmware download has failed because you have tried to use the\n"
-       "  incorrect firmware for this tape drive. Obtain the correct\n"
-       "  firmware and try again.",
-    /* 0x23 */
-   "W: Environmental conditions inside the tape drive are outside the\n"
-       "  specified humidity range.",
-    /* 0x24 */
-   "W: Environmental conditions inside the tape drive are outside the\n"
-       "  specified temperature range.",
-    /* 0x25 */
-   "W: The voltage supply to the tape drive is outside the specified range.",
-    /* 0x26 */
-   "C: A hardware failure of the tape drive is predicted. Call the tape\n"
-       "  drive supplier helpline.",
-    /* 0x27 */
-   "W: The tape drive may have a hardware fault. Run extended diagnostics to\n"
-       "  verify and diagnose the problem. Check the tape drive users manual for\n"
-       "  device specific instructions on running extended diagnostic tests.",
-    /* 0x28 */
-   "C: The changer mechanism is having difficulty communicating with the tape\n"
-       "  drive:\n"
-       "  1. Turn the autoloader off then on.\n"
-       "  2. Restart the operation.\n"
-       "  3. If problem persists, call the tape drive supplier helpline.",
-    /* 0x29 */
-   "C: A tape has been left in the autoloader by a previous hardware fault:\n"
-       "  1. Insert an empty magazine to clear the fault.\n"
-       "  2. If the fault does not clear, turn the autoloader off and then\n"
-       "  on again.\n"
-       "  3. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x2a */
-   "W: There is a problem with the autoloader mechanism.",
-    /* 0x2b */
-   "C: The operation has failed because the autoloader door is open:\n"
-       "  1. Clear any obstructions from the autoloader door.\n"
-       "  2. Eject the magazine and then insert it again.\n"
-       "  3. If the fault does not clear, turn the autoloader off and then\n"
-       "  on again.\n"
-       "  4. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x2c */
-   "C: The autoloader has a hardware fault:\n"
-       "  1. Turn the autoloader off and then on again.\n"
-       "  2. Restart the operation.\n"
-       "  3. If the problem persists, call the tape drive supplier helpline.\n"
-       "  Check the autoloader users manual for device specific instructions\n"
-       "  on turning the device power on and off.",
-    /* 0x2d */
-   "C: The autoloader cannot operate without the magazine,\n"
-       "  1. Insert the magazine into the autoloader.\n"
-       "  2. Restart the operation.",
-    /* 0x2e */
-   "W: A hardware failure of the changer mechanism is predicted. Call the\n"
-       "  tape drive supplier helpline.",
-    /* 0x2f */
-   "I: Reserved.",
-    /* 0x30 */
-   "I: Reserved.",
-    /* 0x31 */
-   "I: Reserved.",
-    /* 0x32 */
-   "W: Media statistics have been lost at some time in the past",
-    /* 0x33 */
-   "W: The tape directory on the tape cartridge just unloaded has been\n"
-       "  corrupted. File search performance will be degraded. The tape\n"
-       "  directory can be rebuilt by reading all the data.",
-    /* 0x34 */
-   "C: The tape just unloaded could not write its system area successfully:\n"
-       "  1. Copy data to another tape cartridge.\n"
-       "  2. Discard the old cartridge.",
-    /* 0x35 */
-   "C: The tape system are could not be read successfully at load time:\n"
-    "  1. Copy data to another tape cartridge.\n",
-    /* 0x36 */
-   "C: The start or data could not be found on the tape:\n"
-       "  1. Check you are using the correct format tape.\n"
-       "  2. Discard the tape or return the tape to your supplier",
-    /* 0x37 */
-    "C: The operation has failed because the media cannot be loaded\n"
-        "  and threaded.\n"
-        "  1. Remove the cartridge, inspect it as specified in the product\n"
-        "  manual, and retry the operation.\n"
-        "  2. If the problem persists, call the tape drive supplier help line.",
-    /* 0x38 */
-    "C: The operation has failed because the medium cannot be unloaded:\n"
-        "  1. Do not attempt to extract the tape cartridge.\n"
-        "  2. Call the tape driver supplier help line.",
-    /* 0x39 */
-    "C: The tape drive has a problem with the automation interface:\n"
-        "  1. Check the power to the automation system.\n"
-        "  2. Check the cables and cable connections.\n"
-        "  3. Call the supplier help line if problem persists.",
-    /* 0x3a */
-    "W: The tape drive has reset itself due to a detected firmware\n"
-        "  fault. If problem persists, call the supplier help line.",
-    };
-
-const char * scsiTapeAlertsTapeDevice(unsigned short code)
-{
-    const int num = sizeof(TapeAlertsMessageTable) /
-                        sizeof(TapeAlertsMessageTable[0]);
-
-    return (code < num) ?  TapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-// The first character (W, C, I) tells the severity
-static const char * ChangerTapeAlertsMessageTable[]= {  
-    " ",
-    /* 0x01 */
-    "C: The library mechanism is having difficulty communicating with the\n"
-        "  drive:\n"
-        "  1. Turn the library off then on.\n"
-        "  2. Restart the operation.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x02 */
-    "W: There is a problem with the library mechanism. If problem persists,\n"
-        "  call the library supplier help line.",
-    /* 0x03 */
-    "C: The library has a hardware fault:\n"
-        "  1. Reset the library.\n"
-        "  2. Restart the operation.\n"
-        "  Check the library users manual for device specific instructions on resetting\n"
-        "  the device.",
-    /* 0x04 */
-    "C: The library has a hardware fault:\n"
-        "  1. Turn the library off then on again.\n"
-        "  2. Restart the operation.\n"
-        "  3. If the problem persists, call the library supplier help line.\n"
-        "  Check the library users manual for device specific instructions on turning the\n"
-        "  device power on and off.",
-    /* 0x05 */
-    "W: The library mechanism may have a hardware fault.\n"
-        "  Run extended diagnostics to verify and diagnose the problem. Check the library\n"
-        "  users manual for device specific instructions on running extended diagnostic\n"
-        "  tests.",
-    /* 0x06 */
-    "C: The library has a problem with the host interface:\n"
-        "  1. Check the cables and connections.\n"
-        "  2. Restart the operation.",
-    /* 0x07 */
-    "W: A hardware failure of the library is predicted. Call the library\n"
-        "  supplier help line.",
-    /* 0x08 */
-    "W: Preventive maintenance of the library is required.\n"
-        "  Check the library users manual for device specific preventative maintenance\n"
-        "  tasks, or call your library supplier help line.",
-    /* 0x09 */
-    "C: General environmental conditions inside the library are outside the\n"
-        "  specified humidity range.",
-    /* 0x0a */
-    "C: General environmental conditions inside the library are outside the\n"
-        "  specified temperature range.",
-    /* 0x0b */
-    "C: The voltage supply to the library is outside the specified range.\n"
-        "  There is a potential problem with the power supply or failure of\n"
-        "  a redundant power supply.",
-    /* 0x0c */
-    "C: A cartridge has been left inside the library by a previous hardware\n"
-        "  fault:\n"
-        "  1. Insert an empty magazine to clear the fault.\n"
-        "  2. If the fault does not clear, turn the library off and then on again.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x0d */
-    "W: There is a potential problem with the drive ejecting cartridges or\n"
-        "  with the library mechanism picking a cartridge from a slot.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x0e */
-    "W: There is a potential problem with the library mechanism placing a\n"
-        "  cartridge into a slot.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x0f */
-    "W: There is a potential problem with the drive or the library mechanism\n"
-        "  loading cartridges, or an incompatible cartridge.",
-    /* 0x10 */
-    "C: The library has failed because the door is open:\n"
-        "  1. Clear any obstructions from the library door.\n"
-        "  2. Close the library door.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x11 */
-    "C: There is a mechanical problem with the library media import/export\n"
-        "  mailslot.",
-    /* 0x12 */
-    "C: The library cannot operate without the magazine.\n"
-        "  1. Insert the magazine into the library.\n"
-        "  2. Restart the operation.",
-    /* 0x13 */
-    "W: Library security has been compromised.",
-    /* 0x14 */
-    "I: The library security mode has been changed.\n"
-        "  The library has either been put into secure mode, or the library has exited\n"
-        "  the secure mode.\n"
-        "  This is for information purposes only. No action is required.",
-    /* 0x15 */
-    "I: The library has been manually turned offline and is unavailable for use.",
-    /* 0x16 */
-    "I: A drive inside the library has been taken offline.\n"
-        "  This is for information purposes only. No action is required.",
-    /* 0x17 */
-    "W: There is a potential problem with the bar code label or the scanner\n"
-        "  hardware in the library mechanism.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x18 */
-    "C: The library has detected an inconsistency in its inventory.\n"
-        "  1. Redo the library inventory to correct inconsistency.\n"
-        "  2. Restart the operation.\n"
-        "  Check the applications users manual or the hardware users manual for\n"
-        "  specific instructions on redoing the library inventory.",
-    /* 0x19 */
-    "W: A library operation has been attempted that is invalid at this time.",
-    /* 0x1a */
-    "W: A redundant interface port on the library has failed.",
-    /* 0x1b */
-    "W: A library cooling fan has failed.",
-    /* 0x1c */
-    "W: A redundant power supply has failed inside the library. Check the\n"
-        "  library users manual for instructions on replacing the failed power supply.",
-    /* 0x1d */
-    "W: The library power consumption is outside the specified range.",
-    /* 0x1e */
-    "C: A failure has occurred in the cartridge pass-through mechanism between\n"
-        "  two library modules.",
-    /* 0x1f */
-    "C: A cartridge has been left in the pass-through mechanism from a\n"
-        "  previous hardware fault. Check the library users guide for instructions on\n"
-        "  clearing this fault.",
-    /* 0x20 */
-    "I: The library was unable to read the bar code on a cartridge.",
-};
-
-const char * scsiTapeAlertsChangerDevice(unsigned short code)
-{
-    const int num = sizeof(ChangerTapeAlertsMessageTable) /
-                        sizeof(ChangerTapeAlertsMessageTable[0]);
-
-    return (code < num) ?  ChangerTapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-
-/* this is a subset of the SCSI additional sense code strings indexed
- * by "ascq" for the case when asc==SCSI_ASC_IMPENDING_FAILURE (0x5d)
- */
-static const char * strs_for_asc_5d[] = {
-   /* 0x00 */   "FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-   /* 0x10 */   "HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "HARDWARE IMPENDING FAILURE CONTROLLER DETECTED",
-        "HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x20 */   "CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED",
-        "CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x30 */   "DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED",
-        "DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x40 */   "SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "SERVO IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "SERVO IMPENDING FAILURE CONTROLLER DETECTED",
-        "SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x50 */   "SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "SPINDLE IMPENDING FAILURE CONTROLLER DETECTED",
-        "SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x60 */   "FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED",
-        "FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-   /* 0x6c */   "FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"};
-
-
-/* this is a subset of the SCSI additional sense code strings indexed
- *  * by "ascq" for the case when asc==SCSI_ASC_WARNING (0xb)
- *   */
-static const char * strs_for_asc_b[] = {
-       /* 0x00 */   "WARNING",
-               "WARNING - SPECIFIED TEMPERATURE EXCEEDED",
-               "WARNING - ENCLOSURE DEGRADED"};
-
-static char spare_buff[128];
-
-const char * scsiGetIEString(UINT8 asc, UINT8 ascq)
-{
-    const char * rp;
-
-    if (SCSI_ASC_IMPENDING_FAILURE == asc) {
-        if (ascq == 0xff)
-            return "FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)";
-        else if (ascq < 
-                 (sizeof(strs_for_asc_5d) / sizeof(strs_for_asc_5d[0]))) {
-            rp = strs_for_asc_5d[ascq];
-            if (strlen(rp) > 0)
-                return rp;
-        }
-        snprintf(spare_buff, sizeof(spare_buff),
-                 "FAILURE PREDICTION THRESHOLD EXCEEDED: ascq=0x%x", ascq);
-        return spare_buff;
-    } else if (SCSI_ASC_WARNING == asc) {
-        if (ascq < (sizeof(strs_for_asc_b) / sizeof(strs_for_asc_b[0]))) {
-            rp = strs_for_asc_b[ascq];
-            if (strlen(rp) > 0)
-                return rp;
-        }
-        snprintf(spare_buff, sizeof(spare_buff), "WARNING: ascq=0x%x", ascq);
-        return spare_buff;
-    }
-    return NULL;        /* not a IE additional sense code */
-}
-
-
-/* This is not documented in t10.org, page 0x80 is vendor specific */
-/* Some IBM disks do an offline read-scan when they get this command. */
-int scsiSmartIBMOfflineTest(int device)
-{       
-    UINT8 tBuf[256];
-        
-    memset(tBuf, 0, sizeof(tBuf));
-    /* Build SMART Off-line Immediate Diag Header */
-    tBuf[0] = 0x80; /* Page Code */
-    tBuf[1] = 0x00; /* Reserved */
-    tBuf[2] = 0x00; /* Page Length MSB */
-    tBuf[3] = 0x04; /* Page Length LSB */
-    tBuf[4] = 0x03; /* SMART Revision */
-    tBuf[5] = 0x00; /* Reserved */
-    tBuf[6] = 0x00; /* Off-line Immediate Time MSB */
-    tBuf[7] = 0x00; /* Off-line Immediate Time LSB */
-    return scsiSendDiagnostic(device, SCSI_DIAG_NO_SELF_TEST, tBuf, 8);
-}
-
-int scsiSmartDefaultSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_DEF_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartShortSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_BG_SHORT_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartExtendSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_BG_EXTENDED_SELF_TEST, 
-                              NULL, 0);
-}
-
-int scsiSmartShortCapSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_FG_SHORT_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartExtendCapSelfTest(int device)
-{
-    return scsiSendDiagnostic(device, SCSI_DIAG_FG_EXTENDED_SELF_TEST, 
-                              NULL, 0);
-}
-
-int scsiSmartSelfTestAbort(int device)
-{
-    return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0);
-}
-
-/* Returns 0 and the expected duration of an extended self test (in seconds)
-   if successful; any other return value indicates a failure. */
-int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
-{
-    int err, offset, res;
-    UINT8 buff[64];
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return err;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, 
-                              MPAGE_CONTROL_CURRENT, 
-                              buff, sizeof(buff));
-        if (err)
-            return err;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if (offset < 0)
-        return -EINVAL;
-    if (buff[offset + 1] >= 0xa) {
-        res = (buff[offset + 10] << 8) | buff[offset + 11];
-        *durationSec = res;
-        return 0;
-    }
-    else
-        return -EINVAL;
-}
-
-void scsiDecodeErrCounterPage(unsigned char * resp, 
-                              struct scsiErrorCounter *ecp)
-{
-    int k, j, num, pl, pc;
-    unsigned char * ucp;
-    unsigned char * xp;
-    uint64_t * ullp;
-
-    memset(ecp, 0, sizeof(*ecp));
-    num = (resp[2] << 8) | resp[3];
-    ucp = &resp[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-            case 0: 
-            case 1: 
-            case 2: 
-            case 3: 
-            case 4: 
-            case 5: 
-            case 6: 
-                ecp->gotPC[pc] = 1;
-                ullp = &ecp->counter[pc];
-                break;
-        default: 
-                ecp->gotExtraPC = 1;
-                ullp = &ecp->counter[7];
-                break;
-        }
-        k = pl - 4;
-        xp = ucp + 4;
-        if (k > (int)sizeof(*ullp)) {
-            xp += (k - sizeof(*ullp));
-            k = sizeof(*ullp);
-        }
-        *ullp = 0;
-        for (j = 0; j < k; ++j) {
-            if (j > 0)
-                *ullp <<= 8;
-            *ullp |= xp[j];
-        }
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-void scsiDecodeNonMediumErrPage(unsigned char *resp, 
-                                struct scsiNonMediumError *nmep)
-{
-    int k, j, num, pl, pc, szof;
-    unsigned char * ucp;
-    unsigned char * xp;
-
-    memset(nmep, 0, sizeof(*nmep));
-    num = (resp[2] << 8) | resp[3];
-    ucp = &resp[0] + 4;
-    szof = sizeof(nmep->counterPC0);
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-            case 0: 
-                nmep->gotPC0 = 1;
-                k = pl - 4;
-                xp = ucp + 4;
-                if (k > szof) {
-                    xp += (k - szof);
-                    k = szof;
-                }
-                nmep->counterPC0 = 0;
-                for (j = 0; j < k; ++j) {
-                    if (j > 0)
-                        nmep->counterPC0 <<= 8;
-                    nmep->counterPC0 |= xp[j];
-                }
-                break;
-        default: 
-                nmep->gotExtraPC = 1;
-                break;
-        }
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-/* Counts number of failed self-tests. Also encodes the poweron_hour
-   of the most recent failed self-test. Return value is negative if
-   this function has a problem (typically -1), otherwise the bottom 8
-   bits are the number of failed self tests and the 16 bits above that
-   are the poweron hour of the most recent failure. Note: aborted self
-   tests (typically by the user) and self tests in progress are not 
-   considered failures. See Working Draft SCSI Primary Commands - 3 
-   (SPC-3) section 7.2.10 T10/1416-D Rev 15 */
-int scsiCountFailedSelfTests(int fd, int noisy)
-{
-    int num, k, n, err, res, fails, fail_hour;
-    UINT8 * ucp;
-    unsigned char resp[LOG_RESP_SELF_TEST_LEN];
-
-    if ((err = scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, resp, 
-                            LOG_RESP_SELF_TEST_LEN, 0))) {
-        if (noisy)
-            pout("scsiCountSelfTests Failed [%s]\n", scsiErrString(err));
-        return -1;
-    }
-    if (resp[0] != SELFTEST_RESULTS_LPAGE) {
-        if (noisy)
-            pout("Self-test Log Sense Failed, page mismatch\n");
-        return -1;
-    }
-    // compute page length
-    num = (resp[2] << 8) + resp[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        if (noisy)
-            pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n", num);
-        return -1;
-    }
-    fails = 0;
-    fail_hour = 0;
-    // loop through the twenty possible entries
-    for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
-
-        // timestamp in power-on hours (or zero if test in progress)
-        n = (ucp[6] << 8) | ucp[7];
-
-        // The spec says "all 20 bytes will be zero if no test" but
-        // DG has found otherwise.  So this is a heuristic.
-        if ((0 == n) && (0 == ucp[4]))
-            break;
-        res = ucp[4] & 0xf;
-        if ((res > 2) && (res < 8)) {
-            fails++;
-            if (1 == fails) 
-                fail_hour = (ucp[6] << 8) + ucp[7];
-        }
-    }
-    return (fail_hour << 8) + fails;
-}
-
-/* Returns 0 if able to read self test log page; then outputs 1 into
-   *inProgress if self test still in progress, else outputs 0. */
-int scsiSelfTestInProgress(int fd, int * inProgress)
-{
-    int num;
-    UINT8 * ucp;
-    unsigned char resp[LOG_RESP_SELF_TEST_LEN];
-
-    if (scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, resp, 
-                     LOG_RESP_SELF_TEST_LEN, 0))
-        return -1;
-    if (resp[0] != SELFTEST_RESULTS_LPAGE)
-        return -1;
-    // compute page length
-    num = (resp[2] << 8) + resp[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        return -1;
-    }
-    ucp = resp + 4;
-    if (inProgress)
-        *inProgress = (0xf == (ucp[4] & 0xf)) ? 1 : 0;
-    return 0;
-}
-
-/* Returns a negative value if failed to fetch Contol mode page or it was
-   malformed. Returns 0 if GLTSD bit is zero and returns 1 if the GLTSD
-   bit is set. Examines default mode page when current==0 else examines
-   current mode page. */
-int scsiFetchControlGLTSD(int device, int modese_len, int current)
-{
-    int err, offset;
-    UINT8 buff[64];
-    int pc = current ? MPAGE_CONTROL_CURRENT : MPAGE_CONTROL_DEFAULT;
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, pc, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return -EINVAL;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, pc,
-                              buff, sizeof(buff));
-        if (err)
-            return -EINVAL;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if ((offset >= 0) && (buff[offset + 1] >= 0xa))
-        return (buff[offset + 2] & 2) ? 1 : 0;
-    return -EINVAL;
-}
-
-/* Attempts to set or clear GLTSD bit in Control mode page. If enabled is
-   0 attempts to clear GLTSD otherwise it attempts to set it. Returns 0 if
-   successful, negative if low level error, > 0 if higher level error (e.g.
-   SIMPLE_ERR_BAD_PARAM if GLTSD bit is not changeable). */
-int scsiSetControlGLTSD(int device, int enabled, int modese_len)
-{
-    int err, offset, resp_len, sp;
-    UINT8 buff[64];
-    UINT8 ch_buff[64];
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return err;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, 
-                              MPAGE_CONTROL_CURRENT, 
-                              buff, sizeof(buff));
-        if (err)
-            return err;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if ((offset < 0) || (buff[offset + 1] < 0xa))
-        return SIMPLE_ERR_BAD_RESP;
-
-    if (enabled)
-        enabled = 2;
-    if (enabled == (buff[offset + 2] & 2))
-        return 0;       /* GLTSD already in wanted state so nothing to do */
-
-    if (modese_len == 6)
-        err = scsiModeSense(device, CONTROL_MODE_PAGE, 
-                            MPAGE_CONTROL_CHANGEABLE, 
-                            ch_buff, sizeof(ch_buff));
-    else
-        err = scsiModeSense10(device, CONTROL_MODE_PAGE, 
-                              MPAGE_CONTROL_CHANGEABLE, 
-                              ch_buff, sizeof(ch_buff));
-    if (err)
-        return err;
-    if (0 == (ch_buff[offset + 2] & 2))
-        return SIMPLE_ERR_BAD_PARAM;  /* GLTSD bit not chageable */
-    
-    if (10 == modese_len) {
-            resp_len = (buff[0] << 8) + buff[1] + 2;
-            memset(buff, 0, 2);
-    } else {
-            resp_len = buff[0] + 1;
-            memset(buff, 0, 1);
-    }
-    sp = (buff[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
-    buff[offset] &= 0x7f;     /* mask off PS bit */
-    if (enabled)
-        buff[offset + 2] |= 0x2;    /* set GLTSD bit */
-    else
-        buff[offset + 2] &= 0xfd;   /* clear GLTSD bit */
-    if (10 == modese_len)
-        err = scsiModeSelect10(device, sp, buff, resp_len);
-    else if (6 == modese_len)
-        err = scsiModeSelect(device, sp, buff, resp_len);
-    return err;
-}
-
-/* Returns a negative value if failed to fetch Protocol specific port mode 
-   page or it was malformed. Returns transport protocol identifier when
-   value >= 0 . */
-int scsiFetchTransportProtocol(int device, int modese_len)
-{
-    int err, offset;
-    UINT8 buff[64];
-
-    memset(buff, 0, sizeof(buff));
-    if (modese_len <= 6) {
-        if ((err = scsiModeSense(device, PROTOCOL_SPECIFIC_PORT_PAGE, 
-                                 MPAGE_CONTROL_CURRENT, 
-                                 buff, sizeof(buff)))) {
-            if (SIMPLE_ERR_BAD_OPCODE == err)
-                modese_len = 10;
-            else
-                return -EINVAL;
-        } else if (0 == modese_len)
-            modese_len = 6;
-    }
-    if (10 == modese_len) {
-        err = scsiModeSense10(device, PROTOCOL_SPECIFIC_PORT_PAGE, 
-                              MPAGE_CONTROL_CURRENT, 
-                              buff, sizeof(buff));
-        if (err)
-            return -EINVAL;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
-    if ((offset >= 0) && (buff[offset + 1] > 1)) {
-        if ((0 == (buff[offset] & 0x40)) &&       /* SPF==0 */
-            (PROTOCOL_SPECIFIC_PORT_PAGE == (buff[offset] & 0x3f))) 
-                return (buff[offset + 2] & 0xf);
-    }
-    return -EINVAL;
-}
-
diff --git a/sm5/scsicmds.h b/sm5/scsicmds.h
deleted file mode 100644
index 3aae4ab5d52e06599821d8e2a2e14039d01bc1e4..0000000000000000000000000000000000000000
--- a/sm5/scsicmds.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * scsicmds.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003-4 Douglas Gilbert <dougg@torque.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- * N.B. What was formerly known as "SMART" are now called "informational
- * exceptions" in recent t10.org drafts (i.e. recent SCSI).
- *
- */
-
-
-#ifndef SCSICMDS_H_
-#define SCSICMDS_H_
-
-#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.50 2004/07/11 15:16:09 dpgilbert Exp $\n"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "int64.h"
-
-/* #define SCSI_DEBUG 1 */ /* Comment out to disable command debugging */
-
-/* Following conditional defines bypass inclusion of scsi/scsi.h and
- * scsi/scsi_ioctl.h . Issue will be resolved later ... */
-#ifndef TEST_UNIT_READY
-#define TEST_UNIT_READY 0x0
-#endif
-#ifndef LOG_SENSE
-#define LOG_SENSE 0x4d
-#endif
-#ifndef MODE_SENSE
-#define MODE_SENSE 0x1a
-#endif
-#ifndef MODE_SENSE_10
-#define MODE_SENSE_10 0x5a
-#endif
-#ifndef MODE_SELECT
-#define MODE_SELECT 0x15
-#endif
-#ifndef MODE_SELECT_10
-#define MODE_SELECT_10 0x55
-#endif
-#ifndef INQUIRY
-#define INQUIRY 0x12
-#endif
-#ifndef REQUEST_SENSE
-#define REQUEST_SENSE  0x03
-#endif
-#ifndef RECEIVE_DIAGNOSTIC
-#define RECEIVE_DIAGNOSTIC  0x1c
-#endif
-#ifndef SEND_DIAGNOSTIC
-#define SEND_DIAGNOSTIC  0x1d
-#endif
-
-typedef unsigned char UINT8;
-typedef char INT8;
-typedef unsigned int UINT32;
-typedef int INT32;
-
-#define DXFER_NONE        0
-#define DXFER_FROM_DEVICE 1
-#define DXFER_TO_DEVICE   2
-
-struct scsi_cmnd_io
-{
-    UINT8 * cmnd;       /* [in]: ptr to SCSI command block (cdb) */
-    size_t  cmnd_len;   /* [in]: number of bytes in SCSI command */
-    int dxfer_dir;      /* [in]: DXFER_NONE, DXFER_FROM_DEVICE, or 
-                                 DXFER_TO_DEVICE */
-    UINT8 * dxferp;     /* [in]: ptr to outgoing or incoming data buffer */
-    size_t dxfer_len;   /* [in]: bytes to be transferred to/from dxferp */
-    UINT8 * sensep;     /* [in]: ptr to sense buffer, filled when 
-                                 CHECK CONDITION status occurs */
-    size_t max_sense_len; /* [in]: max number of bytes to write to sensep */
-    unsigned timeout;   /* [in]: seconds, 0-> default timeout (60 seconds?) */
-    size_t resp_sense_len;  /* [out]: sense buffer length written */
-    UINT8 scsi_status;  /* [out]: 0->ok, 2->CHECK CONDITION, etc ... */
-    int resid;          /* [out]: Number of bytes requested to be transferred
-                                  less actual number transferred (0 if not
-                                   supported) */
-};
-
-struct scsi_sense_disect {
-    UINT8 error_code;
-    UINT8 sense_key;
-    UINT8 asc; 
-    UINT8 ascq;
-};
-
-/* Useful data from Informational Exception Control mode page (0x1c) */
-#define SCSI_IECMP_RAW_LEN 64
-struct scsi_iec_mode_page {
-    UINT8 requestedCurrent;
-    UINT8 gotCurrent;
-    UINT8 requestedChangeable;
-    UINT8 gotChangeable;
-    UINT8 modese_len;   /* 0 (don't know), 6 or 10 */
-    UINT8 raw_curr[SCSI_IECMP_RAW_LEN];
-    UINT8 raw_chg[SCSI_IECMP_RAW_LEN];
-};
-
-/* Carrier for Error counter log pages (e.g. read, write, verify ...) */
-struct scsiErrorCounter {
-    UINT8 gotPC[7];
-    UINT8 gotExtraPC;
-    uint64_t counter[8];
-};
-
-/* Carrier for Non-medium error log page */
-struct scsiNonMediumError {
-    UINT8 gotPC0;
-    UINT8 gotExtraPC;
-    uint64_t counterPC0;
-};
-
-/* SCSI Peripheral types (of interest) */
-#define SCSI_PT_DIRECT_ACCESS           0x0
-#define SCSI_PT_SEQUENTIAL_ACCESS       0x1
-#define SCSI_PT_CDROM                   0x5
-#define SCSI_PT_MEDIUM_CHANGER          0x8
-#define SCSI_PT_ENCLOSURE               0xd
-
-/* ANSI SCSI-3 Log Pages retrieved by LOG SENSE. */
-#define SUPPORTED_LPAGES                        0x00
-#define BUFFER_OVERRUN_LPAGE                    0x01
-#define WRITE_ERROR_COUNTER_LPAGE               0x02
-#define READ_ERROR_COUNTER_LPAGE                0x03
-#define READ_REVERSE_ERROR_COUNTER_LPAGE        0x04
-#define VERIFY_ERROR_COUNTER_LPAGE              0x05
-#define NON_MEDIUM_ERROR_LPAGE                  0x06
-#define LAST_N_ERROR_LPAGE                      0x07
-#define FORMAT_STATUS_LPAGE                     0x08
-#define TEMPERATURE_LPAGE                       0x0d
-#define STARTSTOP_CYCLE_COUNTER_LPAGE           0x0e
-#define APPLICATION_CLIENT_LPAGE                0x0f
-#define SELFTEST_RESULTS_LPAGE                  0x10
-#define IE_LPAGE                                0x2f
-
-/* Seagate vendor specific log pages. */
-#define SEAGATE_CACHE_LPAGE                     0x37
-#define SEAGATE_FACTORY_LPAGE                   0x3e
-
-/* Log page response lengths */
-#define LOG_RESP_SELF_TEST_LEN 0x194
-
-/* See the SSC-2 document at www.t10.org . Earler note: From IBM 
-Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
-#define TAPE_ALERTS_LPAGE                        0x2e
-
-/* ANSI SCSI-3 Mode Pages */
-#define VENDOR_UNIQUE_PAGE                       0x00
-#define READ_WRITE_ERROR_RECOVERY_PAGE           0x01
-#define DISCONNECT_RECONNECT_PAGE                0x02
-#define FORMAT_DEVICE_PAGE                       0x03
-#define RIGID_DISK_DRIVE_GEOMETRY_PAGE           0x04
-#define FLEXIBLE_DISK_PAGE                       0x05
-#define VERIFY_ERROR_RECOVERY_PAGE               0x07
-#define CACHING_PAGE                             0x08
-#define PERIPHERAL_DEVICE_PAGE                   0x09
-#define XOR_CONTROL_MODE_PAGE                    0x10
-#define CONTROL_MODE_PAGE                        0x0a
-#define MEDIUM_TYPES_SUPPORTED_PAGE              0x0b
-#define NOTCH_PAGE                               0x0c
-#define CD_DEVICE_PAGE                           0x0d
-#define CD_AUDIO_CONTROL_PAGE                    0x0e
-#define DATA_COMPRESSION_PAGE                    0x0f
-#define ENCLOSURE_SERVICES_MANAGEMENT_PAGE       0x14
-#define PROTOCOL_SPECIFIC_LUN_PAGE               0x18
-#define PROTOCOL_SPECIFIC_PORT_PAGE              0x19
-#define POWER_CONDITION_PAGE                     0x1a
-#define INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE    0x1c
-#define FAULT_FAILURE_REPORTING_PAGE             0x1c
-
-#define ALL_MODE_PAGES                           0x3f
-
-/* Mode page control field */
-#define MPAGE_CONTROL_CURRENT               0
-#define MPAGE_CONTROL_CHANGEABLE            1
-#define MPAGE_CONTROL_DEFAULT               2
-#define MPAGE_CONTROL_SAVED                 3
-
-/* defines for useful SCSI Status codes */
-#define SCSI_STATUS_CHECK_CONDITION     0x2
-
-/* defines for useful Sense Key codes */
-#define SCSI_SK_NOT_READY               0x2
-#define SCSI_SK_ILLEGAL_REQUEST         0x5
-#define SCSI_SK_UNIT_ATTENTION          0x6
-
-/* defines for useful Additional Sense Codes (ASCs) */
-#define SCSI_ASC_NOT_READY              0x4     /* more info in ASCQ code */
-#define SCSI_ASC_NO_MEDIUM              0x3a    /* more info in ASCQ code */
-#define SCSI_ASC_UNKNOWN_OPCODE         0x20
-#define SCSI_ASC_UNKNOWN_FIELD          0x24
-#define SCSI_ASC_UNKNOWN_PARAM          0x26
-#define SCSI_ASC_WARNING                0xb
-#define SCSI_ASC_IMPENDING_FAILURE      0x5d
-
-/* Simplified error code (negative values as per errno) */
-#define SIMPLE_NO_ERROR                 0
-#define SIMPLE_ERR_NOT_READY            1
-#define SIMPLE_ERR_BAD_OPCODE           2
-#define SIMPLE_ERR_BAD_FIELD            3       /* in cbd */
-#define SIMPLE_ERR_BAD_PARAM            4       /* in data */
-#define SIMPLE_ERR_BAD_RESP             5       /* response fails sanity */
-#define SIMPLE_ERR_NO_MEDIUM            6       /* no medium present */
-#define SIMPLE_ERR_BECOMING_READY       7       /* device will be ready soon */
-#define SIMPLE_ERR_TRY_AGAIN            8       /* some warning, try again */
-
-
-/* defines for functioncode parameter in SENDDIAGNOSTIC function */
-#define SCSI_DIAG_NO_SELF_TEST          0x00
-#define SCSI_DIAG_DEF_SELF_TEST         0xff
-#define SCSI_DIAG_BG_SHORT_SELF_TEST    0x01
-#define SCSI_DIAG_BG_EXTENDED_SELF_TEST 0x02
-#define SCSI_DIAG_FG_SHORT_SELF_TEST    0x05
-#define SCSI_DIAG_FG_EXTENDED_SELF_TEST 0x06
-#define SCSI_DIAG_ABORT_SELF_TEST       0x04
-
-
-/* SCSI command timeout values (units are seconds) */
-#define SCSI_TIMEOUT_DEFAULT    6               /* 6 seconds should be ample */
-#define SCSI_TIMEOUT_SELF_TEST  (5 * 60 * 60)   /* allow max 5 hours for */
-                                            /* extended foreground self test */
-
-
-
-#define LOGPAGEHDRSIZE  4
-
-void scsi_do_sense_disect(const struct scsi_cmnd_io * in,
-                          struct scsi_sense_disect * out);
-
-const char * scsiErrString(int scsiErr);
-
-/* STANDARD SCSI Commands  */
-int scsiTestUnitReady(int device);
-
-int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen);
-
-int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen);
-
-int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
-                 int known_resp_len);
-
-int scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen);
-
-int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen);
-
-int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen);
-
-int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen);
-
-int scsiModePageOffset(const UINT8 * resp, int len, int modese_len);
-
-int scsiRequestSense(int device, struct scsi_sense_disect * sense_info);
-
-int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen);
-
-int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf,
-                      int bufLen);
-
-/* SMART specific commands */
-int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, UINT8 *asc,
-                UINT8 *ascq, UINT8 *currenttemp, UINT8 *triptemp);
-
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, 
-                      int modese_len);
-int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp);
-int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp);
-int scsiSetExceptionControlAndWarning(int device, int enabled,
-                            const struct scsi_iec_mode_page *iecp);
-void scsiDecodeErrCounterPage(unsigned char * resp,
-                              struct scsiErrorCounter *ecp);
-void scsiDecodeNonMediumErrPage(unsigned char * resp,
-                                struct scsiNonMediumError *nmep);
-int scsiFetchExtendedSelfTestTime(int device, int * durationSec, 
-                                  int modese_len);
-int scsiCountFailedSelfTests(int fd, int noisy);
-int scsiSelfTestInProgress(int fd, int * inProgress);
-int scsiFetchControlGLTSD(int device, int modese_len, int current);
-int scsiSetControlGLTSD(int device, int enabled, int modese_len);
-int scsiFetchTransportProtocol(int device, int modese_len);
-
-/* T10 Standard IE Additional Sense Code strings taken from t10.org */
-
-const char* scsiGetIEString(UINT8 asc, UINT8 ascq);
-int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp);
-
-
-int scsiSmartIBMOfflineTest(int device);
-
-int scsiSmartDefaultSelfTest(int device);
-int scsiSmartShortSelfTest(int device);
-int scsiSmartExtendSelfTest(int device);
-int scsiSmartShortCapSelfTest(int device);
-int scsiSmartExtendCapSelfTest(int device);
-int scsiSmartSelfTestAbort(int device);
-
-const char * scsiTapeAlertsTapeDevice(unsigned short code);
-const char * scsiTapeAlertsChangerDevice(unsigned short code);
-
-const char * scsi_get_opcode_name(UINT8 opcode);
-void dStrHex(const char* str, int len, int no_ascii);
-
-/* SCSI command transmission interface function declaration. Its
- * definition is target OS specific (see os_<OS>.c file).
- * Returns 0 if SCSI command successfully launched and response
- * received. Even when 0 is returned the caller should check
- * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
- * (e.g. CHECK CONDITION). If the SCSI command could not be issued
- * (e.g. device not present or not a SCSI device) or some other problem
- * arises (e.g. timeout) then returns a negative errno value. */
-int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
-
-#endif
-
diff --git a/sm5/scsiprint.c b/sm5/scsiprint.c
deleted file mode 100644
index 7633c404e59699613dc577277a5b1b3fc7fe2c40..0000000000000000000000000000000000000000
--- a/sm5/scsiprint.c
+++ /dev/null
@@ -1,1012 +0,0 @@
-/*
- * scsiprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003-4 Douglas Gilbert <dougg@torque.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "config.h"
-#include "int64.h"
-#include "extern.h"
-#include "scsicmds.h"
-#include "scsiprint.h"
-#include "smartctl.h"
-#include "utility.h"
-
-#define GBUF_SIZE 65535
-
-const char* scsiprint_c_cvsid="$Id: scsiprint.c,v 1.79 2004/07/18 07:33:13 makisara Exp $"
-CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// control block which points to external global control variables
-extern smartmonctrl *con;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-UINT8 gBuf[GBUF_SIZE];
-#define LOG_RESP_LEN 252
-#define LOG_RESP_TAPE_ALERT_LEN 0x144
-
-/* Log pages supported */
-static int gSmartLPage = 0;     /* Informational Exceptions log page */
-static int gTempLPage = 0;
-static int gSelfTestLPage = 0;
-static int gStartStopLPage = 0;
-static int gTapeAlertsLPage = 0;
-static int gSeagateCacheLPage = 0;
-static int gSeagateFactoryLPage = 0;
-
-/* Mode pages supported */
-static int gIecMPage = 1;     /* N.B. assume it until we know otherwise */
-
-/* Remember last successful mode sense/select command */
-static int modese_len = 0;
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-extern void failuretest(int type, int returnvalue);
-
-static void scsiGetSupportedLogPages(int device)
-{
-    int i, err;
-
-    if ((err = scsiLogSense(device, SUPPORTED_LPAGES, gBuf, 
-                            LOG_RESP_LEN, 0))) {
-        if (con->reportscsiioctl > 0)
-            pout("Log Sense for supported pages failed [%s]\n", 
-                 scsiErrString(err)); 
-        return;
-    } 
-
-    for (i = 4; i < gBuf[3] + LOGPAGEHDRSIZE; i++) {
-        switch (gBuf[i])
-        {
-            case TEMPERATURE_LPAGE:
-                gTempLPage = 1;
-                break;
-            case STARTSTOP_CYCLE_COUNTER_LPAGE:
-                gStartStopLPage = 1;
-                break;
-            case SELFTEST_RESULTS_LPAGE:
-                gSelfTestLPage = 1;
-                break;
-            case IE_LPAGE:
-                gSmartLPage = 1;
-                break;
-            case TAPE_ALERTS_LPAGE:
-                gTapeAlertsLPage = 1;
-                break;
-            case SEAGATE_CACHE_LPAGE:
-                gSeagateCacheLPage = 1;
-                break;
-            case SEAGATE_FACTORY_LPAGE:
-                gSeagateFactoryLPage = 1;
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-void scsiGetSmartData(int device, int attribs)
-{
-    UINT8 asc;
-    UINT8 ascq;
-    UINT8 currenttemp = 0;
-    UINT8 triptemp = 0;
-    const char * cp;
-    int err;
-
-    PRINT_ON(con);
-    if ((err = scsiCheckIE(device, gSmartLPage, gTempLPage, &asc, 
-                           &ascq, &currenttemp, &triptemp))) {
-        /* error message already announced */
-        PRINT_OFF(con);
-        return;
-    }
-    PRINT_OFF(con);
-    cp = scsiGetIEString(asc, ascq);
-    if (cp) {
-        PRINT_ON(con);
-        pout("SMART Health Status: %s [asc=%x,ascq=%x]\n", cp, asc, ascq); 
-        PRINT_OFF(con);
-    } else if (gIecMPage)
-        pout("SMART Health Status: OK\n");
-
-    if (attribs && !gTempLPage) {
-        if (currenttemp || triptemp)
-            pout("\n");
-        if (currenttemp) {
-            if (255 != currenttemp)
-                pout("Current Drive Temperature:     %d C\n", currenttemp);
-            else
-                pout("Current Drive Temperature:     <not available>\n");
-        }
-        if (triptemp)
-            pout("Drive Trip Temperature:        %d C\n", triptemp);
-    }
-}
-
-
-// Returns number of logged errors or zero if none or -1 if fetching
-// TapeAlerts fails
-static char *severities = "CWI";
-
-static int scsiGetTapeAlertsData(int device, int peripheral_type)
-{
-    unsigned short pagelength;
-    unsigned short parametercode;
-    int i, err;
-    char *s;
-    const char *ts;
-    int failures = 0;
-
-    PRINT_ON(con);
-    if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, gBuf, 
-                        LOG_RESP_TAPE_ALERT_LEN, LOG_RESP_TAPE_ALERT_LEN))) {
-        pout("scsiGetTapesAlertData Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return -1;
-    }
-    if (gBuf[0] != 0x2e) {
-        pout("TapeAlerts Log Sense Failed\n");
-        PRINT_OFF(con);
-        return -1;
-    }
-    pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3];
-
-    for (s=severities; *s; s++) {
-        for (i = 4; i < pagelength; i += 5) {
-            parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1];
-
-            if (gBuf[i + 4]) {
-                ts = SCSI_PT_MEDIUM_CHANGER == peripheral_type ?
-                    scsiTapeAlertsChangerDevice(parametercode) :
-                    scsiTapeAlertsTapeDevice(parametercode);
-                if (*ts == *s) {
-                    if (!failures)
-                        pout("TapeAlert Errors (C=Critical, W=Warning, I=Informational):\n");
-                    pout("[0x%02x] %s\n", parametercode, ts);
-                    failures += 1; 
-                }
-            }
-        }
-    }
-    PRINT_OFF(con);
-
-    if (! failures)
-        pout("TapeAlert: OK\n");
-
-    return failures;
-}
-
-void scsiGetStartStopData(int device)
-{
-    UINT32 currentStartStop;
-    UINT32 recommendedStartStop; 
-    int err, len, k;
-    char str[6];
-
-    if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, gBuf,
-                            LOG_RESP_LEN, 0))) {
-        PRINT_ON(con);
-        pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return;
-    }
-    if (gBuf[0] != STARTSTOP_CYCLE_COUNTER_LPAGE) {
-        PRINT_ON(con);
-        pout("StartStop Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return;
-    }
-    len = ((gBuf[2] << 8) | gBuf[3]) + 4;
-    if (len > 13) {
-        for (k = 0; k < 2; ++k)
-            str[k] = gBuf[12 + k];
-        str[k] = '\0';
-        pout("Manufactured in week %s of year ", str);
-        for (k = 0; k < 4; ++k)
-            str[k] = gBuf[8 + k];
-        str[k] = '\0';
-        pout("%s\n", str);
-    }
-    if (len > 39) {
-        recommendedStartStop = (gBuf[28] << 24) | (gBuf[29] << 16) |
-                               (gBuf[30] << 8) | gBuf[31];
-        currentStartStop = (gBuf[36] << 24) | (gBuf[37] << 16) |
-                           (gBuf[38] << 8) | gBuf[39];
-        pout("Current start stop count:      %u times\n", currentStartStop);
-        pout("Recommended maximum start stop count:  %u times\n", 
-             recommendedStartStop);
-    }
-} 
-
-static void scsiPrintSeagateCacheLPage(int device)
-{
-    int k, j, num, pl, pc, err, len;
-    unsigned char * ucp;
-    unsigned char * xp;
-    uint64_t ull;
-
-    if ((err = scsiLogSense(device, SEAGATE_CACHE_LPAGE, gBuf,
-                            LOG_RESP_LEN, 0))) {
-        PRINT_ON(con);
-        pout("Seagate Cache Log Sense Failed: %s\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return;
-    }
-    if (gBuf[0] != SEAGATE_CACHE_LPAGE) {
-        PRINT_ON(con);
-        pout("Seagate Cache Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return;
-    }
-    len = ((gBuf[2] << 8) | gBuf[3]) + 4;
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: case 1: case 2: case 3: case 4:
-            break;
-        default: 
-            if (con->reportscsiioctl > 0) {
-                PRINT_ON(con);
-                pout("Vendor (Seagate) cache lpage has unexpected parameter"
-                     ", skip\n");
-                PRINT_OFF(con);
-            }
-            return;
-        }
-        num -= pl;
-        ucp += pl;
-    }
-    pout("Vendor (Seagate) cache information\n");
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: pout("  Blocks sent to initiator"); break;
-        case 1: pout("  Blocks received from initiator"); break;
-        case 2: pout("  Blocks read from cache and sent to initiator"); break;
-        case 3: pout("  Number of read and write commands whose size "
-                       "<= segment size"); break;
-        case 4: pout("  Number of read and write commands whose size "
-                       "> segment size"); break;
-        default: pout("  Unknown Seagate parameter code [0x%x]", pc); break;
-        }
-        k = pl - 4;
-        xp = ucp + 4;
-        if (k > (int)sizeof(ull)) {
-            xp += (k - (int)sizeof(ull));
-            k = (int)sizeof(ull);
-        }
-        ull = 0;
-        for (j = 0; j < k; ++j) {
-            if (j > 0)
-                ull <<= 8;
-            ull |= xp[j];
-        }
-        pout(" = %"PRIu64"\n", ull);
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-static void scsiPrintSeagateFactoryLPage(int device)
-{
-    int k, j, num, pl, pc, len, err;
-    unsigned char * ucp;
-    unsigned char * xp;
-    uint64_t ull;
-
-    if ((err = scsiLogSense(device, SEAGATE_FACTORY_LPAGE, gBuf,
-                            LOG_RESP_LEN, 0))) {
-        PRINT_ON(con);
-        pout("scsiPrintSeagateFactoryLPage Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return;
-    }
-    if (gBuf[0] != SEAGATE_FACTORY_LPAGE) {
-        PRINT_ON(con);
-        pout("Seagate Factory Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return;
-    }
-    len = ((gBuf[2] << 8) | gBuf[3]) + 4;
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: case 8:
-            break;
-        default: 
-            if (con->reportscsiioctl > 0) {
-                PRINT_ON(con);
-                pout("\nVendor (Seagate) factory lpage has unexpected "
-                     "parameter, skip\n");
-                PRINT_OFF(con);
-            }
-            return;
-        }
-        num -= pl;
-        ucp += pl;
-    }
-    pout("Vendor (Seagate) factory information\n");
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: pout("  number of hours powered up"); break;
-        case 8: pout("  number of minutes until next internal SMART test");
-            break;
-        default: pout("  Unknown Seagate parameter code [0x%x]", pc); break;
-        }
-        k = pl - 4;
-        xp = ucp + 4;
-        if (k > (int)sizeof(ull)) {
-            xp += (k - (int)sizeof(ull));
-            k = (int)sizeof(ull);
-        }
-        ull = 0;
-        for (j = 0; j < k; ++j) {
-            if (j > 0)
-                ull <<= 8;
-            ull |= xp[j];
-        }
-        if (0 == pc)
-            pout(" = %.2f\n", uint64_to_double(ull) / 60.0 );
-        else
-            pout(" = %"PRIu64"\n", ull);
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-static void scsiPrintErrorCounterLog(int device)
-{
-    struct scsiErrorCounter errCounterArr[3];
-    struct scsiErrorCounter * ecp;
-    struct scsiNonMediumError nme;
-    int found[3] = {0, 0, 0};
-    const char * pageNames[3] = {"read:   ", "write:  ", "verify: "};
-    int k;
-    double processed_gb;
-
-    if (0 == scsiLogSense(device, READ_ERROR_COUNTER_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[0]);
-        found[0] = 1;
-    }
-    if (0 == scsiLogSense(device, WRITE_ERROR_COUNTER_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[1]);
-        found[1] = 1;
-    }
-    if (0 == scsiLogSense(device, VERIFY_ERROR_COUNTER_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[2]);
-        ecp = &errCounterArr[2];
-        for (k = 0; k < 7; ++k) {
-            if (ecp->gotPC[k] && ecp->counter[k]) {
-                found[2] = 1;
-                break;
-            }
-        }
-    }
-    if (found[0] || found[1] || found[2]) {
-        pout("\nError counter log:\n");
-        pout("          Errors Corrected    Total      Total   "
-             "Correction     Gigabytes    Total\n");
-        pout("              delay:       [rereads/    errors   "
-             "algorithm      processed    uncorrected\n");
-        pout("            minor | major  rewrites]  corrected  "
-             "invocations   [10^9 bytes]  errors\n");
-        for (k = 0; k < 3; ++k) {
-            if (! found[k])
-                continue;
-            ecp = &errCounterArr[k];
-            pout("%s%8"PRIu64" %8"PRIu64"  %8"PRIu64"  %8"PRIu64"   %8"PRIu64, 
-                 pageNames[k], ecp->counter[0], ecp->counter[1], 
-                 ecp->counter[2], ecp->counter[3], ecp->counter[4]);
-            processed_gb = uint64_to_double(ecp->counter[5]) / 1000000000.0;
-            pout("   %12.3f    %8"PRIu64"\n", processed_gb, ecp->counter[6]);
-        }
-    }
-    else 
-        pout("\nDevice does not support Error Counter logging\n");
-    if (0 == scsiLogSense(device, NON_MEDIUM_ERROR_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeNonMediumErrPage(gBuf, &nme);
-        if (nme.gotPC0)
-            pout("\nNon-medium error count: %8"PRIu64"\n", nme.counterPC0);
-    }
-}
-
-const char * self_test_code[] = {
-        "Default         ", 
-        "Background short", 
-        "Background long ", 
-        "Reserved(3)     ",
-        "Abort background", 
-        "Foreground short", 
-        "Foreground long ",
-        "Reserved(7)     "
-};
-
-const char * self_test_result[] = {
-        "Completed                ",
-        "Interrupted ('-X' switch)",
-        "Interrupted (bus reset ?)",
-        "Unknown error, incomplete",
-        "Completed, segment failed",
-        "Failed in first segment  ",
-        "Failed in second segment ",
-        "Failed in segment -->    ",
-        "Reserved(8)              ", 
-        "Reserved(9)              ", 
-        "Reserved(10)             ", 
-        "Reserved(11)             ", 
-        "Reserved(12)             ", 
-        "Reserved(13)             ", 
-        "Reserved(14)             ",
-        "Self test in progress ..."
-};
-
-// See Working Draft SCSI Primary Commands - 3 (SPC-3) pages 231-233
-// T10/1416-D Rev 10
-static int scsiPrintSelfTest(int device)
-{
-    int num, k, n, res, err, durationSec;
-    int noheader = 1;
-    UINT8 * ucp;
-    uint64_t ull=0;
-
-    if ((err = scsiLogSense(device, SELFTEST_RESULTS_LPAGE, gBuf, 
-                            LOG_RESP_SELF_TEST_LEN, 0))) {
-        PRINT_ON(con);
-        pout("scsiPrintSelfTest Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    if (gBuf[0] != SELFTEST_RESULTS_LPAGE) {
-        PRINT_ON(con);
-        pout("Self-test Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return 1;
-    }
-    // compute page length
-    num = (gBuf[2] << 8) + gBuf[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        PRINT_ON(con);
-        pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n",num);
-        PRINT_OFF(con);
-        return 1;
-    }
-    // loop through the twenty possible entries
-    for (k = 0, ucp = gBuf + 4; k < 20; ++k, ucp += 20 ) {
-        int i;
-
-        // timestamp in power-on hours (or zero if test in progress)
-        n = (ucp[6] << 8) | ucp[7];
-
-        // The spec says "all 20 bytes will be zero if no test" but
-        // DG has found otherwise.  So this is a heuristic.
-        if ((0 == n) && (0 == ucp[4]))
-            break;
-
-        // only print header if needed
-        if (noheader) {
-            pout("\nSMART Self-test log\n");
-            pout("Num  Test              Status                 segment  "
-                   "LifeTime  LBA_first_err [SK ASC ASQ]\n");
-            pout("     Description                              number   "
-                   "(hours)\n");
-            noheader=0;
-        }
-
-        // print parameter code (test number) & self-test code text
-        pout("#%2d  %s", (ucp[0] << 8) | ucp[1], 
-            self_test_code[(ucp[4] >> 5) & 0x7]);
-
-        // self-test result
-        res = ucp[4] & 0xf;
-        pout("  %s", self_test_result[res]);
-
-        // self-test number identifies test that failed and consists
-        // of either the number of the segment that failed during
-        // the test, or the number of the test that failed and the
-        // number of the segment in which the test was run, using a
-        // vendor-specific method of putting both numbers into a
-        // single byte.
-        if (ucp[5])
-            pout(" %3d",  (int)ucp[5]);
-        else
-            pout("   -");
-
-        // print time that the self-test was completed
-        if (n==0 && res==0xf)
-        // self-test in progress
-            pout("   NOW");
-        else   
-            pout(" %5d", n);
-          
-        // construct 8-byte integer address of first failure
-        for (i = 0; i < 8; i++) {
-            ull <<= 8;
-            ull |= ucp[i+8];
-        }
-        // print Address of First Failure, if sensible
-        if ((~(uint64_t)0 != ull) && (res > 0) && (res < 0xf))
-            pout("  0x%16"PRIx64, ull);
-        else
-            pout("                   -");
-
-        // if sense key nonzero, then print it, along with
-        // additional sense code and additional sense code qualifier
-        if (ucp[16] & 0xf)
-            pout(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]);
-        else
-            pout(" [-   -    -]\n");
-    }
-
-    // if header never printed, then there was no output
-    if (noheader)
-        pout("No self-tests have been logged\n");
-    else
-        pout("\n");
-    if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec, 
-                        modese_len)) && (durationSec > 0)) {
-        pout("Long (extended) Self Test duration: %d seconds "
-             "[%.1f minutes]\n", durationSec, durationSec / 60.0);
-    }
-    return 0;
-}
-
-static const char * peripheral_dt_arr[] = {
-        "disk",
-        "tape",
-        "printer",
-        "processor",
-        "optical disk(4)",
-        "CD/DVD",
-        "scanner",
-        "optical disk(7)",
-        "medium changer",
-        "communications",
-        "graphics(10)",
-        "graphics(11)",
-        "storage array",
-        "enclosure",
-        "simplified disk",
-        "optical card reader"
-};
-
-static const char * transport_proto_arr[] = {
-        "Fibre channel (FCP-2)",
-        "Parallel SCSI (SPI-4)",
-        "SSA",
-        "IEEE 1394 (SBP-2)",
-        "RDMA (SRP)",
-        "iSCSI",
-        "SAS",
-        "ADT",
-        "0x8",
-        "0x9",
-        "0xa",
-        "0xb",
-        "0xc",
-        "0xd",
-        "0xe",
-        "0xf"
-};
- 
-/* Returns 0 on success */
-static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
-{
-    char manufacturer[9];
-    char product[17];
-    char revision[5];
-    char timedatetz[DATEANDEPOCHLEN];
-    struct scsi_iec_mode_page iec;
-    int err, iec_err, len, val;
-    int is_tape = 0;
-    int peri_dt = 0;
-    int returnval=0;
-        
-    memset(gBuf, 0, 36);
-    if ((err = scsiStdInquiry(device, gBuf, 36))) {
-        PRINT_ON(con);
-        pout("Standard Inquiry failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    len = gBuf[4] + 5;
-    peri_dt = gBuf[0] & 0x1f;
-    if (peripheral_type)
-        *peripheral_type = peri_dt;
-    if (! all)
-        return 0;
-
-    if (len < 36) {
-        PRINT_ON(con);
-        pout("Short INQUIRY response, skip product id\n");
-        PRINT_OFF(con);
-        return 1;
-    }
-    memset(manufacturer, 0, sizeof(manufacturer));
-    strncpy(manufacturer, (char *)&gBuf[8], 8);
- 
-    memset(product, 0, sizeof(product));
-    strncpy(product, (char *)&gBuf[16], 16);
-        
-    memset(revision, 0, sizeof(revision));
-    strncpy(revision, (char *)&gBuf[32], 4);
-    pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
-
-    /* Do this here to try and detect badly conforming devices (some USB
-       keys) that will lock up on a InquiryVpd or log sense or ... */
-    if ((iec_err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        if (SIMPLE_ERR_BAD_RESP == iec_err) {
-            pout(">> Terminate command early due to bad response to IEC "
-                 "mode page\n");
-            PRINT_OFF(con);
-            gIecMPage = 0;
-            return 1;
-        }
-    } else
-        modese_len = iec.modese_len;
-
-    if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
-        /* should use VPD page 0x83 and fall back to this page (0x80)
-         * if 0x83 not supported. NAA requires a lot of decoding code */
-        len = gBuf[3];
-        gBuf[4 + len] = '\0';
-        pout("Serial number: %s\n", &gBuf[4]);
-    }
-    else if (con->reportscsiioctl > 0) {
-        PRINT_ON(con);
-        if (SIMPLE_ERR_BAD_RESP == err)
-            pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
-        else
-            pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
-        PRINT_OFF(con);
-    }
-
-    // print SCSI peripheral device type
-    if (peri_dt < (int)(sizeof(peripheral_dt_arr) / 
-                        sizeof(peripheral_dt_arr[0])))
-        pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
-    else
-        pout("Device type: <%d>\n", peri_dt);
-
-    // See if transport protocol is known
-    val = scsiFetchTransportProtocol(device, modese_len);
-    if ((val >= 0) && (val <= 0xf))
-        pout("Transport protocol: %s\n", transport_proto_arr[val]);
-
-    // print current time and date and timezone
-    dateandtimezone(timedatetz);
-    pout("Local Time is: %s\n", timedatetz);
-
-    if ((SCSI_PT_SEQUENTIAL_ACCESS == *peripheral_type) ||
-        (SCSI_PT_MEDIUM_CHANGER == *peripheral_type))
-        is_tape = 1;
-    // See if unit accepts SCSI commmands from us
-    if ((err = scsiTestUnitReady(device))) {
-        if (SIMPLE_ERR_NOT_READY == err) {
-            PRINT_ON(con);
-	    if (!is_tape)
-		pout("device is NOT READY (e.g. spun down, busy)\n");
-	    else
-		pout("device is NOT READY (e.g. no tape)\n");
-            PRINT_OFF(con);
-         } else if (SIMPLE_ERR_NO_MEDIUM == err) {
-            PRINT_ON(con);
-            pout("NO MEDIUM present on device\n");
-            PRINT_OFF(con);
-         } else if (SIMPLE_ERR_BECOMING_READY == err) {
-            PRINT_ON(con);
-            pout("device becoming ready (wait)\n");
-            PRINT_OFF(con);
-        } else {
-            PRINT_ON(con);
-            pout("device Test Unit Ready  [%s]\n", scsiErrString(err));
-            PRINT_OFF(con);
-        }
-        failuretest(MANDATORY_CMD, returnval|=FAILID);
-    }
-   
-    if (iec_err) {
-        if (!is_tape) {
-            PRINT_ON(con);
-            pout("Device does not support SMART");
-            if (con->reportscsiioctl > 0)
-                pout(" [%s]\n", scsiErrString(iec_err));
-            else
-                pout("\n");
-            PRINT_OFF(con);
-        }
-        gIecMPage = 0;
-        return 0;
-    }
-
-    if (!is_tape)
-        pout("Device supports SMART and is %s\n",
-             (scsi_IsExceptionControlEnabled(&iec)) ? "Enabled" : "Disabled");
-    pout("%s\n", (scsi_IsWarningEnabled(&iec)) ? 
-                  "Temperature Warning Enabled" :
-                  "Temperature Warning Disabled or Not Supported");
-    return 0;
-}
-
-static int scsiSmartEnable(int device)
-{
-    struct scsi_iec_mode_page iec;
-    int err;
-
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        PRINT_ON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    if ((err = scsiSetExceptionControlAndWarning(device, 1, &iec))) {
-        PRINT_ON(con);
-        pout("unable to enable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    pout("Informational Exceptions (SMART) %s\n",
-         scsi_IsExceptionControlEnabled(&iec) ? "enabled" : "disabled");
-    pout("Temperature warning %s\n",
-         scsi_IsWarningEnabled(&iec) ? "enabled" : "disabled");
-    return 0;
-}
-        
-static int scsiSmartDisable(int device)
-{
-    struct scsi_iec_mode_page iec;
-    int err;
-
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        PRINT_ON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    if ((err = scsiSetExceptionControlAndWarning(device, 0, &iec))) {
-        PRINT_ON(con);
-        pout("unable to disable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    pout("Informational Exceptions (SMART) %s\n",
-         scsi_IsExceptionControlEnabled(&iec) ? "enabled" : "disabled");
-    pout("Temperature warning %s\n",
-         scsi_IsWarningEnabled(&iec) ? "enabled" : "disabled");
-    return 0;
-}
-
-void scsiPrintTemp(int device)
-{
-    UINT8 temp = 0;
-    UINT8 trip = 0;
-
-    if (scsiGetTemp(device, &temp, &trip))
-        return;
-  
-    if (temp) {
-        if (255 != temp)
-            pout("Current Drive Temperature:     %d C\n", temp);
-        else
-            pout("Current Drive Temperature:     <not available>\n");
-    }
-    if (trip)
-        pout("Drive Trip Temperature:        %d C\n", trip);
-}
-
-/* Main entry point used by smartctl command. Return 0 for success */
-int scsiPrintMain(int fd)
-{
-    int checkedSupportedLogPages = 0;
-    UINT8 peripheral_type = 0;
-    int returnval = 0;
-    int res, durationSec;
-
-    if (scsiGetDriveInfo(fd, &peripheral_type, con->driveinfo)) {
-        failuretest(MANDATORY_CMD, returnval |= FAILID);
-    }
-
-    if (con->smartenable) {
-        if (scsiSmartEnable(fd))
-            failuretest(MANDATORY_CMD, returnval |= FAILSMART);
-    }
-
-    if (con->smartdisable) {
-        if (scsiSmartDisable(fd))
-            failuretest(MANDATORY_CMD,returnval |= FAILSMART);
-    }
-    
-    if (con->smartautosaveenable) {
-      if (scsiSetControlGLTSD(fd, 0, modese_len)) {
-        pout("Enable autosave (clear GLTSD bit) failed\n");
-        failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
-      }
-    }
-    
-    if (con->smartautosavedisable) {
-      if (scsiSetControlGLTSD(fd, 1, modese_len)) {
-        pout("Disable autosave (set GLTSD bit) failed\n");
-        failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
-      }
-    }
-    
-    if (con->checksmart) {
-        scsiGetSupportedLogPages(fd);
-        checkedSupportedLogPages = 1;
-        if ((SCSI_PT_SEQUENTIAL_ACCESS == peripheral_type) ||
-            (SCSI_PT_MEDIUM_CHANGER == peripheral_type)) { /* tape device */
-            if (gTapeAlertsLPage) {
-                if (con->driveinfo)
-                    pout("TapeAlert Supported\n");
-                if (-1 == scsiGetTapeAlertsData(fd, peripheral_type))
-                    failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
-            }
-            else
-                pout("TapeAlert Not Supported\n");
-        } else { /* disk, cd/dvd, enclosure, etc */
-            scsiGetSmartData(fd, con->smartvendorattrib);
-        }
-    }   
-    if (con->smartvendorattrib) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        if (gTempLPage) {
-            if (con->checksmart)
-                pout("\n");
-            scsiPrintTemp(fd);         
-        }
-        if (gStartStopLPage)
-            scsiGetStartStopData(fd);
-        if (SCSI_PT_DIRECT_ACCESS == peripheral_type) {
-            if (gSeagateCacheLPage)
-                scsiPrintSeagateCacheLPage(fd);
-            if (gSeagateFactoryLPage)
-                scsiPrintSeagateFactoryLPage(fd);
-        }
-    }
-    if (con->smarterrorlog) {
-        scsiPrintErrorCounterLog(fd);
-        if (1 == scsiFetchControlGLTSD(fd, modese_len, 1))
-            pout("\n[GLTSD (Global Logging Target Save Disable) set. "
-                 "Enable Save with '-S on']\n");
-    }
-    if (con->smartselftestlog) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        res = 0;
-        if (gSelfTestLPage)
-            res = scsiPrintSelfTest(fd);
-        else {
-            pout("Device does not support Self Test logging\n");
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-        }
-        if (0 != res)
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    if (con->smartexeoffimmediate) {
-        if (scsiSmartDefaultSelfTest(fd)) {
-            pout( "Default Self Test Failed\n");
-            return returnval;
-        }
-        pout("Default Self Test Successful\n");
-    }
-    if (con->smartshortcapselftest) {
-        if (scsiSmartShortCapSelfTest(fd)) {
-            pout("Short Foreground Self Test Failed\n");
-            return returnval;
-        }
-        pout("Short Foreground Self Test Successful\n");
-    }
-    if (con->smartshortselftest ) { 
-        if ( scsiSmartShortSelfTest(fd)) {
-            pout("Short Background Self Test Failed\n");
-            return returnval;
-        }
-        pout("Short Background Self Test has begun\n");
-        pout("Use smartctl -X to abort test\n");
-    }
-    if (con->smartextendselftest) {
-        if (scsiSmartExtendSelfTest(fd)) {
-            pout("Extended Background Self Test Failed\n");
-            return returnval;
-        }
-        pout("Extended Background Self Test has begun\n");
-        if ((0 == scsiFetchExtendedSelfTestTime(fd, &durationSec, 
-                        modese_len)) && (durationSec > 0)) {
-            time_t t = time(NULL);
-
-            t += durationSec;
-            pout("Please wait %d minutes for test to complete.\n", 
-                 durationSec / 60);
-            pout("Estimated completion time: %s\n", ctime(&t));
-        }
-        pout("Use smartctl -X to abort test\n");        
-    }
-    if (con->smartextendcapselftest) {
-        if (scsiSmartExtendCapSelfTest(fd)) {
-            pout("Extended Foreground Self Test Failed\n");
-            return returnval;
-        }
-        pout("Extended Foreground Self Test Successful\n");
-    }
-    if (con->smartselftestabort) {
-        if (scsiSmartSelfTestAbort(fd)) {
-            pout("Self Test Abort Failed\n");
-            return returnval;
-        }
-        pout("Self Test returned without error\n");
-    }           
-    return returnval;
-}
diff --git a/sm5/scsiprint.cpp b/sm5/scsiprint.cpp
deleted file mode 100644
index 4c1282300a54a220dfe9fb5ae24e93cbfc0139a7..0000000000000000000000000000000000000000
--- a/sm5/scsiprint.cpp
+++ /dev/null
@@ -1,1012 +0,0 @@
-/*
- * scsiprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003-4 Douglas Gilbert <dougg@torque.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "config.h"
-#include "int64.h"
-#include "extern.h"
-#include "scsicmds.h"
-#include "scsiprint.h"
-#include "smartctl.h"
-#include "utility.h"
-
-#define GBUF_SIZE 65535
-
-const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.79 2004/07/18 07:33:13 makisara Exp $"
-CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// control block which points to external global control variables
-extern smartmonctrl *con;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-UINT8 gBuf[GBUF_SIZE];
-#define LOG_RESP_LEN 252
-#define LOG_RESP_TAPE_ALERT_LEN 0x144
-
-/* Log pages supported */
-static int gSmartLPage = 0;     /* Informational Exceptions log page */
-static int gTempLPage = 0;
-static int gSelfTestLPage = 0;
-static int gStartStopLPage = 0;
-static int gTapeAlertsLPage = 0;
-static int gSeagateCacheLPage = 0;
-static int gSeagateFactoryLPage = 0;
-
-/* Mode pages supported */
-static int gIecMPage = 1;     /* N.B. assume it until we know otherwise */
-
-/* Remember last successful mode sense/select command */
-static int modese_len = 0;
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-extern void failuretest(int type, int returnvalue);
-
-static void scsiGetSupportedLogPages(int device)
-{
-    int i, err;
-
-    if ((err = scsiLogSense(device, SUPPORTED_LPAGES, gBuf, 
-                            LOG_RESP_LEN, 0))) {
-        if (con->reportscsiioctl > 0)
-            pout("Log Sense for supported pages failed [%s]\n", 
-                 scsiErrString(err)); 
-        return;
-    } 
-
-    for (i = 4; i < gBuf[3] + LOGPAGEHDRSIZE; i++) {
-        switch (gBuf[i])
-        {
-            case TEMPERATURE_LPAGE:
-                gTempLPage = 1;
-                break;
-            case STARTSTOP_CYCLE_COUNTER_LPAGE:
-                gStartStopLPage = 1;
-                break;
-            case SELFTEST_RESULTS_LPAGE:
-                gSelfTestLPage = 1;
-                break;
-            case IE_LPAGE:
-                gSmartLPage = 1;
-                break;
-            case TAPE_ALERTS_LPAGE:
-                gTapeAlertsLPage = 1;
-                break;
-            case SEAGATE_CACHE_LPAGE:
-                gSeagateCacheLPage = 1;
-                break;
-            case SEAGATE_FACTORY_LPAGE:
-                gSeagateFactoryLPage = 1;
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-void scsiGetSmartData(int device, int attribs)
-{
-    UINT8 asc;
-    UINT8 ascq;
-    UINT8 currenttemp = 0;
-    UINT8 triptemp = 0;
-    const char * cp;
-    int err;
-
-    PRINT_ON(con);
-    if ((err = scsiCheckIE(device, gSmartLPage, gTempLPage, &asc, 
-                           &ascq, &currenttemp, &triptemp))) {
-        /* error message already announced */
-        PRINT_OFF(con);
-        return;
-    }
-    PRINT_OFF(con);
-    cp = scsiGetIEString(asc, ascq);
-    if (cp) {
-        PRINT_ON(con);
-        pout("SMART Health Status: %s [asc=%x,ascq=%x]\n", cp, asc, ascq); 
-        PRINT_OFF(con);
-    } else if (gIecMPage)
-        pout("SMART Health Status: OK\n");
-
-    if (attribs && !gTempLPage) {
-        if (currenttemp || triptemp)
-            pout("\n");
-        if (currenttemp) {
-            if (255 != currenttemp)
-                pout("Current Drive Temperature:     %d C\n", currenttemp);
-            else
-                pout("Current Drive Temperature:     <not available>\n");
-        }
-        if (triptemp)
-            pout("Drive Trip Temperature:        %d C\n", triptemp);
-    }
-}
-
-
-// Returns number of logged errors or zero if none or -1 if fetching
-// TapeAlerts fails
-static char *severities = "CWI";
-
-static int scsiGetTapeAlertsData(int device, int peripheral_type)
-{
-    unsigned short pagelength;
-    unsigned short parametercode;
-    int i, err;
-    char *s;
-    const char *ts;
-    int failures = 0;
-
-    PRINT_ON(con);
-    if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, gBuf, 
-                        LOG_RESP_TAPE_ALERT_LEN, LOG_RESP_TAPE_ALERT_LEN))) {
-        pout("scsiGetTapesAlertData Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return -1;
-    }
-    if (gBuf[0] != 0x2e) {
-        pout("TapeAlerts Log Sense Failed\n");
-        PRINT_OFF(con);
-        return -1;
-    }
-    pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3];
-
-    for (s=severities; *s; s++) {
-        for (i = 4; i < pagelength; i += 5) {
-            parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1];
-
-            if (gBuf[i + 4]) {
-                ts = SCSI_PT_MEDIUM_CHANGER == peripheral_type ?
-                    scsiTapeAlertsChangerDevice(parametercode) :
-                    scsiTapeAlertsTapeDevice(parametercode);
-                if (*ts == *s) {
-                    if (!failures)
-                        pout("TapeAlert Errors (C=Critical, W=Warning, I=Informational):\n");
-                    pout("[0x%02x] %s\n", parametercode, ts);
-                    failures += 1; 
-                }
-            }
-        }
-    }
-    PRINT_OFF(con);
-
-    if (! failures)
-        pout("TapeAlert: OK\n");
-
-    return failures;
-}
-
-void scsiGetStartStopData(int device)
-{
-    UINT32 currentStartStop;
-    UINT32 recommendedStartStop; 
-    int err, len, k;
-    char str[6];
-
-    if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, gBuf,
-                            LOG_RESP_LEN, 0))) {
-        PRINT_ON(con);
-        pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return;
-    }
-    if (gBuf[0] != STARTSTOP_CYCLE_COUNTER_LPAGE) {
-        PRINT_ON(con);
-        pout("StartStop Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return;
-    }
-    len = ((gBuf[2] << 8) | gBuf[3]) + 4;
-    if (len > 13) {
-        for (k = 0; k < 2; ++k)
-            str[k] = gBuf[12 + k];
-        str[k] = '\0';
-        pout("Manufactured in week %s of year ", str);
-        for (k = 0; k < 4; ++k)
-            str[k] = gBuf[8 + k];
-        str[k] = '\0';
-        pout("%s\n", str);
-    }
-    if (len > 39) {
-        recommendedStartStop = (gBuf[28] << 24) | (gBuf[29] << 16) |
-                               (gBuf[30] << 8) | gBuf[31];
-        currentStartStop = (gBuf[36] << 24) | (gBuf[37] << 16) |
-                           (gBuf[38] << 8) | gBuf[39];
-        pout("Current start stop count:      %u times\n", currentStartStop);
-        pout("Recommended maximum start stop count:  %u times\n", 
-             recommendedStartStop);
-    }
-} 
-
-static void scsiPrintSeagateCacheLPage(int device)
-{
-    int k, j, num, pl, pc, err, len;
-    unsigned char * ucp;
-    unsigned char * xp;
-    uint64_t ull;
-
-    if ((err = scsiLogSense(device, SEAGATE_CACHE_LPAGE, gBuf,
-                            LOG_RESP_LEN, 0))) {
-        PRINT_ON(con);
-        pout("Seagate Cache Log Sense Failed: %s\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return;
-    }
-    if (gBuf[0] != SEAGATE_CACHE_LPAGE) {
-        PRINT_ON(con);
-        pout("Seagate Cache Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return;
-    }
-    len = ((gBuf[2] << 8) | gBuf[3]) + 4;
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: case 1: case 2: case 3: case 4:
-            break;
-        default: 
-            if (con->reportscsiioctl > 0) {
-                PRINT_ON(con);
-                pout("Vendor (Seagate) cache lpage has unexpected parameter"
-                     ", skip\n");
-                PRINT_OFF(con);
-            }
-            return;
-        }
-        num -= pl;
-        ucp += pl;
-    }
-    pout("Vendor (Seagate) cache information\n");
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: pout("  Blocks sent to initiator"); break;
-        case 1: pout("  Blocks received from initiator"); break;
-        case 2: pout("  Blocks read from cache and sent to initiator"); break;
-        case 3: pout("  Number of read and write commands whose size "
-                       "<= segment size"); break;
-        case 4: pout("  Number of read and write commands whose size "
-                       "> segment size"); break;
-        default: pout("  Unknown Seagate parameter code [0x%x]", pc); break;
-        }
-        k = pl - 4;
-        xp = ucp + 4;
-        if (k > (int)sizeof(ull)) {
-            xp += (k - (int)sizeof(ull));
-            k = (int)sizeof(ull);
-        }
-        ull = 0;
-        for (j = 0; j < k; ++j) {
-            if (j > 0)
-                ull <<= 8;
-            ull |= xp[j];
-        }
-        pout(" = %"PRIu64"\n", ull);
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-static void scsiPrintSeagateFactoryLPage(int device)
-{
-    int k, j, num, pl, pc, len, err;
-    unsigned char * ucp;
-    unsigned char * xp;
-    uint64_t ull;
-
-    if ((err = scsiLogSense(device, SEAGATE_FACTORY_LPAGE, gBuf,
-                            LOG_RESP_LEN, 0))) {
-        PRINT_ON(con);
-        pout("scsiPrintSeagateFactoryLPage Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return;
-    }
-    if (gBuf[0] != SEAGATE_FACTORY_LPAGE) {
-        PRINT_ON(con);
-        pout("Seagate Factory Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return;
-    }
-    len = ((gBuf[2] << 8) | gBuf[3]) + 4;
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: case 8:
-            break;
-        default: 
-            if (con->reportscsiioctl > 0) {
-                PRINT_ON(con);
-                pout("\nVendor (Seagate) factory lpage has unexpected "
-                     "parameter, skip\n");
-                PRINT_OFF(con);
-            }
-            return;
-        }
-        num -= pl;
-        ucp += pl;
-    }
-    pout("Vendor (Seagate) factory information\n");
-    num = len - 4;
-    ucp = &gBuf[0] + 4;
-    while (num > 3) {
-        pc = (ucp[0] << 8) | ucp[1];
-        pl = ucp[3] + 4;
-        switch (pc) {
-        case 0: pout("  number of hours powered up"); break;
-        case 8: pout("  number of minutes until next internal SMART test");
-            break;
-        default: pout("  Unknown Seagate parameter code [0x%x]", pc); break;
-        }
-        k = pl - 4;
-        xp = ucp + 4;
-        if (k > (int)sizeof(ull)) {
-            xp += (k - (int)sizeof(ull));
-            k = (int)sizeof(ull);
-        }
-        ull = 0;
-        for (j = 0; j < k; ++j) {
-            if (j > 0)
-                ull <<= 8;
-            ull |= xp[j];
-        }
-        if (0 == pc)
-            pout(" = %.2f\n", uint64_to_double(ull) / 60.0 );
-        else
-            pout(" = %"PRIu64"\n", ull);
-        num -= pl;
-        ucp += pl;
-    }
-}
-
-static void scsiPrintErrorCounterLog(int device)
-{
-    struct scsiErrorCounter errCounterArr[3];
-    struct scsiErrorCounter * ecp;
-    struct scsiNonMediumError nme;
-    int found[3] = {0, 0, 0};
-    const char * pageNames[3] = {"read:   ", "write:  ", "verify: "};
-    int k;
-    double processed_gb;
-
-    if (0 == scsiLogSense(device, READ_ERROR_COUNTER_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[0]);
-        found[0] = 1;
-    }
-    if (0 == scsiLogSense(device, WRITE_ERROR_COUNTER_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[1]);
-        found[1] = 1;
-    }
-    if (0 == scsiLogSense(device, VERIFY_ERROR_COUNTER_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[2]);
-        ecp = &errCounterArr[2];
-        for (k = 0; k < 7; ++k) {
-            if (ecp->gotPC[k] && ecp->counter[k]) {
-                found[2] = 1;
-                break;
-            }
-        }
-    }
-    if (found[0] || found[1] || found[2]) {
-        pout("\nError counter log:\n");
-        pout("          Errors Corrected    Total      Total   "
-             "Correction     Gigabytes    Total\n");
-        pout("              delay:       [rereads/    errors   "
-             "algorithm      processed    uncorrected\n");
-        pout("            minor | major  rewrites]  corrected  "
-             "invocations   [10^9 bytes]  errors\n");
-        for (k = 0; k < 3; ++k) {
-            if (! found[k])
-                continue;
-            ecp = &errCounterArr[k];
-            pout("%s%8"PRIu64" %8"PRIu64"  %8"PRIu64"  %8"PRIu64"   %8"PRIu64, 
-                 pageNames[k], ecp->counter[0], ecp->counter[1], 
-                 ecp->counter[2], ecp->counter[3], ecp->counter[4]);
-            processed_gb = uint64_to_double(ecp->counter[5]) / 1000000000.0;
-            pout("   %12.3f    %8"PRIu64"\n", processed_gb, ecp->counter[6]);
-        }
-    }
-    else 
-        pout("\nDevice does not support Error Counter logging\n");
-    if (0 == scsiLogSense(device, NON_MEDIUM_ERROR_LPAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeNonMediumErrPage(gBuf, &nme);
-        if (nme.gotPC0)
-            pout("\nNon-medium error count: %8"PRIu64"\n", nme.counterPC0);
-    }
-}
-
-const char * self_test_code[] = {
-        "Default         ", 
-        "Background short", 
-        "Background long ", 
-        "Reserved(3)     ",
-        "Abort background", 
-        "Foreground short", 
-        "Foreground long ",
-        "Reserved(7)     "
-};
-
-const char * self_test_result[] = {
-        "Completed                ",
-        "Interrupted ('-X' switch)",
-        "Interrupted (bus reset ?)",
-        "Unknown error, incomplete",
-        "Completed, segment failed",
-        "Failed in first segment  ",
-        "Failed in second segment ",
-        "Failed in segment -->    ",
-        "Reserved(8)              ", 
-        "Reserved(9)              ", 
-        "Reserved(10)             ", 
-        "Reserved(11)             ", 
-        "Reserved(12)             ", 
-        "Reserved(13)             ", 
-        "Reserved(14)             ",
-        "Self test in progress ..."
-};
-
-// See Working Draft SCSI Primary Commands - 3 (SPC-3) pages 231-233
-// T10/1416-D Rev 10
-static int scsiPrintSelfTest(int device)
-{
-    int num, k, n, res, err, durationSec;
-    int noheader = 1;
-    UINT8 * ucp;
-    uint64_t ull=0;
-
-    if ((err = scsiLogSense(device, SELFTEST_RESULTS_LPAGE, gBuf, 
-                            LOG_RESP_SELF_TEST_LEN, 0))) {
-        PRINT_ON(con);
-        pout("scsiPrintSelfTest Failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    if (gBuf[0] != SELFTEST_RESULTS_LPAGE) {
-        PRINT_ON(con);
-        pout("Self-test Log Sense Failed, page mismatch\n");
-        PRINT_OFF(con);
-        return 1;
-    }
-    // compute page length
-    num = (gBuf[2] << 8) + gBuf[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        PRINT_ON(con);
-        pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n",num);
-        PRINT_OFF(con);
-        return 1;
-    }
-    // loop through the twenty possible entries
-    for (k = 0, ucp = gBuf + 4; k < 20; ++k, ucp += 20 ) {
-        int i;
-
-        // timestamp in power-on hours (or zero if test in progress)
-        n = (ucp[6] << 8) | ucp[7];
-
-        // The spec says "all 20 bytes will be zero if no test" but
-        // DG has found otherwise.  So this is a heuristic.
-        if ((0 == n) && (0 == ucp[4]))
-            break;
-
-        // only print header if needed
-        if (noheader) {
-            pout("\nSMART Self-test log\n");
-            pout("Num  Test              Status                 segment  "
-                   "LifeTime  LBA_first_err [SK ASC ASQ]\n");
-            pout("     Description                              number   "
-                   "(hours)\n");
-            noheader=0;
-        }
-
-        // print parameter code (test number) & self-test code text
-        pout("#%2d  %s", (ucp[0] << 8) | ucp[1], 
-            self_test_code[(ucp[4] >> 5) & 0x7]);
-
-        // self-test result
-        res = ucp[4] & 0xf;
-        pout("  %s", self_test_result[res]);
-
-        // self-test number identifies test that failed and consists
-        // of either the number of the segment that failed during
-        // the test, or the number of the test that failed and the
-        // number of the segment in which the test was run, using a
-        // vendor-specific method of putting both numbers into a
-        // single byte.
-        if (ucp[5])
-            pout(" %3d",  (int)ucp[5]);
-        else
-            pout("   -");
-
-        // print time that the self-test was completed
-        if (n==0 && res==0xf)
-        // self-test in progress
-            pout("   NOW");
-        else   
-            pout(" %5d", n);
-          
-        // construct 8-byte integer address of first failure
-        for (i = 0; i < 8; i++) {
-            ull <<= 8;
-            ull |= ucp[i+8];
-        }
-        // print Address of First Failure, if sensible
-        if ((~(uint64_t)0 != ull) && (res > 0) && (res < 0xf))
-            pout("  0x%16"PRIx64, ull);
-        else
-            pout("                   -");
-
-        // if sense key nonzero, then print it, along with
-        // additional sense code and additional sense code qualifier
-        if (ucp[16] & 0xf)
-            pout(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]);
-        else
-            pout(" [-   -    -]\n");
-    }
-
-    // if header never printed, then there was no output
-    if (noheader)
-        pout("No self-tests have been logged\n");
-    else
-        pout("\n");
-    if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec, 
-                        modese_len)) && (durationSec > 0)) {
-        pout("Long (extended) Self Test duration: %d seconds "
-             "[%.1f minutes]\n", durationSec, durationSec / 60.0);
-    }
-    return 0;
-}
-
-static const char * peripheral_dt_arr[] = {
-        "disk",
-        "tape",
-        "printer",
-        "processor",
-        "optical disk(4)",
-        "CD/DVD",
-        "scanner",
-        "optical disk(7)",
-        "medium changer",
-        "communications",
-        "graphics(10)",
-        "graphics(11)",
-        "storage array",
-        "enclosure",
-        "simplified disk",
-        "optical card reader"
-};
-
-static const char * transport_proto_arr[] = {
-        "Fibre channel (FCP-2)",
-        "Parallel SCSI (SPI-4)",
-        "SSA",
-        "IEEE 1394 (SBP-2)",
-        "RDMA (SRP)",
-        "iSCSI",
-        "SAS",
-        "ADT",
-        "0x8",
-        "0x9",
-        "0xa",
-        "0xb",
-        "0xc",
-        "0xd",
-        "0xe",
-        "0xf"
-};
- 
-/* Returns 0 on success */
-static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
-{
-    char manufacturer[9];
-    char product[17];
-    char revision[5];
-    char timedatetz[DATEANDEPOCHLEN];
-    struct scsi_iec_mode_page iec;
-    int err, iec_err, len, val;
-    int is_tape = 0;
-    int peri_dt = 0;
-    int returnval=0;
-        
-    memset(gBuf, 0, 36);
-    if ((err = scsiStdInquiry(device, gBuf, 36))) {
-        PRINT_ON(con);
-        pout("Standard Inquiry failed [%s]\n", scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    len = gBuf[4] + 5;
-    peri_dt = gBuf[0] & 0x1f;
-    if (peripheral_type)
-        *peripheral_type = peri_dt;
-    if (! all)
-        return 0;
-
-    if (len < 36) {
-        PRINT_ON(con);
-        pout("Short INQUIRY response, skip product id\n");
-        PRINT_OFF(con);
-        return 1;
-    }
-    memset(manufacturer, 0, sizeof(manufacturer));
-    strncpy(manufacturer, (char *)&gBuf[8], 8);
- 
-    memset(product, 0, sizeof(product));
-    strncpy(product, (char *)&gBuf[16], 16);
-        
-    memset(revision, 0, sizeof(revision));
-    strncpy(revision, (char *)&gBuf[32], 4);
-    pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
-
-    /* Do this here to try and detect badly conforming devices (some USB
-       keys) that will lock up on a InquiryVpd or log sense or ... */
-    if ((iec_err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        if (SIMPLE_ERR_BAD_RESP == iec_err) {
-            pout(">> Terminate command early due to bad response to IEC "
-                 "mode page\n");
-            PRINT_OFF(con);
-            gIecMPage = 0;
-            return 1;
-        }
-    } else
-        modese_len = iec.modese_len;
-
-    if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
-        /* should use VPD page 0x83 and fall back to this page (0x80)
-         * if 0x83 not supported. NAA requires a lot of decoding code */
-        len = gBuf[3];
-        gBuf[4 + len] = '\0';
-        pout("Serial number: %s\n", &gBuf[4]);
-    }
-    else if (con->reportscsiioctl > 0) {
-        PRINT_ON(con);
-        if (SIMPLE_ERR_BAD_RESP == err)
-            pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
-        else
-            pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
-        PRINT_OFF(con);
-    }
-
-    // print SCSI peripheral device type
-    if (peri_dt < (int)(sizeof(peripheral_dt_arr) / 
-                        sizeof(peripheral_dt_arr[0])))
-        pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
-    else
-        pout("Device type: <%d>\n", peri_dt);
-
-    // See if transport protocol is known
-    val = scsiFetchTransportProtocol(device, modese_len);
-    if ((val >= 0) && (val <= 0xf))
-        pout("Transport protocol: %s\n", transport_proto_arr[val]);
-
-    // print current time and date and timezone
-    dateandtimezone(timedatetz);
-    pout("Local Time is: %s\n", timedatetz);
-
-    if ((SCSI_PT_SEQUENTIAL_ACCESS == *peripheral_type) ||
-        (SCSI_PT_MEDIUM_CHANGER == *peripheral_type))
-        is_tape = 1;
-    // See if unit accepts SCSI commmands from us
-    if ((err = scsiTestUnitReady(device))) {
-        if (SIMPLE_ERR_NOT_READY == err) {
-            PRINT_ON(con);
-	    if (!is_tape)
-		pout("device is NOT READY (e.g. spun down, busy)\n");
-	    else
-		pout("device is NOT READY (e.g. no tape)\n");
-            PRINT_OFF(con);
-         } else if (SIMPLE_ERR_NO_MEDIUM == err) {
-            PRINT_ON(con);
-            pout("NO MEDIUM present on device\n");
-            PRINT_OFF(con);
-         } else if (SIMPLE_ERR_BECOMING_READY == err) {
-            PRINT_ON(con);
-            pout("device becoming ready (wait)\n");
-            PRINT_OFF(con);
-        } else {
-            PRINT_ON(con);
-            pout("device Test Unit Ready  [%s]\n", scsiErrString(err));
-            PRINT_OFF(con);
-        }
-        failuretest(MANDATORY_CMD, returnval|=FAILID);
-    }
-   
-    if (iec_err) {
-        if (!is_tape) {
-            PRINT_ON(con);
-            pout("Device does not support SMART");
-            if (con->reportscsiioctl > 0)
-                pout(" [%s]\n", scsiErrString(iec_err));
-            else
-                pout("\n");
-            PRINT_OFF(con);
-        }
-        gIecMPage = 0;
-        return 0;
-    }
-
-    if (!is_tape)
-        pout("Device supports SMART and is %s\n",
-             (scsi_IsExceptionControlEnabled(&iec)) ? "Enabled" : "Disabled");
-    pout("%s\n", (scsi_IsWarningEnabled(&iec)) ? 
-                  "Temperature Warning Enabled" :
-                  "Temperature Warning Disabled or Not Supported");
-    return 0;
-}
-
-static int scsiSmartEnable(int device)
-{
-    struct scsi_iec_mode_page iec;
-    int err;
-
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        PRINT_ON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    if ((err = scsiSetExceptionControlAndWarning(device, 1, &iec))) {
-        PRINT_ON(con);
-        pout("unable to enable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    pout("Informational Exceptions (SMART) %s\n",
-         scsi_IsExceptionControlEnabled(&iec) ? "enabled" : "disabled");
-    pout("Temperature warning %s\n",
-         scsi_IsWarningEnabled(&iec) ? "enabled" : "disabled");
-    return 0;
-}
-        
-static int scsiSmartDisable(int device)
-{
-    struct scsi_iec_mode_page iec;
-    int err;
-
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        PRINT_ON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    if ((err = scsiSetExceptionControlAndWarning(device, 0, &iec))) {
-        PRINT_ON(con);
-        pout("unable to disable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        PRINT_OFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    } else
-        modese_len = iec.modese_len;
-
-    pout("Informational Exceptions (SMART) %s\n",
-         scsi_IsExceptionControlEnabled(&iec) ? "enabled" : "disabled");
-    pout("Temperature warning %s\n",
-         scsi_IsWarningEnabled(&iec) ? "enabled" : "disabled");
-    return 0;
-}
-
-void scsiPrintTemp(int device)
-{
-    UINT8 temp = 0;
-    UINT8 trip = 0;
-
-    if (scsiGetTemp(device, &temp, &trip))
-        return;
-  
-    if (temp) {
-        if (255 != temp)
-            pout("Current Drive Temperature:     %d C\n", temp);
-        else
-            pout("Current Drive Temperature:     <not available>\n");
-    }
-    if (trip)
-        pout("Drive Trip Temperature:        %d C\n", trip);
-}
-
-/* Main entry point used by smartctl command. Return 0 for success */
-int scsiPrintMain(int fd)
-{
-    int checkedSupportedLogPages = 0;
-    UINT8 peripheral_type = 0;
-    int returnval = 0;
-    int res, durationSec;
-
-    if (scsiGetDriveInfo(fd, &peripheral_type, con->driveinfo)) {
-        failuretest(MANDATORY_CMD, returnval |= FAILID);
-    }
-
-    if (con->smartenable) {
-        if (scsiSmartEnable(fd))
-            failuretest(MANDATORY_CMD, returnval |= FAILSMART);
-    }
-
-    if (con->smartdisable) {
-        if (scsiSmartDisable(fd))
-            failuretest(MANDATORY_CMD,returnval |= FAILSMART);
-    }
-    
-    if (con->smartautosaveenable) {
-      if (scsiSetControlGLTSD(fd, 0, modese_len)) {
-        pout("Enable autosave (clear GLTSD bit) failed\n");
-        failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
-      }
-    }
-    
-    if (con->smartautosavedisable) {
-      if (scsiSetControlGLTSD(fd, 1, modese_len)) {
-        pout("Disable autosave (set GLTSD bit) failed\n");
-        failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
-      }
-    }
-    
-    if (con->checksmart) {
-        scsiGetSupportedLogPages(fd);
-        checkedSupportedLogPages = 1;
-        if ((SCSI_PT_SEQUENTIAL_ACCESS == peripheral_type) ||
-            (SCSI_PT_MEDIUM_CHANGER == peripheral_type)) { /* tape device */
-            if (gTapeAlertsLPage) {
-                if (con->driveinfo)
-                    pout("TapeAlert Supported\n");
-                if (-1 == scsiGetTapeAlertsData(fd, peripheral_type))
-                    failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
-            }
-            else
-                pout("TapeAlert Not Supported\n");
-        } else { /* disk, cd/dvd, enclosure, etc */
-            scsiGetSmartData(fd, con->smartvendorattrib);
-        }
-    }   
-    if (con->smartvendorattrib) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        if (gTempLPage) {
-            if (con->checksmart)
-                pout("\n");
-            scsiPrintTemp(fd);         
-        }
-        if (gStartStopLPage)
-            scsiGetStartStopData(fd);
-        if (SCSI_PT_DIRECT_ACCESS == peripheral_type) {
-            if (gSeagateCacheLPage)
-                scsiPrintSeagateCacheLPage(fd);
-            if (gSeagateFactoryLPage)
-                scsiPrintSeagateFactoryLPage(fd);
-        }
-    }
-    if (con->smarterrorlog) {
-        scsiPrintErrorCounterLog(fd);
-        if (1 == scsiFetchControlGLTSD(fd, modese_len, 1))
-            pout("\n[GLTSD (Global Logging Target Save Disable) set. "
-                 "Enable Save with '-S on']\n");
-    }
-    if (con->smartselftestlog) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        res = 0;
-        if (gSelfTestLPage)
-            res = scsiPrintSelfTest(fd);
-        else {
-            pout("Device does not support Self Test logging\n");
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-        }
-        if (0 != res)
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    if (con->smartexeoffimmediate) {
-        if (scsiSmartDefaultSelfTest(fd)) {
-            pout( "Default Self Test Failed\n");
-            return returnval;
-        }
-        pout("Default Self Test Successful\n");
-    }
-    if (con->smartshortcapselftest) {
-        if (scsiSmartShortCapSelfTest(fd)) {
-            pout("Short Foreground Self Test Failed\n");
-            return returnval;
-        }
-        pout("Short Foreground Self Test Successful\n");
-    }
-    if (con->smartshortselftest ) { 
-        if ( scsiSmartShortSelfTest(fd)) {
-            pout("Short Background Self Test Failed\n");
-            return returnval;
-        }
-        pout("Short Background Self Test has begun\n");
-        pout("Use smartctl -X to abort test\n");
-    }
-    if (con->smartextendselftest) {
-        if (scsiSmartExtendSelfTest(fd)) {
-            pout("Extended Background Self Test Failed\n");
-            return returnval;
-        }
-        pout("Extended Background Self Test has begun\n");
-        if ((0 == scsiFetchExtendedSelfTestTime(fd, &durationSec, 
-                        modese_len)) && (durationSec > 0)) {
-            time_t t = time(NULL);
-
-            t += durationSec;
-            pout("Please wait %d minutes for test to complete.\n", 
-                 durationSec / 60);
-            pout("Estimated completion time: %s\n", ctime(&t));
-        }
-        pout("Use smartctl -X to abort test\n");        
-    }
-    if (con->smartextendcapselftest) {
-        if (scsiSmartExtendCapSelfTest(fd)) {
-            pout("Extended Foreground Self Test Failed\n");
-            return returnval;
-        }
-        pout("Extended Foreground Self Test Successful\n");
-    }
-    if (con->smartselftestabort) {
-        if (scsiSmartSelfTestAbort(fd)) {
-            pout("Self Test Abort Failed\n");
-            return returnval;
-        }
-        pout("Self Test returned without error\n");
-    }           
-    return returnval;
-}
diff --git a/sm5/scsiprint.h b/sm5/scsiprint.h
deleted file mode 100644
index f1b2eae58084b78a94d13c752ba452601f772b3d..0000000000000000000000000000000000000000
--- a/sm5/scsiprint.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * scsiprint.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003-4 Douglas Gilbert <dougg@torque.net>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-
-/* scsismart version number */
-#ifndef SCSI_PRINT_H_
-#define SCSI_PRINT_H_
-
-#define SCSIPRINT_H_CVSID "$Id: scsiprint.h,v 1.18 2004/01/27 15:29:17 ballen4705 Exp $\n"
-
-int scsiPrintMain(int fd);
-
-#endif
diff --git a/sm5/smartctl.8.in b/sm5/smartctl.8.in
deleted file mode 100644
index e64f4a54b7b56b313b06837e3fffbd462cac777b..0000000000000000000000000000000000000000
--- a/sm5/smartctl.8.in
+++ /dev/null
@@ -1,1236 +0,0 @@
-.ig
- Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
- $Id: smartctl.8.in,v 1.57 2004/07/16 15:49:56 ballen4705 Exp $
- 
- 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, write to the Free Software Foundation, Inc., 675
- Mass Ave, Cambridge, MA 02139, USA.
-
- This code was originally developed as a Senior Thesis by Michael Cornwell
- at the Concurrent Systems Laboratory (now part of the Storage Systems
- Research Center), Jack Baskin School of Engineering, University of
- California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-
-..
-.TH SMARTCTL 8 CURRENT_CVS_DATE CURRENT_CVS_VERSION CURRENT_CVS_DATE
-.SH NAME
-\fBsmartctl\fP \- Control and Monitor Utility for SMART Disks
-
-.SH SYNOPSIS
-.B smartctl [options] device
-
-.SH FULL PATH
-.B /usr/sbin/smartctl
-
-.SH PACKAGE VERSION
-CURRENT_CVS_VERSION released CURRENT_CVS_DATE at CURRENT_CVS_TIME
-
-.SH DESCRIPTION
-\fBsmartctl\fP controls the Self\-Monitoring, Analysis and Reporting
-Technology (SMART) system built into many ATA\-3 and later ATA, IDE and
-SCSI\-3 hard drives. The purpose of SMART is to monitor the reliability
-of the hard drive and predict drive failures, and to carry out
-different types of drive self\-tests.  This version of \fBsmartctl\fP
-is compatible with ATA/ATAPI\-5 and earlier standards (see REFERENCES
-below)
-
-\fBsmartctl\fP is a command line utility designed to perform SMART
-tasks such as printing the SMART self\-test and error logs, enabling
-and disabling SMART automatic testing, and initiating device
-self\-tests. Note: if the user issues a SMART command that is
-(apparently) not implemented by the device, \fBsmartctl\fP will print
-a warning message but issue the command anyway (see the \fB\-T,
-\-\-tolerance\fP option below).  This should not cause problems: on
-most devices, unimplemented SMART commands issued to a drive are
-ignored and/or return an error.
-
-\fBsmartctl\fP also provides support for polling TapeAlert messages
-from SCSI tape drives and changers.
-
-The user must specify the device to be controlled or interrogated as
-the final argument to \fBsmartctl\fP.  Device paths are as follows:
-.IP \fBLINUX\fP: 9
-Use the forms \fB"/dev/hd[a\-t]"\fP for IDE/ATA
-devices, and \fB"/dev/sd[a\-z]"\fP for SCSI devices. For
-SCSI Tape Drives and Changers with TapeAlert support use the devices
-\fB"/dev/nst*"\fP and \fB"/dev/sg*"\fP. 
-More general paths (such as devfs ones) may also be specified.
-.IP \fBFREEBSD\fP: 9
-Use the forms \fB"/dev/ad[0\-9]+"\fP for IDE/ATA
-devices and \fB"/dev/da[0\-9]+"\fP for SCSI devices.
-.IP \fBNETBSD\fP: 9
-Use the form \fB"/dev/wd[0\-9]+[cd]"\fP for IDE/ATA
-devices.  Be sure to specify correct "whole disk" partition letter
-for your architecture.
-.IP \fBSOLARIS\fP: 9
-Use the forms \fB"/dev/rdsk/c?t?d?s?"\fP for IDE/ATA and SCSI disk
-devices, and \fB"/dev/rmt/*"\fP for SCSI tape devices.
-.IP \fBWINDOWS\fP: 9
-Use the forms \fB"/dev/hd[a\-j]"\fP for IDE/ATA devices
-"\\\\.\\PhysicalDisk[0\-9]" on WinNT4/2000/XP,
-\fB"/dev/hd[a\-d]"\fP for standard IDE/ATA devices on Win95/98/98SE/ME,
-and \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices on ASPI adapter 0\-9, ID 0\-15.
-The prefix \fB"/dev/"\fP is optional.
-.IP \fBCYGWIN\fP: 9
-See "WINDOWS" above.
-.PP
-Based on the device path, \fBsmartctl\fP will guess the device type
-(ATA or SCSI).  If necessary, the \'\-d\' option can be used to over\-ride
-this guess
-
-Note that the printed output of \fBsmartctl\fP displays most numerical
-values in base 10 (decimal), but some values are displayed in base 16
-(hexidecimal).  To distinguish them, the base 16 values are always
-displayed with a leading \fB"0x"\fP, for example: "0xff". This man
-page follows the same convention.
-
-.PP
-.SH OPTIONS
-.PP
-The options are grouped below into several categories.  \fBsmartctl\fP
-will execute the corresponding commands in the order: INFORMATION,
-ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
-
-SCSI devices only accept the options \fB\-h, \-V, \-i, \-a, \-A, \-d,
-\-s, \-S,\-H, \-t, \-C, \-l selftest, \-l error, \-r,\fP and
-\fB\-X\fP.  TapeAlert devices only accept the options \fB\-h, \-V,
-\-i, \-a, \-A, \-d, \-s, \-S, \-t, \-l selftest, \-l error, \-r,\fP
-and \fB\-H\fP.
-
-Long options  are  not  supported  on  all  systems.   Use
-.B \'smartctl \-h\'
-to see the available options.
-
-.TP
-.B SHOW INFORMATION OPTIONS:
-.TP
-.B \-h, \-\-help, \-\-usage
-Prints a usage message to STDOUT and exits.
-.TP
-.B \-V, \-\-version, \-\-copyright, \-\-license
-Prints version, copyright, license, home page and CVS\-id information
-for your copy of \fBsmartctl\fP to STDOUT and then exits.  Please
-include this information if you are reporting bugs or problems.
-.TP
-.B \-i, \-\-info
-Prints the device model number, serial number, firmware version, and
-ATA Standard version/revision information.  Says if the device
-supports SMART, and if so, whether SMART support is currently enabled
-or disabled.  If the device supports Logical Block Address mode (LBA
-mode) print current user drive capacity in bytes. (If drive is has a
-user protected area reserved, or is "clipped", this may be smaller
-than the potential maximum drive capacity.)
-.TP
-.B \-a, \-\-all
-Prints all SMART information about the disk, or TapeAlert information
-about the tape drive or changer.  For ATA devices this is equivalent
-to
-.nf
-\'\-H \-i \-c \-A \-l error \-l selftest -l selective\'
-.fi
-and for SCSI, this is equivalent to
-.nf
-\'\-H \-i \-A \-l error \-l selftest\'.
-.fi
-Note that for ATA disks this does \fBnot\fP enable the \'\-l
-directory\' option.
-
-.TP
-.B RUN\-TIME BEHAVIOR OPTIONS:
-.TP
-.B \-q TYPE, \-\-quietmode=TYPE
-Specifies that \fBsmartctl\fP should run in one of the two quiet modes
-described here.  The valid arguments to this option are:
-
-.I errorsonly
-\- only print: For the \'\-l error\' option, if nonzero, the number
-of errors recorded in the SMART error log and the power\-on time when
-they occurred; For the \'\-l selftest\' option, errors recorded in the device
-self\-test log; For the \'\-H\' option, SMART "disk failing" status or device
-Attributes (pre\-failure or usage) which failed either now or in the
-past; For the \'\-A\' option, device Attributes (pre\-failure or usage)
-which failed either now or in the past.
-
-.I silent
-\- print no output.  The only way to learn about what was found is to
-use the exit status of \fBsmartctl\fP (see RETURN VALUES below).
-.TP
-.B \-d TYPE, \-\-device=TYPE
-Specifies the type of the device.  The valid arguments to this option
-are \fIata\fP, \fIscsi\fP, and \fI3ware,N\fP. If this option is not
-used then \fBsmartctl\fP will attempt to guess the device type from
-the device name.
-
-To look at ATA disks behind 3ware SCSI RAID controllers, use syntax
-such as:
-.nf
-\fBsmartctl \-a \-d 3ware,2 /dev/sda\fP
-.fi
-.nf
-\fBsmartctl \-a \-d 3ware,0 /dev/twe0\fP
-.fi
-.nf
-\fBsmartctl \-a \-d 3ware,1 /dev/twa0\fP
-.fi
-where in the argument \fI3ware,N\fP, the integer N is the disk number
-(3ware \'port\') within the 3ware ATA RAID controller.  The allowed
-values of N are from 0 to 15 inclusive.  The first two forms, which
-refer to devices /dev/sda-z and /dev/twe0-15, may be used with 3ware
-series 6000, 7000, and 8000 series controllers that use the 3x-xxxx
-driver.  The final form, which refers to devices /dev/twa0-15, must be
-used with 3ware 9000 series controllers, which use the 3w-9xxx driver.
-
-Note that if the special character device nodes /dev/twa? and
-/dev/twe? do not exist, or exist with the incorrect major or minor
-numbers, smartctl will recreate them on the fly.  Typically /dev/twa0
-refers to the first 9000-series controller, /dev/twa1 refers to the
-second 9000 series controller, and so on. Likewise /dev/twe0 refers to
-the first 6/7/8000-series controller, /dev/twa1 refers to the second
-6/7/8000 series controller, and so on.
-
-Note that for the 6/7/8000 controllers, \fBany\fP of the physical
-disks can be queried or examined using \fBany\fP of the 3ware's SCSI
-logical device /dev/sd?  entries.  Thus, if logical device /dev/sda is
-made up of two physical disks (3ware ports zero and one) and logical
-device /dev/sdb is made up of two other physical disks (3ware ports
-two and three) then you can examine the SMART data on \fBany\fP of the
-four physical disks using \fBeither\fP SCSI device /dev/sda \fBor\fP
-/dev/sdb.  If you need to know which logical SCSI device a particular
-physical disk (3ware port) is associated with, use the dmesg or SYSLOG
-output to show which SCSI ID corresponds to a particular 3ware unit,
-and then use the 3ware CLI or 3dm tool to determine which ports
-(physical disks) correspond to particular 3ware units.
-
-If the value of N corresponds to a port that does \fBnot\fP exist on
-the 3ware controller, or to a port that does not physically have a
-disk attached to it, the behavior of \fBsmartctl\fP depends upon the
-specific controller model, firmware, Linux kernel and platform.  In
-some cases you will get a warning message that the device does not
-exist. In other cases you will be presented with \'void\' data for a
-non\-existent device.
-
-Note that if the /dev/sd? addressing form is used, then older 3w\-xxxx
-drivers do not pass the "Enable Autosave"
-(\'\fB\-S on\fP\') and "Enable Automatic Offline" (\'\fB\-o on\fP\')
-commands to the disk, and produce these types of harmless syslog error
-messages instead: "\fB3w\-xxxx: tw_ioctl(): Passthru size (123392) too
-big\fP". This can be fixed by upgrading to version 1.02.00.037 or
-later of the 3w\-xxxx driver, or by applying a patch to older
-versions. See \fBhttp://smartmontools.sourceforge.net/\fP for
-instructions.  Alternatively, use the character device /dev/twe0-15 interface.
-
-The selective self-test functions ('-t select,A-B') are only supported
-using the character device interface /dev/twa0-15 and /dev/twe0-15.
-The necessary WRITE LOG commands can not be passed through the SCSI
-interface.
-
-.B 3ware controllers are currently ONLY supported under Linux.
-
-.TP
-.B \-T TYPE, \-\-tolerance=TYPE
-Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART command
-failures. 
-
-The behavior of \fBsmartctl\fP depends upon whether the command is
-"\fBoptional\fP" or "\fBmandatory\fP". Here "\fBmandatory\fP" means
-"required by the ATA/ATAPI\-5 Specification if the device implements
-the SMART command set" and "\fBoptional\fP" means "not required by the
-ATA/ATAPI\-5 Specification even if the device implements the SMART
-command set."  The "\fBmandatory\fP" ATA and SMART commands are: (1)
-ATA IDENTIFY DEVICE, (2) SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE, (3)
-SMART ENABLE/DISABLE, and (4) SMART RETURN STATUS.
-
-The valid arguments to this option are:
-
-.I normal
-\- exit on failure of any \fBmandatory\fP SMART command, and ignore
-all failures of \fBoptional\fP SMART commands.  This is the default.
-Note that on some devices, issuing unimplemented optional SMART
-commands doesn\'t cause an error.  This can result in misleading
-\fBsmartctl\fP messages such as "Feature X not implemented", followed
-shortly by "Feature X: enabled".  In most such cases, contrary to the
-final message, Feature X is \fBnot\fP enabled.
-
-.I conservative
-\- exit on failure of any \fBoptional\fP SMART command.
-
-.I permissive
-\- ignore failure(s) of \fBmandatory\fP SMART commands.  This option
-may be given more than once.  Each additional use of this option will
-cause one more additional failure to be ignored.  Note that the use of
-this option can lead to messages like "Feature X not implemented",
-followed shortly by "Error: unable to enable Feature X".  In a few
-such cases, contrary to the final message, Feature X \fBis\fP enabled.
-
-.I verypermissive
-\- equivalent to giving a large number of \'\-T permissive\' options:
-ignore failures of \fBany number\fP of \fBmandatory\fP SMART commands.
-Please see the note above.
-
-.TP
-.B \-b TYPE, \-\-badsum=TYPE
-Specifies the action \fBsmartctl\fP should take if a checksum error is
-detected in the: (1) Device Identity Structure, (2) SMART Self\-Test
-Log Structure, (3) SMART Attribute Value Structure, (4) SMART
-Attribute Threshold Structure, or (5) ATA Error Log Structure.
-
-The valid arguments to this option are:
-
-.I warn
-\- report the incorrect checksum but carry on in spite of it.  This is the
-default.
-
-.I exit
-\- exit \fBsmartctl\fP.
-
-.I ignore
-\- continue silently without issuing a warning.
-
-.TP
-.B \-r TYPE, \-\-report=TYPE
-Intended primarily to help \fBsmartmontools\fP developers understand
-the behavior of \fBsmartmontools\fP on non\-conforming or poorly
-conforming hardware.  This option reports details of \fBsmartctl\fP
-transactions with the device.  The option can be used multiple times.
-When used just once, it shows a record of the ioctl() transactions
-with the device.  When used more than once, the detail of these
-ioctl() transactions are reported in greater detail.  The valid
-arguments to this option are:
-
-.I ioctl
-\- report all ioctl() transactions.
-
-.I ataioctl
-\- report only ioctl() transactions with ATA devices.
-
-.I scsiioctl
-\- report only ioctl() transactions with SCSI devices. Invoking this once
-shows the SCSI commands in hex and the corresponding status. Invoking
-it a second time adds a hex listing of the first 64 bytes of data send to, 
-or received from the device.
-
-Any argument may include a positive integer to specify the level of detail
-that should be reported.  The argument should be followed by a comma then
-the integer with no spaces.  For example, 
-.I ataioctl,2
-The default
-level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are equivalent.
-
-.TP
-.B SMART FEATURE ENABLE/DISABLE COMMANDS:
-.IP
-.B Note: 
-if multiple options are used to both enable and disable a
-feature, then 
-.B both
-the enable and disable commands will be issued.  The enable command
-will always be issued
-.B before
-the corresponding disable command.
-.TP
-.B \-s VALUE, \-\-smart=VALUE 
-Enables or disables SMART on device.  The valid arguments to
-this option are \fIon\fP and \fIoff\fP.  Note that the command \'\-s on\'
-(perhaps used with with the \'\-o on\' and \'\-S on\' options) should be placed
-in a start\-up script for your machine, for example in rc.local or rc.sysinit.
-In principle the SMART feature settings are preserved over
-power\-cycling, but it doesn\'t hurt to be sure. It is not necessary (or
-useful) to enable SMART to see the TapeAlert messages.
-.TP
-.B \-o VALUE, \-\-offlineauto=VALUE
-Enables or disables SMART automatic offline test, which scans the drive
-every four hours for disk defects. This command can be given during normal
-system operation.  The valid arguments to this option are \fIon\fP
-and \fIoff\fP.
-
-Note that the SMART automatic offline test command is listed as
-"Obsolete" in every version of the ATA and ATA/ATAPI Specifications.
-It was originally part of the SFF\-8035i Revision 2.0 specification,
-but was never part of any ATA specification.  However it is
-implemented and used by many vendors. [Good documentation can be found
-in IBM\'s Official Published Disk Specifications.  For example the IBM
-Travelstar 40GNX Hard Disk Drive Specifications (Revision 1.1, 22
-April 2002, Publication # 1541, Document S07N\-7715\-02) page 164. You
-can also read the SFF\-8035i Specification \-\- see REFERENCES below.]
-You can tell if automatic offline testing is supported by seeing if
-this command enables and disables it, as indicated by the \'Auto
-Offline Data Collection\' part of the SMART capabilities report
-(displayed with \'\-c\').
-
-SMART provides \fBthree\fP basic categories of testing.  The
-\fBfirst\fP category, called "online" testing, has no effect on the
-performance of the device.  It is turned on by the \'\-s on\' option.
-
-The \fBsecond\fP category of testing is called "offline" testing. This
-type of test can, in principle, degrade the device performance.  The
-\'\-o on\' option causes this offline testing to be carried out,
-automatically, on a regular scheduled basis.  Normally, the disk will
-suspend offline testing while disk accesses are taking place, and then
-automatically resume it when the disk would otherwise be idle, so in
-practice it has little effect.  Note that a one\-time offline test can
-also be carried out immediately upon receipt of a user command.  See
-the \'\-t offline\' option below, which causes a one\-time offline test
-to be carried out immediately.
-
-The choice (made by the SFF\-8035i and ATA specification authors) of
-the word \fItesting\fP for these first two categories is unfortunate,
-and often leads to confusion.  In fact these first two categories of
-online and offline testing could have been more accurately described
-as online and offline \fBdata collection\fP.
-
-The results of this automatic or immediate offline testing (data
-collection) are reflected in the values of the SMART Attributes.
-Thus, if problems or errors are detected, the values of these
-Attributes will go below their failure thresholds; some types of
-errors may also appear in the SMART error log. These are visible with
-the \'\-A\' and \'\-l error\' options respectively.
-
-Some SMART attribute values are updated only during off\-line data
-collection activities; the rest are updated during normal operation of
-the device or during both normal operation and off\-line testing.  The
-Attribute value table produced by the \'\-A\' option indicates this in
-the UPDATED column.  Attributes of the first type are labeled
-"Offline" and Attributes of the second type are labeled "Always".
-
-The \fBthird\fP category of testing (and the \fIonly\fP category for
-which the word \'testing\' is really an appropriate choice) is "self"
-testing.  This third type of test is only performed (immediately) when
-a command to run it is issued.  The \'\-t\' and \'\-X\' options can be
-used to carry out and abort such self\-tests; please see below for
-further details.
-
-Any errors detected in the self testing will be shown in the
-SMART self\-test log, which can be examined using the \'\-l selftest\'
-option.
-
-\fBNote:\fP in this manual page, the word \fB"Test"\fP is used in
-connection with the second category just described, e.g. for the
-"offline" testing.  The words \fB"Self\-test"\fP are used in
-connection with the third category.
-.TP
-.B \-S VALUE, \-\-saveauto=VALUE
-Enables or disables SMART autosave of device vendor\-specific
-Attributes. The valid arguments to this option are \fIon\fP
-and \fIoff\fP.  Note that this feature is preserved across disk power
-cycles, so you should only need to issue it once.
-
-For SCSI devices this toggles the value of the Global Logging Target
-Save Disabled (GLTSD) bit in the Control Mode Page. Some disk
-manufacturers set this bit by default. This prevents error counters,
-power\-up hours and other useful data from being placed in non\-volatile
-storage, so these values may be reset to zero the next time the device
-is power\-cycled.  If the GLTSD bit is set then \'smartctl \-a\' will
-issue a warning. Use \fIon\fP to clear the GLTSD bit and thus enable
-saving counters to non\-volatile storage. For extreme streaming\-video
-type applications you might consider using \fIoff\fP to set the GLTSD
-bit.
-
-.TP
-.B SMART READ AND DISPLAY DATA OPTIONS:
-.TP
-.B \-H, \-\-health
-Check: Ask the device to report its SMART health status or pending
-TapeAlert messages.  SMART status is based on
-information that it has gathered from online and offline
-tests, which were used to determine/update its
-SMART vendor\-specific Attribute values. TapeAlert status is obtained
-by reading the TapeAlert log page.
-
-If the device reports failing health status, this means
-.B either
-that the device has already failed, 
-.B or 
-that it is predicting its own failure within the next 24 hours.  If
-this happens, use the \'\-a\' option to get more information, and
-.B get your data off the disk and someplace safe as soon as you can.
-.TP
-.B \-c, \-\-capabilities
-Prints only the generic SMART capabilities.  These show
-what SMART features are implemented and how the device will
-respond to some of the different SMART commands.  For example it
-shows if the device logs errors, if it supports offline surface
-scanning, and so on.  If the device can carry out self\-tests, this
-option also shows the estimated time required to run those tests.
-
-Note that the time required to run the Self\-tests (listed in minutes)
-are fixed.  However the time required to run the Immediate Offline
-Test (listed in seconds) is variable.  This means that if you issue a
-command to perform an Immediate Offline test with the \'\-t offline\' option,
-then the time may jump to a larger value and then count down as the
-Immediate Offline Test is carried out.  Please see REFERENCES below
-for further information about the the flags and capabilities described
-by this option.
-.TP
-.B \-A, \-\-attributes
-Prints only the vendor specific SMART Attributes.  The Attributes are
-numbered from 1 to 253 and have specific names and ID numbers. For
-example Attribute 12 is "power cycle count": how many times has the
-disk been powered up.
-
-Each Attribute has a "Raw" value, printed under the heading
-"RAW_VALUE", and a "Normalized" value printed under the heading
-"VALUE".  [Note: \fBsmartctl\fP prints these values in base\-10.]  In
-the example just given, the "Raw Value" for Attribute 12 would be the
-actual number of times that the disk has been power\-cycled, for
-example 365 if the disk has been turned on once per day for exactly
-one year.  Each vendor uses their own algorithm to convert this "Raw"
-value to a "Normalized" value in the range from 1 to 254.  Please keep
-in mind that \fBsmartctl\fP only reports the different Attribute
-types, values, and thresholds as read from the device.  It does
-\fBnot\fP carry out the conversion between "Raw" and "Normalized"
-values: this is done by the disk\'s firmware.
-
-The conversion from Raw value to a quantity with physical units is
-not specified by the SMART standard. In most cases, the values printed
-by \fBsmartctl\fP are sensible.  For example the temperature Attribute
-generally has its raw value equal to the temperature in Celsius.
-However in some cases vendors use unusual conventions.  For example
-the Hitachi disk on my laptop reports its power\-on hours in minutes,
-not hours. Some IBM disks track three temperatures rather than one, in
-their raw values.  And so on.
-
-Each Attribute also has a Threshold value (whose range is 0 to 255)
-which is printed under the heading "THRESH".  If the Normalized value
-is \fBless than or equal to\fP the Threshold value, then the Attribute
-is said to have failed.  If the Attribute is a pre\-failure Attribute,
-then disk failure is imminent.
-
-Each Attribute also has a "Worst" value shown under the heading
-"WORST".  This is the smallest (closest to failure) value that the
-disk has recorded at any time during its lifetime when SMART was
-enabled.  [Note however that some vendors firmware may actually
-\fBincrease\fP the "Worst" value for some "rate\-type" Attributes.]
-
-The Attribute table printed out by \fBsmartctl\fP also shows the
-"TYPE" of the Attribute. Attributes are one of two possible types:
-Pre\-failure or Old age.  Pre\-failure Attributes are ones which, if
-less than or equal to their threshold values, indicate pending disk
-failure.  Old age, or usage Attributes, are ones which indicate
-end\-of\-product life from old\-age or normal aging and wearout, if
-the Attribute value is less than or equal to the threshold.  \fBPlease
-note\fP: the fact that an Attribute is of type 'Pre\-fail' does
-\fBnot\fP mean that your disk is about to fail!  It only has this
-meaning if the Attribute\'s current Normalized value is less than or
-equal to the threshold value.
-
-If the Attribute\'s current Normalized value is less than or equal to
-the threshold value, then the "WHEN_FAILED" column will display
-"FAILING_NOW". If not, but the worst recorded value is less than or
-equal to the threshold value, then this column will display
-"In_the_past".  If the "WHEN_FAILED" column has no entry (indicated by
-a dash: \'\-\') then this Attribute is OK now (not failing) and has
-also never failed in the past.
-
-The table column labeled "UPDATED" shows if the SMART Attribute values
-are updated during both normal operation and off\-line testing, or
-only during offline testing.  The former are labeled "Always" and the
-latter are labeled "Offline".
-
-So to summarize: the Raw Attribute values are the ones that might have
-a real physical interpretation, such as "Temperature Celsius",
-"Hours", or "Start\-Stop Cycles".  Each manufacturer converts these,
-using their detailed knowledge of the disk\'s operations and failure
-modes, to Normalized Attribute values in the range 1\-254.  The
-current and worst (lowest measured) of these Normalized Attribute
-values are stored on the disk, along with a Threshold value that the
-manufacturer has determined will indicate that the disk is going to
-fail, or that it has exceeded its design age or aging limit.
-\fBsmartctl\fP does \fBnot\fP calculate any of the Attribute values,
-thresholds, or types, it merely reports them from the SMART data on
-the device.
-
-Note that starting with ATA/ATAPI\-4, revision 4, the meaning of these
-Attribute fields has been made entirely vendor\-specific.  However most
-ATA/ATAPI\-5 disks seem to respect their meaning, so we have retained
-the option of printing the Attribute values.
-
-For SCSI devices the "attributes" are obtained from the temperature
-and start-stop cycle counter log pages. Certain vendor specific
-attributes are listed if recognised. The attributes are output in a
-relatively free format (compared with ATA disk attributes).
-.TP
-.B \-l TYPE, \-\-log=TYPE
-Prints either the SMART Error Log, the SMART Self\-Test Log, the SMART
-Selective Self-Test Log [ATA only], or the Log Directory [ATA only].
-The valid arguments to this option are:
-
-.I error
-\- prints only the SMART error log.  SMART disks maintain a log of the
-most recent five non\-trivial errors. For each of these errors, the
-disk power\-on lifetime at which the error occurred is recorded, as is
-the device status (idle, standby, etc) at the time of the error.  For
-some common types of errors, the Error Register (ER) and Status
-Register (SR) values are decoded and printed as text. The meanings of these
-are:
-.nf
-   \fBABRT\fP:  Command \fBAB\fPo\fBRT\fPed
-   \fBAMNF\fP:  \fBA\fPddress \fBM\fPark \fBN\fPot \fBF\fPound
-   \fBCCTO\fP:  \fBC\fPommand \fBC\fPompletion \fBT\fPimed \fBO\fPut
-   \fBEOM\fP:   \fBE\fPnd \fBO\fPf \fBM\fPedia
-   \fBICRC\fP:  \fBI\fPnterface \fBC\fPyclic \fBR\fPedundancy \fBC\fPode (CRC) error
-   \fBIDNF\fP:  \fBID\fPentity \fBN\fPot \fBF\fPound
-   \fBILI\fP:   (packet command\-set specific)
-   \fBMC\fP:    \fBM\fPedia \fBC\fPhanged
-   \fBMCR\fP:   \fBM\fPedia \fBC\fPhange \fBR\fPequest
-   \fBNM\fP:    \fBN\fPo \fBM\fPedia
-   \fBobs\fP:   \fBobs\fPolete
-   \fBTK0NF\fP: \fBT\fPrac\fBK 0 N\fPot \fBF\fPound
-   \fBUNC\fP:   \fBUNC\fPorrectable Error in Data
-   \fBWP\fP:    Media is \fBW\fPrite \fBP\fProtected
-.fi
-In addition, up to the last five commands that preceded the error are
-listed, along with a timestamp measured from the start of the
-corresponding power cycle. This is displayed in the form
-Dd+HH:MM:SS.msec where D is the number of days, HH is hours, MM is
-minutes, SS is seconds and msec is milliseconds.  [Note: this time
-stamp wraps after 2^32 milliseconds, or 49 days 17 hours 2 minutes and
-47.296 seconds.]  The key ATA disk registers are also recorded in the
-log.  The final column of the error log is a text\-string description
-of the ATA command defined by the Command Register (CR) and Feature
-Register (FR) values.  Commands that are obsolete in the most current
-(ATA\-7) spec are listed like this: \fBREAD LONG (w/ retry) [OBS\-4]\fP,
-indicating that the command became obsolete with or in the ATA\-4
-specification.  Similarly, the notation \fB[RET\-\fP\fIN\fP\fB]\fP is
-used to indicate that a command was retired in the ATA\-\fIN\fP
-specification.  Some commands are not defined in any version of the
-ATA specification but are in common use nonetheless; these are marked
-\fB[NS]\fP, meaning non\-standard.
-
-The ATA Specification (ATA\-5 Revision 1c, Section 8.41.6.8.2) says:
-\fB"Error log structures shall include UNC errors, IDNF errors for
-which the address requested was valid, servo errors, write fault
-errors, etc.  Error log data structures shall not include errors
-attributed to the receipt of faulty commands such as command codes not
-implemented by the device or requests with invalid parameters or
-invalid addresses."\fP The definitions of these terms are:
-.br
-\fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable.  This refers
-to data which has been read from the disk, but for which the Error
-Checking and Correction (ECC) codes are inconsistent.  In effect, this
-means that the data can not be read.
-.br
-\fBIDNF\fP (\fBID N\fPot \fBF\fPound): user\-accessible address could
-not be found. For READ LOG type commands, \fBIDNF\fP can also indicate
-that a device data log structure checksum was incorrect.
-
-If the command that caused the error was a READ or WRITE command, then
-the Logical Block Address (LBA) at which the error occurred will be
-printed in base 10 and base 16.  The LBA is a linear address, which
-counts 512\-byte sectors on the disk, starting from zero.  (Because of
-the limitations of the SMART error log, if the LBA is greater than
-0xfffffff, then either no error log entry will be made, or the error
-log entry will have an incorrect LBA. This may happen for drives with
-a capacity greater than 128 GiB or 137 GB.) On Linux systems the
-smartmontools web page has instructions about how to convert the LBA
-address to the name of the disk file containing the erroneous disk
-sector.
-
-Please note that some manufacturers \fBignore\fP the ATA
-specifications, and make entries in the error log if the device
-receives a command which is not implemented or is not valid.
-
-.I error [SCSI]
-\- prints the error counter log pages for reads, write and verifies.
-The verify row is only output if it has an element other than zero.
-
-.I selftest
-\- prints the SMART self\-test log.  The disk maintains a self\-test log
-showing the results of the self tests, which can be run using the
-\'\-t\' option described below.  For each of the most recent
-twenty\-one self\-tests, the log shows the type of test (short or
-extended, off\-line or captive) and the final status of the test.  If
-the test did not complete successfully, then the percentage of the
-test remaining is shown.  The time at which the test took place,
-measured in hours of disk lifetime, is also printed.  If any errors
-were detected, the Logical Block Address (LBA) of the first error is
-printed in hexadecimal notation. On Linux systems the smartmontools
-web page has instructions about how to convert this LBA address to the
-name of the disk file containing the erroneous block.
-
-.I selftest [SCSI]
-\- the self\-test log for a SCSI device has a slightly different format
-than for an ATA device.  For each of the most recent twenty
-self\-tests, it shows the type of test and the status (final or in
-progress) of the test. SCSI standards use the terms "foreground" and
-"background" (rather than ATA\'s corresponding "captive" and
-"off\-line") and "short" and "long" (rather than ATA\'s corresponding
-"short" and "extended") to describe the type of the test.  The printed
-segment number is only relevant when a test fails in the third or
-later test segment.  It identifies the test that failed and consists
-of either the number of the segment that failed during the test, or
-the number of the test that failed and the number of the segment in
-which the test was run, using a vendor\-specific method of putting both
-numbers into a single byte.  The Logical Block Address (LBA) of the
-first error is printed in hexadecimal notation.  On Linux systems the
-smartmontools web page has instructions about how to convert this LBA
-address to the name of the disk file containing the erroneous block.
-If provided, the SCSI Sense Key (SK), Additional Sense Code (ASC) and
-Additional Sense Code Qualifier (ASQ) are also printed. The self tests
-can be run using the \'\-t\' option described below (using the ATA
-test terminology).
-
-.I selective [ATA]
-\- Some ATA\-7 disks (example: Maxtor) also maintain a selective
-self\-test log.  Please see the \'\-t select\' option below for a
-description of selective self\-tests.  The selective self\-test log
-shows the start/end Logical Block Addresses (LBA) of each of the five
-test spans, and their current test status.  If the span is being
-tested or the remainder of the disk is being read\-scanned, the
-current 65536\-sector block of LBAs being tested is also displayed.
-The selective self\-test log also shows if a read\-scan of the
-remainder of the disk will be carried out after the selective
-self\-test has completed (see \'\-t afterselect\' option) and the time
-delay before restarting this read\-scan if it is interrupted (see
-\'\-t pending\' option). This is a new smartmontools feature; please
-report unusual or incorrect behavior to the smartmontools\-support
-mailing list.
-
-.I directory
-\- if the device supports the General Purpose Logging feature set
-(ATA\-6 and ATA\-7 only) then this prints the Log Directory (the log at
-address 0).  The Log Directory shows what logs are available and their
-length in sectors (512 bytes).  The contents of the logs at address 1
-[Summary SMART error log] and at address 6 [SMART self\-test log] may
-be printed using the previously\-described
-.I error
-and
-.I selftest
-arguments to this option. [Please note: this is a new, experimental
-feature.  We would like to add support for printing the contents of
-extended and comprehensive SMART self\-test and error logs.  If your
-disk supports these, and you would like to assist, please contact the
-\fBsmartmontools\fP developers.]
-
-.TP
-.B \-v N,OPTION, \-\-vendorattribute=N,OPTION
-Sets a vendor\-specific display OPTION for Attribute N.  This option
-may be used multiple times. Valid arguments to this option are:
-
-.I help
-\- Prints (to STDOUT) a list of all valid arguments to this option,
-then exits.
-
-.I 9,minutes
-\- Raw Attribute number 9 is power\-on time in minutes.  Its raw value
-will be displayed in the form "Xh+Ym".  Here X is hours, and Y is
-minutes in the range 0\-59 inclusive.  Y is always printed with two
-digits, for example "06" or "31" or "00".
-
-.I 9,seconds
-\- Raw Attribute number 9 is power\-on time in seconds.  Its raw value
-will be displayed in the form "Xh+Ym+Zs".  Here X is hours, Y is
-minutes in the range 0\-59 inclusive, and Z is seconds in the range
-0\-59 inclusive.  Y and Z are always printed with two digits, for
-example "06" or "31" or "00".
-
-.I 9,halfminutes
-\- Raw Attribute number 9 is power\-on time, measured in units of 30
-seconds.  This format is used by some Samsung disks.  Its raw value
-will be displayed in the form "Xh+Ym".  Here X is hours, and Y is
-minutes in the range 0\-59 inclusive.  Y is always printed with two
-digits, for example "06" or "31" or "00".
-
-.I 9,temp
-\- Raw Attribute number 9 is the disk temperature in Celsius.
-
-.I 192,emergencyretractcyclect
-\- Raw Attribute number 192 is the Emergency Retract Cycle Count.
-
-.I 193,loadunload
-\- Raw Attribute number 193 contains two values. The first is the
-number of load cycles.  The second is the number of unload cycles.
-The difference between these two values is the number of times that
-the drive was unexpectedly powered off (also called an emergency
-unload). As a rule of thumb, the mechanical stress created by one
-emergency unload is equivalent to that created by one hundred normal
-unloads.
-
-.I 194,10xCelsius
-\- Raw Attribute number 194 is ten times the disk temperature in
-Celsius.  This is used by some Samsung disks (example: model SV1204H
-with RK100\-13 firmware).
-
-.I 194,unknown
-\- Raw Attribute number 194 is NOT the disk temperature, and its
-interpretation is unknown. This is primarily useful for the \-P
-(presets) option.
-
-.I 198,offlinescanuncsectorct
-\- Raw Attribute number 198 is the Offline Scan UNC Sector Count.
-
-.I 200,writeerrorcount
-\- Raw Attribute number 200 is the Write Error Count.
-
-.I 201,detectedtacount
-\- Raw Attribute number 201 is the Detected TA Count.
-
-.I 220,temp
-\- Raw Attribute number 220 is the disk temperature in Celsius.
-
-Note: a table of hard drive models, listing which Attribute
-corresponds to temperature, can be found at:
-http://coredump.free.fr/linux/hddtemp.db
-
-.I N,raw8
-\- Print the Raw value of Attribute N as six 8\-bit unsigned base\-10
-integers.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw8\' prints Raw values for ALL Attributes in this
-form.  The form (for example) \'123,raw8\' only prints the Raw value for
-Attribute 123 in this form.
-
-.I N,raw16
-\- Print the Raw value of Attribute N as three 16\-bit unsigned base\-10
-integers.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw16\' prints Raw values for ALL Attributes in this
-form.  The form (for example) \'123,raw16\' only prints the Raw value for
-Attribute 123 in this form.
-
-.I N,raw48
-\- Print the Raw value of Attribute N as a 48\-bit unsigned base\-10
-integer.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw48\' prints Raw values for ALL Attributes in
-this form.  The form (for example) \'123,raw48\' only prints the Raw
-value for Attribute 123 in this form.
-
-.TP
-.B \-F TYPE, \-\-firmwarebug=TYPE
-Modifies the behavior of \fBsmartctl\fP to compensate for some known
-and understood device firmware bug.  The arguments to this option are
-exclusive, so that only the final option given is used.  The valid
-values are:
-
-.I none
-\- Assume that the device firmware obeys the ATA specifications.  This
-is the default, unless the device has presets for \'\-F\' in the
-device database (see note below).
-
-.I samsung
-\- In some Samsung disks (example: model SV4012H Firmware Version:
-RM100\-08) some of the two\- and four\-byte quantities in the SMART data
-structures are byte\-swapped (relative to the ATA specification).
-Enabling this option tells \fBsmartctl\fP to evaluate these quantities
-in byte\-reversed order.  Some signs that your disk needs this option
-are (1) no self\-test log printed, even though you have run self\-tests;
-(2) very large numbers of ATA errors reported in the ATA error log;
-(3) strange and impossible values for the ATA error log timestamps.
-
-.I samsung2
-\- In more recent Samsung disks (firmware revisions ending in "\-23")
-the number of ATA errors reported is byte swapped.  Enabling this
-option tells \fBsmartctl\fP to evaluate this quantity in byte\-reversed
-order.
-
-Note that an explicit \'\-F\' option on the command line will
-over\-ride any preset values for \'\-F\' (see the \'\-P\' option
-below).
-
-.TP
-.B \-P TYPE, \-\-presets=TYPE
-Specifies whether \fBsmartctl\fP should use any preset options that
-are available for this drive. By default, if the drive is recognized
-in the \fBsmartmontools\fP database, then the presets are used.
-
-\fBsmartctl\fP can automatically set appropriate options for known
-drives.  For example, the Maxtor 4D080H4 uses Attribute 9 to stores
-power\-on time in minutes whereas most drives use that Attribute to
-store the power\-on time in hours.  The command\-line option \'-v
-9,minutes\' ensures that \fBsmartctl\fP correctly interprets Attribute
-9 in this case, but that option is preset for the Maxtor 4D080H4 and
-so need not be specified by the user on the \fBsmartctl\fP command
-line.
-
-The argument
-.I show
-will show any preset options for your drive and the argument
-.I showall
-will show all known drives in the \fBsmartmontools\fP database, along
-with their preset options.  If there are no presets for your drive and
-you think there should be (for example, a \-v or \-F option is needed
-to get \fBsmartctl\fP to display correct values) then please contact
-the \fBsmartmontools\fP developers so that this information can be
-added to the \fBsmartmontools\fP database.  Contact information is at the
-end of this man page.
-
-The valid arguments to this option are:
-
-.I use
-\- if a drive is recognized, then use the stored presets for it.  This
-is the default. Note that presets will NOT over\-ride additional
-Attribute interpretation (\'-v N,something\') command\-line options or
-explicit \'\-F\' command\-line options..
-
-.I ignore
-\- do not use presets.
-
-.I show
-\- show if the drive is recognized in the database, and if so, its
-presets, then exit.
-
-.I showall
-\- list all recognized drives, and the presets that are set for them,
-then exit.
-
-.TP
-.B SMART RUN/ABORT OFFLINE TEST AND SELF\-TEST OPTIONS:
-.TP
-.B \-t TEST, \-\-test=TEST
-Executes TEST immediately.  The \'\-C\' option can be used in
-conjunction with this option to run the short or long (and also for
-ATA devices, selective or conveyance) self\-tests in captive mode
-(known as "foreground mode" for SCSI devices).  Note that only one
-test can be run at a time, so this option should only be used once per
-command line.
-
-The valid arguments to this option are:  
-
-.I offline
-\- runs SMART Immediate Offline Test.  This immediately
-starts the test described above.  This command can be given during
-normal system operation.  The effects of this test are visible only in
-that it updates the SMART Attribute values, and if errors are
-found they will appear in the SMART error log, visible with the \'\-l error\'
-option. [In the case of SCSI devices runs the default self test in
-foreground. No entry is placed in the self test log.]
-
-If the \'\-c\' option to \fBsmartctl\fP shows that the device has the
-"Suspend Offline collection upon new command" capability then you can
-track the progress of the Immediate Offline test using the \'\-c\'
-option to \fBsmartctl\fP.  If the \'\-c\' option show that the device
-has the "Abort Offline collection upon new command" capability then
-most commands will abort the Immediate Offline Test, so you should not
-try to track the progress of the test with \'\-c\', as it will abort
-the test.
-
-.I short
-\- runs SMART Short Self Test (usually under ten minutes).
-[Note: in the case of SCSI devices,
-this command option runs the "Background short" self\-test.]
-This command can be given during normal system operation (unless run in
-captive mode \- see the \'\-C\' option below).  This is a
-test in a different category than the immediate or automatic offline
-tests.  The "Self" tests check the electrical and mechanical
-performance as well as the read performance of the disk.  Their
-results are reported in the Self Test Error Log, readable with
-the \'\-l selftest\' option.  Note that on some disks the progress of the
-self\-test can be monitored by watching this log during the self\-test; with other disks
-use the \'\-c\' option to monitor progress.
-
-.I long
-\- runs SMART Extended Self Test (tens of minutes).
-[Note: in the case of SCSI devices,
-this command option runs the "Background long" self\-test.]
-This is a
-longer and more thorough version of the Short Self Test described
-above.  Note that this command can be given during normal
-system operation (unless run in captive mode \- see the \'\-C\' option below).
-
-.I conveyance
-\- [ATA ONLY] runs a SMART Conveyance Self Test (minutes).  This
-self\-test routine is intended to identify damage incurred during
-transporting of the device. This self\-test routine should take on the
-order of minutes to complete.  Note that this command can be given
-during normal system operation (unless run in captive mode \- see the
-\'\-C\' option below).
-
-.I select,N\-M
-
-\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] runs a SMART
-Selective Self Test, to test a \fBrange\fP of disk Logical Block
-Addresses (LBAs), rather than the entire disk.  Each range of LBAs
-that is checked is called a "span" and is specified by a starting LBA
-(N) and an ending LBA (M) with N less than or equal to M.  For example
-the command:
-.nf
-  smartctl \-t select,10\-20 /dev/hda
-.fi
-runs a self test on one span consisting of LBAs ten to twenty
-(inclusive). The \'\-t\' option can be given up to five times, to test
-up to five spans.  For example the command:
-.nf
-  smartctl \-t select,0\-100 \-t select,1000\-2000 /dev/hda
-.fi
-runs a self test on two spans.  The first span consists of 101 LBAs
-and the second span consists of 1001 LBAs.  Note that the spans can
-overlap partially or completely, for example:
-.nf
-  smartctl \-t select,0\-10 \-t select,5\-15 \-t select,10\-20 /dev/hda
-.fi
-The results of the selective self\-test can be obtained (both during
-and after the test) by printing the SMART self\-test log, using the
-\'\-l selftest\' option to smartctl.
-
-Selective self tests are particularly useful as disk capacities
-increase: an extended self test (smartctl \-t long) can take several
-hours.  Selective self\-tests are helpful if (based on SYSLOG error
-messages, previous failed self\-tests, or SMART error log entries) you
-suspect that a disk is having problems at a particular range of
-Logical Block Addresses (LBAs).
-
-Selective self\-tests can be run during normal system operation (unless
-done in captive mode \- see the \'\-C\' option below).
-
-[Note: this new experimental smartmontools feature is currently only
-available under Linux.  The Linux kernel must be compiled with the
-configuration option CONFIG_IDE_TASKFILE_IO enabled.  Please report
-unusual or incorrect behavior to the smartmontools\-support mailing
-list.]
-
-.I afterselect,on
-\- [ATA ONLY] perform an offline read scan after a Selective Self\-test
-has completed. This option must be used together with one or more of
-the \fIselect,N\-M\fP options above. If the LBAs that have been
-specified in the Selective self\-test pass the test with no errors
-found, then read scan the \fBremainder\fP of the disk.  If the device
-is powered\-cycled while this read scan is in progress, the read scan
-will be automatically resumed after a time specified by the pending
-timer (see below).  The value of this option is preserved between
-selective self\-tests.
-
-.I afterselect,off
-\- [ATA ONLY] do not read scan the remainder of the disk after a
-Selective self\-test has completed.  This option must be use together
-with one or more of the \fIselect,N\-M\fP options above.  The value of this
-option is preserved between selective self\-tests.
-
-.I pending,N 
-\- [ATA ONLY] set the pending offline read scan timer to N minutes.
-Here N is an integer in the range from 0 to 65535 inclusive.  If the
-device is powered off during a read scan after a Selective self\-test,
-then resume the test automatically N minutes after power\-up.  This
-option must be use together with one or more of the \fIselect,N\-M\fP
-options above. The value of this option is preserved between selective
-self\-tests.
-
-.TP
-.B \-C, \-\-captive
-Runs self\-tests in captive mode.  This has no effect with \'\-t
-offline\' or if the \'\-t\' option is not used. [Note: in the case of
-SCSI devices, this command option runs the self\-test in "Foreground"
-mode.]
-
-\fBWARNING: Tests run in captive mode may busy out the drive for the
-length of the test.  Only run captive tests on drives without any
-mounted partitions!\fP
-
-.TP
-.B \-X, \-\-abort
-Aborts non\-captive SMART Self Tests.  Note that this
-command will abort the Offline Immediate Test routine only if your
-disk has the "Abort Offline collection upon new command" capability.
-.PP
-.SH EXAMPLES
-.nf
-.B smartctl \-a /dev/hda
-.fi
-Print all SMART information for drive /dev/hda (Primary Master).
-.PP
-.nf
-.B smartctl \-s off /dev/hdd
-.fi
-Disable SMART on drive /dev/hdd (Secondary Slave).
-.PP
-.nf
-.B smartctl \-\-smart=on \-\-offlineauto=on \-\-saveauto=on /dev/hda
-.fi
-Enable SMART on drive /dev/hda, enable automatic offline
-testing every four hours, and enable autosaving of
-SMART Attributes.  This is a good start\-up line for your system\'s
-init files.  You can issue this command on a running system.
-.PP
-.nf
-.B smartctl \-t long /dev/hdc
-.fi
-Begin an extended self\-test of drive /dev/hdc.  You can issue this
-command on a running system.  The results can be seen in the self\-test
-log visible with the \'\-l selftest\' option after it has completed.
-.PP
-.nf
-.B smartctl \-s on \-t offline /dev/hda
-.fi
-Enable SMART on the disk, and begin an immediate offline test of
-drive /dev/hda.  You can issue this command on a running system.  The
-results are only used to update the SMART Attributes, visible
-with the \'\-A\' option.  If any device errors occur, they are logged to
-the SMART error log, which can be seen with the \'\-l error\' option.
-.PP
-.nf
-.B smartctl \-A \-v 9,minutes /dev/hda
-.fi
-Shows the vendor Attributes, when the disk stores its power\-on time
-internally in minutes rather than hours.
-.PP
-.nf
-.B smartctl \-q errorsonly \-H \-l selftest /dev/hda
-.fi
-Produces output only if the device returns failing SMART status,
-or if some of the logged self\-tests ended with errors.
-.PP
-.nf
-.B smartctl \-q silent \-a /dev/hda
-.fi
-Examine all SMART data for device /dev/hda, but produce no
-printed output.  You must use the exit status (the
-.B $?
-shell variable) to learn if any Attributes are out of bound, if the
-SMART status is failing, if there are errors recorded in the
-self\-test log, or if there are errors recorded in the disk error log.
-.PP
-.nf
-.B smartctl \-a \-d 3ware,0 /dev/sda
-.fi
-Examine all SMART data for the first ATA disk connected to a 3ware
-RAID controller card.
-.PP
-.nf
-.B smartctl \-t short \-d 3ware,3 /dev/sdb
-.fi
-Start a short self\-test on the fourth ATA disk connected to the 3ware RAID
-controller card which is the second SCSI device /dev/sdb.
-.nf
-.B smartctl \-t select,10\-100 \-t select,30\-300 \-t afterselect,on \-t pending,45 /dev/hda
-.fi
-Run a selective self\-test on LBAs 10 to 100 and 30 to 300.  After the
-these LBAs have been tested, read\-scan the remainder of the disk.  If the disk is
-power\-cycled during the read\-scan, resume the scan 45 minutes after power to the
-device is restored.
-.PP
-.SH RETURN VALUES
-The return values of \fBsmartctl\fP are defined by a bitmask.  If all
-is well with the disk, the return value (exit status) of
-\fBsmartctl\fP is 0 (all bits turned off).  If a problem occurs, or an
-error, potential error, or fault is detected, then a non\-zero status
-is returned.  In this case, the eight different bits in the return
-value have the following meanings for ATA disks; some of these values
-may also be returned for SCSI disks.
-.TP
-.B Bit 0:
-Command line did not parse.
-.TP
-.B Bit 1:
-Device open failed, or device did not return an IDENTIFY DEVICE structure. 
-.TP
-.B Bit 2:
-Some SMART command to the disk failed, or there was a checksum error
-in a SMART data structure (see \'\-b\' option above).
-.TP
-.B Bit 3:
-SMART status check returned "DISK FAILING".
-.TP
-.B Bit 4:
-SMART status check returned "DISK OK" but we found prefail Attributes <= threshold.
-.TP
-.B Bit 5:
-SMART status check returned "DISK OK" but we found that some (usage
-or prefail) Attributes have been <= threshold at some time in the
-past. 
-.TP
-.B Bit 6:
-The device error log contains records of errors.
-.TP
-.B Bit 7:
-The device self\-test log contains records of errors.
-
-To test within the shell for whether or not the different bits are
-turned on or off, you can use the following type of construction (this
-is bash syntax):
-.nf
-.B smartstat=$(($? & 8))
-.fi
-This looks at only at bit 3 of the exit status
-.B $?
-(since 8=2^3).  The shell variable
-$smartstat will be nonzero if SMART status check returned "disk
-failing" and zero otherwise.
-
-.PP
-.SH NOTES
-The TapeAlert log page flags are cleared for the initiator when the
-page is read. This means that each alert condition is reported only
-once by \fBsmartctl\fP for each initiator for each activation of the
-condition.
-
-.PP
-.SH AUTHOR
-\fBBruce Allen\fP smartmontools\-support@lists.sourceforge.net
-.fi
-University of Wisconsin \- Milwaukee Physics Department
- 
-.PP
-.SH CONTRIBUTORS
-The following have made large contributions to smartmontools:
-.nf
-\fBCasper Dik\fP (Solaris SCSI interface)
-\fBChristian Franke\fP (Windows interface)
-\fBDouglas Gilbert\fP (SCSI subsystem)
-\fBGuido Guenther\fP (Autoconf/Automake packaging)
-\fBGeoffrey Keating\fP (Darwin ATA interface)
-\fBEduard Martinescu\fP (FreeBSD interface)
-\fBFr\*'ed\*'eric L. W. Meunier\fP (Web site and Mailing list)
-\fBKeiji Sawada\fP (Solaris ATA interface)
-\fBSergey Svishchev\fP (NetBSD interface)
-\fBPhil Williams\fP (User interface and drive database)
-.fi
-Many other individuals have made smaller contributions and corrections.
-
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package.  It extends
-these to cover ATA\-5 disks.  This code was originally developed as a
-Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
-(now part of the Storage Systems Research Center), Jack Baskin School
-of Engineering, University of California, Santa
-Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
-.SH
-HOME PAGE FOR SMARTMONTOOLS: 
-.fi
-Please see the following web site for updates, further documentation, bug
-reports and patches:
-.nf
-.B
-http://smartmontools.sourceforge.net/
-
-.SH
-SEE ALSO:
-\fBsmartd\fP(8), \fBbadblocks\fP(8), \fBide\-smart\fP(8).
-.SH
-REFERENCES FOR SMART
-.fi
-An introductory article about smartmontools is \fIMonitoring Hard
-Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
-pages 74-77. This is http://www.linuxjournal.com/article.php?sid=6983
-online.
-
-If you would like to understand better how SMART works, and what it
-does, a good place to start is Section 8.41 of the "AT Attachment with
-Packet Interface\-5" (ATA/ATAPI\-5) specification.  This documents the
-SMART functionality which the \fBsmartmontools\fP utilities provide
-access to.  You can find Revision 1 of this document at
-\fBhttp://www.t13.org/project/d1321r1c.pdf\fP .
-
-.fi
-Future versions of the specifications (ATA/ATAPI\-6 and ATA/ATAPI\-7),
-and later revisions (2, 3) of the ATA/ATAPI\-5 specification are
-available from \fBhttp://www.t13.org/#FTP_site\fP .
-
-.fi
-The functioning of SMART was originally defined by the SFF\-8035i
-revision 2 and the SFF\-8055i revision 1.4 specifications.  These are
-publications of the Small Form Factors (SFF) Committee.  Links to
-these documents may be found in the References section of the
-\fBsmartmontools\fP home page at
-\fBhttp://smartmontools.sourceforge.net/\fP .
-
-.SH
-CVS ID OF THIS PAGE:
-$Id: smartctl.8.in,v 1.57 2004/07/16 15:49:56 ballen4705 Exp $
-.\" Local Variables:	         
-.\" mode: nroff         
-.\" End:
diff --git a/sm5/smartctl.c b/sm5/smartctl.c
deleted file mode 100644
index 3cc41e9295c2a49d064d8cec36a22f443402a817..0000000000000000000000000000000000000000
--- a/sm5/smartctl.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * smartctl.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#include "config.h"
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
-#endif
-#if defined(__FreeBSD_version) && (__FreeBSD_version < 500000)
-#include <unistd.h>
-#endif
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "int64.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "scsiprint.h"
-#include "smartctl.h"
-#include "utility.h"
-
-#ifdef NEED_SOLARIS_ATA_CODE
-extern const char *os_solaris_ata_s_cvsid;
-#endif
-#if defined(_WIN32) && defined(_MSC_VER)
-extern const char *int64_vc6_c_cvsid;
-#endif
-extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid;
-const char* smartctl_c_cvsid="$Id: smartctl.c,v 1.134 2004/08/16 22:44:27 ballen4705 Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// This is a block containing all the "control variables".  We declare
-// this globally in this file, and externally in other files.
-smartmonctrl *con=NULL;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Track memory use
-extern int64_t bytes;
-
-void printslogan(){
-  pout("smartctl version %s [%s] Copyright (C) 2002-4 Bruce Allen\n", PACKAGE_VERSION, SMARTMONTOOLS_BUILD_HOST);
-  pout("Home page is " PACKAGE_HOMEPAGE "\n\n");
-  return;
-}
-
-void PrintOneCVS(const char *a_cvs_id){
-  char out[CVSMAXLEN];
-  printone(out,a_cvs_id);
-  pout("%s",out);
-  return;
-}
-
-void printcopy(){
-  char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
-
-  pout("smartctl comes with ABSOLUTELY NO WARRANTY. This\n");
-  pout("is free software, and you are welcome to redistribute it\n");
-  pout("under the terms of the GNU General Public License Version 2.\n");
-  pout("See http://www.gnu.org for further details.\n\n");
-  pout("CVS version IDs of files used to build this code are:\n");
-  PrintOneCVS(atacmdnames_c_cvsid);
-  PrintOneCVS(atacmds_c_cvsid);
-  PrintOneCVS(ataprint_c_cvsid);
-#if defined(_WIN32) && defined(_MSC_VER)
-  PrintOneCVS(int64_vc6_c_cvsid);
-#endif
-  PrintOneCVS(knowndrives_c_cvsid);
-  PrintOneCVS(os_XXXX_c_cvsid);
-#ifdef NEED_SOLARIS_ATA_CODE
-  PrintOneCVS(os_solaris_ata_s_cvsid);
-#endif
-  PrintOneCVS(scsicmds_c_cvsid);
-  PrintOneCVS(scsiprint_c_cvsid);
-  PrintOneCVS(smartctl_c_cvsid);
-  PrintOneCVS(utility_c_cvsid);
-  pout("\nsmartmontools release " PACKAGE_VERSION " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n");
-  pout("smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n");
-  pout("smartmontools build configured: " SMARTMONTOOLS_CONFIGURE_DATE "\n");
-  pout("smartctl compile dated " __DATE__ " at "__TIME__ "\n");
-  pout("smartmontools configure arguments: %s\n", configargs);
-  return;
-}
-
-void UsageSummary(){
-  pout("\nUse smartctl -h to get a usage summary\n\n");
-  return;
-}
-
-/*  void prints help information for command syntax */
-void Usage (void){
-  printf("Usage: smartctl [options] device\n\n");
-  printf("============================================ SHOW INFORMATION OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -h, --help, --usage\n"
-"         Display this help and exit\n\n"
-"  -V, --version, --copyright, --license\n"
-"         Print license, copyright, and version information and exit\n\n"
-"  -i, --info                                                       \n"
-"         Show identity information for device\n\n"
-"  -a, --all                                                        \n"
-"         Show all SMART information for device\n\n"
-  );
-#else
-  printf(
-"  -h        Display this help and exit\n"
-"  -V        Print license, copyright, and version information\n"
-"  -i        Show identity information for device\n"
-"  -a        Show all SMART information for device\n\n"
-  );
-#endif
-  printf("================================== SMARTCTL RUN-TIME BEHAVIOR OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -q TYPE, --quietmode=TYPE                                           (ATA)\n"
-"         Set smartctl quiet mode to one of: errorsonly, silent\n\n"
-"  -d TYPE, --device=TYPE\n"
-"         Specify device type to one of: ata, scsi, 3ware,N\n\n"
-"  -T TYPE, --tolerance=TYPE                                           (ATA)\n"
-"         Tolerance: normal, conservative, permissive, verypermissive\n\n"
-"  -b TYPE, --badsum=TYPE                                              (ATA)\n"
-"         Set action on bad checksum to one of: warn, exit, ignore\n\n"
-"  -r TYPE, --report=TYPE\n"
-"         Report transactions (see man page)\n\n"
-  );
-#else
-  printf(
-"  -q TYPE   Set smartctl quiet mode to one of: errorsonly, silent     (ATA)\n"
-"  -d TYPE   Specify device type to one of: ata, scsi, 3ware,N\n"
-"  -T TYPE   Tolerance: normal, conservative,permissive,verypermissive (ATA\n"
-"  -b TYPE   Set action on bad checksum to one of: warn, exit, ignore  (ATA)\n"
-"  -r TYPE   Report transactions (see man page)\n\n"
-  );
-#endif
-  printf("============================== DEVICE FEATURE ENABLE/DISABLE COMMANDS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -s VALUE, --smart=VALUE\n"
-"        Enable/disable SMART on device (on/off)\n\n"
-"  -o VALUE, --offlineauto=VALUE                                       (ATA)\n"
-"        Enable/disable automatic offline testing on device (on/off)\n\n"
-"  -S VALUE, --saveauto=VALUE                                          (ATA)\n"
-"        Enable/disable Attribute autosave on device (on/off)\n\n"
-  );
-#else
-  printf(
-"  -s VALUE  Enable/disable SMART on device (on/off)\n"
-"  -o VALUE  Enable/disable device automatic offline testing (on/off)  (ATA)\n"
-"  -S VALUE  Enable/disable device Attribute autosave (on/off)         (ATA)\n\n"
-  );
-#endif
-  printf("======================================= READ AND DISPLAY DATA OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -H, --health\n"
-"        Show device SMART health status\n\n"
-"  -c, --capabilities                                                  (ATA)\n"
-"        Show device SMART capabilities\n\n"
-"  -A, --attributes                                                         \n"
-"        Show device SMART vendor-specific Attributes and values\n\n"
-"  -l TYPE, --log=TYPE\n"
-"        Show device log. TYPE: error, selftest, selective, directory\n\n"
-"  -v N,OPTION , --vendorattribute=N,OPTION                            (ATA)\n"
-"        Set display OPTION for vendor Attribute N (see man page)\n\n"
-"  -F TYPE, --firmwarebug=TYPE                                         (ATA)\n"
-"        Use firmware bug workaround: none, samsung, samsung2\n\n"
-"  -P TYPE, --presets=TYPE                                             (ATA)\n"
-"        Drive-specific presets: use, ignore, show, showall\n\n"
-  );
-#else
-  printf(
-"  -H        Show device SMART health status\n"
-"  -c        Show device SMART capabilities                             (ATA)\n"
-"  -A        Show device SMART vendor-specific Attributes and values    (ATA)\n"
-"  -l TYPE   Show device log. TYPE: error,selftest,selective,directory\n"
-"  -v N,OPT  Set display OPTion for vendor Attribute N (see man page)   (ATA)\n"
-"  -F TYPE   Use firmware bug workaround: none, samsung, samsung2       (ATA)\n"
-"  -P TYPE   Drive-specific presets: use, ignore, show, showall         (ATA)\n\n"
-  );
-#endif
-  printf("============================================ DEVICE SELF-TEST OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -t TEST, --test=TEST\n"
-"        Run test.  TEST is: offline short long conveyance select,M-N pending,N afterselect,on afterselect,off\n\n"
-"  -C, --captive\n"
-"        Do test in captive mode (along with -t)\n\n"
-"  -X, --abort\n"
-"        Abort any non-captive test on device\n\n"
-);
-#else
-  printf(
-"  -t TEST   Run test.  TEST is: offline short long conveyance select,M-N pending,N afterselect,on afterselect,off\n"
-"  -C        Do test in captive mode (along with -t)\n"
-"  -X        Abort any non-captive test\n\n"
-  );
-#endif
-  print_smartctl_examples();
-  return;
-}
-
-/* Returns a pointer to a static string containing a formatted list of the valid
-   arguments to the option opt or NULL on failure. Note 'v' case different */
-const char *getvalidarglist(char opt) {
-  switch (opt) {
-  case 'q':
-    return "errorsonly, silent";
-  case 'd':
-    return "ata, scsi, 3ware,N";
-  case 'T':
-    return "normal, conservative, permissive, verypermissive";
-  case 'b':
-    return "warn, exit, ignore";
-  case 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 's':
-  case 'o':
-  case 'S':
-    return "on, off";
-  case 'l':
-    return "error, selftest, selective, directory";
-  case 'P':
-    return "use, ignore, show, showall";
-  case 't':
-    return "offline, short, long, conveyance, select,M-N, pending,N, afterselect,on, afterselect,off";
-  case 'F':
-    return "none, samsung, samsung2";
-  case 'v':
-  default:
-    return NULL;
-  }
-}
-
-/* Prints the message "=======> VALID ARGUMENTS ARE: <LIST> \n", where
-   <LIST> is the list of valid arguments for option opt. */
-void printvalidarglistmessage(char opt) {
-  char *s;
-  
-  if (opt=='v')
-    s=create_vendor_attribute_arg_list();
-  else
-    s=(char *)getvalidarglist(opt);
-  
-  if (!s) {
-    pout("Error whilst constructing argument list for option %c", opt);
-    return;
-  }
- 
-  if (opt=='v'){
-    pout("=======> VALID ARGUMENTS ARE:\n\thelp\n%s\n<=======\n", s);
-    free(s);
-  }
-  else {
-  // getvalidarglist() might produce a multiline or single line string.  We
-  // need to figure out which to get the formatting right.
-    char separator = strchr(s, '\n') ? '\n' : ' ';
-    pout("=======> VALID ARGUMENTS ARE:%c%s%c<=======\n", separator, (char *)s, separator);
-  }
-
-  return;
-}
-
-/*      Takes command options and sets features to be run */    
-void ParseOpts (int argc, char** argv){
-  int optchar;
-  int badarg;
-  int captive;
-  unsigned char *charp;
-  extern char *optarg;
-  extern int optopt, optind, opterr;
-  char extraerror[256];
-  // Please update getvalidarglist() if you edit shortopts
-  const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iav:P:t:CXF:";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update getvalidarglist() if you edit longopts
-  struct option longopts[] = {
-    { "help",            no_argument,       0, 'h' },
-    { "usage",           no_argument,       0, 'h' },
-    { "version",         no_argument,       0, 'V' },
-    { "copyright",       no_argument,       0, 'V' },
-    { "license",         no_argument,       0, 'V' },
-    { "quietmode",       required_argument, 0, 'q' },
-    { "device",          required_argument, 0, 'd' },
-    { "tolerance",       required_argument, 0, 'T' },
-    { "badsum",          required_argument, 0, 'b' },
-    { "report",          required_argument, 0, 'r' },
-    { "smart",           required_argument, 0, 's' },
-    { "offlineauto",     required_argument, 0, 'o' },
-    { "saveauto",        required_argument, 0, 'S' },
-    { "health",          no_argument,       0, 'H' },
-    { "capabilities",    no_argument,       0, 'c' },
-    { "attributes",      no_argument,       0, 'A' },
-    { "log",             required_argument, 0, 'l' },
-    { "info",            no_argument,       0, 'i' },
-    { "all",             no_argument,       0, 'a' },
-    { "vendorattribute", required_argument, 0, 'v' },
-    { "presets",         required_argument, 0, 'P' },
-    { "test",            required_argument, 0, 't' },
-    { "captive",         no_argument,       0, 'C' },
-    { "abort",           no_argument,       0, 'X' },
-    { "firmwarebug",     required_argument, 0, 'F' },
-    { 0,                 0,                 0, 0   }
-  };
-#endif
-  
-  memset(extraerror, 0, sizeof(extraerror));
-  memset(con,0,sizeof(*con));
-  con->testcase=-1;
-  opterr=optopt=0;
-  badarg = captive = FALSE;
-  
-  // This miserable construction is needed to get emacs to do proper indenting. Sorry!
-  while (-1 != (optchar = 
-#ifdef HAVE_GETOPT_LONG
-                getopt_long(argc, argv, shortopts, longopts, NULL)
-#else
-                getopt(argc, argv, shortopts)
-#endif
-                )){
-    switch (optchar){
-    case 'V':
-      con->dont_print=FALSE;
-      printslogan();
-      printcopy();
-      exit(0);
-      break;
-    case 'q':
-      if (!strcmp(optarg,"errorsonly")) {
-        con->printing_switchable     = TRUE;
-        con->dont_print = FALSE;
-      } else if (!strcmp(optarg,"silent")) {
-        con->printing_switchable     = FALSE;
-        con->dont_print = TRUE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'd':
-      if (!strcmp(optarg,"ata")) {
-	con->controller_type = CONTROLLER_ATA;
-        con->controller_port = 0;
-      } else if (!strcmp(optarg,"scsi")) {
-	con->controller_type = CONTROLLER_SCSI;
-        con->controller_port = 0;
-      } else {
-        // look for RAID-type device
-        int i;
-        char *s;
-        
-        // make a copy of the string to mess with
-        if (!(s = strdup(optarg))) {
-          con->dont_print = FALSE;
-          pout("No memory for argument of -d. Exiting...\n");
-          exit(FAILCMD);
-        } else if (strncmp(s,"3ware,",6)) {
-          badarg = TRUE;
-        } else if (split_report_arg2(s, &i)) {
-          sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n");
-          badarg = TRUE;
-        } else if (i<0 || i>15) {
-          sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i);
-          badarg = TRUE;
-        } else {
-	  // NOTE: controller_port == disk number + 1
-	  con->controller_type = CONTROLLER_3WARE;
-          con->controller_port = i+1;
-        }
-        free(s);
-      }         
-      break;
-    case 'T':
-      if (!strcmp(optarg,"normal")) {
-        con->conservative = FALSE;
-        con->permissive   = 0;
-      } else if (!strcmp(optarg,"conservative")) {
-        con->conservative = TRUE;
-      } else if (!strcmp(optarg,"permissive")) {
-        if (con->permissive<0xff)
-          con->permissive++;
-      } else if (!strcmp(optarg,"verypermissive")) {
-        con->permissive=0xff;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'b':
-      if (!strcmp(optarg,"warn")) {
-        con->checksumfail   = FALSE;
-        con->checksumignore = FALSE;
-      } else if (!strcmp(optarg,"exit")) {
-        con->checksumfail   = TRUE;
-        con->checksumignore = FALSE;
-      } else if (!strcmp(optarg,"ignore")) {
-        con->checksumignore = TRUE;
-        con->checksumfail   = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'r':
-      {
-        int i;
-        char *s;
-
-        // split_report_arg() may modify its first argument string, so use a
-        // copy of optarg in case we want optarg for an error message.
-        if (!(s = strdup(optarg))) {
-          con->dont_print = FALSE;
-          pout("Can't allocate memory to copy argument to -r option"
-               " - exiting\n");
-          EXIT(FAILCMD);
-        }
-        if (split_report_arg(s, &i)) {
-          badarg = TRUE;
-        } else if (!strcmp(s,"ioctl")) {
-          con->reportataioctl  = con->reportscsiioctl = i;
-        } else if (!strcmp(s,"ataioctl")) {
-          con->reportataioctl = i;
-        } else if (!strcmp(s,"scsiioctl")) {
-          con->reportscsiioctl = i;
-        } else {
-          badarg = TRUE;
-        }
-        free(s);
-      }
-      break;
-    case 's':
-      if (!strcmp(optarg,"on")) {
-        con->smartenable  = TRUE;
-        con->smartdisable = FALSE;
-      } else if (!strcmp(optarg,"off")) {
-        con->smartdisable = TRUE;
-        con->smartenable  = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'o':
-      if (!strcmp(optarg,"on")) {
-        con->smartautoofflineenable  = TRUE;
-        con->smartautoofflinedisable = FALSE;
-      } else if (!strcmp(optarg,"off")) {
-        con->smartautoofflinedisable = TRUE;
-        con->smartautoofflineenable  = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'S':
-      if (!strcmp(optarg,"on")) {
-        con->smartautosaveenable  = TRUE;
-        con->smartautosavedisable = FALSE;
-      } else if (!strcmp(optarg,"off")) {
-        con->smartautosavedisable = TRUE;
-        con->smartautosaveenable  = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'H':
-      con->checksmart = TRUE;           
-      break;
-    case 'F':
-      if (!strcmp(optarg,"none")) {
-        con->fixfirmwarebug = FIX_NONE;
-      } else if (!strcmp(optarg,"samsung")) {
-        con->fixfirmwarebug = FIX_SAMSUNG;
-      } else if (!strcmp(optarg,"samsung2")) {
-        con->fixfirmwarebug = FIX_SAMSUNG2;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'c':
-      con->generalsmartvalues = TRUE;
-      break;
-    case 'A':
-      con->smartvendorattrib = TRUE;
-      break;
-    case 'l':
-      if (!strcmp(optarg,"error")) {
-        con->smarterrorlog = TRUE;
-      } else if (!strcmp(optarg,"selftest")) {
-        con->smartselftestlog = TRUE;
-      } else if (!strcmp(optarg, "selective")) {
-	con->selectivetestlog = TRUE;
-      } else if (!strcmp(optarg,"directory")) {
-        con->smartlogdirectory = TRUE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'i':
-      con->driveinfo = TRUE;
-      break;            
-    case 'a':
-      con->driveinfo          = TRUE;
-      con->checksmart         = TRUE;
-      con->generalsmartvalues = TRUE;
-      con->smartvendorattrib  = TRUE;
-      con->smarterrorlog      = TRUE;
-      con->smartselftestlog   = TRUE;
-      con->selectivetestlog   = TRUE;
-      break;
-    case 'v':
-      // parse vendor-specific definitions of attributes
-      if (!strcmp(optarg,"help")) {
-        char *s;
-        con->dont_print=FALSE;
-        printslogan();
-        if (!(s = create_vendor_attribute_arg_list())) {
-          pout("Insufficient memory to construct argument list\n");
-          EXIT(FAILCMD);
-        }
-        pout("The valid arguments to -v are:\n\thelp\n%s\n", s);
-        free(s);
-        EXIT(0);
-      }
-      charp=con->attributedefs;
-      if (!charp){
-        pout("Fatal internal error in ParseOpts()\n");
-        EXIT(FAILCMD);
-      }
-      if (parse_attribute_def(optarg, &charp))
-        badarg = TRUE;
-      break;    
-    case 'P':
-      if (!strcmp(optarg, "use")) {
-        con->ignorepresets = FALSE;
-      } else if (!strcmp(optarg, "ignore")) {
-        con->ignorepresets = TRUE;
-      } else if (!strcmp(optarg, "show")) {
-        con->showpresets = TRUE;
-      } else if (!strcmp(optarg, "showall")) {
-        showallpresets();
-        EXIT(0);
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 't':
-      if (!strcmp(optarg,"offline")) {
-        con->smartexeoffimmediate = TRUE;
-        con->testcase             = OFFLINE_FULL_SCAN;
-      } else if (!strcmp(optarg,"short")) {
-        con->smartshortselftest = TRUE;
-        con->testcase           = SHORT_SELF_TEST;
-      } else if (!strcmp(optarg,"long")) {
-        con->smartextendselftest = TRUE;
-        con->testcase            = EXTEND_SELF_TEST;
-      } else if (!strcmp(optarg,"conveyance")) {
-        con->smartconveyanceselftest = TRUE;
-        con->testcase            = CONVEYANCE_SELF_TEST;
-      } else if (!strcmp(optarg,"afterselect,on")) {
-	// scan remainder of disk after doing selected segments
-	con->scanafterselect=2;
-      } else if (!strcmp(optarg,"afterselect,off")) {
-	// don't scan remainder of disk after doing selected segments
-	con->scanafterselect=1;
-      } else if (!strncmp(optarg,"pending,",strlen("pending,"))) {
-	// parse number of minutes that test should be pending
-	int i;
-	char *tailptr=NULL;
-	errno=0;
-	i=(int)strtol(optarg+strlen("pending,"), &tailptr, 10);
-	if (errno || *tailptr != '\0') {
-	  sprintf(extraerror, "Option -t pending,N requires N to be a non-negative integer\n");
-	  badarg = TRUE;
-	} else if (i<0 || i>65535) {
-	  sprintf(extraerror, "Option -t pending,N (N=%d) must have 0 <= N <= 65535\n", i);
-	  badarg = TRUE;
-	} else {
-	  con->pendingtime=i+1;
-	}
-      } else if (!strncmp(optarg,"select",strlen("select"))) {
-	// parse range of LBAs to test
-	uint64_t start, stop;
-
-        if (split_selective_arg(optarg, &start, &stop)) {
-	  sprintf(extraerror, "Option -t select,M-N must have non-negative integer M and N\n");
-          badarg = TRUE;
-        } else {
-          if (con->smartselectivenumspans >= 5 || start > stop) {
-            if (start > stop) {
-              sprintf(extraerror, "ERROR: Start LBA (%"PRIu64") > ending LBA (%"PRId64") in argument \"%s\"\n",
-                start, stop, optarg);
-            } else {
-              sprintf(extraerror,"ERROR: No more than five selective self-test spans may be"
-                " defined\n");
-            }
-	    badarg = TRUE;
-          }
-          con->smartselectivespan[con->smartselectivenumspans][0] = start;
-          con->smartselectivespan[con->smartselectivenumspans][1] = stop;
-          con->smartselectivenumspans++;
-          con->testcase            = SELECTIVE_SELF_TEST;
-        }
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'C':
-      captive = TRUE;
-      break;
-    case 'X':
-      con->smartselftestabort = TRUE;
-      con->testcase           = ABORT_SELF_TEST;
-      break;
-    case 'h':
-      con->dont_print=FALSE;
-      printslogan();
-      Usage();
-      EXIT(0);  
-      break;
-    case '?':
-    default:
-      con->dont_print=FALSE;
-      printslogan();
-#ifdef HAVE_GETOPT_LONG
-      // Point arg to the argument in which this option was found.
-      arg = argv[optind-1];
-      // Check whether the option is a long option that doesn't map to -h.
-      if (arg[1] == '-' && optchar != 'h') {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (optopt && (strchr(shortopts, optopt) != NULL)) {
-          pout("=======> ARGUMENT REQUIRED FOR OPTION: %s\n", arg+2);
-          printvalidarglistmessage(optopt);
-        } else
-          pout("=======> UNRECOGNIZED OPTION: %s\n",arg+2);
-	if (extraerror[0])
-	  pout("=======> %s", extraerror);
-        UsageSummary();
-        EXIT(FAILCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be
-        // missing.  Note (BA) this logic seems to fail using Solaris
-        // getopt!
-        if (strchr(shortopts, optopt) != NULL) {
-          pout("=======> ARGUMENT REQUIRED FOR OPTION: %c\n", optopt);
-          printvalidarglistmessage(optopt);
-        } else
-          pout("=======> UNRECOGNIZED OPTION: %c\n",optopt);
-	if (extraerror[0])
-	  pout("=======> %s", extraerror);
-        UsageSummary();
-        EXIT(FAILCMD);
-      }
-      Usage();
-      EXIT(0);  
-    } // closes switch statement to process command-line options
-    
-    // Check to see if option had an unrecognized or incorrect argument.
-    if (badarg) {
-      printslogan();
-      // It would be nice to print the actual option name given by the user
-      // here, but we just print the short form.  Please fix this if you know
-      // a clean way to do it.
-      pout("=======> INVALID ARGUMENT TO -%c: %s\n", optchar, optarg);
-      printvalidarglistmessage(optchar);
-      if (extraerror[0])
-	pout("=======> %s", extraerror);
-      UsageSummary();
-      EXIT(FAILCMD);
-    }
-  }
-  // At this point we have processed all command-line options.  If the
-  // print output is switchable, then start with the print output
-  // turned off
-  if (con->printing_switchable)
-    con->dont_print=TRUE;
-
-  // error message if user has asked for more than one test
-  if (1<(con->smartexeoffimmediate+con->smartshortselftest+con->smartextendselftest+
-         con->smartshortcapselftest+con->smartextendcapselftest+con->smartselftestabort + (con->smartselectivenumspans>0?1:0))){
-    con->dont_print=FALSE;
-    printslogan();
-    pout("\nERROR: smartctl can only run a single test type (or abort) at a time.\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-
-  // error message if user has set selective self-test options without
-  // asking for a selective self-test
-  if ((con->pendingtime || con->scanafterselect) && !con->smartselectivenumspans){
-    con->dont_print=FALSE;
-    printslogan();
-    if (con->pendingtime)
-      pout("\nERROR: smartctl -t pending,N must be used with -t select,N-M.\n");
-    else
-      pout("\nERROR: smartctl -t afterselect,(on|off) must be used with -t select,N-M.\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-
-  // If captive option was used, change test type if appropriate.
-  if (captive && con->smartshortselftest) {
-    con->smartshortselftest    = FALSE;
-    con->smartshortcapselftest = TRUE;
-    con->testcase              = SHORT_CAPTIVE_SELF_TEST;
-  } else if (captive && con->smartextendselftest) {
-    con->smartextendselftest    = FALSE;
-    con->smartextendcapselftest = TRUE;
-    con->testcase               = EXTEND_CAPTIVE_SELF_TEST;
-  }
-  else if (captive && con->smartconveyanceselftest) {
-    con->smartconveyanceselftest    = FALSE;
-    con->smartconveyancecapselftest = TRUE;
-    con->testcase                   = CONVEYANCE_CAPTIVE_SELF_TEST;
-  }
-  else if (captive && con->smartselectiveselftest) {
-    con->smartselectiveselftest    = FALSE;
-    con->smartselectivecapselftest = TRUE;
-    con->testcase                  = SELECTIVE_CAPTIVE_SELF_TEST;
-  }
- 
-  // From here on, normal operations...
-  printslogan();
-  
-  // Warn if the user has provided no device name
-  if (argc-optind<1){
-    pout("ERROR: smartctl requires a device name as the final command-line argument.\n\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-  
-  // Warn if the user has provided more than one device name
-  if (argc-optind>1){
-    int i;
-    pout("ERROR: smartctl takes ONE device name as the final command-line argument.\n");
-    pout("You have provided %d device names:\n",argc-optind);
-    for (i=0; i<argc-optind; i++)
-      pout("%s\n",argv[optind+i]);
-    UsageSummary();
-    EXIT(FAILCMD);
-  }  
-}
-
-// Printing function (controlled by global con->dont_print) 
-// [From GLIBC Manual: Since the prototype doesn't specify types for
-// optional arguments, in a call to a variadic function the default
-// argument promotions are performed on the optional argument
-// values. This means the objects of type char or short int (whether
-// signed or not) are promoted to either int or unsigned int, as
-// appropriate.]
-void pout(char *fmt, ...){
-  va_list ap;
-  
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  if (con->dont_print){
-    va_end(ap);
-    return;
-  }
-
-  // print out
-  vprintf(fmt,ap);
-  va_end(ap);
-  fflush(stdout);
-  return;
-}
-
-// This function is used by utility.c to report LOG_CRIT errors.
-// The smartctl version prints to stdout instead of syslog().
-void PrintOut(int priority, char *fmt, ...) {
-  va_list ap;
-
-  // avoid warning message about unused variable from gcc -W: just
-  // change value of local copy.
-  priority=0;
-
-  va_start(ap,fmt);
-  vprintf(fmt,ap);
-  va_end(ap);
-  return;
-}
-
-
-/* Main Program */
-int main (int argc, char **argv){
-  int fd,retval=0;
-  char *device;
-  smartmonctrl control;
-  char *mode=NULL;
-
-  // define control block for external functions
-  con=&control;
-
-  // Part input arguments
-  ParseOpts(argc,argv);
-
-  device = argv[argc-1];
-
-  // If use has specified 3ware controller, determine which interface 
-  if (con->controller_type == CONTROLLER_3WARE) {
-    con->controller_type=guess_device_type(device);
-    if (con->controller_type!=CONTROLLER_3WARE_9000_CHAR && con->controller_type!=CONTROLLER_3WARE_678K_CHAR)
-      con->controller_type = CONTROLLER_3WARE_678K;
-  }
-
-  if (con->controller_type == CONTROLLER_UNKNOWN)
-    con->controller_type=guess_device_type(device);
-  
-  if (con->controller_type == CONTROLLER_UNKNOWN) {
-    pout("Smartctl: please specify device type with the -d option.\n");
-    UsageSummary();
-    return FAILCMD;
-  }
-  
-  // set up mode for open() call.  SCSI case is:
-  switch (con->controller_type) {
-  case CONTROLLER_SCSI:
-    mode="SCSI";
-    break;
-  case CONTROLLER_ATA:
-  case CONTROLLER_3WARE_678K:
-    mode="ATA";
-    break;
-  case CONTROLLER_3WARE_9000_CHAR:
-    mode="ATA_3WARE_9000";
-    break;
-  case CONTROLLER_3WARE_678K_CHAR:
-    mode="ATA_3WARE_678K";
-    break;
-  }
-
-  // open device - SCSI devices are opened (O_RDWR | O_NONBLOCK) so the
-  // scsi generic device can be used (needs write permission for MODE 
-  // SELECT command) plus O_NONBLOCK to stop open hanging if media not
-  // present (e.g. with st).  Opening is retried O_RDONLY if read-only
-  // media prevents opening O_RDWR (it cannot happen for scsi generic
-  // devices, but it can for the others).
-  fd = deviceopen(device, mode);
-  if (fd<0) {
-    char errmsg[256];
-    snprintf(errmsg,256,"Smartctl open device: %s failed",argv[argc-1]);
-    errmsg[255]='\0';
-    syserror(errmsg);
-    return FAILDEV;
-  }
-
-  // now call appropriate ATA or SCSI routine
-  switch (con->controller_type) {
-  case CONTROLLER_ATA:
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_3WARE_9000_CHAR:
-  case CONTROLLER_3WARE_678K_CHAR:
-    retval = ataPrintMain(fd);
-    break;
-  case CONTROLLER_SCSI:
-    retval = scsiPrintMain(fd);
-    break;
-  default:
-    pout("Smartctl: specify if this is an ATA or SCSI device with the -d option.\n");
-    UsageSummary();
-    return FAILCMD;
-  }
-  
-  return retval;
-}
diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp
deleted file mode 100644
index 05d2f4964993042f686fd976605b85e1a9df3de9..0000000000000000000000000000000000000000
--- a/sm5/smartctl.cpp
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * smartctl.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#include "config.h"
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
-#endif
-#if defined(__FreeBSD_version) && (__FreeBSD_version < 500000)
-#include <unistd.h>
-#endif
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "int64.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "scsiprint.h"
-#include "smartctl.h"
-#include "utility.h"
-
-#ifdef NEED_SOLARIS_ATA_CODE
-extern const char *os_solaris_ata_s_cvsid;
-#endif
-#if defined(_WIN32) && defined(_MSC_VER)
-extern const char *int64_vc6_c_cvsid;
-#endif
-extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid;
-const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.134 2004/08/16 22:44:27 ballen4705 Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// This is a block containing all the "control variables".  We declare
-// this globally in this file, and externally in other files.
-smartmonctrl *con=NULL;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Track memory use
-extern int64_t bytes;
-
-void printslogan(){
-  pout("smartctl version %s [%s] Copyright (C) 2002-4 Bruce Allen\n", PACKAGE_VERSION, SMARTMONTOOLS_BUILD_HOST);
-  pout("Home page is " PACKAGE_HOMEPAGE "\n\n");
-  return;
-}
-
-void PrintOneCVS(const char *a_cvs_id){
-  char out[CVSMAXLEN];
-  printone(out,a_cvs_id);
-  pout("%s",out);
-  return;
-}
-
-void printcopy(){
-  char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
-
-  pout("smartctl comes with ABSOLUTELY NO WARRANTY. This\n");
-  pout("is free software, and you are welcome to redistribute it\n");
-  pout("under the terms of the GNU General Public License Version 2.\n");
-  pout("See http://www.gnu.org for further details.\n\n");
-  pout("CVS version IDs of files used to build this code are:\n");
-  PrintOneCVS(atacmdnames_c_cvsid);
-  PrintOneCVS(atacmds_c_cvsid);
-  PrintOneCVS(ataprint_c_cvsid);
-#if defined(_WIN32) && defined(_MSC_VER)
-  PrintOneCVS(int64_vc6_c_cvsid);
-#endif
-  PrintOneCVS(knowndrives_c_cvsid);
-  PrintOneCVS(os_XXXX_c_cvsid);
-#ifdef NEED_SOLARIS_ATA_CODE
-  PrintOneCVS(os_solaris_ata_s_cvsid);
-#endif
-  PrintOneCVS(scsicmds_c_cvsid);
-  PrintOneCVS(scsiprint_c_cvsid);
-  PrintOneCVS(smartctl_c_cvsid);
-  PrintOneCVS(utility_c_cvsid);
-  pout("\nsmartmontools release " PACKAGE_VERSION " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n");
-  pout("smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n");
-  pout("smartmontools build configured: " SMARTMONTOOLS_CONFIGURE_DATE "\n");
-  pout("smartctl compile dated " __DATE__ " at "__TIME__ "\n");
-  pout("smartmontools configure arguments: %s\n", configargs);
-  return;
-}
-
-void UsageSummary(){
-  pout("\nUse smartctl -h to get a usage summary\n\n");
-  return;
-}
-
-/*  void prints help information for command syntax */
-void Usage (void){
-  printf("Usage: smartctl [options] device\n\n");
-  printf("============================================ SHOW INFORMATION OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -h, --help, --usage\n"
-"         Display this help and exit\n\n"
-"  -V, --version, --copyright, --license\n"
-"         Print license, copyright, and version information and exit\n\n"
-"  -i, --info                                                       \n"
-"         Show identity information for device\n\n"
-"  -a, --all                                                        \n"
-"         Show all SMART information for device\n\n"
-  );
-#else
-  printf(
-"  -h        Display this help and exit\n"
-"  -V        Print license, copyright, and version information\n"
-"  -i        Show identity information for device\n"
-"  -a        Show all SMART information for device\n\n"
-  );
-#endif
-  printf("================================== SMARTCTL RUN-TIME BEHAVIOR OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -q TYPE, --quietmode=TYPE                                           (ATA)\n"
-"         Set smartctl quiet mode to one of: errorsonly, silent\n\n"
-"  -d TYPE, --device=TYPE\n"
-"         Specify device type to one of: ata, scsi, 3ware,N\n\n"
-"  -T TYPE, --tolerance=TYPE                                           (ATA)\n"
-"         Tolerance: normal, conservative, permissive, verypermissive\n\n"
-"  -b TYPE, --badsum=TYPE                                              (ATA)\n"
-"         Set action on bad checksum to one of: warn, exit, ignore\n\n"
-"  -r TYPE, --report=TYPE\n"
-"         Report transactions (see man page)\n\n"
-  );
-#else
-  printf(
-"  -q TYPE   Set smartctl quiet mode to one of: errorsonly, silent     (ATA)\n"
-"  -d TYPE   Specify device type to one of: ata, scsi, 3ware,N\n"
-"  -T TYPE   Tolerance: normal, conservative,permissive,verypermissive (ATA\n"
-"  -b TYPE   Set action on bad checksum to one of: warn, exit, ignore  (ATA)\n"
-"  -r TYPE   Report transactions (see man page)\n\n"
-  );
-#endif
-  printf("============================== DEVICE FEATURE ENABLE/DISABLE COMMANDS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -s VALUE, --smart=VALUE\n"
-"        Enable/disable SMART on device (on/off)\n\n"
-"  -o VALUE, --offlineauto=VALUE                                       (ATA)\n"
-"        Enable/disable automatic offline testing on device (on/off)\n\n"
-"  -S VALUE, --saveauto=VALUE                                          (ATA)\n"
-"        Enable/disable Attribute autosave on device (on/off)\n\n"
-  );
-#else
-  printf(
-"  -s VALUE  Enable/disable SMART on device (on/off)\n"
-"  -o VALUE  Enable/disable device automatic offline testing (on/off)  (ATA)\n"
-"  -S VALUE  Enable/disable device Attribute autosave (on/off)         (ATA)\n\n"
-  );
-#endif
-  printf("======================================= READ AND DISPLAY DATA OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -H, --health\n"
-"        Show device SMART health status\n\n"
-"  -c, --capabilities                                                  (ATA)\n"
-"        Show device SMART capabilities\n\n"
-"  -A, --attributes                                                         \n"
-"        Show device SMART vendor-specific Attributes and values\n\n"
-"  -l TYPE, --log=TYPE\n"
-"        Show device log. TYPE: error, selftest, selective, directory\n\n"
-"  -v N,OPTION , --vendorattribute=N,OPTION                            (ATA)\n"
-"        Set display OPTION for vendor Attribute N (see man page)\n\n"
-"  -F TYPE, --firmwarebug=TYPE                                         (ATA)\n"
-"        Use firmware bug workaround: none, samsung, samsung2\n\n"
-"  -P TYPE, --presets=TYPE                                             (ATA)\n"
-"        Drive-specific presets: use, ignore, show, showall\n\n"
-  );
-#else
-  printf(
-"  -H        Show device SMART health status\n"
-"  -c        Show device SMART capabilities                             (ATA)\n"
-"  -A        Show device SMART vendor-specific Attributes and values    (ATA)\n"
-"  -l TYPE   Show device log. TYPE: error,selftest,selective,directory\n"
-"  -v N,OPT  Set display OPTion for vendor Attribute N (see man page)   (ATA)\n"
-"  -F TYPE   Use firmware bug workaround: none, samsung, samsung2       (ATA)\n"
-"  -P TYPE   Drive-specific presets: use, ignore, show, showall         (ATA)\n\n"
-  );
-#endif
-  printf("============================================ DEVICE SELF-TEST OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -t TEST, --test=TEST\n"
-"        Run test.  TEST is: offline short long conveyance select,M-N pending,N afterselect,on afterselect,off\n\n"
-"  -C, --captive\n"
-"        Do test in captive mode (along with -t)\n\n"
-"  -X, --abort\n"
-"        Abort any non-captive test on device\n\n"
-);
-#else
-  printf(
-"  -t TEST   Run test.  TEST is: offline short long conveyance select,M-N pending,N afterselect,on afterselect,off\n"
-"  -C        Do test in captive mode (along with -t)\n"
-"  -X        Abort any non-captive test\n\n"
-  );
-#endif
-  print_smartctl_examples();
-  return;
-}
-
-/* Returns a pointer to a static string containing a formatted list of the valid
-   arguments to the option opt or NULL on failure. Note 'v' case different */
-const char *getvalidarglist(char opt) {
-  switch (opt) {
-  case 'q':
-    return "errorsonly, silent";
-  case 'd':
-    return "ata, scsi, 3ware,N";
-  case 'T':
-    return "normal, conservative, permissive, verypermissive";
-  case 'b':
-    return "warn, exit, ignore";
-  case 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 's':
-  case 'o':
-  case 'S':
-    return "on, off";
-  case 'l':
-    return "error, selftest, selective, directory";
-  case 'P':
-    return "use, ignore, show, showall";
-  case 't':
-    return "offline, short, long, conveyance, select,M-N, pending,N, afterselect,on, afterselect,off";
-  case 'F':
-    return "none, samsung, samsung2";
-  case 'v':
-  default:
-    return NULL;
-  }
-}
-
-/* Prints the message "=======> VALID ARGUMENTS ARE: <LIST> \n", where
-   <LIST> is the list of valid arguments for option opt. */
-void printvalidarglistmessage(char opt) {
-  char *s;
-  
-  if (opt=='v')
-    s=create_vendor_attribute_arg_list();
-  else
-    s=(char *)getvalidarglist(opt);
-  
-  if (!s) {
-    pout("Error whilst constructing argument list for option %c", opt);
-    return;
-  }
- 
-  if (opt=='v'){
-    pout("=======> VALID ARGUMENTS ARE:\n\thelp\n%s\n<=======\n", s);
-    free(s);
-  }
-  else {
-  // getvalidarglist() might produce a multiline or single line string.  We
-  // need to figure out which to get the formatting right.
-    char separator = strchr(s, '\n') ? '\n' : ' ';
-    pout("=======> VALID ARGUMENTS ARE:%c%s%c<=======\n", separator, (char *)s, separator);
-  }
-
-  return;
-}
-
-/*      Takes command options and sets features to be run */    
-void ParseOpts (int argc, char** argv){
-  int optchar;
-  int badarg;
-  int captive;
-  unsigned char *charp;
-  extern char *optarg;
-  extern int optopt, optind, opterr;
-  char extraerror[256];
-  // Please update getvalidarglist() if you edit shortopts
-  const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iav:P:t:CXF:";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update getvalidarglist() if you edit longopts
-  struct option longopts[] = {
-    { "help",            no_argument,       0, 'h' },
-    { "usage",           no_argument,       0, 'h' },
-    { "version",         no_argument,       0, 'V' },
-    { "copyright",       no_argument,       0, 'V' },
-    { "license",         no_argument,       0, 'V' },
-    { "quietmode",       required_argument, 0, 'q' },
-    { "device",          required_argument, 0, 'd' },
-    { "tolerance",       required_argument, 0, 'T' },
-    { "badsum",          required_argument, 0, 'b' },
-    { "report",          required_argument, 0, 'r' },
-    { "smart",           required_argument, 0, 's' },
-    { "offlineauto",     required_argument, 0, 'o' },
-    { "saveauto",        required_argument, 0, 'S' },
-    { "health",          no_argument,       0, 'H' },
-    { "capabilities",    no_argument,       0, 'c' },
-    { "attributes",      no_argument,       0, 'A' },
-    { "log",             required_argument, 0, 'l' },
-    { "info",            no_argument,       0, 'i' },
-    { "all",             no_argument,       0, 'a' },
-    { "vendorattribute", required_argument, 0, 'v' },
-    { "presets",         required_argument, 0, 'P' },
-    { "test",            required_argument, 0, 't' },
-    { "captive",         no_argument,       0, 'C' },
-    { "abort",           no_argument,       0, 'X' },
-    { "firmwarebug",     required_argument, 0, 'F' },
-    { 0,                 0,                 0, 0   }
-  };
-#endif
-  
-  memset(extraerror, 0, sizeof(extraerror));
-  memset(con,0,sizeof(*con));
-  con->testcase=-1;
-  opterr=optopt=0;
-  badarg = captive = FALSE;
-  
-  // This miserable construction is needed to get emacs to do proper indenting. Sorry!
-  while (-1 != (optchar = 
-#ifdef HAVE_GETOPT_LONG
-                getopt_long(argc, argv, shortopts, longopts, NULL)
-#else
-                getopt(argc, argv, shortopts)
-#endif
-                )){
-    switch (optchar){
-    case 'V':
-      con->dont_print=FALSE;
-      printslogan();
-      printcopy();
-      exit(0);
-      break;
-    case 'q':
-      if (!strcmp(optarg,"errorsonly")) {
-        con->printing_switchable     = TRUE;
-        con->dont_print = FALSE;
-      } else if (!strcmp(optarg,"silent")) {
-        con->printing_switchable     = FALSE;
-        con->dont_print = TRUE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'd':
-      if (!strcmp(optarg,"ata")) {
-	con->controller_type = CONTROLLER_ATA;
-        con->controller_port = 0;
-      } else if (!strcmp(optarg,"scsi")) {
-	con->controller_type = CONTROLLER_SCSI;
-        con->controller_port = 0;
-      } else {
-        // look for RAID-type device
-        int i;
-        char *s;
-        
-        // make a copy of the string to mess with
-        if (!(s = strdup(optarg))) {
-          con->dont_print = FALSE;
-          pout("No memory for argument of -d. Exiting...\n");
-          exit(FAILCMD);
-        } else if (strncmp(s,"3ware,",6)) {
-          badarg = TRUE;
-        } else if (split_report_arg2(s, &i)) {
-          sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n");
-          badarg = TRUE;
-        } else if (i<0 || i>15) {
-          sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i);
-          badarg = TRUE;
-        } else {
-	  // NOTE: controller_port == disk number + 1
-	  con->controller_type = CONTROLLER_3WARE;
-          con->controller_port = i+1;
-        }
-        free(s);
-      }         
-      break;
-    case 'T':
-      if (!strcmp(optarg,"normal")) {
-        con->conservative = FALSE;
-        con->permissive   = 0;
-      } else if (!strcmp(optarg,"conservative")) {
-        con->conservative = TRUE;
-      } else if (!strcmp(optarg,"permissive")) {
-        if (con->permissive<0xff)
-          con->permissive++;
-      } else if (!strcmp(optarg,"verypermissive")) {
-        con->permissive=0xff;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'b':
-      if (!strcmp(optarg,"warn")) {
-        con->checksumfail   = FALSE;
-        con->checksumignore = FALSE;
-      } else if (!strcmp(optarg,"exit")) {
-        con->checksumfail   = TRUE;
-        con->checksumignore = FALSE;
-      } else if (!strcmp(optarg,"ignore")) {
-        con->checksumignore = TRUE;
-        con->checksumfail   = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'r':
-      {
-        int i;
-        char *s;
-
-        // split_report_arg() may modify its first argument string, so use a
-        // copy of optarg in case we want optarg for an error message.
-        if (!(s = strdup(optarg))) {
-          con->dont_print = FALSE;
-          pout("Can't allocate memory to copy argument to -r option"
-               " - exiting\n");
-          EXIT(FAILCMD);
-        }
-        if (split_report_arg(s, &i)) {
-          badarg = TRUE;
-        } else if (!strcmp(s,"ioctl")) {
-          con->reportataioctl  = con->reportscsiioctl = i;
-        } else if (!strcmp(s,"ataioctl")) {
-          con->reportataioctl = i;
-        } else if (!strcmp(s,"scsiioctl")) {
-          con->reportscsiioctl = i;
-        } else {
-          badarg = TRUE;
-        }
-        free(s);
-      }
-      break;
-    case 's':
-      if (!strcmp(optarg,"on")) {
-        con->smartenable  = TRUE;
-        con->smartdisable = FALSE;
-      } else if (!strcmp(optarg,"off")) {
-        con->smartdisable = TRUE;
-        con->smartenable  = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'o':
-      if (!strcmp(optarg,"on")) {
-        con->smartautoofflineenable  = TRUE;
-        con->smartautoofflinedisable = FALSE;
-      } else if (!strcmp(optarg,"off")) {
-        con->smartautoofflinedisable = TRUE;
-        con->smartautoofflineenable  = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'S':
-      if (!strcmp(optarg,"on")) {
-        con->smartautosaveenable  = TRUE;
-        con->smartautosavedisable = FALSE;
-      } else if (!strcmp(optarg,"off")) {
-        con->smartautosavedisable = TRUE;
-        con->smartautosaveenable  = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'H':
-      con->checksmart = TRUE;           
-      break;
-    case 'F':
-      if (!strcmp(optarg,"none")) {
-        con->fixfirmwarebug = FIX_NONE;
-      } else if (!strcmp(optarg,"samsung")) {
-        con->fixfirmwarebug = FIX_SAMSUNG;
-      } else if (!strcmp(optarg,"samsung2")) {
-        con->fixfirmwarebug = FIX_SAMSUNG2;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'c':
-      con->generalsmartvalues = TRUE;
-      break;
-    case 'A':
-      con->smartvendorattrib = TRUE;
-      break;
-    case 'l':
-      if (!strcmp(optarg,"error")) {
-        con->smarterrorlog = TRUE;
-      } else if (!strcmp(optarg,"selftest")) {
-        con->smartselftestlog = TRUE;
-      } else if (!strcmp(optarg, "selective")) {
-	con->selectivetestlog = TRUE;
-      } else if (!strcmp(optarg,"directory")) {
-        con->smartlogdirectory = TRUE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'i':
-      con->driveinfo = TRUE;
-      break;            
-    case 'a':
-      con->driveinfo          = TRUE;
-      con->checksmart         = TRUE;
-      con->generalsmartvalues = TRUE;
-      con->smartvendorattrib  = TRUE;
-      con->smarterrorlog      = TRUE;
-      con->smartselftestlog   = TRUE;
-      con->selectivetestlog   = TRUE;
-      break;
-    case 'v':
-      // parse vendor-specific definitions of attributes
-      if (!strcmp(optarg,"help")) {
-        char *s;
-        con->dont_print=FALSE;
-        printslogan();
-        if (!(s = create_vendor_attribute_arg_list())) {
-          pout("Insufficient memory to construct argument list\n");
-          EXIT(FAILCMD);
-        }
-        pout("The valid arguments to -v are:\n\thelp\n%s\n", s);
-        free(s);
-        EXIT(0);
-      }
-      charp=con->attributedefs;
-      if (!charp){
-        pout("Fatal internal error in ParseOpts()\n");
-        EXIT(FAILCMD);
-      }
-      if (parse_attribute_def(optarg, &charp))
-        badarg = TRUE;
-      break;    
-    case 'P':
-      if (!strcmp(optarg, "use")) {
-        con->ignorepresets = FALSE;
-      } else if (!strcmp(optarg, "ignore")) {
-        con->ignorepresets = TRUE;
-      } else if (!strcmp(optarg, "show")) {
-        con->showpresets = TRUE;
-      } else if (!strcmp(optarg, "showall")) {
-        showallpresets();
-        EXIT(0);
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 't':
-      if (!strcmp(optarg,"offline")) {
-        con->smartexeoffimmediate = TRUE;
-        con->testcase             = OFFLINE_FULL_SCAN;
-      } else if (!strcmp(optarg,"short")) {
-        con->smartshortselftest = TRUE;
-        con->testcase           = SHORT_SELF_TEST;
-      } else if (!strcmp(optarg,"long")) {
-        con->smartextendselftest = TRUE;
-        con->testcase            = EXTEND_SELF_TEST;
-      } else if (!strcmp(optarg,"conveyance")) {
-        con->smartconveyanceselftest = TRUE;
-        con->testcase            = CONVEYANCE_SELF_TEST;
-      } else if (!strcmp(optarg,"afterselect,on")) {
-	// scan remainder of disk after doing selected segments
-	con->scanafterselect=2;
-      } else if (!strcmp(optarg,"afterselect,off")) {
-	// don't scan remainder of disk after doing selected segments
-	con->scanafterselect=1;
-      } else if (!strncmp(optarg,"pending,",strlen("pending,"))) {
-	// parse number of minutes that test should be pending
-	int i;
-	char *tailptr=NULL;
-	errno=0;
-	i=(int)strtol(optarg+strlen("pending,"), &tailptr, 10);
-	if (errno || *tailptr != '\0') {
-	  sprintf(extraerror, "Option -t pending,N requires N to be a non-negative integer\n");
-	  badarg = TRUE;
-	} else if (i<0 || i>65535) {
-	  sprintf(extraerror, "Option -t pending,N (N=%d) must have 0 <= N <= 65535\n", i);
-	  badarg = TRUE;
-	} else {
-	  con->pendingtime=i+1;
-	}
-      } else if (!strncmp(optarg,"select",strlen("select"))) {
-	// parse range of LBAs to test
-	uint64_t start, stop;
-
-        if (split_selective_arg(optarg, &start, &stop)) {
-	  sprintf(extraerror, "Option -t select,M-N must have non-negative integer M and N\n");
-          badarg = TRUE;
-        } else {
-          if (con->smartselectivenumspans >= 5 || start > stop) {
-            if (start > stop) {
-              sprintf(extraerror, "ERROR: Start LBA (%"PRIu64") > ending LBA (%"PRId64") in argument \"%s\"\n",
-                start, stop, optarg);
-            } else {
-              sprintf(extraerror,"ERROR: No more than five selective self-test spans may be"
-                " defined\n");
-            }
-	    badarg = TRUE;
-          }
-          con->smartselectivespan[con->smartselectivenumspans][0] = start;
-          con->smartselectivespan[con->smartselectivenumspans][1] = stop;
-          con->smartselectivenumspans++;
-          con->testcase            = SELECTIVE_SELF_TEST;
-        }
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'C':
-      captive = TRUE;
-      break;
-    case 'X':
-      con->smartselftestabort = TRUE;
-      con->testcase           = ABORT_SELF_TEST;
-      break;
-    case 'h':
-      con->dont_print=FALSE;
-      printslogan();
-      Usage();
-      EXIT(0);  
-      break;
-    case '?':
-    default:
-      con->dont_print=FALSE;
-      printslogan();
-#ifdef HAVE_GETOPT_LONG
-      // Point arg to the argument in which this option was found.
-      arg = argv[optind-1];
-      // Check whether the option is a long option that doesn't map to -h.
-      if (arg[1] == '-' && optchar != 'h') {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (optopt && (strchr(shortopts, optopt) != NULL)) {
-          pout("=======> ARGUMENT REQUIRED FOR OPTION: %s\n", arg+2);
-          printvalidarglistmessage(optopt);
-        } else
-          pout("=======> UNRECOGNIZED OPTION: %s\n",arg+2);
-	if (extraerror[0])
-	  pout("=======> %s", extraerror);
-        UsageSummary();
-        EXIT(FAILCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be
-        // missing.  Note (BA) this logic seems to fail using Solaris
-        // getopt!
-        if (strchr(shortopts, optopt) != NULL) {
-          pout("=======> ARGUMENT REQUIRED FOR OPTION: %c\n", optopt);
-          printvalidarglistmessage(optopt);
-        } else
-          pout("=======> UNRECOGNIZED OPTION: %c\n",optopt);
-	if (extraerror[0])
-	  pout("=======> %s", extraerror);
-        UsageSummary();
-        EXIT(FAILCMD);
-      }
-      Usage();
-      EXIT(0);  
-    } // closes switch statement to process command-line options
-    
-    // Check to see if option had an unrecognized or incorrect argument.
-    if (badarg) {
-      printslogan();
-      // It would be nice to print the actual option name given by the user
-      // here, but we just print the short form.  Please fix this if you know
-      // a clean way to do it.
-      pout("=======> INVALID ARGUMENT TO -%c: %s\n", optchar, optarg);
-      printvalidarglistmessage(optchar);
-      if (extraerror[0])
-	pout("=======> %s", extraerror);
-      UsageSummary();
-      EXIT(FAILCMD);
-    }
-  }
-  // At this point we have processed all command-line options.  If the
-  // print output is switchable, then start with the print output
-  // turned off
-  if (con->printing_switchable)
-    con->dont_print=TRUE;
-
-  // error message if user has asked for more than one test
-  if (1<(con->smartexeoffimmediate+con->smartshortselftest+con->smartextendselftest+
-         con->smartshortcapselftest+con->smartextendcapselftest+con->smartselftestabort + (con->smartselectivenumspans>0?1:0))){
-    con->dont_print=FALSE;
-    printslogan();
-    pout("\nERROR: smartctl can only run a single test type (or abort) at a time.\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-
-  // error message if user has set selective self-test options without
-  // asking for a selective self-test
-  if ((con->pendingtime || con->scanafterselect) && !con->smartselectivenumspans){
-    con->dont_print=FALSE;
-    printslogan();
-    if (con->pendingtime)
-      pout("\nERROR: smartctl -t pending,N must be used with -t select,N-M.\n");
-    else
-      pout("\nERROR: smartctl -t afterselect,(on|off) must be used with -t select,N-M.\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-
-  // If captive option was used, change test type if appropriate.
-  if (captive && con->smartshortselftest) {
-    con->smartshortselftest    = FALSE;
-    con->smartshortcapselftest = TRUE;
-    con->testcase              = SHORT_CAPTIVE_SELF_TEST;
-  } else if (captive && con->smartextendselftest) {
-    con->smartextendselftest    = FALSE;
-    con->smartextendcapselftest = TRUE;
-    con->testcase               = EXTEND_CAPTIVE_SELF_TEST;
-  }
-  else if (captive && con->smartconveyanceselftest) {
-    con->smartconveyanceselftest    = FALSE;
-    con->smartconveyancecapselftest = TRUE;
-    con->testcase                   = CONVEYANCE_CAPTIVE_SELF_TEST;
-  }
-  else if (captive && con->smartselectiveselftest) {
-    con->smartselectiveselftest    = FALSE;
-    con->smartselectivecapselftest = TRUE;
-    con->testcase                  = SELECTIVE_CAPTIVE_SELF_TEST;
-  }
- 
-  // From here on, normal operations...
-  printslogan();
-  
-  // Warn if the user has provided no device name
-  if (argc-optind<1){
-    pout("ERROR: smartctl requires a device name as the final command-line argument.\n\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-  
-  // Warn if the user has provided more than one device name
-  if (argc-optind>1){
-    int i;
-    pout("ERROR: smartctl takes ONE device name as the final command-line argument.\n");
-    pout("You have provided %d device names:\n",argc-optind);
-    for (i=0; i<argc-optind; i++)
-      pout("%s\n",argv[optind+i]);
-    UsageSummary();
-    EXIT(FAILCMD);
-  }  
-}
-
-// Printing function (controlled by global con->dont_print) 
-// [From GLIBC Manual: Since the prototype doesn't specify types for
-// optional arguments, in a call to a variadic function the default
-// argument promotions are performed on the optional argument
-// values. This means the objects of type char or short int (whether
-// signed or not) are promoted to either int or unsigned int, as
-// appropriate.]
-void pout(char *fmt, ...){
-  va_list ap;
-  
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  if (con->dont_print){
-    va_end(ap);
-    return;
-  }
-
-  // print out
-  vprintf(fmt,ap);
-  va_end(ap);
-  fflush(stdout);
-  return;
-}
-
-// This function is used by utility.c to report LOG_CRIT errors.
-// The smartctl version prints to stdout instead of syslog().
-void PrintOut(int priority, char *fmt, ...) {
-  va_list ap;
-
-  // avoid warning message about unused variable from gcc -W: just
-  // change value of local copy.
-  priority=0;
-
-  va_start(ap,fmt);
-  vprintf(fmt,ap);
-  va_end(ap);
-  return;
-}
-
-
-/* Main Program */
-int main (int argc, char **argv){
-  int fd,retval=0;
-  char *device;
-  smartmonctrl control;
-  char *mode=NULL;
-
-  // define control block for external functions
-  con=&control;
-
-  // Part input arguments
-  ParseOpts(argc,argv);
-
-  device = argv[argc-1];
-
-  // If use has specified 3ware controller, determine which interface 
-  if (con->controller_type == CONTROLLER_3WARE) {
-    con->controller_type=guess_device_type(device);
-    if (con->controller_type!=CONTROLLER_3WARE_9000_CHAR && con->controller_type!=CONTROLLER_3WARE_678K_CHAR)
-      con->controller_type = CONTROLLER_3WARE_678K;
-  }
-
-  if (con->controller_type == CONTROLLER_UNKNOWN)
-    con->controller_type=guess_device_type(device);
-  
-  if (con->controller_type == CONTROLLER_UNKNOWN) {
-    pout("Smartctl: please specify device type with the -d option.\n");
-    UsageSummary();
-    return FAILCMD;
-  }
-  
-  // set up mode for open() call.  SCSI case is:
-  switch (con->controller_type) {
-  case CONTROLLER_SCSI:
-    mode="SCSI";
-    break;
-  case CONTROLLER_ATA:
-  case CONTROLLER_3WARE_678K:
-    mode="ATA";
-    break;
-  case CONTROLLER_3WARE_9000_CHAR:
-    mode="ATA_3WARE_9000";
-    break;
-  case CONTROLLER_3WARE_678K_CHAR:
-    mode="ATA_3WARE_678K";
-    break;
-  }
-
-  // open device - SCSI devices are opened (O_RDWR | O_NONBLOCK) so the
-  // scsi generic device can be used (needs write permission for MODE 
-  // SELECT command) plus O_NONBLOCK to stop open hanging if media not
-  // present (e.g. with st).  Opening is retried O_RDONLY if read-only
-  // media prevents opening O_RDWR (it cannot happen for scsi generic
-  // devices, but it can for the others).
-  fd = deviceopen(device, mode);
-  if (fd<0) {
-    char errmsg[256];
-    snprintf(errmsg,256,"Smartctl open device: %s failed",argv[argc-1]);
-    errmsg[255]='\0';
-    syserror(errmsg);
-    return FAILDEV;
-  }
-
-  // now call appropriate ATA or SCSI routine
-  switch (con->controller_type) {
-  case CONTROLLER_ATA:
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_3WARE_9000_CHAR:
-  case CONTROLLER_3WARE_678K_CHAR:
-    retval = ataPrintMain(fd);
-    break;
-  case CONTROLLER_SCSI:
-    retval = scsiPrintMain(fd);
-    break;
-  default:
-    pout("Smartctl: specify if this is an ATA or SCSI device with the -d option.\n");
-    UsageSummary();
-    return FAILCMD;
-  }
-  
-  return retval;
-}
diff --git a/sm5/smartctl.h b/sm5/smartctl.h
deleted file mode 100644
index 5519a791d501dd01abd3ab22e8f0c5602e091235..0000000000000000000000000000000000000000
--- a/sm5/smartctl.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * smartctl.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef SMARTCTL_H_
-#define SMARTCTL_H_
-
-#define SMARTCTL_H_CVSID "$Id: smartctl.h,v 1.21 2004/01/29 03:21:06 ballen4705 Exp $\n"
-
-/* Boolean Values */
-#define TRUE 0x01
-#define FALSE 0x00
-
-// Return codes (bitmask)
-
-// command line did not parse, or internal error occured in smartctl
-#define FAILCMD   (0x01<<0)
-
-// device open failed
-#define FAILDEV   (0x01<<1)
-
-// read device identity (ATA only) failed
-#define FAILID    (0x01<<1)
-
-// smart command failed, or ATA identify device structure missing information
-#define FAILSMART (0x01<<2)
-
-// SMART STATUS returned FAILURE
-#define FAILSTATUS (0x01<<3)
-
-// Attributes found <= threshold with prefail=1
-#define FAILATTR (0x01<<4)
-
-// SMART STATUS returned GOOD but age attributes failed or prefail
-// attributes have failed in the past
-#define FAILAGE (0x01<<5)
-
-// Device had Errors in the error log
-#define FAILERR (0x01<<6)
-
-// Device had Errors in the self-test log
-#define FAILLOG (0x01<<7)
-
-// Classes of SMART commands.  Here 'mandatory' means "Required by the
-// ATA/ATAPI-5 Specification if the device implements the S.M.A.R.T.
-// command set."  The 'mandatory' S.M.A.R.T.  commands are: (1)
-// Enable/Disable Attribute Autosave, (2) Enable/Disable S.M.A.R.T.,
-// and (3) S.M.A.R.T. Return Status.  All others are optional.
-#define OPTIONAL_CMD 1
-#define MANDATORY_CMD 2
-
-void print_smartctl_examples();
-
-#endif
diff --git a/sm5/smartd.8.in b/sm5/smartd.8.in
deleted file mode 100644
index 40a517e82c0b4bce2ec0bf2ede081de3ac203d90..0000000000000000000000000000000000000000
--- a/sm5/smartd.8.in
+++ /dev/null
@@ -1,1771 +0,0 @@
-.ig
-Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- 
-$Id: smartd.8.in,v 1.78 2004/08/06 19:48:42 chrfranke Exp $
-
-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, write to the Free Software Foundation, Inc.,
-675 Mass Ave, Cambridge, MA 02139, USA.
- 
-This code was originally developed as a Senior Thesis by Michael
-Cornwell at the Concurrent Systems Laboratory (now part of the Storage
-Systems Research Center), Jack Baskin School of Engineering,
-University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-..
-.TH SMARTD 8 CURRENT_CVS_DATE CURRENT_CVS_VERSION CURRENT_CVS_DATE
-.SH NAME
-\fBsmartd\fP \- SMART Disk Monitoring Daemon
-
-.SH SYNOPSIS
-.B smartd [options]
-
-.SH FULL PATH
-.B /usr/sbin/smartd
-
-.SH PACKAGE VERSION
-CURRENT_CVS_VERSION released CURRENT_CVS_DATE at CURRENT_CVS_TIME
-
-.SH DESCRIPTION
-\fBsmartd\fP is a daemon that monitors the Self-Monitoring, Analysis
-and Reporting Technology (SMART) system built into many ATA-3 and
-later ATA, IDE and SCSI-3 hard drives. The purpose of SMART is to
-monitor the reliability of the hard drive and predict drive failures,
-and to carry out different types of drive self-tests.  This version of
-\fBsmartd\fP is compatible with ATA/ATAPI-5 and earlier standards (see
-\fBREFERENCES\fP below).
-
-\fBsmartd\fP will attempt to enable SMART monitoring on ATA devices
-(equivalent to \fBsmartctl -s on\fP) and polls these and SCSI devices
-every 30 minutes (configurable), logging SMART errors and changes of
-SMART Attributes via the SYSLOG interface.  The default location for
-these SYSLOG notifications and warnings is \fB/var/log/messages\fP.
-To change this default location, please see the \fB\'-l\'\fP
-command-line option described below.
-
-In addition to logging to a file, \fBsmartd\fP can also be configured
-to send email warnings if problems are detected.  Depending upon the
-type of problem, you may want to run self\-tests on the disk, back up
-the disk, replace the disk, or use a manufacturer\'s utility to force
-reallocation of bad or unreadable disk sectors.  If disk problems are
-detected, please see the \fBsmartctl\fP manual page and the
-\fBsmartmontools\fP web page/FAQ for further guidance.
-
-If you send a \fBUSR1\fP signal to \fBsmartd\fP it will immediately
-check the status of the disks, and then return to polling the disks
-every 30 minutes. See the \fB\'\-i\'\fP option below for additional
-details.
-
-\fBsmartd\fP can be configured at start-up using the configuration
-file \fB/etc/smartd.conf\fP (Windows: \fB./smartd.conf\fP).
-If the configuration file is subsequently modified, \fBsmartd\fP
-can be told to re-read the configuration file by sending it a
-\fBHUP\fP signal, for example with the command:
-.fi
-\fBkillall -HUP smartd\fP.
-.fi
-(Windows: See NOTES below.)
-
-On startup, if \fBsmartd\fP finds a syntax error in the configuration
-file, it will print an error message and then exit. However if
-\fBsmartd\fP is already running, then is told with a \fBHUP\fP signal
-to re-read the configuration file, and then find a syntax error in
-this file, it will print an error message and then continue, ignoring
-the contents of the (faulty) configuration file, as if the \fBHUP\fP
-signal had never been received.
-
-When \fBsmartd\fP is running in debug mode, the \fBQUIT\fP signal
-(normally generated from a shell with CONTROL\-C) is treated in the
-same way as a \fBHUP\fP signal: it makes \fBsmartd\fP reload its
-configuration file. To exit \fBsmartd\fP use CONTROL-\e
-(Cygwin: 2x CONTROL\-C, Windows: CONTROL\-Break).
-
-On startup, in the absence of the configuration file
-\fB/etc/smartd.conf\fP, the \fBsmartd\fP daemon first scans for all
-devices that support SMART.  The scanning is done as follows:
-.IP \fBLINUX:\fP 9
-Examine all entries \fB"/dev/hd[a-t]"\fP for IDE/ATA
-devices, and \fB"/dev/sd[a-z]"\fP for SCSI devices.
-.IP \fBFREEBSD:\fP 9
-Examine all entries \fB"/dev/ad[0-9]+"\fP for IDE/ATA
-devices and \fB"/dev/da[0-9]+"\fP for SCSI devices.
-.IP \fBNETBSD:\fP 9
-Authoritative list of disk devices is obtained from sysctl 
-\'hw.disknames\'.
-.IP \fBSOLARIS:\fP 9
-Examine all entries \fB"/dev/rdsk/c?t?d?s?"\fP for IDE/ATA and SCSI disk
-devices, and entries \fB"/dev/rmt/*"\fP for SCSI tape devices.
-.IP \fBWINDOWS:\fP 9
-Examine all entries \fB"/dev/hd[a-j]"\fP ("\\\\.\\PhysicalDisk[0-9]")
-for IDE/ATA devices on WinNT4/2000/XP, \fB"/dev/hd[a-d]"\fP
-(bitmask from "\\\\.\\SMARTVSD") for IDE/ATA devices on Win95/98/98SE/ME,
-and \fB"/dev/scsi[0-3][0-7]"\fP (ASPI adapter 0-3, ID 0-7) for SCSI
-devices on all versions of Windows.
-.IP \fBCYGWIN\fP: 9
-See "WINDOWS" above.
-.PP
-\fBsmartd\fP then monitors
-for \fIall\fP possible SMART errors (corresponding to the \fB\'\-a\'\fP
-Directive in the configuration file; see \fBCONFIGURATION FILE\fP
-below). 
-
-.SH 
-OPTIONS
-Long options are not supported on all systems.  Use \fB\'smartd
-\-h\'\fP to see the available options.
-.TP
-.B \-c FILE, \-\-configfile=FILE
-
-Read \fBsmartd\fP configuration Directives from FILE, instead of from
-the default location \fB/etc/smartd.conf\fP (Windows: \fB./smartd.conf\fP).
-If FILE does \fBnot\fP exist, then \fBsmartd\fP will print an error
-message and exit with nonzero status.  Thus, \'\-c /etc/smartd.conf\'
-can be used to verify the existence of the default configuration file.
-
-By using \'\-\' for FILE, the configuration is read from standard
-input. This is useful for commands like:
-.nf
-.B echo /dev/hdb \-m user@home \-M test | smartd \-c \- \-q onecheck
-.fi
-to perform quick and simple checks without a configuration file.
-
-.TP
-.B \-d, \-\-debug
-Runs \fBsmartd\fP in "debug" mode. In this mode, it displays status
-information to STDOUT rather than logging it to SYSLOG and does not
-\fBfork(2)\fP into the background and detach from the controlling
-terminal.  In this mode, \fBsmartd\fP also prints more verbose
-information about what it is doing than when operating in "daemon"
-mode. In this mode, the \fBQUIT\fP signal (normally generated from a
-terminal with CONTROL\-C) makes \fBsmartd\fP reload its configuration
-file.  Please use CONTROL-\e to exit
-(Cygwin: 2x CONTROL\-C, Windows: CONTROL\-Break).
-
-Windows only: The "debug" mode can be toggled by the command
-\fBsmartd sigusr2\fP. A new console for debug output is opened when
-debug mode is enabled.
-.TP
-.B \-D, \-\-showdirectives
-Prints a list (to STDOUT) of all the possible Directives which may
-appear in the configuration file /etc/smartd.conf, and then exits.
-These Directives are also described later in this man page. They may
-appear in the configuration file following the device name.
-.TP
-.B \-h, \-\-help, \-\-usage
-Prints usage message to STDOUT and exits.
-.TP
-.B \-i N, \-\-interval=N
-Sets the interval between disk checks to \fIN\fP seconds, where
-\fIN\fP is a decimal integer.  The minimum allowed value is ten and
-the maximum is the largest positive integer that can be represented on
-your system (often 2^31-1).  The default is 1800 seconds.
-
-Note that the superuser can make \fBsmartd\fP check the status of the
-disks at any time by sending it the \fBSIGUSR1\fP signal, for example
-with the command:
-.nf
-.B kill -SIGUSR1 <pid>
-.fi
-where \fB<pid>\fP is the process id number of \fBsmartd\fP.  One may
-also use:
-.nf
-.B killall -USR1 smartd
-.fi
-for the same purpose.
-.fi
-(Windows: See NOTES below.)
-
-.TP
-.B \-l FACILITY, \-\-logfacility=FACILITY
-Uses syslog facility FACILITY to log the messages from \fBsmartd\fP.
-Here FACILITY is one of \fIlocal0\fP, \fIlocal1\fP, ..., \fIlocal7\fP,
-or \fIdaemon\fP [default].  If this command-line option is not used,
-then by default messages from \fBsmartd\fP are logged to the facility
-\fIdaemon\fP.
-
-If you would like to have \fBsmartd\fP messages logged somewhere other
-than the default \fB/var/log/messages\fP location, this can typically
-be accomplished with (for example) the following steps:
-.RS 7
-.IP \fB[1]\fP 4
-Modify the script that starts \fBsmartd\fP to include the \fBsmartd\fP
-command-line argument \'\-l local3\'.  This tells \fBsmartd\fP to log its
-messages to facility \fBlocal3\fP.
-.IP \fB[2]\fP 4
-Modify the \fBsyslogd\fP configuration file (typically
-\fB/etc/syslog.conf\fP) by adding a line of the form:
-.nf
-\fBlocal3.* /var/log/smartd.log\fP
-.fi
-This tells \fBsyslogd\fP to log all the messages from facility \fBlocal3\fP to
-the designated file: /var/log/smartd.log.
-.IP \fB[3]\fP 4
-Tell \fBsyslogd\fP to re-read its configuration file, typically by
-sending the \fBsyslogd\fP process a \fBSIGHUP\fP hang-up signal.
-.IP \fB[4]\fP 4
-Start (or restart) the \fBsmartd\fP daemon.
-.RE
-.\"  The following two lines are a workaround for a man2html bug.  Please leave them.
-.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
-.TP
-.B \&
-For more detailed information, please refer to the man pages for
-\fBsyslog.conf\fP, \fBsyslogd\fP, and \fBsyslog\fP.  You may also want
-to modify the log rotation configuration files; see the man pages for
-\fBlogrotate\fP and examine your system\'s /etc/logrotate.conf file.
-
-Cygwin: The current release of Cygwin writes \fBsyslog\fP(3)
-messages to Windows event log or to file \fBC:/CYGWIN_SYSLOG.TXT\fP
-if the event log is not available.
-The FACILITY parameter is always ignored by Cygwin.
-
-Windows: Some \fBsyslog\fP(3) functionality is implemented
-internally in \fBsmartd\fP as follows: If no \'\-l\' option
-(or \'\-l daemon\') is specified, messages are written to Windows
-event log or to file \fB./smartd.log\fP if event log is not available
-(Win9x/ME or access denied). By specifying other values of FACILITY,
-log output is redirected as follows:
-\'\-l local0\' to file \fB./smartd.log\fP,
-\'\-l local1\' to standard output (redirect with \'>\' to any file),
-\'\-l local2\' to standard error,
-\'\-l local[3-7]\': to file \fB./smartd[1-5].log\fP.
-
-When using the event log, the enclosed utility \fBsyslogevt.exe\fP
-should be registered as an event message file to avoid error
-messages from the event viewer. Use \'\fBsyslogevt -r smartd\fP\'
-to register, \'\fBsyslogevt -u smartd\fP\' to unregister and
-\'\fBsyslogevt\fP\' for more help.
-
-.TP
-.B \-p NAME, \-\-pidfile=NAME
-Writes pidfile \fINAME\fP containing the \fBsmartd\fP Process ID
-number (PID).  To avoid symlink attacks make sure the directory to
-which pidfile is written is only writable for root.  Without this
-option, or if the \-\-debug option is given, no PID file is written on
-startup.  If \fBsmartd\fP is killed with a maskable signal then the
-pidfile is removed.
-.TP
-.B \-q WHEN, \-\-quit=WHEN
-Specifies when, if ever, \fBsmartd\fP should exit.  The valid
-arguments are to this option are:
-
-.I nodev
-\- Exit if there are no devices to monitor, or if any errors are found
-at startup in the configuration file.  This is the default.
-
-.I errors
-\- Exit if there are no devices to monitor, or if any errors are found
-in the configuration file /etc/smartd.conf at startup or whenever it
-is reloaded.
-
-.I nodevstartup
-\- Exit if there are no devices to monitor at startup.  But continue
-to run if no devices are found whenever the configuration file is
-reloaded.
-
-.I never
-\- Only exit if a fatal error occurs (no remaining system memory,
-invalid command line arguments). In this mode, even if there are no
-devices to monitor, or if the configuration file
-\fB/etc/smartd.conf\fP has errors, \fBsmartd\fP will continue to run,
-waiting to load a configuration file listing valid devices.
-
-.I onecheck
-\- Start \fBsmartd\fP in debug mode, then register devices, then check
-device\'s SMART status once, and then exit with zero exit status if all
-of these steps worked correctly.
-
-This last option is intended for \'distribution-writers\' who want to
-create automated scripts to determine whether or not to automatically
-start up \fBsmartd\fP after installing smartmontools.  After starting
-\fBsmartd\fP with this command-line option, the distribution\'s install
-scripts should wait a reasonable length of time (say ten seconds).  If
-\fBsmartd\fP has not exited with zero status by that time, the script
-should send \fBsmartd\fP a SIGTERM or SIGKILL and assume that
-\fBsmartd\fP will not operate correctly on the host.  Conversely, if
-\fBsmartd\fP exits with zero status, then it is safe to run
-\fBsmartd\fP in normal daemon mode. If \fBsmartd\fP is unable to
-monitor any devices or encounters other problems then it will return
-with non-zero exit status.
-.TP
-.B \-r TYPE, \-\-report=TYPE
-Intended primarily to help
-.B smartmontools
-developers understand the behavior of
-.B smartmontools
-on non-conforming or poorly conforming hardware.  This option reports
-details of
-\fBsmartd\fP
-transactions with the device.  The option can be used multiple times.
-When used just once, it shows a record of the ioctl() transactions
-with the device.  When used more than once, the detail of these ioctl()
-transactions are reported in greater detail.  The valid arguments to
-this option are:
-
-.I ioctl
-\- report all ioctl() transactions.
-
-.I ataioctl
-\- report only ioctl() transactions with ATA devices.
-
-.I scsiioctl
-\- report only ioctl() transactions with SCSI devices.
-
-Any argument may include a positive integer to specify the level of
-detail that should be reported.  The argument should be followed by a
-comma then the integer with no spaces.  For example, \fIataioctl,2\fP
-The default level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are
-equivalent.
-
-.TP
-.B \-\-service
-Windows only: Enables \fBsmartd\fP to run as a Windows service.
-It must be specified in the service command line as the first argument.
-See NOTES below for details.
-
-.TP
-.B \-V, \-\-version, \-\-license, \-\-copyright
-Prints license, copyright, and CVS version information onto
-STDOUT and then exits. Please include this information if you are
-reporting bugs, or have specific questions about the behavior of
-\fBsmartd\fP.
-
-.SH EXAMPLES
-
-.B
-smartd
-.fi
-Runs the daemon in forked mode. This is the normal way to run
-\fBsmartd\fP.
-Entries are logged to SYSLOG (by default
-.B /var/log/messages.)
-
-.B
-smartd -d -i 30
-.fi
-Run in foreground (debug) mode, checking the disk status
-every 30 seconds.
-
-.B
-smartd -q onecheck
-.fi
-Registers devices, and checks the status of the devices exactly
-once. The exit status (the bash
-.B $?
-variable) will be zero if all went well, and nonzero if no devices
-were detected or some other problem was encountered.
-
-.fi 
-Note that \fBsmartmontools\fP provides a start-up script in
-\fB/etc/rc.d/init.d/smartd\fP which is responsible for starting and
-stopping the daemon via the normal init interface.  Using this script,
-you can start \fBsmartd\fP by giving the command:
-.nf
-.B /etc/rc.d/init.d/smartd start
-.fi
-and stop it by using the command:
-.nf
-.B /etc/rc.d/init.d/smartd stop
-
-.fi
-If you want \fBsmartd\fP to start running whenever your machine is
-booted, this can be enabled by using the command:
-.nf
-.B /sbin/chkconfig --add smartd
-.fi
-and disabled using the command:
-.nf
-.B /sbin/chkconfig --del smartd
-.fi
-
-.\" DO NOT MODIFY THIS OR THE FOLLOWING TWO LINES. THIS MATERIAL
-.\" IS AUTOMATICALLY INCLUDED IN THE FILE smartd.conf.5
-.\" STARTINCLUDE
-
-.SH CONFIGURATION FILE /etc/smartd.conf
-In the absence of a configuration file,
-\fBsmartd\fP 
-will try to open the 20 ATA devices 
-.B /dev/hd[a-t] 
-and the 26 SCSI devices
-.B /dev/sd[a-z]
-under Linux. Under FreeBSD, 
-\fBsmartd\fP
-will try to open all existing ATA devices (with entries in /dev)
-.B /dev/ad[0-9]+
-and all existing SCSI devices
-.B /dev/da[0-9]+.
-This can be annoying if you have an ATA or SCSI device that hangs or
-misbehaves when receiving SMART commands.  Even if this causes no
-problems, you may be annoyed by the string of error log messages about
-block-major devices that can\'t be found, and SCSI devices that can\'t
-be opened.
-
-One can avoid this problem, and gain more control over the types of
-events monitored by
-\fBsmartd\fP,
-by using the configuration file
-.B /etc/smartd.conf.
-This file contains a list of devices to monitor, with one device per
-line.  An example file is included with the
-.B smartmontools
-distribution. You will find this sample configuration file in
-\fB/usr/share/doc/smartmontools-5.1/\fP. For security, the configuration file
-should not be writable by anyone but root. The syntax of the file is as
-follows:
-.IP \(bu 4
-There should be one device listed per line, although you may have
-lines that are entirely comments or white space.
-.IP \(bu 4
-Any text following a hash sign \'#\' and up to the end of the line is
-taken to be a comment, and ignored.
-.IP \(bu 4
-Lines may be continued by using a backslash \'\e\' as the last
-non-whitespace or non-comment item on a line.
-.IP \(bu 4
-Note: a line whose first character is a hash sign \'#\' is treated as
-a white-space blank line, \fBnot\fP as a non-existent line, and will
-\fBend\fP a continuation line.
-.PP 0
-.fi
-Here is an example configuration file.  It\'s for illustrative purposes
-only; please don\'t copy it onto your system without reading to the end
-of the
-.B DIRECTIVES
-Section below!
-
-.nf
-.B ################################################
-.B # This is an example smartd startup config
-.B # file /etc/smartd.conf for monitoring three ATA
-.B # disks, three SCSI disks, and six ATA disks
-.B # behind two 3ware controllers.
-.B #
-.nf
-.B # First ATA disk on each of two interfaces. On
-.B # the second disk, do a long self-test every
-.B # Sunday at 3am.
-.B #
-.B \ \ /dev/hda -a -m admin@example.com,root@localhost 
-.B \ \ /dev/hdc -a -I 194 -I 5 -i 12 -s L/../../7/03
-.B #
-.nf
-.B # SCSI disks.  Send a TEST warning email to admin on
-.B # startup.
-.B #
-.B \ \ /dev/sda
-.B \ \ /dev/sdb -m admin@example.com -M test
-.B #
-.nf
-.B # Strange device.  It\'s SCSI. Do a scheduled
-.B # long self test at 5am Monday/Thursday
-.B \ \ /dev/weird -d scsi -s L/../../(1|4)/05
-.B #
-.nf
-.B # Four ATA disks on a 3ware 6/7/8000 controller.
-.B # Do short self-tests daily at midnight, 1, 2, and 3 am
-.B # (Note that the syntax /dev/twe0 is also allowed.)
-.B \ \ /dev/sdc -d 3ware,0 -a -s S/../.././00
-.B \ \ /dev/sdc -d 3ware,1 -a -s S/../.././01
-.B \ \ /dev/sdd -d 3ware,2 -a -s S/../.././02
-.B \ \ /dev/sdd -d 3ware,3 -a -s S/../.././03
-.B #
-.nf
-.B # Two ATA disks on a 3ware 9000 controller.
-.B # Do long self-tests Sundays at midnight and 2 am
-.B \ \ /dev/twa0 -d 3ware,0 -a -s L/../../7/00
-.B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
-.B #
-.nf
-.B # The following line enables monitoring of the 
-.B # ATA Error Log and the Self-Test Error Log.  
-.B # It also tracks changes in both Prefailure
-.B # and Usage Attributes, apart from Attributes
-.B # 9, 194, and 231, and shows  continued lines:
-.B #
-.B \ \ /dev/hdd\ -l\ error\ \e
-.B \ \ \ \ \ \ \ \ \ \ \ -l\ selftest\ \e
-.B \ \ \ \ \ \ \ \ \ \ \ -t\ \e\ \ \ \ \ \ # Attributes not tracked:
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 194\ \e\ \ # temperature
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 231\ \e\ \ # also temperature
-.B \ \ \ \ \ \ \ \ \ \ \ -I 9\ \ \ \ \ \ # power-on hours
-.B #
-.B ################################################
-.fi
-
-.PP 
-.SH CONFIGURATION FILE DIRECTIVES
-.PP
-
-If the first non-comment entry in the configuration file is the text
-string
-.B DEVICESCAN
-in capital letters, then
-\fBsmartd\fP
-will ignore any remaining lines in the configuration file, and will
-scan for devices.
-.B DEVICESCAN
-may optionally be followed by Directives that will apply to all
-devices that are found in the scan.  Please see below for additional
-details.
-
-.sp 2
-The following are the Directives that may appear following the device
-name or
-.B DEVICESCAN
-on any line of the
-.B /etc/smartd.conf
-configuration file. Note that
-.B these are NOT command-line options for 
-\fBsmartd\fP.
-The Directives below may appear in any order, following the device
-name. 
-
-.B For an ATA device,
-if no Directives appear, then the device will be monitored
-as if the \'\-a\' Directive (monitor all SMART properties) had been given.
-
-.B If a SCSI disk is listed,
-it will be monitored at the maximum implemented level: roughly
-equivalent to using the \'\-H \-l selftest\' options for an ATA disk.
-So with the exception of \'\-d\', \'\-m\', \'\-l selftest\', \'\-s\', and
-\'\-M\', the Directives below are ignored for SCSI disks.  For SCSI
-disks, the \'\-m\' Directive sends a warning email if the SMART status
-indicates a disk failure or problem, if the SCSI inquiry about disk
-status fails, or if new errors appear in the self-test log.
-
-.B If a 3ware controller is used
-then the corresponding SCSI (/dev/sd?) or character device (/dev/twe?
-or /dev/twa?) must be listed, along with the \'\-d 3ware,N\' Directive
-(see below).  The individual ATA disks hosted by the 3ware controller
-appear to \fBsmartd\fP as normal ATA devices.  Hence all the ATA
-directives can be used for these disks (but see note below).
-
-.TP
-.B \-d TYPE
-Specifies the type of the device.  This Directive may be used multiple times
-for one device, but the arguments \fIata\fP, \fIscsi\fP, and \fI3ware,N\fP are
-mutually-exclusive. If more than one is given then
-\fBsmartd\fP
-will use the last one which appears.
-
-If none of these three arguments is given, then \fBsmartd\fP will
-first attempt to guess the device type by looking at whether the sixth
-character in the device name is an \'s\' or an \'h\'.  This will work for
-device names like /dev/hda or /dev/sdb, and corresponds to choosing
-\fIata\fP or \fIscsi\fP respectively. If
-\fBsmartd\fP
-can\'t guess from this sixth character, then it will simply try to
-access the device using first ATA and then SCSI ioctl()s.
-
-The valid arguments to this Directive are:
-
-.I ata
-\- the device type is ATA.  This prevents
-\fBsmartd\fP
-from issuing SCSI commands to an ATA device.
-
-.I scsi
-\- the device type is SCSI.  This prevents
-\fBsmartd\fP
-from issuing ATA commands to a SCSI device.
-
-.I 3ware,N
-\- the device consists of one or more ATA disks connected to a 3ware
-RAID controller. The non-negative integer N (in the range from 0 to 15
-inclusive) denotes which disk on the controller is monitored.  In log
-files and email messages this disk will be identified as 3ware_disk_XX
-with XX in the range from 00 to 15 inclusive.
-
-This Directive may at first appear confusing, because the 3ware
-controller is a SCSI device (such as /dev/sda) and should be listed as
-such in the the configuration file.
-However when the \'\-d 3ware,N\'
-Directive is used, then the corresponding disk is addressed using
-native ATA commands which are \'passed through\' the SCSI driver. All
-ATA Directives listed in this man page may be used.  Note that while
-you may use \fBany\fP of the 3ware SCSI logical devices /dev/sd? to
-address \fBany\fP of the physical disks (3ware ports), error and log
-messages will make the most sense if you always list the 3ware SCSI
-logical device corresponding to the particular physical disks.  Please
-see the \fBsmartctl\fP man page for further details.
-
-ATA disks behind 3ware controllers may alternatively be accessed via a
-character device interface /dev/twe0-15 (3ware 6000/7000/8000
-controllers) and /dev/twa0-15 (3ware 9000 series controllers).  Note
-that the 9000 series controllers may \fBonly\fP be accessed using the
-character device interface /dev/twa0-15 and not the SCSI device
-interface /dev/sd?.  Please see the \fBsmartctl\fP man page for
-further details.
-
-Note that older 3w-xxxx drivers do not pass the \'Enable Autosave\'
-(\fB-S on\fP) and \'Enable Automatic Offline\' (\fB-o on\fP) commands
-to the disk, if the SCSI interface is used, and produce these types of
-harmless syslog error messages instead: \fB\'3w-xxxx: tw_ioctl():
-Passthru size (123392) too big\'\fP. This can be fixed by upgrading to
-version 1.02.00.037 or later of the 3w-xxxx driver, or by applying a
-patch to older versions.  See
-\fBhttp://smartmontools.sourceforge.net/\fP for instructions.
-Alternatively use the character device interfaces /dev/twe0-15 (3ware
-6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series
-controllers).
-
-
-.B 3ware controllers are currently ONLY supported under Linux.
-
-.I removable
-\- the device or its media is removable.  This indicates to
-\fBsmartd\fP
-that it should continue (instead of exiting, which is the default
-behavior) if the device does not appear to be present when
-\fBsmartd\fP is started.  This Directive may be used in conjunction
-with the other \'\-d\' Directives.
-
-.TP
-.B \-n POWERMODE
-This \'nocheck\' Directive is used to prevent a disk from being
-spun-up when it is periodically polled by \fBsmartd\fP.
-
-ATA disks have five different power states. In order of increasing
-power consumption they are: \'OFF\', \'SLEEP\', \'STANDBY\', \'IDLE\',
-and \'ACTIVE\'.  Typically in the OFF, SLEEP, and STANDBY modes the
-disk\'s platters are not spinning. But usually, in response to SMART
-commands issued by \fBsmartd\fP, the disk platters are spun up.  So if
-this option is not used, then a disk which is in a low\-power mode may
-be spun up and put into a higher\-power mode when it is periodically
-polled by \fBsmartd\fP.
-
-Note that if the disk is in SLEEP mode when \fBsmartd\fP is started,
-then it won't respond to \fBsmartd\fP commands, and so the disk won't
-be registered as a device for \fBsmartd\fP to monitor. If a disk is in
-any other low\-power mode, then the commands issued by \fBsmartd\fP to
-register the disk will probably cause it to spin\-up.
-
-The \'\fB\-n\fP\' (nocheck) Directive specifies if \fBsmartd\fP\'s
-periodic checks should still be carried out when the device is in a
-low\-power mode.  It may be used to prevent a disk from being spun\-up
-by periodic \fBsmartd\fP polling.  The allowed values of POWERMODE
-are:
-
-.I never
-\- \fBsmartd\fP will poll (check) the device regardless of its power
-mode. This may cause a disk which is spun\-down to be spun\-up when
-\fBsmartd\fP checks it.  This is the default behavior if the '\-n'
-Directive is not given.
-
-.I sleep
-\- check the device unless it is in SLEEP mode.
-
-.I standby
-\- check the device unless it is in SLEEP or STANDBY mode.  In
-these modes most disks are not spinning, so if you want to prevent
-a laptop disk from spinning up each time that \fBsmartd\fP polls,
-this is probably what you want.
-
-.I idle
-\- check the device unless it is in SLEEP, STANDBY or IDLE mode.
-In the IDLE state, most disks are still spinning, so this is probably
-not what you want.
-
-
-.TP
-.B \-T TYPE
-Specifies how tolerant
-\fBsmartd\fP
-should be of SMART command failures.  The valid arguments to this
-Directive are:
-
-.I normal
-\- do not try to monitor the disk if a mandatory SMART command fails, but
-continue if an optional SMART command fails.  This is the default.
-
-.I permissive
-\- try to monitor the disk even if it appears to lack SMART
-capabilities.  This may be required for some old disks (prior to
-ATA\-3 revision 4) that implemented SMART before the SMART standards
-were incorporated into the ATA/ATAPI Specifications.  This may also be
-needed for some Maxtor disks which fail to comply with the ATA
-Specifications and don't properly indicate support for error\- or
-self\-test logging.
-
-[Please see the \fBsmartctl \-T\fP command-line option.]
-.TP
-.B \-o VALUE
-Enables or disables SMART Automatic Offline Testing when
-\fBsmartd\fP
-starts up and has no further effect.  The valid arguments to this
-Directive are \fIon\fP and \fIoff\fP.
-
-The delay between tests is vendor-specific, but is typically four
-hours.
-
-Note that SMART Automatic Offline Testing is \fBnot\fP part of the ATA
-Specification.  Please see the
-.B smartctl \-o
-command-line option documentation for further information about this
-feature.
-.TP
-.B \-S VALUE
-Enables or disables Attribute Autosave when \fBsmartd\fP
-starts up and has no further effect.  The valid arguments to this
-Directive are \fIon\fP and \fIoff\fP.  Also affects SCSI devices.
-[Please see the \fBsmartctl \-S\fP command-line option.]
-.TP
-.B \-H
-Check the SMART health status of the disk.  If any Prefailure
-Attributes are less than or equal to their threshold values, then disk
-failure is predicted in less than 24 hours, and a message at loglevel
-.B \'LOG_CRITICAL\'
-will be logged to syslog.  [Please see the
-.B smartctl \-H
-command-line option.]
-.TP
-.B \-l TYPE
-Reports increases in the number of errors in one of the two SMART logs.  The
-valid arguments to this Directive are:
-
-.I error
-\- report if the number of ATA errors reported in the ATA Error Log
-has increased since the last check.
-
-.I selftest
-\- report if the number of failed tests reported in the SMART
-Self-Test Log has increased since the last check, or if the timestamp
-associated with the most recent failed test has increased.  Note that
-such errors will \fBonly\fP be logged if you run self-tests on the
-disk (and it fails a test!).  Self-Tests can be run automatically by
-\fBsmartd\fP: please see the \fB\'\-s\'\fP Directive below.
-Self-Tests can also be run manually by using the \fB\'\-t\ short\'\fP
-and \fB\'\-t\ long\'\fP options of \fBsmartctl\fP and the results of
-the testing can be observed using the \fBsmartctl \'\-l\ selftest\'\fP
-command-line option.]
-
-[Please see the \fBsmartctl \-l\fP and \fB\-t\fP command-line
-options.]
-.TP
-.B \-s REGEXP
-Run Self-Tests or Offline Immediate Tests, at scheduled times.  A
-Self- or Offline Immediate Test will be run at the end of periodic
-device polling, if all 12 characters of the string \fBT/MM/DD/d/HH\fP
-match the extended regular expression \fBREGEXP\fP. Here:
-.RS 7
-.IP \fBT\fP 4
-is the type of the test.  The values that \fBsmartd\fP will try to
-match (in turn) are: \'L\' for a \fBL\fPong Self-Test, \'S\' for a
-\fBS\fPhort Self-Test, \'C\' for a \fBC\fPonveyance Self-Test (ATA
-only), and \'O\' for an \fBO\fPffline Immediate Test (ATA only).  As
-soon as a match is found, the test will be started and no additional
-matches will be sought for that device and that polling cycle.
-.IP \fBMM\fP 4
-is the month of the year, expressed with two decimal digits.  The
-range is from 01 (January) to 12 (December) inclusive.  Do \fBnot\fP
-use a single decimal digit or the match will always fail!
-.IP \fBDD\fP 4
-is the day of the month, expressed with two decimal digits. The
-range is from 01 to 31 inclusive.  Do \fBnot\fP
-use a single decimal digit or the match will always fail!
-.IP \fBd\fP 4
-is the day of the week, expressed with one decimal digit.  The
-range is from 1 (Monday) to 7 (Sunday) inclusive.
-.IP \fBHH\fP 4
-is the hour of the day, written with two decimal digits, and given in
-hours after midnight.  The range is 00 (midnight to just before 1am)
-to 23 (11pm to just before midnight) inclusive.  Do \fBnot\fP use a
-single decimal digit or the match will always fail!
-.RE
-.\"  The following two lines are a workaround for a man2html bug.  Please leave them.
-.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
-.TP
-.B \&
-Some examples follow.  In reading these, keep in mind that in extended
-regular expressions a dot \fB\'.\'\fP matches any single character, and
-a parenthetical expression such as \fB\'(A|B|C)\'\fP denotes any one of the three possibilities \fBA\fP,
-\fBB\fP, or \fBC\fP.
-
-To schedule a short Self-Test between 2-3am every morning, use:
-.nf
-\fB \-s S/../.././02\fP
-.fi
-To schedule a long Self-Test between 4-5am every Sunday morning, use:
-.nf
-\fB \-s L/../../7/04\fP
-.fi
-To schedule a long Self-Test between 10-11pm on the first and
-fifteenth day of each month, use:
-.nf
-\fB \-s L/../(01|15)/./22\fP
-.fi
-To schedule an Offline Immediate test after every midnight, 6am,
-noon,and 6pm, plus a Short Self-Test daily at 1-2am and a Long
-Self-Test every Saturday at 3-4am, use:
-.nf
-\fB \-s (O/../.././(00|06|12|18)|S/../.././01|L/../../6/03)\fP
-.fi
-
-Scheduled tests are run immediately following the regularly-scheduled
-device polling, if the current local date, time, and test type, match
-\fBREGEXP\fP.  By default the regularly-scheduled device polling
-occurs every thirty minutes after starting \fBsmartd\fP.  Take caution
-if you use the \'\-i\' option to make this polling interval more than
-sixty minutes: the poll times may fail to coincide with any of the
-testing times that you have specified with \fBREGEXP\fP, and so the
-self tests may not take place as you wish.
-
-Before running an offline or self-test, \fBsmartd\fP checks to be sure
-that a self-test is not already running.  If a self-test \fBis\fP
-already running, then this running self test will \fBnot\fP be
-interrupted to begin another test.
-
-\fBsmartd\fP will not attempt to run \fBany\fP type of test if another
-test was already started or run in the same hour.
-
-Each time a test is run, \fBsmartd\fP will log an entry to SYSLOG.
-You can use these to verify that you constructed \fBREGEXP\fP
-correctly.  The matching order (\fBL\fP before \fBS\fP before \fBC\fP
-before \fBO\fP) ensures that if multiple test types are all scheduled
-for the same hour, the longer test type has precedence.  This is
-usually the desired behavior.
-
-Unix users: please beware that the rules for extended regular
-expressions [regex(7)] are \fBnot\fP the same as the rules for
-file\-name pattern matching by the shell [glob(7)].  \fBsmartd\fP will
-issue harmless informational warning messages if it detects characters
-in \fBREGEXP\fP that appear to indicate that you have made this
-mistake.
-
-.TP
-.B \-m ADD
-Send a warning email to the email address \fBADD\fP if the \'\-H\',
-\'\-l\', \'\-f\', \'\-C\', or \'\-O\' Directives detect a failure or a
-new error, or if a SMART command to the disk fails. This Directive
-only works in conjunction with these other Directives (or with the
-equivalent default \'\-a\' Directive).
-
-To prevent your email in-box from getting filled up with warning
-messages, by default only a single warning will be sent for each of
-the enabled alert types, \'\-H\', \'\-l\', \'\-f\', \'\-C\', or
-\'\-O\' even if more than one failure or error is detected or if the
-failure or error persists.  [This behavior can be modified; see the
-\'\-M\' Directive below.]
-
-To send email to more than one user, please use the following "comma
-separated" form for the address: \fBuser1@add1,user2@add2,...,userN@addN\fP
-(with no spaces).
-
-To test that email is being sent correctly, use the \'\-M test\'
-Directive described below to send one test email message on
-\fBsmartd\fP
-startup.
-
-By default, email is sent using the system 
-.B mail
-command.  In order that
-\fBsmartd\fP
-find the mail command (normally /bin/mail) an executable named
-.B \'mail\'
-must be in the path of the shell or environment from which
-\fBsmartd\fP
-was started.  If you wish to specify an explicit path to the mail
-executable (for example /usr/local/bin/mail) or a custom script to
-run, please use the \'\-M exec\' Directive below.
-
-Note that by default under Solaris, in the previous paragraph,
-\'\fBmailx\fP\' and \'\fB/bin/mailx\fP\' are used, since Solaris
-\'/bin/mail\' does not accept a \'\-s\' (Subject) command-line
-argument.
-
-On Windows, the \'\fBBlat\fP\' mailer
-(\fBhttp://blat.sourceforge.net/\fP) is used by default.
-This mailer uses a different command line syntax, see
-\'\-M exec\' below.
-
-Note also that there is a special argument
-.B <nomailer>
-which can be given to the \'\-m\' Directive in conjunction with the \'\-M
-exec\' Directive. Please see below for an explanation of its effect.
-
-If the mailer or the shell running it produces any STDERR/STDOUT
-output, then a snippet of that output will be copied to SYSLOG.  The
-remainder of the output is discarded. If problems are encountered in
-sending mail, this should help you to understand and fix them.  If
-you have mail problems, we recommend running \fBsmartd\fP in debug
-mode with the \'-d\' flag, using the \'-M test\' Directive described
-below.
-
-The following extension is available on Windows:
-By specifying \'\fBmsgbox\fP\' as a mail address, a warning
-"email" is displayed as a message box on the screen.
-Using both \'\fBmsgbox\fP\' and regular mail addresses is possible,
-if \'\fBmsgbox\fP\' is the first word in the comma separated list.
-With \'\fBsysmsgbox\fP\', a system modal (always on top) message box
-is used. If running as a service, a service notification message box
-(always shown on current visible desktop) is used.
-
-.TP
-.B \-M TYPE
-These Directives modify the behavior of the
-\fBsmartd\fP
-email warnings enabled with the \'\-m\' email Directive described above.
-These \'\-M\' Directives only work in conjunction with the \'\-m\'
-Directive and can not be used without it.
-
-Multiple \-M Directives may be given.  If conflicting \-M Directives
-are given (example: \-M once \-M daily) then the final one (in the
-example, \-M daily) is used.
-
-The valid arguments to the \-M Directive are:
-
-.I once
-\- send only one warning email for each type of disk problem detected.  This
-is the default.
-
-.I daily
-\- send additional warning reminder emails, once per day, for each type
-of disk problem detected.
-
-.I diminishing
-\- send additional warning reminder emails, after a one-day interval,
-then a two-day interval, then a four-day interval, and so on for each
-type of disk problem detected. Each interval is twice as long as the
-previous interval.
-
-.I test
-\- send a single test email
-immediately upon
-\fBsmartd\fP
-startup.  This allows one to verify that email is delivered correctly.
-
-.I exec PATH
-\- run the executable PATH instead of the default mail command, when
-\fBsmartd\fP
-needs to send email.  PATH must point to an executable binary file or
-script.
-
-By setting PATH to point to a customized script, you can make
-\fBsmartd\fP perform useful tricks when a disk problem is detected
-(beeping the console, shutting down the machine, broadcasting warnings
-to all logged-in users, etc.)  But please be careful. \fBsmartd\fP
-will \fBblock\fP until the executable PATH returns, so if your
-executable hangs, then \fBsmartd\fP will also hang. Some sample
-scripts are included in
-/usr/share/doc/smartmontools-5.1/examplescripts/.
-
-The return status of the executable is recorded by \fBsmartd\fP in
-SYSLOG. The executable is not expected to write to STDOUT or
-STDERR.  If it does, then this is interpreted as indicating that
-something is going wrong with your executable, and a fragment of this
-output is logged to SYSLOG to help you to understand the problem.
-Normally, if you wish to leave some record behind, the executable
-should send mail or write to a file or device.
-
-Before running the executable, \fBsmartd\fP sets a number of
-environment variables.  These environment variables may be used to
-control the executable\'s behavior.  The environment variables
-exported by \fBsmartd\fP are:
-.RS 7
-.IP \fBSMARTD_MAILER\fP 4
-is set to the argument of \-M exec, if present or else to \'mail\'
-(examples: /bin/mail, mail).
-.IP \fBSMARTD_DEVICE\fP 4
-is set to the device path (examples: /dev/hda, /dev/sdb).
-.IP \fBSMARTD_DEVICETYPE\fP 4
-is set to the device type (possible values: ata, scsi, 3ware,N). Here
-N=0,...,15 denotes the ATA disk behind a 3ware RAID controller.
-.IP \fBSMARTD_DEVICESTRING\fP 4
-is set to the device description.  For SMARTD_DEVICETYPE of ata or
-scsi, this is the same as SMARTD_DEVICE.  For 3ware RAID controllers,
-the form used is \'/dev/sdc [3ware_disk_01]\'. In this case the device
-string contains a space and is NOT quoted.  So to use
-$SMARTD_DEVICESTRING in a bash script you should probably enclose it
-in double quotes.
-.IP \fBSMARTD_FAILTYPE\fP 4
-gives the reason for the warning or message email.  The possible values that
-it takes and their meanings are:
-.nf
-.fi
-\fIEmailTest\fP: this is an email test message.
-.nf
-.fi
-\fIHealth\fP: the SMART health status indicates imminent failure.
-.nf
-.fi
-\fIUsage\fP: a usage Attribute has failed.
-.nf
-.fi
-\fISelfTest\fP: the number of self-test failures has increased.
-.nf
-.fi
-\fIErrorCount\fP: the number of errors in the ATA error log has increased.
-.nf
-.fi
-\fICurrentPendingSector\fP: one of more disk sectors could not be
-read and are marked to be reallocated (replaced with spare sectors).
-.nf
-.fi
-\fIOfflineUncorrectableSector\fP: during off\-line testing, or self\-testing,
-one or more disk sectors could not be read.
-.nf
-.fi
-\fIFailedHealthCheck\fP: the SMART health status command failed.
-.nf
-.fi
-\fIFailedReadSmartData\fP: the command to read SMART Attribute data failed.
-.nf
-.fi
-\fIFailedReadSmartErrorLog\fP: the command to read the SMART error log failed.
-.nf
-.fi
-\fIFailedReadSmartSelfTestLog\fP: the command to read the SMART self-test log failed.
-.nf
-.fi
-\fIFailedOpenDevice\fP: the open() command to the device failed.
-.IP \fBSMARTD_ADDRESS\fP 4
-is determined by the address argument ADD of the \'\-m\' Directive.
-If ADD is \fB<nomailer>\fP, then \fBSMARTD_ADDRESS\fP is not set.
-Otherwise, it is set to the comma-separated-list of email addresses
-given by the argument ADD, with the commas replaced by spaces
-(example:admin@example.com root).  If more than one email address is
-given, then this string will contain space characters and is NOT
-quoted, so to use it in a bash script you may want to enclose it in
-double quotes.
-.IP \fBSMARTD_MESSAGE\fP 4
-is set to the warning email message string from
-\fBsmartd\fP. 
-This message string contains space characters and is NOT quoted. So to
-use $SMARTD_MESSAGE in a bash script you should probably enclose it in
-double quotes.
-.IP \fBSMARTD_TFIRST\fP 4
-is a text string giving the time and date at which the first problem
-of this type was reported. This text string contains space characters
-and no newlines, and is NOT quoted. For example:
-.nf
-.fi
-Sun Feb  9 14:58:19 2003 CST
-.IP \fBSMARTD_TFIRSTEPOCH\fP 4
-is an integer, which is the unix epoch (number of seconds since Jan 1,
-1970) for \fBSMARTD_TFIRST\fP.
-.RE
-.\"  The following two lines are a workaround for a man2html bug.  Please leave them.
-.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
-.TP
-.B \&
-The shell which is used to run PATH is system-dependent. For vanilla
-Linux/glibc it\'s bash. For other systems, the man page for
-\fBpopen\fP(3) should say what shell is used.
-
-If the \'\-m ADD\' Directive is given with a normal address argument,
-then the executable pointed to by PATH will be run in a shell with
-STDIN receiving the body of the email message, and with the same
-command-line arguments:
-.nf
--s "$SMARTD_SUBJECT" $SMARTD_ADDRESS
-.fi
-that would normally be provided to \'mail\'.  Examples include:
-.nf
-.B -m user@home -M exec /bin/mail
-.B -m admin@work -M exec /usr/local/bin/mailto
-.B -m root -M exec /Example_1/bash/script/below
-.fi
-
-Note that on Windows, the syntax of the \'\fBBlat\fP\' mailer is
-used:
-.nf
-- -q -subject "$SMARTD_SUBJECT" -to "$SMARTD_ADDRESS"
-.fi
-
-If the \'\-m ADD\' Directive is given with the special address argument
-.B <nomailer>
-then the executable pointed to by PATH is run in a shell with
-.B no
-STDIN and
-.B no
-command-line arguments, for example:
-.nf
-.B -m <nomailer> -M exec /Example_2/bash/script/below
-.fi
-If the executable produces any STDERR/STDOUT output, then \fBsmartd\fP
-assumes that something is going wrong, and a snippet of that output
-will be copied to SYSLOG.  The remainder of the output is then
-discarded.
-
-Some EXAMPLES of scripts that can be used with the \'\-M exec\'
-Directive are given below. Some sample scripts are also included in
-/usr/share/doc/smartmontools-5.1/examplescripts/.
-
-.TP
-.B \-f
-Check for \'failure\' of any Usage Attributes.  If these Attributes are
-less than or equal to the threshold, it does NOT indicate imminent
-disk failure.  It "indicates an advisory condition where the usage or
-age of the device has exceeded its intended design life period."
-[Please see the \fBsmartctl \-A\fP command-line option.]
-.TP
-.B \-p
-Report anytime that a Prefail Attribute has changed
-its value since the last check, 30 minutes ago. [Please see the
-.B smartctl \-A
-command-line option.]
-.TP
-.B \-u
-Report anytime that a Usage Attribute has changed its value
-since the last check, 30 minutes ago. [Please see the
-.B smartctl \-A
-command-line option.]
-.TP
-.B \-t
-Equivalent to turning on the two previous flags \'\-p\' and \'\-u\'.
-Tracks changes in \fIall\fP device Attributes (both Prefailure and
-Usage). [Please see the \fBsmartctl\fP \-A command-line option.]
-.TP
-.B \-i ID
-Ignore device Attribute number \fBID\fP when checking for failure of
-Usage Attributes.  \fBID\fP must be a decimal integer in the range
-from 1 to 255.  This Directive modifies the behavior of the \'\-f\'
-Directive and has no effect without it.
-
-This is useful, for example, if you have a very old disk and don\'t
-want to keep getting messages about the hours-on-lifetime Attribute
-(usually Attribute 9) failing.  This Directive may appear multiple
-times for a single device, if you want to ignore multiple Attributes.
-.TP
-.B \-I ID
-Ignore device Attribute \fBID\fP when tracking changes in the
-Attribute values.  \fBID\fP must be a decimal integer in the range
-from 1 to 255.  This Directive modifies the behavior of the \'\-p\',
-\'\-u\', and \'\-t\' tracking Directives and has no effect without one
-of them.
-
-This is useful, for example, if one of the device Attributes is the disk
-temperature (usually Attribute 194 or 231). It\'s annoying to get reports
-each time the temperature changes.  This Directive may appear multiple
-times for a single device, if you want to ignore multiple Attributes.
-.TP
-.B \-r ID
-When tracking, report the \fIRaw\fP value of Attribute \fBID\fP along
-with its (normally reported) \fINormalized\fP value.  \fBID\fP must be
-a decimal integer in the range from 1 to 255.  This Directive modifies
-the behavior of the \'\-p\', \'\-u\', and \'\-t\' tracking Directives
-and has no effect without one of them.  This Directive may be given
-multiple times.
-
-A common use of this Directive is to track the device Temperature
-(often ID=194 or 231).
-
-.TP
-.B \-R ID
-When tracking, report whenever the \fIRaw\fP value of Attribute
-\fBID\fP changes.  (Normally \fBsmartd\fP only tracks/reports changes
-of the \fINormalized\fP Attribute values.)  \fBID\fP must be a decimal
-integer in the range from 1 to 255.  This Directive modifies the
-behavior of the \'\-p\', \'\-u\', and \'\-t\' tracking Directives and
-has no effect without one of them.  This Directive may be given
-multiple times.
-
-If this Directive is given, it automatically implies the \'\-r\'
-Directive for the same Attribute, so that the Raw value of the
-Attribute is reported.
-
-A common use of this Directive is to track the device Temperature
-(often ID=194 or 231).  It is also useful for understanding how
-different types of system behavior affects the values of certain
-Attributes.
-
-.TP
-.B \-C ID
-[ATA only] Report if the current number of pending sectors is
-non-zero.  Here \fBID\fP is the id number of the Attribute whose raw
-value is the Current Pending Sector count.  The allowed range of
-\fBID\fP is 0 to 255 inclusive.  To turn off this reporting, use
-ID\ =\ 0.  If the \fB\-C ID\fP option is not given, then it defaults to
-\fB\-C 197\fP (since Attribute 197 is generally used to monitor
-pending sectors).
-
-A pending sector is a disk sector (containing 512 bytes of your data)
-which the device would like to mark as ``bad" and reallocate.
-Typically this is because your computer tried to read that sector, and
-the read failed because the data on it has been corrupted and has
-inconsistent Error Checking and Correction (ECC) codes.  This is
-important to know, because it means that there is some unreadable data
-on the disk.  The problem of figuring out what file this data belongs
-to is operating system and file system specific.  You can typically
-force the sector to reallocate by writing to it (translation: make the
-device substitute a spare good sector for the bad one) but at the
-price of losing the 512 bytes of data stored there.
-
-.TP
-.B \-U ID
-[ATA only] Report if the number of offline uncorrectable sectors is
-non-zero.  Here \fBID\fP is the id number of the Attribute whose raw
-value is the Offline Uncorrectable Sector count.  The allowed range of
-\fBID\fP is 0 to 255 inclusive.  To turn off this reporting, use
-ID\ =\ 0.  If the \fB\-U ID\fP option is not given, then it defaults to
-\fB\-U 198\fP (since Attribute 198 is generally used to monitor
-offline uncorrectable sectors).
-
-
-An offline uncorrectable sector is a disk sector which was not
-readable during an off\-line scan or a self\-test.  This is important
-to know, because if you have data stored in this disk sector, and you
-need to read it, the read will fail.  Please see the previous \'\-C\'
-option for more details.
-
-.TP
-.B \-F TYPE
-[ATA only] Modifies the behavior of \fBsmartd\fP to compensate for
-some known and understood device firmware bug.  The arguments to this
-Directive are exclusive, so that only the final Directive given is
-used.  The valid values are:
-
-.I none
-\- Assume that the device firmware obeys the ATA specifications.  This is
-the default, unless the device has presets for \'\-F\' in the device
-database.
-
-.I samsung
-\- In some Samsung disks (example: model SV4012H Firmware Version:
-RM100-08) some of the two- and four-byte quantities in the SMART data
-structures are byte-swapped (relative to the ATA specification).
-Enabling this option tells \fBsmartd\fP to evaluate these quantities
-in byte-reversed order.  Some signs that your disk needs this option
-are (1) no self-test log printed, even though you have run self-tests;
-(2) very large numbers of ATA errors reported in the ATA error log;
-(3) strange and impossible values for the ATA error log timestamps.
-
-.I samsung2
-\- In more recent Samsung disks (firmware revisions ending in "\-23") the
-number of ATA errors reported is byte swapped.  Enabling this option
-tells \fBsmartd\fP to evaluate this quantity in byte-reversed order.
-
-Note that an explicit \'\-F\' Directive will over-ride any preset
-values for \'\-F\' (see the \'\-P\' option below).
-
-
-[Please see the \fBsmartctl \-F\fP command-line option.]
-
-.TP
-.B \-v N,OPTION
-Modifies the labeling for Attribute N, for disks which use
-non-standard Attribute definitions.  This is useful in connection with
-the Attribute tracking/reporting Directives.
-
-This Directive may appear multiple times. Valid arguments to this
-Directive are:
-
-.I 9,minutes
-\- Raw Attribute number 9 is power-on time in minutes.  Its raw value
-will be displayed in the form \'Xh+Ym\'.  Here X is hours, and Y is
-minutes in the range 0-59 inclusive.  Y is always printed with two
-digits, for example \'06\' or \'31\' or \'00\'.
-
-.I 9,seconds
-\- Raw Attribute number 9 is power-on time in seconds.  Its raw value
-will be displayed in the form \'Xh+Ym+Zs\'.  Here X is hours, Y is
-minutes in the range 0-59 inclusive, and Z is seconds in the range
-0-59 inclusive.  Y and Z are always printed with two digits, for
-example \'06\' or \'31\' or \'00\'.
-
-.I 9,halfminutes
-\- Raw Attribute number 9 is power-on time, measured in units of 30
-seconds.  This format is used by some Samsung disks.  Its raw value
-will be displayed in the form \'Xh+Ym\'.  Here X is hours, and Y is
-minutes in the range 0-59 inclusive.  Y is always printed with two
-digits, for example \'06\' or \'31\' or \'00\'.
-
-.I 9,temp
-\- Raw Attribute number 9 is the disk temperature in Celsius.
-
-.I 192,emergencyretractcyclect
-\- Raw Attribute number 192 is the Emergency Retract Cycle Count.
-
-.I 193,loadunload
-\- Raw Attribute number 193 contains two values. The first is the
-number of load cycles.  The second is the number of unload cycles.
-The difference between these two values is the number of times that
-the drive was unexpectedly powered off (also called an emergency
-unload). As a rule of thumb, the mechanical stress created by one
-emergency unload is equivalent to that created by one hundred normal
-unloads.
-
-.I 194,10xCelsius
-\- Raw Attribute number 194 is ten times the disk temperature in
-Celsius.  This is used by some Samsung disks (example: model SV1204H
-with RK100-13 firmware).
-
-.I 194,unknown
-\- Raw Attribute number 194 is NOT the disk temperature, and its
-interpretation is unknown. This is primarily useful for the -P
-(presets) Directive.
-
-.I 198,offlinescanuncsectorct
-\- Raw Attribute number 198 is the Offline Scan UNC Sector Count.
-
-.I 200,writeerrorcount
-\- Raw Attribute number 200 is the Write Error Count.
-
-.I 201,detectedtacount
-\- Raw Attribute number 201 is the Detected TA Count.
-
-.I 220,temp
-\- Raw Attribute number 220 is the disk temperature in Celsius.
-
-Note: a table of hard drive models, listing which Attribute
-corresponds to temperature, can be found at:
-http://coredump.free.fr/linux/hddtemp.db
-
-.I N,raw8
-\- Print the Raw value of Attribute N as six 8-bit unsigned base-10
-integers.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw8\' prints Raw values for ALL Attributes in this
-form.  The form (for example) \'123,raw8\' only prints the Raw value for
-Attribute 123 in this form.
-
-.I N,raw16
-\- Print the Raw value of Attribute N as three 16-bit unsigned base-10
-integers.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw16\' prints Raw values for ALL Attributes in this
-form.  The form (for example) \'123,raw16\' only prints the Raw value for
-Attribute 123 in this form.
-
-.I N,raw48
-\- Print the Raw value of Attribute N as a 48-bit unsigned base-10
-integer.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw48\' prints Raw values for ALL Attributes in
-this form.  The form (for example) \'123,raw48\' only prints the Raw
-value for Attribute 123 in this form.
-
-.TP
-.B \-P TYPE
-Specifies whether
-\fBsmartd\fP
-should use any preset options that are available for this drive.  The
-valid arguments to this Directive are:
-
-.I use
-\- use any presets that are available for this drive.  This is the default.
-
-.I ignore
-\- do not use any presets for this drive.
-
-.I show
-\- show the presets listed for this drive in the database.
-
-.I showall
-\- show the presets that are available for all drives and then exit.
-
-[Please see the
-.B smartctl \-P
-command-line option.]
-
-.TP
-.B \-a
-Equivalent to turning on all of the following Directives: 
-.B \'\-H\' 
-to check the SMART health status,
-.B \'\-f\' 
-to report failures of Usage (rather than Prefail) Attributes,
-.B \'\-t\' 
-to track changes in both Prefailure and Usage Attributes,
-.B \'\-l\ selftest\' 
-to report increases in the number of Self-Test Log errors,
-.B \'\-l\ error\' 
-to report increases in the number of ATA errors,
-.B \'\-C 197\'
-to report nonzero values of the current pending sector count, and
-.B \'\-U 198\'
-to report nonzero values of the offline pending sector count.
-
-Note that \-a is the default for ATA devices.  If none of these other
-Directives is given, then \-a is assumed.
-
-.TP
-.B #
-Comment: ignore the remainder of the line.
-.TP
-.B \e
-Continuation character: if this is the last non-white or non-comment
-character on a line, then the following line is a continuation of the current
-one.
-.PP
-If you are not sure which Directives to use, I suggest experimenting
-for a few minutes with
-.B smartctl
-to see what SMART functionality your disk(s) support(s).  If you do
-not like voluminous syslog messages, a good choice of
-\fBsmartd\fP
-configuration file Directives might be:
-.nf
-.B \-H \-l\ selftest \-l\ error \-f.
-.fi
-If you want more frequent information, use:
-.B -a.
-
-.TP
-.B ADDITIONAL DETAILS ABOUT DEVICESCAN
-If the first non-comment entry in the configuration file is the text
-string \fBDEVICESCAN\fP in capital letters, then \fBsmartd\fP will
-ignore any remaining lines in the configuration file, and will scan
-for devices.
-
-If \fBDEVICESCAN\fP is not followed by any Directives, then smartd
-will scan for both ATA and SCSI devices, and will monitor all possible
-SMART properties of any devices that are found.
-
-\fBDEVICESCAN\fP may optionally be followed by any valid Directives,
-which will be applied to all devices that are found in the scan.  For
-example
-.nf
-.B DEVICESCAN -m root@example.com
-.fi
-will scan for all devices, and then monitor them.  It will send one
-email warning per device for any problems that are found.
-.nf
-.B  DEVICESCAN -d ata -m root@example.com
-.fi
-will do the same, but restricts the scan to ATA devices only.  
-.nf
-.B  DEVICESCAN -H -d ata -m root@example.com
-.fi
-will do the same, but only monitors the SMART health status of the
-devices, (rather than the default \-a, which monitors all SMART
-properties).
-
-.TP
-.B EXAMPLES OF SHELL SCRIPTS FOR \'\-M exec\'
-These are two examples of shell scripts that can be used with the \'\-M
-exec PATH\' Directive described previously.  The paths to these scripts
-and similar executables is the PATH argument to the \'\-M exec PATH\'
-Directive.
-
-Example 1: This script is for use with \'\-m ADDRESS -M exec PATH\'.  It appends
-the output of
-.B smartctl -a
-to the output of the smartd email warning message and sends it to ADDRESS.
-
-.nf
-\fB
-#! /bin/bash
-
-# Save the email message (STDIN) to a file:
-cat > /root/msg
-
-# Append the output of smartctl -a to the message:
-/usr/sbin/smartctl -a -d $SMART_DEVICETYPE $SMARTD_DEVICE >> /root/msg
- 
-# Now email the message to the user at address ADD:
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
-\fP
-.fi
-
-Example 2: This script is for use with \'\-m <nomailer> \-M exec
-PATH\'. It warns all users about a disk problem, waits 30 seconds, and
-then powers down the machine.
-
-.nf
-\fB
-#! /bin/bash
-
-# Warn all users of a problem
-wall \'Problem detected with disk: \' "$SMARTD_DEVICESTRING"
-wall \'Warning message from smartd is: \' "$SMARTD_MESSAGE"
-wall \'Shutting down machine in 30 seconds... \'
- 
-# Wait half a minute
-sleep 30
- 
-# Power down the machine
-/sbin/shutdown -hf now
-\fP
-.fi
-
-Some example scripts are distributed with the smartmontools package,
-in /usr/share/doc/smartmontools-5.1/examplescripts/.
-
-Please note that these scripts typically run as root, so any files
-that they read/write should not be writable by ordinary users or
-reside in directories like /tmp that are writable by ordinary users
-and may expose your system to symlink attacks.
-
-As previously described, if the scripts write to STDOUT or STDERR,
-this is interpreted as indicating that there was an internal error
-within the script, and a snippet of STDOUT/STDERR is logged to SYSLOG.
-The remainder is flushed.
-
-.\" ENDINCLUDE
-.\" DO NOT MODIFY THIS OR PREVIOUS/NEXT LINES. THIS DEFINES THE 
-.\" END OF THE INCLUDE SECTION FOR smartd.conf.5
-
-.SH NOTES
-\fBsmartd\fP
-will make log entries at loglevel 
-.B LOG_INFO
-if the Normalized SMART Attribute values have changed, as reported using the
-.B \'\-t\', \'\-p\',
-or
-.B \'\-u\'
-Directives. For example:
-.nf
-.B \'Device: /dev/hda, SMART Attribute: 194 Temperature_Celsius changed from 94 to 93\'
-.fi
-Note that in this message, the value given is the \'Normalized\' not the \'Raw\' 
-Attribute value (the disk temperature in this case is about 22
-Celsius).  The 
-.B \'-R\'
-and 
-.B \'-r\'
-Directives modify this behavior, so that the information is printed
-with the Raw values as well, for example:
-.nf
-.B \'Device: /dev/hda, SMART Attribute: 194 Temperature_Celsius changed from 94 [Raw 22] to 93 [Raw 23]\'
-.fi
-Here the Raw values are the actual disk temperatures in Celsius.  The
-way in which the Raw values are printed, and the names under which the
-Attributes are reported, is governed by the various
-.B \'-v Num,Description\'
-Directives described previously.
-
-Please see the
-.B smartctl
-manual page for further explanation of the differences between
-Normalized and Raw Attribute values.
-
-\fBsmartd\fP
-will make log entries at loglevel
-.B LOG_CRIT
-if a SMART Attribute has failed, for example:
-.nf
-.B \'Device: /dev/hdc, Failed SMART Attribute: 5 Reallocated_Sector_Ct\'
-.fi
- This loglevel is used for reporting enabled by the
-.B \'\-H\', \-f\', \'\-l\ selftest\',
-and
-.B \'\-l\ error\'
-Directives. Entries reporting failure of SMART Prefailure Attributes
-should not be ignored: they mean that the disk is failing.  Use the
-.B smartctl
-utility to investigate. 
-
-Under Solaris with the default \fB/etc/syslog.conf\fP configuration,
-messages below loglevel \fBLOG_NOTICE\fP will \fBnot\fP be recorded.
-Hence all \fBsmartd\fP messages with loglevel \fBLOG_INFO\fP will be
-lost.  If you want to use the existing daemon facility to log all
-messages from \fBsmartd\fP, you should change \fB/etc/syslog.conf\fP
-from:
-.nf
-       ...;daemon.notice;...        /var/adm/messages
-.fi
-to read:
-.nf
-       ...;daemon.info;...          /var/adm/messages
-.fi
-Alternatively, you can use a local facility to log messages: please
-see the \fBsmartd\fP '-l' command-line option described above.
-
-On Cygwin and Windows, the log messages are written to the event log
-or to a file. See documentation of the '-l FACILITY' option above for
-details.
-
-On Windows, the following built-in commands can be used to control
-\fBsmartd\fP, if running as a daemon:
-
-\'\fBsmartd status\fP\' \- check status
-
-\'\fBsmartd stop\fP\' \- stop smartd
-
-\'\fBsmartd reload\fP\' \- reread config file
-
-\'\fBsmartd restart\fP\' \- restart smartd
-
-\'\fBsmartd sigusr1\fP\' \- check disks now
-
-\'\fBsmartd sigusr2\fP\' \- toggle debug mode
-
-On WinNT4/2000/XP, \fBsmartd\fP can also be run as a Windows service:
-
-\'\fBsmartd install [options]\fP\' installs a service
-named "smartd" (display name "SmartD Service") using the command line
-\'/installpath/smartd.exe --service [options]\'.
-
-\'\fBsmartd remove\fP\' can later be used to remove the service entry
-from registry.
-
-Upon startup, the smartd service changes the working directory
-to its own installation path. If smartd.conf and blat.exe are stored
-in this directory, no \'-c\' option and \'-M exec\' directive is needed.
-
-The debug mode (\'-d\', \'-q onecheck\') does not work if smartd is
-running as service.
-
-The service can be controlled as usual with Windows commands \'net\'
-or \'sc\' (\'\fBnet start smartd\fP\', \'\fBnet stop smartd\fP\').
-
-Pausing the service (\'\fBnet pause smartd\fP\') sets the interval between
-disk checks (\'-i N\') to infinite.
-
-Continuing the paused service (\'\fBnet continue smartd\fP\') resets the
-interval and rereads the configuration file immediately (like \fBSIGHUP\fP):
-
-Continuing a still running service (\'\fBnet continue smartd\fP\' without
-preceding \'\fBnet pause smartd\fP\') does not reread configuration but
-checks disks immediately (like \fBSIGUSR1\fP).
-
-.SH LOG TIMESTAMP TIMEZONE
-
-When \fBsmartd\fP makes log entries, these are time-stamped.  The time
-stamps are in the computer's local time zone, which is generally set
-using either the environment variable \'\fBTZ\fP\' or using a
-time-zone file such as \fB/etc/localtime\fP.  You may wish to change
-the timezone while \fBsmartd\fP is running (for example, if you carry
-a laptop to a new time-zone and don't reboot it).  Due to a bug in the
-\fBtzset(3)\fP function of many unix standard C libraries, the
-time-zone stamps of \fBsmartd\fP might not change.  For some systems,
-\fBsmartd\fP will work around this problem \fIif\fP the time-zone is
-set using \fB/etc/localtime\fP. The work-around \fIfails\fP if the
-time-zone is set using the \'\fBTZ\fP\' variable (or a file that it
-points to).
-
-
-.SH RETURN VALUES
-The return value (exit status) of 
-\fBsmartd\fP
-can have the following values:
-.TP
-.B 0:
-Daemon startup successful, or \fBsmartd\fP was killed by a SIGTERM (or in debug mode, a SIGQUIT).
-.TP
-.B 1:
-Commandline did not parse.
-.TP
-.B 2:
-There was a syntax error in the config file.
-.TP
-.B 3:
-Forking the daemon failed.
-.TP
-.B 4:
-Couldn\'t create PID file.
-.TP
-.B 5:
-Config file does not exist (only returned in conjunction with the \'-c\' option).
-.TP
-.B 6:
-Config file exists, but cannot be read.
-.TP
-.B 8:
-\fBsmartd\fP
-ran out of memory during startup.
-.TP
-.B 9:
-A compile time constant of\fB smartd\fP was too small.  This can be caused by an
-excessive number of disks, or by lines in \fB /etc/smartd.conf\fP that are too long.
-Please report this problem to \fB smartmontools-support@lists.sourceforge.net\fP.
-.TP
-.B 10
-An inconsistency was found in \fBsmartd\fP\'s internal data
-structures. This should never happen.  It must be due to either a
-coding or compiler bug.  \fIPlease\fP report such failures to
-smartmontools-support@lists.sourceforge.net.
-.TP
-.B 16:
-A device explicitly listed in
-.B /etc/smartd.conf
-can\'t be monitored.
-.TP
-.B 17:
-\fBsmartd\fP
-didn\'t find any devices to monitor.
-.TP
-.B 254:
-When in daemon mode,
-\fBsmartd\fP
-received a SIGINT or SIGQUIT.  (Note that in debug mode, SIGINT has
-the same effect as SIGHUP, and makes \fBsmartd\fP reload its
-configuration file. SIGQUIT has the same effect as SIGTERM and causes
-\fBsmartd\fP to exit with zero exit status.
-.TP
-.B 132 and above
-\fBsmartd\fP
-was killed by a signal that is not explicitly listed above.  The exit
-status is then 128 plus the signal number.  For example if
-\fBsmartd\fP
-is killed by SIGKILL (signal 9) then the exit status is 137.
-
-.PP
-.SH AUTHOR
-\fBBruce Allen\fP smartmontools-support@lists.sourceforge.net
-.fi
-University of Wisconsin \- Milwaukee Physics Department
-
-.PP
-.SH CONTRIBUTORS
-The following have made large contributions to smartmontools:
-.nf
-\fBCasper Dik\fP (Solaris SCSI interface)
-\fBChristian Franke\fP (Windows interface)
-\fBDouglas Gilbert\fP (SCSI subsystem)
-\fBGuido Guenther\fP (Autoconf/Automake packaging)
-\fBGeoffrey Keating\fP (Darwin ATA interface)
-\fBEduard Martinescu\fP (FreeBSD interface)
-\fBFr\*'ed\*'eric L. W. Meunier\fP (Web site and Mailing list)
-\fBKeiji Sawada\fP (Solaris ATA interface)
-\fBSergey Svishchev\fP (NetBSD interface)
-\fBPhil Williams\fP (User interface and drive database)
-.fi
-Many other individuals have made smaller contributions and corrections.
-
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous ucsc smartsuite package. It extends
-these to cover ATA-5 disks. This code was originally developed as a
-Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
-(now part of the Storage Systems Research Center), Jack Baskin School
-of Engineering, University of California, Santa
-Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
-.SH
-HOME PAGE FOR SMARTMONTOOLS: 
-.fi
-Please see the following web site for updates, further documentation, bug
-reports and patches:
-.nf
-.B
-http://smartmontools.sourceforge.net/
-
-.SH SEE ALSO:
-\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
-\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
-
-.SH
-REFERENCES FOR SMART
-.fi
-An introductory article about smartmontools is \fIMonitoring Hard
-Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
-pages 74-77. This is http://www.linuxjournal.com/article.php?sid=6983
-online.
-
-If you would like to understand better how SMART works, and what
-it does, a good place to start is  Section 8.41 of the \'AT
-Attachment with Packet Interface-5\' (ATA/ATAPI-5) specification.  This
-documents the SMART functionality which the smartmontools
-utilities provide access to.  You can find Revision 1 of this document
-at \fBhttp://www.t13.org/project/d1321r1c.pdf\fP .
-
-.fi
-Future versions of the specifications (ATA/ATAPI-6 and ATA/ATAPI-7),
-and later revisions (2, 3) of the ATA/ATAPI-5 specification are
-available from \fBhttp://www.t13.org/#FTP_site\fP .
-
-.fi
-The functioning of SMART was originally defined by the SFF-8035i
-revision 2 and the SFF-8055i revision 1.4 specifications.  These are
-publications of the Small Form Factors (SFF) Committee.  Links to
-these documents may be found in the References section of the
-smartmontools home page at \fBhttp://smartmontools.sourceforge.net/\fP .
-
-.SH
-CVS ID OF THIS PAGE:
-$Id: smartd.8.in,v 1.78 2004/08/06 19:48:42 chrfranke Exp $
diff --git a/sm5/smartd.c b/sm5/smartd.c
deleted file mode 100644
index 1953213500f87f619f455d630b4a7de1e8433537..0000000000000000000000000000000000000000
--- a/sm5/smartd.c
+++ /dev/null
@@ -1,3940 +0,0 @@
-/*
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-// unconditionally included files
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>   // umask
-#ifndef _WIN32
-#include <sys/wait.h>
-#include <unistd.h>
-#endif
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <limits.h>
-
-#if SCSITIMEOUT
-#include <setjmp.h>
-#endif
-
-// see which system files to conditionally include
-#include "config.h"
-
-// conditionally included files
-#ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef _WIN32
-#ifdef _MSC_VER
-#pragma warning(disable:4761) // "conversion supplied"
-typedef unsigned short mode_t;
-typedef int pid_t;
-#endif
-#include <io.h> // umask()
-#include <process.h> // getpid()
-#endif // _WIN32
-
-// locally included files
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "int64.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "smartd.h"
-#include "utility.h"
-
-#ifdef _WIN32
-#include "hostname_win32.h" // gethost/domainname()
-#define HAVE_GETHOSTNAME   1
-#define HAVE_GETDOMAINNAME 1
-// fork()/signal()/initd simulation for native Windows
-#include "daemon_win32.h" // daemon_main/detach/signal()
-#undef SIGNALFN
-#define SIGNALFN  daemon_signal
-#define strsignal daemon_strsignal
-#define sleep     daemon_sleep
-#undef EXIT // see utility.h
-#define EXIT(x)  { exitstatus = daemon_winsvc_exitcode = (x); exit((x)); }
-// SIGQUIT does not exits, CONTROL-Break signals SIGBREAK.
-#define SIGQUIT SIGBREAK
-#define SIGQUIT_KEYNAME "CONTROL-Break"
-#else  // _WIN32
-#ifdef __CYGWIN__
-// 2x CONTROL-C simulates missing SIGQUIT via keyboard
-#define SIGQUIT_KEYNAME "2x CONTROL-C"
-#else // __CYGWIN__
-#define SIGQUIT_KEYNAME "CONTROL-\\"
-#endif // __CYGWIN__
-#endif // _WIN32
-
-#if defined (__SVR4) && defined (__sun)
-int getdomainname(char *, int); /* no declaration in header files! */
-#endif
-
-#define ARGUSED(x) ((void)(x))
-
-// These are CVS identification information for *.c and *.h files
-extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, 
-                  *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
-
-static const char *filenameandversion="$Id: smartd.c,v 1.333 2004/08/16 22:44:27 ballen4705 Exp $";
-#ifdef NEED_SOLARIS_ATA_CODE
-extern const char *os_solaris_ata_s_cvsid;
-#endif
-#ifdef _WIN32
-extern const char *daemon_win32_c_cvsid, *hostname_win32_c_cvsid, *syslog_win32_c_cvsid;
-#ifdef _MSC_VER
-extern const char *int64_vc6_c_cvsid;
-#endif
-#endif
-const char *smartd_c_cvsid="$Id: smartd.c,v 1.333 2004/08/16 22:44:27 ballen4705 Exp $" 
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID
-#ifdef DAEMON_WIN32_H_CVSID
-DAEMON_WIN32_H_CVSID
-#endif
-EXTERN_H_CVSID INT64_H_CVSID
-#ifdef HOSTNAME_WIN32_H_CVSID
-HOSTNAME_WIN32_H_CVSID
-#endif
-KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID
-#ifdef SYSLOG_H_CVSID
-SYSLOG_H_CVSID
-#endif
-UTILITY_H_CVSID;
-
-extern const char *reportbug;
-
-// GNU copyleft statement.  Needed for GPL purposes.
-const char *copyleftstring="smartd comes with ABSOLUTELY NO WARRANTY. This is\n"
-                           "free software, and you are welcome to redistribute it\n"
-                           "under the terms of the GNU General Public License\n"
-                           "Version 2. See http://www.gnu.org for further details.\n\n";
-
-extern unsigned char debugmode;
-
-// command-line: how long to sleep between checks
-static int checktime=CHECKTIME;
-
-// command-line: name of PID file (NULL for no pid file)
-static char* pid_file=NULL;
-
-// configuration file name
-#ifndef _WIN32
-static char* configfile = SMARTMONTOOLS_SYSCONFDIR "/" CONFIGFILENAME ;
-#else
-static char* configfile = "./" CONFIGFILENAME ;
-#endif
-// configuration file "name" if read from stdin
-static /*const*/ char * const configfile_stdin = "<stdin>";
-// allocated memory for alternate configuration file name
-static char* configfile_alt = NULL;
-
-// command-line: when should we exit?
-static int quit=0;
-
-// command-line; this is the default syslog(3) log facility to use.
-static int facility=LOG_DAEMON;
-
-// used for control of printing, passing arguments to atacmds.c
-smartmonctrl *con=NULL;
-
-// pointers to (real or simulated) entries in configuration file, and
-// maximum space currently allocated for these entries.
-cfgfile **cfgentries=NULL;
-int cfgentries_max=0;
-
-// pointers to ATA and SCSI devices being monitored, maximum and
-// actual numbers
-cfgfile **atadevlist=NULL, **scsidevlist=NULL;
-int atadevlist_max=0, scsidevlist_max=0;
-int numdevata=0, numdevscsi=0;
-
-// track memory usage
-extern int64_t bytes;
-
-// exit status
-extern int exitstatus;
-
-// set to one if we catch a USR1 (check devices now)
-volatile int caughtsigUSR1=0;
-
-#ifdef _WIN32
-// set to one if we catch a USR2 (toggle debug mode)
-volatile int caughtsigUSR2=0;
-#endif
-
-// set to one if we catch a HUP (reload config file). In debug mode,
-// set to two, if we catch INT (also reload config file).
-volatile int caughtsigHUP=0;
-
-// set to signal value if we catch INT, QUIT, or TERM
-volatile int caughtsigEXIT=0;
-
-#if SCSITIMEOUT
-// stack environment if we time out during SCSI access (USB devices)
-jmp_buf registerscsienv;
-#endif
-
-// tranlate cfg->pending into the correct Attribute numbers
-void TranslatePending(unsigned short pending, unsigned char *current, unsigned char *offline) {
-
-  unsigned char curr = CURR_PEND(pending);
-  unsigned char off =  OFF_PEND(pending);
-
-  // look for special value of CUR_UNC_DEFAULT that means DONT
-  // monitor. 0 means DO test.
-  if (curr==CUR_UNC_DEFAULT)
-    curr=0;
-  else if (curr==0)
-    curr=CUR_UNC_DEFAULT;
-	
-  // look for special value of OFF_UNC_DEFAULT that means DONT
-  // monitor.  0 means DO TEST.
-  if (off==OFF_UNC_DEFAULT)
-    off=0;
-  else if (off==0)
-    off=OFF_UNC_DEFAULT;
-
-  *current=curr;
-  *offline=off;
-
-  return;
-}
-
-
-// free all memory associated with selftest part of configfile entry.  Return NULL
-testinfo* FreeTestData(testinfo *data){
-  
-  // make sure we have something to do.
-  if (!data)
-    return NULL;
-  
-  // free space for text pattern
-  data->regex=FreeNonZero(data->regex, -1, __LINE__, filenameandversion);
-  
-  // free compiled expression
-  regfree(&(data->cregex));
-
-  // make sure that no sign of the compiled expression is left behind
-  // (just in case, to help detect bugs if we ever try and refer to
-  // that again).
-  memset(&(data->cregex), '0', sizeof(regex_t));
-
-  // free remaining memory space
-  data=FreeNonZero(data, sizeof(testinfo), __LINE__, filenameandversion);
-
-  return NULL;
-}
-
-cfgfile **AllocateMoreSpace(cfgfile **oldarray, int *oldsize, char *listname){
-  // for now keep BLOCKSIZE small to help detect coding problems.
-  // Perhaps increase in the future.
-  const int BLOCKSIZE=8;
-  int i;
-  int old = *oldsize;
-  int new = old + BLOCKSIZE;
-  cfgfile **newptr=realloc(oldarray, new*sizeof(cfgfile *));
-  
-  // did we get more space?
-  if (newptr) {
-
-    // clear remaining entries ala calloc()
-    for (i=old; i<new; i++)
-      newptr[i]=NULL;
-    
-    bytes += BLOCKSIZE*sizeof(cfgfile *);
-    
-    *oldsize=new;
-    
-#if 0
-    PrintOut(LOG_INFO, "allocating %d slots for %s\n", BLOCKSIZE, listname);
-#endif
-
-    return newptr;
-  }
-  
-  PrintOut(LOG_CRIT, "out of memory for allocating %s list\n", listname);
-  EXIT(EXIT_NOMEM);
-}
-
-void PrintOneCVS(const char *a_cvs_id){
-  char out[CVSMAXLEN];
-  printone(out,a_cvs_id);
-  PrintOut(LOG_INFO,"%s",out);
-  return;
-}
-
-// prints CVS identity information for the executable
-void PrintCVS(void){
-  char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
-
-  PrintOut(LOG_INFO,(char *)copyleftstring);
-  PrintOut(LOG_INFO,"CVS version IDs of files used to build this code are:\n");
-  PrintOneCVS(atacmdnames_c_cvsid);
-  PrintOneCVS(atacmds_c_cvsid);
-  PrintOneCVS(ataprint_c_cvsid);
-#ifdef _WIN32
-  PrintOneCVS(daemon_win32_c_cvsid);
-#endif
-#if defined(_WIN32) && defined(_MSC_VER)
-  PrintOneCVS(int64_vc6_c_cvsid);
-#endif
-#ifdef _WIN32
-  PrintOneCVS(hostname_win32_c_cvsid);
-#endif
-  PrintOneCVS(knowndrives_c_cvsid);
-  PrintOneCVS(os_XXXX_c_cvsid);
-#ifdef NEED_SOLARIS_ATA_CODE
-  PrintOneCVS( os_solaris_ata_s_cvsid);
-#endif
-  PrintOneCVS(scsicmds_c_cvsid);
-  PrintOneCVS(smartd_c_cvsid);
-#ifdef _WIN32
-  PrintOneCVS(syslog_win32_c_cvsid);
-#endif
-  PrintOneCVS(utility_c_cvsid);
-  PrintOut(LOG_INFO, "\nsmartmontools release " PACKAGE_VERSION " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n");
-  PrintOut(LOG_INFO, "smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n");
-  PrintOut(LOG_INFO, "smartmontools build configured: " SMARTMONTOOLS_CONFIGURE_DATE "\n");
-  PrintOut(LOG_INFO, "smartd compile dated " __DATE__ " at "__TIME__ "\n");
-  PrintOut(LOG_INFO, "smartmontools configure arguments: %s\n", configargs);
-  return;
-}
-
-// Removes config file entry, freeing all memory
-void RmConfigEntry(cfgfile **anentry, int whatline){
-  
-  cfgfile *cfg;
-
-  // pointer should never be null!
-  if (!anentry){
-    PrintOut(LOG_CRIT,"Internal error in RmConfigEntry() at line %d of file %s\n%s",
-             whatline, filenameandversion, reportbug);    
-    EXIT(EXIT_BADCODE);
-  }
-  
-  // only remove entries that exist!
-  if (!(cfg=*anentry))
-    return;
-
-  // entry exists -- free all of its memory  
-  cfg->name            = FreeNonZero(cfg->name,           -1,__LINE__,filenameandversion);
-  cfg->smartthres      = FreeNonZero(cfg->smartthres,      sizeof(struct ata_smart_thresholds_pvt),__LINE__,filenameandversion);
-  cfg->smartval        = FreeNonZero(cfg->smartval,        sizeof(struct ata_smart_values),__LINE__,filenameandversion);
-  cfg->monitorattflags = FreeNonZero(cfg->monitorattflags, NMONITOR*32,__LINE__,filenameandversion);
-  cfg->attributedefs   = FreeNonZero(cfg->attributedefs,   MAX_ATTRIBUTE_NUM,__LINE__,filenameandversion);
-  if (cfg->mailwarn){
-    cfg->mailwarn->address         = FreeNonZero(cfg->mailwarn->address,        -1,__LINE__,filenameandversion);
-    cfg->mailwarn->emailcmdline    = FreeNonZero(cfg->mailwarn->emailcmdline,   -1,__LINE__,filenameandversion);
-    cfg->mailwarn                  = FreeNonZero(cfg->mailwarn,   sizeof(maildata),__LINE__,filenameandversion);
-  }
-  cfg->testdata        = FreeTestData(cfg->testdata);
-  *anentry             = FreeNonZero(cfg,                  sizeof(cfgfile),__LINE__,filenameandversion);
-
-  return;
-}
-
-// deallocates all memory associated with cfgentries list
-void RmAllConfigEntries(){
-  int i;
-
-  for (i=0; i<cfgentries_max; i++)
-    RmConfigEntry(cfgentries+i, __LINE__);
-
-  cfgentries=FreeNonZero(cfgentries, sizeof(cfgfile *)*cfgentries_max, __LINE__, filenameandversion);
-  cfgentries_max=0;
-
-  return;
-}
-
-// deallocates all memory associated with ATA/SCSI device lists
-void RmAllDevEntries(){
-  int i;
-  
-  for (i=0; i<atadevlist_max; i++)
-    RmConfigEntry(atadevlist+i, __LINE__);
-
-  atadevlist=FreeNonZero(atadevlist, sizeof(cfgfile *)*atadevlist_max, __LINE__, filenameandversion);
-  atadevlist_max=0;
-
-  for (i=0; i<scsidevlist_max; i++)
-    RmConfigEntry(scsidevlist+i, __LINE__);
-  
-  scsidevlist=FreeNonZero(scsidevlist, sizeof(cfgfile *)*scsidevlist_max, __LINE__, filenameandversion);
-  scsidevlist_max=0;
-
-  return;
-}
-
-// remove the PID file
-void RemovePidFile(){
-  if (pid_file) {
-    if ( -1==unlink(pid_file) )
-      PrintOut(LOG_CRIT,"Can't unlink PID file %s (%s).\n", 
-               pid_file, strerror(errno));
-    pid_file=FreeNonZero(pid_file, -1,__LINE__,filenameandversion);
-  }
-  return;
-}
-
-
-//  Note if we catch a SIGUSR1
-void USR1handler(int sig){
-  if (SIGUSR1==sig)
-    caughtsigUSR1=1;
-  return;
-}
-
-#ifdef _WIN32
-//  Note if we catch a SIGUSR2
-void USR2handler(int sig){
-  if (SIGUSR2==sig)
-    caughtsigUSR2=1;
-  return;
-}
-#endif
-
-// Note if we catch a HUP (or INT in debug mode)
-void HUPhandler(int sig){
-  if (sig==SIGHUP)
-    caughtsigHUP=1;
-  else
-    caughtsigHUP=2;
-  return;
-}
-
-// signal handler for TERM, QUIT, and INT (if not in debug mode)
-void sighandler(int sig){
-  if (!caughtsigEXIT)
-    caughtsigEXIT=sig;
-  return;
-}
-
-
-// signal handler that prints Goodbye message and removes pidfile
-void Goodbye(void){
-  
-  // clean up memory -- useful for debugging
-  RmAllConfigEntries();
-  RmAllDevEntries();
-
-  // delete PID file, if one was created
-  RemovePidFile();
-
-  // remove alternate configfile name
-  configfile_alt=FreeNonZero(configfile_alt, -1,__LINE__,filenameandversion);
-
-  // useful for debugging -- have we managed memory correctly?
-  if (debugmode || (bytes && exitstatus!=EXIT_NOMEM))
-    PrintOut(LOG_INFO, "Memory still allocated for devices at exit is %" PRId64 " bytes.\n", bytes);
-
-  // if we are exiting because of a code bug, tell user
-  if (exitstatus==EXIT_BADCODE || (bytes && exitstatus!=EXIT_NOMEM))
-        PrintOut(LOG_CRIT, "Please inform " PACKAGE_BUGREPORT ", including output of smartd -V.\n");
-
-  if (exitstatus==0 && bytes)
-    exitstatus=EXIT_BADCODE;
-
-  // and this should be the final output from smartd before it exits
-  PrintOut(exitstatus?LOG_CRIT:LOG_INFO, "smartd is exiting (exit status %d)\n", exitstatus);
-
-  return;
-}
-
-#define ENVLENGTH 512
-
-// a replacement for setenv() which is not available on all platforms.
-// Note that the string passed to putenv must not be freed or made
-// invalid, since a pointer to it is kept by putenv(). This means that
-// it must either be a static buffer or allocated off the heap. The
-// string can be freed if the environment variable is redefined or
-// deleted via another call to putenv(). So we keep these on the stack
-// as long as the popen() call is underway.
-int exportenv(char* stackspace, const char *name, const char *value){
-  snprintf(stackspace,ENVLENGTH, "%s=%s", name, value);
-  return putenv(stackspace);
-}
-
-char* dnsdomain(const char* hostname) {
-  char *p = NULL;
-#ifdef HAVE_GETHOSTBYNAME
-  struct hostent *hp;
-  
-  if ((hp = gethostbyname(hostname))) {
-    // Does this work if gethostbyname() returns an IPv6 name in
-    // colon/dot notation?  [BA]
-    if ((p = strchr(hp->h_name, '.')))
-      p++; // skip "."
-  }
-#else
-  ARGUSED(hostname);
-#endif
-  return p;
-}
-
-#define EBUFLEN 1024
-
-// If either address or executable path is non-null then send and log
-// a warning email, or execute executable
-void MailWarning(cfgfile *cfg, int which, char *fmt, ...){
-  char command[2048], message[256], hostname[256], domainname[256], additional[256];
-  char original[256], further[256], nisdomain[256], subject[256],dates[DATEANDEPOCHLEN];
-  char environ_strings[10][ENVLENGTH];
-  time_t epoch;
-  va_list ap;
-  const int day=24*3600;
-  int days=0;
-  char *whichfail[]={
-    "EmailTest",                  // 0
-    "Health",                     // 1
-    "Usage",                      // 2
-    "SelfTest",                   // 3
-    "ErrorCount",                 // 4
-    "FailedHealthCheck",          // 5
-    "FailedReadSmartData",        // 6
-    "FailedReadSmartErrorLog",    // 7
-    "FailedReadSmartSelfTestLog", // 8
-    "FailedOpenDevice",           // 9
-    "CurrentPendingSector",       // 10
-    "OfflineUncorrectableSector" //  11
-  };
-  
-  char *address, *executable;
-  mailinfo *mail;
-  maildata* data=cfg->mailwarn;
-#ifndef _WIN32
-  FILE *pfp=NULL;
-#else
-  char stdinbuf[1024]; int boxmsgoffs, boxtype;
-#endif
-  char *newadd=NULL, *newwarn=NULL;
-  const char *unknown="[Unknown]";
-
-  // See if user wants us to send mail
-  if (!data)
-    return;
-  
-  address=data->address;
-  executable=data->emailcmdline;
-  
-  if (!address && !executable)
-    return;
-  
-  // which type of mail are we sending?
-  mail=(data->maillog)+which;
-  
-  // checks for sanity
-  if (data->emailfreq<1 || data->emailfreq>3) {
-    PrintOut(LOG_CRIT,"internal error in MailWarning(): cfg->mailwarn->emailfreq=%d\n",data->emailfreq);
-    return;
-  }
-  if (which<0 || which>=SMARTD_NMAIL || sizeof(whichfail)!=SMARTD_NMAIL*sizeof(char *)) {
-    PrintOut(LOG_CRIT,"Contact " PACKAGE_BUGREPORT "; internal error in MailWarning(): which=%d, size=%d\n",
-             which, (int)sizeof(whichfail));
-    return;
-  }
-  
-  // Return if a single warning mail has been sent.
-  if ((data->emailfreq==1) && mail->logged)
-    return;
-
-  // Return if this is an email test and one has already been sent.
-  if (which == 0 && mail->logged)
-    return;
-  
-  // To decide if to send mail, we need to know what time it is.
-  epoch=time(NULL);
-
-  // Return if less than one day has gone by
-  if (data->emailfreq==2 && mail->logged && epoch<(mail->lastsent+day))
-    return;
-
-  // Return if less than 2^(logged-1) days have gone by
-  if (data->emailfreq==3 && mail->logged){
-    days=0x01<<(mail->logged-1);
-    days*=day;
-    if  (epoch<(mail->lastsent+days))
-      return;
-  }
-
-  // record the time of this mail message, and the first mail message
-  if (!mail->logged)
-    mail->firstsent=epoch;
-  mail->lastsent=epoch;
-  
-  // get system host & domain names (not null terminated if length=MAX) 
-#ifdef HAVE_GETHOSTNAME
-  if (gethostname(hostname, 256))
-    strcpy(hostname, unknown);
-  else {
-    char *p=NULL;
-    hostname[255]='\0';
-    p = dnsdomain(hostname);
-    if (p && *p) {
-      strncpy(domainname, p, 255);
-      domainname[255]='\0';
-    } else
-      strcpy(domainname, unknown);
-  }
-#else
-  strcpy(hostname, unknown);
-  strcpy(domainname, unknown);
-#endif
-  
-#ifdef HAVE_GETDOMAINNAME
-  if (getdomainname(nisdomain, 256))
-    strcpy(nisdomain, unknown);
-  else
-    nisdomain[255]='\0';
-#else
-  strcpy(nisdomain, unknown);
-#endif
-  
-  // print warning string into message
-  va_start(ap, fmt);
-  vsnprintf(message, 256, fmt, ap);
-  va_end(ap);
-
-  // appropriate message about further information
-  additional[0]=original[0]=further[0]='\0';
-  if (which) {
-    sprintf(further,"You can also use the smartctl utility for further investigation.\n");
-
-    switch (data->emailfreq){
-    case 1:
-      sprintf(additional,"No additional email messages about this problem will be sent.\n");
-      break;
-    case 2:
-      sprintf(additional,"Another email message will be sent in 24 hours if the problem persists.\n");
-      break;
-    case 3:
-      sprintf(additional,"Another email message will be sent in %d days if the problem persists\n",
-              (0x01)<<mail->logged);
-      break;
-    }
-    if (data->emailfreq>1 && mail->logged){
-      dateandtimezoneepoch(dates, mail->firstsent);
-      sprintf(original,"The original email about this issue was sent at %s\n", dates);
-    }
-  }
-  
-  snprintf(subject, 256,"SMART error (%s) detected on host: %s", whichfail[which], hostname);
-
-  // If the user has set cfg->emailcmdline, use that as mailer, else "mail" or "mailx".
-  if (!executable)
-#ifdef DEFAULT_MAILER
-    executable = DEFAULT_MAILER ;
-#else
-#ifndef _WIN32
-    executable = "mail";
-#else
-    executable = "blat"; // http://blat.sourceforge.net/
-#endif
-#endif
-
-  // make a private copy of address with commas replaced by spaces
-  // to separate recipients
-  if (address) {
-    address=CustomStrDup(data->address, 1, __LINE__, filenameandversion);
-#ifndef _WIN32 // blat mailer needs comma
-    char *comma=address;
-    while ((comma=strchr(comma, ',')))
-      *comma=' ';
-#endif
-  }
-
-  // Export information in environment variables that will be useful
-  // for user scripts
-  exportenv(environ_strings[0], "SMARTD_MAILER", executable);
-  exportenv(environ_strings[1], "SMARTD_MESSAGE", message);
-  exportenv(environ_strings[2], "SMARTD_SUBJECT", subject);
-  dateandtimezoneepoch(dates, mail->firstsent);
-  exportenv(environ_strings[3], "SMARTD_TFIRST", dates);
-  snprintf(dates, DATEANDEPOCHLEN,"%d", (int)mail->firstsent);
-  exportenv(environ_strings[4], "SMARTD_TFIRSTEPOCH", dates);
-  exportenv(environ_strings[5], "SMARTD_FAILTYPE", whichfail[which]);
-  if (address)
-    exportenv(environ_strings[6], "SMARTD_ADDRESS", address);
-  exportenv(environ_strings[7], "SMARTD_DEVICESTRING", cfg->name);
-
-  switch (cfg->controller_type) {
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_3WARE_9000_CHAR:
-  case CONTROLLER_3WARE_678K_CHAR:
-    {
-      char *s,devicetype[16];
-      sprintf(devicetype, "3ware,%d", cfg->controller_port-1);
-      exportenv(environ_strings[8], "SMARTD_DEVICETYPE", devicetype);
-      if ((s=strchr(cfg->name, ' ')))
-	*s='\0';
-      exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-      if (s)
-	*s=' ';
-    }
-    break;
-  case CONTROLLER_ATA:
-    exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "ata");
-    exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-    break;
-  case CONTROLLER_SCSI:
-    exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "scsi");
-    exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-  }
-
-  // now construct a command to send this as EMAIL
-#ifndef _WIN32
-  if (address)
-    snprintf(command, 2048, 
-             "$SMARTD_MAILER -s '%s' %s 2>&1 << \"ENDMAIL\"\n"
-             "This email was generated by the smartd daemon running on:\n\n"
-             "   host name: %s\n"
-             "  DNS domain: %s\n"
-             "  NIS domain: %s\n\n"
-             "The following warning/error was logged by the smartd daemon:\n\n"
-             "%s\n\n"
-             "For details see host's SYSLOG (default: /var/log/messages).\n\n"
-             "%s%s%s"
-             "ENDMAIL\n",
-	     subject, address, hostname, domainname, nisdomain, message, further, original, additional);
-  else
-    snprintf(command, 2048, "%s 2>&1", executable);
-  
-  // tell SYSLOG what we are about to do...
-  newadd=address?address:"<nomailer>";
-  newwarn=which?"Warning via":"Test of";
-
-  PrintOut(LOG_INFO,"%s %s to %s ...\n",
-           which?"Sending warning via":"Executing test of", executable, newadd);
-  
-  // issue the command to send mail or to run the user's executable
-  errno=0;
-  if (!(pfp=popen(command, "r")))
-    // failed to popen() mail process
-    PrintOut(LOG_CRIT,"%s %s to %s: failed (fork or pipe failed, or no memory) %s\n", 
-	     newwarn,  executable, newadd, errno?strerror(errno):"");
-  else {
-    // pipe suceeded!
-    int len, status;
-    char buffer[EBUFLEN];
-
-    // if unexpected output on stdout/stderr, null terminate, print, and flush
-    if ((len=fread(buffer, 1, EBUFLEN, pfp))) {
-      int count=0;
-      int newlen = len<EBUFLEN ? len : EBUFLEN-1;
-      buffer[newlen]='\0';
-      PrintOut(LOG_CRIT,"%s %s to %s produced unexpected output (%s%d bytes) to STDOUT/STDERR: \n%s\n", 
-	       newwarn, executable, newadd, len!=newlen?"here truncated to ":"", newlen, buffer);
-      
-      // flush pipe if needed
-      while (fread(buffer, 1, EBUFLEN, pfp) && count<EBUFLEN)
-	count++;
-
-      // tell user that pipe was flushed, or that something is really wrong
-      if (count && count<EBUFLEN)
-	PrintOut(LOG_CRIT,"%s %s to %s: flushed remaining STDOUT/STDERR\n", 
-		 newwarn, executable, newadd);
-      else if (count)
-	PrintOut(LOG_CRIT,"%s %s to %s: more than 1 MB STDOUT/STDERR flushed, breaking pipe\n", 
-		 newwarn, executable, newadd);
-    }
-    
-    // if something went wrong with mail process, print warning
-    errno=0;
-    if (-1==(status=pclose(pfp)))
-      PrintOut(LOG_CRIT,"%s %s to %s: pclose(3) failed %s\n", newwarn, executable, newadd,
-	       errno?strerror(errno):"");
-    else {
-      // mail process apparently succeeded. Check and report exit status
-      int status8;
-
-      if (WIFEXITED(status)) {
-	// exited 'normally' (but perhaps with nonzero status)
-	status8=WEXITSTATUS(status);
-	
-	if (status8>128)  
-	  PrintOut(LOG_CRIT,"%s %s to %s: failed (32-bit/8-bit exit status: %d/%d) perhaps caught signal %d [%s]\n", 
-		   newwarn, executable, newadd, status, status8, status8-128, strsignal(status8-128));
-	else if (status8)  
-	  PrintOut(LOG_CRIT,"%s %s to %s: failed (32-bit/8-bit exit status: %d/%d)\n", 
-		   newwarn, executable, newadd, status, status8);
-	else
-	  PrintOut(LOG_INFO,"%s %s to %s: successful\n", newwarn, executable, newadd);
-      }
-      
-      if (WIFSIGNALED(status))
-	PrintOut(LOG_INFO,"%s %s to %s: exited because of uncaught signal %d [%s]\n", 
-		 newwarn, executable, newadd, WTERMSIG(status), strsignal(WTERMSIG(status)));
-      
-      // this branch is probably not possible. If subprocess is
-      // stopped then pclose() should not return.
-      if (WIFSTOPPED(status)) 
-      	PrintOut(LOG_CRIT,"%s %s to %s: process STOPPED because it caught signal %d [%s]\n",
-		 newwarn, executable, newadd, WSTOPSIG(status), strsignal(WSTOPSIG(status)));
-      
-    }
-  }
-  
-#else // _WIN32
-
-  // No "here-documents" on Windows, so must use separate commandline and stdin
-  command[0] = stdinbuf[0] = 0;
-  boxtype = -1; boxmsgoffs = 0;
-  newadd = "<nomailer>";
-  if (address) {
-    // address "[sys]msgbox ..." => show warning (also) as [system modal ]messagebox
-    int addroffs = (!strncmp(address, "sys", 3) ? 3 : 0);
-    if (!strncmp(address+addroffs, "msgbox", 6) && (!address[addroffs+6] || address[addroffs+6] == ',')) {
-      boxtype = (addroffs > 0 ? 1 : 0);
-      addroffs += 6;
-      if (address[addroffs])
-        addroffs++;
-    }
-    else
-      addroffs = 0;
-
-    if (address[addroffs]) {
-      // Use "blat" parameter syntax (TODO: configure via -M for other mailers)
-      snprintf(command, sizeof(command),
-               "%s - -q -subject \"%s\" -to \"%s\"",
-               executable, subject, address+addroffs);
-      newadd = address+addroffs;
-    }
-    // Message for mail [0...] and messagebox [boxmsgoffs...]
-    snprintf(stdinbuf, sizeof(stdinbuf),
-             "This email was generated by the smartd daemon running on:\n\n"
-             "   host name: %s\n"
-             "  DNS domain: %s\n"
-//           "  NIS domain: %s\n"
-             "\n%n"
-             "The following warning/error was logged by the smartd daemon:\n\n"
-             "%s\n\n"
-             "For details see the event log or log file of smartd.\n\n"
-             "%s%s%s"
-             "\n",
-             hostname, /*domainname, */ nisdomain, &boxmsgoffs, message, further, original, additional);
-  }
-  else
-    snprintf(command, sizeof(command), "%s", executable);
-
-  newwarn=which?"Warning via":"Test of";
-  if (boxtype >= 0) {
-    // show message box
-    daemon_messagebox(boxtype, subject, stdinbuf+boxmsgoffs);
-    PrintOut(LOG_INFO,"%s message box\n", newwarn);
-  }
-  if (command[0]) {
-    char stdoutbuf[800]; // < buffer in syslog_win32::vsyslog()
-    int rc;
-    // run command
-    PrintOut(LOG_INFO,"%s %s to %s ...\n",
-             (which?"Sending warning via":"Executing test of"), executable, newadd);
-    rc = daemon_spawn(command, stdinbuf, strlen(stdinbuf), stdoutbuf, sizeof(stdoutbuf));
-    if (rc >= 0 && stdoutbuf[0])
-      PrintOut(LOG_CRIT,"%s %s to %s produced unexpected output (%d bytes) to STDOUT/STDERR:\n%s\n",
-        newwarn, executable, newadd, strlen(stdoutbuf), stdoutbuf);
-    if (rc != 0)
-      PrintOut(LOG_CRIT,"%s %s to %s: failed, exit status %d\n",
-        newwarn, executable, newadd, rc);
-    else
-      PrintOut(LOG_INFO,"%s %s to %s: successful\n", newwarn, executable, newadd);
-  }
-
-#endif // _WIN32
-
-  // increment mail sent counter
-  mail->logged++;
-  
-  // free copy of address (without commas)
-  address=FreeNonZero(address, -1, __LINE__, filenameandversion);
-
-  return;
-}
-
-// Printing function for watching ataprint commands, or losing them
-// [From GLIBC Manual: Since the prototype doesn't specify types for
-// optional arguments, in a call to a variadic function the default
-// argument promotions are performed on the optional argument
-// values. This means the objects of type char or short int (whether
-// signed or not) are promoted to either int or unsigned int, as
-// appropriate.]
-void pout(char *fmt, ...){
-  va_list ap;
-
-  // get the correct time in syslog()
-  FixGlibcTimeZoneBug();
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  // in debug==1 mode we will print the output from the ataprint.o functions!
-  if (debugmode && debugmode!=2)
-#ifdef _WIN32
-   if (facility == LOG_LOCAL1) // logging to stdout
-    vfprintf(stderr,fmt,ap);
-   else   
-#endif
-    vprintf(fmt,ap);
-  // in debug==2 mode we print output from knowndrives.o functions
-  else if (debugmode==2 || con->reportataioctl || con->reportscsiioctl || con->controller_port) {
-    openlog("smartd", LOG_PID, facility);
-    vsyslog(LOG_INFO, fmt, ap);
-    closelog();
-  }
-  va_end(ap);
-  fflush(NULL);
-  return;
-}
-
-// This function prints either to stdout or to the syslog as needed.
-// This function is also used by utility.c to report LOG_CRIT errors.
-void PrintOut(int priority,char *fmt, ...){
-  va_list ap;
-  
-  // get the correct time in syslog()
-  FixGlibcTimeZoneBug();
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  if (debugmode) 
-#ifdef _WIN32
-   if (facility == LOG_LOCAL1) // logging to stdout
-    vfprintf(stderr,fmt,ap);
-   else   
-#endif
-    vprintf(fmt,ap);
-  else {
-    openlog("smartd", LOG_PID, facility);
-    vsyslog(priority,fmt,ap);
-    closelog();
-  }
-  va_end(ap);
-  return;
-}
-
-// Forks new process, closes ALL file descriptors, redirects stdin,
-// stdout, and stderr.  Not quite daemon().  See
-// http://www.iar.unlp.edu.ar/~fede/revistas/lj/Magazines/LJ47/2335.html
-// for a good description of why we do things this way.
-void DaemonInit(){
-#ifndef _WIN32
-  pid_t pid;
-  int i;  
-
-  // flush all buffered streams.  Else we might get two copies of open
-  // streams since both parent and child get copies of the buffers.
-  fflush(NULL);
-  
-  if ((pid=fork()) < 0) {
-    // unable to fork!
-    PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  else if (pid)
-    // we are the parent process -- exit cleanly
-    EXIT(0);
-  
-  // from here on, we are the child process.
-  setsid();
-
-  // Fork one more time to avoid any possibility of having terminals
-  if ((pid=fork()) < 0) {
-    // unable to fork!
-    PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  else if (pid)
-    // we are the parent process -- exit cleanly
-    EXIT(0);
-
-  // Now we are the child's child...
-
-  // close any open file descriptors
-  for (i=getdtablesize();i>=0;--i)
-    close(i);
-  
-  // redirect any IO attempts to /dev/null for stdin
-  i=open("/dev/null",O_RDWR);
-  // stdout
-  dup(i);
-  // stderr
-  dup(i);
-  umask(0);
-  chdir("/");
-  
-  PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid());
-
-#else // _WIN32
-
-  // No fork() on native Win32
-  // Detach this process from console
-  fflush(NULL);
-  if (daemon_detach("smartd")) {
-    PrintOut(LOG_CRIT,"smartd unable to detach from console!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  // stdin/out/err now closed if not redirected
-
-#endif // _WIN32
-  return;
-}
-
-// create a PID file containing the current process id
-void WritePidFile() {
-  if (pid_file) {
-    int error = 0;
-    pid_t pid = getpid();
-    mode_t old_umask;
-    FILE* fp; 
-    
-    old_umask = umask(0077);
-    fp = fopen(pid_file, "w");
-    umask(old_umask);
-    if (fp == NULL) {
-      error = 1;
-    } else if (fprintf(fp, "%d\n", (int)pid) <= 0) {
-      error = 1;
-    } else if (fclose(fp) != 0) {
-      error = 1;
-    }
-    if (error) {
-      PrintOut(LOG_CRIT, "unable to write PID file %s - exiting.\n", pid_file);
-      EXIT(EXIT_PID);
-    }
-    PrintOut(LOG_INFO, "file %s written containing PID %d\n", pid_file, (int)pid);
-  }
-  return;
-}
-
-// Prints header identifying version of code and home
-void PrintHead(){
-  PrintOut(LOG_INFO,"smartd version %s [%s] Copyright (C) 2002-4 Bruce Allen\n", PACKAGE_VERSION, SMARTMONTOOLS_BUILD_HOST);
-  PrintOut(LOG_INFO,"Home page is " PACKAGE_HOMEPAGE "\n\n");
-  return;
-}
-
-// prints help info for configuration file Directives
-void Directives() {
-  PrintOut(LOG_INFO,
-           "Configuration file (%s) Directives (after device name):\n"
-           "  -d TYPE Set the device type: ata, scsi, removable, 3ware,N\n"
-           "  -T TYPE Set the tolerance to one of: normal, permissive\n"
-           "  -o VAL  Enable/disable automatic offline tests (on/off)\n"
-           "  -S VAL  Enable/disable attribute autosave (on/off)\n"
-           "  -n MODE No check if: never, sleep, standby, idle\n"
-           "  -H      Monitor SMART Health Status, report if failed\n"
-           "  -s REG  Do Self-Test at time(s) given by regular expression REG\n"
-           "  -l TYPE Monitor SMART log.  Type is one of: error, selftest\n"
-           "  -f      Monitor 'Usage' Attributes, report failures\n"
-           "  -m ADD  Send email warning to address ADD\n"
-           "  -M TYPE Modify email warning behavior (see man page)\n"
-           "  -p      Report changes in 'Prefailure' Attributes\n"
-           "  -u      Report changes in 'Usage' Attributes\n"
-           "  -t      Equivalent to -p and -u Directives\n"
-           "  -r ID   Also report Raw values of Attribute ID with -p, -u or -t\n"
-           "  -R ID   Track changes in Attribute ID Raw value with -p, -u or -t\n"
-           "  -i ID   Ignore Attribute ID for -f Directive\n"
-           "  -I ID   Ignore Attribute ID for -p, -u or -t Directive\n"
-	   "  -C ID   Monitor Current Pending Sectors in Attribute ID\n"
-	   "  -U ID   Monitor Offline Uncorrectable Sectors in Attribute ID\n"
-           "  -v N,ST Modifies labeling of Attribute N (see man page)  \n"
-           "  -P TYPE Drive-specific presets: use, ignore, show, showall\n"
-           "  -a      Default: -H -f -t -l error -l selftest -C 197 -U 198\n"
-           "  -F TYPE Firmware bug workaround: none, samsung, samsung2\n"
-           "   #      Comment: text after a hash sign is ignored\n"
-           "   \\      Line continuation character\n"
-           "Attribute ID is a decimal integer 1 <= ID <= 255\n"
-	   "Use ID = 0 to turn off -C and/or -U Directives\n"
-           "Example: /dev/hda -a\n", 
-           configfile);
-  return;
-}
-
-/* Returns a pointer to a static string containing a formatted list of the valid
-   arguments to the option opt or NULL on failure. */
-const char *GetValidArgList(char opt) {
-  switch (opt) {
-  case 'c':
-    return "<FILE_NAME>, -";
-  case 's':
-    return "valid_regular_expression";
-  case 'l':
-    return "daemon, local0, local1, local2, local3, local4, local5, local6, local7";
-  case 'q':
-    return "nodev, errors, nodevstartup, never, onecheck";
-  case 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 'p':
-    return "<FILE_NAME>";
-  case 'i':
-    return "<INTEGER_SECONDS>";
-  default:
-    return NULL;
-  }
-}
-
-/* prints help information for command syntax */
-void Usage (void){
-  PrintOut(LOG_INFO,"Usage: smartd [options]\n\n");
-#ifdef HAVE_GETOPT_LONG
-  PrintOut(LOG_INFO,"  -c NAME|-, --configfile=NAME|-\n");
-  PrintOut(LOG_INFO,"        Read configuration file NAME or stdin [default is %s]\n\n", configfile);
-  PrintOut(LOG_INFO,"  -d, --debug\n");
-  PrintOut(LOG_INFO,"        Start smartd in debug mode\n\n");
-  PrintOut(LOG_INFO,"  -D, --showdirectives\n");
-  PrintOut(LOG_INFO,"        Print the configuration file Directives and exit\n\n");
-  PrintOut(LOG_INFO,"  -h, --help, --usage\n");
-  PrintOut(LOG_INFO,"        Display this help and exit\n\n");
-  PrintOut(LOG_INFO,"  -i N, --interval=N\n");
-  PrintOut(LOG_INFO,"        Set interval between disk checks to N seconds, where N >= 10\n\n");
-  PrintOut(LOG_INFO,"  -l local[0-7], --logfacility=local[0-7]\n");
-#if !(defined(_WIN32) || defined(__CYGWIN__))
-  PrintOut(LOG_INFO,"        Use syslog facility local0 - local7 or daemon [default]\n\n");
-#else
-#ifdef _WIN32
-  PrintOut(LOG_INFO,"        Log to \"./smartd.log\", stdout, stderr [default is event log]\n\n");
-#else
-  PrintOut(LOG_INFO,"        Use syslog facility local0 - local7 (ignored on Cygwin)\n\n");
-#endif
-#endif // _WIN32 || __CYGWIN__
-  PrintOut(LOG_INFO,"  -p NAME, --pidfile=NAME\n");
-  PrintOut(LOG_INFO,"        Write PID file NAME\n\n");
-  PrintOut(LOG_INFO,"  -q WHEN, --quit=WHEN\n");
-  PrintOut(LOG_INFO,"        Quit on one of: %s\n\n", GetValidArgList('q'));
-  PrintOut(LOG_INFO,"  -r, --report=TYPE\n");
-  PrintOut(LOG_INFO,"        Report transactions for one of: %s\n\n", GetValidArgList('r'));
-#ifdef _WIN32
-  PrintOut(LOG_INFO,"  --service\n");
-  PrintOut(LOG_INFO,"        Running as windows service (must be first arg, do not use from console)\n\n");
-#endif // _WIN32
-  PrintOut(LOG_INFO,"  -V, --version, --license, --copyright\n");
-  PrintOut(LOG_INFO,"        Print License, Copyright, and version information\n");
-#else
-  PrintOut(LOG_INFO,"  -c NAME|-  Read configuration file NAME or stdin [default is %s]\n", configfile);
-  PrintOut(LOG_INFO,"  -d         Start smartd in debug mode\n");
-  PrintOut(LOG_INFO,"  -D         Print the configuration file Directives and exit\n");
-  PrintOut(LOG_INFO,"  -h         Display this help and exit\n");
-  PrintOut(LOG_INFO,"  -i N       Set interval between disk checks to N seconds, where N >= 10\n");
-  PrintOut(LOG_INFO,"  -l local?  Use syslog facility local0 - local7, or daemon\n");
-  PrintOut(LOG_INFO,"  -p NAME    Write PID file NAME\n");
-  PrintOut(LOG_INFO,"  -q WHEN    Quit on one of: %s\n", GetValidArgList('q'));
-  PrintOut(LOG_INFO,"  -r TYPE    Report transactions for one of: %s\n", GetValidArgList('r'));
-  PrintOut(LOG_INFO,"  -V         Print License, Copyright, and version information\n");
-#endif
-}
-
-// returns negative if problem, else fd>=0
-static int OpenDevice(char *device, char *mode, int scanning) {
-  int fd;
-  char *s=device;
-  
-  // If there is an ASCII "space" character in the device name,
-  // terminate string there.  This is for 3ware devices only.
-  if ((s=strchr(device,' ')))
-    *s='\0';
-
-  // open the device
-  fd = deviceopen(device, mode);
-
-  // if we removed a space, put it back in please
-  if (s)
-    *s=' ';
-
-  // if we failed to open the device, complain!
-  if (fd < 0) {
-
-    // For linux+devfs, a nonexistent device gives a strange error
-    // message.  This makes the error message a bit more sensible.
-    // If no debug and scanning - don't print errors
-    if (debugmode || !scanning) {
-      if (errno==ENOENT || errno==ENOTDIR)
-	errno=ENODEV;
-      
-      PrintOut(LOG_INFO,"Device: %s, %s, open() failed\n",
-	       device, strerror(errno));
-    }
-    return -1;
-  }
-  // device opened sucessfully
-  return fd;
-}
-
-int CloseDevice(int fd, char *name){
-  if (deviceclose(fd)){
-    PrintOut(LOG_INFO,"Device: %s, %s, close(%d) failed\n", name, strerror(errno), fd);
-    return 1;
-  }
-  // device sucessfully closed
-  return 0;
-}
-
-// returns <0 on failure
-int ATAErrorCount(int fd, char *name){
-  struct ata_smart_errorlog log;
-  
-  if (-1==ataReadErrorLog(fd,&log)){
-    PrintOut(LOG_INFO,"Device: %s, Read SMART Error Log Failed\n",name);
-    return -1;
-  }
-  
-  // return current number of ATA errors
-  return log.error_log_pointer?log.ata_error_count:0;
-}
-
-// returns <0 if problem.  Otherwise, bottom 8 bits are the self test
-// error count, and top bits are the power-on hours of the last error.
-int SelfTestErrorCount(int fd, char *name){
-  struct ata_smart_selftestlog log;
-
-  if (-1==ataReadSelfTestLog(fd,&log)){
-    PrintOut(LOG_INFO,"Device: %s, Read SMART Self Test Log Failed\n",name);
-    return -1;
-  }
-  
-  // return current number of self-test errors
-  return ataPrintSmartSelfTestlog(&log,0);
-}
-
-// scan to see what ata devices there are, and if they support SMART
-int ATADeviceScan(cfgfile *cfg, int scanning){
-  int fd, supported=0;
-  struct ata_identify_device drive;
-  char *name=cfg->name;
-  int retainsmartdata=0;
-  int retid;
-  char *mode;
-  
-  // should we try to register this as an ATA device?
-  switch (cfg->controller_type) {
-  case CONTROLLER_ATA:
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_UNKNOWN:
-    mode="ATA";
-    break;
-  case CONTROLLER_3WARE_678K_CHAR:
-    mode="ATA_3WARE_678K";
-    break;
-  case CONTROLLER_3WARE_9000_CHAR:
-    mode="ATA_3WARE_9000";
-    break;
-  default:
-    // not a recognized ATA or SATA device.  We should never enter
-    // this branch.
-    return 1;
-  }
-  
-  // open the device
-  if ((fd=OpenDevice(name, mode, scanning))<0)
-    // device open failed
-    return 1;
-  PrintOut(LOG_INFO,"Device: %s, opened\n", name);
-  
-  // pass user settings on to low-level ATA commands
-  con->controller_port=cfg->controller_port;
-  con->controller_type=cfg->controller_type;
-  con->fixfirmwarebug = cfg->fixfirmwarebug;
-  
-  // Get drive identity structure
-  if ((retid=ataReadHDIdentity (fd,&drive))){
-    if (retid<0)
-      // Unable to read Identity structure
-      PrintOut(LOG_INFO,"Device: %s, not ATA, no IDENTIFY DEVICE Structure\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, packet devices [this device %s] not SMART capable\n",
-               name, packetdevicetype(retid-1));
-    CloseDevice(fd, name);
-    return 2; 
-  }
-
-  // Show if device in database, and use preset vendor attribute
-  // options unless user has requested otherwise.
-  if (cfg->ignorepresets)
-    PrintOut(LOG_INFO, "Device: %s, smartd database not searched (Directive: -P ignore).\n", name);
-  else {
-    // do whatever applypresets decides to do. Will allocate memory if
-    // cfg->attributedefs is needed.
-    if (applypresets(&drive, &cfg->attributedefs, con)<0)
-      PrintOut(LOG_INFO, "Device: %s, not found in smartd database.\n", name);
-    else
-      PrintOut(LOG_INFO, "Device: %s, found in smartd database.\n", name);
-    
-    // then save the correct state of the flag (applypresets may have changed it)
-    cfg->fixfirmwarebug = con->fixfirmwarebug;
-  }
-  
-  // If requested, show which presets would be used for this drive
-  if (cfg->showpresets) {
-    int savedebugmode=debugmode;
-    PrintOut(LOG_INFO, "Device %s: presets are:\n", name);
-    if (!debugmode)
-      debugmode=2;
-    showpresets(&drive);
-    debugmode=savedebugmode;
-  }
-
-  // see if drive supports SMART
-  supported=ataSmartSupport(&drive);
-  if (supported!=1) {
-    if (supported==0)
-      // drive does NOT support SMART
-      PrintOut(LOG_INFO,"Device: %s, lacks SMART capability\n",name);
-    else
-      // can't tell if drive supports SMART
-      PrintOut(LOG_INFO,"Device: %s, ATA IDENTIFY DEVICE words 82-83 don't specify if SMART capable.\n",name);
-  
-    // should we proceed anyway?
-    if (cfg->permissive){
-      PrintOut(LOG_INFO,"Device: %s, proceeding since '-T permissive' Directive given.\n",name);
-    }
-    else {
-      PrintOut(LOG_INFO,"Device: %s, to proceed anyway, use '-T permissive' Directive.\n",name);
-      CloseDevice(fd, name);
-      return 2;
-    }
-  }
-  
-  if (ataEnableSmart(fd)){
-    // Enable SMART command has failed
-    PrintOut(LOG_INFO,"Device: %s, could not enable SMART capability\n",name);
-    CloseDevice(fd, name);
-    return 2; 
-  }
-  
-  // disable device attribute autosave...
-  if (cfg->autosave==1){
-    if (ataDisableAutoSave(fd))
-      PrintOut(LOG_INFO,"Device: %s, could not disable SMART Attribute Autosave.\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, disabled SMART Attribute Autosave.\n",name);
-  }
-
-  // or enable device attribute autosave
-  if (cfg->autosave==2){
-    if (ataEnableAutoSave(fd))
-      PrintOut(LOG_INFO,"Device: %s, could not enable SMART Attribute Autosave.\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, enabled SMART Attribute Autosave.\n",name);
-  }
-
-  // capability check: SMART status
-  if (cfg->smartcheck && ataSmartStatus2(fd)==-1){
-    PrintOut(LOG_INFO,"Device: %s, not capable of SMART Health Status check\n",name);
-    cfg->smartcheck=0;
-  }
-  
-  // capability check: Read smart values and thresholds.  Note that
-  // smart values are ALSO needed even if we ONLY want to know if the
-  // device is self-test log or error-log capable!  After ATA-5, this
-  // information was ALSO reproduced in the IDENTIFY DEVICE response,
-  // but sadly not for ATA-5.  Sigh.
-
-  // do we need to retain SMART data after returning from this routine?
-  retainsmartdata=cfg->usagefailed || cfg->prefail || cfg->usage;
-  
-  // do we need to get SMART data?
-  if (retainsmartdata || cfg->autoofflinetest || cfg->selftest || cfg->errorlog || cfg->pending!=DONT_MONITOR_UNC) {
-
-    unsigned char currentpending, offlinepending;
-
-    cfg->smartval=(struct ata_smart_values *)Calloc(1,sizeof(struct ata_smart_values));
-    cfg->smartthres=(struct ata_smart_thresholds_pvt *)Calloc(1,sizeof(struct ata_smart_thresholds_pvt));
-    
-    if (!cfg->smartval || !cfg->smartthres){
-      PrintOut(LOG_CRIT,"Not enough memory to obtain SMART data\n");
-      EXIT(EXIT_NOMEM);
-    }
-    
-    if (ataReadSmartValues(fd,cfg->smartval) ||
-        ataReadSmartThresholds (fd,cfg->smartthres)){
-      PrintOut(LOG_INFO,"Device: %s, Read SMART Values and/or Thresholds Failed\n",name);
-      retainsmartdata=cfg->usagefailed=cfg->prefail=cfg->usage=0;
-      cfg->pending=DONT_MONITOR_UNC;
-    }
-    
-    // see if the necessary Attribute is there to monitor offline or
-    // current pending sectors
-    TranslatePending(cfg->pending, &currentpending, &offlinepending);
-    
-    if (currentpending && ATAReturnAttributeRawValue(currentpending, cfg->smartval)<0) {
-      PrintOut(LOG_INFO,"Device: %s, can't monitor Current Pending Sector count - no Attribute %d\n",
-	       name, (int)currentpending);
-      cfg->pending &= 0xff00;
-      cfg->pending |= CUR_UNC_DEFAULT;
-    }
-    
-    if (offlinepending && ATAReturnAttributeRawValue(offlinepending, cfg->smartval)<0) {
-      PrintOut(LOG_INFO,"Device: %s, can't monitor Offline Uncorrectable Sector count  - no Attribute %d\n",
-	       name, (int)offlinepending);
-      cfg->pending &= 0x00ff;
-      cfg->pending |= OFF_UNC_DEFAULT<<8;
-    }
-  }
-  
-  // enable/disable automatic on-line testing
-  if (cfg->autoofflinetest){
-    // is this an enable or disable request?
-    char *what=(cfg->autoofflinetest==1)?"disable":"enable";
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO,"Device: %s, could not %s SMART Automatic Offline Testing.\n",name, what);
-    else {
-      // if command appears unsupported, issue a warning...
-      if (!isSupportAutomaticTimer(cfg->smartval))
-        PrintOut(LOG_INFO,"Device: %s, SMART Automatic Offline Testing unsupported...\n",name);
-      // ... but then try anyway
-      if ((cfg->autoofflinetest==1)?ataDisableAutoOffline(fd):ataEnableAutoOffline(fd))
-        PrintOut(LOG_INFO,"Device: %s, %s SMART Automatic Offline Testing failed.\n", name, what);
-      else
-        PrintOut(LOG_INFO,"Device: %s, %sd SMART Automatic Offline Testing.\n", name, what);
-    }
-  }
-  
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int retval;
-    
-    // start with service disabled, and re-enable it if all works OK
-    cfg->selftest=0;
-    cfg->selflogcount=0;
-    cfg->selfloghour=0;
-
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Self-Test log (SMART READ DATA failed); disabling -l selftest\n", name);
-    else if (!cfg->permissive && !isSmartTestLogCapable(cfg->smartval, &drive))
-      PrintOut(LOG_INFO, "Device: %s, appears to lack SMART Self-Test log; disabling -l selftest (override with -T permissive Directive)\n", name);
-    else if ((retval=SelfTestErrorCount(fd, name))<0)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Self-Test log; remove -l selftest Directive from smartd.conf\n", name);
-    else {
-      cfg->selftest=1;
-      cfg->selflogcount=SELFTEST_ERRORCOUNT(retval);
-      cfg->selfloghour =SELFTEST_ERRORHOURS(retval);
-    }
-  }
-  
-  // capability check: ATA error log
-  if (cfg->errorlog){
-    int val;
-
-    // start with service disabled, and re-enable it if all works OK
-    cfg->errorlog=0;
-    cfg->ataerrorcount=0;
-
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Error log (SMART READ DATA failed); disabling -l error\n", name);
-    else if (!cfg->permissive && !isSmartErrorLogCapable(cfg->smartval, &drive))
-      PrintOut(LOG_INFO, "Device: %s, appears to lack SMART Error log; disabling -l error (override with -T permissive Directive)\n", name);
-    else if ((val=ATAErrorCount(fd, name))<0)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Error log; remove -l error Directive from smartd.conf\n", name);
-    else {
-        cfg->errorlog=1;
-        cfg->ataerrorcount=val;
-    }
-  }
-  
-  // If we don't need to save SMART data, get rid of it now
-  if (!retainsmartdata) {
-    if (cfg->smartval) {
-      cfg->smartval=CheckFree(cfg->smartval, __LINE__,filenameandversion);
-      bytes-=sizeof(struct ata_smart_values);
-    }
-    if (cfg->smartthres) {
-      cfg->smartthres=CheckFree(cfg->smartthres, __LINE__,filenameandversion);
-      bytes-=sizeof(struct ata_smart_thresholds_pvt);
-    }
-  }
-
-  // capabilities check -- does it support powermode?
-  if (cfg->powermode) {
-    int powermode=ataCheckPowerMode(fd);
-    
-    if (-1 == powermode) {
-      PrintOut(LOG_CRIT, "Device: %s, no ATA CHECK POWER STATUS support, ignoring -n Directive\n", name);
-      cfg->powermode=0;
-    } 
-    else if (powermode!=0 && powermode!=0x80 && powermode!=0xff) {
-      PrintOut(LOG_CRIT, "Device: %s, CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Directive\n",
-	       name, powermode);
-      cfg->powermode=0;
-    }
-  }
-
-  // If no tests available or selected, return
-  if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck || 
-        cfg->usagefailed || cfg->prefail || cfg->usage)) {
-    CloseDevice(fd, name);
-    return 3;
-  }
-  
-  // Do we still have entries available?
-  while (numdevata>=atadevlist_max)
-    atadevlist=AllocateMoreSpace(atadevlist, &atadevlist_max, "ATA device");
-  
-  // register device
-  PrintOut(LOG_INFO,"Device: %s, is SMART capable. Adding to \"monitor\" list.\n",name);
-  
-    // record number of device, type of device, increment device count
-  if (cfg->controller_type == CONTROLLER_UNKNOWN)
-    cfg->controller_type=CONTROLLER_ATA;;
-  
-  // close file descriptor
-  CloseDevice(fd, name);
-  return 0;
-}
-
-// on success, return 0. On failure, return >0.  Never return <0,
-// please.
-static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
-  int k, fd, err; 
-  char *device = cfg->name;
-  struct scsi_iec_mode_page iec;
-  UINT8  tBuf[64];
-  
-  // should we try to register this as a SCSI device?
-  switch (con->controller_type) {
-  case CONTROLLER_SCSI:
-  case CONTROLLER_UNKNOWN:
-    break;
-  default:
-    return 1;
-  }
-  
-  // open the device
-  if ((fd = OpenDevice(device, "SCSI", scanning)) < 0)
-    return 1;
-  PrintOut(LOG_INFO,"Device: %s, opened\n", device);
-    
-  // check that device is ready for commands. IE stores its stuff on
-  // the media.
-  if ((err = scsiTestUnitReady(fd))) {
-    if (SIMPLE_ERR_NOT_READY == err)
-      PrintOut(LOG_INFO, "Device: %s, NOT READY (e.g. spun down); skip device\n", device);
-    else if (SIMPLE_ERR_NO_MEDIUM == err)
-      PrintOut(LOG_INFO, "Device: %s, NO MEDIUM present; skip device\n", device);
-    else if (SIMPLE_ERR_BECOMING_READY == err)
-      PrintOut(LOG_INFO, "Device: %s, BECOMING (but not yet) READY; skip device\n", device);
-    else
-      PrintOut(LOG_CRIT, "Device: %s, failed Test Unit Ready [err=%d]\n", device, err);
-    CloseDevice(fd, device);
-    return 2; 
-  }
-  
-  // Badly-conforming USB storage devices may fail this check.
-  // The response to the following IE mode page fetch (current and
-  // changeable values) is carefully examined. It has been found
-  // that various USB devices that malform the response will lock up
-  // if asked for a log page (e.g. temperature) so it is best to
-  // bail out now.
-  if (!(err = scsiFetchIECmpage(fd, &iec, cfg->modese_len)))
-    cfg->modese_len = iec.modese_len;
-  else if (SIMPLE_ERR_BAD_FIELD == err)
-    ;  /* continue since it is reasonable not to support IE mpage */
-  else { /* any other error (including malformed response) unreasonable */
-    PrintOut(LOG_INFO, 
-             "Device: %s, Bad IEC (SMART) mode page, err=%d, skip device\n", 
-             device, err);
-    CloseDevice(fd, device);
-    return 3;
-  }
-  
-  // N.B. The following is passive (i.e. it doesn't attempt to turn on
-  // smart if it is off). This may change to be the same as the ATA side.
-  if (!scsi_IsExceptionControlEnabled(&iec)) {
-    PrintOut(LOG_INFO, "Device: %s, IE (SMART) not enabled, skip device\n"
-	               "Try 'smartctl -s on %s' to turn on SMART features\n", 
-                        device, device);
-    CloseDevice(fd, device);
-    return 3;
-  }
-  
-  // Device exists, and does SMART.  Add to list (allocating more space if needed)
-  while (numdevscsi >= scsidevlist_max)
-    scsidevlist=AllocateMoreSpace(scsidevlist, &scsidevlist_max, "SCSI device");
-  
-  // Flag that certain log pages are supported (information may be
-  // available from other sources).
-  if (0 == scsiLogSense(fd, SUPPORTED_LPAGES, tBuf, sizeof(tBuf), 0)) {
-    for (k = 4; k < tBuf[3] + LOGPAGEHDRSIZE; ++k) {
-      switch (tBuf[k]) { 
-      case TEMPERATURE_LPAGE:
-        cfg->TempPageSupported = 1;
-        break;
-      case IE_LPAGE:
-        cfg->SmartPageSupported = 1;
-        break;
-      default:
-        break;
-      }
-    }   
-  }
-  
-  // record type of device
-  cfg->controller_type = CONTROLLER_SCSI;
-  
-  // get rid of allocated memory only needed for ATA devices.  These
-  // might have been allocated if the user specified Ignore options or
-  // other ATA-only Attribute-specific options on the DEVICESCAN line.
-  cfg->monitorattflags = FreeNonZero(cfg->monitorattflags, NMONITOR*32,__LINE__,filenameandversion);
-  cfg->attributedefs   = FreeNonZero(cfg->attributedefs,   MAX_ATTRIBUTE_NUM,__LINE__,filenameandversion);
-  cfg->smartval        = FreeNonZero(cfg->smartval,        sizeof(struct ata_smart_values),__LINE__,filenameandversion);
-  cfg->smartthres      = FreeNonZero(cfg->smartthres,      sizeof(struct ata_smart_thresholds_pvt),__LINE__,filenameandversion);
-  
-  // Check if scsiCheckIE() is going to work
-  {
-    UINT8 asc = 0;
-    UINT8 ascq = 0;
-    UINT8 currenttemp = 0;
-    UINT8 triptemp = 0;
-    
-    if (scsiCheckIE(fd, cfg->SmartPageSupported, cfg->TempPageSupported,
-                    &asc, &ascq, &currenttemp, &triptemp)) {
-      PrintOut(LOG_INFO, "Device: %s, unexpectedly failed to read SMART values\n", device);
-      cfg->SuppressReport = 1;
-    }
-  }
-  
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int retval=scsiCountFailedSelfTests(fd, 0);
-    if (retval<0) {
-      // no self-test log, turn off monitoring
-      PrintOut(LOG_INFO, "Device: %s, does not support SMART Self-Test Log.\n", device);
-      cfg->selftest=0;
-      cfg->selflogcount=0;
-      cfg->selfloghour=0;
-    }
-    else {
-      // register starting values to watch for changes
-      cfg->selflogcount=SELFTEST_ERRORCOUNT(retval);
-      cfg->selfloghour =SELFTEST_ERRORHOURS(retval);
-    }
-  }
-  
-  // disable autosave (set GLTSD bit)
-  if (cfg->autosave==1){
-    if (scsiSetControlGLTSD(fd, 1, cfg->modese_len))
-      PrintOut(LOG_INFO,"Device: %s, could not disable autosave (set GLTSD bit).\n",device);
-    else
-      PrintOut(LOG_INFO,"Device: %s, disabled autosave (set GLTSD bit).\n",device);
-  }
-
-  // or enable autosave (clear GLTSD bit)
-  if (cfg->autosave==2){
-    if (scsiSetControlGLTSD(fd, 0, cfg->modese_len))
-      PrintOut(LOG_INFO,"Device: %s, could not enable autosave (clear GLTSD bit).\n",device);
-    else
-      PrintOut(LOG_INFO,"Device: %s, enabled autosave (cleared GLTSD bit).\n",device);
-  }
-  
-  // tell user we are registering device
-  PrintOut(LOG_INFO, "Device: %s, is SMART capable. Adding to \"monitor\" list.\n", device);
-  
-  // close file descriptor
-  CloseDevice(fd, device);
-  return 0;
-}
-
-// We compare old and new values of the n'th attribute.  Note that n
-// is NOT the attribute ID number.. If (Normalized & Raw) equal,
-// then return 0, else nonzero.
-int  ATACompareValues(changedattribute_t *delta,
-                            struct ata_smart_values *new,
-                            struct ata_smart_values *old,
-                            struct ata_smart_thresholds_pvt *thresholds,
-                            int n, char *name){
-  struct ata_smart_attribute *now,*was;
-  struct ata_smart_threshold_entry *thre;
-  unsigned char oldval,newval;
-  int sameraw;
-
-  // check that attribute number in range, and no null pointers
-  if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !new || !old || !thresholds)
-    return 0;
-  
-  // pointers to disk's values and vendor's thresholds
-  now=new->vendor_attributes+n;
-  was=old->vendor_attributes+n;
-  thre=thresholds->thres_entries+n;
-
-  // consider only valid attributes
-  if (!now->id || !was->id || !thre->id)
-    return 0;
-  
-  
-  // issue warning if they don't have the same ID in all structures:
-  if ( (now->id != was->id) || (now->id != thre->id) ){
-    PrintOut(LOG_INFO,"Device: %s, same Attribute has different ID numbers: %d = %d = %d\n",
-             name, (int)now->id, (int)was->id, (int)thre->id);
-    return 0;
-  }
-
-  // new and old values of Normalized Attributes
-  newval=now->current;
-  oldval=was->current;
-
-  // See if the RAW values are unchanged (ie, the same)
-  if (memcmp(now->raw, was->raw, 6))
-    sameraw=0;
-  else
-    sameraw=1;
-  
-  // if any values out of the allowed range, or if the values haven't
-  // changed, return 0
-  if (!newval || !oldval || newval>0xfe || oldval>0xfe || (oldval==newval && sameraw))
-    return 0;
-  
-  // values have changed.  Construct output and return
-  delta->newval=newval;
-  delta->oldval=oldval;
-  delta->id=now->id;
-  delta->prefail=ATTRIBUTE_FLAGS_PREFAILURE(now->flags);
-  delta->sameraw=sameraw;
-
-  return 1;
-}
-
-// This looks to see if the corresponding bit of the 32 bytes is set.
-// This wastes a few bytes of storage but eliminates all searching and
-// sorting functions! Entry is ZERO <==> the attribute ON. Calling
-// with set=0 tells you if the attribute is being tracked or not.
-// Calling with set=1 turns the attribute OFF.
-int IsAttributeOff(unsigned char attr, unsigned char **datap, int set, int which, int whatline){
-  unsigned char *data;
-  int loc=attr>>3;
-  int bit=attr & 0x07;
-  unsigned char mask=0x01<<bit;
-
-  if (which>=NMONITOR || which < 0){
-    PrintOut(LOG_CRIT, "Internal error in IsAttributeOff() at line %d of file %s (which=%d)\n%s",
-             whatline, filenameandversion, which, reportbug);
-    EXIT(EXIT_BADCODE);
-  }
-
-  if (*datap == NULL){
-    // NULL data implies Attributes are ON...
-    if (!set)
-      return 0;
-    
-    // we are writing
-    if (!(*datap=(unsigned char *)Calloc(NMONITOR*32, 1))){
-      PrintOut(LOG_CRIT,"No memory to create monattflags\n");
-      EXIT(EXIT_NOMEM);
-    }
-  }
-  
-  // pointer to the 256 bits that we need
-  data=*datap+which*32;
-
-  // attribute zero is always OFF
-  if (!attr)
-    return 1;
-
-  if (!set)
-    return (data[loc] & mask);
-  
-  data[loc]|=mask;
-
-  // return value when setting has no sense
-  return 0;
-}
-
-// If the self-test log has got more self-test errors (or more recent
-// self-test errors) recorded, then notify user.
-void CheckSelfTestLogs(cfgfile *cfg, int new){
-  char *name=cfg->name;
-
-  if (new<0)
-    // command failed
-    MailWarning(cfg, 8, "Device: %s, Read SMART Self-Test Log Failed", name);
-  else {      
-    // old and new error counts
-    int oldc=cfg->selflogcount;
-    int newc=SELFTEST_ERRORCOUNT(new);
-    
-    // old and new error timestamps in hours
-    int oldh=cfg->selfloghour;
-    int newh=SELFTEST_ERRORHOURS(new);
-    
-    if (oldc<newc) {
-      // increase in error count
-      PrintOut(LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d\n",
-               name, oldc, newc);
-      MailWarning(cfg, 3, "Device: %s, Self-Test Log error count increased from %d to %d",
-                   name, oldc, newc);
-    } else if (oldh<newh) {
-      // more recent error
-      PrintOut(LOG_CRIT, "Device: %s, new Self-Test Log error at hour timestamp %d\n",
-               name, newh);
-      MailWarning(cfg, 3, "Device: %s, new Self-Test Log error at hour timestamp %d\n",
-                   name, newh);
-    }
-    
-    // Needed since self-test error count may DECREASE.  Hour should
-    // never decrease but this does no harm.
-    cfg->selflogcount= newc;
-    cfg->selfloghour = newh;
-  }
-  return;
-}
-
-// returns 1 if time to do test of type testtype, 0 if not time to do
-// test, < 0 if error
-int DoTestNow(cfgfile *cfg, char testtype) {
-  // start by finding out the time:
-  struct tm *timenow;
-  time_t epochnow;
-  char matchpattern[16];
-  regmatch_t substring;
-  int weekday, length;
-  unsigned short hours;
-  testinfo *dat=cfg->testdata;
-
-  // check that self-testing has been requested
-  if (!dat)
-    return 0;
-  
-  // since we are about to call localtime(), be sure glibc is informed
-  // of any timezone changes we make.
-  FixGlibcTimeZoneBug();
-  
-  // construct pattern containing the month, day of month, day of
-  // week, and hour
-  time(&epochnow);
-  timenow=localtime(&epochnow);
-  
-  // tm_wday is 0 (Sunday) to 6 (Saturday).  We use 1 (Monday) to 7
-  // (Sunday).
-  weekday=timenow->tm_wday?timenow->tm_wday:7;
-  sprintf(matchpattern, "%c/%02d/%02d/%1d/%02d", testtype, timenow->tm_mon+1, 
-          timenow->tm_mday, weekday, timenow->tm_hour);
-  
-  // if no match, we are done
-  if (regexec(&(dat->cregex), matchpattern, 1, &substring, 0))
-    return 0;
-  
-  // must match the ENTIRE type/date/time string
-  length=strlen(matchpattern);
-  if (substring.rm_so!=0 || substring.rm_eo!=length)
-    return 0;
-  
-  // never do a second test in the same hour as another test (the % 7 ensures
-  // that the RHS will never be greater than 65535 and so will always fit into
-  // an unsigned short)
-  hours=1+timenow->tm_hour+24*(timenow->tm_yday+366*(timenow->tm_year % 7));
-  if (hours==dat->hour) {
-    if (testtype!=dat->testtype)
-      PrintOut(LOG_INFO, "Device: %s, did test of type %c in current hour, skipping test of type %c\n",
-	       cfg->name, dat->testtype, testtype);
-    return 0;
-  }
-  
-  // save time and type of the current test; we are ready to do a test
-  dat->hour=hours;
-  dat->testtype=testtype;
-  return 1;
-}
-
-// Return zero on success, nonzero on failure. Perform offline (background)
-// short or long (extended) self test on given scsi device.
-int DoSCSISelfTest(int fd, cfgfile *cfg, char testtype) {
-  int retval = 0;
-  char *testname = NULL;
-  char *name = cfg->name;
-  int inProgress;
-
-  if (scsiSelfTestInProgress(fd, &inProgress)) {
-    PrintOut(LOG_CRIT, "Device: %s, does not support Self-Tests\n", name);
-    cfg->testdata->not_cap_short=cfg->testdata->not_cap_long=1;
-    return 1;
-  }
-
-  if (1 == inProgress) {
-    PrintOut(LOG_INFO, "Device: %s, skip since Self-Test already in "
-             "progress.\n", name);
-    return 1;
-  }
-
-  switch (testtype) {
-  case 'S':
-    testname = "Short Self";
-    retval = scsiSmartShortSelfTest(fd);
-    break;
-  case 'L':
-    testname = "Long Self";
-    retval = scsiSmartExtendSelfTest(fd);
-    break;
-  }
-  // If we can't do the test, exit
-  if (NULL == testname) {
-    PrintOut(LOG_CRIT, "Device: %s, not capable of %c Self-Test\n", name, 
-             testtype);
-    return 1;
-  }
-  if (retval) {
-    if ((SIMPLE_ERR_BAD_OPCODE == retval) || 
-        (SIMPLE_ERR_BAD_FIELD == retval)) {
-      PrintOut(LOG_CRIT, "Device: %s, not capable of %s-Test\n", name, 
-               testname);
-      if ('L'==testtype)
-        cfg->testdata->not_cap_long=1;
-      else
-        cfg->testdata->not_cap_short=1;
-     
-      return 1;
-    }
-    PrintOut(LOG_CRIT, "Device: %s, execute %s-Test failed (err: %d)\n", name, 
-             testname, retval);
-    return 1;
-  }
-  
-  PrintOut(LOG_INFO, "Device: %s, starting scheduled %s-Test.\n", name, testname);
-  
-  return 0;
-}
-
-// Do an offline immediate or self-test.  Return zero on success,
-// nonzero on failure.
-int DoATASelfTest(int fd, cfgfile *cfg, char testtype) {
-  
-  struct ata_smart_values data;
-  char *testname=NULL;
-  int retval, dotest=-1;
-  char *name=cfg->name;
-  
-  // Read current smart data and check status/capability
-  if (ataReadSmartValues(fd, &data) || !(data.offline_data_collection_capability)) {
-    PrintOut(LOG_CRIT, "Device: %s, not capable of Offline or Self-Testing.\n", name);
-    return 1;
-  }
-  
-  // Check for capability to do the test
-  switch (testtype) {
-  case 'O':
-    testname="Offline Immediate ";
-    if (isSupportExecuteOfflineImmediate(&data))
-      dotest=OFFLINE_FULL_SCAN;
-    else
-      cfg->testdata->not_cap_offline=1;
-    break;
-  case 'C':
-    testname="Conveyance Self-";
-    if (isSupportConveyanceSelfTest(&data))
-      dotest=CONVEYANCE_SELF_TEST;
-    else
-      cfg->testdata->not_cap_conveyance=1;
-    break;
-  case 'S':
-    testname="Short Self-";
-    if (isSupportSelfTest(&data))
-      dotest=SHORT_SELF_TEST;
-    else
-      cfg->testdata->not_cap_short=1;
-    break;
-  case 'L':
-    testname="Long Self-";
-    if (isSupportSelfTest(&data))
-      dotest=EXTEND_SELF_TEST;
-    else
-      cfg->testdata->not_cap_long=1;
-    break;
-  }
-  
-  // If we can't do the test, exit
-  if (dotest<0) {
-    PrintOut(LOG_CRIT, "Device: %s, not capable of %sTest\n", name, testname);
-    return 1;
-  }
-  
-  // If currently running a self-test, do not interrupt it to start another.
-  if (15==(data.self_test_exec_status >> 4)) {
-    PrintOut(LOG_INFO, "Device: %s, skip scheduled %sTest; %1d0%% remaining of current Self-Test.\n",
-             name, testname, (int)(data.self_test_exec_status & 0x0f));
-    return 1;
-  }
-
-  // else execute the test, and return status
-  if ((retval=smartcommandhandler(fd, IMMEDIATE_OFFLINE, dotest, NULL)))
-    PrintOut(LOG_CRIT, "Device: %s, execute %sTest failed.\n", name, testname);
-  else
-    PrintOut(LOG_INFO, "Device: %s, starting scheduled %sTest.\n", name, testname);
-  
-  return retval;
-}
-
-
-int ATACheckDevice(cfgfile *cfg){
-  int fd,i;
-  char *name=cfg->name;
-  char *mode="ATA";
-  
-  // fix firmware bug if requested
-  con->fixfirmwarebug=cfg->fixfirmwarebug;
-  con->controller_port=cfg->controller_port;
-  con->controller_type=cfg->controller_type;
-
-  // If user has asked, test the email warning system
-  if (cfg->mailwarn && cfg->mailwarn->emailtest)
-    MailWarning(cfg, 0, "TEST EMAIL from smartd for device: %s", name);
-
-  if (cfg->controller_type == CONTROLLER_3WARE_9000_CHAR)
-    mode="ATA_3WARE_9000";
-  
-  if (cfg->controller_type == CONTROLLER_3WARE_678K_CHAR)
-    mode="ATA_3WARE_678K";
-
-  // if we can't open device, fail gracefully rather than hard --
-  // perhaps the next time around we'll be able to open it.  ATAPI
-  // cd/dvd devices will hang awaiting media if O_NONBLOCK is not
-  // given (see linux cdrom driver).
-  if ((fd=OpenDevice(name, mode, 0))<0){
-    MailWarning(cfg, 9, "Device: %s, unable to open device", name);
-    return 1;
-  }
-
-  // user may have requested (with the -n Directive) to leave the disk
-  // alone if it is in idle or sleeping mode.  In this case check the
-  // power mode and exit without check if needed
-  if (cfg->powermode){
-    int dontcheck=0, powermode=ataCheckPowerMode(fd);
-    char *mode=NULL;
-        
-    switch (powermode){
-    case -1:
-      // SLEEP
-      mode="SLEEP";
-      if (cfg->powermode>=1)
-	dontcheck=1;
-      break;
-    case 0:
-      // STANDBY
-      mode="STANDBY";
-      if (cfg->powermode>=2)
-	dontcheck=1;
-      break;
-    case 0x80:
-      // IDLE
-      mode="IDLE";
-      if (cfg->powermode>=3)
-	dontcheck=1;
-      break;
-    case 0xff:
-      // ACTIVE/IDLE
-      break;
-    default:
-      // UNKNOWN
-      PrintOut(LOG_CRIT, "Device: %s, CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Directive\n",
-	       name, powermode);
-      cfg->powermode=0;
-      break;
-    }
-
-    // if we are going to skip a check, return now
-    if (dontcheck){
-      CloseDevice(fd, name);
-      PrintOut(LOG_INFO, "Device: %s, is in %s mode, skipping checks\n", name, mode);
-      return 0;
-    }    
-  }
-
-  // check smart status
-  if (cfg->smartcheck){
-    int status=ataSmartStatus2(fd);
-    if (status==-1){
-      PrintOut(LOG_INFO,"Device: %s, not capable of SMART self-check\n",name);
-      MailWarning(cfg, 5, "Device: %s, not capable of SMART self-check", name);
-    }
-    else if (status==1){
-      PrintOut(LOG_CRIT, "Device: %s, FAILED SMART self-check. BACK UP DATA NOW!\n", name);
-      MailWarning(cfg, 1, "Device: %s, FAILED SMART self-check. BACK UP DATA NOW!", name);
-    }
-  }
-  
-  // Check everything that depends upon SMART Data (eg, Attribute values)
-  if (cfg->usagefailed || cfg->prefail || cfg->usage || cfg->pending!=DONT_MONITOR_UNC){
-    struct ata_smart_values     curval;
-    struct ata_smart_thresholds_pvt *thresh=cfg->smartthres;
-    
-    // Read current attribute values. *drive contains old values and thresholds
-    if (ataReadSmartValues(fd,&curval)){
-      PrintOut(LOG_CRIT, "Device: %s, failed to read SMART Attribute Data\n", name);
-      MailWarning(cfg, 6, "Device: %s, failed to read SMART Attribute Data", name);
-    }
-    else {
-      // look for current or offline pending sectors
-      if (cfg->pending != DONT_MONITOR_UNC) {
-	int64_t rawval;
-	unsigned char currentpending, offlinepending;
-	
-	TranslatePending(cfg->pending, &currentpending, &offlinepending);
-	
-	if (currentpending && (rawval=ATAReturnAttributeRawValue(currentpending, &curval))>0) {
-	  // Unreadable pending sectors!!
-	  PrintOut(LOG_CRIT,   "Device: %s, %"PRId64" Currently unreadable (pending) sectors\n", name, rawval);
-	  MailWarning(cfg, 10, "Device: %s, %"PRId64" Currently unreadable (pending) sectors", name, rawval);
-	}
-	
-	if (offlinepending && (rawval=ATAReturnAttributeRawValue(offlinepending, &curval))>0) {
-	  // Unreadable offline sectors!!
-	  PrintOut(LOG_CRIT,   "Device: %s, %"PRId64" Offline uncorrectable sectors\n", name, rawval);
-	  MailWarning(cfg, 11, "Device: %s, %"PRId64" Offline uncorrectable sectors", name, rawval);
-	}
-      }
-
-      if (cfg->usagefailed || cfg->prefail || cfg->usage) {
-
-	// look for failed usage attributes, or track usage or prefail attributes
-	for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-	  int att;
-	  changedattribute_t delta;
-	  
-	  // This block looks for usage attributes that have failed.
-	  // Prefail attributes that have failed are returned with a
-	  // positive sign. No failure returns 0. Usage attributes<0.
-	  if (cfg->usagefailed && ((att=ataCheckAttribute(&curval, thresh, i))<0)){
-	    
-	    // are we ignoring failures of this attribute?
-	    att *= -1;
-	    if (!IsAttributeOff(att, &cfg->monitorattflags, 0, MONITOR_FAILUSE, __LINE__)){
-	      char attname[64], *loc=attname;
-	      
-	      // get attribute name & skip white space
-	      ataPrintSmartAttribName(loc, att, cfg->attributedefs);
-	      while (*loc && *loc==' ') loc++;
-	      
-	      // warning message
-	      PrintOut(LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc);
-	      MailWarning(cfg, 2, "Device: %s, Failed SMART usage Attribute: %s.", name, loc);
-	    }
-	  }
-	  
-	  // This block tracks usage or prefailure attributes to see if
-	  // they are changing.  It also looks for changes in RAW values
-	  // if this has been requested by user.
-	  if ((cfg->usage || cfg->prefail) && ATACompareValues(&delta, &curval, cfg->smartval, thresh, i, name)){
-	    unsigned char id=delta.id;
-	    
-	    // if the only change is the raw value, and we're not
-	    // tracking raw value, then continue loop over attributes
-	    if (!delta.sameraw && delta.newval==delta.oldval && !IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_RAW, __LINE__))
-	      continue;
-	    
-	    // are we tracking this attribute?
-	    if (!IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_IGNORE, __LINE__)){
-	      char newrawstring[64], oldrawstring[64], attname[64], *loc=attname;
-	      
-	      // get attribute name, skip spaces
-	      ataPrintSmartAttribName(loc, id, cfg->attributedefs);
-	      while (*loc && *loc==' ') loc++;
-	      
-	      // has the user asked for us to print raw values?
-	      if (IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_RAWPRINT, __LINE__)) {
-		// get raw values (as a string) and add to printout
-		char rawstring[64];
-		ataPrintSmartAttribRawValue(rawstring, curval.vendor_attributes+i, cfg->attributedefs);
-		sprintf(newrawstring, " [Raw %s]", rawstring);
-		ataPrintSmartAttribRawValue(rawstring, cfg->smartval->vendor_attributes+i, cfg->attributedefs);
-		sprintf(oldrawstring, " [Raw %s]", rawstring);
-	      }
-	      else
-		newrawstring[0]=oldrawstring[0]='\0';
-	      
-	      // prefailure attribute
-	      if (cfg->prefail && delta.prefail)
-		PrintOut(LOG_INFO, "Device: %s, SMART Prefailure Attribute: %s changed from %d%s to %d%s\n",
-			 name, loc, delta.oldval, oldrawstring, delta.newval, newrawstring);
-	      
-	      // usage attribute
-	      if (cfg->usage && !delta.prefail)
-		PrintOut(LOG_INFO, "Device: %s, SMART Usage Attribute: %s changed from %d%s to %d%s\n",
-			 name, loc, delta.oldval, oldrawstring, delta.newval, newrawstring);
-	    }
-	  } // endof block tracking usage or prefailure
-	} // end of loop over attributes
-	
-	// Save the new values into *drive for the next time around
-	*(cfg->smartval)=curval;
-      }
-    }
-  }
-  
-  // check if number of selftest errors has increased (note: may also DECREASE)
-  if (cfg->selftest)
-    CheckSelfTestLogs(cfg, SelfTestErrorCount(fd, name));
-  
-  // check if number of ATA errors has increased
-  if (cfg->errorlog){
-
-    int new,old=cfg->ataerrorcount;
-
-    // new number of errors
-    new=ATAErrorCount(fd, name);
-
-    // did command fail?
-    if (new<0)
-      // lack of PrintOut here is INTENTIONAL
-      MailWarning(cfg, 7, "Device: %s, Read SMART Error Log Failed", name);
-
-    // has error count increased?
-    if (new>old){
-      PrintOut(LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n",
-               name, old, new);
-      MailWarning(cfg, 4, "Device: %s, ATA error count increased from %d to %d",
-                   name, old, new);
-    }
-    
-    // this last line is probably not needed, count always increases
-    if (new>=0)
-      cfg->ataerrorcount=new;
-  }
-  
-  // if the user has asked, and device is capable (or we're not yet
-  // sure) carry out scheduled self-tests.
-  if (cfg->testdata) {
-    // long test
-    if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L')>0)
-      DoATASelfTest(fd, cfg, 'L');    
-    // short test
-    else if (!cfg->testdata->not_cap_short && DoTestNow(cfg, 'S')>0)
-      DoATASelfTest(fd, cfg, 'S');
-    // conveyance test
-    else if (!cfg->testdata->not_cap_conveyance && DoTestNow(cfg, 'C')>0)
-      DoATASelfTest(fd, cfg, 'C');
-    // offline immediate
-    else if (!cfg->testdata->not_cap_offline && DoTestNow(cfg, 'O')>0)
-      DoATASelfTest(fd, cfg, 'O');  
-  }
-  
-  // Don't leave device open -- the OS/user may want to access it
-  // before the next smartd cycle!
-  CloseDevice(fd, name);
-  return 0;
-}
-
-#define DEF_SCSI_REPORT_TEMPERATURE_DELTA 2
-static int scsi_report_temperature_delta = DEF_SCSI_REPORT_TEMPERATURE_DELTA;
-
-int SCSICheckDevice(cfgfile *cfg)
-{
-    UINT8 asc, ascq;
-    UINT8 currenttemp;
-    UINT8 triptemp;
-    int fd;
-    char *name=cfg->name;
-    const char *cp;
-
-    // If the user has asked for it, test the email warning system
-    if (cfg->mailwarn && cfg->mailwarn->emailtest)
-      MailWarning(cfg, 0, "TEST EMAIL from smartd for device: %s", name);
-
-    // if we can't open device, fail gracefully rather than hard --
-    // perhaps the next time around we'll be able to open it
-    if ((fd=OpenDevice(name, "SCSI", 0))<0) {
-      // Lack of PrintOut() here is intentional!
-      MailWarning(cfg, 9, "Device: %s, unable to open device", name);
-      return 1;
-    }
-    currenttemp = 0;
-    asc = 0;
-    ascq = 0;
-    if (! cfg->SuppressReport) {
-        if (scsiCheckIE(fd, cfg->SmartPageSupported, cfg->TempPageSupported,
-                        &asc, &ascq, &currenttemp, &triptemp)) {
-            PrintOut(LOG_INFO, "Device: %s, failed to read SMART values\n",
-                      name);
-            MailWarning(cfg, 6, "Device: %s, failed to read SMART values", name);
-            cfg->SuppressReport = 1;
-        }
-    }
-    if (asc > 0) {
-        cp = scsiGetIEString(asc, ascq);
-        if (cp) {
-            PrintOut(LOG_CRIT, "Device: %s, SMART Failure: %s\n", name, cp);
-            MailWarning(cfg, 1,"Device: %s, SMART Failure: %s", name, cp); 
-        }
-    } else if (debugmode)
-        PrintOut(LOG_INFO,"Device: %s, Acceptable asc,ascq: %d,%d\n", 
-                 name, (int)asc, (int)ascq);  
-  
-    if (currenttemp && currenttemp!=255) {
-        if (cfg->Temperature) {
-            if (abs(((int)currenttemp - (int)cfg->Temperature)) >= 
-                scsi_report_temperature_delta) {
-                PrintOut(LOG_INFO, "Device: %s, Temperature changed %d Celsius "
-                         "to %d Celsius since last report\n", name, 
-                         (int)(currenttemp - cfg->Temperature), 
-                         (int)currenttemp);
-                cfg->Temperature = currenttemp;
-            }
-        }
-        else {
-            PrintOut(LOG_INFO, "Device: %s, initial Temperature is %d "
-                     "Celsius\n", name, (int)currenttemp);
-           if (triptemp)
-                PrintOut(LOG_INFO, "    [trip Temperature is %d Celsius]\n",
-                         (int)triptemp);
-            cfg->Temperature = currenttemp;
-            cfg->Temperature = currenttemp;
-        }
-    }
-    
-    // check if number of selftest errors has increased (note: may also DECREASE)
-    if (cfg->selftest)
-      CheckSelfTestLogs(cfg, scsiCountFailedSelfTests(fd, 0));
-    
-    if (cfg->testdata) {
-      // long (extended) background test
-      if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L')>0)
-        DoSCSISelfTest(fd, cfg, 'L');
-      // short background test
-      else if (!cfg->testdata->not_cap_short && DoTestNow(cfg, 'S')>0)
-        DoSCSISelfTest(fd, cfg, 'S');
-    }
-    CloseDevice(fd, name);
-    return 0;
-}
-
-// Checks the SMART status of all ATA and SCSI devices
-void CheckDevicesOnce(cfgfile **atadevices, cfgfile **scsidevices){
-  int i;
-  
-  for (i=0; i<numdevata; i++) 
-    ATACheckDevice(atadevices[i]);
-  
-  for (i=0; i<numdevscsi; i++)
-    SCSICheckDevice(scsidevices[i]);
-
-  return;
-}
-
-#if SCSITIMEOUT
-// This alarm means that a SCSI USB device was hanging
-void AlarmHandler(int signal) {
-  longjmp(registerscsienv, 1);
-}
-#endif
-
-// Does initialization right after fork to daemon mode
-void Initialize(time_t *wakeuptime){
-
-  // install goobye message and remove pidfile handler
-  atexit(Goodbye);
-  
-  // write PID file only after installing exit handler
-  if (!debugmode)
-    WritePidFile();
-  
-  // install signal handlers.  On Solaris, can't use signal() because
-  // it resets the handler to SIG_DFL after each call.  So use sigset()
-  // instead.  So SIGNALFN()==signal() or SIGNALFN()==sigset().
-  
-  // normal and abnormal exit
-  if (SIGNALFN(SIGTERM, sighandler)==SIG_IGN)
-    SIGNALFN(SIGTERM, SIG_IGN);
-  if (SIGNALFN(SIGQUIT, sighandler)==SIG_IGN)
-    SIGNALFN(SIGQUIT, SIG_IGN);
-  
-  // in debug mode, <CONTROL-C> ==> HUP
-  if (SIGNALFN(SIGINT, debugmode?HUPhandler:sighandler)==SIG_IGN)
-    SIGNALFN(SIGINT, SIG_IGN);
-  
-  // Catch HUP and USR1
-  if (SIGNALFN(SIGHUP, HUPhandler)==SIG_IGN)
-    SIGNALFN(SIGHUP, SIG_IGN);
-  if (SIGNALFN(SIGUSR1, USR1handler)==SIG_IGN)
-    SIGNALFN(SIGUSR1, SIG_IGN);
-#ifdef _WIN32
-  if (SIGNALFN(SIGUSR2, USR2handler)==SIG_IGN)
-    SIGNALFN(SIGUSR2, SIG_IGN);
-#endif
-
-  // initialize wakeup time to CURRENT time
-  *wakeuptime=time(NULL);
-  
-  return;
-}
-
-#ifdef _WIN32
-// Toggle debug mode implemented for native windows only
-// (there is no easy way to reopen tty on *nix)
-static void ToggleDebugMode()
-{
-  if (!debugmode) {
-    PrintOut(LOG_INFO,"Signal USR2 - enabling debug mode\n");
-    if (!daemon_enable_console("smartd [Debug]")) {
-      debugmode = 1;
-      daemon_signal(SIGINT, HUPhandler);
-      PrintOut(LOG_INFO,"smartd debug mode enabled, PID=%d\n", getpid());
-    }
-    else
-      PrintOut(LOG_INFO,"enable console failed\n");
-  }
-  else if (debugmode == 1) {
-    daemon_disable_console();
-    debugmode = 0;
-    daemon_signal(SIGINT, sighandler);
-    PrintOut(LOG_INFO,"Signal USR2 - debug mode disabled\n");
-  }
-  else
-    PrintOut(LOG_INFO,"Signal USR2 - debug mode %d not changed\n", debugmode);
-}
-#endif
-
-time_t dosleep(time_t wakeuptime){
-  time_t timenow=0;
-  
-  // If past wake-up-time, compute next wake-up-time
-  timenow=time(NULL);
-  while (wakeuptime<=timenow){
-    int intervals=1+(timenow-wakeuptime)/checktime;
-    wakeuptime+=intervals*checktime;
-  }
-  
-  // sleep until we catch SIGUSR1 or have completed sleeping
-  while (timenow<wakeuptime && !caughtsigUSR1 && !caughtsigHUP && !caughtsigEXIT){
-    
-    // protect user again system clock being adjusted backwards
-    if (wakeuptime>timenow+checktime){
-      PrintOut(LOG_CRIT, "System clock time adjusted to the past. Resetting next wakeup time.\n");
-      wakeuptime=timenow+checktime;
-    }
-    
-    // Exit sleep when time interval has expired or a signal is received
-    sleep(wakeuptime-timenow);
-
-#ifdef _WIN32
-    // toggle debug mode?
-    if (caughtsigUSR2) {
-      ToggleDebugMode();
-      caughtsigUSR2 = 0;
-    }
-#endif
-
-    timenow=time(NULL);
-  }
- 
-  // if we caught a SIGUSR1 then print message and clear signal
-  if (caughtsigUSR1){
-    PrintOut(LOG_INFO,"Signal USR1 - checking devices now rather than in %d seconds.\n",
-             wakeuptime-timenow>0?(int)(wakeuptime-timenow):0);
-    caughtsigUSR1=0;
-  }
-  
-  // return adjusted wakeuptime
-  return wakeuptime;
-}
-
-// Print out a list of valid arguments for the Directive d
-void printoutvaliddirectiveargs(int priority, char d) {
-  char *s=NULL;
-
-  switch (d) {
-  case 'n':
-    PrintOut(priority, "never, sleep, standby, idle");
-    break;
-  case 's':
-    PrintOut(priority, "valid_regular_expression");
-    break;
-  case 'd':
-    PrintOut(priority, "ata, scsi, removable, 3ware,N");
-    break;
-  case 'T':
-    PrintOut(priority, "normal, permissive");
-    break;
-  case 'o':
-  case 'S':
-    PrintOut(priority, "on, off");
-    break;
-  case 'l':
-    PrintOut(priority, "error, selftest");
-    break;
-  case 'M':
-    PrintOut(priority, "\"once\", \"daily\", \"diminishing\", \"test\", \"exec\"");
-    break;
-  case 'v':
-    if (!(s = create_vendor_attribute_arg_list())) {
-      PrintOut(LOG_CRIT,"Insufficient memory to construct argument list\n");
-      EXIT(EXIT_NOMEM);
-    }
-    PrintOut(priority, "\n%s\n", s);
-    s=CheckFree(s, __LINE__,filenameandversion);
-    break;
-  case 'P':
-    PrintOut(priority, "use, ignore, show, showall");
-    break;
-  case 'F':
-    PrintOut(priority, "none, samsung, samsung2");
-    break;
-  }
-}
-
-// exits with an error message, or returns integer value of token
-int GetInteger(char *arg, char *name, char *token, int lineno, char *configfile, int min, int max){
-  char *endptr;
-  int val;
-  
-  // check input range
-  if (min<0){
-    PrintOut(LOG_CRIT, "min =%d passed to GetInteger() must be >=0\n", min);
-    return -1;
-  }
-
-  // make sure argument is there
-  if (!arg) {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s takes integer argument from %d to %d.\n",
-             configfile, lineno, name, token, min, max);
-    return -1;
-  }
-  
-  // get argument value (base 10), check that it's integer, and in-range
-  val=strtol(arg,&endptr,10);
-  if (*endptr!='\0' || val<min || val>max )  {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s has argument: %s; needs integer from %d to %d.\n",
-             configfile, lineno, name, token, arg, min, max);
-    return -1;
-  }
-
-  // all is well; return value
-  return val;
-}
-
-// This function returns 1 if it has correctly parsed one token (and
-// any arguments), else zero if no tokens remain.  It returns -1 if an
-// error was encountered.
-int ParseToken(char *token,cfgfile *cfg){
-  char sym;
-  char *name=cfg->name;
-  int lineno=cfg->lineno;
-  char *delim = " \n\t";
-  int badarg = 0;
-  int missingarg = 0;
-  char *arg = NULL;
-  int makemail=0;
-  maildata *mdat=NULL, tempmail;
-
-  // is the rest of the line a comment
-  if (*token=='#')
-    return 1;
-  
-  // is the token not recognized?
-  if (*token!='-' || strlen(token)!=2) {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n",
-             configfile, lineno, name, token);
-    PrintOut(LOG_CRIT, "Run smartd -D to print a list of valid Directives.\n");
-    return -1;
-  }
-  
-  // token we will be parsing:
-  sym=token[1];
-
-  // create temporary maildata structure.  This means we can postpone
-  // allocating space in the data segment until we are sure there are
-  // no errors.
-  if ('m'==sym || 'M'==sym){
-    if (!cfg->mailwarn){
-      memset(&tempmail, 0, sizeof(maildata));
-      mdat=&tempmail;
-      makemail=1;
-    }
-    else
-      mdat=cfg->mailwarn;
-  }
-
-  // parse the token and swallow its argument
-  switch (sym) {
-    int val;
-
-  case 'C':
-    // monitor current pending sector count (default 197)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 0, 255))<0)
-      return -1;
-    if (val==CUR_UNC_DEFAULT)
-      val=0;
-    else if (val==0)
-      val=CUR_UNC_DEFAULT;
-    // set bottom 8 bits to correct value
-    cfg->pending &= 0xff00;
-    cfg->pending |= val;
-    break;
-  case 'U':
-    // monitor offline uncorrectable sectors (default 198)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 0, 255))<0)
-      return -1;
-    if (val==OFF_UNC_DEFAULT)
-      val=0;
-    else if (val==0)
-      val=OFF_UNC_DEFAULT;
-    // turn off top 8 bits, then set to correct value
-    cfg->pending &= 0xff;
-    cfg->pending |= (val<<8);
-    break;
-  case 'T':
-    // Set tolerance level for SMART command failures
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "normal")) {
-      // Normal mode: exit on failure of a mandatory S.M.A.R.T. command, but
-      // not on failure of an optional S.M.A.R.T. command.
-      // This is the default so we don't need to actually do anything here.
-      cfg->permissive=0;
-    } else if (!strcmp(arg, "permissive")) {
-      // Permissive mode; ignore errors from Mandatory SMART commands
-      cfg->permissive=1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'd':
-    // specify the device type
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "ata")) {
-      cfg->controller_port = 0;
-      cfg->controller_type = CONTROLLER_ATA;
-    } else if (!strcmp(arg, "scsi")) {
-      cfg->controller_port =0;
-      cfg->controller_type = CONTROLLER_SCSI;
-    } else if (!strcmp(arg, "removable")) {
-      cfg->removable = 1;
-    } else {
-      // look 3ware,N RAID device
-      int i;
-      char *s;
-      
-      // make a copy of the string to mess with
-      if (!(s = strdup(arg))) {
-        PrintOut(LOG_CRIT,
-                 "No memory to copy argument to -d option - exiting\n");
-        EXIT(EXIT_NOMEM);
-      } else if (strncmp(s,"3ware,",6)) {
-        badarg=1;
-      } else if (split_report_arg2(s, &i)){
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n",
-                 configfile, lineno, name);
-        badarg=1;
-      } else if ( i<0 || i>15) {
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n",
-                 configfile, lineno, name, i);
-        badarg=1;
-      } else {
-	// determine type of escalade device from name of device
-	cfg->controller_type = guess_device_type(name);
-	if (cfg->controller_type!=CONTROLLER_3WARE_9000_CHAR && cfg->controller_type!=CONTROLLER_3WARE_678K_CHAR)
-	  cfg->controller_type=CONTROLLER_3WARE_678K;
-	    
-        // NOTE: controller_port == disk number + 1
-        cfg->controller_port = i+1;
-      }
-      s=CheckFree(s, __LINE__,filenameandversion); 
-    }
-    break;
-  case 'F':
-    // fix firmware bug
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "none")) {
-      cfg->fixfirmwarebug = FIX_NONE;
-    } else if (!strcmp(arg, "samsung")) {
-      cfg->fixfirmwarebug = FIX_SAMSUNG;
-    } else if (!strcmp(arg, "samsung2")) {
-      cfg->fixfirmwarebug = FIX_SAMSUNG2;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'H':
-    // check SMART status
-    cfg->smartcheck=1;
-    break;
-  case 'f':
-    // check for failure of usage attributes
-    cfg->usagefailed=1;
-    break;
-  case 't':
-    // track changes in all vendor attributes
-    cfg->prefail=1;
-    cfg->usage=1;
-    break;
-  case 'p':
-    // track changes in prefail vendor attributes
-    cfg->prefail=1;
-    break;
-  case 'u':
-    //  track changes in usage vendor attributes
-    cfg->usage=1;
-    break;
-  case 'l':
-    // track changes in SMART logs
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "selftest")) {
-      // track changes in self-test log
-      cfg->selftest=1;
-    } else if (!strcmp(arg, "error")) {
-      // track changes in ATA error log
-      cfg->errorlog=1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'a':
-    // monitor everything
-    cfg->smartcheck=1;
-    cfg->prefail=1;
-    cfg->usagefailed=1;
-    cfg->usage=1;
-    cfg->selftest=1;
-    cfg->errorlog=1;
-    break;
-  case 'o':
-    // automatic offline testing enable/disable
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "on")) {
-      cfg->autoofflinetest = 2;
-    } else if (!strcmp(arg, "off")) {
-      cfg->autoofflinetest = 1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'n':
-    // skip disk check if in idle or standby mode
-    if (!(arg = strtok(NULL, delim)))
-      missingarg = 1;
-    else if (!strcmp(arg, "never"))
-      cfg->powermode = 0;
-    else if (!strcmp(arg, "sleep"))
-      cfg->powermode = 1;
-    else if (!strcmp(arg, "standby"))
-      cfg->powermode = 2;
-    else if (!strcmp(arg, "idle"))
-      cfg->powermode = 3;
-    else
-      badarg = 1;
-    break;
-  case 'S':
-    // automatic attribute autosave enable/disable
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "on")) {
-      cfg->autosave = 2;
-    } else if (!strcmp(arg, "off")) {
-      cfg->autosave = 1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 's':
-    // warn user, and delete any previously given -s REGEXP Directives
-    if (cfg->testdata){
-      PrintOut(LOG_INFO, "File %s line %d (drive %s): ignoring previous Test Directive -s %s\n",
-               configfile, lineno, name, cfg->testdata->regex);
-      cfg->testdata=FreeTestData(cfg->testdata);
-    }
-    // check for missing argument
-    if (!(arg = strtok(NULL, delim))) {
-      missingarg = 1;
-    }
-    // allocate space for structure and string
-    else if (!(cfg->testdata=(testinfo *)Calloc(1, sizeof(testinfo))) || !(cfg->testdata->regex=CustomStrDup(arg, 1, __LINE__,filenameandversion))) {
-      PrintOut(LOG_INFO, "File %s line %d (drive %s): no memory to create Test Directive -s %s!\n",
-               configfile, lineno, name, arg);
-      EXIT(EXIT_NOMEM);
-    }
-    else if ((val=regcomp(&(cfg->testdata->cregex), arg, REG_EXTENDED))) {
-      char errormsg[512];
-      // not a valid regular expression!
-      regerror(val, &(cfg->testdata->cregex), errormsg, 512);
-      PrintOut(LOG_CRIT, "File %s line %d (drive %s): -s argument \"%s\" is INVALID extended regular expression. %s.\n",
-               configfile, lineno, name, arg, errormsg);
-      cfg->testdata=FreeTestData(cfg->testdata);
-      return -1;
-    }
-    // Do a bit of sanity checking and warn user if we think that
-    // their regexp is "strange". User probably confused about shell
-    // glob(3) syntax versus regular expression syntax regexp(7).
-    if ((int)strlen(arg) != (val=strspn(arg,"0123456789/.+*|()?^$[]SLCO")))
-      PrintOut(LOG_INFO,  "File %s line %d (drive %s): warning, character %d (%c) looks odd in extended regular expression %s\n",
-               configfile, lineno, name, val+1, arg[val], arg);
-    break;
-  case 'm':
-    // send email to address that follows
-    if (!(arg = strtok(NULL,delim)))
-      missingarg = 1;
-    else {
-      if (mdat->address) {
-        PrintOut(LOG_INFO, "File %s line %d (drive %s): ignoring previous Address Directive -m %s\n",
-                 configfile, lineno, name, mdat->address);
-        mdat->address=FreeNonZero(mdat->address, -1,__LINE__,filenameandversion);
-      }
-      mdat->address=CustomStrDup(arg, 1, __LINE__,filenameandversion);
-    }
-    break;
-  case 'M':
-    // email warning options
-    if (!(arg = strtok(NULL, delim)))
-      missingarg = 1;
-    else if (!strcmp(arg, "once"))
-      mdat->emailfreq = 1;
-    else if (!strcmp(arg, "daily"))
-      mdat->emailfreq = 2;
-    else if (!strcmp(arg, "diminishing"))
-      mdat->emailfreq = 3;
-    else if (!strcmp(arg, "test"))
-      mdat->emailtest = 1;
-    else if (!strcmp(arg, "exec")) {
-      // Get the next argument (the command line)
-      if (!(arg = strtok(NULL, delim))) {
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive %s 'exec' argument must be followed by executable path.\n",
-                 configfile, lineno, name, token);
-        return -1;
-      }
-      // Free the last cmd line given if any, and copy new one
-      if (mdat->emailcmdline) {
-        PrintOut(LOG_INFO, "File %s line %d (drive %s): ignoring previous mail Directive -M exec %s\n",
-                 configfile, lineno, name, mdat->emailcmdline);
-        mdat->emailcmdline=FreeNonZero(mdat->emailcmdline, -1,__LINE__,filenameandversion);
-      }
-      mdat->emailcmdline=CustomStrDup(arg, 1, __LINE__,filenameandversion);
-    } 
-    else
-      badarg = 1;
-    break;
-  case 'i':
-    // ignore failure of usage attribute
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_FAILUSE, __LINE__);
-    break;
-  case 'I':
-    // ignore attribute for tracking purposes
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_IGNORE, __LINE__);
-    break;
-  case 'r':
-    // print raw value when tracking
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
-    break;
-  case 'R':
-    // track changes in raw value (forces printing of raw value)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAW, __LINE__);
-    break;
-  case 'v':
-    // non-default vendor-specific attribute meaning
-    if (!(arg=strtok(NULL,delim))) {
-      missingarg = 1;
-    } else if (parse_attribute_def(arg, &cfg->attributedefs)){   
-      badarg = 1;
-    }
-    break;
-  case 'P':
-    // Define use of drive-specific presets.
-    if (!(arg = strtok(NULL, delim))) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "use")) {
-      cfg->ignorepresets = FALSE;
-    } else if (!strcmp(arg, "ignore")) {
-      cfg->ignorepresets = TRUE;
-    } else if (!strcmp(arg, "show")) {
-      cfg->showpresets = TRUE;
-    } else if (!strcmp(arg, "showall")) {
-      showallpresets();
-    } else {
-      badarg = 1;
-    }
-    break;
-  default:
-    // Directive not recognized
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n",
-             configfile, lineno, name, token);
-    Directives();
-    return -1;
-  }
-  if (missingarg) {
-    PrintOut(LOG_CRIT, "File %s line %d (drive %s): Missing argument to %s Directive\n",
-             configfile, lineno, name, token);
-  }
-  if (badarg) {
-    PrintOut(LOG_CRIT, "File %s line %d (drive %s): Invalid argument to %s Directive: %s\n",
-             configfile, lineno, name, token, arg);
-  }
-  if (missingarg || badarg) {
-    PrintOut(LOG_CRIT, "Valid arguments to %s Directive are: ", token);
-    printoutvaliddirectiveargs(LOG_CRIT, sym);
-    PrintOut(LOG_CRIT, "\n");
-    return -1;
-  }
-
-  // If this did something to fill the mail structure, and that didn't
-  // already exist, create it and copy.
-  if (makemail) {
-    if (!(cfg->mailwarn=(maildata *)Calloc(1, sizeof(maildata)))) {
-      PrintOut(LOG_INFO, "File %s line %d (drive %s): no memory to create mail warning entry!\n",
-               configfile, lineno, name);
-      EXIT(EXIT_NOMEM);
-    }
-    memcpy(cfg->mailwarn, mdat, sizeof(maildata));
-  }
-  
-  return 1;
-}
-
-// Allocate storage for a new cfgfile entry.  If original!=NULL, it's
-// a copy of the original, but with private data storage.  Else all is
-// zeroed.  Returns address, and fails if non memory available.
-
-cfgfile *CreateConfigEntry(cfgfile *original){
-  cfgfile *add;
-  
-  // allocate memory for new structure
-  if (!(add=(cfgfile *)Calloc(1,sizeof(cfgfile))))
-    goto badexit;
-  
-  // if old structure was pointed to, copy it
-  if (original)
-    memcpy(add, original, sizeof(cfgfile));
-  
-  // make private copies of data items ONLY if they are in use (non
-  // NULL)
-  add->name         = CustomStrDup(add->name,         0, __LINE__,filenameandversion);
-
-  if (add->testdata) {
-    int val;
-    if (!(add->testdata=(testinfo *)Calloc(1,sizeof(testinfo))))
-      goto badexit;
-    memcpy(add->testdata, original->testdata, sizeof(testinfo));
-    add->testdata->regex = CustomStrDup(add->testdata->regex,   1, __LINE__,filenameandversion);
-    // only POSIX-portable way to make fresh copy of compiled regex is
-    // to recompile it completely.  There is no POSIX
-    // compiled-regex-copy command.
-    if ((val=regcomp(&(add->testdata->cregex), add->testdata->regex, REG_EXTENDED))) {
-      char errormsg[512];
-      regerror(val, &(add->testdata->cregex), errormsg, 512);
-      PrintOut(LOG_CRIT, "unable to recompile regular expression %s. %s\n", add->testdata->regex, errormsg);
-      goto badexit;
-    }
-  }
-  
-  if (add->mailwarn) {
-    if (!(add->mailwarn=(maildata *)Calloc(1,sizeof(maildata))))
-      goto badexit;
-    memcpy(add->mailwarn, original->mailwarn, sizeof(maildata));
-    add->mailwarn->address      = CustomStrDup(add->mailwarn->address,      0, __LINE__,filenameandversion);
-    add->mailwarn->emailcmdline = CustomStrDup(add->mailwarn->emailcmdline, 0, __LINE__,filenameandversion);
-  }
-
-  if (add->attributedefs) {
-    if (!(add->attributedefs=(unsigned char *)Calloc(MAX_ATTRIBUTE_NUM,1)))
-      goto badexit;
-    memcpy(add->attributedefs, original->attributedefs, MAX_ATTRIBUTE_NUM);
-  }
-  
-  if (add->monitorattflags) {
-    if (!(add->monitorattflags=(unsigned char *)Calloc(NMONITOR*32, 1)))
-      goto badexit;
-    memcpy(add->monitorattflags, original->monitorattflags, NMONITOR*32);
-  }
-  
-  if (add->smartval) {
-    if (!(add->smartval=(struct ata_smart_values *)Calloc(1,sizeof(struct ata_smart_values))))
-      goto badexit;
-  }
-  
-  if (add->smartthres) {
-    if (!(add->smartthres=(struct ata_smart_thresholds_pvt *)Calloc(1,sizeof(struct ata_smart_thresholds_pvt))))
-      goto badexit;
-  }
-
-  return add;
-
- badexit:
-  PrintOut(LOG_CRIT, "No memory to create entry from configuration file\n");
-  EXIT(EXIT_NOMEM);
-}
-
-
-
-// This is the routine that adds things to the cfgentries list. To
-// prevent memory leaks when re-reading the configuration file many
-// times, this routine MUST deallocate any memory other than that
-// pointed to within cfg-> before it returns.
-//
-// Return values are:
-//  1: parsed a normal line
-//  0: found comment or blank line
-// -1: found SCANDIRECTIVE line
-// -2: found an error
-//
-// Note: this routine modifies *line from the caller!
-int ParseConfigLine(int entry, int lineno,char *line){
-  char *token=NULL;
-  char *name=NULL;
-  char *delim = " \n\t";
-  cfgfile *cfg=NULL;
-  int devscan=0;
-
-  // get first token: device name. If a comment, skip line
-  if (!(name=strtok(line,delim)) || *name=='#') {
-    return 0;
-  }
-
-  // Have we detected the SCANDIRECTIVE directive?
-  if (!strcmp(SCANDIRECTIVE,name)){
-    devscan=1;
-    if (entry) {
-      PrintOut(LOG_INFO,"Scan Directive %s (line %d) must be the first entry in %s\n",name, lineno, configfile);
-      return -2;
-    }
-  }
-  
-  // Is there space for another entry?  If not, allocate more
-  while (entry>=cfgentries_max)
-    cfgentries=AllocateMoreSpace(cfgentries, &cfgentries_max, "configuration file device");
-
-  // We've got a legit entry, make space to store it
-  cfg=cfgentries[entry]=CreateConfigEntry(NULL);
-  cfg->name = CustomStrDup(name, 1, __LINE__,filenameandversion);
-
-  // Store line number, and by default check for both device types.
-  cfg->lineno=lineno;
-  
-  // Try and recognize if a IDE or SCSI device.  These can be
-  // overwritten by configuration file directives.
-  if (cfg->controller_type==CONTROLLER_UNKNOWN)
-    cfg->controller_type = guess_device_type(cfg->name);
-  
-  // parse tokens one at a time from the file.
-  while ((token=strtok(NULL,delim))){
-    int retval=ParseToken(token,cfg);
-    
-    if (retval==0)
-      // No tokens left:
-      break;
-    
-    if (retval>0) {
-      // Parsed token  
-#if (0)
-      PrintOut(LOG_INFO,"Parsed token %s\n",token);
-#endif
-      continue;
-    }
-    
-    if (retval<0) {
-      // error found on the line
-      return -2;
-    }
-  }
-  
-  // If we found 3ware controller, then modify device name by adding a SPACE
-  if (cfg->controller_port){
-    int len=17+strlen(cfg->name);
-    char *newname;
-    
-    if (devscan){
-      PrintOut(LOG_CRIT, "smartd: can not scan for 3ware devices (line %d of file %s)\n",
-               lineno, configfile);
-      return -2;
-    }
-    
-    if (!(newname=(char *)calloc(len,1))) {
-      PrintOut(LOG_INFO,"No memory to parse file: %s line %d, %s\n", configfile, lineno, strerror(errno));
-      EXIT(EXIT_NOMEM);
-    }
-    
-    // Make new device name by adding a space then RAID disk number
-    snprintf(newname, len, "%s [3ware_disk_%02d]", cfg->name, cfg->controller_port-1);
-    cfg->name=CheckFree(cfg->name, __LINE__,filenameandversion);
-    cfg->name=newname;
-    bytes+=16;
-  }
-
-  // If NO monitoring directives are set, then set all of them.
-  if (!(cfg->smartcheck || cfg->usagefailed || cfg->prefail  || 
-        cfg->usage      || cfg->selftest    || cfg->errorlog   )){
-    
-    PrintOut(LOG_INFO,"Drive: %s, implied '-a' Directive on line %d of file %s\n",
-             cfg->name, cfg->lineno, configfile);
-    
-    cfg->smartcheck=1;
-    cfg->usagefailed=1;
-    cfg->prefail=1;
-    cfg->usage=1;
-    cfg->selftest=1;
-    cfg->errorlog=1;
-  }
-  
-  // additional sanity check. Has user set -M options without -m?
-  if (cfg->mailwarn && !cfg->mailwarn->address && (cfg->mailwarn->emailcmdline || cfg->mailwarn->emailfreq || cfg->mailwarn->emailtest)){
-    PrintOut(LOG_CRIT,"Drive: %s, -M Directive(s) on line %d of file %s need -m ADDRESS Directive\n",
-             cfg->name, cfg->lineno, configfile);
-    return -2;
-  }
-  
-  // has the user has set <nomailer>?
-  if (cfg->mailwarn && cfg->mailwarn->address && !strcmp(cfg->mailwarn->address,"<nomailer>")){
-    // check that -M exec is also set
-    if (!cfg->mailwarn->emailcmdline){
-      PrintOut(LOG_CRIT,"Drive: %s, -m <nomailer> Directive on line %d of file %s needs -M exec Directive\n",
-               cfg->name, cfg->lineno, configfile);
-      return -2;
-    }
-    // now free memory.  From here on the sign of <nomailer> is
-    // address==NULL and cfg->emailcmdline!=NULL
-    cfg->mailwarn->address=FreeNonZero(cfg->mailwarn->address, -1,__LINE__,filenameandversion);
-  }
-
-  // set cfg->emailfreq to 1 (once) if user hasn't set it
-  if (cfg->mailwarn && !cfg->mailwarn->emailfreq)
-    cfg->mailwarn->emailfreq = 1;
-
-  entry++;
-
-  if (devscan)
-    return -1;
-  else
-    return 1;
-}
-
-// clean up utility for ParseConfigFile()
-void cleanup(FILE **fpp, int is_stdin){
-  if (*fpp){
-    // (*fpp != stdin) does not work here if stdin has been closed & reopened
-    if (!is_stdin)
-      fclose(*fpp);
-    *fpp=NULL;
-  }
-
-  return;
-}
-
-
-// Parses a configuration file.  Return values are:
-//  N=>0: found N entries
-// -1:    syntax error in config file
-// -2:    config file does not exist
-// -3:    config file exists but cannot be read
-//
-// In the case where the return value is 0, there are three
-// possiblities:
-// Empty configuration file ==> cfgentries==NULL
-// No configuration file    ==> cfgentries[0]->lineno == 0
-// SCANDIRECTIVE found      ==> cfgentries[0]->lineno != 0
-int ParseConfigFile(){
-  FILE *fp=NULL;
-  int entry=0,lineno=1,cont=0,contlineno=0;
-  char line[MAXLINELEN+2];
-  char fullline[MAXCONTLINE+1];
-
-  int is_stdin = (configfile == configfile_stdin); // pointer comparison ok here
-
-  // Open config file, if it exists and is not <stdin>
-  if (!is_stdin) {
-    fp=fopen(configfile,"r");
-    if (fp==NULL && (errno!=ENOENT || configfile_alt)) {
-      // file exists but we can't read it or it should exist due to '-c' option
-      int ret = (errno!=ENOENT ? -3 : -2);
-      PrintOut(LOG_CRIT,"%s: Unable to open configuration file %s\n",
-               strerror(errno),configfile);
-      return ret;
-    }
-  }
-  else // read from stdin ('-c -' option)
-    fp = stdin;
-  
-  // No configuration file found -- use fake one
-  if (fp==NULL) {
-    int len=strlen(SCANDIRECTIVE)+4;
-    char *fakeconfig=(char *)calloc(len,1);
-  
-    if (!fakeconfig || 
-        (len-1) != snprintf(fakeconfig, len, "%s -a", SCANDIRECTIVE) ||
-        -1 != ParseConfigLine(entry, 0, fakeconfig)
-        ) {
-      PrintOut(LOG_CRIT,"Internal error in ParseConfigFile() at line %d of file %s\n%s", 
-               __LINE__, filenameandversion, reportbug);
-      EXIT(EXIT_BADCODE);
-    }
-    fakeconfig=CheckFree(fakeconfig, __LINE__,filenameandversion);
-    return 0;
-  }
-    
-  // configuration file exists
-  PrintOut(LOG_INFO,"Opened configuration file %s\n",configfile);
-
-  // parse config file line by line
-  while (1) {
-    int len=0,scandevice;
-    char *lastslash;
-    char *comment;
-    char *code;
-
-    // make debugging simpler
-    memset(line,0,sizeof(line));
-
-    // get a line
-    code=fgets(line,MAXLINELEN+2,fp);
-    
-    // are we at the end of the file?
-    if (!code){
-      if (cont) {
-        scandevice=ParseConfigLine(entry,contlineno,fullline);
-        // See if we found a SCANDIRECTIVE directive
-        if (scandevice==-1) {
-          cleanup(&fp, is_stdin);
-          return 0;
-        }
-        // did we find a syntax error
-        if (scandevice==-2) {
-          cleanup(&fp, is_stdin);
-          return -1;
-        }
-        // the final line is part of a continuation line
-        cont=0;
-        entry+=scandevice;
-      }
-      break;
-    }
-
-    // input file line number
-    contlineno++;
-    
-    // See if line is too long
-    len=strlen(line);
-    if (len>MAXLINELEN){
-      char *warn;
-      if (line[len-1]=='\n')
-        warn="(including newline!) ";
-      else
-        warn="";
-      PrintOut(LOG_CRIT,"Error: line %d of file %s %sis more than MAXLINELEN=%d characters.\n",
-               (int)contlineno,configfile,warn,(int)MAXLINELEN);
-      cleanup(&fp, is_stdin);
-      return -1;
-    }
-
-    // Ignore anything after comment symbol
-    if ((comment=strchr(line,'#'))){
-      *comment='\0';
-      len=strlen(line);
-    }
-
-    // is the total line (made of all continuation lines) too long?
-    if (cont+len>MAXCONTLINE){
-      PrintOut(LOG_CRIT,"Error: continued line %d (actual line %d) of file %s is more than MAXCONTLINE=%d characters.\n",
-               lineno, (int)contlineno, configfile, (int)MAXCONTLINE);
-      cleanup(&fp, is_stdin);
-      return -1;
-    }
-    
-    // copy string so far into fullline, and increment length
-    strcpy(fullline+cont,line);
-    cont+=len;
-
-    // is this a continuation line.  If so, replace \ by space and look at next line
-    if ( (lastslash=strrchr(line,'\\')) && !strtok(lastslash+1," \n\t")){
-      *(fullline+(cont-len)+(lastslash-line))=' ';
-      continue;
-    }
-
-    // Not a continuation line. Parse it
-    scandevice=ParseConfigLine(entry,contlineno,fullline);
-
-    // did we find a scandevice directive?
-    if (scandevice==-1) {
-      cleanup(&fp, is_stdin);
-      return 0;
-    }
-    // did we find a syntax error
-    if (scandevice==-2) {
-      cleanup(&fp, is_stdin);
-      return -1;
-    }
-
-    entry+=scandevice;
-    lineno++;
-    cont=0;
-  }
-  cleanup(&fp, is_stdin);
-  
-  // note -- may be zero if syntax of file OK, but no valid entries!
-  return entry;
-}
-
-
-// Prints copyright, license and version information
-void PrintCopyleft(void){
-  debugmode=1;
-  PrintHead();
-  PrintCVS();
-  return;
-}
-
-/* Prints the message "=======> VALID ARGUMENTS ARE: <LIST>  <=======\n", where
-   <LIST> is the list of valid arguments for option opt. */
-void PrintValidArgs(char opt) {
-  const char *s;
-
-  PrintOut(LOG_CRIT, "=======> VALID ARGUMENTS ARE: ");
-  if (!(s = GetValidArgList(opt)))
-    PrintOut(LOG_CRIT, "Error constructing argument list for option %c", opt);
-  else
-    PrintOut(LOG_CRIT, (char *)s);
-  PrintOut(LOG_CRIT, " <=======\n");
-}
-
-// Parses input line, prints usage message and
-// version/license/copyright messages
-void ParseOpts(int argc, char **argv){
-  extern char *optarg;
-  extern int  optopt, optind, opterr;
-  int optchar;
-  int badarg;
-  char *tailptr;
-  long lchecktime;
-  // Please update GetValidArgList() if you edit shortopts
-  const char *shortopts = "c:l:q:dDi:p:r:Vh?";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update GetValidArgList() if you edit longopts
-  struct option longopts[] = {
-    { "configfile",     required_argument, 0, 'c' },
-    { "logfacility",    required_argument, 0, 'l' },
-    { "quit",           required_argument, 0, 'q' },
-    { "debug",          no_argument,       0, 'd' },
-    { "showdirectives", no_argument,       0, 'D' },
-    { "interval",       required_argument, 0, 'i' },
-    { "pidfile",        required_argument, 0, 'p' },
-    { "report",         required_argument, 0, 'r' },
-#ifdef _WIN32
-    { "service",        no_argument,       0, 'S' },
-#endif
-    { "version",        no_argument,       0, 'V' },
-    { "license",        no_argument,       0, 'V' },
-    { "copyright",      no_argument,       0, 'V' },
-    { "help",           no_argument,       0, 'h' },
-    { "usage",          no_argument,       0, 'h' },
-    { 0,                0,                 0, 0   }
-  };
-#endif
-  
-  opterr=optopt=0;
-  badarg=FALSE;
-  
-  // Parse input options.  This horrible construction is so that emacs
-  // indents properly.  Sorry.
-  while (-1 != (optchar = 
-#ifdef HAVE_GETOPT_LONG
-                getopt_long(argc, argv, shortopts, longopts, NULL)
-#else
-                getopt(argc, argv, shortopts)
-#endif
-                )) {
-    
-    switch(optchar) {
-    case 'q':
-      // when to quit
-      if (!(strcmp(optarg,"nodev"))) {
-        quit=0;
-      } else if (!(strcmp(optarg,"nodevstartup"))) {
-        quit=1;
-      } else if (!(strcmp(optarg,"never"))) {
-        quit=2;
-      } else if (!(strcmp(optarg,"onecheck"))) {
-        quit=3;
-        debugmode=1;
-      } else if (!(strcmp(optarg,"errors"))) {
-        quit=4;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'l':
-      // set the log facility level
-      if (!strcmp(optarg, "daemon"))
-        facility=LOG_DAEMON;
-      else if (!strcmp(optarg, "local0"))
-        facility=LOG_LOCAL0;
-      else if (!strcmp(optarg, "local1"))
-        facility=LOG_LOCAL1;
-      else if (!strcmp(optarg, "local2"))
-        facility=LOG_LOCAL2;
-      else if (!strcmp(optarg, "local3"))
-        facility=LOG_LOCAL3;
-      else if (!strcmp(optarg, "local4"))
-        facility=LOG_LOCAL4;
-      else if (!strcmp(optarg, "local5"))
-        facility=LOG_LOCAL5;
-      else if (!strcmp(optarg, "local6"))
-        facility=LOG_LOCAL6;
-      else if (!strcmp(optarg, "local7"))
-        facility=LOG_LOCAL7;
-      else
-        badarg = TRUE;
-      break;
-    case 'd':
-      // enable debug mode
-      debugmode = TRUE;
-      break;
-    case 'D':
-      // print summary of all valid directives
-      debugmode = TRUE;
-      Directives();
-      EXIT(0);
-      break;
-    case 'i':
-      // Period (time interval) for checking
-      // strtol will set errno in the event of overflow, so we'll check it.
-      errno = 0;
-      lchecktime = strtol(optarg, &tailptr, 10);
-      if (*tailptr != '\0' || lchecktime < 10 || lchecktime > INT_MAX || errno) {
-        debugmode=1;
-        PrintHead();
-        PrintOut(LOG_CRIT, "======> INVALID INTERVAL: %s <=======\n", optarg);
-        PrintOut(LOG_CRIT, "======> INTERVAL MUST BE INTEGER BETWEEN %d AND %d <=======\n", 10, INT_MAX);
-        PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-      checktime = (int)lchecktime;
-      break;
-    case 'r':
-      // report IOCTL transactions
-      {
-        int i;
-        char *s;
-
-        // split_report_arg() may modify its first argument string, so use a
-        // copy of optarg in case we want optarg for an error message.
-        if (!(s = strdup(optarg))) {
-          PrintOut(LOG_CRIT, "No memory to process -r option - exiting\n");
-          EXIT(EXIT_NOMEM);
-        }
-        if (split_report_arg(s, &i)) {
-          badarg = TRUE;
-        } else if (i<1 || i>3) {
-          debugmode=1;
-          PrintHead();
-          PrintOut(LOG_CRIT, "======> INVALID REPORT LEVEL: %s <=======\n", optarg);
-          PrintOut(LOG_CRIT, "======> LEVEL MUST BE INTEGER BETWEEN 1 AND 3<=======\n");
-          EXIT(EXIT_BADCMD);
-        } else if (!strcmp(s,"ioctl")) {
-          con->reportataioctl  = con->reportscsiioctl = i;
-        } else if (!strcmp(s,"ataioctl")) {
-          con->reportataioctl = i;
-        } else if (!strcmp(s,"scsiioctl")) {
-          con->reportscsiioctl = i;
-        } else {
-          badarg = TRUE;
-        }
-        s=CheckFree(s, __LINE__,filenameandversion);
-      }
-      break;
-    case 'c':
-      // alternate configuration file
-      if (strcmp(optarg,"-"))
-        configfile=configfile_alt=CustomStrDup(optarg, 1, __LINE__,filenameandversion);
-      else // read from stdin
-        configfile=configfile_stdin;
-      break;
-    case 'p':
-      // output file with PID number
-      pid_file=CustomStrDup(optarg, 1, __LINE__,filenameandversion);
-      break;
-#ifdef _WIN32
-    case 'S':
-      // running as service, option already handled by deamon_main(), so ignore it
-      break;
-#endif
-    case 'V':
-      // print version and CVS info
-      PrintCopyleft();
-      EXIT(0);
-      break;
-    case 'h':
-      // help: print summary of command-line options
-      debugmode=1;
-      PrintHead();
-      Usage();
-      EXIT(0);
-      break;
-    case '?':
-    default:
-      // unrecognized option
-      debugmode=1;
-      PrintHead();
-#ifdef HAVE_GETOPT_LONG
-      // Point arg to the argument in which this option was found.
-      arg = argv[optind-1];
-      // Check whether the option is a long option that doesn't map to -h.
-      if (arg[1] == '-' && optchar != 'h') {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (optopt && (strchr(shortopts, optopt) != NULL)) {
-          PrintOut(LOG_CRIT, "=======> ARGUMENT REQUIRED FOR OPTION: %s <=======\n",arg+2);
-          PrintValidArgs(optopt);
-        } else {
-          PrintOut(LOG_CRIT, "=======> UNRECOGNIZED OPTION: %s <=======\n\n",arg+2);
-        }
-        PrintOut(LOG_CRIT, "\nUse smartd --help to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (strchr(shortopts, optopt) != NULL){
-          PrintOut(LOG_CRIT, "=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n",optopt);
-          PrintValidArgs(optopt);
-        } else {
-          PrintOut(LOG_CRIT, "=======> UNRECOGNIZED OPTION: %c <=======\n\n",optopt);
-        }
-        PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-      Usage();
-      EXIT(0);
-    }
-
-    // Check to see if option had an unrecognized or incorrect argument.
-    if (badarg) {
-      debugmode=1;
-      PrintHead();
-      // It would be nice to print the actual option name given by the user
-      // here, but we just print the short form.  Please fix this if you know
-      // a clean way to do it.
-      PrintOut(LOG_CRIT, "=======> INVALID ARGUMENT TO -%c: %s <======= \n", optchar, optarg);
-      PrintValidArgs(optchar);
-      PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-      EXIT(EXIT_BADCMD);
-    }
-  }
-
-  // non-option arguments are not allowed
-  if (argc > optind) {
-    debugmode=1;
-    PrintHead();
-    PrintOut(LOG_CRIT, "=======> UNRECOGNIZED ARGUMENT: %s <=======\n\n", argv[optind]);
-    PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-    EXIT(EXIT_BADCMD);
-  }
-
-  // no pidfile in debug mode
-  if (debugmode && pid_file) {
-    debugmode=1;
-    PrintHead();
-    PrintOut(LOG_CRIT, "=======> INVALID CHOICE OF OPTIONS: -d and -p <======= \n\n");
-    PrintOut(LOG_CRIT, "Error: pid file %s not written in debug (-d) mode\n\n", pid_file);
-    pid_file=FreeNonZero(pid_file, -1,__LINE__,filenameandversion);
-    EXIT(EXIT_BADCMD);
-  }
-  
-  // print header
-  PrintHead();
-  
-  return;
-}
-
-// Function we call if no configuration file was found or if the
-// SCANDIRECTIVE Directive was found.  It makes entries for device
-// names returned by make_device_names() in os_OSNAME.c
-int MakeConfigEntries(const char *type, int start){
-  int i;
-  int num;
-  char** devlist = NULL;
-  cfgfile *first=cfgentries[0],*cfg=first;
-
-  // make list of devices
-  if ((num=make_device_names(&devlist,type))<0)
-    PrintOut(LOG_CRIT,"Problem creating device name scan list\n");
-  
-  // if no devices, or error constructing list, return
-  if (num<=0)
-    return 0;
-  
-  // loop over entries to create
-  for (i=0; i<num; i++){
-    
-    // make storage and copy for all but first entry
-    if (start+i) {
-      // allocate more storage if needed
-      while (cfgentries_max<=start+i)
-        cfgentries=AllocateMoreSpace(cfgentries, &cfgentries_max, "simulated configuration file device");
-      cfg=cfgentries[start+i]=CreateConfigEntry(first);
-    }
-
-    // ATA or SCSI?
-    if (!strcmp(type,"ATA") )
-      cfg->controller_type = CONTROLLER_ATA;
-    if (!strcmp(type,"SCSI") ) 
-      cfg->controller_type = CONTROLLER_SCSI;
-    
-    // remove device name, if it's there, and put in correct one
-    cfg->name=FreeNonZero(cfg->name, -1,__LINE__,filenameandversion);
-    // save pointer to the device name created within
-    // make_device_names
-    cfg->name=devlist[i];
-  }
-  
-  // If needed, free memory used for devlist: pointers now in
-  // cfgentries[]->names.  If num==0 we never get to this point, but
-  // that's OK.  If we realloc()d the array length in
-  // make_device_names() that was ALREADY equivalent to calling
-  // free().
-  devlist = FreeNonZero(devlist,(sizeof (char*) * num),__LINE__, filenameandversion);
-  
-  return num;
-}
- 
-void CanNotRegister(char *name, char *type, int line, int scandirective){
-  if( !debugmode && scandirective == 1 ) { return; }
-  if (line)
-    PrintOut(scandirective?LOG_INFO:LOG_CRIT,
-             "Unable to register %s device %s at line %d of file %s\n",
-             type, name, line, configfile);
-  else
-    PrintOut(LOG_INFO,"Unable to register %s device %s\n",
-             type, name);
-  return;
-}
-
-// Returns negative value (see ParseConfigFile()) if config file
-// had errors, else number of entries which may be zero or positive. 
-// If we found no configuration file, or it contained SCANDIRECTIVE,
-// then *scanning is set to 1, else 0.
-int ReadOrMakeConfigEntries(int *scanning){
-  int entries;
-  
-  // deallocate any cfgfile data structures in memory
-  RmAllConfigEntries();
-  
-  // parse configuration file configfile (normally /etc/smartd.conf)  
-  if ((entries=ParseConfigFile())<0) {
- 
-    // There was an error reading the configuration file.
-    RmAllConfigEntries();
-    if (entries == -1)
-      PrintOut(LOG_CRIT, "Configuration file %s has fatal syntax errors.\n", configfile);
-    return entries;
-  }
-
-  // did we find entries or scan?
-  *scanning=0;
-  
-  // no error parsing config file.
-  if (entries) {
-    // we did not find a SCANDIRECTIVE and did find valid entries
-    PrintOut(LOG_INFO, "Configuration file %s parsed.\n", configfile);
-  }
-  else if (cfgentries && cfgentries[0]) {
-    // we found a SCANDIRECTIVE or there was no configuration file so
-    // scan.  Configuration file's first entry contains all options
-    // that were set
-    cfgfile *first=cfgentries[0];
-    int doata  = !(first->controller_type==CONTROLLER_SCSI);
-    int doscsi = !(first->controller_type==CONTROLLER_ATA);
-    
-    *scanning=1;
-    
-    if (first->lineno)
-      PrintOut(LOG_INFO,"Configuration file %s was parsed, found %s, scanning devices\n", configfile, SCANDIRECTIVE);
-    else
-      PrintOut(LOG_INFO,"No configuration file %s found, scanning devices\n", configfile);
-    
-    // make config list of ATA devices to search for
-    if (doata)
-      entries+=MakeConfigEntries("ATA", entries);
-    // make config list of SCSI devices to search for
-    if (doscsi)
-      entries+=MakeConfigEntries("SCSI", entries);
-
-    // warn user if scan table found no devices
-    if (!entries) {
-      PrintOut(LOG_CRIT,"In the system's table of devices NO devices found to scan\n");
-      // get rid of fake entry with SCANDIRECTIVE as name
-      RmConfigEntry(cfgentries, __LINE__);
-    }
-  } 
-  else
-    PrintOut(LOG_CRIT,"Configuration file %s parsed but has no entries (like /dev/hda)\n",configfile);
-  
-  return entries;
-}
-
-
-// This function tries devices from cfgentries.  Each one that can be
-// registered is moved onto the [ata|scsi]devices lists and removed
-// from the cfgentries list, else it's memory is deallocated.
-void RegisterDevices(int scanning){
-  int i;
-  
-  // start by clearing lists/memory of ALL existing devices
-  RmAllDevEntries();
-  numdevata=numdevscsi=0;
-  
-  // Register entries
-  for (i=0; i<cfgentries_max ; i++){
-    
-    cfgfile *ent=cfgentries[i];
-    
-    // skip any NULL entries (holes)
-    if (!ent)
-      continue;
-    
-    // register ATA devices
-    if (ent->controller_type!=CONTROLLER_SCSI){
-      if (ATADeviceScan(ent, scanning))
-        CanNotRegister(ent->name, "ATA", ent->lineno, scanning);
-      else {
-        // move onto the list of ata devices
-        cfgentries[i]=NULL;
-        while (numdevata>=atadevlist_max)
-          atadevlist=AllocateMoreSpace(atadevlist, &atadevlist_max, "ATA device");
-        atadevlist[numdevata++]=ent;
-      }
-    }
-    
-    // then register SCSI devices
-    if (ent->controller_type==CONTROLLER_SCSI || ent->controller_type==CONTROLLER_UNKNOWN){
-      int retscsi=0;
-
-#if SCSITIMEOUT
-      struct sigaction alarmAction, defaultaction;
-
-      // Set up an alarm handler to catch USB devices that hang on
-      // SCSI scanning...
-      alarmAction.sa_handler= AlarmHandler;
-      alarmAction.sa_flags  = SA_RESTART;
-      if (sigaction(SIGALRM, &alarmAction, &defaultaction)) {
-        // if we can't set timeout, just scan device
-        PrintOut(LOG_CRIT, "Unable to initialize SCSI timeout mechanism.\n");
-        retscsi=SCSIDeviceScan(ent, scanning);
-      }
-      else {
-        // prepare return point in case of bad SCSI device
-        if (setjmp(registerscsienv))
-          // SCSI device timed out!
-          retscsi=-1;
-        else {
-        // Set alarm, make SCSI call, reset alarm
-          alarm(SCSITIMEOUT);
-          retscsi=SCSIDeviceScan(ent, scanning);
-          alarm(0);
-        }
-        if (sigaction(SIGALRM, &defaultaction, NULL)){
-          PrintOut(LOG_CRIT, "Unable to clear SCSI timeout mechanism.\n");
-        }
-      }
-#else
-      retscsi=SCSIDeviceScan(ent, scanning);
-#endif   
-
-      // Now scan SCSI device...
-      if (retscsi){
-        if (retscsi<0)
-          PrintOut(LOG_CRIT, "Device %s timed out (poorly-implemented USB device?)\n", ent->name);
-        CanNotRegister(ent->name, "SCSI", ent->lineno, scanning);
-      }
-      else {
-        // move onto the list of scsi devices
-        cfgentries[i]=NULL;
-        while (numdevscsi>=scsidevlist_max)
-          scsidevlist=AllocateMoreSpace(scsidevlist, &scsidevlist_max, "SCSI device");
-        scsidevlist[numdevscsi++]=ent;
-      }
-    }
-    
-    // if device is explictly listed and we can't register it, then
-    // exit unless the user has specified that the device is removable
-    if (cfgentries[i]  && !scanning){
-      if (ent->removable || quit==2)
-        PrintOut(LOG_INFO, "Device %s not available\n", ent->name);
-      else {
-        PrintOut(LOG_CRIT, "Unable to register device %s (no Directive -d removable). Exiting.\n", ent->name);
-        EXIT(EXIT_BADDEV);
-      }
-    }
-    
-    // free up memory if device could not be registered
-    RmConfigEntry(cfgentries+i, __LINE__);
-  }
-  
-  return;
-}
-
-
-#ifndef _WIN32
-// Main function
-int main(int argc, char **argv)
-#else
-// Windows: internal main function started direct or by service control manager
-static int smartd_main(int argc, char **argv)
-#endif
-{
-  // external control variables for ATA disks
-  smartmonctrl control;
-
-  // is it our first pass through?
-  int firstpass=1;
-
-  // next time to wake up
-  time_t wakeuptime;
-
-  // for simplicity, null all global communications variables/lists
-  con=&control;
-  memset(con,        0,sizeof(control));
-
-  // parse input and print header and usage info if needed
-  ParseOpts(argc,argv);
-  
-  // do we mute printing from ataprint commands?
-  con->printing_switchable=0;
-  con->dont_print=debugmode?0:1;
-  
-  // don't exit on bad checksums
-  con->checksumfail=0;
-  
-  // the main loop of the code
-  while (1){
-
-    // are we exiting from a signal?
-    if (caughtsigEXIT) {
-      // are we exiting with SIGTERM?
-      int isterm=(caughtsigEXIT==SIGTERM);
-      int isquit=(caughtsigEXIT==SIGQUIT);
-      int isok=debugmode?isterm || isquit:isterm;
-      
-      PrintOut(isok?LOG_INFO:LOG_CRIT, "smartd received signal %d: %s\n",
-               caughtsigEXIT, strsignal(caughtsigEXIT));
-      
-      EXIT(isok?0:EXIT_SIGNAL);
-    }
-
-    // Should we (re)read the config file?
-    if (firstpass || caughtsigHUP){
-      int entries, scanning=0;
-
-      if (!firstpass) {
-#ifdef __CYGWIN__
-        // Workaround for missing SIGQUIT via keyboard on Cygwin
-        if (caughtsigHUP==2) {
-          // Simulate SIGQUIT if another SIGINT arrives soon
-          caughtsigHUP=0;
-          sleep(1);
-          if (caughtsigHUP==2) {
-            caughtsigEXIT=SIGQUIT;
-            continue;
-          }
-          caughtsigHUP=2;
-        }
-#endif
-        PrintOut(LOG_INFO,
-                 caughtsigHUP==1?
-                 "Signal HUP - rereading configuration file %s\n":
-                 "\a\nSignal INT - rereading configuration file %s ("SIGQUIT_KEYNAME" quits)\n\n",
-                 configfile);
-      }
-
-      // clears cfgentries, (re)reads config file, makes >=0 entries
-      entries=ReadOrMakeConfigEntries(&scanning);
-
-      if (entries>=0) {
-        // checks devices, then moves onto ata/scsi list or deallocates.
-        RegisterDevices(scanning);
-      }
-      else if (quit==2 || ((quit==0 || quit==1) && !firstpass)) {
-        // user has asked to continue on error in configuration file
-        if (!firstpass)
-          PrintOut(LOG_INFO,"Reusing previous configuration\n");
-      }
-      else {
-        // exit with configuration file error status
-        int status = (entries==-3 ? EXIT_READCONF : entries==-2 ? EXIT_NOCONF : EXIT_BADCONF);
-        EXIT(status);
-      }
-
-      // Log number of devices we are monitoring...
-      if (numdevata+numdevscsi || quit==2 || (quit==1 && !firstpass))
-        PrintOut(LOG_INFO,"Monitoring %d ATA and %d SCSI devices\n",
-                 numdevata, numdevscsi);
-      else {
-        PrintOut(LOG_INFO,"Unable to monitor any SMART enabled devices. Try debug (-d) option. Exiting...\n");
-        EXIT(EXIT_NODEV);
-      }   
-      
-      // reset signal
-      caughtsigHUP=0;
-    }
-
-    // check all devices once
-    CheckDevicesOnce(atadevlist, scsidevlist); 
-    
-    // user has asked us to exit after first check
-    if (quit==3) {
-      PrintOut(LOG_INFO,"Started with '-q onecheck' option. All devices sucessfully checked once.\n"
-               "smartd is exiting (exit status 0)\n");
-      EXIT(0);
-    }
-    
-    // fork into background if needed
-    if (firstpass && !debugmode)
-      DaemonInit();
-    
-    // set exit and signal handlers, write PID file, set wake-up time
-    if (firstpass){
-      Initialize(&wakeuptime);
-      firstpass=0;
-    }
-    
-    // sleep until next check time, or a signal arrives
-    wakeuptime=dosleep(wakeuptime);
-  }
-}
-
-
-#ifdef _WIN32
-// Main function for Windows
-int main(int argc, char **argv){
-  // Options for smartd windows service
-  static const daemon_winsvc_options svc_opts = {
-    "--service", // cmd_opt
-    "smartd", "SmartD Service", // servicename, displayname
-    // description
-    "Controls and monitors storage devices using the Self-Monitoring, "
-    "Analysis and Reporting Technology System (S.M.A.R.T.) "
-    "built into ATA and SCSI Hard Drives. "
-    PACKAGE_HOMEPAGE
-  };
-  // daemon_main() handles daemon and service specific commands
-  // and starts smartd_main() direct, from a new process,
-  // or via service control manager
-  return daemon_main("smartd", &svc_opts , smartd_main, argc, argv);
-}
-#endif
diff --git a/sm5/smartd.conf b/sm5/smartd.conf
deleted file mode 100644
index 6e450eeba816bfb5ebcded53f170a0eaf799540e..0000000000000000000000000000000000000000
--- a/sm5/smartd.conf
+++ /dev/null
@@ -1,92 +0,0 @@
-# Sample configuration file for smartd.  See man smartd.conf.
-
-# Home page is: http://smartmontools.sourceforge.net
-
-# $Id: smartd.conf,v 1.37 2004/08/04 05:32:44 ballen4705 Exp $
-
-# smartd will re-read the configuration file if it receives a HUP
-# signal
-
-# The file gives a list of devices to monitor using smartd, with one
-# device per line. Text after a hash (#) is ignored, and you may use
-# spaces and tabs for white space. You may use '\' to continue lines.
-
-# You can usually identify which hard disks are on your system by
-# looking in /proc/ide and in /proc/scsi.
-
-# The word DEVICESCAN will cause any remaining lines in this
-# configuration file to be ignored: it tells smartd to scan for all
-# ATA and SCSI devices.  DEVICESCAN may be followed by any of the
-# Directives listed below, which will be applied to all devices that
-# are found.  Most users should comment out DEVICESCAN and explicitly
-# list the devices that they wish to monitor.
-DEVICESCAN
-
-# First (primary) ATA/IDE hard disk.  Monitor all attributes, enable
-# automatic online data collection, automatic Attribute autosave, and
-# do a short self-test every day at 2am, and a long self test
-# Saturdays at 3am.
-#/dev/hda -a -o on -S on -s (S/../.././02|L/../../6/03)
-
-# Monitor SMART status, ATA Error Log, Self-test log, and track
-# changes in all attributes except for attribute 194
-#/dev/hdb -H -l error -l selftest -t -I 194 
-
-# A very silent check.  Only report SMART health status if it fails
-# But send an email in this case
-#/dev/hdc -H -m admin@example.com
-
-# First two SCSI disks.  This will monitor everything that smartd can
-# monitor.  Do extended self-tests Wednesdays at 6pm and Sundays at 1 am
-#/dev/sda -d scsi -s L/../../3/18
-#/dev/sdb -d scsi -s L/../../7/01
-
-# Monitor 4 ATA disks connected to a 3ware 6/7/8000 controller which uses
-# the 3w-xxxx driver. Do a long self-tests Sundays at 1, 2, 3, and 4 am
-# Note: one can also use the /dev/twe0 character device interface.
-#/dev/sdc -d 3ware,0 -a -s L/../../7/01
-#/dev/sdc -d 3ware,1 -a -s L/../../7/02
-#/dev/sdc -d 3ware,2 -a -s L/../../7/03
-#/dev/sdc -d 3ware,3 -a -s L/../../7/04
-
-# Monitor 2 ATA disks connected to a 3ware 9000 controller which uses
-# the 3w-9xxx driver. Do a long self-tests Tuesdays at 1 and 3 am
-#/dev/twa0 -d 3ware,0 -a -s L/../../2/01
-#/dev/twa0 -d 3ware,1 -a -s L/../../2/03
-
-# HERE IS A LIST OF DIRECTIVES FOR THIS CONFIGURATION FILE.
-# PLEASE SEE THE smartd.conf MAN PAGE FOR DETAILS
-#
-#   -d TYPE Set the device type: ata, scsi, removable, 3ware,N
-#   -T TYPE set the tolerance to one of: normal, permissive
-#   -o VAL  Enable/disable automatic offline tests (on/off)
-#   -S VAL  Enable/disable attribute autosave (on/off)
-#   -n MODE No check. MODE is one of: never, sleep, standby, idle
-#   -H      Monitor SMART Health Status, report if failed
-#   -l TYPE Monitor SMART log.  Type is one of: error, selftest
-#   -f      Monitor for failure of any 'Usage' Attributes
-#   -m ADD  Send warning email to ADD for -H, -l error, -l selftest, and -f
-#   -M TYPE Modify email warning behavior (see man page)
-#   -s REGE Do self-test when type/date matches regular expression (see man page)
-#   -p      Report changes in 'Prefailure' Normalized Attributes
-#   -u      Report changes in 'Usage' Normalized Attributes
-#   -t      Equivalent to -p and -u Directives
-#   -r ID   Also report Raw values of Attribute ID with -p, -u or -t
-#   -R ID   Track changes in Attribute ID Raw value with -p, -u or -t
-#   -i ID   Ignore Attribute ID for -f Directive
-#   -I ID   Ignore Attribute ID for -p, -u or -t Directive
-#   -C ID   Report if Current Pending Sector count non-zero
-#   -U ID   Report if Offline Uncorrectable count non-zero
-#   -v N,ST Modifies labeling of Attribute N (see man page)
-#   -a      Default: equivalent to -H -f -t -l error -l selftest -C 197 -U 198
-#   -F TYPE Use firmware bug workaround. Type is one of: none, samsung
-#   -P TYPE Drive-specific presets: use, ignore, show, showall
-#    #      Comment: text after a hash sign is ignored
-#    \      Line continuation character
-# Attribute ID is a decimal integer 1 <= ID <= 255
-# except for -C and -U, where ID = 0 turns them off.
-# All but -d, -m and -M Directives are only implemented for ATA devices
-#
-# If the test string DEVICESCAN is the first uncommented text
-# then smartd will scan for devices /dev/hd[a-l] and /dev/sd[a-z]
-# DEVICESCAN may be followed by any desired Directives.
diff --git a/sm5/smartd.conf.5.in b/sm5/smartd.conf.5.in
deleted file mode 100644
index a7c59397c185bb43cdd3584765aa9a858913f97e..0000000000000000000000000000000000000000
--- a/sm5/smartd.conf.5.in
+++ /dev/null
@@ -1,1209 +0,0 @@
-.ig
-Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
-$Id: smartd.conf.5.in,v 1.58 2004/08/08 14:32:07 ballen4705 Exp $
-
-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, write to the Free Software Foundation, Inc., 675
-Mass Ave, Cambridge, MA 02139, USA.
-
-This code was originally developed as a Senior Thesis by Michael Cornwell
-at the Concurrent Systems Laboratory (now part of the Storage Systems
-Research Center), Jack Baskin School of Engineering, University of
-California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-..
-.TH SMARTD.CONF 5 CURRENT_CVS_DATE CURRENT_CVS_VERSION CURRENT_CVS_DATE
-.SH NAME
-\fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File\fP
-
-.SH FULL PATH
-.B /etc/smartd.conf
-
-.SH PACKAGE VERSION
-CURRENT_CVS_VERSION released CURRENT_CVS_DATE at CURRENT_CVS_TIME
-
-.SH DESCRIPTION
-\fB/etc/smartd.conf\fP is the configuration file for the \fBsmartd\fP
-daemon, which monitors the Self-Monitoring, Analysis and Reporting
-Technology (SMART) system built into many ATA-3 and later ATA, IDE and
-SCSI-3 hard drives.
-
-If the configuration file \fB/etc/smartd.conf\fP is present,
-\fBsmartd\fP reads it at startup, before \fBfork\fP(2)ing into the
-background. If \fBsmartd\fP subsequently receives a \fBHUP\fP signal,
-it will then re-read the configuration file.  If \fBsmartd\fP is
-running in debug mode, then an \fBINT\fP signal will also make it
-re-read the configuration file. This signal can be generated by typing
-\fB\<CONTROL-C\>\fP in the terminal window where \fBsmartd\fP is
-running.
-
-.\" DO NOT MODIFY THIS OR THE FOLLOWING TWO LINES. WHAT FOLLOWS
-.\" IS AUTOMATICALLY INCLUDED FROM THE FILE smartd.8.in
-.\" STARTINCLUDE
-
-.SH CONFIGURATION FILE /etc/smartd.conf
-In the absence of a configuration file,
-\fBsmartd\fP 
-will try to open the 20 ATA devices 
-.B /dev/hd[a-t] 
-and the 26 SCSI devices
-.B /dev/sd[a-z]
-under Linux. Under FreeBSD, 
-\fBsmartd\fP
-will try to open all existing ATA devices (with entries in /dev)
-.B /dev/ad[0-9]+
-and all existing SCSI devices
-.B /dev/da[0-9]+.
-This can be annoying if you have an ATA or SCSI device that hangs or
-misbehaves when receiving SMART commands.  Even if this causes no
-problems, you may be annoyed by the string of error log messages about
-block-major devices that can\'t be found, and SCSI devices that can\'t
-be opened.
-
-One can avoid this problem, and gain more control over the types of
-events monitored by
-\fBsmartd\fP,
-by using the configuration file
-.B /etc/smartd.conf.
-This file contains a list of devices to monitor, with one device per
-line.  An example file is included with the
-.B smartmontools
-distribution. You will find this sample configuration file in
-\fB/usr/share/doc/smartmontools-5.1/\fP. For security, the configuration file
-should not be writable by anyone but root. The syntax of the file is as
-follows:
-.IP \(bu 4
-There should be one device listed per line, although you may have
-lines that are entirely comments or white space.
-.IP \(bu 4
-Any text following a hash sign \'#\' and up to the end of the line is
-taken to be a comment, and ignored.
-.IP \(bu 4
-Lines may be continued by using a backslash \'\e\' as the last
-non-whitespace or non-comment item on a line.
-.IP \(bu 4
-Note: a line whose first character is a hash sign \'#\' is treated as
-a white-space blank line, \fBnot\fP as a non-existent line, and will
-\fBend\fP a continuation line.
-.PP 0
-.fi
-Here is an example configuration file.  It\'s for illustrative purposes
-only; please don\'t copy it onto your system without reading to the end
-of the
-.B DIRECTIVES
-Section below!
-
-.nf
-.B ################################################
-.B # This is an example smartd startup config
-.B # file /etc/smartd.conf for monitoring three ATA
-.B # disks, three SCSI disks, and six ATA disks
-.B # behind two 3ware controllers.
-.B #
-.nf
-.B # First ATA disk on each of two interfaces. On
-.B # the second disk, do a long self-test every
-.B # Sunday at 3am.
-.B #
-.B \ \ /dev/hda -a -m admin@example.com,root@localhost 
-.B \ \ /dev/hdc -a -I 194 -I 5 -i 12 -s L/../../7/03
-.B #
-.nf
-.B # SCSI disks.  Send a TEST warning email to admin on
-.B # startup.
-.B #
-.B \ \ /dev/sda
-.B \ \ /dev/sdb -m admin@example.com -M test
-.B #
-.nf
-.B # Strange device.  It\'s SCSI. Do a scheduled
-.B # long self test at 5am Monday/Thursday
-.B \ \ /dev/weird -d scsi -s L/../../(1|4)/05
-.B #
-.nf
-.B # Four ATA disks on a 3ware 6/7/8000 controller.
-.B # Do short self-tests daily at midnight, 1, 2, and 3 am
-.B # (Note that the syntax /dev/twe0 is also allowed.)
-.B \ \ /dev/sdc -d 3ware,0 -a -s S/../.././00
-.B \ \ /dev/sdc -d 3ware,1 -a -s S/../.././01
-.B \ \ /dev/sdd -d 3ware,2 -a -s S/../.././02
-.B \ \ /dev/sdd -d 3ware,3 -a -s S/../.././03
-.B #
-.nf
-.B # Two ATA disks on a 3ware 9000 controller.
-.B # Do long self-tests Sundays at midnight and 2 am
-.B \ \ /dev/twa0 -d 3ware,0 -a -s L/../../7/00
-.B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
-.B #
-.nf
-.B # The following line enables monitoring of the 
-.B # ATA Error Log and the Self-Test Error Log.  
-.B # It also tracks changes in both Prefailure
-.B # and Usage Attributes, apart from Attributes
-.B # 9, 194, and 231, and shows  continued lines:
-.B #
-.B \ \ /dev/hdd\ -l\ error\ \e
-.B \ \ \ \ \ \ \ \ \ \ \ -l\ selftest\ \e
-.B \ \ \ \ \ \ \ \ \ \ \ -t\ \e\ \ \ \ \ \ # Attributes not tracked:
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 194\ \e\ \ # temperature
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 231\ \e\ \ # also temperature
-.B \ \ \ \ \ \ \ \ \ \ \ -I 9\ \ \ \ \ \ # power-on hours
-.B #
-.B ################################################
-.fi
-
-.PP 
-.SH CONFIGURATION FILE DIRECTIVES
-.PP
-
-If the first non-comment entry in the configuration file is the text
-string
-.B DEVICESCAN
-in capital letters, then
-\fBsmartd\fP
-will ignore any remaining lines in the configuration file, and will
-scan for devices.
-.B DEVICESCAN
-may optionally be followed by Directives that will apply to all
-devices that are found in the scan.  Please see below for additional
-details.
-
-.sp 2
-The following are the Directives that may appear following the device
-name or
-.B DEVICESCAN
-on any line of the
-.B /etc/smartd.conf
-configuration file. Note that
-.B these are NOT command-line options for 
-\fBsmartd\fP.
-The Directives below may appear in any order, following the device
-name. 
-
-.B For an ATA device,
-if no Directives appear, then the device will be monitored
-as if the \'\-a\' Directive (monitor all SMART properties) had been given.
-
-.B If a SCSI disk is listed,
-it will be monitored at the maximum implemented level: roughly
-equivalent to using the \'\-H \-l selftest\' options for an ATA disk.
-So with the exception of \'\-d\', \'\-m\', \'\-l selftest\', \'\-s\', and
-\'\-M\', the Directives below are ignored for SCSI disks.  For SCSI
-disks, the \'\-m\' Directive sends a warning email if the SMART status
-indicates a disk failure or problem, if the SCSI inquiry about disk
-status fails, or if new errors appear in the self-test log.
-
-.B If a 3ware controller is used
-then the corresponding SCSI (/dev/sd?) or character device (/dev/twe?
-or /dev/twa?) must be listed, along with the \'\-d 3ware,N\' Directive
-(see below).  The individual ATA disks hosted by the 3ware controller
-appear to \fBsmartd\fP as normal ATA devices.  Hence all the ATA
-directives can be used for these disks (but see note below).
-
-.TP
-.B \-d TYPE
-Specifies the type of the device.  This Directive may be used multiple times
-for one device, but the arguments \fIata\fP, \fIscsi\fP, and \fI3ware,N\fP are
-mutually-exclusive. If more than one is given then
-\fBsmartd\fP
-will use the last one which appears.
-
-If none of these three arguments is given, then \fBsmartd\fP will
-first attempt to guess the device type by looking at whether the sixth
-character in the device name is an \'s\' or an \'h\'.  This will work for
-device names like /dev/hda or /dev/sdb, and corresponds to choosing
-\fIata\fP or \fIscsi\fP respectively. If
-\fBsmartd\fP
-can\'t guess from this sixth character, then it will simply try to
-access the device using first ATA and then SCSI ioctl()s.
-
-The valid arguments to this Directive are:
-
-.I ata
-\- the device type is ATA.  This prevents
-\fBsmartd\fP
-from issuing SCSI commands to an ATA device.
-
-.I scsi
-\- the device type is SCSI.  This prevents
-\fBsmartd\fP
-from issuing ATA commands to a SCSI device.
-
-.I 3ware,N
-\- the device consists of one or more ATA disks connected to a 3ware
-RAID controller. The non-negative integer N (in the range from 0 to 15
-inclusive) denotes which disk on the controller is monitored.  In log
-files and email messages this disk will be identified as 3ware_disk_XX
-with XX in the range from 00 to 15 inclusive.
-
-This Directive may at first appear confusing, because the 3ware
-controller is a SCSI device (such as /dev/sda) and should be listed as
-such in the the configuration file.
-However when the \'\-d 3ware,N\'
-Directive is used, then the corresponding disk is addressed using
-native ATA commands which are \'passed through\' the SCSI driver. All
-ATA Directives listed in this man page may be used.  Note that while
-you may use \fBany\fP of the 3ware SCSI logical devices /dev/sd? to
-address \fBany\fP of the physical disks (3ware ports), error and log
-messages will make the most sense if you always list the 3ware SCSI
-logical device corresponding to the particular physical disks.  Please
-see the \fBsmartctl\fP man page for further details.
-
-ATA disks behind 3ware controllers may alternatively be accessed via a
-character device interface /dev/twe0-15 (3ware 6000/7000/8000
-controllers) and /dev/twa0-15 (3ware 9000 series controllers).  Note
-that the 9000 series controllers may \fBonly\fP be accessed using the
-character device interface /dev/twa0-15 and not the SCSI device
-interface /dev/sd?.  Please see the \fBsmartctl\fP man page for
-further details.
-
-Note that older 3w-xxxx drivers do not pass the \'Enable Autosave\'
-(\fB-S on\fP) and \'Enable Automatic Offline\' (\fB-o on\fP) commands
-to the disk, if the SCSI interface is used, and produce these types of
-harmless syslog error messages instead: \fB\'3w-xxxx: tw_ioctl():
-Passthru size (123392) too big\'\fP. This can be fixed by upgrading to
-version 1.02.00.037 or later of the 3w-xxxx driver, or by applying a
-patch to older versions.  See
-\fBhttp://smartmontools.sourceforge.net/\fP for instructions.
-Alternatively use the character device interfaces /dev/twe0-15 (3ware
-6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series
-controllers).
-
-
-.B 3ware controllers are currently ONLY supported under Linux.
-
-.I removable
-\- the device or its media is removable.  This indicates to
-\fBsmartd\fP
-that it should continue (instead of exiting, which is the default
-behavior) if the device does not appear to be present when
-\fBsmartd\fP is started.  This Directive may be used in conjunction
-with the other \'\-d\' Directives.
-
-.TP
-.B \-n POWERMODE
-This \'nocheck\' Directive is used to prevent a disk from being
-spun-up when it is periodically polled by \fBsmartd\fP.
-
-ATA disks have five different power states. In order of increasing
-power consumption they are: \'OFF\', \'SLEEP\', \'STANDBY\', \'IDLE\',
-and \'ACTIVE\'.  Typically in the OFF, SLEEP, and STANDBY modes the
-disk\'s platters are not spinning. But usually, in response to SMART
-commands issued by \fBsmartd\fP, the disk platters are spun up.  So if
-this option is not used, then a disk which is in a low\-power mode may
-be spun up and put into a higher\-power mode when it is periodically
-polled by \fBsmartd\fP.
-
-Note that if the disk is in SLEEP mode when \fBsmartd\fP is started,
-then it won't respond to \fBsmartd\fP commands, and so the disk won't
-be registered as a device for \fBsmartd\fP to monitor. If a disk is in
-any other low\-power mode, then the commands issued by \fBsmartd\fP to
-register the disk will probably cause it to spin\-up.
-
-The \'\fB\-n\fP\' (nocheck) Directive specifies if \fBsmartd\fP\'s
-periodic checks should still be carried out when the device is in a
-low\-power mode.  It may be used to prevent a disk from being spun\-up
-by periodic \fBsmartd\fP polling.  The allowed values of POWERMODE
-are:
-
-.I never
-\- \fBsmartd\fP will poll (check) the device regardless of its power
-mode. This may cause a disk which is spun\-down to be spun\-up when
-\fBsmartd\fP checks it.  This is the default behavior if the '\-n'
-Directive is not given.
-
-.I sleep
-\- check the device unless it is in SLEEP mode.
-
-.I standby
-\- check the device unless it is in SLEEP or STANDBY mode.  In
-these modes most disks are not spinning, so if you want to prevent
-a laptop disk from spinning up each time that \fBsmartd\fP polls,
-this is probably what you want.
-
-.I idle
-\- check the device unless it is in SLEEP, STANDBY or IDLE mode.
-In the IDLE state, most disks are still spinning, so this is probably
-not what you want.
-
-
-.TP
-.B \-T TYPE
-Specifies how tolerant
-\fBsmartd\fP
-should be of SMART command failures.  The valid arguments to this
-Directive are:
-
-.I normal
-\- do not try to monitor the disk if a mandatory SMART command fails, but
-continue if an optional SMART command fails.  This is the default.
-
-.I permissive
-\- try to monitor the disk even if it appears to lack SMART
-capabilities.  This may be required for some old disks (prior to
-ATA\-3 revision 4) that implemented SMART before the SMART standards
-were incorporated into the ATA/ATAPI Specifications.  This may also be
-needed for some Maxtor disks which fail to comply with the ATA
-Specifications and don't properly indicate support for error\- or
-self\-test logging.
-
-[Please see the \fBsmartctl \-T\fP command-line option.]
-.TP
-.B \-o VALUE
-Enables or disables SMART Automatic Offline Testing when
-\fBsmartd\fP
-starts up and has no further effect.  The valid arguments to this
-Directive are \fIon\fP and \fIoff\fP.
-
-The delay between tests is vendor-specific, but is typically four
-hours.
-
-Note that SMART Automatic Offline Testing is \fBnot\fP part of the ATA
-Specification.  Please see the
-.B smartctl \-o
-command-line option documentation for further information about this
-feature.
-.TP
-.B \-S VALUE
-Enables or disables Attribute Autosave when \fBsmartd\fP
-starts up and has no further effect.  The valid arguments to this
-Directive are \fIon\fP and \fIoff\fP.  Also affects SCSI devices.
-[Please see the \fBsmartctl \-S\fP command-line option.]
-.TP
-.B \-H
-Check the SMART health status of the disk.  If any Prefailure
-Attributes are less than or equal to their threshold values, then disk
-failure is predicted in less than 24 hours, and a message at loglevel
-.B \'LOG_CRITICAL\'
-will be logged to syslog.  [Please see the
-.B smartctl \-H
-command-line option.]
-.TP
-.B \-l TYPE
-Reports increases in the number of errors in one of the two SMART logs.  The
-valid arguments to this Directive are:
-
-.I error
-\- report if the number of ATA errors reported in the ATA Error Log
-has increased since the last check.
-
-.I selftest
-\- report if the number of failed tests reported in the SMART
-Self-Test Log has increased since the last check, or if the timestamp
-associated with the most recent failed test has increased.  Note that
-such errors will \fBonly\fP be logged if you run self-tests on the
-disk (and it fails a test!).  Self-Tests can be run automatically by
-\fBsmartd\fP: please see the \fB\'\-s\'\fP Directive below.
-Self-Tests can also be run manually by using the \fB\'\-t\ short\'\fP
-and \fB\'\-t\ long\'\fP options of \fBsmartctl\fP and the results of
-the testing can be observed using the \fBsmartctl \'\-l\ selftest\'\fP
-command-line option.]
-
-[Please see the \fBsmartctl \-l\fP and \fB\-t\fP command-line
-options.]
-.TP
-.B \-s REGEXP
-Run Self-Tests or Offline Immediate Tests, at scheduled times.  A
-Self- or Offline Immediate Test will be run at the end of periodic
-device polling, if all 12 characters of the string \fBT/MM/DD/d/HH\fP
-match the extended regular expression \fBREGEXP\fP. Here:
-.RS 7
-.IP \fBT\fP 4
-is the type of the test.  The values that \fBsmartd\fP will try to
-match (in turn) are: \'L\' for a \fBL\fPong Self-Test, \'S\' for a
-\fBS\fPhort Self-Test, \'C\' for a \fBC\fPonveyance Self-Test (ATA
-only), and \'O\' for an \fBO\fPffline Immediate Test (ATA only).  As
-soon as a match is found, the test will be started and no additional
-matches will be sought for that device and that polling cycle.
-.IP \fBMM\fP 4
-is the month of the year, expressed with two decimal digits.  The
-range is from 01 (January) to 12 (December) inclusive.  Do \fBnot\fP
-use a single decimal digit or the match will always fail!
-.IP \fBDD\fP 4
-is the day of the month, expressed with two decimal digits. The
-range is from 01 to 31 inclusive.  Do \fBnot\fP
-use a single decimal digit or the match will always fail!
-.IP \fBd\fP 4
-is the day of the week, expressed with one decimal digit.  The
-range is from 1 (Monday) to 7 (Sunday) inclusive.
-.IP \fBHH\fP 4
-is the hour of the day, written with two decimal digits, and given in
-hours after midnight.  The range is 00 (midnight to just before 1am)
-to 23 (11pm to just before midnight) inclusive.  Do \fBnot\fP use a
-single decimal digit or the match will always fail!
-.RE
-.\"  The following two lines are a workaround for a man2html bug.  Please leave them.
-.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
-.TP
-.B \&
-Some examples follow.  In reading these, keep in mind that in extended
-regular expressions a dot \fB\'.\'\fP matches any single character, and
-a parenthetical expression such as \fB\'(A|B|C)\'\fP denotes any one of the three possibilities \fBA\fP,
-\fBB\fP, or \fBC\fP.
-
-To schedule a short Self-Test between 2-3am every morning, use:
-.nf
-\fB \-s S/../.././02\fP
-.fi
-To schedule a long Self-Test between 4-5am every Sunday morning, use:
-.nf
-\fB \-s L/../../7/04\fP
-.fi
-To schedule a long Self-Test between 10-11pm on the first and
-fifteenth day of each month, use:
-.nf
-\fB \-s L/../(01|15)/./22\fP
-.fi
-To schedule an Offline Immediate test after every midnight, 6am,
-noon,and 6pm, plus a Short Self-Test daily at 1-2am and a Long
-Self-Test every Saturday at 3-4am, use:
-.nf
-\fB \-s (O/../.././(00|06|12|18)|S/../.././01|L/../../6/03)\fP
-.fi
-
-Scheduled tests are run immediately following the regularly-scheduled
-device polling, if the current local date, time, and test type, match
-\fBREGEXP\fP.  By default the regularly-scheduled device polling
-occurs every thirty minutes after starting \fBsmartd\fP.  Take caution
-if you use the \'\-i\' option to make this polling interval more than
-sixty minutes: the poll times may fail to coincide with any of the
-testing times that you have specified with \fBREGEXP\fP, and so the
-self tests may not take place as you wish.
-
-Before running an offline or self-test, \fBsmartd\fP checks to be sure
-that a self-test is not already running.  If a self-test \fBis\fP
-already running, then this running self test will \fBnot\fP be
-interrupted to begin another test.
-
-\fBsmartd\fP will not attempt to run \fBany\fP type of test if another
-test was already started or run in the same hour.
-
-Each time a test is run, \fBsmartd\fP will log an entry to SYSLOG.
-You can use these to verify that you constructed \fBREGEXP\fP
-correctly.  The matching order (\fBL\fP before \fBS\fP before \fBC\fP
-before \fBO\fP) ensures that if multiple test types are all scheduled
-for the same hour, the longer test type has precedence.  This is
-usually the desired behavior.
-
-Unix users: please beware that the rules for extended regular
-expressions [regex(7)] are \fBnot\fP the same as the rules for
-file\-name pattern matching by the shell [glob(7)].  \fBsmartd\fP will
-issue harmless informational warning messages if it detects characters
-in \fBREGEXP\fP that appear to indicate that you have made this
-mistake.
-
-.TP
-.B \-m ADD
-Send a warning email to the email address \fBADD\fP if the \'\-H\',
-\'\-l\', \'\-f\', \'\-C\', or \'\-O\' Directives detect a failure or a
-new error, or if a SMART command to the disk fails. This Directive
-only works in conjunction with these other Directives (or with the
-equivalent default \'\-a\' Directive).
-
-To prevent your email in-box from getting filled up with warning
-messages, by default only a single warning will be sent for each of
-the enabled alert types, \'\-H\', \'\-l\', \'\-f\', \'\-C\', or
-\'\-O\' even if more than one failure or error is detected or if the
-failure or error persists.  [This behavior can be modified; see the
-\'\-M\' Directive below.]
-
-To send email to more than one user, please use the following "comma
-separated" form for the address: \fBuser1@add1,user2@add2,...,userN@addN\fP
-(with no spaces).
-
-To test that email is being sent correctly, use the \'\-M test\'
-Directive described below to send one test email message on
-\fBsmartd\fP
-startup.
-
-By default, email is sent using the system 
-.B mail
-command.  In order that
-\fBsmartd\fP
-find the mail command (normally /bin/mail) an executable named
-.B \'mail\'
-must be in the path of the shell or environment from which
-\fBsmartd\fP
-was started.  If you wish to specify an explicit path to the mail
-executable (for example /usr/local/bin/mail) or a custom script to
-run, please use the \'\-M exec\' Directive below.
-
-Note that by default under Solaris, in the previous paragraph,
-\'\fBmailx\fP\' and \'\fB/bin/mailx\fP\' are used, since Solaris
-\'/bin/mail\' does not accept a \'\-s\' (Subject) command-line
-argument.
-
-On Windows, the \'\fBBlat\fP\' mailer
-(\fBhttp://blat.sourceforge.net/\fP) is used by default.
-This mailer uses a different command line syntax, see
-\'\-M exec\' below.
-
-Note also that there is a special argument
-.B <nomailer>
-which can be given to the \'\-m\' Directive in conjunction with the \'\-M
-exec\' Directive. Please see below for an explanation of its effect.
-
-If the mailer or the shell running it produces any STDERR/STDOUT
-output, then a snippet of that output will be copied to SYSLOG.  The
-remainder of the output is discarded. If problems are encountered in
-sending mail, this should help you to understand and fix them.  If
-you have mail problems, we recommend running \fBsmartd\fP in debug
-mode with the \'-d\' flag, using the \'-M test\' Directive described
-below.
-
-The following extension is available on Windows:
-By specifying \'\fBmsgbox\fP\' as a mail address, a warning
-"email" is displayed as a message box on the screen.
-Using both \'\fBmsgbox\fP\' and regular mail addresses is possible,
-if \'\fBmsgbox\fP\' is the first word in the comma separated list.
-With \'\fBsysmsgbox\fP\', a system modal (always on top) message box
-is used. If running as a service, a service notification message box
-(always shown on current visible desktop) is used.
-
-.TP
-.B \-M TYPE
-These Directives modify the behavior of the
-\fBsmartd\fP
-email warnings enabled with the \'\-m\' email Directive described above.
-These \'\-M\' Directives only work in conjunction with the \'\-m\'
-Directive and can not be used without it.
-
-Multiple \-M Directives may be given.  If conflicting \-M Directives
-are given (example: \-M once \-M daily) then the final one (in the
-example, \-M daily) is used.
-
-The valid arguments to the \-M Directive are:
-
-.I once
-\- send only one warning email for each type of disk problem detected.  This
-is the default.
-
-.I daily
-\- send additional warning reminder emails, once per day, for each type
-of disk problem detected.
-
-.I diminishing
-\- send additional warning reminder emails, after a one-day interval,
-then a two-day interval, then a four-day interval, and so on for each
-type of disk problem detected. Each interval is twice as long as the
-previous interval.
-
-.I test
-\- send a single test email
-immediately upon
-\fBsmartd\fP
-startup.  This allows one to verify that email is delivered correctly.
-
-.I exec PATH
-\- run the executable PATH instead of the default mail command, when
-\fBsmartd\fP
-needs to send email.  PATH must point to an executable binary file or
-script.
-
-By setting PATH to point to a customized script, you can make
-\fBsmartd\fP perform useful tricks when a disk problem is detected
-(beeping the console, shutting down the machine, broadcasting warnings
-to all logged-in users, etc.)  But please be careful. \fBsmartd\fP
-will \fBblock\fP until the executable PATH returns, so if your
-executable hangs, then \fBsmartd\fP will also hang. Some sample
-scripts are included in
-/usr/share/doc/smartmontools-5.1/examplescripts/.
-
-The return status of the executable is recorded by \fBsmartd\fP in
-SYSLOG. The executable is not expected to write to STDOUT or
-STDERR.  If it does, then this is interpreted as indicating that
-something is going wrong with your executable, and a fragment of this
-output is logged to SYSLOG to help you to understand the problem.
-Normally, if you wish to leave some record behind, the executable
-should send mail or write to a file or device.
-
-Before running the executable, \fBsmartd\fP sets a number of
-environment variables.  These environment variables may be used to
-control the executable\'s behavior.  The environment variables
-exported by \fBsmartd\fP are:
-.RS 7
-.IP \fBSMARTD_MAILER\fP 4
-is set to the argument of \-M exec, if present or else to \'mail\'
-(examples: /bin/mail, mail).
-.IP \fBSMARTD_DEVICE\fP 4
-is set to the device path (examples: /dev/hda, /dev/sdb).
-.IP \fBSMARTD_DEVICETYPE\fP 4
-is set to the device type (possible values: ata, scsi, 3ware,N). Here
-N=0,...,15 denotes the ATA disk behind a 3ware RAID controller.
-.IP \fBSMARTD_DEVICESTRING\fP 4
-is set to the device description.  For SMARTD_DEVICETYPE of ata or
-scsi, this is the same as SMARTD_DEVICE.  For 3ware RAID controllers,
-the form used is \'/dev/sdc [3ware_disk_01]\'. In this case the device
-string contains a space and is NOT quoted.  So to use
-$SMARTD_DEVICESTRING in a bash script you should probably enclose it
-in double quotes.
-.IP \fBSMARTD_FAILTYPE\fP 4
-gives the reason for the warning or message email.  The possible values that
-it takes and their meanings are:
-.nf
-.fi
-\fIEmailTest\fP: this is an email test message.
-.nf
-.fi
-\fIHealth\fP: the SMART health status indicates imminent failure.
-.nf
-.fi
-\fIUsage\fP: a usage Attribute has failed.
-.nf
-.fi
-\fISelfTest\fP: the number of self-test failures has increased.
-.nf
-.fi
-\fIErrorCount\fP: the number of errors in the ATA error log has increased.
-.nf
-.fi
-\fICurrentPendingSector\fP: one of more disk sectors could not be
-read and are marked to be reallocated (replaced with spare sectors).
-.nf
-.fi
-\fIOfflineUncorrectableSector\fP: during off\-line testing, or self\-testing,
-one or more disk sectors could not be read.
-.nf
-.fi
-\fIFailedHealthCheck\fP: the SMART health status command failed.
-.nf
-.fi
-\fIFailedReadSmartData\fP: the command to read SMART Attribute data failed.
-.nf
-.fi
-\fIFailedReadSmartErrorLog\fP: the command to read the SMART error log failed.
-.nf
-.fi
-\fIFailedReadSmartSelfTestLog\fP: the command to read the SMART self-test log failed.
-.nf
-.fi
-\fIFailedOpenDevice\fP: the open() command to the device failed.
-.IP \fBSMARTD_ADDRESS\fP 4
-is determined by the address argument ADD of the \'\-m\' Directive.
-If ADD is \fB<nomailer>\fP, then \fBSMARTD_ADDRESS\fP is not set.
-Otherwise, it is set to the comma-separated-list of email addresses
-given by the argument ADD, with the commas replaced by spaces
-(example:admin@example.com root).  If more than one email address is
-given, then this string will contain space characters and is NOT
-quoted, so to use it in a bash script you may want to enclose it in
-double quotes.
-.IP \fBSMARTD_MESSAGE\fP 4
-is set to the warning email message string from
-\fBsmartd\fP. 
-This message string contains space characters and is NOT quoted. So to
-use $SMARTD_MESSAGE in a bash script you should probably enclose it in
-double quotes.
-.IP \fBSMARTD_TFIRST\fP 4
-is a text string giving the time and date at which the first problem
-of this type was reported. This text string contains space characters
-and no newlines, and is NOT quoted. For example:
-.nf
-.fi
-Sun Feb  9 14:58:19 2003 CST
-.IP \fBSMARTD_TFIRSTEPOCH\fP 4
-is an integer, which is the unix epoch (number of seconds since Jan 1,
-1970) for \fBSMARTD_TFIRST\fP.
-.RE
-.\"  The following two lines are a workaround for a man2html bug.  Please leave them.
-.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
-.TP
-.B \&
-The shell which is used to run PATH is system-dependent. For vanilla
-Linux/glibc it\'s bash. For other systems, the man page for
-\fBpopen\fP(3) should say what shell is used.
-
-If the \'\-m ADD\' Directive is given with a normal address argument,
-then the executable pointed to by PATH will be run in a shell with
-STDIN receiving the body of the email message, and with the same
-command-line arguments:
-.nf
--s "$SMARTD_SUBJECT" $SMARTD_ADDRESS
-.fi
-that would normally be provided to \'mail\'.  Examples include:
-.nf
-.B -m user@home -M exec /bin/mail
-.B -m admin@work -M exec /usr/local/bin/mailto
-.B -m root -M exec /Example_1/bash/script/below
-.fi
-
-Note that on Windows, the syntax of the \'\fBBlat\fP\' mailer is
-used:
-.nf
-- -q -subject "$SMARTD_SUBJECT" -to "$SMARTD_ADDRESS"
-.fi
-
-If the \'\-m ADD\' Directive is given with the special address argument
-.B <nomailer>
-then the executable pointed to by PATH is run in a shell with
-.B no
-STDIN and
-.B no
-command-line arguments, for example:
-.nf
-.B -m <nomailer> -M exec /Example_2/bash/script/below
-.fi
-If the executable produces any STDERR/STDOUT output, then \fBsmartd\fP
-assumes that something is going wrong, and a snippet of that output
-will be copied to SYSLOG.  The remainder of the output is then
-discarded.
-
-Some EXAMPLES of scripts that can be used with the \'\-M exec\'
-Directive are given below. Some sample scripts are also included in
-/usr/share/doc/smartmontools-5.1/examplescripts/.
-
-.TP
-.B \-f
-Check for \'failure\' of any Usage Attributes.  If these Attributes are
-less than or equal to the threshold, it does NOT indicate imminent
-disk failure.  It "indicates an advisory condition where the usage or
-age of the device has exceeded its intended design life period."
-[Please see the \fBsmartctl \-A\fP command-line option.]
-.TP
-.B \-p
-Report anytime that a Prefail Attribute has changed
-its value since the last check, 30 minutes ago. [Please see the
-.B smartctl \-A
-command-line option.]
-.TP
-.B \-u
-Report anytime that a Usage Attribute has changed its value
-since the last check, 30 minutes ago. [Please see the
-.B smartctl \-A
-command-line option.]
-.TP
-.B \-t
-Equivalent to turning on the two previous flags \'\-p\' and \'\-u\'.
-Tracks changes in \fIall\fP device Attributes (both Prefailure and
-Usage). [Please see the \fBsmartctl\fP \-A command-line option.]
-.TP
-.B \-i ID
-Ignore device Attribute number \fBID\fP when checking for failure of
-Usage Attributes.  \fBID\fP must be a decimal integer in the range
-from 1 to 255.  This Directive modifies the behavior of the \'\-f\'
-Directive and has no effect without it.
-
-This is useful, for example, if you have a very old disk and don\'t
-want to keep getting messages about the hours-on-lifetime Attribute
-(usually Attribute 9) failing.  This Directive may appear multiple
-times for a single device, if you want to ignore multiple Attributes.
-.TP
-.B \-I ID
-Ignore device Attribute \fBID\fP when tracking changes in the
-Attribute values.  \fBID\fP must be a decimal integer in the range
-from 1 to 255.  This Directive modifies the behavior of the \'\-p\',
-\'\-u\', and \'\-t\' tracking Directives and has no effect without one
-of them.
-
-This is useful, for example, if one of the device Attributes is the disk
-temperature (usually Attribute 194 or 231). It\'s annoying to get reports
-each time the temperature changes.  This Directive may appear multiple
-times for a single device, if you want to ignore multiple Attributes.
-.TP
-.B \-r ID
-When tracking, report the \fIRaw\fP value of Attribute \fBID\fP along
-with its (normally reported) \fINormalized\fP value.  \fBID\fP must be
-a decimal integer in the range from 1 to 255.  This Directive modifies
-the behavior of the \'\-p\', \'\-u\', and \'\-t\' tracking Directives
-and has no effect without one of them.  This Directive may be given
-multiple times.
-
-A common use of this Directive is to track the device Temperature
-(often ID=194 or 231).
-
-.TP
-.B \-R ID
-When tracking, report whenever the \fIRaw\fP value of Attribute
-\fBID\fP changes.  (Normally \fBsmartd\fP only tracks/reports changes
-of the \fINormalized\fP Attribute values.)  \fBID\fP must be a decimal
-integer in the range from 1 to 255.  This Directive modifies the
-behavior of the \'\-p\', \'\-u\', and \'\-t\' tracking Directives and
-has no effect without one of them.  This Directive may be given
-multiple times.
-
-If this Directive is given, it automatically implies the \'\-r\'
-Directive for the same Attribute, so that the Raw value of the
-Attribute is reported.
-
-A common use of this Directive is to track the device Temperature
-(often ID=194 or 231).  It is also useful for understanding how
-different types of system behavior affects the values of certain
-Attributes.
-
-.TP
-.B \-C ID
-[ATA only] Report if the current number of pending sectors is
-non-zero.  Here \fBID\fP is the id number of the Attribute whose raw
-value is the Current Pending Sector count.  The allowed range of
-\fBID\fP is 0 to 255 inclusive.  To turn off this reporting, use
-ID\ =\ 0.  If the \fB\-C ID\fP option is not given, then it defaults to
-\fB\-C 197\fP (since Attribute 197 is generally used to monitor
-pending sectors).
-
-A pending sector is a disk sector (containing 512 bytes of your data)
-which the device would like to mark as ``bad" and reallocate.
-Typically this is because your computer tried to read that sector, and
-the read failed because the data on it has been corrupted and has
-inconsistent Error Checking and Correction (ECC) codes.  This is
-important to know, because it means that there is some unreadable data
-on the disk.  The problem of figuring out what file this data belongs
-to is operating system and file system specific.  You can typically
-force the sector to reallocate by writing to it (translation: make the
-device substitute a spare good sector for the bad one) but at the
-price of losing the 512 bytes of data stored there.
-
-.TP
-.B \-U ID
-[ATA only] Report if the number of offline uncorrectable sectors is
-non-zero.  Here \fBID\fP is the id number of the Attribute whose raw
-value is the Offline Uncorrectable Sector count.  The allowed range of
-\fBID\fP is 0 to 255 inclusive.  To turn off this reporting, use
-ID\ =\ 0.  If the \fB\-U ID\fP option is not given, then it defaults to
-\fB\-U 198\fP (since Attribute 198 is generally used to monitor
-offline uncorrectable sectors).
-
-
-An offline uncorrectable sector is a disk sector which was not
-readable during an off\-line scan or a self\-test.  This is important
-to know, because if you have data stored in this disk sector, and you
-need to read it, the read will fail.  Please see the previous \'\-C\'
-option for more details.
-
-.TP
-.B \-F TYPE
-[ATA only] Modifies the behavior of \fBsmartd\fP to compensate for
-some known and understood device firmware bug.  The arguments to this
-Directive are exclusive, so that only the final Directive given is
-used.  The valid values are:
-
-.I none
-\- Assume that the device firmware obeys the ATA specifications.  This is
-the default, unless the device has presets for \'\-F\' in the device
-database.
-
-.I samsung
-\- In some Samsung disks (example: model SV4012H Firmware Version:
-RM100-08) some of the two- and four-byte quantities in the SMART data
-structures are byte-swapped (relative to the ATA specification).
-Enabling this option tells \fBsmartd\fP to evaluate these quantities
-in byte-reversed order.  Some signs that your disk needs this option
-are (1) no self-test log printed, even though you have run self-tests;
-(2) very large numbers of ATA errors reported in the ATA error log;
-(3) strange and impossible values for the ATA error log timestamps.
-
-.I samsung2
-\- In more recent Samsung disks (firmware revisions ending in "\-23") the
-number of ATA errors reported is byte swapped.  Enabling this option
-tells \fBsmartd\fP to evaluate this quantity in byte-reversed order.
-
-Note that an explicit \'\-F\' Directive will over-ride any preset
-values for \'\-F\' (see the \'\-P\' option below).
-
-
-[Please see the \fBsmartctl \-F\fP command-line option.]
-
-.TP
-.B \-v N,OPTION
-Modifies the labeling for Attribute N, for disks which use
-non-standard Attribute definitions.  This is useful in connection with
-the Attribute tracking/reporting Directives.
-
-This Directive may appear multiple times. Valid arguments to this
-Directive are:
-
-.I 9,minutes
-\- Raw Attribute number 9 is power-on time in minutes.  Its raw value
-will be displayed in the form \'Xh+Ym\'.  Here X is hours, and Y is
-minutes in the range 0-59 inclusive.  Y is always printed with two
-digits, for example \'06\' or \'31\' or \'00\'.
-
-.I 9,seconds
-\- Raw Attribute number 9 is power-on time in seconds.  Its raw value
-will be displayed in the form \'Xh+Ym+Zs\'.  Here X is hours, Y is
-minutes in the range 0-59 inclusive, and Z is seconds in the range
-0-59 inclusive.  Y and Z are always printed with two digits, for
-example \'06\' or \'31\' or \'00\'.
-
-.I 9,halfminutes
-\- Raw Attribute number 9 is power-on time, measured in units of 30
-seconds.  This format is used by some Samsung disks.  Its raw value
-will be displayed in the form \'Xh+Ym\'.  Here X is hours, and Y is
-minutes in the range 0-59 inclusive.  Y is always printed with two
-digits, for example \'06\' or \'31\' or \'00\'.
-
-.I 9,temp
-\- Raw Attribute number 9 is the disk temperature in Celsius.
-
-.I 192,emergencyretractcyclect
-\- Raw Attribute number 192 is the Emergency Retract Cycle Count.
-
-.I 193,loadunload
-\- Raw Attribute number 193 contains two values. The first is the
-number of load cycles.  The second is the number of unload cycles.
-The difference between these two values is the number of times that
-the drive was unexpectedly powered off (also called an emergency
-unload). As a rule of thumb, the mechanical stress created by one
-emergency unload is equivalent to that created by one hundred normal
-unloads.
-
-.I 194,10xCelsius
-\- Raw Attribute number 194 is ten times the disk temperature in
-Celsius.  This is used by some Samsung disks (example: model SV1204H
-with RK100-13 firmware).
-
-.I 194,unknown
-\- Raw Attribute number 194 is NOT the disk temperature, and its
-interpretation is unknown. This is primarily useful for the -P
-(presets) Directive.
-
-.I 198,offlinescanuncsectorct
-\- Raw Attribute number 198 is the Offline Scan UNC Sector Count.
-
-.I 200,writeerrorcount
-\- Raw Attribute number 200 is the Write Error Count.
-
-.I 201,detectedtacount
-\- Raw Attribute number 201 is the Detected TA Count.
-
-.I 220,temp
-\- Raw Attribute number 220 is the disk temperature in Celsius.
-
-Note: a table of hard drive models, listing which Attribute
-corresponds to temperature, can be found at:
-http://coredump.free.fr/linux/hddtemp.db
-
-.I N,raw8
-\- Print the Raw value of Attribute N as six 8-bit unsigned base-10
-integers.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw8\' prints Raw values for ALL Attributes in this
-form.  The form (for example) \'123,raw8\' only prints the Raw value for
-Attribute 123 in this form.
-
-.I N,raw16
-\- Print the Raw value of Attribute N as three 16-bit unsigned base-10
-integers.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw16\' prints Raw values for ALL Attributes in this
-form.  The form (for example) \'123,raw16\' only prints the Raw value for
-Attribute 123 in this form.
-
-.I N,raw48
-\- Print the Raw value of Attribute N as a 48-bit unsigned base-10
-integer.  This may be useful for decoding the meaning of the Raw
-value.  The form \'N,raw48\' prints Raw values for ALL Attributes in
-this form.  The form (for example) \'123,raw48\' only prints the Raw
-value for Attribute 123 in this form.
-
-.TP
-.B \-P TYPE
-Specifies whether
-\fBsmartd\fP
-should use any preset options that are available for this drive.  The
-valid arguments to this Directive are:
-
-.I use
-\- use any presets that are available for this drive.  This is the default.
-
-.I ignore
-\- do not use any presets for this drive.
-
-.I show
-\- show the presets listed for this drive in the database.
-
-.I showall
-\- show the presets that are available for all drives and then exit.
-
-[Please see the
-.B smartctl \-P
-command-line option.]
-
-.TP
-.B \-a
-Equivalent to turning on all of the following Directives: 
-.B \'\-H\' 
-to check the SMART health status,
-.B \'\-f\' 
-to report failures of Usage (rather than Prefail) Attributes,
-.B \'\-t\' 
-to track changes in both Prefailure and Usage Attributes,
-.B \'\-l\ selftest\' 
-to report increases in the number of Self-Test Log errors,
-.B \'\-l\ error\' 
-to report increases in the number of ATA errors,
-.B \'\-C 197\'
-to report nonzero values of the current pending sector count, and
-.B \'\-U 198\'
-to report nonzero values of the offline pending sector count.
-
-Note that \-a is the default for ATA devices.  If none of these other
-Directives is given, then \-a is assumed.
-
-.TP
-.B #
-Comment: ignore the remainder of the line.
-.TP
-.B \e
-Continuation character: if this is the last non-white or non-comment
-character on a line, then the following line is a continuation of the current
-one.
-.PP
-If you are not sure which Directives to use, I suggest experimenting
-for a few minutes with
-.B smartctl
-to see what SMART functionality your disk(s) support(s).  If you do
-not like voluminous syslog messages, a good choice of
-\fBsmartd\fP
-configuration file Directives might be:
-.nf
-.B \-H \-l\ selftest \-l\ error \-f.
-.fi
-If you want more frequent information, use:
-.B -a.
-
-.TP
-.B ADDITIONAL DETAILS ABOUT DEVICESCAN
-If the first non-comment entry in the configuration file is the text
-string \fBDEVICESCAN\fP in capital letters, then \fBsmartd\fP will
-ignore any remaining lines in the configuration file, and will scan
-for devices.
-
-If \fBDEVICESCAN\fP is not followed by any Directives, then smartd
-will scan for both ATA and SCSI devices, and will monitor all possible
-SMART properties of any devices that are found.
-
-\fBDEVICESCAN\fP may optionally be followed by any valid Directives,
-which will be applied to all devices that are found in the scan.  For
-example
-.nf
-.B DEVICESCAN -m root@example.com
-.fi
-will scan for all devices, and then monitor them.  It will send one
-email warning per device for any problems that are found.
-.nf
-.B  DEVICESCAN -d ata -m root@example.com
-.fi
-will do the same, but restricts the scan to ATA devices only.  
-.nf
-.B  DEVICESCAN -H -d ata -m root@example.com
-.fi
-will do the same, but only monitors the SMART health status of the
-devices, (rather than the default \-a, which monitors all SMART
-properties).
-
-.TP
-.B EXAMPLES OF SHELL SCRIPTS FOR \'\-M exec\'
-These are two examples of shell scripts that can be used with the \'\-M
-exec PATH\' Directive described previously.  The paths to these scripts
-and similar executables is the PATH argument to the \'\-M exec PATH\'
-Directive.
-
-Example 1: This script is for use with \'\-m ADDRESS -M exec PATH\'.  It appends
-the output of
-.B smartctl -a
-to the output of the smartd email warning message and sends it to ADDRESS.
-
-.nf
-\fB
-#! /bin/bash
-
-# Save the email message (STDIN) to a file:
-cat > /root/msg
-
-# Append the output of smartctl -a to the message:
-/usr/sbin/smartctl -a -d $SMART_DEVICETYPE $SMARTD_DEVICE >> /root/msg
- 
-# Now email the message to the user at address ADD:
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
-\fP
-.fi
-
-Example 2: This script is for use with \'\-m <nomailer> \-M exec
-PATH\'. It warns all users about a disk problem, waits 30 seconds, and
-then powers down the machine.
-
-.nf
-\fB
-#! /bin/bash
-
-# Warn all users of a problem
-wall \'Problem detected with disk: \' "$SMARTD_DEVICESTRING"
-wall \'Warning message from smartd is: \' "$SMARTD_MESSAGE"
-wall \'Shutting down machine in 30 seconds... \'
- 
-# Wait half a minute
-sleep 30
- 
-# Power down the machine
-/sbin/shutdown -hf now
-\fP
-.fi
-
-Some example scripts are distributed with the smartmontools package,
-in /usr/share/doc/smartmontools-5.1/examplescripts/.
-
-Please note that these scripts typically run as root, so any files
-that they read/write should not be writable by ordinary users or
-reside in directories like /tmp that are writable by ordinary users
-and may expose your system to symlink attacks.
-
-As previously described, if the scripts write to STDOUT or STDERR,
-this is interpreted as indicating that there was an internal error
-within the script, and a snippet of STDOUT/STDERR is logged to SYSLOG.
-The remainder is flushed.
-
-.\" ENDINCLUDE
-.\" DO NOT MODIFY THIS OR PREVIOUS/NEXT LINES. THIS DEFINES THE 
-.\" END OF THE INCLUDED SECTION FROM smartd.8.in
-
-.PP
-.SH AUTHOR
-\fBBruce Allen\fP smartmontools-support@lists.sourceforge.net
-.fi
-University of Wisconsin \- Milwaukee Physics Department
-
-.PP
-.SH CONTRIBUTORS
-The following have made large contributions to smartmontools:
-.nf
-\fBCasper Dik\fP (Solaris SCSI interface)
-\fBChristian Franke\fP (Windows interface)
-\fBDouglas Gilbert\fP (SCSI subsystem)
-\fBGuido Guenther\fP (Autoconf/Automake packaging)
-\fBEduard Martinescu\fP (FreeBSD interface)
-\fBFr\*'ed\*'eric L. W. Meunier\fP (Web site and Mailing list)
-\fBKeiji Sawada\fP (Solaris ATA interface)
-\fBSergey Svishchev\fP (NetBSD interface)
-\fBPhil Williams\fP (User interface and drive database)
-.fi
-Many other individuals have made smaller contributions and corrections.
-
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous ucsc smartsuite package. It extends
-these to cover ATA-5 disks. This code was originally developed as a
-Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
-(now part of the Storage Systems Research Center), Jack Baskin School
-of Engineering, University of California, Santa
-Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
-.SH
-HOME PAGE FOR SMARTMONTOOLS: 
-.fi
-Please see the following web site for updates, further documentation, bug
-reports and patches:
-.nf
-.B
-http://smartmontools.sourceforge.net/
-
-.SH
-SEE ALSO:
-\fBsmartd\fP(8), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
-\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
-
-.SH
-CVS ID OF THIS PAGE:
-$Id: smartd.conf.5.in,v 1.58 2004/08/08 14:32:07 ballen4705 Exp $
diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp
deleted file mode 100644
index c2b77c91594e3eba287d6b51885bc06812d8070c..0000000000000000000000000000000000000000
--- a/sm5/smartd.cpp
+++ /dev/null
@@ -1,3940 +0,0 @@
-/*
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-// unconditionally included files
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>   // umask
-#ifndef _WIN32
-#include <sys/wait.h>
-#include <unistd.h>
-#endif
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <limits.h>
-
-#if SCSITIMEOUT
-#include <setjmp.h>
-#endif
-
-// see which system files to conditionally include
-#include "config.h"
-
-// conditionally included files
-#ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef _WIN32
-#ifdef _MSC_VER
-#pragma warning(disable:4761) // "conversion supplied"
-typedef unsigned short mode_t;
-typedef int pid_t;
-#endif
-#include <io.h> // umask()
-#include <process.h> // getpid()
-#endif // _WIN32
-
-// locally included files
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "int64.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "smartd.h"
-#include "utility.h"
-
-#ifdef _WIN32
-#include "hostname_win32.h" // gethost/domainname()
-#define HAVE_GETHOSTNAME   1
-#define HAVE_GETDOMAINNAME 1
-// fork()/signal()/initd simulation for native Windows
-#include "daemon_win32.h" // daemon_main/detach/signal()
-#undef SIGNALFN
-#define SIGNALFN  daemon_signal
-#define strsignal daemon_strsignal
-#define sleep     daemon_sleep
-#undef EXIT // see utility.h
-#define EXIT(x)  { exitstatus = daemon_winsvc_exitcode = (x); exit((x)); }
-// SIGQUIT does not exits, CONTROL-Break signals SIGBREAK.
-#define SIGQUIT SIGBREAK
-#define SIGQUIT_KEYNAME "CONTROL-Break"
-#else  // _WIN32
-#ifdef __CYGWIN__
-// 2x CONTROL-C simulates missing SIGQUIT via keyboard
-#define SIGQUIT_KEYNAME "2x CONTROL-C"
-#else // __CYGWIN__
-#define SIGQUIT_KEYNAME "CONTROL-\\"
-#endif // __CYGWIN__
-#endif // _WIN32
-
-#if defined (__SVR4) && defined (__sun)
-int getdomainname(char *, int); /* no declaration in header files! */
-#endif
-
-#define ARGUSED(x) ((void)(x))
-
-// These are CVS identification information for *.c and *.h files
-extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, 
-                  *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
-
-static const char *filenameandversion="$Id: smartd.cpp,v 1.333 2004/08/16 22:44:27 ballen4705 Exp $";
-#ifdef NEED_SOLARIS_ATA_CODE
-extern const char *os_solaris_ata_s_cvsid;
-#endif
-#ifdef _WIN32
-extern const char *daemon_win32_c_cvsid, *hostname_win32_c_cvsid, *syslog_win32_c_cvsid;
-#ifdef _MSC_VER
-extern const char *int64_vc6_c_cvsid;
-#endif
-#endif
-const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.333 2004/08/16 22:44:27 ballen4705 Exp $" 
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID
-#ifdef DAEMON_WIN32_H_CVSID
-DAEMON_WIN32_H_CVSID
-#endif
-EXTERN_H_CVSID INT64_H_CVSID
-#ifdef HOSTNAME_WIN32_H_CVSID
-HOSTNAME_WIN32_H_CVSID
-#endif
-KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID
-#ifdef SYSLOG_H_CVSID
-SYSLOG_H_CVSID
-#endif
-UTILITY_H_CVSID;
-
-extern const char *reportbug;
-
-// GNU copyleft statement.  Needed for GPL purposes.
-const char *copyleftstring="smartd comes with ABSOLUTELY NO WARRANTY. This is\n"
-                           "free software, and you are welcome to redistribute it\n"
-                           "under the terms of the GNU General Public License\n"
-                           "Version 2. See http://www.gnu.org for further details.\n\n";
-
-extern unsigned char debugmode;
-
-// command-line: how long to sleep between checks
-static int checktime=CHECKTIME;
-
-// command-line: name of PID file (NULL for no pid file)
-static char* pid_file=NULL;
-
-// configuration file name
-#ifndef _WIN32
-static char* configfile = SMARTMONTOOLS_SYSCONFDIR "/" CONFIGFILENAME ;
-#else
-static char* configfile = "./" CONFIGFILENAME ;
-#endif
-// configuration file "name" if read from stdin
-static /*const*/ char * const configfile_stdin = "<stdin>";
-// allocated memory for alternate configuration file name
-static char* configfile_alt = NULL;
-
-// command-line: when should we exit?
-static int quit=0;
-
-// command-line; this is the default syslog(3) log facility to use.
-static int facility=LOG_DAEMON;
-
-// used for control of printing, passing arguments to atacmds.c
-smartmonctrl *con=NULL;
-
-// pointers to (real or simulated) entries in configuration file, and
-// maximum space currently allocated for these entries.
-cfgfile **cfgentries=NULL;
-int cfgentries_max=0;
-
-// pointers to ATA and SCSI devices being monitored, maximum and
-// actual numbers
-cfgfile **atadevlist=NULL, **scsidevlist=NULL;
-int atadevlist_max=0, scsidevlist_max=0;
-int numdevata=0, numdevscsi=0;
-
-// track memory usage
-extern int64_t bytes;
-
-// exit status
-extern int exitstatus;
-
-// set to one if we catch a USR1 (check devices now)
-volatile int caughtsigUSR1=0;
-
-#ifdef _WIN32
-// set to one if we catch a USR2 (toggle debug mode)
-volatile int caughtsigUSR2=0;
-#endif
-
-// set to one if we catch a HUP (reload config file). In debug mode,
-// set to two, if we catch INT (also reload config file).
-volatile int caughtsigHUP=0;
-
-// set to signal value if we catch INT, QUIT, or TERM
-volatile int caughtsigEXIT=0;
-
-#if SCSITIMEOUT
-// stack environment if we time out during SCSI access (USB devices)
-jmp_buf registerscsienv;
-#endif
-
-// tranlate cfg->pending into the correct Attribute numbers
-void TranslatePending(unsigned short pending, unsigned char *current, unsigned char *offline) {
-
-  unsigned char curr = CURR_PEND(pending);
-  unsigned char off =  OFF_PEND(pending);
-
-  // look for special value of CUR_UNC_DEFAULT that means DONT
-  // monitor. 0 means DO test.
-  if (curr==CUR_UNC_DEFAULT)
-    curr=0;
-  else if (curr==0)
-    curr=CUR_UNC_DEFAULT;
-	
-  // look for special value of OFF_UNC_DEFAULT that means DONT
-  // monitor.  0 means DO TEST.
-  if (off==OFF_UNC_DEFAULT)
-    off=0;
-  else if (off==0)
-    off=OFF_UNC_DEFAULT;
-
-  *current=curr;
-  *offline=off;
-
-  return;
-}
-
-
-// free all memory associated with selftest part of configfile entry.  Return NULL
-testinfo* FreeTestData(testinfo *data){
-  
-  // make sure we have something to do.
-  if (!data)
-    return NULL;
-  
-  // free space for text pattern
-  data->regex=FreeNonZero(data->regex, -1, __LINE__, filenameandversion);
-  
-  // free compiled expression
-  regfree(&(data->cregex));
-
-  // make sure that no sign of the compiled expression is left behind
-  // (just in case, to help detect bugs if we ever try and refer to
-  // that again).
-  memset(&(data->cregex), '0', sizeof(regex_t));
-
-  // free remaining memory space
-  data=FreeNonZero(data, sizeof(testinfo), __LINE__, filenameandversion);
-
-  return NULL;
-}
-
-cfgfile **AllocateMoreSpace(cfgfile **oldarray, int *oldsize, char *listname){
-  // for now keep BLOCKSIZE small to help detect coding problems.
-  // Perhaps increase in the future.
-  const int BLOCKSIZE=8;
-  int i;
-  int old = *oldsize;
-  int new = old + BLOCKSIZE;
-  cfgfile **newptr=realloc(oldarray, new*sizeof(cfgfile *));
-  
-  // did we get more space?
-  if (newptr) {
-
-    // clear remaining entries ala calloc()
-    for (i=old; i<new; i++)
-      newptr[i]=NULL;
-    
-    bytes += BLOCKSIZE*sizeof(cfgfile *);
-    
-    *oldsize=new;
-    
-#if 0
-    PrintOut(LOG_INFO, "allocating %d slots for %s\n", BLOCKSIZE, listname);
-#endif
-
-    return newptr;
-  }
-  
-  PrintOut(LOG_CRIT, "out of memory for allocating %s list\n", listname);
-  EXIT(EXIT_NOMEM);
-}
-
-void PrintOneCVS(const char *a_cvs_id){
-  char out[CVSMAXLEN];
-  printone(out,a_cvs_id);
-  PrintOut(LOG_INFO,"%s",out);
-  return;
-}
-
-// prints CVS identity information for the executable
-void PrintCVS(void){
-  char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
-
-  PrintOut(LOG_INFO,(char *)copyleftstring);
-  PrintOut(LOG_INFO,"CVS version IDs of files used to build this code are:\n");
-  PrintOneCVS(atacmdnames_c_cvsid);
-  PrintOneCVS(atacmds_c_cvsid);
-  PrintOneCVS(ataprint_c_cvsid);
-#ifdef _WIN32
-  PrintOneCVS(daemon_win32_c_cvsid);
-#endif
-#if defined(_WIN32) && defined(_MSC_VER)
-  PrintOneCVS(int64_vc6_c_cvsid);
-#endif
-#ifdef _WIN32
-  PrintOneCVS(hostname_win32_c_cvsid);
-#endif
-  PrintOneCVS(knowndrives_c_cvsid);
-  PrintOneCVS(os_XXXX_c_cvsid);
-#ifdef NEED_SOLARIS_ATA_CODE
-  PrintOneCVS( os_solaris_ata_s_cvsid);
-#endif
-  PrintOneCVS(scsicmds_c_cvsid);
-  PrintOneCVS(smartd_c_cvsid);
-#ifdef _WIN32
-  PrintOneCVS(syslog_win32_c_cvsid);
-#endif
-  PrintOneCVS(utility_c_cvsid);
-  PrintOut(LOG_INFO, "\nsmartmontools release " PACKAGE_VERSION " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n");
-  PrintOut(LOG_INFO, "smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n");
-  PrintOut(LOG_INFO, "smartmontools build configured: " SMARTMONTOOLS_CONFIGURE_DATE "\n");
-  PrintOut(LOG_INFO, "smartd compile dated " __DATE__ " at "__TIME__ "\n");
-  PrintOut(LOG_INFO, "smartmontools configure arguments: %s\n", configargs);
-  return;
-}
-
-// Removes config file entry, freeing all memory
-void RmConfigEntry(cfgfile **anentry, int whatline){
-  
-  cfgfile *cfg;
-
-  // pointer should never be null!
-  if (!anentry){
-    PrintOut(LOG_CRIT,"Internal error in RmConfigEntry() at line %d of file %s\n%s",
-             whatline, filenameandversion, reportbug);    
-    EXIT(EXIT_BADCODE);
-  }
-  
-  // only remove entries that exist!
-  if (!(cfg=*anentry))
-    return;
-
-  // entry exists -- free all of its memory  
-  cfg->name            = FreeNonZero(cfg->name,           -1,__LINE__,filenameandversion);
-  cfg->smartthres      = FreeNonZero(cfg->smartthres,      sizeof(struct ata_smart_thresholds_pvt),__LINE__,filenameandversion);
-  cfg->smartval        = FreeNonZero(cfg->smartval,        sizeof(struct ata_smart_values),__LINE__,filenameandversion);
-  cfg->monitorattflags = FreeNonZero(cfg->monitorattflags, NMONITOR*32,__LINE__,filenameandversion);
-  cfg->attributedefs   = FreeNonZero(cfg->attributedefs,   MAX_ATTRIBUTE_NUM,__LINE__,filenameandversion);
-  if (cfg->mailwarn){
-    cfg->mailwarn->address         = FreeNonZero(cfg->mailwarn->address,        -1,__LINE__,filenameandversion);
-    cfg->mailwarn->emailcmdline    = FreeNonZero(cfg->mailwarn->emailcmdline,   -1,__LINE__,filenameandversion);
-    cfg->mailwarn                  = FreeNonZero(cfg->mailwarn,   sizeof(maildata),__LINE__,filenameandversion);
-  }
-  cfg->testdata        = FreeTestData(cfg->testdata);
-  *anentry             = FreeNonZero(cfg,                  sizeof(cfgfile),__LINE__,filenameandversion);
-
-  return;
-}
-
-// deallocates all memory associated with cfgentries list
-void RmAllConfigEntries(){
-  int i;
-
-  for (i=0; i<cfgentries_max; i++)
-    RmConfigEntry(cfgentries+i, __LINE__);
-
-  cfgentries=FreeNonZero(cfgentries, sizeof(cfgfile *)*cfgentries_max, __LINE__, filenameandversion);
-  cfgentries_max=0;
-
-  return;
-}
-
-// deallocates all memory associated with ATA/SCSI device lists
-void RmAllDevEntries(){
-  int i;
-  
-  for (i=0; i<atadevlist_max; i++)
-    RmConfigEntry(atadevlist+i, __LINE__);
-
-  atadevlist=FreeNonZero(atadevlist, sizeof(cfgfile *)*atadevlist_max, __LINE__, filenameandversion);
-  atadevlist_max=0;
-
-  for (i=0; i<scsidevlist_max; i++)
-    RmConfigEntry(scsidevlist+i, __LINE__);
-  
-  scsidevlist=FreeNonZero(scsidevlist, sizeof(cfgfile *)*scsidevlist_max, __LINE__, filenameandversion);
-  scsidevlist_max=0;
-
-  return;
-}
-
-// remove the PID file
-void RemovePidFile(){
-  if (pid_file) {
-    if ( -1==unlink(pid_file) )
-      PrintOut(LOG_CRIT,"Can't unlink PID file %s (%s).\n", 
-               pid_file, strerror(errno));
-    pid_file=FreeNonZero(pid_file, -1,__LINE__,filenameandversion);
-  }
-  return;
-}
-
-
-//  Note if we catch a SIGUSR1
-void USR1handler(int sig){
-  if (SIGUSR1==sig)
-    caughtsigUSR1=1;
-  return;
-}
-
-#ifdef _WIN32
-//  Note if we catch a SIGUSR2
-void USR2handler(int sig){
-  if (SIGUSR2==sig)
-    caughtsigUSR2=1;
-  return;
-}
-#endif
-
-// Note if we catch a HUP (or INT in debug mode)
-void HUPhandler(int sig){
-  if (sig==SIGHUP)
-    caughtsigHUP=1;
-  else
-    caughtsigHUP=2;
-  return;
-}
-
-// signal handler for TERM, QUIT, and INT (if not in debug mode)
-void sighandler(int sig){
-  if (!caughtsigEXIT)
-    caughtsigEXIT=sig;
-  return;
-}
-
-
-// signal handler that prints Goodbye message and removes pidfile
-void Goodbye(void){
-  
-  // clean up memory -- useful for debugging
-  RmAllConfigEntries();
-  RmAllDevEntries();
-
-  // delete PID file, if one was created
-  RemovePidFile();
-
-  // remove alternate configfile name
-  configfile_alt=FreeNonZero(configfile_alt, -1,__LINE__,filenameandversion);
-
-  // useful for debugging -- have we managed memory correctly?
-  if (debugmode || (bytes && exitstatus!=EXIT_NOMEM))
-    PrintOut(LOG_INFO, "Memory still allocated for devices at exit is %" PRId64 " bytes.\n", bytes);
-
-  // if we are exiting because of a code bug, tell user
-  if (exitstatus==EXIT_BADCODE || (bytes && exitstatus!=EXIT_NOMEM))
-        PrintOut(LOG_CRIT, "Please inform " PACKAGE_BUGREPORT ", including output of smartd -V.\n");
-
-  if (exitstatus==0 && bytes)
-    exitstatus=EXIT_BADCODE;
-
-  // and this should be the final output from smartd before it exits
-  PrintOut(exitstatus?LOG_CRIT:LOG_INFO, "smartd is exiting (exit status %d)\n", exitstatus);
-
-  return;
-}
-
-#define ENVLENGTH 512
-
-// a replacement for setenv() which is not available on all platforms.
-// Note that the string passed to putenv must not be freed or made
-// invalid, since a pointer to it is kept by putenv(). This means that
-// it must either be a static buffer or allocated off the heap. The
-// string can be freed if the environment variable is redefined or
-// deleted via another call to putenv(). So we keep these on the stack
-// as long as the popen() call is underway.
-int exportenv(char* stackspace, const char *name, const char *value){
-  snprintf(stackspace,ENVLENGTH, "%s=%s", name, value);
-  return putenv(stackspace);
-}
-
-char* dnsdomain(const char* hostname) {
-  char *p = NULL;
-#ifdef HAVE_GETHOSTBYNAME
-  struct hostent *hp;
-  
-  if ((hp = gethostbyname(hostname))) {
-    // Does this work if gethostbyname() returns an IPv6 name in
-    // colon/dot notation?  [BA]
-    if ((p = strchr(hp->h_name, '.')))
-      p++; // skip "."
-  }
-#else
-  ARGUSED(hostname);
-#endif
-  return p;
-}
-
-#define EBUFLEN 1024
-
-// If either address or executable path is non-null then send and log
-// a warning email, or execute executable
-void MailWarning(cfgfile *cfg, int which, char *fmt, ...){
-  char command[2048], message[256], hostname[256], domainname[256], additional[256];
-  char original[256], further[256], nisdomain[256], subject[256],dates[DATEANDEPOCHLEN];
-  char environ_strings[10][ENVLENGTH];
-  time_t epoch;
-  va_list ap;
-  const int day=24*3600;
-  int days=0;
-  char *whichfail[]={
-    "EmailTest",                  // 0
-    "Health",                     // 1
-    "Usage",                      // 2
-    "SelfTest",                   // 3
-    "ErrorCount",                 // 4
-    "FailedHealthCheck",          // 5
-    "FailedReadSmartData",        // 6
-    "FailedReadSmartErrorLog",    // 7
-    "FailedReadSmartSelfTestLog", // 8
-    "FailedOpenDevice",           // 9
-    "CurrentPendingSector",       // 10
-    "OfflineUncorrectableSector" //  11
-  };
-  
-  char *address, *executable;
-  mailinfo *mail;
-  maildata* data=cfg->mailwarn;
-#ifndef _WIN32
-  FILE *pfp=NULL;
-#else
-  char stdinbuf[1024]; int boxmsgoffs, boxtype;
-#endif
-  char *newadd=NULL, *newwarn=NULL;
-  const char *unknown="[Unknown]";
-
-  // See if user wants us to send mail
-  if (!data)
-    return;
-  
-  address=data->address;
-  executable=data->emailcmdline;
-  
-  if (!address && !executable)
-    return;
-  
-  // which type of mail are we sending?
-  mail=(data->maillog)+which;
-  
-  // checks for sanity
-  if (data->emailfreq<1 || data->emailfreq>3) {
-    PrintOut(LOG_CRIT,"internal error in MailWarning(): cfg->mailwarn->emailfreq=%d\n",data->emailfreq);
-    return;
-  }
-  if (which<0 || which>=SMARTD_NMAIL || sizeof(whichfail)!=SMARTD_NMAIL*sizeof(char *)) {
-    PrintOut(LOG_CRIT,"Contact " PACKAGE_BUGREPORT "; internal error in MailWarning(): which=%d, size=%d\n",
-             which, (int)sizeof(whichfail));
-    return;
-  }
-  
-  // Return if a single warning mail has been sent.
-  if ((data->emailfreq==1) && mail->logged)
-    return;
-
-  // Return if this is an email test and one has already been sent.
-  if (which == 0 && mail->logged)
-    return;
-  
-  // To decide if to send mail, we need to know what time it is.
-  epoch=time(NULL);
-
-  // Return if less than one day has gone by
-  if (data->emailfreq==2 && mail->logged && epoch<(mail->lastsent+day))
-    return;
-
-  // Return if less than 2^(logged-1) days have gone by
-  if (data->emailfreq==3 && mail->logged){
-    days=0x01<<(mail->logged-1);
-    days*=day;
-    if  (epoch<(mail->lastsent+days))
-      return;
-  }
-
-  // record the time of this mail message, and the first mail message
-  if (!mail->logged)
-    mail->firstsent=epoch;
-  mail->lastsent=epoch;
-  
-  // get system host & domain names (not null terminated if length=MAX) 
-#ifdef HAVE_GETHOSTNAME
-  if (gethostname(hostname, 256))
-    strcpy(hostname, unknown);
-  else {
-    char *p=NULL;
-    hostname[255]='\0';
-    p = dnsdomain(hostname);
-    if (p && *p) {
-      strncpy(domainname, p, 255);
-      domainname[255]='\0';
-    } else
-      strcpy(domainname, unknown);
-  }
-#else
-  strcpy(hostname, unknown);
-  strcpy(domainname, unknown);
-#endif
-  
-#ifdef HAVE_GETDOMAINNAME
-  if (getdomainname(nisdomain, 256))
-    strcpy(nisdomain, unknown);
-  else
-    nisdomain[255]='\0';
-#else
-  strcpy(nisdomain, unknown);
-#endif
-  
-  // print warning string into message
-  va_start(ap, fmt);
-  vsnprintf(message, 256, fmt, ap);
-  va_end(ap);
-
-  // appropriate message about further information
-  additional[0]=original[0]=further[0]='\0';
-  if (which) {
-    sprintf(further,"You can also use the smartctl utility for further investigation.\n");
-
-    switch (data->emailfreq){
-    case 1:
-      sprintf(additional,"No additional email messages about this problem will be sent.\n");
-      break;
-    case 2:
-      sprintf(additional,"Another email message will be sent in 24 hours if the problem persists.\n");
-      break;
-    case 3:
-      sprintf(additional,"Another email message will be sent in %d days if the problem persists\n",
-              (0x01)<<mail->logged);
-      break;
-    }
-    if (data->emailfreq>1 && mail->logged){
-      dateandtimezoneepoch(dates, mail->firstsent);
-      sprintf(original,"The original email about this issue was sent at %s\n", dates);
-    }
-  }
-  
-  snprintf(subject, 256,"SMART error (%s) detected on host: %s", whichfail[which], hostname);
-
-  // If the user has set cfg->emailcmdline, use that as mailer, else "mail" or "mailx".
-  if (!executable)
-#ifdef DEFAULT_MAILER
-    executable = DEFAULT_MAILER ;
-#else
-#ifndef _WIN32
-    executable = "mail";
-#else
-    executable = "blat"; // http://blat.sourceforge.net/
-#endif
-#endif
-
-  // make a private copy of address with commas replaced by spaces
-  // to separate recipients
-  if (address) {
-    address=CustomStrDup(data->address, 1, __LINE__, filenameandversion);
-#ifndef _WIN32 // blat mailer needs comma
-    char *comma=address;
-    while ((comma=strchr(comma, ',')))
-      *comma=' ';
-#endif
-  }
-
-  // Export information in environment variables that will be useful
-  // for user scripts
-  exportenv(environ_strings[0], "SMARTD_MAILER", executable);
-  exportenv(environ_strings[1], "SMARTD_MESSAGE", message);
-  exportenv(environ_strings[2], "SMARTD_SUBJECT", subject);
-  dateandtimezoneepoch(dates, mail->firstsent);
-  exportenv(environ_strings[3], "SMARTD_TFIRST", dates);
-  snprintf(dates, DATEANDEPOCHLEN,"%d", (int)mail->firstsent);
-  exportenv(environ_strings[4], "SMARTD_TFIRSTEPOCH", dates);
-  exportenv(environ_strings[5], "SMARTD_FAILTYPE", whichfail[which]);
-  if (address)
-    exportenv(environ_strings[6], "SMARTD_ADDRESS", address);
-  exportenv(environ_strings[7], "SMARTD_DEVICESTRING", cfg->name);
-
-  switch (cfg->controller_type) {
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_3WARE_9000_CHAR:
-  case CONTROLLER_3WARE_678K_CHAR:
-    {
-      char *s,devicetype[16];
-      sprintf(devicetype, "3ware,%d", cfg->controller_port-1);
-      exportenv(environ_strings[8], "SMARTD_DEVICETYPE", devicetype);
-      if ((s=strchr(cfg->name, ' ')))
-	*s='\0';
-      exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-      if (s)
-	*s=' ';
-    }
-    break;
-  case CONTROLLER_ATA:
-    exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "ata");
-    exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-    break;
-  case CONTROLLER_SCSI:
-    exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "scsi");
-    exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-  }
-
-  // now construct a command to send this as EMAIL
-#ifndef _WIN32
-  if (address)
-    snprintf(command, 2048, 
-             "$SMARTD_MAILER -s '%s' %s 2>&1 << \"ENDMAIL\"\n"
-             "This email was generated by the smartd daemon running on:\n\n"
-             "   host name: %s\n"
-             "  DNS domain: %s\n"
-             "  NIS domain: %s\n\n"
-             "The following warning/error was logged by the smartd daemon:\n\n"
-             "%s\n\n"
-             "For details see host's SYSLOG (default: /var/log/messages).\n\n"
-             "%s%s%s"
-             "ENDMAIL\n",
-	     subject, address, hostname, domainname, nisdomain, message, further, original, additional);
-  else
-    snprintf(command, 2048, "%s 2>&1", executable);
-  
-  // tell SYSLOG what we are about to do...
-  newadd=address?address:"<nomailer>";
-  newwarn=which?"Warning via":"Test of";
-
-  PrintOut(LOG_INFO,"%s %s to %s ...\n",
-           which?"Sending warning via":"Executing test of", executable, newadd);
-  
-  // issue the command to send mail or to run the user's executable
-  errno=0;
-  if (!(pfp=popen(command, "r")))
-    // failed to popen() mail process
-    PrintOut(LOG_CRIT,"%s %s to %s: failed (fork or pipe failed, or no memory) %s\n", 
-	     newwarn,  executable, newadd, errno?strerror(errno):"");
-  else {
-    // pipe suceeded!
-    int len, status;
-    char buffer[EBUFLEN];
-
-    // if unexpected output on stdout/stderr, null terminate, print, and flush
-    if ((len=fread(buffer, 1, EBUFLEN, pfp))) {
-      int count=0;
-      int newlen = len<EBUFLEN ? len : EBUFLEN-1;
-      buffer[newlen]='\0';
-      PrintOut(LOG_CRIT,"%s %s to %s produced unexpected output (%s%d bytes) to STDOUT/STDERR: \n%s\n", 
-	       newwarn, executable, newadd, len!=newlen?"here truncated to ":"", newlen, buffer);
-      
-      // flush pipe if needed
-      while (fread(buffer, 1, EBUFLEN, pfp) && count<EBUFLEN)
-	count++;
-
-      // tell user that pipe was flushed, or that something is really wrong
-      if (count && count<EBUFLEN)
-	PrintOut(LOG_CRIT,"%s %s to %s: flushed remaining STDOUT/STDERR\n", 
-		 newwarn, executable, newadd);
-      else if (count)
-	PrintOut(LOG_CRIT,"%s %s to %s: more than 1 MB STDOUT/STDERR flushed, breaking pipe\n", 
-		 newwarn, executable, newadd);
-    }
-    
-    // if something went wrong with mail process, print warning
-    errno=0;
-    if (-1==(status=pclose(pfp)))
-      PrintOut(LOG_CRIT,"%s %s to %s: pclose(3) failed %s\n", newwarn, executable, newadd,
-	       errno?strerror(errno):"");
-    else {
-      // mail process apparently succeeded. Check and report exit status
-      int status8;
-
-      if (WIFEXITED(status)) {
-	// exited 'normally' (but perhaps with nonzero status)
-	status8=WEXITSTATUS(status);
-	
-	if (status8>128)  
-	  PrintOut(LOG_CRIT,"%s %s to %s: failed (32-bit/8-bit exit status: %d/%d) perhaps caught signal %d [%s]\n", 
-		   newwarn, executable, newadd, status, status8, status8-128, strsignal(status8-128));
-	else if (status8)  
-	  PrintOut(LOG_CRIT,"%s %s to %s: failed (32-bit/8-bit exit status: %d/%d)\n", 
-		   newwarn, executable, newadd, status, status8);
-	else
-	  PrintOut(LOG_INFO,"%s %s to %s: successful\n", newwarn, executable, newadd);
-      }
-      
-      if (WIFSIGNALED(status))
-	PrintOut(LOG_INFO,"%s %s to %s: exited because of uncaught signal %d [%s]\n", 
-		 newwarn, executable, newadd, WTERMSIG(status), strsignal(WTERMSIG(status)));
-      
-      // this branch is probably not possible. If subprocess is
-      // stopped then pclose() should not return.
-      if (WIFSTOPPED(status)) 
-      	PrintOut(LOG_CRIT,"%s %s to %s: process STOPPED because it caught signal %d [%s]\n",
-		 newwarn, executable, newadd, WSTOPSIG(status), strsignal(WSTOPSIG(status)));
-      
-    }
-  }
-  
-#else // _WIN32
-
-  // No "here-documents" on Windows, so must use separate commandline and stdin
-  command[0] = stdinbuf[0] = 0;
-  boxtype = -1; boxmsgoffs = 0;
-  newadd = "<nomailer>";
-  if (address) {
-    // address "[sys]msgbox ..." => show warning (also) as [system modal ]messagebox
-    int addroffs = (!strncmp(address, "sys", 3) ? 3 : 0);
-    if (!strncmp(address+addroffs, "msgbox", 6) && (!address[addroffs+6] || address[addroffs+6] == ',')) {
-      boxtype = (addroffs > 0 ? 1 : 0);
-      addroffs += 6;
-      if (address[addroffs])
-        addroffs++;
-    }
-    else
-      addroffs = 0;
-
-    if (address[addroffs]) {
-      // Use "blat" parameter syntax (TODO: configure via -M for other mailers)
-      snprintf(command, sizeof(command),
-               "%s - -q -subject \"%s\" -to \"%s\"",
-               executable, subject, address+addroffs);
-      newadd = address+addroffs;
-    }
-    // Message for mail [0...] and messagebox [boxmsgoffs...]
-    snprintf(stdinbuf, sizeof(stdinbuf),
-             "This email was generated by the smartd daemon running on:\n\n"
-             "   host name: %s\n"
-             "  DNS domain: %s\n"
-//           "  NIS domain: %s\n"
-             "\n%n"
-             "The following warning/error was logged by the smartd daemon:\n\n"
-             "%s\n\n"
-             "For details see the event log or log file of smartd.\n\n"
-             "%s%s%s"
-             "\n",
-             hostname, /*domainname, */ nisdomain, &boxmsgoffs, message, further, original, additional);
-  }
-  else
-    snprintf(command, sizeof(command), "%s", executable);
-
-  newwarn=which?"Warning via":"Test of";
-  if (boxtype >= 0) {
-    // show message box
-    daemon_messagebox(boxtype, subject, stdinbuf+boxmsgoffs);
-    PrintOut(LOG_INFO,"%s message box\n", newwarn);
-  }
-  if (command[0]) {
-    char stdoutbuf[800]; // < buffer in syslog_win32::vsyslog()
-    int rc;
-    // run command
-    PrintOut(LOG_INFO,"%s %s to %s ...\n",
-             (which?"Sending warning via":"Executing test of"), executable, newadd);
-    rc = daemon_spawn(command, stdinbuf, strlen(stdinbuf), stdoutbuf, sizeof(stdoutbuf));
-    if (rc >= 0 && stdoutbuf[0])
-      PrintOut(LOG_CRIT,"%s %s to %s produced unexpected output (%d bytes) to STDOUT/STDERR:\n%s\n",
-        newwarn, executable, newadd, strlen(stdoutbuf), stdoutbuf);
-    if (rc != 0)
-      PrintOut(LOG_CRIT,"%s %s to %s: failed, exit status %d\n",
-        newwarn, executable, newadd, rc);
-    else
-      PrintOut(LOG_INFO,"%s %s to %s: successful\n", newwarn, executable, newadd);
-  }
-
-#endif // _WIN32
-
-  // increment mail sent counter
-  mail->logged++;
-  
-  // free copy of address (without commas)
-  address=FreeNonZero(address, -1, __LINE__, filenameandversion);
-
-  return;
-}
-
-// Printing function for watching ataprint commands, or losing them
-// [From GLIBC Manual: Since the prototype doesn't specify types for
-// optional arguments, in a call to a variadic function the default
-// argument promotions are performed on the optional argument
-// values. This means the objects of type char or short int (whether
-// signed or not) are promoted to either int or unsigned int, as
-// appropriate.]
-void pout(char *fmt, ...){
-  va_list ap;
-
-  // get the correct time in syslog()
-  FixGlibcTimeZoneBug();
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  // in debug==1 mode we will print the output from the ataprint.o functions!
-  if (debugmode && debugmode!=2)
-#ifdef _WIN32
-   if (facility == LOG_LOCAL1) // logging to stdout
-    vfprintf(stderr,fmt,ap);
-   else   
-#endif
-    vprintf(fmt,ap);
-  // in debug==2 mode we print output from knowndrives.o functions
-  else if (debugmode==2 || con->reportataioctl || con->reportscsiioctl || con->controller_port) {
-    openlog("smartd", LOG_PID, facility);
-    vsyslog(LOG_INFO, fmt, ap);
-    closelog();
-  }
-  va_end(ap);
-  fflush(NULL);
-  return;
-}
-
-// This function prints either to stdout or to the syslog as needed.
-// This function is also used by utility.c to report LOG_CRIT errors.
-void PrintOut(int priority,char *fmt, ...){
-  va_list ap;
-  
-  // get the correct time in syslog()
-  FixGlibcTimeZoneBug();
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  if (debugmode) 
-#ifdef _WIN32
-   if (facility == LOG_LOCAL1) // logging to stdout
-    vfprintf(stderr,fmt,ap);
-   else   
-#endif
-    vprintf(fmt,ap);
-  else {
-    openlog("smartd", LOG_PID, facility);
-    vsyslog(priority,fmt,ap);
-    closelog();
-  }
-  va_end(ap);
-  return;
-}
-
-// Forks new process, closes ALL file descriptors, redirects stdin,
-// stdout, and stderr.  Not quite daemon().  See
-// http://www.iar.unlp.edu.ar/~fede/revistas/lj/Magazines/LJ47/2335.html
-// for a good description of why we do things this way.
-void DaemonInit(){
-#ifndef _WIN32
-  pid_t pid;
-  int i;  
-
-  // flush all buffered streams.  Else we might get two copies of open
-  // streams since both parent and child get copies of the buffers.
-  fflush(NULL);
-  
-  if ((pid=fork()) < 0) {
-    // unable to fork!
-    PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  else if (pid)
-    // we are the parent process -- exit cleanly
-    EXIT(0);
-  
-  // from here on, we are the child process.
-  setsid();
-
-  // Fork one more time to avoid any possibility of having terminals
-  if ((pid=fork()) < 0) {
-    // unable to fork!
-    PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  else if (pid)
-    // we are the parent process -- exit cleanly
-    EXIT(0);
-
-  // Now we are the child's child...
-
-  // close any open file descriptors
-  for (i=getdtablesize();i>=0;--i)
-    close(i);
-  
-  // redirect any IO attempts to /dev/null for stdin
-  i=open("/dev/null",O_RDWR);
-  // stdout
-  dup(i);
-  // stderr
-  dup(i);
-  umask(0);
-  chdir("/");
-  
-  PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid());
-
-#else // _WIN32
-
-  // No fork() on native Win32
-  // Detach this process from console
-  fflush(NULL);
-  if (daemon_detach("smartd")) {
-    PrintOut(LOG_CRIT,"smartd unable to detach from console!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  // stdin/out/err now closed if not redirected
-
-#endif // _WIN32
-  return;
-}
-
-// create a PID file containing the current process id
-void WritePidFile() {
-  if (pid_file) {
-    int error = 0;
-    pid_t pid = getpid();
-    mode_t old_umask;
-    FILE* fp; 
-    
-    old_umask = umask(0077);
-    fp = fopen(pid_file, "w");
-    umask(old_umask);
-    if (fp == NULL) {
-      error = 1;
-    } else if (fprintf(fp, "%d\n", (int)pid) <= 0) {
-      error = 1;
-    } else if (fclose(fp) != 0) {
-      error = 1;
-    }
-    if (error) {
-      PrintOut(LOG_CRIT, "unable to write PID file %s - exiting.\n", pid_file);
-      EXIT(EXIT_PID);
-    }
-    PrintOut(LOG_INFO, "file %s written containing PID %d\n", pid_file, (int)pid);
-  }
-  return;
-}
-
-// Prints header identifying version of code and home
-void PrintHead(){
-  PrintOut(LOG_INFO,"smartd version %s [%s] Copyright (C) 2002-4 Bruce Allen\n", PACKAGE_VERSION, SMARTMONTOOLS_BUILD_HOST);
-  PrintOut(LOG_INFO,"Home page is " PACKAGE_HOMEPAGE "\n\n");
-  return;
-}
-
-// prints help info for configuration file Directives
-void Directives() {
-  PrintOut(LOG_INFO,
-           "Configuration file (%s) Directives (after device name):\n"
-           "  -d TYPE Set the device type: ata, scsi, removable, 3ware,N\n"
-           "  -T TYPE Set the tolerance to one of: normal, permissive\n"
-           "  -o VAL  Enable/disable automatic offline tests (on/off)\n"
-           "  -S VAL  Enable/disable attribute autosave (on/off)\n"
-           "  -n MODE No check if: never, sleep, standby, idle\n"
-           "  -H      Monitor SMART Health Status, report if failed\n"
-           "  -s REG  Do Self-Test at time(s) given by regular expression REG\n"
-           "  -l TYPE Monitor SMART log.  Type is one of: error, selftest\n"
-           "  -f      Monitor 'Usage' Attributes, report failures\n"
-           "  -m ADD  Send email warning to address ADD\n"
-           "  -M TYPE Modify email warning behavior (see man page)\n"
-           "  -p      Report changes in 'Prefailure' Attributes\n"
-           "  -u      Report changes in 'Usage' Attributes\n"
-           "  -t      Equivalent to -p and -u Directives\n"
-           "  -r ID   Also report Raw values of Attribute ID with -p, -u or -t\n"
-           "  -R ID   Track changes in Attribute ID Raw value with -p, -u or -t\n"
-           "  -i ID   Ignore Attribute ID for -f Directive\n"
-           "  -I ID   Ignore Attribute ID for -p, -u or -t Directive\n"
-	   "  -C ID   Monitor Current Pending Sectors in Attribute ID\n"
-	   "  -U ID   Monitor Offline Uncorrectable Sectors in Attribute ID\n"
-           "  -v N,ST Modifies labeling of Attribute N (see man page)  \n"
-           "  -P TYPE Drive-specific presets: use, ignore, show, showall\n"
-           "  -a      Default: -H -f -t -l error -l selftest -C 197 -U 198\n"
-           "  -F TYPE Firmware bug workaround: none, samsung, samsung2\n"
-           "   #      Comment: text after a hash sign is ignored\n"
-           "   \\      Line continuation character\n"
-           "Attribute ID is a decimal integer 1 <= ID <= 255\n"
-	   "Use ID = 0 to turn off -C and/or -U Directives\n"
-           "Example: /dev/hda -a\n", 
-           configfile);
-  return;
-}
-
-/* Returns a pointer to a static string containing a formatted list of the valid
-   arguments to the option opt or NULL on failure. */
-const char *GetValidArgList(char opt) {
-  switch (opt) {
-  case 'c':
-    return "<FILE_NAME>, -";
-  case 's':
-    return "valid_regular_expression";
-  case 'l':
-    return "daemon, local0, local1, local2, local3, local4, local5, local6, local7";
-  case 'q':
-    return "nodev, errors, nodevstartup, never, onecheck";
-  case 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 'p':
-    return "<FILE_NAME>";
-  case 'i':
-    return "<INTEGER_SECONDS>";
-  default:
-    return NULL;
-  }
-}
-
-/* prints help information for command syntax */
-void Usage (void){
-  PrintOut(LOG_INFO,"Usage: smartd [options]\n\n");
-#ifdef HAVE_GETOPT_LONG
-  PrintOut(LOG_INFO,"  -c NAME|-, --configfile=NAME|-\n");
-  PrintOut(LOG_INFO,"        Read configuration file NAME or stdin [default is %s]\n\n", configfile);
-  PrintOut(LOG_INFO,"  -d, --debug\n");
-  PrintOut(LOG_INFO,"        Start smartd in debug mode\n\n");
-  PrintOut(LOG_INFO,"  -D, --showdirectives\n");
-  PrintOut(LOG_INFO,"        Print the configuration file Directives and exit\n\n");
-  PrintOut(LOG_INFO,"  -h, --help, --usage\n");
-  PrintOut(LOG_INFO,"        Display this help and exit\n\n");
-  PrintOut(LOG_INFO,"  -i N, --interval=N\n");
-  PrintOut(LOG_INFO,"        Set interval between disk checks to N seconds, where N >= 10\n\n");
-  PrintOut(LOG_INFO,"  -l local[0-7], --logfacility=local[0-7]\n");
-#if !(defined(_WIN32) || defined(__CYGWIN__))
-  PrintOut(LOG_INFO,"        Use syslog facility local0 - local7 or daemon [default]\n\n");
-#else
-#ifdef _WIN32
-  PrintOut(LOG_INFO,"        Log to \"./smartd.log\", stdout, stderr [default is event log]\n\n");
-#else
-  PrintOut(LOG_INFO,"        Use syslog facility local0 - local7 (ignored on Cygwin)\n\n");
-#endif
-#endif // _WIN32 || __CYGWIN__
-  PrintOut(LOG_INFO,"  -p NAME, --pidfile=NAME\n");
-  PrintOut(LOG_INFO,"        Write PID file NAME\n\n");
-  PrintOut(LOG_INFO,"  -q WHEN, --quit=WHEN\n");
-  PrintOut(LOG_INFO,"        Quit on one of: %s\n\n", GetValidArgList('q'));
-  PrintOut(LOG_INFO,"  -r, --report=TYPE\n");
-  PrintOut(LOG_INFO,"        Report transactions for one of: %s\n\n", GetValidArgList('r'));
-#ifdef _WIN32
-  PrintOut(LOG_INFO,"  --service\n");
-  PrintOut(LOG_INFO,"        Running as windows service (must be first arg, do not use from console)\n\n");
-#endif // _WIN32
-  PrintOut(LOG_INFO,"  -V, --version, --license, --copyright\n");
-  PrintOut(LOG_INFO,"        Print License, Copyright, and version information\n");
-#else
-  PrintOut(LOG_INFO,"  -c NAME|-  Read configuration file NAME or stdin [default is %s]\n", configfile);
-  PrintOut(LOG_INFO,"  -d         Start smartd in debug mode\n");
-  PrintOut(LOG_INFO,"  -D         Print the configuration file Directives and exit\n");
-  PrintOut(LOG_INFO,"  -h         Display this help and exit\n");
-  PrintOut(LOG_INFO,"  -i N       Set interval between disk checks to N seconds, where N >= 10\n");
-  PrintOut(LOG_INFO,"  -l local?  Use syslog facility local0 - local7, or daemon\n");
-  PrintOut(LOG_INFO,"  -p NAME    Write PID file NAME\n");
-  PrintOut(LOG_INFO,"  -q WHEN    Quit on one of: %s\n", GetValidArgList('q'));
-  PrintOut(LOG_INFO,"  -r TYPE    Report transactions for one of: %s\n", GetValidArgList('r'));
-  PrintOut(LOG_INFO,"  -V         Print License, Copyright, and version information\n");
-#endif
-}
-
-// returns negative if problem, else fd>=0
-static int OpenDevice(char *device, char *mode, int scanning) {
-  int fd;
-  char *s=device;
-  
-  // If there is an ASCII "space" character in the device name,
-  // terminate string there.  This is for 3ware devices only.
-  if ((s=strchr(device,' ')))
-    *s='\0';
-
-  // open the device
-  fd = deviceopen(device, mode);
-
-  // if we removed a space, put it back in please
-  if (s)
-    *s=' ';
-
-  // if we failed to open the device, complain!
-  if (fd < 0) {
-
-    // For linux+devfs, a nonexistent device gives a strange error
-    // message.  This makes the error message a bit more sensible.
-    // If no debug and scanning - don't print errors
-    if (debugmode || !scanning) {
-      if (errno==ENOENT || errno==ENOTDIR)
-	errno=ENODEV;
-      
-      PrintOut(LOG_INFO,"Device: %s, %s, open() failed\n",
-	       device, strerror(errno));
-    }
-    return -1;
-  }
-  // device opened sucessfully
-  return fd;
-}
-
-int CloseDevice(int fd, char *name){
-  if (deviceclose(fd)){
-    PrintOut(LOG_INFO,"Device: %s, %s, close(%d) failed\n", name, strerror(errno), fd);
-    return 1;
-  }
-  // device sucessfully closed
-  return 0;
-}
-
-// returns <0 on failure
-int ATAErrorCount(int fd, char *name){
-  struct ata_smart_errorlog log;
-  
-  if (-1==ataReadErrorLog(fd,&log)){
-    PrintOut(LOG_INFO,"Device: %s, Read SMART Error Log Failed\n",name);
-    return -1;
-  }
-  
-  // return current number of ATA errors
-  return log.error_log_pointer?log.ata_error_count:0;
-}
-
-// returns <0 if problem.  Otherwise, bottom 8 bits are the self test
-// error count, and top bits are the power-on hours of the last error.
-int SelfTestErrorCount(int fd, char *name){
-  struct ata_smart_selftestlog log;
-
-  if (-1==ataReadSelfTestLog(fd,&log)){
-    PrintOut(LOG_INFO,"Device: %s, Read SMART Self Test Log Failed\n",name);
-    return -1;
-  }
-  
-  // return current number of self-test errors
-  return ataPrintSmartSelfTestlog(&log,0);
-}
-
-// scan to see what ata devices there are, and if they support SMART
-int ATADeviceScan(cfgfile *cfg, int scanning){
-  int fd, supported=0;
-  struct ata_identify_device drive;
-  char *name=cfg->name;
-  int retainsmartdata=0;
-  int retid;
-  char *mode;
-  
-  // should we try to register this as an ATA device?
-  switch (cfg->controller_type) {
-  case CONTROLLER_ATA:
-  case CONTROLLER_3WARE_678K:
-  case CONTROLLER_UNKNOWN:
-    mode="ATA";
-    break;
-  case CONTROLLER_3WARE_678K_CHAR:
-    mode="ATA_3WARE_678K";
-    break;
-  case CONTROLLER_3WARE_9000_CHAR:
-    mode="ATA_3WARE_9000";
-    break;
-  default:
-    // not a recognized ATA or SATA device.  We should never enter
-    // this branch.
-    return 1;
-  }
-  
-  // open the device
-  if ((fd=OpenDevice(name, mode, scanning))<0)
-    // device open failed
-    return 1;
-  PrintOut(LOG_INFO,"Device: %s, opened\n", name);
-  
-  // pass user settings on to low-level ATA commands
-  con->controller_port=cfg->controller_port;
-  con->controller_type=cfg->controller_type;
-  con->fixfirmwarebug = cfg->fixfirmwarebug;
-  
-  // Get drive identity structure
-  if ((retid=ataReadHDIdentity (fd,&drive))){
-    if (retid<0)
-      // Unable to read Identity structure
-      PrintOut(LOG_INFO,"Device: %s, not ATA, no IDENTIFY DEVICE Structure\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, packet devices [this device %s] not SMART capable\n",
-               name, packetdevicetype(retid-1));
-    CloseDevice(fd, name);
-    return 2; 
-  }
-
-  // Show if device in database, and use preset vendor attribute
-  // options unless user has requested otherwise.
-  if (cfg->ignorepresets)
-    PrintOut(LOG_INFO, "Device: %s, smartd database not searched (Directive: -P ignore).\n", name);
-  else {
-    // do whatever applypresets decides to do. Will allocate memory if
-    // cfg->attributedefs is needed.
-    if (applypresets(&drive, &cfg->attributedefs, con)<0)
-      PrintOut(LOG_INFO, "Device: %s, not found in smartd database.\n", name);
-    else
-      PrintOut(LOG_INFO, "Device: %s, found in smartd database.\n", name);
-    
-    // then save the correct state of the flag (applypresets may have changed it)
-    cfg->fixfirmwarebug = con->fixfirmwarebug;
-  }
-  
-  // If requested, show which presets would be used for this drive
-  if (cfg->showpresets) {
-    int savedebugmode=debugmode;
-    PrintOut(LOG_INFO, "Device %s: presets are:\n", name);
-    if (!debugmode)
-      debugmode=2;
-    showpresets(&drive);
-    debugmode=savedebugmode;
-  }
-
-  // see if drive supports SMART
-  supported=ataSmartSupport(&drive);
-  if (supported!=1) {
-    if (supported==0)
-      // drive does NOT support SMART
-      PrintOut(LOG_INFO,"Device: %s, lacks SMART capability\n",name);
-    else
-      // can't tell if drive supports SMART
-      PrintOut(LOG_INFO,"Device: %s, ATA IDENTIFY DEVICE words 82-83 don't specify if SMART capable.\n",name);
-  
-    // should we proceed anyway?
-    if (cfg->permissive){
-      PrintOut(LOG_INFO,"Device: %s, proceeding since '-T permissive' Directive given.\n",name);
-    }
-    else {
-      PrintOut(LOG_INFO,"Device: %s, to proceed anyway, use '-T permissive' Directive.\n",name);
-      CloseDevice(fd, name);
-      return 2;
-    }
-  }
-  
-  if (ataEnableSmart(fd)){
-    // Enable SMART command has failed
-    PrintOut(LOG_INFO,"Device: %s, could not enable SMART capability\n",name);
-    CloseDevice(fd, name);
-    return 2; 
-  }
-  
-  // disable device attribute autosave...
-  if (cfg->autosave==1){
-    if (ataDisableAutoSave(fd))
-      PrintOut(LOG_INFO,"Device: %s, could not disable SMART Attribute Autosave.\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, disabled SMART Attribute Autosave.\n",name);
-  }
-
-  // or enable device attribute autosave
-  if (cfg->autosave==2){
-    if (ataEnableAutoSave(fd))
-      PrintOut(LOG_INFO,"Device: %s, could not enable SMART Attribute Autosave.\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, enabled SMART Attribute Autosave.\n",name);
-  }
-
-  // capability check: SMART status
-  if (cfg->smartcheck && ataSmartStatus2(fd)==-1){
-    PrintOut(LOG_INFO,"Device: %s, not capable of SMART Health Status check\n",name);
-    cfg->smartcheck=0;
-  }
-  
-  // capability check: Read smart values and thresholds.  Note that
-  // smart values are ALSO needed even if we ONLY want to know if the
-  // device is self-test log or error-log capable!  After ATA-5, this
-  // information was ALSO reproduced in the IDENTIFY DEVICE response,
-  // but sadly not for ATA-5.  Sigh.
-
-  // do we need to retain SMART data after returning from this routine?
-  retainsmartdata=cfg->usagefailed || cfg->prefail || cfg->usage;
-  
-  // do we need to get SMART data?
-  if (retainsmartdata || cfg->autoofflinetest || cfg->selftest || cfg->errorlog || cfg->pending!=DONT_MONITOR_UNC) {
-
-    unsigned char currentpending, offlinepending;
-
-    cfg->smartval=(struct ata_smart_values *)Calloc(1,sizeof(struct ata_smart_values));
-    cfg->smartthres=(struct ata_smart_thresholds_pvt *)Calloc(1,sizeof(struct ata_smart_thresholds_pvt));
-    
-    if (!cfg->smartval || !cfg->smartthres){
-      PrintOut(LOG_CRIT,"Not enough memory to obtain SMART data\n");
-      EXIT(EXIT_NOMEM);
-    }
-    
-    if (ataReadSmartValues(fd,cfg->smartval) ||
-        ataReadSmartThresholds (fd,cfg->smartthres)){
-      PrintOut(LOG_INFO,"Device: %s, Read SMART Values and/or Thresholds Failed\n",name);
-      retainsmartdata=cfg->usagefailed=cfg->prefail=cfg->usage=0;
-      cfg->pending=DONT_MONITOR_UNC;
-    }
-    
-    // see if the necessary Attribute is there to monitor offline or
-    // current pending sectors
-    TranslatePending(cfg->pending, &currentpending, &offlinepending);
-    
-    if (currentpending && ATAReturnAttributeRawValue(currentpending, cfg->smartval)<0) {
-      PrintOut(LOG_INFO,"Device: %s, can't monitor Current Pending Sector count - no Attribute %d\n",
-	       name, (int)currentpending);
-      cfg->pending &= 0xff00;
-      cfg->pending |= CUR_UNC_DEFAULT;
-    }
-    
-    if (offlinepending && ATAReturnAttributeRawValue(offlinepending, cfg->smartval)<0) {
-      PrintOut(LOG_INFO,"Device: %s, can't monitor Offline Uncorrectable Sector count  - no Attribute %d\n",
-	       name, (int)offlinepending);
-      cfg->pending &= 0x00ff;
-      cfg->pending |= OFF_UNC_DEFAULT<<8;
-    }
-  }
-  
-  // enable/disable automatic on-line testing
-  if (cfg->autoofflinetest){
-    // is this an enable or disable request?
-    char *what=(cfg->autoofflinetest==1)?"disable":"enable";
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO,"Device: %s, could not %s SMART Automatic Offline Testing.\n",name, what);
-    else {
-      // if command appears unsupported, issue a warning...
-      if (!isSupportAutomaticTimer(cfg->smartval))
-        PrintOut(LOG_INFO,"Device: %s, SMART Automatic Offline Testing unsupported...\n",name);
-      // ... but then try anyway
-      if ((cfg->autoofflinetest==1)?ataDisableAutoOffline(fd):ataEnableAutoOffline(fd))
-        PrintOut(LOG_INFO,"Device: %s, %s SMART Automatic Offline Testing failed.\n", name, what);
-      else
-        PrintOut(LOG_INFO,"Device: %s, %sd SMART Automatic Offline Testing.\n", name, what);
-    }
-  }
-  
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int retval;
-    
-    // start with service disabled, and re-enable it if all works OK
-    cfg->selftest=0;
-    cfg->selflogcount=0;
-    cfg->selfloghour=0;
-
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Self-Test log (SMART READ DATA failed); disabling -l selftest\n", name);
-    else if (!cfg->permissive && !isSmartTestLogCapable(cfg->smartval, &drive))
-      PrintOut(LOG_INFO, "Device: %s, appears to lack SMART Self-Test log; disabling -l selftest (override with -T permissive Directive)\n", name);
-    else if ((retval=SelfTestErrorCount(fd, name))<0)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Self-Test log; remove -l selftest Directive from smartd.conf\n", name);
-    else {
-      cfg->selftest=1;
-      cfg->selflogcount=SELFTEST_ERRORCOUNT(retval);
-      cfg->selfloghour =SELFTEST_ERRORHOURS(retval);
-    }
-  }
-  
-  // capability check: ATA error log
-  if (cfg->errorlog){
-    int val;
-
-    // start with service disabled, and re-enable it if all works OK
-    cfg->errorlog=0;
-    cfg->ataerrorcount=0;
-
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Error log (SMART READ DATA failed); disabling -l error\n", name);
-    else if (!cfg->permissive && !isSmartErrorLogCapable(cfg->smartval, &drive))
-      PrintOut(LOG_INFO, "Device: %s, appears to lack SMART Error log; disabling -l error (override with -T permissive Directive)\n", name);
-    else if ((val=ATAErrorCount(fd, name))<0)
-      PrintOut(LOG_INFO, "Device: %s, no SMART Error log; remove -l error Directive from smartd.conf\n", name);
-    else {
-        cfg->errorlog=1;
-        cfg->ataerrorcount=val;
-    }
-  }
-  
-  // If we don't need to save SMART data, get rid of it now
-  if (!retainsmartdata) {
-    if (cfg->smartval) {
-      cfg->smartval=CheckFree(cfg->smartval, __LINE__,filenameandversion);
-      bytes-=sizeof(struct ata_smart_values);
-    }
-    if (cfg->smartthres) {
-      cfg->smartthres=CheckFree(cfg->smartthres, __LINE__,filenameandversion);
-      bytes-=sizeof(struct ata_smart_thresholds_pvt);
-    }
-  }
-
-  // capabilities check -- does it support powermode?
-  if (cfg->powermode) {
-    int powermode=ataCheckPowerMode(fd);
-    
-    if (-1 == powermode) {
-      PrintOut(LOG_CRIT, "Device: %s, no ATA CHECK POWER STATUS support, ignoring -n Directive\n", name);
-      cfg->powermode=0;
-    } 
-    else if (powermode!=0 && powermode!=0x80 && powermode!=0xff) {
-      PrintOut(LOG_CRIT, "Device: %s, CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Directive\n",
-	       name, powermode);
-      cfg->powermode=0;
-    }
-  }
-
-  // If no tests available or selected, return
-  if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck || 
-        cfg->usagefailed || cfg->prefail || cfg->usage)) {
-    CloseDevice(fd, name);
-    return 3;
-  }
-  
-  // Do we still have entries available?
-  while (numdevata>=atadevlist_max)
-    atadevlist=AllocateMoreSpace(atadevlist, &atadevlist_max, "ATA device");
-  
-  // register device
-  PrintOut(LOG_INFO,"Device: %s, is SMART capable. Adding to \"monitor\" list.\n",name);
-  
-    // record number of device, type of device, increment device count
-  if (cfg->controller_type == CONTROLLER_UNKNOWN)
-    cfg->controller_type=CONTROLLER_ATA;;
-  
-  // close file descriptor
-  CloseDevice(fd, name);
-  return 0;
-}
-
-// on success, return 0. On failure, return >0.  Never return <0,
-// please.
-static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
-  int k, fd, err; 
-  char *device = cfg->name;
-  struct scsi_iec_mode_page iec;
-  UINT8  tBuf[64];
-  
-  // should we try to register this as a SCSI device?
-  switch (con->controller_type) {
-  case CONTROLLER_SCSI:
-  case CONTROLLER_UNKNOWN:
-    break;
-  default:
-    return 1;
-  }
-  
-  // open the device
-  if ((fd = OpenDevice(device, "SCSI", scanning)) < 0)
-    return 1;
-  PrintOut(LOG_INFO,"Device: %s, opened\n", device);
-    
-  // check that device is ready for commands. IE stores its stuff on
-  // the media.
-  if ((err = scsiTestUnitReady(fd))) {
-    if (SIMPLE_ERR_NOT_READY == err)
-      PrintOut(LOG_INFO, "Device: %s, NOT READY (e.g. spun down); skip device\n", device);
-    else if (SIMPLE_ERR_NO_MEDIUM == err)
-      PrintOut(LOG_INFO, "Device: %s, NO MEDIUM present; skip device\n", device);
-    else if (SIMPLE_ERR_BECOMING_READY == err)
-      PrintOut(LOG_INFO, "Device: %s, BECOMING (but not yet) READY; skip device\n", device);
-    else
-      PrintOut(LOG_CRIT, "Device: %s, failed Test Unit Ready [err=%d]\n", device, err);
-    CloseDevice(fd, device);
-    return 2; 
-  }
-  
-  // Badly-conforming USB storage devices may fail this check.
-  // The response to the following IE mode page fetch (current and
-  // changeable values) is carefully examined. It has been found
-  // that various USB devices that malform the response will lock up
-  // if asked for a log page (e.g. temperature) so it is best to
-  // bail out now.
-  if (!(err = scsiFetchIECmpage(fd, &iec, cfg->modese_len)))
-    cfg->modese_len = iec.modese_len;
-  else if (SIMPLE_ERR_BAD_FIELD == err)
-    ;  /* continue since it is reasonable not to support IE mpage */
-  else { /* any other error (including malformed response) unreasonable */
-    PrintOut(LOG_INFO, 
-             "Device: %s, Bad IEC (SMART) mode page, err=%d, skip device\n", 
-             device, err);
-    CloseDevice(fd, device);
-    return 3;
-  }
-  
-  // N.B. The following is passive (i.e. it doesn't attempt to turn on
-  // smart if it is off). This may change to be the same as the ATA side.
-  if (!scsi_IsExceptionControlEnabled(&iec)) {
-    PrintOut(LOG_INFO, "Device: %s, IE (SMART) not enabled, skip device\n"
-	               "Try 'smartctl -s on %s' to turn on SMART features\n", 
-                        device, device);
-    CloseDevice(fd, device);
-    return 3;
-  }
-  
-  // Device exists, and does SMART.  Add to list (allocating more space if needed)
-  while (numdevscsi >= scsidevlist_max)
-    scsidevlist=AllocateMoreSpace(scsidevlist, &scsidevlist_max, "SCSI device");
-  
-  // Flag that certain log pages are supported (information may be
-  // available from other sources).
-  if (0 == scsiLogSense(fd, SUPPORTED_LPAGES, tBuf, sizeof(tBuf), 0)) {
-    for (k = 4; k < tBuf[3] + LOGPAGEHDRSIZE; ++k) {
-      switch (tBuf[k]) { 
-      case TEMPERATURE_LPAGE:
-        cfg->TempPageSupported = 1;
-        break;
-      case IE_LPAGE:
-        cfg->SmartPageSupported = 1;
-        break;
-      default:
-        break;
-      }
-    }   
-  }
-  
-  // record type of device
-  cfg->controller_type = CONTROLLER_SCSI;
-  
-  // get rid of allocated memory only needed for ATA devices.  These
-  // might have been allocated if the user specified Ignore options or
-  // other ATA-only Attribute-specific options on the DEVICESCAN line.
-  cfg->monitorattflags = FreeNonZero(cfg->monitorattflags, NMONITOR*32,__LINE__,filenameandversion);
-  cfg->attributedefs   = FreeNonZero(cfg->attributedefs,   MAX_ATTRIBUTE_NUM,__LINE__,filenameandversion);
-  cfg->smartval        = FreeNonZero(cfg->smartval,        sizeof(struct ata_smart_values),__LINE__,filenameandversion);
-  cfg->smartthres      = FreeNonZero(cfg->smartthres,      sizeof(struct ata_smart_thresholds_pvt),__LINE__,filenameandversion);
-  
-  // Check if scsiCheckIE() is going to work
-  {
-    UINT8 asc = 0;
-    UINT8 ascq = 0;
-    UINT8 currenttemp = 0;
-    UINT8 triptemp = 0;
-    
-    if (scsiCheckIE(fd, cfg->SmartPageSupported, cfg->TempPageSupported,
-                    &asc, &ascq, &currenttemp, &triptemp)) {
-      PrintOut(LOG_INFO, "Device: %s, unexpectedly failed to read SMART values\n", device);
-      cfg->SuppressReport = 1;
-    }
-  }
-  
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int retval=scsiCountFailedSelfTests(fd, 0);
-    if (retval<0) {
-      // no self-test log, turn off monitoring
-      PrintOut(LOG_INFO, "Device: %s, does not support SMART Self-Test Log.\n", device);
-      cfg->selftest=0;
-      cfg->selflogcount=0;
-      cfg->selfloghour=0;
-    }
-    else {
-      // register starting values to watch for changes
-      cfg->selflogcount=SELFTEST_ERRORCOUNT(retval);
-      cfg->selfloghour =SELFTEST_ERRORHOURS(retval);
-    }
-  }
-  
-  // disable autosave (set GLTSD bit)
-  if (cfg->autosave==1){
-    if (scsiSetControlGLTSD(fd, 1, cfg->modese_len))
-      PrintOut(LOG_INFO,"Device: %s, could not disable autosave (set GLTSD bit).\n",device);
-    else
-      PrintOut(LOG_INFO,"Device: %s, disabled autosave (set GLTSD bit).\n",device);
-  }
-
-  // or enable autosave (clear GLTSD bit)
-  if (cfg->autosave==2){
-    if (scsiSetControlGLTSD(fd, 0, cfg->modese_len))
-      PrintOut(LOG_INFO,"Device: %s, could not enable autosave (clear GLTSD bit).\n",device);
-    else
-      PrintOut(LOG_INFO,"Device: %s, enabled autosave (cleared GLTSD bit).\n",device);
-  }
-  
-  // tell user we are registering device
-  PrintOut(LOG_INFO, "Device: %s, is SMART capable. Adding to \"monitor\" list.\n", device);
-  
-  // close file descriptor
-  CloseDevice(fd, device);
-  return 0;
-}
-
-// We compare old and new values of the n'th attribute.  Note that n
-// is NOT the attribute ID number.. If (Normalized & Raw) equal,
-// then return 0, else nonzero.
-int  ATACompareValues(changedattribute_t *delta,
-                            struct ata_smart_values *new,
-                            struct ata_smart_values *old,
-                            struct ata_smart_thresholds_pvt *thresholds,
-                            int n, char *name){
-  struct ata_smart_attribute *now,*was;
-  struct ata_smart_threshold_entry *thre;
-  unsigned char oldval,newval;
-  int sameraw;
-
-  // check that attribute number in range, and no null pointers
-  if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !new || !old || !thresholds)
-    return 0;
-  
-  // pointers to disk's values and vendor's thresholds
-  now=new->vendor_attributes+n;
-  was=old->vendor_attributes+n;
-  thre=thresholds->thres_entries+n;
-
-  // consider only valid attributes
-  if (!now->id || !was->id || !thre->id)
-    return 0;
-  
-  
-  // issue warning if they don't have the same ID in all structures:
-  if ( (now->id != was->id) || (now->id != thre->id) ){
-    PrintOut(LOG_INFO,"Device: %s, same Attribute has different ID numbers: %d = %d = %d\n",
-             name, (int)now->id, (int)was->id, (int)thre->id);
-    return 0;
-  }
-
-  // new and old values of Normalized Attributes
-  newval=now->current;
-  oldval=was->current;
-
-  // See if the RAW values are unchanged (ie, the same)
-  if (memcmp(now->raw, was->raw, 6))
-    sameraw=0;
-  else
-    sameraw=1;
-  
-  // if any values out of the allowed range, or if the values haven't
-  // changed, return 0
-  if (!newval || !oldval || newval>0xfe || oldval>0xfe || (oldval==newval && sameraw))
-    return 0;
-  
-  // values have changed.  Construct output and return
-  delta->newval=newval;
-  delta->oldval=oldval;
-  delta->id=now->id;
-  delta->prefail=ATTRIBUTE_FLAGS_PREFAILURE(now->flags);
-  delta->sameraw=sameraw;
-
-  return 1;
-}
-
-// This looks to see if the corresponding bit of the 32 bytes is set.
-// This wastes a few bytes of storage but eliminates all searching and
-// sorting functions! Entry is ZERO <==> the attribute ON. Calling
-// with set=0 tells you if the attribute is being tracked or not.
-// Calling with set=1 turns the attribute OFF.
-int IsAttributeOff(unsigned char attr, unsigned char **datap, int set, int which, int whatline){
-  unsigned char *data;
-  int loc=attr>>3;
-  int bit=attr & 0x07;
-  unsigned char mask=0x01<<bit;
-
-  if (which>=NMONITOR || which < 0){
-    PrintOut(LOG_CRIT, "Internal error in IsAttributeOff() at line %d of file %s (which=%d)\n%s",
-             whatline, filenameandversion, which, reportbug);
-    EXIT(EXIT_BADCODE);
-  }
-
-  if (*datap == NULL){
-    // NULL data implies Attributes are ON...
-    if (!set)
-      return 0;
-    
-    // we are writing
-    if (!(*datap=(unsigned char *)Calloc(NMONITOR*32, 1))){
-      PrintOut(LOG_CRIT,"No memory to create monattflags\n");
-      EXIT(EXIT_NOMEM);
-    }
-  }
-  
-  // pointer to the 256 bits that we need
-  data=*datap+which*32;
-
-  // attribute zero is always OFF
-  if (!attr)
-    return 1;
-
-  if (!set)
-    return (data[loc] & mask);
-  
-  data[loc]|=mask;
-
-  // return value when setting has no sense
-  return 0;
-}
-
-// If the self-test log has got more self-test errors (or more recent
-// self-test errors) recorded, then notify user.
-void CheckSelfTestLogs(cfgfile *cfg, int new){
-  char *name=cfg->name;
-
-  if (new<0)
-    // command failed
-    MailWarning(cfg, 8, "Device: %s, Read SMART Self-Test Log Failed", name);
-  else {      
-    // old and new error counts
-    int oldc=cfg->selflogcount;
-    int newc=SELFTEST_ERRORCOUNT(new);
-    
-    // old and new error timestamps in hours
-    int oldh=cfg->selfloghour;
-    int newh=SELFTEST_ERRORHOURS(new);
-    
-    if (oldc<newc) {
-      // increase in error count
-      PrintOut(LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d\n",
-               name, oldc, newc);
-      MailWarning(cfg, 3, "Device: %s, Self-Test Log error count increased from %d to %d",
-                   name, oldc, newc);
-    } else if (oldh<newh) {
-      // more recent error
-      PrintOut(LOG_CRIT, "Device: %s, new Self-Test Log error at hour timestamp %d\n",
-               name, newh);
-      MailWarning(cfg, 3, "Device: %s, new Self-Test Log error at hour timestamp %d\n",
-                   name, newh);
-    }
-    
-    // Needed since self-test error count may DECREASE.  Hour should
-    // never decrease but this does no harm.
-    cfg->selflogcount= newc;
-    cfg->selfloghour = newh;
-  }
-  return;
-}
-
-// returns 1 if time to do test of type testtype, 0 if not time to do
-// test, < 0 if error
-int DoTestNow(cfgfile *cfg, char testtype) {
-  // start by finding out the time:
-  struct tm *timenow;
-  time_t epochnow;
-  char matchpattern[16];
-  regmatch_t substring;
-  int weekday, length;
-  unsigned short hours;
-  testinfo *dat=cfg->testdata;
-
-  // check that self-testing has been requested
-  if (!dat)
-    return 0;
-  
-  // since we are about to call localtime(), be sure glibc is informed
-  // of any timezone changes we make.
-  FixGlibcTimeZoneBug();
-  
-  // construct pattern containing the month, day of month, day of
-  // week, and hour
-  time(&epochnow);
-  timenow=localtime(&epochnow);
-  
-  // tm_wday is 0 (Sunday) to 6 (Saturday).  We use 1 (Monday) to 7
-  // (Sunday).
-  weekday=timenow->tm_wday?timenow->tm_wday:7;
-  sprintf(matchpattern, "%c/%02d/%02d/%1d/%02d", testtype, timenow->tm_mon+1, 
-          timenow->tm_mday, weekday, timenow->tm_hour);
-  
-  // if no match, we are done
-  if (regexec(&(dat->cregex), matchpattern, 1, &substring, 0))
-    return 0;
-  
-  // must match the ENTIRE type/date/time string
-  length=strlen(matchpattern);
-  if (substring.rm_so!=0 || substring.rm_eo!=length)
-    return 0;
-  
-  // never do a second test in the same hour as another test (the % 7 ensures
-  // that the RHS will never be greater than 65535 and so will always fit into
-  // an unsigned short)
-  hours=1+timenow->tm_hour+24*(timenow->tm_yday+366*(timenow->tm_year % 7));
-  if (hours==dat->hour) {
-    if (testtype!=dat->testtype)
-      PrintOut(LOG_INFO, "Device: %s, did test of type %c in current hour, skipping test of type %c\n",
-	       cfg->name, dat->testtype, testtype);
-    return 0;
-  }
-  
-  // save time and type of the current test; we are ready to do a test
-  dat->hour=hours;
-  dat->testtype=testtype;
-  return 1;
-}
-
-// Return zero on success, nonzero on failure. Perform offline (background)
-// short or long (extended) self test on given scsi device.
-int DoSCSISelfTest(int fd, cfgfile *cfg, char testtype) {
-  int retval = 0;
-  char *testname = NULL;
-  char *name = cfg->name;
-  int inProgress;
-
-  if (scsiSelfTestInProgress(fd, &inProgress)) {
-    PrintOut(LOG_CRIT, "Device: %s, does not support Self-Tests\n", name);
-    cfg->testdata->not_cap_short=cfg->testdata->not_cap_long=1;
-    return 1;
-  }
-
-  if (1 == inProgress) {
-    PrintOut(LOG_INFO, "Device: %s, skip since Self-Test already in "
-             "progress.\n", name);
-    return 1;
-  }
-
-  switch (testtype) {
-  case 'S':
-    testname = "Short Self";
-    retval = scsiSmartShortSelfTest(fd);
-    break;
-  case 'L':
-    testname = "Long Self";
-    retval = scsiSmartExtendSelfTest(fd);
-    break;
-  }
-  // If we can't do the test, exit
-  if (NULL == testname) {
-    PrintOut(LOG_CRIT, "Device: %s, not capable of %c Self-Test\n", name, 
-             testtype);
-    return 1;
-  }
-  if (retval) {
-    if ((SIMPLE_ERR_BAD_OPCODE == retval) || 
-        (SIMPLE_ERR_BAD_FIELD == retval)) {
-      PrintOut(LOG_CRIT, "Device: %s, not capable of %s-Test\n", name, 
-               testname);
-      if ('L'==testtype)
-        cfg->testdata->not_cap_long=1;
-      else
-        cfg->testdata->not_cap_short=1;
-     
-      return 1;
-    }
-    PrintOut(LOG_CRIT, "Device: %s, execute %s-Test failed (err: %d)\n", name, 
-             testname, retval);
-    return 1;
-  }
-  
-  PrintOut(LOG_INFO, "Device: %s, starting scheduled %s-Test.\n", name, testname);
-  
-  return 0;
-}
-
-// Do an offline immediate or self-test.  Return zero on success,
-// nonzero on failure.
-int DoATASelfTest(int fd, cfgfile *cfg, char testtype) {
-  
-  struct ata_smart_values data;
-  char *testname=NULL;
-  int retval, dotest=-1;
-  char *name=cfg->name;
-  
-  // Read current smart data and check status/capability
-  if (ataReadSmartValues(fd, &data) || !(data.offline_data_collection_capability)) {
-    PrintOut(LOG_CRIT, "Device: %s, not capable of Offline or Self-Testing.\n", name);
-    return 1;
-  }
-  
-  // Check for capability to do the test
-  switch (testtype) {
-  case 'O':
-    testname="Offline Immediate ";
-    if (isSupportExecuteOfflineImmediate(&data))
-      dotest=OFFLINE_FULL_SCAN;
-    else
-      cfg->testdata->not_cap_offline=1;
-    break;
-  case 'C':
-    testname="Conveyance Self-";
-    if (isSupportConveyanceSelfTest(&data))
-      dotest=CONVEYANCE_SELF_TEST;
-    else
-      cfg->testdata->not_cap_conveyance=1;
-    break;
-  case 'S':
-    testname="Short Self-";
-    if (isSupportSelfTest(&data))
-      dotest=SHORT_SELF_TEST;
-    else
-      cfg->testdata->not_cap_short=1;
-    break;
-  case 'L':
-    testname="Long Self-";
-    if (isSupportSelfTest(&data))
-      dotest=EXTEND_SELF_TEST;
-    else
-      cfg->testdata->not_cap_long=1;
-    break;
-  }
-  
-  // If we can't do the test, exit
-  if (dotest<0) {
-    PrintOut(LOG_CRIT, "Device: %s, not capable of %sTest\n", name, testname);
-    return 1;
-  }
-  
-  // If currently running a self-test, do not interrupt it to start another.
-  if (15==(data.self_test_exec_status >> 4)) {
-    PrintOut(LOG_INFO, "Device: %s, skip scheduled %sTest; %1d0%% remaining of current Self-Test.\n",
-             name, testname, (int)(data.self_test_exec_status & 0x0f));
-    return 1;
-  }
-
-  // else execute the test, and return status
-  if ((retval=smartcommandhandler(fd, IMMEDIATE_OFFLINE, dotest, NULL)))
-    PrintOut(LOG_CRIT, "Device: %s, execute %sTest failed.\n", name, testname);
-  else
-    PrintOut(LOG_INFO, "Device: %s, starting scheduled %sTest.\n", name, testname);
-  
-  return retval;
-}
-
-
-int ATACheckDevice(cfgfile *cfg){
-  int fd,i;
-  char *name=cfg->name;
-  char *mode="ATA";
-  
-  // fix firmware bug if requested
-  con->fixfirmwarebug=cfg->fixfirmwarebug;
-  con->controller_port=cfg->controller_port;
-  con->controller_type=cfg->controller_type;
-
-  // If user has asked, test the email warning system
-  if (cfg->mailwarn && cfg->mailwarn->emailtest)
-    MailWarning(cfg, 0, "TEST EMAIL from smartd for device: %s", name);
-
-  if (cfg->controller_type == CONTROLLER_3WARE_9000_CHAR)
-    mode="ATA_3WARE_9000";
-  
-  if (cfg->controller_type == CONTROLLER_3WARE_678K_CHAR)
-    mode="ATA_3WARE_678K";
-
-  // if we can't open device, fail gracefully rather than hard --
-  // perhaps the next time around we'll be able to open it.  ATAPI
-  // cd/dvd devices will hang awaiting media if O_NONBLOCK is not
-  // given (see linux cdrom driver).
-  if ((fd=OpenDevice(name, mode, 0))<0){
-    MailWarning(cfg, 9, "Device: %s, unable to open device", name);
-    return 1;
-  }
-
-  // user may have requested (with the -n Directive) to leave the disk
-  // alone if it is in idle or sleeping mode.  In this case check the
-  // power mode and exit without check if needed
-  if (cfg->powermode){
-    int dontcheck=0, powermode=ataCheckPowerMode(fd);
-    char *mode=NULL;
-        
-    switch (powermode){
-    case -1:
-      // SLEEP
-      mode="SLEEP";
-      if (cfg->powermode>=1)
-	dontcheck=1;
-      break;
-    case 0:
-      // STANDBY
-      mode="STANDBY";
-      if (cfg->powermode>=2)
-	dontcheck=1;
-      break;
-    case 0x80:
-      // IDLE
-      mode="IDLE";
-      if (cfg->powermode>=3)
-	dontcheck=1;
-      break;
-    case 0xff:
-      // ACTIVE/IDLE
-      break;
-    default:
-      // UNKNOWN
-      PrintOut(LOG_CRIT, "Device: %s, CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Directive\n",
-	       name, powermode);
-      cfg->powermode=0;
-      break;
-    }
-
-    // if we are going to skip a check, return now
-    if (dontcheck){
-      CloseDevice(fd, name);
-      PrintOut(LOG_INFO, "Device: %s, is in %s mode, skipping checks\n", name, mode);
-      return 0;
-    }    
-  }
-
-  // check smart status
-  if (cfg->smartcheck){
-    int status=ataSmartStatus2(fd);
-    if (status==-1){
-      PrintOut(LOG_INFO,"Device: %s, not capable of SMART self-check\n",name);
-      MailWarning(cfg, 5, "Device: %s, not capable of SMART self-check", name);
-    }
-    else if (status==1){
-      PrintOut(LOG_CRIT, "Device: %s, FAILED SMART self-check. BACK UP DATA NOW!\n", name);
-      MailWarning(cfg, 1, "Device: %s, FAILED SMART self-check. BACK UP DATA NOW!", name);
-    }
-  }
-  
-  // Check everything that depends upon SMART Data (eg, Attribute values)
-  if (cfg->usagefailed || cfg->prefail || cfg->usage || cfg->pending!=DONT_MONITOR_UNC){
-    struct ata_smart_values     curval;
-    struct ata_smart_thresholds_pvt *thresh=cfg->smartthres;
-    
-    // Read current attribute values. *drive contains old values and thresholds
-    if (ataReadSmartValues(fd,&curval)){
-      PrintOut(LOG_CRIT, "Device: %s, failed to read SMART Attribute Data\n", name);
-      MailWarning(cfg, 6, "Device: %s, failed to read SMART Attribute Data", name);
-    }
-    else {
-      // look for current or offline pending sectors
-      if (cfg->pending != DONT_MONITOR_UNC) {
-	int64_t rawval;
-	unsigned char currentpending, offlinepending;
-	
-	TranslatePending(cfg->pending, &currentpending, &offlinepending);
-	
-	if (currentpending && (rawval=ATAReturnAttributeRawValue(currentpending, &curval))>0) {
-	  // Unreadable pending sectors!!
-	  PrintOut(LOG_CRIT,   "Device: %s, %"PRId64" Currently unreadable (pending) sectors\n", name, rawval);
-	  MailWarning(cfg, 10, "Device: %s, %"PRId64" Currently unreadable (pending) sectors", name, rawval);
-	}
-	
-	if (offlinepending && (rawval=ATAReturnAttributeRawValue(offlinepending, &curval))>0) {
-	  // Unreadable offline sectors!!
-	  PrintOut(LOG_CRIT,   "Device: %s, %"PRId64" Offline uncorrectable sectors\n", name, rawval);
-	  MailWarning(cfg, 11, "Device: %s, %"PRId64" Offline uncorrectable sectors", name, rawval);
-	}
-      }
-
-      if (cfg->usagefailed || cfg->prefail || cfg->usage) {
-
-	// look for failed usage attributes, or track usage or prefail attributes
-	for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-	  int att;
-	  changedattribute_t delta;
-	  
-	  // This block looks for usage attributes that have failed.
-	  // Prefail attributes that have failed are returned with a
-	  // positive sign. No failure returns 0. Usage attributes<0.
-	  if (cfg->usagefailed && ((att=ataCheckAttribute(&curval, thresh, i))<0)){
-	    
-	    // are we ignoring failures of this attribute?
-	    att *= -1;
-	    if (!IsAttributeOff(att, &cfg->monitorattflags, 0, MONITOR_FAILUSE, __LINE__)){
-	      char attname[64], *loc=attname;
-	      
-	      // get attribute name & skip white space
-	      ataPrintSmartAttribName(loc, att, cfg->attributedefs);
-	      while (*loc && *loc==' ') loc++;
-	      
-	      // warning message
-	      PrintOut(LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc);
-	      MailWarning(cfg, 2, "Device: %s, Failed SMART usage Attribute: %s.", name, loc);
-	    }
-	  }
-	  
-	  // This block tracks usage or prefailure attributes to see if
-	  // they are changing.  It also looks for changes in RAW values
-	  // if this has been requested by user.
-	  if ((cfg->usage || cfg->prefail) && ATACompareValues(&delta, &curval, cfg->smartval, thresh, i, name)){
-	    unsigned char id=delta.id;
-	    
-	    // if the only change is the raw value, and we're not
-	    // tracking raw value, then continue loop over attributes
-	    if (!delta.sameraw && delta.newval==delta.oldval && !IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_RAW, __LINE__))
-	      continue;
-	    
-	    // are we tracking this attribute?
-	    if (!IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_IGNORE, __LINE__)){
-	      char newrawstring[64], oldrawstring[64], attname[64], *loc=attname;
-	      
-	      // get attribute name, skip spaces
-	      ataPrintSmartAttribName(loc, id, cfg->attributedefs);
-	      while (*loc && *loc==' ') loc++;
-	      
-	      // has the user asked for us to print raw values?
-	      if (IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_RAWPRINT, __LINE__)) {
-		// get raw values (as a string) and add to printout
-		char rawstring[64];
-		ataPrintSmartAttribRawValue(rawstring, curval.vendor_attributes+i, cfg->attributedefs);
-		sprintf(newrawstring, " [Raw %s]", rawstring);
-		ataPrintSmartAttribRawValue(rawstring, cfg->smartval->vendor_attributes+i, cfg->attributedefs);
-		sprintf(oldrawstring, " [Raw %s]", rawstring);
-	      }
-	      else
-		newrawstring[0]=oldrawstring[0]='\0';
-	      
-	      // prefailure attribute
-	      if (cfg->prefail && delta.prefail)
-		PrintOut(LOG_INFO, "Device: %s, SMART Prefailure Attribute: %s changed from %d%s to %d%s\n",
-			 name, loc, delta.oldval, oldrawstring, delta.newval, newrawstring);
-	      
-	      // usage attribute
-	      if (cfg->usage && !delta.prefail)
-		PrintOut(LOG_INFO, "Device: %s, SMART Usage Attribute: %s changed from %d%s to %d%s\n",
-			 name, loc, delta.oldval, oldrawstring, delta.newval, newrawstring);
-	    }
-	  } // endof block tracking usage or prefailure
-	} // end of loop over attributes
-	
-	// Save the new values into *drive for the next time around
-	*(cfg->smartval)=curval;
-      }
-    }
-  }
-  
-  // check if number of selftest errors has increased (note: may also DECREASE)
-  if (cfg->selftest)
-    CheckSelfTestLogs(cfg, SelfTestErrorCount(fd, name));
-  
-  // check if number of ATA errors has increased
-  if (cfg->errorlog){
-
-    int new,old=cfg->ataerrorcount;
-
-    // new number of errors
-    new=ATAErrorCount(fd, name);
-
-    // did command fail?
-    if (new<0)
-      // lack of PrintOut here is INTENTIONAL
-      MailWarning(cfg, 7, "Device: %s, Read SMART Error Log Failed", name);
-
-    // has error count increased?
-    if (new>old){
-      PrintOut(LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n",
-               name, old, new);
-      MailWarning(cfg, 4, "Device: %s, ATA error count increased from %d to %d",
-                   name, old, new);
-    }
-    
-    // this last line is probably not needed, count always increases
-    if (new>=0)
-      cfg->ataerrorcount=new;
-  }
-  
-  // if the user has asked, and device is capable (or we're not yet
-  // sure) carry out scheduled self-tests.
-  if (cfg->testdata) {
-    // long test
-    if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L')>0)
-      DoATASelfTest(fd, cfg, 'L');    
-    // short test
-    else if (!cfg->testdata->not_cap_short && DoTestNow(cfg, 'S')>0)
-      DoATASelfTest(fd, cfg, 'S');
-    // conveyance test
-    else if (!cfg->testdata->not_cap_conveyance && DoTestNow(cfg, 'C')>0)
-      DoATASelfTest(fd, cfg, 'C');
-    // offline immediate
-    else if (!cfg->testdata->not_cap_offline && DoTestNow(cfg, 'O')>0)
-      DoATASelfTest(fd, cfg, 'O');  
-  }
-  
-  // Don't leave device open -- the OS/user may want to access it
-  // before the next smartd cycle!
-  CloseDevice(fd, name);
-  return 0;
-}
-
-#define DEF_SCSI_REPORT_TEMPERATURE_DELTA 2
-static int scsi_report_temperature_delta = DEF_SCSI_REPORT_TEMPERATURE_DELTA;
-
-int SCSICheckDevice(cfgfile *cfg)
-{
-    UINT8 asc, ascq;
-    UINT8 currenttemp;
-    UINT8 triptemp;
-    int fd;
-    char *name=cfg->name;
-    const char *cp;
-
-    // If the user has asked for it, test the email warning system
-    if (cfg->mailwarn && cfg->mailwarn->emailtest)
-      MailWarning(cfg, 0, "TEST EMAIL from smartd for device: %s", name);
-
-    // if we can't open device, fail gracefully rather than hard --
-    // perhaps the next time around we'll be able to open it
-    if ((fd=OpenDevice(name, "SCSI", 0))<0) {
-      // Lack of PrintOut() here is intentional!
-      MailWarning(cfg, 9, "Device: %s, unable to open device", name);
-      return 1;
-    }
-    currenttemp = 0;
-    asc = 0;
-    ascq = 0;
-    if (! cfg->SuppressReport) {
-        if (scsiCheckIE(fd, cfg->SmartPageSupported, cfg->TempPageSupported,
-                        &asc, &ascq, &currenttemp, &triptemp)) {
-            PrintOut(LOG_INFO, "Device: %s, failed to read SMART values\n",
-                      name);
-            MailWarning(cfg, 6, "Device: %s, failed to read SMART values", name);
-            cfg->SuppressReport = 1;
-        }
-    }
-    if (asc > 0) {
-        cp = scsiGetIEString(asc, ascq);
-        if (cp) {
-            PrintOut(LOG_CRIT, "Device: %s, SMART Failure: %s\n", name, cp);
-            MailWarning(cfg, 1,"Device: %s, SMART Failure: %s", name, cp); 
-        }
-    } else if (debugmode)
-        PrintOut(LOG_INFO,"Device: %s, Acceptable asc,ascq: %d,%d\n", 
-                 name, (int)asc, (int)ascq);  
-  
-    if (currenttemp && currenttemp!=255) {
-        if (cfg->Temperature) {
-            if (abs(((int)currenttemp - (int)cfg->Temperature)) >= 
-                scsi_report_temperature_delta) {
-                PrintOut(LOG_INFO, "Device: %s, Temperature changed %d Celsius "
-                         "to %d Celsius since last report\n", name, 
-                         (int)(currenttemp - cfg->Temperature), 
-                         (int)currenttemp);
-                cfg->Temperature = currenttemp;
-            }
-        }
-        else {
-            PrintOut(LOG_INFO, "Device: %s, initial Temperature is %d "
-                     "Celsius\n", name, (int)currenttemp);
-           if (triptemp)
-                PrintOut(LOG_INFO, "    [trip Temperature is %d Celsius]\n",
-                         (int)triptemp);
-            cfg->Temperature = currenttemp;
-            cfg->Temperature = currenttemp;
-        }
-    }
-    
-    // check if number of selftest errors has increased (note: may also DECREASE)
-    if (cfg->selftest)
-      CheckSelfTestLogs(cfg, scsiCountFailedSelfTests(fd, 0));
-    
-    if (cfg->testdata) {
-      // long (extended) background test
-      if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L')>0)
-        DoSCSISelfTest(fd, cfg, 'L');
-      // short background test
-      else if (!cfg->testdata->not_cap_short && DoTestNow(cfg, 'S')>0)
-        DoSCSISelfTest(fd, cfg, 'S');
-    }
-    CloseDevice(fd, name);
-    return 0;
-}
-
-// Checks the SMART status of all ATA and SCSI devices
-void CheckDevicesOnce(cfgfile **atadevices, cfgfile **scsidevices){
-  int i;
-  
-  for (i=0; i<numdevata; i++) 
-    ATACheckDevice(atadevices[i]);
-  
-  for (i=0; i<numdevscsi; i++)
-    SCSICheckDevice(scsidevices[i]);
-
-  return;
-}
-
-#if SCSITIMEOUT
-// This alarm means that a SCSI USB device was hanging
-void AlarmHandler(int signal) {
-  longjmp(registerscsienv, 1);
-}
-#endif
-
-// Does initialization right after fork to daemon mode
-void Initialize(time_t *wakeuptime){
-
-  // install goobye message and remove pidfile handler
-  atexit(Goodbye);
-  
-  // write PID file only after installing exit handler
-  if (!debugmode)
-    WritePidFile();
-  
-  // install signal handlers.  On Solaris, can't use signal() because
-  // it resets the handler to SIG_DFL after each call.  So use sigset()
-  // instead.  So SIGNALFN()==signal() or SIGNALFN()==sigset().
-  
-  // normal and abnormal exit
-  if (SIGNALFN(SIGTERM, sighandler)==SIG_IGN)
-    SIGNALFN(SIGTERM, SIG_IGN);
-  if (SIGNALFN(SIGQUIT, sighandler)==SIG_IGN)
-    SIGNALFN(SIGQUIT, SIG_IGN);
-  
-  // in debug mode, <CONTROL-C> ==> HUP
-  if (SIGNALFN(SIGINT, debugmode?HUPhandler:sighandler)==SIG_IGN)
-    SIGNALFN(SIGINT, SIG_IGN);
-  
-  // Catch HUP and USR1
-  if (SIGNALFN(SIGHUP, HUPhandler)==SIG_IGN)
-    SIGNALFN(SIGHUP, SIG_IGN);
-  if (SIGNALFN(SIGUSR1, USR1handler)==SIG_IGN)
-    SIGNALFN(SIGUSR1, SIG_IGN);
-#ifdef _WIN32
-  if (SIGNALFN(SIGUSR2, USR2handler)==SIG_IGN)
-    SIGNALFN(SIGUSR2, SIG_IGN);
-#endif
-
-  // initialize wakeup time to CURRENT time
-  *wakeuptime=time(NULL);
-  
-  return;
-}
-
-#ifdef _WIN32
-// Toggle debug mode implemented for native windows only
-// (there is no easy way to reopen tty on *nix)
-static void ToggleDebugMode()
-{
-  if (!debugmode) {
-    PrintOut(LOG_INFO,"Signal USR2 - enabling debug mode\n");
-    if (!daemon_enable_console("smartd [Debug]")) {
-      debugmode = 1;
-      daemon_signal(SIGINT, HUPhandler);
-      PrintOut(LOG_INFO,"smartd debug mode enabled, PID=%d\n", getpid());
-    }
-    else
-      PrintOut(LOG_INFO,"enable console failed\n");
-  }
-  else if (debugmode == 1) {
-    daemon_disable_console();
-    debugmode = 0;
-    daemon_signal(SIGINT, sighandler);
-    PrintOut(LOG_INFO,"Signal USR2 - debug mode disabled\n");
-  }
-  else
-    PrintOut(LOG_INFO,"Signal USR2 - debug mode %d not changed\n", debugmode);
-}
-#endif
-
-time_t dosleep(time_t wakeuptime){
-  time_t timenow=0;
-  
-  // If past wake-up-time, compute next wake-up-time
-  timenow=time(NULL);
-  while (wakeuptime<=timenow){
-    int intervals=1+(timenow-wakeuptime)/checktime;
-    wakeuptime+=intervals*checktime;
-  }
-  
-  // sleep until we catch SIGUSR1 or have completed sleeping
-  while (timenow<wakeuptime && !caughtsigUSR1 && !caughtsigHUP && !caughtsigEXIT){
-    
-    // protect user again system clock being adjusted backwards
-    if (wakeuptime>timenow+checktime){
-      PrintOut(LOG_CRIT, "System clock time adjusted to the past. Resetting next wakeup time.\n");
-      wakeuptime=timenow+checktime;
-    }
-    
-    // Exit sleep when time interval has expired or a signal is received
-    sleep(wakeuptime-timenow);
-
-#ifdef _WIN32
-    // toggle debug mode?
-    if (caughtsigUSR2) {
-      ToggleDebugMode();
-      caughtsigUSR2 = 0;
-    }
-#endif
-
-    timenow=time(NULL);
-  }
- 
-  // if we caught a SIGUSR1 then print message and clear signal
-  if (caughtsigUSR1){
-    PrintOut(LOG_INFO,"Signal USR1 - checking devices now rather than in %d seconds.\n",
-             wakeuptime-timenow>0?(int)(wakeuptime-timenow):0);
-    caughtsigUSR1=0;
-  }
-  
-  // return adjusted wakeuptime
-  return wakeuptime;
-}
-
-// Print out a list of valid arguments for the Directive d
-void printoutvaliddirectiveargs(int priority, char d) {
-  char *s=NULL;
-
-  switch (d) {
-  case 'n':
-    PrintOut(priority, "never, sleep, standby, idle");
-    break;
-  case 's':
-    PrintOut(priority, "valid_regular_expression");
-    break;
-  case 'd':
-    PrintOut(priority, "ata, scsi, removable, 3ware,N");
-    break;
-  case 'T':
-    PrintOut(priority, "normal, permissive");
-    break;
-  case 'o':
-  case 'S':
-    PrintOut(priority, "on, off");
-    break;
-  case 'l':
-    PrintOut(priority, "error, selftest");
-    break;
-  case 'M':
-    PrintOut(priority, "\"once\", \"daily\", \"diminishing\", \"test\", \"exec\"");
-    break;
-  case 'v':
-    if (!(s = create_vendor_attribute_arg_list())) {
-      PrintOut(LOG_CRIT,"Insufficient memory to construct argument list\n");
-      EXIT(EXIT_NOMEM);
-    }
-    PrintOut(priority, "\n%s\n", s);
-    s=CheckFree(s, __LINE__,filenameandversion);
-    break;
-  case 'P':
-    PrintOut(priority, "use, ignore, show, showall");
-    break;
-  case 'F':
-    PrintOut(priority, "none, samsung, samsung2");
-    break;
-  }
-}
-
-// exits with an error message, or returns integer value of token
-int GetInteger(char *arg, char *name, char *token, int lineno, char *configfile, int min, int max){
-  char *endptr;
-  int val;
-  
-  // check input range
-  if (min<0){
-    PrintOut(LOG_CRIT, "min =%d passed to GetInteger() must be >=0\n", min);
-    return -1;
-  }
-
-  // make sure argument is there
-  if (!arg) {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s takes integer argument from %d to %d.\n",
-             configfile, lineno, name, token, min, max);
-    return -1;
-  }
-  
-  // get argument value (base 10), check that it's integer, and in-range
-  val=strtol(arg,&endptr,10);
-  if (*endptr!='\0' || val<min || val>max )  {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s has argument: %s; needs integer from %d to %d.\n",
-             configfile, lineno, name, token, arg, min, max);
-    return -1;
-  }
-
-  // all is well; return value
-  return val;
-}
-
-// This function returns 1 if it has correctly parsed one token (and
-// any arguments), else zero if no tokens remain.  It returns -1 if an
-// error was encountered.
-int ParseToken(char *token,cfgfile *cfg){
-  char sym;
-  char *name=cfg->name;
-  int lineno=cfg->lineno;
-  char *delim = " \n\t";
-  int badarg = 0;
-  int missingarg = 0;
-  char *arg = NULL;
-  int makemail=0;
-  maildata *mdat=NULL, tempmail;
-
-  // is the rest of the line a comment
-  if (*token=='#')
-    return 1;
-  
-  // is the token not recognized?
-  if (*token!='-' || strlen(token)!=2) {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n",
-             configfile, lineno, name, token);
-    PrintOut(LOG_CRIT, "Run smartd -D to print a list of valid Directives.\n");
-    return -1;
-  }
-  
-  // token we will be parsing:
-  sym=token[1];
-
-  // create temporary maildata structure.  This means we can postpone
-  // allocating space in the data segment until we are sure there are
-  // no errors.
-  if ('m'==sym || 'M'==sym){
-    if (!cfg->mailwarn){
-      memset(&tempmail, 0, sizeof(maildata));
-      mdat=&tempmail;
-      makemail=1;
-    }
-    else
-      mdat=cfg->mailwarn;
-  }
-
-  // parse the token and swallow its argument
-  switch (sym) {
-    int val;
-
-  case 'C':
-    // monitor current pending sector count (default 197)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 0, 255))<0)
-      return -1;
-    if (val==CUR_UNC_DEFAULT)
-      val=0;
-    else if (val==0)
-      val=CUR_UNC_DEFAULT;
-    // set bottom 8 bits to correct value
-    cfg->pending &= 0xff00;
-    cfg->pending |= val;
-    break;
-  case 'U':
-    // monitor offline uncorrectable sectors (default 198)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 0, 255))<0)
-      return -1;
-    if (val==OFF_UNC_DEFAULT)
-      val=0;
-    else if (val==0)
-      val=OFF_UNC_DEFAULT;
-    // turn off top 8 bits, then set to correct value
-    cfg->pending &= 0xff;
-    cfg->pending |= (val<<8);
-    break;
-  case 'T':
-    // Set tolerance level for SMART command failures
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "normal")) {
-      // Normal mode: exit on failure of a mandatory S.M.A.R.T. command, but
-      // not on failure of an optional S.M.A.R.T. command.
-      // This is the default so we don't need to actually do anything here.
-      cfg->permissive=0;
-    } else if (!strcmp(arg, "permissive")) {
-      // Permissive mode; ignore errors from Mandatory SMART commands
-      cfg->permissive=1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'd':
-    // specify the device type
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "ata")) {
-      cfg->controller_port = 0;
-      cfg->controller_type = CONTROLLER_ATA;
-    } else if (!strcmp(arg, "scsi")) {
-      cfg->controller_port =0;
-      cfg->controller_type = CONTROLLER_SCSI;
-    } else if (!strcmp(arg, "removable")) {
-      cfg->removable = 1;
-    } else {
-      // look 3ware,N RAID device
-      int i;
-      char *s;
-      
-      // make a copy of the string to mess with
-      if (!(s = strdup(arg))) {
-        PrintOut(LOG_CRIT,
-                 "No memory to copy argument to -d option - exiting\n");
-        EXIT(EXIT_NOMEM);
-      } else if (strncmp(s,"3ware,",6)) {
-        badarg=1;
-      } else if (split_report_arg2(s, &i)){
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n",
-                 configfile, lineno, name);
-        badarg=1;
-      } else if ( i<0 || i>15) {
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n",
-                 configfile, lineno, name, i);
-        badarg=1;
-      } else {
-	// determine type of escalade device from name of device
-	cfg->controller_type = guess_device_type(name);
-	if (cfg->controller_type!=CONTROLLER_3WARE_9000_CHAR && cfg->controller_type!=CONTROLLER_3WARE_678K_CHAR)
-	  cfg->controller_type=CONTROLLER_3WARE_678K;
-	    
-        // NOTE: controller_port == disk number + 1
-        cfg->controller_port = i+1;
-      }
-      s=CheckFree(s, __LINE__,filenameandversion); 
-    }
-    break;
-  case 'F':
-    // fix firmware bug
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "none")) {
-      cfg->fixfirmwarebug = FIX_NONE;
-    } else if (!strcmp(arg, "samsung")) {
-      cfg->fixfirmwarebug = FIX_SAMSUNG;
-    } else if (!strcmp(arg, "samsung2")) {
-      cfg->fixfirmwarebug = FIX_SAMSUNG2;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'H':
-    // check SMART status
-    cfg->smartcheck=1;
-    break;
-  case 'f':
-    // check for failure of usage attributes
-    cfg->usagefailed=1;
-    break;
-  case 't':
-    // track changes in all vendor attributes
-    cfg->prefail=1;
-    cfg->usage=1;
-    break;
-  case 'p':
-    // track changes in prefail vendor attributes
-    cfg->prefail=1;
-    break;
-  case 'u':
-    //  track changes in usage vendor attributes
-    cfg->usage=1;
-    break;
-  case 'l':
-    // track changes in SMART logs
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "selftest")) {
-      // track changes in self-test log
-      cfg->selftest=1;
-    } else if (!strcmp(arg, "error")) {
-      // track changes in ATA error log
-      cfg->errorlog=1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'a':
-    // monitor everything
-    cfg->smartcheck=1;
-    cfg->prefail=1;
-    cfg->usagefailed=1;
-    cfg->usage=1;
-    cfg->selftest=1;
-    cfg->errorlog=1;
-    break;
-  case 'o':
-    // automatic offline testing enable/disable
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "on")) {
-      cfg->autoofflinetest = 2;
-    } else if (!strcmp(arg, "off")) {
-      cfg->autoofflinetest = 1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'n':
-    // skip disk check if in idle or standby mode
-    if (!(arg = strtok(NULL, delim)))
-      missingarg = 1;
-    else if (!strcmp(arg, "never"))
-      cfg->powermode = 0;
-    else if (!strcmp(arg, "sleep"))
-      cfg->powermode = 1;
-    else if (!strcmp(arg, "standby"))
-      cfg->powermode = 2;
-    else if (!strcmp(arg, "idle"))
-      cfg->powermode = 3;
-    else
-      badarg = 1;
-    break;
-  case 'S':
-    // automatic attribute autosave enable/disable
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "on")) {
-      cfg->autosave = 2;
-    } else if (!strcmp(arg, "off")) {
-      cfg->autosave = 1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 's':
-    // warn user, and delete any previously given -s REGEXP Directives
-    if (cfg->testdata){
-      PrintOut(LOG_INFO, "File %s line %d (drive %s): ignoring previous Test Directive -s %s\n",
-               configfile, lineno, name, cfg->testdata->regex);
-      cfg->testdata=FreeTestData(cfg->testdata);
-    }
-    // check for missing argument
-    if (!(arg = strtok(NULL, delim))) {
-      missingarg = 1;
-    }
-    // allocate space for structure and string
-    else if (!(cfg->testdata=(testinfo *)Calloc(1, sizeof(testinfo))) || !(cfg->testdata->regex=CustomStrDup(arg, 1, __LINE__,filenameandversion))) {
-      PrintOut(LOG_INFO, "File %s line %d (drive %s): no memory to create Test Directive -s %s!\n",
-               configfile, lineno, name, arg);
-      EXIT(EXIT_NOMEM);
-    }
-    else if ((val=regcomp(&(cfg->testdata->cregex), arg, REG_EXTENDED))) {
-      char errormsg[512];
-      // not a valid regular expression!
-      regerror(val, &(cfg->testdata->cregex), errormsg, 512);
-      PrintOut(LOG_CRIT, "File %s line %d (drive %s): -s argument \"%s\" is INVALID extended regular expression. %s.\n",
-               configfile, lineno, name, arg, errormsg);
-      cfg->testdata=FreeTestData(cfg->testdata);
-      return -1;
-    }
-    // Do a bit of sanity checking and warn user if we think that
-    // their regexp is "strange". User probably confused about shell
-    // glob(3) syntax versus regular expression syntax regexp(7).
-    if ((int)strlen(arg) != (val=strspn(arg,"0123456789/.+*|()?^$[]SLCO")))
-      PrintOut(LOG_INFO,  "File %s line %d (drive %s): warning, character %d (%c) looks odd in extended regular expression %s\n",
-               configfile, lineno, name, val+1, arg[val], arg);
-    break;
-  case 'm':
-    // send email to address that follows
-    if (!(arg = strtok(NULL,delim)))
-      missingarg = 1;
-    else {
-      if (mdat->address) {
-        PrintOut(LOG_INFO, "File %s line %d (drive %s): ignoring previous Address Directive -m %s\n",
-                 configfile, lineno, name, mdat->address);
-        mdat->address=FreeNonZero(mdat->address, -1,__LINE__,filenameandversion);
-      }
-      mdat->address=CustomStrDup(arg, 1, __LINE__,filenameandversion);
-    }
-    break;
-  case 'M':
-    // email warning options
-    if (!(arg = strtok(NULL, delim)))
-      missingarg = 1;
-    else if (!strcmp(arg, "once"))
-      mdat->emailfreq = 1;
-    else if (!strcmp(arg, "daily"))
-      mdat->emailfreq = 2;
-    else if (!strcmp(arg, "diminishing"))
-      mdat->emailfreq = 3;
-    else if (!strcmp(arg, "test"))
-      mdat->emailtest = 1;
-    else if (!strcmp(arg, "exec")) {
-      // Get the next argument (the command line)
-      if (!(arg = strtok(NULL, delim))) {
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive %s 'exec' argument must be followed by executable path.\n",
-                 configfile, lineno, name, token);
-        return -1;
-      }
-      // Free the last cmd line given if any, and copy new one
-      if (mdat->emailcmdline) {
-        PrintOut(LOG_INFO, "File %s line %d (drive %s): ignoring previous mail Directive -M exec %s\n",
-                 configfile, lineno, name, mdat->emailcmdline);
-        mdat->emailcmdline=FreeNonZero(mdat->emailcmdline, -1,__LINE__,filenameandversion);
-      }
-      mdat->emailcmdline=CustomStrDup(arg, 1, __LINE__,filenameandversion);
-    } 
-    else
-      badarg = 1;
-    break;
-  case 'i':
-    // ignore failure of usage attribute
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_FAILUSE, __LINE__);
-    break;
-  case 'I':
-    // ignore attribute for tracking purposes
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_IGNORE, __LINE__);
-    break;
-  case 'r':
-    // print raw value when tracking
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
-    break;
-  case 'R':
-    // track changes in raw value (forces printing of raw value)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAW, __LINE__);
-    break;
-  case 'v':
-    // non-default vendor-specific attribute meaning
-    if (!(arg=strtok(NULL,delim))) {
-      missingarg = 1;
-    } else if (parse_attribute_def(arg, &cfg->attributedefs)){   
-      badarg = 1;
-    }
-    break;
-  case 'P':
-    // Define use of drive-specific presets.
-    if (!(arg = strtok(NULL, delim))) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "use")) {
-      cfg->ignorepresets = FALSE;
-    } else if (!strcmp(arg, "ignore")) {
-      cfg->ignorepresets = TRUE;
-    } else if (!strcmp(arg, "show")) {
-      cfg->showpresets = TRUE;
-    } else if (!strcmp(arg, "showall")) {
-      showallpresets();
-    } else {
-      badarg = 1;
-    }
-    break;
-  default:
-    // Directive not recognized
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n",
-             configfile, lineno, name, token);
-    Directives();
-    return -1;
-  }
-  if (missingarg) {
-    PrintOut(LOG_CRIT, "File %s line %d (drive %s): Missing argument to %s Directive\n",
-             configfile, lineno, name, token);
-  }
-  if (badarg) {
-    PrintOut(LOG_CRIT, "File %s line %d (drive %s): Invalid argument to %s Directive: %s\n",
-             configfile, lineno, name, token, arg);
-  }
-  if (missingarg || badarg) {
-    PrintOut(LOG_CRIT, "Valid arguments to %s Directive are: ", token);
-    printoutvaliddirectiveargs(LOG_CRIT, sym);
-    PrintOut(LOG_CRIT, "\n");
-    return -1;
-  }
-
-  // If this did something to fill the mail structure, and that didn't
-  // already exist, create it and copy.
-  if (makemail) {
-    if (!(cfg->mailwarn=(maildata *)Calloc(1, sizeof(maildata)))) {
-      PrintOut(LOG_INFO, "File %s line %d (drive %s): no memory to create mail warning entry!\n",
-               configfile, lineno, name);
-      EXIT(EXIT_NOMEM);
-    }
-    memcpy(cfg->mailwarn, mdat, sizeof(maildata));
-  }
-  
-  return 1;
-}
-
-// Allocate storage for a new cfgfile entry.  If original!=NULL, it's
-// a copy of the original, but with private data storage.  Else all is
-// zeroed.  Returns address, and fails if non memory available.
-
-cfgfile *CreateConfigEntry(cfgfile *original){
-  cfgfile *add;
-  
-  // allocate memory for new structure
-  if (!(add=(cfgfile *)Calloc(1,sizeof(cfgfile))))
-    goto badexit;
-  
-  // if old structure was pointed to, copy it
-  if (original)
-    memcpy(add, original, sizeof(cfgfile));
-  
-  // make private copies of data items ONLY if they are in use (non
-  // NULL)
-  add->name         = CustomStrDup(add->name,         0, __LINE__,filenameandversion);
-
-  if (add->testdata) {
-    int val;
-    if (!(add->testdata=(testinfo *)Calloc(1,sizeof(testinfo))))
-      goto badexit;
-    memcpy(add->testdata, original->testdata, sizeof(testinfo));
-    add->testdata->regex = CustomStrDup(add->testdata->regex,   1, __LINE__,filenameandversion);
-    // only POSIX-portable way to make fresh copy of compiled regex is
-    // to recompile it completely.  There is no POSIX
-    // compiled-regex-copy command.
-    if ((val=regcomp(&(add->testdata->cregex), add->testdata->regex, REG_EXTENDED))) {
-      char errormsg[512];
-      regerror(val, &(add->testdata->cregex), errormsg, 512);
-      PrintOut(LOG_CRIT, "unable to recompile regular expression %s. %s\n", add->testdata->regex, errormsg);
-      goto badexit;
-    }
-  }
-  
-  if (add->mailwarn) {
-    if (!(add->mailwarn=(maildata *)Calloc(1,sizeof(maildata))))
-      goto badexit;
-    memcpy(add->mailwarn, original->mailwarn, sizeof(maildata));
-    add->mailwarn->address      = CustomStrDup(add->mailwarn->address,      0, __LINE__,filenameandversion);
-    add->mailwarn->emailcmdline = CustomStrDup(add->mailwarn->emailcmdline, 0, __LINE__,filenameandversion);
-  }
-
-  if (add->attributedefs) {
-    if (!(add->attributedefs=(unsigned char *)Calloc(MAX_ATTRIBUTE_NUM,1)))
-      goto badexit;
-    memcpy(add->attributedefs, original->attributedefs, MAX_ATTRIBUTE_NUM);
-  }
-  
-  if (add->monitorattflags) {
-    if (!(add->monitorattflags=(unsigned char *)Calloc(NMONITOR*32, 1)))
-      goto badexit;
-    memcpy(add->monitorattflags, original->monitorattflags, NMONITOR*32);
-  }
-  
-  if (add->smartval) {
-    if (!(add->smartval=(struct ata_smart_values *)Calloc(1,sizeof(struct ata_smart_values))))
-      goto badexit;
-  }
-  
-  if (add->smartthres) {
-    if (!(add->smartthres=(struct ata_smart_thresholds_pvt *)Calloc(1,sizeof(struct ata_smart_thresholds_pvt))))
-      goto badexit;
-  }
-
-  return add;
-
- badexit:
-  PrintOut(LOG_CRIT, "No memory to create entry from configuration file\n");
-  EXIT(EXIT_NOMEM);
-}
-
-
-
-// This is the routine that adds things to the cfgentries list. To
-// prevent memory leaks when re-reading the configuration file many
-// times, this routine MUST deallocate any memory other than that
-// pointed to within cfg-> before it returns.
-//
-// Return values are:
-//  1: parsed a normal line
-//  0: found comment or blank line
-// -1: found SCANDIRECTIVE line
-// -2: found an error
-//
-// Note: this routine modifies *line from the caller!
-int ParseConfigLine(int entry, int lineno,char *line){
-  char *token=NULL;
-  char *name=NULL;
-  char *delim = " \n\t";
-  cfgfile *cfg=NULL;
-  int devscan=0;
-
-  // get first token: device name. If a comment, skip line
-  if (!(name=strtok(line,delim)) || *name=='#') {
-    return 0;
-  }
-
-  // Have we detected the SCANDIRECTIVE directive?
-  if (!strcmp(SCANDIRECTIVE,name)){
-    devscan=1;
-    if (entry) {
-      PrintOut(LOG_INFO,"Scan Directive %s (line %d) must be the first entry in %s\n",name, lineno, configfile);
-      return -2;
-    }
-  }
-  
-  // Is there space for another entry?  If not, allocate more
-  while (entry>=cfgentries_max)
-    cfgentries=AllocateMoreSpace(cfgentries, &cfgentries_max, "configuration file device");
-
-  // We've got a legit entry, make space to store it
-  cfg=cfgentries[entry]=CreateConfigEntry(NULL);
-  cfg->name = CustomStrDup(name, 1, __LINE__,filenameandversion);
-
-  // Store line number, and by default check for both device types.
-  cfg->lineno=lineno;
-  
-  // Try and recognize if a IDE or SCSI device.  These can be
-  // overwritten by configuration file directives.
-  if (cfg->controller_type==CONTROLLER_UNKNOWN)
-    cfg->controller_type = guess_device_type(cfg->name);
-  
-  // parse tokens one at a time from the file.
-  while ((token=strtok(NULL,delim))){
-    int retval=ParseToken(token,cfg);
-    
-    if (retval==0)
-      // No tokens left:
-      break;
-    
-    if (retval>0) {
-      // Parsed token  
-#if (0)
-      PrintOut(LOG_INFO,"Parsed token %s\n",token);
-#endif
-      continue;
-    }
-    
-    if (retval<0) {
-      // error found on the line
-      return -2;
-    }
-  }
-  
-  // If we found 3ware controller, then modify device name by adding a SPACE
-  if (cfg->controller_port){
-    int len=17+strlen(cfg->name);
-    char *newname;
-    
-    if (devscan){
-      PrintOut(LOG_CRIT, "smartd: can not scan for 3ware devices (line %d of file %s)\n",
-               lineno, configfile);
-      return -2;
-    }
-    
-    if (!(newname=(char *)calloc(len,1))) {
-      PrintOut(LOG_INFO,"No memory to parse file: %s line %d, %s\n", configfile, lineno, strerror(errno));
-      EXIT(EXIT_NOMEM);
-    }
-    
-    // Make new device name by adding a space then RAID disk number
-    snprintf(newname, len, "%s [3ware_disk_%02d]", cfg->name, cfg->controller_port-1);
-    cfg->name=CheckFree(cfg->name, __LINE__,filenameandversion);
-    cfg->name=newname;
-    bytes+=16;
-  }
-
-  // If NO monitoring directives are set, then set all of them.
-  if (!(cfg->smartcheck || cfg->usagefailed || cfg->prefail  || 
-        cfg->usage      || cfg->selftest    || cfg->errorlog   )){
-    
-    PrintOut(LOG_INFO,"Drive: %s, implied '-a' Directive on line %d of file %s\n",
-             cfg->name, cfg->lineno, configfile);
-    
-    cfg->smartcheck=1;
-    cfg->usagefailed=1;
-    cfg->prefail=1;
-    cfg->usage=1;
-    cfg->selftest=1;
-    cfg->errorlog=1;
-  }
-  
-  // additional sanity check. Has user set -M options without -m?
-  if (cfg->mailwarn && !cfg->mailwarn->address && (cfg->mailwarn->emailcmdline || cfg->mailwarn->emailfreq || cfg->mailwarn->emailtest)){
-    PrintOut(LOG_CRIT,"Drive: %s, -M Directive(s) on line %d of file %s need -m ADDRESS Directive\n",
-             cfg->name, cfg->lineno, configfile);
-    return -2;
-  }
-  
-  // has the user has set <nomailer>?
-  if (cfg->mailwarn && cfg->mailwarn->address && !strcmp(cfg->mailwarn->address,"<nomailer>")){
-    // check that -M exec is also set
-    if (!cfg->mailwarn->emailcmdline){
-      PrintOut(LOG_CRIT,"Drive: %s, -m <nomailer> Directive on line %d of file %s needs -M exec Directive\n",
-               cfg->name, cfg->lineno, configfile);
-      return -2;
-    }
-    // now free memory.  From here on the sign of <nomailer> is
-    // address==NULL and cfg->emailcmdline!=NULL
-    cfg->mailwarn->address=FreeNonZero(cfg->mailwarn->address, -1,__LINE__,filenameandversion);
-  }
-
-  // set cfg->emailfreq to 1 (once) if user hasn't set it
-  if (cfg->mailwarn && !cfg->mailwarn->emailfreq)
-    cfg->mailwarn->emailfreq = 1;
-
-  entry++;
-
-  if (devscan)
-    return -1;
-  else
-    return 1;
-}
-
-// clean up utility for ParseConfigFile()
-void cleanup(FILE **fpp, int is_stdin){
-  if (*fpp){
-    // (*fpp != stdin) does not work here if stdin has been closed & reopened
-    if (!is_stdin)
-      fclose(*fpp);
-    *fpp=NULL;
-  }
-
-  return;
-}
-
-
-// Parses a configuration file.  Return values are:
-//  N=>0: found N entries
-// -1:    syntax error in config file
-// -2:    config file does not exist
-// -3:    config file exists but cannot be read
-//
-// In the case where the return value is 0, there are three
-// possiblities:
-// Empty configuration file ==> cfgentries==NULL
-// No configuration file    ==> cfgentries[0]->lineno == 0
-// SCANDIRECTIVE found      ==> cfgentries[0]->lineno != 0
-int ParseConfigFile(){
-  FILE *fp=NULL;
-  int entry=0,lineno=1,cont=0,contlineno=0;
-  char line[MAXLINELEN+2];
-  char fullline[MAXCONTLINE+1];
-
-  int is_stdin = (configfile == configfile_stdin); // pointer comparison ok here
-
-  // Open config file, if it exists and is not <stdin>
-  if (!is_stdin) {
-    fp=fopen(configfile,"r");
-    if (fp==NULL && (errno!=ENOENT || configfile_alt)) {
-      // file exists but we can't read it or it should exist due to '-c' option
-      int ret = (errno!=ENOENT ? -3 : -2);
-      PrintOut(LOG_CRIT,"%s: Unable to open configuration file %s\n",
-               strerror(errno),configfile);
-      return ret;
-    }
-  }
-  else // read from stdin ('-c -' option)
-    fp = stdin;
-  
-  // No configuration file found -- use fake one
-  if (fp==NULL) {
-    int len=strlen(SCANDIRECTIVE)+4;
-    char *fakeconfig=(char *)calloc(len,1);
-  
-    if (!fakeconfig || 
-        (len-1) != snprintf(fakeconfig, len, "%s -a", SCANDIRECTIVE) ||
-        -1 != ParseConfigLine(entry, 0, fakeconfig)
-        ) {
-      PrintOut(LOG_CRIT,"Internal error in ParseConfigFile() at line %d of file %s\n%s", 
-               __LINE__, filenameandversion, reportbug);
-      EXIT(EXIT_BADCODE);
-    }
-    fakeconfig=CheckFree(fakeconfig, __LINE__,filenameandversion);
-    return 0;
-  }
-    
-  // configuration file exists
-  PrintOut(LOG_INFO,"Opened configuration file %s\n",configfile);
-
-  // parse config file line by line
-  while (1) {
-    int len=0,scandevice;
-    char *lastslash;
-    char *comment;
-    char *code;
-
-    // make debugging simpler
-    memset(line,0,sizeof(line));
-
-    // get a line
-    code=fgets(line,MAXLINELEN+2,fp);
-    
-    // are we at the end of the file?
-    if (!code){
-      if (cont) {
-        scandevice=ParseConfigLine(entry,contlineno,fullline);
-        // See if we found a SCANDIRECTIVE directive
-        if (scandevice==-1) {
-          cleanup(&fp, is_stdin);
-          return 0;
-        }
-        // did we find a syntax error
-        if (scandevice==-2) {
-          cleanup(&fp, is_stdin);
-          return -1;
-        }
-        // the final line is part of a continuation line
-        cont=0;
-        entry+=scandevice;
-      }
-      break;
-    }
-
-    // input file line number
-    contlineno++;
-    
-    // See if line is too long
-    len=strlen(line);
-    if (len>MAXLINELEN){
-      char *warn;
-      if (line[len-1]=='\n')
-        warn="(including newline!) ";
-      else
-        warn="";
-      PrintOut(LOG_CRIT,"Error: line %d of file %s %sis more than MAXLINELEN=%d characters.\n",
-               (int)contlineno,configfile,warn,(int)MAXLINELEN);
-      cleanup(&fp, is_stdin);
-      return -1;
-    }
-
-    // Ignore anything after comment symbol
-    if ((comment=strchr(line,'#'))){
-      *comment='\0';
-      len=strlen(line);
-    }
-
-    // is the total line (made of all continuation lines) too long?
-    if (cont+len>MAXCONTLINE){
-      PrintOut(LOG_CRIT,"Error: continued line %d (actual line %d) of file %s is more than MAXCONTLINE=%d characters.\n",
-               lineno, (int)contlineno, configfile, (int)MAXCONTLINE);
-      cleanup(&fp, is_stdin);
-      return -1;
-    }
-    
-    // copy string so far into fullline, and increment length
-    strcpy(fullline+cont,line);
-    cont+=len;
-
-    // is this a continuation line.  If so, replace \ by space and look at next line
-    if ( (lastslash=strrchr(line,'\\')) && !strtok(lastslash+1," \n\t")){
-      *(fullline+(cont-len)+(lastslash-line))=' ';
-      continue;
-    }
-
-    // Not a continuation line. Parse it
-    scandevice=ParseConfigLine(entry,contlineno,fullline);
-
-    // did we find a scandevice directive?
-    if (scandevice==-1) {
-      cleanup(&fp, is_stdin);
-      return 0;
-    }
-    // did we find a syntax error
-    if (scandevice==-2) {
-      cleanup(&fp, is_stdin);
-      return -1;
-    }
-
-    entry+=scandevice;
-    lineno++;
-    cont=0;
-  }
-  cleanup(&fp, is_stdin);
-  
-  // note -- may be zero if syntax of file OK, but no valid entries!
-  return entry;
-}
-
-
-// Prints copyright, license and version information
-void PrintCopyleft(void){
-  debugmode=1;
-  PrintHead();
-  PrintCVS();
-  return;
-}
-
-/* Prints the message "=======> VALID ARGUMENTS ARE: <LIST>  <=======\n", where
-   <LIST> is the list of valid arguments for option opt. */
-void PrintValidArgs(char opt) {
-  const char *s;
-
-  PrintOut(LOG_CRIT, "=======> VALID ARGUMENTS ARE: ");
-  if (!(s = GetValidArgList(opt)))
-    PrintOut(LOG_CRIT, "Error constructing argument list for option %c", opt);
-  else
-    PrintOut(LOG_CRIT, (char *)s);
-  PrintOut(LOG_CRIT, " <=======\n");
-}
-
-// Parses input line, prints usage message and
-// version/license/copyright messages
-void ParseOpts(int argc, char **argv){
-  extern char *optarg;
-  extern int  optopt, optind, opterr;
-  int optchar;
-  int badarg;
-  char *tailptr;
-  long lchecktime;
-  // Please update GetValidArgList() if you edit shortopts
-  const char *shortopts = "c:l:q:dDi:p:r:Vh?";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update GetValidArgList() if you edit longopts
-  struct option longopts[] = {
-    { "configfile",     required_argument, 0, 'c' },
-    { "logfacility",    required_argument, 0, 'l' },
-    { "quit",           required_argument, 0, 'q' },
-    { "debug",          no_argument,       0, 'd' },
-    { "showdirectives", no_argument,       0, 'D' },
-    { "interval",       required_argument, 0, 'i' },
-    { "pidfile",        required_argument, 0, 'p' },
-    { "report",         required_argument, 0, 'r' },
-#ifdef _WIN32
-    { "service",        no_argument,       0, 'S' },
-#endif
-    { "version",        no_argument,       0, 'V' },
-    { "license",        no_argument,       0, 'V' },
-    { "copyright",      no_argument,       0, 'V' },
-    { "help",           no_argument,       0, 'h' },
-    { "usage",          no_argument,       0, 'h' },
-    { 0,                0,                 0, 0   }
-  };
-#endif
-  
-  opterr=optopt=0;
-  badarg=FALSE;
-  
-  // Parse input options.  This horrible construction is so that emacs
-  // indents properly.  Sorry.
-  while (-1 != (optchar = 
-#ifdef HAVE_GETOPT_LONG
-                getopt_long(argc, argv, shortopts, longopts, NULL)
-#else
-                getopt(argc, argv, shortopts)
-#endif
-                )) {
-    
-    switch(optchar) {
-    case 'q':
-      // when to quit
-      if (!(strcmp(optarg,"nodev"))) {
-        quit=0;
-      } else if (!(strcmp(optarg,"nodevstartup"))) {
-        quit=1;
-      } else if (!(strcmp(optarg,"never"))) {
-        quit=2;
-      } else if (!(strcmp(optarg,"onecheck"))) {
-        quit=3;
-        debugmode=1;
-      } else if (!(strcmp(optarg,"errors"))) {
-        quit=4;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'l':
-      // set the log facility level
-      if (!strcmp(optarg, "daemon"))
-        facility=LOG_DAEMON;
-      else if (!strcmp(optarg, "local0"))
-        facility=LOG_LOCAL0;
-      else if (!strcmp(optarg, "local1"))
-        facility=LOG_LOCAL1;
-      else if (!strcmp(optarg, "local2"))
-        facility=LOG_LOCAL2;
-      else if (!strcmp(optarg, "local3"))
-        facility=LOG_LOCAL3;
-      else if (!strcmp(optarg, "local4"))
-        facility=LOG_LOCAL4;
-      else if (!strcmp(optarg, "local5"))
-        facility=LOG_LOCAL5;
-      else if (!strcmp(optarg, "local6"))
-        facility=LOG_LOCAL6;
-      else if (!strcmp(optarg, "local7"))
-        facility=LOG_LOCAL7;
-      else
-        badarg = TRUE;
-      break;
-    case 'd':
-      // enable debug mode
-      debugmode = TRUE;
-      break;
-    case 'D':
-      // print summary of all valid directives
-      debugmode = TRUE;
-      Directives();
-      EXIT(0);
-      break;
-    case 'i':
-      // Period (time interval) for checking
-      // strtol will set errno in the event of overflow, so we'll check it.
-      errno = 0;
-      lchecktime = strtol(optarg, &tailptr, 10);
-      if (*tailptr != '\0' || lchecktime < 10 || lchecktime > INT_MAX || errno) {
-        debugmode=1;
-        PrintHead();
-        PrintOut(LOG_CRIT, "======> INVALID INTERVAL: %s <=======\n", optarg);
-        PrintOut(LOG_CRIT, "======> INTERVAL MUST BE INTEGER BETWEEN %d AND %d <=======\n", 10, INT_MAX);
-        PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-      checktime = (int)lchecktime;
-      break;
-    case 'r':
-      // report IOCTL transactions
-      {
-        int i;
-        char *s;
-
-        // split_report_arg() may modify its first argument string, so use a
-        // copy of optarg in case we want optarg for an error message.
-        if (!(s = strdup(optarg))) {
-          PrintOut(LOG_CRIT, "No memory to process -r option - exiting\n");
-          EXIT(EXIT_NOMEM);
-        }
-        if (split_report_arg(s, &i)) {
-          badarg = TRUE;
-        } else if (i<1 || i>3) {
-          debugmode=1;
-          PrintHead();
-          PrintOut(LOG_CRIT, "======> INVALID REPORT LEVEL: %s <=======\n", optarg);
-          PrintOut(LOG_CRIT, "======> LEVEL MUST BE INTEGER BETWEEN 1 AND 3<=======\n");
-          EXIT(EXIT_BADCMD);
-        } else if (!strcmp(s,"ioctl")) {
-          con->reportataioctl  = con->reportscsiioctl = i;
-        } else if (!strcmp(s,"ataioctl")) {
-          con->reportataioctl = i;
-        } else if (!strcmp(s,"scsiioctl")) {
-          con->reportscsiioctl = i;
-        } else {
-          badarg = TRUE;
-        }
-        s=CheckFree(s, __LINE__,filenameandversion);
-      }
-      break;
-    case 'c':
-      // alternate configuration file
-      if (strcmp(optarg,"-"))
-        configfile=configfile_alt=CustomStrDup(optarg, 1, __LINE__,filenameandversion);
-      else // read from stdin
-        configfile=configfile_stdin;
-      break;
-    case 'p':
-      // output file with PID number
-      pid_file=CustomStrDup(optarg, 1, __LINE__,filenameandversion);
-      break;
-#ifdef _WIN32
-    case 'S':
-      // running as service, option already handled by deamon_main(), so ignore it
-      break;
-#endif
-    case 'V':
-      // print version and CVS info
-      PrintCopyleft();
-      EXIT(0);
-      break;
-    case 'h':
-      // help: print summary of command-line options
-      debugmode=1;
-      PrintHead();
-      Usage();
-      EXIT(0);
-      break;
-    case '?':
-    default:
-      // unrecognized option
-      debugmode=1;
-      PrintHead();
-#ifdef HAVE_GETOPT_LONG
-      // Point arg to the argument in which this option was found.
-      arg = argv[optind-1];
-      // Check whether the option is a long option that doesn't map to -h.
-      if (arg[1] == '-' && optchar != 'h') {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (optopt && (strchr(shortopts, optopt) != NULL)) {
-          PrintOut(LOG_CRIT, "=======> ARGUMENT REQUIRED FOR OPTION: %s <=======\n",arg+2);
-          PrintValidArgs(optopt);
-        } else {
-          PrintOut(LOG_CRIT, "=======> UNRECOGNIZED OPTION: %s <=======\n\n",arg+2);
-        }
-        PrintOut(LOG_CRIT, "\nUse smartd --help to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (strchr(shortopts, optopt) != NULL){
-          PrintOut(LOG_CRIT, "=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n",optopt);
-          PrintValidArgs(optopt);
-        } else {
-          PrintOut(LOG_CRIT, "=======> UNRECOGNIZED OPTION: %c <=======\n\n",optopt);
-        }
-        PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-      Usage();
-      EXIT(0);
-    }
-
-    // Check to see if option had an unrecognized or incorrect argument.
-    if (badarg) {
-      debugmode=1;
-      PrintHead();
-      // It would be nice to print the actual option name given by the user
-      // here, but we just print the short form.  Please fix this if you know
-      // a clean way to do it.
-      PrintOut(LOG_CRIT, "=======> INVALID ARGUMENT TO -%c: %s <======= \n", optchar, optarg);
-      PrintValidArgs(optchar);
-      PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-      EXIT(EXIT_BADCMD);
-    }
-  }
-
-  // non-option arguments are not allowed
-  if (argc > optind) {
-    debugmode=1;
-    PrintHead();
-    PrintOut(LOG_CRIT, "=======> UNRECOGNIZED ARGUMENT: %s <=======\n\n", argv[optind]);
-    PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-    EXIT(EXIT_BADCMD);
-  }
-
-  // no pidfile in debug mode
-  if (debugmode && pid_file) {
-    debugmode=1;
-    PrintHead();
-    PrintOut(LOG_CRIT, "=======> INVALID CHOICE OF OPTIONS: -d and -p <======= \n\n");
-    PrintOut(LOG_CRIT, "Error: pid file %s not written in debug (-d) mode\n\n", pid_file);
-    pid_file=FreeNonZero(pid_file, -1,__LINE__,filenameandversion);
-    EXIT(EXIT_BADCMD);
-  }
-  
-  // print header
-  PrintHead();
-  
-  return;
-}
-
-// Function we call if no configuration file was found or if the
-// SCANDIRECTIVE Directive was found.  It makes entries for device
-// names returned by make_device_names() in os_OSNAME.c
-int MakeConfigEntries(const char *type, int start){
-  int i;
-  int num;
-  char** devlist = NULL;
-  cfgfile *first=cfgentries[0],*cfg=first;
-
-  // make list of devices
-  if ((num=make_device_names(&devlist,type))<0)
-    PrintOut(LOG_CRIT,"Problem creating device name scan list\n");
-  
-  // if no devices, or error constructing list, return
-  if (num<=0)
-    return 0;
-  
-  // loop over entries to create
-  for (i=0; i<num; i++){
-    
-    // make storage and copy for all but first entry
-    if (start+i) {
-      // allocate more storage if needed
-      while (cfgentries_max<=start+i)
-        cfgentries=AllocateMoreSpace(cfgentries, &cfgentries_max, "simulated configuration file device");
-      cfg=cfgentries[start+i]=CreateConfigEntry(first);
-    }
-
-    // ATA or SCSI?
-    if (!strcmp(type,"ATA") )
-      cfg->controller_type = CONTROLLER_ATA;
-    if (!strcmp(type,"SCSI") ) 
-      cfg->controller_type = CONTROLLER_SCSI;
-    
-    // remove device name, if it's there, and put in correct one
-    cfg->name=FreeNonZero(cfg->name, -1,__LINE__,filenameandversion);
-    // save pointer to the device name created within
-    // make_device_names
-    cfg->name=devlist[i];
-  }
-  
-  // If needed, free memory used for devlist: pointers now in
-  // cfgentries[]->names.  If num==0 we never get to this point, but
-  // that's OK.  If we realloc()d the array length in
-  // make_device_names() that was ALREADY equivalent to calling
-  // free().
-  devlist = FreeNonZero(devlist,(sizeof (char*) * num),__LINE__, filenameandversion);
-  
-  return num;
-}
- 
-void CanNotRegister(char *name, char *type, int line, int scandirective){
-  if( !debugmode && scandirective == 1 ) { return; }
-  if (line)
-    PrintOut(scandirective?LOG_INFO:LOG_CRIT,
-             "Unable to register %s device %s at line %d of file %s\n",
-             type, name, line, configfile);
-  else
-    PrintOut(LOG_INFO,"Unable to register %s device %s\n",
-             type, name);
-  return;
-}
-
-// Returns negative value (see ParseConfigFile()) if config file
-// had errors, else number of entries which may be zero or positive. 
-// If we found no configuration file, or it contained SCANDIRECTIVE,
-// then *scanning is set to 1, else 0.
-int ReadOrMakeConfigEntries(int *scanning){
-  int entries;
-  
-  // deallocate any cfgfile data structures in memory
-  RmAllConfigEntries();
-  
-  // parse configuration file configfile (normally /etc/smartd.conf)  
-  if ((entries=ParseConfigFile())<0) {
- 
-    // There was an error reading the configuration file.
-    RmAllConfigEntries();
-    if (entries == -1)
-      PrintOut(LOG_CRIT, "Configuration file %s has fatal syntax errors.\n", configfile);
-    return entries;
-  }
-
-  // did we find entries or scan?
-  *scanning=0;
-  
-  // no error parsing config file.
-  if (entries) {
-    // we did not find a SCANDIRECTIVE and did find valid entries
-    PrintOut(LOG_INFO, "Configuration file %s parsed.\n", configfile);
-  }
-  else if (cfgentries && cfgentries[0]) {
-    // we found a SCANDIRECTIVE or there was no configuration file so
-    // scan.  Configuration file's first entry contains all options
-    // that were set
-    cfgfile *first=cfgentries[0];
-    int doata  = !(first->controller_type==CONTROLLER_SCSI);
-    int doscsi = !(first->controller_type==CONTROLLER_ATA);
-    
-    *scanning=1;
-    
-    if (first->lineno)
-      PrintOut(LOG_INFO,"Configuration file %s was parsed, found %s, scanning devices\n", configfile, SCANDIRECTIVE);
-    else
-      PrintOut(LOG_INFO,"No configuration file %s found, scanning devices\n", configfile);
-    
-    // make config list of ATA devices to search for
-    if (doata)
-      entries+=MakeConfigEntries("ATA", entries);
-    // make config list of SCSI devices to search for
-    if (doscsi)
-      entries+=MakeConfigEntries("SCSI", entries);
-
-    // warn user if scan table found no devices
-    if (!entries) {
-      PrintOut(LOG_CRIT,"In the system's table of devices NO devices found to scan\n");
-      // get rid of fake entry with SCANDIRECTIVE as name
-      RmConfigEntry(cfgentries, __LINE__);
-    }
-  } 
-  else
-    PrintOut(LOG_CRIT,"Configuration file %s parsed but has no entries (like /dev/hda)\n",configfile);
-  
-  return entries;
-}
-
-
-// This function tries devices from cfgentries.  Each one that can be
-// registered is moved onto the [ata|scsi]devices lists and removed
-// from the cfgentries list, else it's memory is deallocated.
-void RegisterDevices(int scanning){
-  int i;
-  
-  // start by clearing lists/memory of ALL existing devices
-  RmAllDevEntries();
-  numdevata=numdevscsi=0;
-  
-  // Register entries
-  for (i=0; i<cfgentries_max ; i++){
-    
-    cfgfile *ent=cfgentries[i];
-    
-    // skip any NULL entries (holes)
-    if (!ent)
-      continue;
-    
-    // register ATA devices
-    if (ent->controller_type!=CONTROLLER_SCSI){
-      if (ATADeviceScan(ent, scanning))
-        CanNotRegister(ent->name, "ATA", ent->lineno, scanning);
-      else {
-        // move onto the list of ata devices
-        cfgentries[i]=NULL;
-        while (numdevata>=atadevlist_max)
-          atadevlist=AllocateMoreSpace(atadevlist, &atadevlist_max, "ATA device");
-        atadevlist[numdevata++]=ent;
-      }
-    }
-    
-    // then register SCSI devices
-    if (ent->controller_type==CONTROLLER_SCSI || ent->controller_type==CONTROLLER_UNKNOWN){
-      int retscsi=0;
-
-#if SCSITIMEOUT
-      struct sigaction alarmAction, defaultaction;
-
-      // Set up an alarm handler to catch USB devices that hang on
-      // SCSI scanning...
-      alarmAction.sa_handler= AlarmHandler;
-      alarmAction.sa_flags  = SA_RESTART;
-      if (sigaction(SIGALRM, &alarmAction, &defaultaction)) {
-        // if we can't set timeout, just scan device
-        PrintOut(LOG_CRIT, "Unable to initialize SCSI timeout mechanism.\n");
-        retscsi=SCSIDeviceScan(ent, scanning);
-      }
-      else {
-        // prepare return point in case of bad SCSI device
-        if (setjmp(registerscsienv))
-          // SCSI device timed out!
-          retscsi=-1;
-        else {
-        // Set alarm, make SCSI call, reset alarm
-          alarm(SCSITIMEOUT);
-          retscsi=SCSIDeviceScan(ent, scanning);
-          alarm(0);
-        }
-        if (sigaction(SIGALRM, &defaultaction, NULL)){
-          PrintOut(LOG_CRIT, "Unable to clear SCSI timeout mechanism.\n");
-        }
-      }
-#else
-      retscsi=SCSIDeviceScan(ent, scanning);
-#endif   
-
-      // Now scan SCSI device...
-      if (retscsi){
-        if (retscsi<0)
-          PrintOut(LOG_CRIT, "Device %s timed out (poorly-implemented USB device?)\n", ent->name);
-        CanNotRegister(ent->name, "SCSI", ent->lineno, scanning);
-      }
-      else {
-        // move onto the list of scsi devices
-        cfgentries[i]=NULL;
-        while (numdevscsi>=scsidevlist_max)
-          scsidevlist=AllocateMoreSpace(scsidevlist, &scsidevlist_max, "SCSI device");
-        scsidevlist[numdevscsi++]=ent;
-      }
-    }
-    
-    // if device is explictly listed and we can't register it, then
-    // exit unless the user has specified that the device is removable
-    if (cfgentries[i]  && !scanning){
-      if (ent->removable || quit==2)
-        PrintOut(LOG_INFO, "Device %s not available\n", ent->name);
-      else {
-        PrintOut(LOG_CRIT, "Unable to register device %s (no Directive -d removable). Exiting.\n", ent->name);
-        EXIT(EXIT_BADDEV);
-      }
-    }
-    
-    // free up memory if device could not be registered
-    RmConfigEntry(cfgentries+i, __LINE__);
-  }
-  
-  return;
-}
-
-
-#ifndef _WIN32
-// Main function
-int main(int argc, char **argv)
-#else
-// Windows: internal main function started direct or by service control manager
-static int smartd_main(int argc, char **argv)
-#endif
-{
-  // external control variables for ATA disks
-  smartmonctrl control;
-
-  // is it our first pass through?
-  int firstpass=1;
-
-  // next time to wake up
-  time_t wakeuptime;
-
-  // for simplicity, null all global communications variables/lists
-  con=&control;
-  memset(con,        0,sizeof(control));
-
-  // parse input and print header and usage info if needed
-  ParseOpts(argc,argv);
-  
-  // do we mute printing from ataprint commands?
-  con->printing_switchable=0;
-  con->dont_print=debugmode?0:1;
-  
-  // don't exit on bad checksums
-  con->checksumfail=0;
-  
-  // the main loop of the code
-  while (1){
-
-    // are we exiting from a signal?
-    if (caughtsigEXIT) {
-      // are we exiting with SIGTERM?
-      int isterm=(caughtsigEXIT==SIGTERM);
-      int isquit=(caughtsigEXIT==SIGQUIT);
-      int isok=debugmode?isterm || isquit:isterm;
-      
-      PrintOut(isok?LOG_INFO:LOG_CRIT, "smartd received signal %d: %s\n",
-               caughtsigEXIT, strsignal(caughtsigEXIT));
-      
-      EXIT(isok?0:EXIT_SIGNAL);
-    }
-
-    // Should we (re)read the config file?
-    if (firstpass || caughtsigHUP){
-      int entries, scanning=0;
-
-      if (!firstpass) {
-#ifdef __CYGWIN__
-        // Workaround for missing SIGQUIT via keyboard on Cygwin
-        if (caughtsigHUP==2) {
-          // Simulate SIGQUIT if another SIGINT arrives soon
-          caughtsigHUP=0;
-          sleep(1);
-          if (caughtsigHUP==2) {
-            caughtsigEXIT=SIGQUIT;
-            continue;
-          }
-          caughtsigHUP=2;
-        }
-#endif
-        PrintOut(LOG_INFO,
-                 caughtsigHUP==1?
-                 "Signal HUP - rereading configuration file %s\n":
-                 "\a\nSignal INT - rereading configuration file %s ("SIGQUIT_KEYNAME" quits)\n\n",
-                 configfile);
-      }
-
-      // clears cfgentries, (re)reads config file, makes >=0 entries
-      entries=ReadOrMakeConfigEntries(&scanning);
-
-      if (entries>=0) {
-        // checks devices, then moves onto ata/scsi list or deallocates.
-        RegisterDevices(scanning);
-      }
-      else if (quit==2 || ((quit==0 || quit==1) && !firstpass)) {
-        // user has asked to continue on error in configuration file
-        if (!firstpass)
-          PrintOut(LOG_INFO,"Reusing previous configuration\n");
-      }
-      else {
-        // exit with configuration file error status
-        int status = (entries==-3 ? EXIT_READCONF : entries==-2 ? EXIT_NOCONF : EXIT_BADCONF);
-        EXIT(status);
-      }
-
-      // Log number of devices we are monitoring...
-      if (numdevata+numdevscsi || quit==2 || (quit==1 && !firstpass))
-        PrintOut(LOG_INFO,"Monitoring %d ATA and %d SCSI devices\n",
-                 numdevata, numdevscsi);
-      else {
-        PrintOut(LOG_INFO,"Unable to monitor any SMART enabled devices. Try debug (-d) option. Exiting...\n");
-        EXIT(EXIT_NODEV);
-      }   
-      
-      // reset signal
-      caughtsigHUP=0;
-    }
-
-    // check all devices once
-    CheckDevicesOnce(atadevlist, scsidevlist); 
-    
-    // user has asked us to exit after first check
-    if (quit==3) {
-      PrintOut(LOG_INFO,"Started with '-q onecheck' option. All devices sucessfully checked once.\n"
-               "smartd is exiting (exit status 0)\n");
-      EXIT(0);
-    }
-    
-    // fork into background if needed
-    if (firstpass && !debugmode)
-      DaemonInit();
-    
-    // set exit and signal handlers, write PID file, set wake-up time
-    if (firstpass){
-      Initialize(&wakeuptime);
-      firstpass=0;
-    }
-    
-    // sleep until next check time, or a signal arrives
-    wakeuptime=dosleep(wakeuptime);
-  }
-}
-
-
-#ifdef _WIN32
-// Main function for Windows
-int main(int argc, char **argv){
-  // Options for smartd windows service
-  static const daemon_winsvc_options svc_opts = {
-    "--service", // cmd_opt
-    "smartd", "SmartD Service", // servicename, displayname
-    // description
-    "Controls and monitors storage devices using the Self-Monitoring, "
-    "Analysis and Reporting Technology System (S.M.A.R.T.) "
-    "built into ATA and SCSI Hard Drives. "
-    PACKAGE_HOMEPAGE
-  };
-  // daemon_main() handles daemon and service specific commands
-  // and starts smartd_main() direct, from a new process,
-  // or via service control manager
-  return daemon_main("smartd", &svc_opts , smartd_main, argc, argv);
-}
-#endif
diff --git a/sm5/smartd.h b/sm5/smartd.h
deleted file mode 100644
index 3f300004ca4d49a2014db12ec348382a2ef43f63..0000000000000000000000000000000000000000
--- a/sm5/smartd.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * smartd.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef SMARTD_H_
-#define SMARTD_H_
-
-// Needed since some structure definitions below require POSIX
-// extended regular expressions.
-#include <sys/types.h>
-#include <regex.h>
-
-
-#ifndef SMARTD_H_CVSID
-#define SMARTD_H_CVSID "$Id: smartd.h,v 1.73 2004/08/16 22:44:28 ballen4705 Exp $\n"
-#endif
-
-// Configuration file
-#define CONFIGFILENAME "smartd.conf"
-
-// Scan directive for configuration file
-#define SCANDIRECTIVE "DEVICESCAN"
-
-// maximum line length in configuration file
-#define MAXLINELEN 128
-
-// maximum length of a continued line in configuration file
-#define MAXCONTLINE 1023
-
-// default for how often SMART status is checked, in seconds
-#define CHECKTIME 1800
-
-/* Boolean Values */
-#define TRUE 0x01
-#define FALSE 0x00
-
-// Number of monitoring flags per Attribute and offsets.  See
-// monitorattflags below.
-#define NMONITOR 4
-#define MONITOR_FAILUSE   0
-#define MONITOR_IGNORE    1
-#define MONITOR_RAWPRINT  2
-#define MONITOR_RAW       3
-
-
-// Number of allowed mail message types
-#define SMARTD_NMAIL 12
-
-typedef struct mailinfo_s {
-  int logged;// number of times an email has been sent
-  time_t firstsent;// time first email was sent, as defined by time(2)
-  time_t lastsent; // time last email was sent, as defined by time(2)
-} mailinfo;
-
-// If user has requested email warning messages, then this structure
-// stores the information about them, and track type/date of email
-// messages.
-typedef struct maildata_s {
-  mailinfo maillog[SMARTD_NMAIL];         // log info on when mail sent
-  char *emailcmdline;                     // script to execute
-  char *address;                          // email address, or null
-  unsigned char emailfreq;                // Emails once (1) daily (2) diminishing (3)
-  unsigned char emailtest;                // Send test email?
-} maildata;
-
-// If user has requested automatic testing, then this structure stores
-// their regular expression pattern, the compiled form of that regex,
-// and information about the disk capabilities and when the last text
-// took place
-
-typedef struct testinfo_s {
-  char *regex;                    // text form of regex
-  regex_t cregex;                 // compiled form of regex
-  unsigned short hour;            // 1+hour of year when last scheduled self-test done
-  char testtype;                  // type of test done at hour indicated just above
-  signed char not_cap_offline;    // 0==unknown OR capable of offline, 1==not capable 
-  signed char not_cap_conveyance;
-  signed char not_cap_short;
-  signed char not_cap_long;
-} testinfo;
-
-
-// cfgfile is the main data structure of smartd. It is used in two
-// ways.  First, to store a list of devices/options given in the
-// configuration smartd.conf or constructed with DEVICESCAN.  And
-// second, to point to or provide all persistent storage needed to
-// track a device, if registered either as SCSI or ATA.
-// 
-// After parsing the config file, each valid entry has a cfgfile data
-// structure allocated in memory for it.  In parsing the configuration
-// file, some storage space may be needed, of indeterminate length,
-// for example for the device name.  When this happens, memory should
-// be allocated and then pointed to from within the corresponding
-// cfgfile structure.
-
-// After parsing the configuration file, each device is then checked
-// to see if it can be monitored (this process is called "registering
-// the device".  This is done in [scsi|ata]devicescan, which is called
-// exactly once, after the configuration file has been parsed and
-// cfgfile data structures have been created for each of its entries.
-//
-// If a device can not be monitored, the memory for its cfgfile data
-// structure should be freed by calling rmconfigentry(cfgfile *). In
-// this case, we say that this device "was not registered".  All
-// memory associated with that particular cfgfile structure is thus
-// freed.
-// 
-// The remaining devices are polled in a timing look, where
-// [ata|scsi]CheckDevice looks at each entry in turn.
-// 
-// If you want to add small amounts of "private" data on a per-device
-// basis, just make a new field in cfgfile.  This is guaranteed zero
-// on startup (when ata|scsi]scsidevicescan(cfgfile *cfg) is first
-// called with a pointer to cfgfile.
-// 
-// If you need *substantial* persistent data space for a device
-// (dozens or hundreds of bytes) please add a pointer field to
-// cfgfile.  As before, this is guaranteed NULL when
-// ata|scsi]scsidevicescan(cfgfile *cfg) is called. Allocate space for
-// it in scsidevicescan or atadevicescan, if needed, and deallocate
-// the space in rmconfigentry(cfgfile *cfg). Be sure to make the
-// pointer NULL unless it points to an area of the heap that can be
-// deallocated with free().  In other words, a non-NULL pointer in
-// cfgfile means "this points to data space that should be freed if I
-// stop monitoring this device." If you don't need the space anymore,
-// please call free() and then SET THE POINTER IN cfgfile TO NULL.
-// 
-// Note that we allocate one cfgfile structure per device.  This is
-// why substantial persisent data storage should only be pointed to
-// from within cfgfile, not kept within cfgfile itself - it saves
-// memory for those devices that don't need that type of persistent
-// data.
-// 
-// In general, the capabilities of devices should be checked at
-// registration time within atadevicescan() and scsidevicescan(), and
-// then noted within *cfg.  So if device lacks some capability, this
-// should be visible within *cfg after returning from
-// [ata|scsi]devicescan.
-// 
-// Devices are then checked, once per polling interval, within
-// ataCheckDevice() and scsiCheckDevice().  These should only check
-// the capabilities that devices already are known to have (as noted
-// within *cfg).
-
-typedef struct configfile_s {
-  // FIRST SET OF ENTRIES CORRESPOND TO WHAT THE USER PUT IN THE
-  // CONFIG FILE.  SOME ENTRIES MAY BE MODIFIED WHEN A DEVICE IS
-  // REGISTERED AND WE LEARN ITS CAPABILITIES.
-  int lineno;                             // Line number of entry in file
-  char *name;                             // Device name (+ optional [3ware_disk_XX])
-  unsigned char controller_type;          // Controller type, ATA/SCSI/3Ware/(more to come)
-  unsigned char controller_port;          // 1 + (disk number in controller). 0 means controller only handles one disk.
-  char smartcheck;                        // Check SMART status
-  char usagefailed;                       // Check for failed Usage Attributes
-  char prefail;                           // Track changes in Prefail Attributes
-  char usage;                             // Track changes in Usage Attributes
-  char selftest;                          // Monitor number of selftest errors
-  char errorlog;                          // Monitor number of ATA errors
-  char permissive;                        // Ignore failed SMART commands
-  char autosave;                          // 1=disable, 2=enable Autosave Attributes
-  char autoofflinetest;                   // 1=disable, 2=enable Auto Offline Test
-  unsigned char fixfirmwarebug;           // Fix firmware bug
-  char ignorepresets;                     // Ignore database of -v options
-  char showpresets;                       // Show database entry for this device
-  char removable;                         // Device may disappear (not be present)
-  char powermode;                         // skip check, if disk in idle or standby mode
-  unsigned char selflogcount;             // total number of self-test errors
-  unsigned short selfloghour;             // lifetime hours of last self-test error
-  testinfo *testdata;                     // Pointer to data on scheduled testing
-  unsigned short pending;                 // lower 8 bits: ID of current pending sector count
-                                          // upper 8 bits: ID of offline pending sector count
-  
-  // THE NEXT SET OF ENTRIES ALSO TRACK DEVICE STATE AND ARE DYNAMIC
-  maildata *mailwarn;                     // non-NULL: info about sending mail or executing script
-
-  // SCSI ONLY
-  unsigned char SmartPageSupported;       // has log sense IE page (0x2f)
-  unsigned char TempPageSupported;        // has log sense temperature page (0xd)
-  unsigned char Temperature;              // last recorded figure (in Celsius)
-  unsigned char SuppressReport;           // minimize nuisance reports
-  unsigned char modese_len;               // mode sense/select cmd len: 0 (don't
-                                          // know yet) 6 or 10
-  unsigned char notused2[3];              // for packing alignment
-
-  // ATA ONLY FROM HERE ON TO THE END
-  int ataerrorcount;                      // Total number of ATA errors
-  
-  // following NMONITOR items each point to 32 bytes, in the form of
-  // 32x8=256 single bit flags 
-  // valid attribute numbers are from 1 <= x <= 255
-  // monitorattflags+0  set: ignore failure for a usage attribute
-  // monitorattflats+32 set: don't track attribute
-  // monitorattflags+64 set: print raw value when tracking
-  // monitorattflags+96 set: track changes in raw value
-  unsigned char *monitorattflags;
-
-  // NULL UNLESS (1) STORAGE IS ALLOCATED WHEN CONFIG FILE SCANNED
-  // (SET BY USER) or (2) IT IS SET WHEN DRIVE IS AUTOMATICALLY
-  // RECOGNIZED IN DATABASE (WHEN DRIVE IS REGISTERED)
-  unsigned char *attributedefs;            // -v options, see end of extern.h for def
-
-  // ATA ONLY - SAVE SMART DATA. NULL POINTERS UNLESS NEEDED.  IF
-  // NEEDED, ALLOCATED WHEN DEVICE REGISTERED.
-  struct ata_smart_values *smartval;       // Pointer to SMART data
-  struct ata_smart_thresholds_pvt *smartthres; // Pointer to SMART thresholds
-
-} cfgfile;
-
-
-typedef struct changedattribute_s {
-  unsigned char newval;
-  unsigned char oldval;
-  unsigned char id;
-  unsigned char prefail;
-  unsigned char sameraw;
-} changedattribute_t;
-
-// Declare our own printing functions. Doing this provides error
-// messages if the argument number/types don't match the format.
-#ifndef __GNUC__
-#define __attribute__(x)      /* nothing */
-#endif
-void PrintOut(int priority,char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
-
-void PrintAndMail(cfgfile *cfg, int which, int priority, char *fmt, ...) __attribute__ ((format(printf, 4, 5)));   
-
-/* Debugging notes: to check for memory allocation/deallocation problems, use:
-
-export LD_PRELOAD=libnjamd.so;
-export NJAMD_PROT=strict;           
-export NJAMD_CHK_FREE=error;
-export NJAMD_DUMP_LEAKS_ON_EXIT=num;
-export NJAMD_DUMP_LEAKS_ON_EXIT=3;
-export NJAMD_TRACE_LIBS=1
-
-*/
-
-// Number of seconds to allow for registering a SCSI device. If this
-// time expires without sucess or failure, then treat it as failure.
-// Set to 0 to eliminate this timeout feature from the code
-// (equivalent to an infinite timeout interval).
-#define SCSITIMEOUT 0
-
-// This is for solaris, where signal() resets the handler to SIG_DFL
-// after the first signal is caught.
-#ifdef HAVE_SIGSET
-#define SIGNALFN sigset
-#else
-#define SIGNALFN signal
-#endif
-
-#endif
-
-#define SELFTEST_ERRORCOUNT(x) (x & 0xff)
-#define SELFTEST_ERRORHOURS(x) ((x >> 8) & 0xffff)
-
-// cfg->pending is a 16 bit unsigned quantity.  If the least
-// significant 8 bits are zero, this means monitor Attribute
-// CUR_UNC_DEFAULT's raw value.  If they are CUR_UNC_DEFAULT, this
-// means DON'T MONITOR.  If the most significant 8 bits are zero, this
-// means monitor Attribute OFF_UNC_DEFAULT's raw value.  If they are
-// OFF_UNC_DEFAULT, this means DON'T MONITOR.
-#define OFF_UNC_DEFAULT 198
-#define CUR_UNC_DEFAULT 197
-
-#define CURR_PEND(x) (x & 0xff)
-#define OFF_PEND(x) ((x >> 8) & 0xff)
-
-// if cfg->pending has this value, dont' monitor
-#define DONT_MONITOR_UNC (256*OFF_UNC_DEFAULT+CUR_UNC_DEFAULT)
diff --git a/sm5/smartd.initd.in b/sm5/smartd.initd.in
deleted file mode 100755
index 3c4fa58d4fc80b26089c3e79120a58ada95e9715..0000000000000000000000000000000000000000
--- a/sm5/smartd.initd.in
+++ /dev/null
@@ -1,418 +0,0 @@
-#! @SHELL@
-
-# smartmontools init file for smartd
-# Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-# $Id: smartd.initd.in,v 1.26 2004/08/13 12:41:40 arvoreen Exp $
-
-# For RedHat and cousins:
-# chkconfig: 2345 40 40
-# description: Self Monitoring and Reporting Technology (SMART) Daemon
-# processname: smartd 
-
-# For SuSE and cousins
-### BEGIN INIT INFO
-# Provides:          smartd
-# Required-Start:    $syslog
-# X-UnitedLinux-Should-Start: $sendmail
-# Required-Stop:     $syslog
-# X-UnitedLinux-Should-Stop:
-# Default-Start:     2 3 5
-# Default-Stop:
-# Short-Description: Monitors disk and tape health via S.M.A.R.T.
-# Description:       Start S.M.A.R.T. disk and tape monitor.
-### END INIT INFO
-
-# 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, write to the Free Software Foundation, Inc., 675
-# Mass Ave, Cambridge, MA 02139, USA.
-# This code was originally developed as a Senior Thesis by Michael Cornwell
-# at the Concurrent Systems Laboratory (now part of the Storage Systems
-# Research Center), Jack Baskin School of Engineering, University of
-# California, Santa Cruz. http://ssrc.soe.ucsc.edu/.
-
-# Uncomment the line below to pass options to smartd on startup. 
-# Note that distribution specific configuration files like
-# /etc/{default,sysconfig}/smartmontools might override these
-#smartd_opts="--interval=1800"
-
-report_unsupported () {
-    echo "Currently the smartmontools package has no init script for"
-    echo "the $1 OS/distribution. If you can provide one or this"
-    echo "one works after removing some ifdefs, please contact"
-    echo "smartmontools-support@lists.sourceforge.net."
-    exit 1
-}
-
-# Red Hat or Yellow Dog or Mandrake
-if [ -f /etc/redhat-release -o -f /etc/yellowdog-release -o -f /etc/mandrake-release -o -f /etc/whitebox-release ] ; then
-    
-# Source function library
-    . /etc/rc.d/init.d/functions
-
-# Source configuration file.  This should define the shell variable smartd_opts
-    [ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
-    
-    RETVAL=0
-    
-    prog=smartd
-    
-    case "$1" in
-	start)
-	    echo -n $"Starting $prog: "
-	    daemon /usr/sbin/smartd $smartd_opts
-	    touch /var/lock/subsys/smartd
-	    echo
-	    ;;
-	stop)
-	    echo -n $"Shutting down $prog: "
-	    killproc smartd
-	    rm -f /var/lock/subsys/smartd
-	    echo
-	    ;;
-	reload)
-            echo -n $"Reloading $prog daemon configuration: "
-	    killproc /usr/sbin/smartd -HUP
-	    RETVAL=$?
-	    echo
-	    ;;
-	report)
-	    echo -n $"Checking SMART devices now: "
-	    killproc /usr/sbin/smartd -USR1
-	    RETVAL=$?
-	    echo
-            ;;
-	restart)
-	    $0 stop
-	    $0 start
-	    ;;
-	status)
-	    status $prog
-	    ;;
-	*)
-	    echo $"Usage: $0 {start|stop|reload|report|restart|status}"
-	    RETVAL=1
-    esac
-    
-    exit $RETVAL
-
-# Slackware
-elif [ -f /etc/slackware-version ] ; then
-    
-# Source configuration file.  This should define the shell variable smartd_opts.
-# Email smartmontools-support@lists.sourceforge.net if there is a better choice
-# of path for Slackware.
-
-    [ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
-
-    case "$1" in
-	start)
-	    echo -n "Starting smartd: "
-	    smartd $smartd_opts
-	    echo
-	    ;;
-	stop)
-	    echo -n "Shutting down smartd: "
-	    killall smartd
-	    echo
-	    ;;
-	restart)
-	    $0 stop
-	    sleep 1
-	    $0 start
-	    ;;
-	*)
-	    echo "Usage: smartd {start|stop|restart}"
-	    exit 1
-    esac
-    
-    exit 0
-    
-# SuSE
-elif [ -f /etc/SuSE-release ] ; then
-    
-    SMARTD_BIN=/usr/sbin/smartd
-    test -x $SMARTD_BIN || exit 5
-
-    # Existence of config file is optional
-    SMARTD_CONFIG=/etc/smartd.conf
-
-# source configuration file. This should set the shell variable smartd_opts
-    [ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
-
-   # Shell functions sourced from /etc/rc.status:
-   #      rc_check         check and set local and overall rc status
-   #      rc_status        check and set local and overall rc status
-   #      rc_status -v     ditto but be verbose in local rc status
-   #      rc_status -v -r  ditto and clear the local rc status
-   #      rc_failed        set local and overall rc status to failed
-   #      rc_reset         clear local rc status (overall remains)
-   #      rc_exit          exit appropriate to overall rc status
-    . /etc/rc.status
-    
-   # First reset status of this service
-    rc_reset
-    
-   # Return values acc. to LSB for all commands but status:
-   # 0 - success
-   # 1 - misc error
-   # 2 - invalid or excess args
-   # 3 - unimplemented feature (e.g. reload)
-   # 4 - insufficient privilege
-   # 5 - program not installed
-   # 6 - program not configured
-   #
-   # Note that starting an already running service, stopping
-   # or restarting a not-running service as well as the restart
-   # with force-reload (in case signalling is not supported) are
-   # considered a success.
-    case "$1" in
-	start)
-	    echo -n "Starting smartd"
-            ## Start daemon with startproc(8). If this fails
-            ## the echo return value is set appropriate.
-	    
-            # startproc should return 0, even if service is
-            # already running to match LSB spec.
-            startproc $SMARTD_BIN $smartd_opts
-	    
-            # Remember status and be verbose
-            rc_status -v
-	    ;;
-	stop)
-	    echo -n "Shutting down smartd"
-            killproc -TERM $SMARTD_BIN
-	    
-            # Remember status and be verbose
-            rc_status -v
-	    ;;
-	restart | force-reload)
-	    $0 stop
-	    $0 start
-	    ;;
-	reload)
-	## Like force-reload, but if daemon does not support
-	## signaling, do nothing (!)
-	    rc_failed 3
-	    rc_status -v
-	    ;;
-        status)
-            echo -n "Checking for service smartd: "
-            ## Check status with checkproc(8), if process is running
-            ## checkproc will return with exit status 0.
-	    
-            # Status has a slightly different for the status command:
-            # 0 - service running
-            # 1 - service dead, but /var/run/  pid  file exists
-            # 2 - service dead, but /var/lock/ lock file exists
-            # 3 - service not running
-	    
-            # NOTE: checkproc returns LSB compliant status values.
-            checkproc $SMARTD_BIN
-            rc_status -v
-            ;;
-        probe)
-	    ## Optional: Probe for the necessity of a reload, print out the
-	    ## argument to this init script which is required for a reload.
-	    ## Note: probe is not (yet) part of LSB (as of 1.2)
-
-	    test $SMARTD_CONFIG -nt /var/run/smartd.pid && echo reload
-	    ;;
-	*)
-	    echo "Usage: $0 {start|stop|status|restart|force-reload|reload|probe}"
-	    exit 1
-	    ;;
-    esac
-    
-    rc_exit
-
-# Debian case
-elif [ -f /etc/debian_version ] ; then
-        PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-	SMARTCTL=/usr/sbin/smartctl
-	SMARTD=/usr/sbin/smartd
-	SMARTDPID=/var/run/smartd.pid
-	[ -x $SMARTCTL ] || exit 0
-	[ -x $SMARTD ] || exit 0
-	RET=0
-
-# source configuration file
-	[ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
-
-	smartd_opts="--pidfile $SMARTDPID $smartd_opts"
-	
-	case "$1" in
-	start)
-		echo -n "Starting S.M.A.R.T. daemon: smartd"
-		if start-stop-daemon --start --quiet --pidfile $SMARTDPID \
-	    	--exec $SMARTD -- $smartd_opts; then 
-	    		echo "."
-		else
-	        	echo " (failed)"
-			RET=1
-	    	fi
-	;;
-	stop)
-		echo -n "Stopping S.M.A.R.T. daemon: smartd"
-		start-stop-daemon --stop --quiet --oknodo --pidfile $SMARTDPID
-		echo "."
-	;;
-	restart|force-reload)
-       		$0 stop
-        	$0 start
-        	;;
-  	*)
-		echo "Usage: /etc/init.d/smartmontools {start|stop|restart|force-reload}"
-		exit 1
-	esac
- 	exit $RET
-
-elif [ -f /etc/gentoo-release ] ; then
-    report_unsupported "Gentoo"
-
-elif [ -f /etc/turbolinux-release ] ; then
-    report_unsupported "Turbolinux"
-
-elif [ -f /etc/environment.corel ] ; then
-    report_unsupported "Corel"
-
-# PLEASE ADD OTHER LINUX DISTRIBUTIONS JUST BEFORE THIS LINE, USING elif
-
-elif uname -a | grep FreeBSD > /dev/null 2>&1 ; then
-# following is replaced by port install
-    PREFIX=@@PREFIX@@
-    
-# Updated to try both the RCNG version of things from 5.x, or fallback to
-# oldfashioned rc.conf
-
-    if [ -r /etc/rc.subr ]; then 
-# This is RC-NG, pick up our values
-	. /etc/rc.subr
-        name="smartd"
-	rcvar="smartd_enable" 
-        command="${PREFIX}/bin/smartd"
-	load_rc_config $name
-    elif [ -r /etc/defaults/rc.conf ]; then
-# Not a 5.x system, try the default location for variables
-	. /etc/defaults/rc.conf
-	source_rc_confs
-    elif [ -r /etc/rc.conf ]; then
-# Worst case, fallback to system config file
-	. /etc/rc.conf
-    fi
-
-    if [ -r /etc/rc.subr ]; then 
-# Use new functionality from RC-NG
-	run_rc_command "$1"
-    else
-	PID_FILE=/var/run/smartd.pid
-	case "$1" in
-	    start)
-		$PREFIX/bin/smartd -p $PID_FILE $smartd_flags
-		echo -n " smartd"
-		;;
-	    stop)
-		kill `cat $PID_FILE`
-		echo -n " smartd"
-		;;
-	    restart)
-		$0 stop
-		sleep 1
-		$0 start
-		;;
-	    *)
-		echo "Usage: smartd {start|stop|restart}"
-		exit 1
-	esac
-	
-	exit 0
-    fi
-elif uname -a | grep SunOS > /dev/null 2>&1 ; then
-    
-# Source configuration file.  This should define the shell variable smartd_opts.
-# Email smartmontools-support@lists.sourceforge.net if there is a better choice
-# of path for Solaris
-
-    [ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
-
-    PID_FILE=/var/run/smartd.pid
-    
-    case "$1" in
-	start)
-	    smartd -p $PID_FILE $smartd_opts
-	    echo -n "smartd "
-	    ;;
-	stop)
-	    [ -f $PID_FILE ] && kill `cat $PID_FILE`
-	    echo -n "smartd "
-	    ;;
-	restart)
-	    $0 stop
-	    sleep 1
-	    $0 start
-	    ;;
-	*)
-	    echo "Usage: smartd {start|stop|restart}"
-	    exit 1
-    esac
-    
-    exit 0
-elif uname | grep -i CYGWIN > /dev/null 2>&1 ; then
-
-# Source configuration file.  This should define the shell variable smartd_opts.
-# Email smartmontools-support@lists.sourceforge.net if there is a better choice
-# of path for Cygwin
-
-    [ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
-
-    PID_FILE=/var/run/smartd.pid
-    RETVAL=0
-
-    case "$1" in
-        start)
-            echo -n "Starting smartd: "
-            /usr/sbin/smartd -p $PID_FILE $smartd_opts
-            RETVAL=$?
-            ;;
-        stop)
-            echo -n "Shutting down smartd: "
-            [ -r $PID_FILE ] && kill `cat $PID_FILE`
-            RETVAL=$?
-            ;;
-        reload)
-            echo -n "Reloading smartd configuration: "
-            [ -r $PID_FILE ] && kill -HUP `cat $PID_FILE`
-            RETVAL=$?
-            ;;
-        report)
-            echo -n "Checking SMART devices now: "
-            [ -r $PID_FILE ] && kill -USR1 `cat $PID_FILE`
-            RETVAL=$?
-            ;;
-        restart)
-            $0 stop
-            sleep 1
-            $0 start
-            exit $?
-            ;;
-        *)
-            echo "Usage: $0 {start|stop|restart|reload|report}"
-            exit 1
-    esac
-
-    if [ "$RETVAL" -eq 0 ]; then echo "done"; else echo "ERROR"; fi
-    exit $RETVAL
-
-# Add other OSes HERE, using elif...
-else
-    report_unsupported "Unknown"
-fi
-
-# One should NEVER arrive here, except for a badly written case above,
-# that fails to exit.  
-echo "SOMETHING IS WRONG WITH THE SMARTD STARTUP SCRIPT"
-echo "PLEASE CONTACT smartmontools-support@lists.sourceforge.net"
-exit 1
diff --git a/sm5/smartmontools.spec b/sm5/smartmontools.spec
deleted file mode 100644
index 181a69217338b0953516ee6a44311e899e7d51f4..0000000000000000000000000000000000000000
--- a/sm5/smartmontools.spec
+++ /dev/null
@@ -1,1551 +0,0 @@
-Release:  1
-Summary:	smartmontools - for monitoring S.M.A.R.T. disks and devices
-Summary(cs):	smartmontools - pro monitorov�n� S.M.A.R.T. disk� a za��zen�
-Summary(de):	smartmontools - zur �berwachung von S.M.A.R.T.-Platten und-Ger�ten
-Summary(es):	smartmontools - para el seguimiento de discos y dispositivos S.M.A.R.T.
-Summary(fr):	smartmontools - pour le suivi des disques et instruments S.M.A.R.T.
-Summary(pt):	smartmontools - para monitorar discos e dispositivos S.M.A.R.T.
-Summary(it):	smartmontools - per monitare dischi e dispositivi S.M.A.R.T.
-Summary(pl):	Monitorowanie i kontrola dysk�w u�ywaj�� S.M.A.R.T.
-Name:		smartmontools
-Version:	5.33
-License:	GPL
-Group:		Applications/System
-Group(de):	Applikationen/System
-Group(es):	Aplicaciones/Sistema
-Group(fr):	Applications/Syst�me
-Group(pt):	Aplicativos/Sistema
-Group(it):      Applicazioni/Sistemi
-Source0:	%{name}-%{version}.tar.gz
-URL:            http://smartmontools.sourceforge.net/
-Prereq:		/sbin/chkconfig
-BuildRoot:	%{_tmppath}/%{name}-%{version}-root
-Obsoletes:	smartctl
-Obsoletes:      smartd
-Obsoletes:	ucsc-smartsuite
-Obsoletes:      smartsuite
-Packager:       Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
-%define redhat      %(test ! -f /etc/redhat-release ; echo $?)
-%define redhat      %(test ! -f /etc/fedora-release ; echo $?)
-%define mandrake    %(test ! -f /etc/mandrake-release ; echo $?)
-%define suse        %(test ! -f /etc/SuSE-release ; echo $?)
-
-# Source code can be found at:
-# http://ftp1.sourceforge.net/smartmontools/smartmontools-%{version}-%{release}.tar.gz
-
-# CVS ID of this file is:
-# $Id: smartmontools.spec,v 1.160 2004/07/07 14:45:19 ballen4705 Exp $
-
-# Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-# Home page: http://smartmontools.sourceforge.net/
-#
-# 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, write to the Free Software Foundation, Inc., 675
-# Mass Ave, Cambridge, MA 02139, USA.
-#
-# This code was originally developed as a Senior Thesis by Michael Cornwell
-# at the Concurrent Systems Laboratory (now part of the Storage Systems
-# Research Center), Jack Baskin School of Engineering, University of
-# California, Santa Cruz. http://ssrc.soe.ucsc.edu/
-
-
-%description
-smartmontools controls and monitors storage devices using the
-Self-Monitoring, Analysis and Reporting Technology System (S.M.A.R.T.)
-built into ATA and SCSI Hard Drives.  This is used to check the
-reliability of the hard drive and to predict drive failures.  The suite
-is derived from the smartsuite package, and contains two utilities.  The
-first, smartctl, is a command line utility designed to perform simple
-S.M.A.R.T. tasks.  The second, smartd, is a daemon that periodically
-monitors smart status and reports errors to syslog.  The package is
-compatible with the ATA/ATAPI-5 specification.  Future releases will be
-compatible with the ATA/ATAPI-6 andATA/ATAPI-7 specifications.  The
-package is intended to incorporate as much "vendor specific" and
-"reserved" information as possible about disk drives.  man smartctl and
-man smartd will provide more information.  This RPM file is compatible
-with all RedHat releases back to at least 6.2 and should work OK on any
-modern linux distribution.  The most recent versions of this package and
-additional information can be found at the URL:
-http://smartmontools.sourceforge.net/
-
-%description -l cs
-smartmontools ��d� a monitoruj� za��zen� pro ukl�d�n� dat za pou�it�
-technologie automatick�ho monitorov�n�, anal�zy a hl�en�
-(Self-Monitoring, Analysis and Reporting Technology System -
-S.M.A.R.T.) vestav�n�ho do pevn�ch disk� ATA a SCSI. Pou��v� se ke
-kontrole pou�itelnosti pevn�ho disku a p�edv�d�n� hav�ri� disk�.
-N�stroje jsou odvozeny od bal��ku smartsuite a obsahuj� dva programy.
-Prvn�, smartctl, je n�stroj pro prov�d�n� jednoduch�ch S.M.A.R.T. �loh
-na p��kazov� ��dce. Druh�, smartd, je d�mon, kter� periodicky
-monitoruje stav a hl�s� chyby do syst�mov�ho protokolu. Bal��ek je
-kompatibiln� se specifikac� ATA/ATAPI-5. Dal�� verze budou
-kompatibiln� se specifikacemi ATA/ATAPI-6 a ATA/ATAPI-7. Bal��ek je
-navr�en tak, aby pokryl co nejv�ce polo�ek s informacemi "z�visl� na
-v�robci" a "rezervov�no". V�ce informac� z�sk�te pomoc� man smartctl a
-man smartd. Tento RPM bal��ek je kompatibiln� se v�emi verzemi RedHatu
-a m�l by fungovat na v�ech modern�ch distribuc�ch Linuxu. Aktu�ln�
-verzi najdete na URL http://smartmontools.sourceforge.net/
-
-%description -l de
-Die smartmontools steuern und �berwachen Speicherger�te mittels des
-S.M.A.R.T.-Systems (Self-Monitoring, Analysis and Reporting Technology,
-Technologie zur Selbst-�berwachung, Analyse und Berichterstellung), das
-in ATA- und SCSI-Festplatten eingesetzt wird.  Sie werden benutzt, um
-die Zuverl�ssigkeit der Festplatte zu pr�fen und Plattenfehler
-vorherzusagen.  Die Suite wurde vom smartsuite-Paket abgeleitet und
-enth�lt zwei Dienstprogramme.  Das erste, smartctl, ist ein
-Kommandozeilentool, das einfache S.M.A.R.T. Aufgaben ausf�hrt.  Das
-zweite, smartd, ist ein Daemon, der periodisch den S.M.A.R.T.-Status
-�berwacht und Fehler ins Syslog protokolliert.  Das Paket ist zur
-ATA/ATAPI-5 Spezifikation kompatibel. Zuk�nftige Versionen werden auch
-die ATA/ATAPI-6 und ATA/ATAPI-7 Spezifikationen umsetzen.  Das Paket
-versucht, so viele "herstellerspezifische" und "reservierte" Information
-�ber Plattenlaufwerke wie m�glich bereitzustellen.  man smartctl und man
-smartd liefern mehr Informationen �ber den Einsatz.  Dieses RPM ist zu
-allen RedHat-Versionen ab sp�testens 6.2 kompatibel und sollte unter
-jedem modernen Linux arbeiten.  Die aktuellsten Versionen dieses Pakets
-und zus�tzliche Informationen sind zu finden unter der URL:
-http://smartmontools.sourceforge.net/
-
-%description -l es
-smartmontools controla y hace el seguimiento de dispositivos de
-almacenamiento usando el Self-Monitoring, Analysis and Reporting
-Technology System (S.M.A.R.T.) incorporado en discos duros ATA y SCSI. 
-Es usado para asegurar la fiabilidad de discos duros y predecir averias. 
-El conjunto de programas proviene del conjunto smartsuite y contiene dos
-utilidades.  La primera, smartctl, es una utilidad command-line hecha
-para hacer operaciones S.M.A.R.T. sencillas.  La segunda, smartd, es un
-programa que periodicamente chequea el estatus smart e informa de
-errores a syslog.  Estos programas son compatibles con el sistema
-ATA/ATAPI-5.  Futuras versiones seran compatibles con los sistemas
-ATA/ATAPI-6 y ATA/ATAPI-7.  Este conjunto de programas tiene el
-proposito de incorporar la mayor cantidad posible de informacion
-reservada y especifica de discos duros.  Los comandos 'man smartctl' y
-'man smartd' contienen mas informacion.  Este fichero RPM es compatible
-con todas las versiones de RedHat a partir de la 6.2 y posiblemente
-funcionaran sin problemas en cualquier distribucion moderna de linux. 
-La version mas reciente de estos programas ademas de informacion
-adicional pueden encontrarse en: http://smartmontools.sourceforge.net/
-
-%description -l fr
-smartmontools contr�le et fait le suivi de p�riph�riques de stockage
-utilisant le syst�me Self-Monitoring, Analysis and Reporting
-Technology (S.M.A.R.T) int�gr�dans les disques durs ATA et SCSI.  Ce
-syst�me est utilis� pour v�rifier la fiabilit� du disque dur et pr�dire
-les d�faillances du lecteur.  La suite logicielle d�rive du paquet
-smartsuite et contient deux utilitaires.  Le premier, smartctl,
-fonctionne en ligne de commande et permet de r�aliser des t�ches
-S.M.A.R.T. simples.  Le second, smartd, est un d�mon qui fait
-p�riodiquement le suivi du statut smart et transmet les erreurs au
-syslog.  Ce paquet est compatible avec la sp�cification ATA/ATAPI-5. 
-Les prochaines versions seront compatibles avec les sp�cifications
-ATA/ATAPI-6 et ATA/ATAPI-7.  Ce paquet tente d'incorporer le plus
-d'informations possible sur les disques durs qu'elles soient sp�cifiques
-au constructeur ("vendor specific") ou r�serv�es ("reserved").  man
-smartctl et man smartd donnent plus de renseignements.  Ce fichier RPM
-est compatible avec toutes les versions de RedHat v6.2 et ult�rieures,
-et devrait fonctionner sur toutes les distributions r�centes de Linux. 
-Les derni�res versions de ce paquet et des informations suppl�mentaires
-peuvent �tre trouv�es � l'adresse URL:
-http://smartmontools.sourceforge.net/
-
-%description -l pt
-smartmontools controla e monitora dispositivos de armazenamento
-utilizando o recurso Self-Monitoring, Analysis and Reporting Technology
-System (S.M.A.R.T.) integrado nos discos r�gidos ATA e SCSI, cuja
-finalidade � verificar a confiabilidade do disco r�gido e prever falhas
-da unidade.  A suite � derivada do pacote smartsuite, e cont�m dois
-utilit�rios.  O primeiro, smartctl, � um utilit�rio de linha de comando
-projetado para executar tarefas simples de S.M.A.R.T.  O segundo,
-smartd, � um daemon que monitora periodicamente estados do smart e
-reporta erros para o syslog.  O pacote � compat�vel com a especifica��o
-ATA/ATAPI-5.  Futuras vers�es ser�o compat�veis com as especifica��es
-ATA/ATAPI-6 e ATA/ATAPI-7.  O pacote pretende incorporar o maior n�mero
-poss�vel de informa��es "espec�ficas do fabricante" e "reservadas" sobre
-unidades de disco.  man smartctl e man smartd cont�m mais informa��es. 
-Este arquivo RPM � compat�vel com todas as vers�es do RedHat a partir da
-6.2 e dever� funcionar perfeitamente em qualquer distribui��o moderna do
-Linux.  As mais recentes vers�es deste pacote e informa��es adicionais
-podem ser encontradas em http://smartmontools.sourceforge.net/
-
-%description -l it
-smartmontools controlla e monitora dischi che usano il "Self-Monitoring,
-Analysis and Reporting Technology System" (S.M.A.R.T.), in hard drive
-ATA e SCSI. Esso � usato per controllare l'affidabilit� dei drive e
-predire i guasti. La suite � derivata dal package smartsuite e contiene
-due utility. La prima, smartctl, � una utility a linea di comando
-progettata per eseguire semplici task S.M.A.R.T.. La seconda, smartd, �
-un daemon che periodicamente monitora lo stato di smart e riporta errori
-al syslog. Il package � compatibile con le specifiche ATA/ATAPI-6 e
-ATA/ATAPI-7. Il package vuole incorporare tutte le possibili
-informazioni riservate e "vendor specific" sui dischi. man smartctl e
-man smartd danno pi� informazioni. Questo file RPM � compatibile con
-tutte le release di RedHat, almeno dalla 6.2 e dovrebbe funzionare bene
-su ogni moderna distribuzione di linux. Le versioni pi� recenti di
-questo package e informazioni addizionali possono essere trovate al sito
-http://smartmontools.sourceforge.net/
-
-%description -l pl
-Pakiet zawiera dwa programy (smartctl oraz smartd) do kontroli i
-monitorowania system�w przechowywania danych za pomoc� S.M.A.R.T -
-systemu wbudowanego w wi�kszo�� nowych dysk�w ATA oraz SCSI. Pakiet
-pochodzi od oprogramowania smartsuite i wspiera dyski ATA/ATAPI-5.
-
-# The following sections are executed by the SRPM file
-%prep
-
-%setup -q
-
-%build
-  %configure
-  make
-
-%install
-  rm -rf $RPM_BUILD_ROOT
-  rm -rf %{_buildroot}
-  %makeinstall
-  rm -f examplescripts/Makefile*
-  %if %{suse}
-    mkdir -p $RPM_BUILD_ROOT%{_defaultdocdir}
-    mv $RPM_BUILD_ROOT/usr/share/doc/%{name}-%{version} $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}
-    ln -s ../../etc/rc.d/init.d/smartd $RPM_BUILD_ROOT%{_sbindir}/rcsmartd
-  %endif
-
-%files
-  %defattr(-,root,root)
-  %attr(755,root,root) %{_sbindir}/smartd
-  %attr(755,root,root) %{_sbindir}/smartctl
-  %if %{suse}
-    %attr(755,root,root) %{_sbindir}/rcsmartd
-  %endif
-  %attr(755,root,root) /etc/rc.d/init.d/smartd
-  %attr(644,root,root) %{_mandir}/man8/smartctl.8*
-  %attr(644,root,root) %{_mandir}/man8/smartd.8*
-  %attr(644,root,root) %{_mandir}/man5/smartd.conf.5*
-  %doc AUTHORS CHANGELOG COPYING INSTALL NEWS README TODO WARNINGS smartd.conf examplescripts
-  %config(noreplace) %{_sysconfdir}/smartd.conf
-
-%clean
-  rm -rf $RPM_BUILD_ROOT
-  rm -rf %{_buildroot}
-  rm -rf %{_builddir}/%{name}-%{version}
-
-# The following are executed only by the binary RPM at install/uninstall
-
-# since this installs the gzipped documentation files, remove
-# non-gzipped ones of the same name.
-
-# run before installation.  Passed "1" the first time package installed, else a larger number
-%pre
-if [ -f /usr/share/man/man8/smartctl.8 ] ; then
-	echo "You MUST delete (by hand) the outdated file /usr/share/man/man8/smartctl.8 to read the new manual page for smartctl."	
-fi
-if [ -f /usr/share/man/man8/smartd.8 ] ; then
-	echo "You MUST delete (by hand) the outdated file /usr/share/man/man8/smartd.8 to read the new manual page for smartd."	
-fi
-if [ -f /usr/share/man/man5/smartd.conf.5 ] ; then
-        echo "You MUST delete (by hand) the outdated file /usr/share/man/man5/smartd.conf.5 to read the new manual page for smartd.conf"
-fi
-
-if [ ! -f /etc/smartd.conf ]; then
-	echo "Note that you can use a configuration file /etc/smartd.conf to control the"
-	echo "startup behavior of the smartd daemon.  See man 8 smartd for details."
-fi
-
-# run after installation.  Passed "1" the first time package installed, else a larger number
-%post
-# if smartd is already running, restart it with the new daemon
-if [ -f /var/lock/subsys/smartd ]; then
-        /etc/rc.d/init.d/smartd restart 1>&2
-	echo "Restarted smartd services"
-else
-# else tell the user how to start it
-        echo "Run \"/etc/rc.d/init.d/smartd start\" to start smartd service now."
-fi
-
-# Now see if we should tell user to set service to start on boot	
-/sbin/chkconfig --list smartd > /dev/null 2> /dev/null
-printmessage=$?
-
-if [ $printmessage -ne 0 ] ; then
-	echo "Run \"/sbin/chkconfig --add smartd\", to start smartd service on system boot"
-else
-	echo "smartd will continue to start up on system boot"
-fi
-
-
-# run before uninstallation.  Passed zero when the last version uninstalled, else larger
-%preun
-
-# if uninstalling the final copy, stop and remove any links	
-if [ "$1" = "0" ]; then
-  if [ -f /var/lock/subsys/smartd ]; then
-    /etc/rc.d/init.d/smartd stop 1>&2
-    echo "Stopping smartd services"
-  fi
-
-# see if any links remain, and kill them if they do
-  /sbin/chkconfig --list smartd > /dev/null 2> /dev/null
-  notlinked=$?
-	
-  if [ $notlinked -eq 0 ]; then
-    /sbin/chkconfig --del smartd
-    echo "Removing chkconfig links to smartd boot-time startup scripts"
-  fi
-fi
-
-# run after uninstallation. Passed zero when the last version uninstalled, else larger
-# %postun
-
-%define date	%(echo `LC_ALL="C" date +"%a %b %d %Y"`)
-
-# Maintainers / Developers Key:
-# [BA] Bruce Allen
-# [EB] Erik Inge Bols�
-# [SB] Stanislav Brabec
-# [PC] Peter Cassidy
-# [CD] Capser Dik
-# [CF] Christian Franke
-# [GF] Guilhem Fr�zou
-# [DG] Douglas Gilbert
-# [GG] Guido Guenther
-# [DK] David Kirkby
-# [KM] Kai M�kisarai
-# [EM] Eduard Martinescu
-# [FM] Fr�d�ric L. W. Meunier
-# [KS] Keiji Sawada
-# [SS] Sergey Svishchev
-# [PW] Phil Williams
-
-%changelog
-* Mon Jul 5 2004 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-  [BA] Update link to revised/updated IBM Deskstar Firmware
-  [CF] Cygwin & Windows: Added missing ASPI manager initialization
-       with GetASPI32SupportInfo(). Thanks to Nikolai SAOUKH for pointing
-       this out and providing a patch.
-  [BA] modified smartd init script to work on whitebox (thanks to
-       Michael Falzon)
-  [BA] removed (reverted) additional Attribute definitions from
-       http://smart.friko.pl/attributes.php.  All (or most?) of these
-       appear to be return code values for the WD Digital Life Guard Utility.
-  [PW] Added Seagate Medalist 17242, 13032, 10232, 8422, and 4312 to
-       knowndrives table.  Added missing Seagate U Series 5 drives.
-  [PW] Added the following QUANTUM models to knowndrives table:
-       FIREBALL EX6.4A, FIREBALLP AS10.2, FIREBALLP AS40.0, FIREBALL CR4.3A,
-       FIREBALLP LM15, FIREBALLP LM30, and FIREBALLlct20 30
-  [PW] Added missing Western Digital Protege drives to knowndrives table.
-  [PW] Added Maxtor DiamondMax 40 ATA 66 series and DiamondMax 40 VL Ultra
-       ATA 100 series to knowndrives table.
-  [PW] Added the following Hitachi/IBM drives to knowndrives table:
-       HITACHI_DK14FA-20B, Travelstar 40GNX series, Travelstar 4LP series,
-       and Travelstar DK23XXB series.  Added the missing Travelstar 80GN
-       drives.
-  [PW] Added Fujitsu MPB series and MPG series to knowndrives table.  Added
-       the missing Fujitsu MHSxxxxAT drives.
-  [KS] Solaris: added workaround for dynamic change of time-zone.
-  [KS] Solaris: fixed problem that autogen.sh cannot detect absence of
-       auto* tools.
-  [BA] smartd: added time-zone bug information to man page. 
-       Reverted CF code for _WIN32 case. 
-  [CF] Cygwin & Windows: Added better error messages on IDE/ATA device
-       open error.
-  [BA] added additional Attribute definitions from
-       http://smart.friko.pl/attributes.php
-  [BA] smartd: reworked TimeZone bug workaround so it is only invoked
-       for glibc.  Note: this might not be right -- a similar bug may
-       exist in other platform's libcs.
-  [DG] SCSI smartmontools documentation updated [2004/5/6]. See:
-       http://smartmontools.sourceforge.net/smartmontools_scsi.html
-  [CF] Windows: Fixed reset of TZ=GMT in glibc timezone bug workaround.
-
-* Tue May 4 2004 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-  [DG] move SCSI device temperature and start-stop log page output
-       (smartctl) into --attributes section (was in --info section).
-  [GG] change default installation location to /usr/local
-  [CF] Cygwin smartd: Fixed crash on access of SCSI devices after fork().
-  [PW] Added TOSHIBA MK4018GAS and the following Maxtor drive families
-       to knowndrives table: DiamondMax D540X-4G, Fireball 541DX,
-       DiamondMax 3400 Ultra ATA, DiamondMax Plus 6800 Ultra ATA 66.
-  [PW] Added missing Maxtor DiamondMax 16, DiamondMax D540X-4K, and
-       DiamondMax Plus 45 Ulta ATA 100 drives to knowndrives table.
-  [PW] Added ExcelStor J240, Hitachi Travelstar 80GN family, Fujitsu
-       MHTxxxxAT family, and IBM Deskstar 25GP and 22GXP families to
-       knowndrives table.
-  [CF] Cygwin smartd: Added workaround for missing SIGQUIT via keyboard:
-       To exit smartd in debug mode, type CONTROL-C twice.
-  [BA] smartctl: printing of the selective self-test log is now
-       controlled by a new option: -l selective
-  [BA] Added entries for Samsung firmware versions -25 to -39 based
-       on latest info about firmware bug fixes.
-  [PW] Added Seagate U Series X family, Seagate U8 family, and Seagate
-       Medalist 8641 family to knowndrives table.
-  [CF] smartd: Added exit values 5/6 for missing/unreadable config file.
-  [BA] smartd: now monitor the Current Pending Sector count (Attribute 197)
-       and the Offline Pending Sector Count (Attribute 198).  Log a
-       warning (and send an email, if so configured) if the raw count
-       is nonzero.  These are controlled by new Directives: -C and -U.
-       Currently they are enabled by default.
-  [CF] Added option -c FILE, --configfile=FILE to smartd to specify
-       an alternate configuration FILE or '-' for standard input.
-  [KS] configure.in now searches for -lnsl and -lsocket for Solaris.
-  [CF] Win32/native smartd: Added thread to combine several syslog output
-       lines into one single event log entry.
-  [CF] Win32 smartd: Added DEVICESCAN for SCSI/ASPI devices.
-  [GG] Use gethostbyname() the get the DNS domain since getdomainname() 
-       returns the NIS domain when sending mails from smartd.
-  [GG] smartd.init.in: pass smartd_opts to smartd on startup, read distribution
-       specific configuration files if found
-  [SS] smartctl: added NetBSD support for Selective Self-tests.
-  [BA] smartd.conf example configuration file now has all examples
-       commented out except for 'DEVICESCAN'.
-  [CF] Win32/native smartd: Added ability to display warning "emails"
-       as message box by "-m msgbox" directive. With "-m sysmsgbox",
-       a system modal (always on top) message box is shown.
-  [BA] smartctl: printing of self-test log for disks that support
-       Selective self-testing now shows the status of the (optional)
-       read-scan after the selective self test.  Also, changed format
-       in printing self-test log to print failing LBA in base 10 not
-       base 16 (more compatible with kernel error messages).  Also,
-       in printing SMART error log, print timestamps in format
-       days+hours+minutes+seconds.
-  [CF] Win32 smartd: Added ability to log to stdout/stderr
-       (-l local1/2). Toggling debug console still works
-       if stdout is redirected.
-  [BA] smartctl: selective self-test log, print current status
-       in a  more detailed way.  Allow writing of selective self-test
-       log provided that no other self-test is underway.
-  [BA] Linux: eliminated dependency on kernel tree hdreg.h.
-  [BA] smartctl: -l selftest option now prints Selective self-test
-       log in addition to the normal self-test log.
-       Added additional options (-t pending, -t afterselect) to
-       control remaining Selective Self-test capabilities.  Tested
-       with several Maxtor disks. Modified error message printing
-       so that munged option messages print at the end not the
-       start of output.
-  [CF] Added daemon support to Win32 native version of smartd.
-       The daemon can be controlled by commands similar to initd
-       scripts: "smartd status|stop|reload|restart|sigusr1|sigusr2".
-  [CF] Added minor support for option "-l local[0-7]" to Win32 native
-       (not Cygwin) version of smartd. If specified, the log output
-       is written to file "./smartd[1-7]?.log" instead of event log.
-  [BA] Added Selective Self-test to smartctl (-t selective,M-N).
-       Currently only supported under Linux; Solaris, NetBSD, FreeBSD
-       and Windows developers must add WRITE LOG functionality to
-       os_*.c
-  [BA] Added workaround for an annoying glibc bug: if you change
-       timezones, (eg, flying with a laptop from USA to Europe)
-       localtime() does not notice this in a running
-       executable, so time that appears in the system log (syslog!)
-       will be incorrect.  See
-       http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48184
-       for additional examples of this bug.
-  [DG] Set explicit timeouts for SCSI commands (most default to 6 seconds).
-       Previously a 0 second timeout was meant to be interpreted as a 
-       default timeout but the FreeBSD port had a problem in this area.
-  [CF] Fixed un-thread-safe exit signal handler for Win32
-  [BA] Fixed un-thread-safe exit signal handler pointed out
-       by CF.
-  [BA] Changed configure script to eliminate warnings under
-       Solaris from sys/int_type.h conflicts with int64.h
-       Added header files for umask to smartd.c.
-  [BA] Man page format change from Werner LEMBERG.  " " changed to \&
-  [CF] Added os_win32/syslogevt.* event message file tool for Win32
-       smartd (native+cygwin). May also be useful for other cygwin
-       programs writing to syslog().
-  [CF] Added Win32 version of smartd
-  [CF] Merged RELEASE_5_26_WIN32_BRANCH
-  [BA] Made some changes to man page markup suggested by
-       Richard Verhoeven to work around bugs in man2html.
-       Tested not to break anything under Linux and Solaris.
-  [CF] Moved PrintOut() from utility.c to smart{ctl,d}.c to avoid
-       syslog() output of smartctl.
-  [BA] Grew worried that some time-zone names could be very long (eg,
-       Mitteleuropaische Zeit) and put date string lengths into a
-       single macro in utility.c
-  [EM] Updated os_freebsd.c to handle older versions of FreeBSD in a 
-       more appropriate/obvious fashion.
-  [EM] Modified autogen.sh as FreeBSD installs automake 1.7 as 
-       'automake17' and NOT 'automake-1.7'
-
-* Sat Mar 6 2004 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-  [PW] Added QUANTUM FIREBALLlct15 30, QUANTUM FIREBALLlct20 40, and
-       Maxtor 6Y060P0 (DiamondMax Plus 9 60GB) to knowndrives table.
-  [PW] Added Maxtor MaXLine II family to knowndrives table (thanks to
-       Brett Russ for submitting the patch).
-  [BA] Added remaining read/write commands to detailed list of
-       error log commands that have text descriptions of problem
-       printed.  For commands that support it, print number of failed
-       sectors at problem LBA.
-  [BA] Made SuSE section of smartd init script more SuSE 9 compatible.
-       Thanks to Hans-Peter Jansen.
-  [CF] Windows smartd: Added IDE/ATA device scan
-       Added windows device names to smartctl.8.in, smartd.8.in
-  [BA] smartctl/smartd: user-provided '-F samsung' and '-F samsung2'
-       command line options/Directives did NOT over-ride preset values
-       unless user specified '-P ignore'.  Now they will always over-ride
-       preset values from the database.
-  [BA] Added error decoding for a few more READ and WRITE commands.
-  [PW] Added Maxtor MaXLine Plus II, Western Digital Caviar SE (Serial ATA)
-       series, Hitachi Deskstar 7K250 series, and Ultra ATA 66 models of
-       the Maxtor DiamondMax Plus 40 series to knowndrives table.
-  [BA] Added Maxtor Diamondmax 250 GB drives to database.  Note that
-       these model numbers are not listed in Maxtor documentation, but
-       they exist.
-  [BA] Removed the 'contact developers' phrase from the Samsung disk
-       warning messages.
-  [PW] Added TOSHIBA MK2017GAP, IBM Deskstar 14GXP and 16GP series,
-       Fujitsu MPC series, Seagate Barracuda ATA III family, and missing
-       Seagate Barracuda U Series drives to knowndrives table
-  [BA] smartd: wrong loglevel for message: Configuration file
-       /etc/smartd.conf parsed.  Changed to LOG_INFO from LOG_CRIT.
-       Thanks to  Emmanuel CHANTREAU for the report.
-  [CF] Checked in development version of windows code base.
-
-* Tue Feb 24 2004 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-  [BA] smartd: configure script did not set correct directory to search for
-       smartd.conf based on --prefix argument to ./configure.  Thanks to
-       GG for identifying the problem and fix.
-  [BA] make clean now removes man pages (generated from *.in) files as well
-       as object files.
-  [EM] Correct copying of sense data in FreeBSD SCSI implementation. Thanks
-       to Sergey Svishchev for noticing the bug.
-  [BA] On solaris, wrong warning message if no ATA support.  Warning message
-       concerns 3ware controller, not ATA.
-  [SS] Added SCSI support for NetBSD.
-  [BA] on big-endian linux machines, fixed interpretation of HDIO_GET_IDENTITY
-       to correctly identify ATAPI bit (was byte swapped).  This should
-       eliminate some SYSLOG noise if user queries a packet device (eg, CD
-       ROM or DVD reader).
-  [PW] Removed warning for IBM Deskstar 40GV & 75GXP series drives with
-       A5AA/A6AA firmware.  Thanks to Gerald Schnabel.
-  [PW] Added Toshiba TOS MK3019GAXB SUN30G to knowndrives table
-  [PW] Added Western Digital Caviar AC12500, AC24300, AC25100, AC36400,
-       and AC38400 to knowndrives table
-  [BA] When printing ATA error log, print the LBA at which READ
-       or WRITE commands failed.
-  [BA] Changed syntax of error message in smartctl
-  [BA] Added versioning info (-V options to smartd/smartctl) for
-       Solaris ATA module.
-
-* Thu Feb 12 2004 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-  [KS] Added ATA/IDE support for Solaris/SPARC (ATA/IDE not yet for
-       Solaris/x86).
-  [BA] 3ware controllers: documented that one can monitor any of the
-       physical disks from any of the 3ware /dev/sd? logical devices.
-       Better warnings if querying a disk that does not exist.
-  [PW] Added Hitachi Travelstar DK23DA series, Maxtor DiamondMax Plus 40
-       series, Western Digital Caviar WDxxxAA, WDxxxBA, and WDxxxAB series
-       to knowndrives table
-  [BA] missing 'pragma pack' on ATA IDENIFY DEVICE structure may have
-       caused odd or incorrect results on 64-bit machines.
-  [BA] smartctl/smartd allow inspection of self-test and error logs even
-       if disk firmware claims that these don't exist.  This is needed
-       for some Maxtor disks whose firmware does not indicate log support
-       even though the disk DOES support it.
-  [BA] Improved porting instructions and documentation in os_generic.c
-  [PW] Add Western Digital Caviar WD136AA and SAMSUNG SP40A2H (RR100-07
-       firmware) to knowndrives table.
-  [EM] FreeBSD:	remove extra definition of FreeNonZero
-  [BA] smartctl: the -q silent option was printing output for some
-       error conditions.  Fixed.  Will rename relevant variables to help
-       avoid these errors in the future.
-  [SS] NetBSD port added.
-  [BA] more sensible error messages for devfs and devfs-like systems.
-       Instead of saying that the DIRECTORY does not exist, say that
-       the DEVICE does not exist.
-  [BA] smartd: added -n Directive, to prevent disk spin-up depending
-       upon the power mode (SLEEP, STANDBY, or IDLE).
-  [PW] Added Maxtor DiamondMax 20 VL series, Fujitsu MPF series,
-       Maxtor DiamondMax 36 series, Maxtor DiamondMax 4320 series, and
-       Maxtor DiamondMax 536DX series to knowndrives table.
-  [BA] many warning messages now give the file name AND VERSION
-  [BA] smartd: when the user provides multiple address recipients
-       to the '-m' Directive in a comma-delineated list, the commas
-       are stripped out before passing the list of addresses to the
-       mailer program. (Thanks to Calin A. Culianu for pointing this out
-       and providing a patch.)
-  [BA] smartd: when the '-M exec path' Directive is used, any stdout OR
-       stderr output from the executable "path" is assumed to indicate a
-       problem, and is echoed to SYSLOG.
-  [BA] Added all missing IBM/Hitachi Deskstar 180GXP models to knowndrives
-       table.
-  [PW] Added some missing IBM/Hitachi Deskstar 120GXP models to knowndrives
-       table.
-  [PW] Added IBM Travelstar 14GS to knowndrives table.
-  [PW] Modified knowndrives table to match entire Hitachi Travelstar
-       DK23BA and DK23EA series of drives (thanks to Norikatsu Shigemura
-       for submitting the patch).
-  [PW] Added some missing Fujitsu MPE series drives to knowndrives table.
-  [PW] Added TOSHIBA MK4019GAX, TOSHIBA MK6409MAV, and QUANTUM
-       FIREBALLlct15 20 to knowndrives table.
-  [EM] Fixup example command output for FreeBSD
-  [PW] Added Maxtor DiamondMax 80 family to knowndrives table.
-  [EM] Catch up FreeBSD code to switch PROJECTHOME to PACKAGE_HOMEPAGE
-       macros.
-  [BA] smartd: now watches stdout/stderr when trying to run mail, mailx
-       or mail warning script, and reports any output to SYSLOG.  This
-       gives a clearer error message if something is wrong.
-  [BA] smartd: Solaris init script modified to accomodate grep that
-       lacks '-q' quiet option.  Also check for running process to kill
-       on stop.
-  [PW] Added some missing Seagate Barracuda 7200.7 and 7200.7 Plus drives
-       to knowndrives table.
-  [PW] Added Maxtor DiamondMax Plus 60 family and Seagate U Series 5 20413
-       to knowndrives table.
-  [BA] smartd: under Solaris, made default mailer be 'mailx' not
-       'mail', since Solaris 'mail' does not accept a '-s' argument.
-       A workaround for Solaris users of earlier versions is to
-       have '-M exec /bin/mailx' in their smartd.conf config file.
-  [DG] some SCSI controllers don't like odd length transfers so make
-       sure LOG SENSE transfers are rounded up to an even number when
-       and odd length is reported (i.e. there is a double fetch, the
-       first to find the length, the second gets the data)
-  [BA] smartd man pages: under Solaris, correct section numbers in the
-       'See also' section.
-  [KS/BA] smartd man page: describe how to set Solaris syslog.conf
-       file to catch all messages.  Give correct Solaris SYSLOG default
-       path /var/adm/messages in man pages.
-  [BA] smartd: incorporated Debian startup script submitted by user.
-  [BA] smartctl: modified printing of self-test log entry number.  Seagate
-       firmware can leave 'holes' in the self-test log while a test is
-       actually running.  We now print entry numbers consistently in this
-       case, not assuming that entries are contiguous.
-  [PW] Added QUANTUM FIREBALL CX10.2A and Western Digital Caviar AC23200L
-       to knowndrives table.
-  [PW] Added QUANTUM FIREBALLlct20 20 to knowndrives table.
-  [PW] Added Maxtor DiamondMax Plus D740X family to knowndrives table.
-  [PW] Added IBM Travelstar 32GH, 30GT, and 20GN family to knowndrives
-       table.
-  [BA] Slackware init script modified to search for /etc/slackware-version
-       rather than /etc/slackware-release.
-  [PW] Added Seagate Barracuda ATA II family and TOSHIBA MK4019GAXB to
-       knowndrives table.
-  [GG] explain howto use autoreconf in autogen.sh
-  [KS] Makefile.am/configure.in: changed manual page sections for
-       Solaris.
-  [BA] smartd: reduced number of scheduled self-test messages if
-       test already run in current hour.
-  [PW] Added Maxtor DiamondMax Plus 8 family to knowndrives table.
-  [BA] linux: check for linux/hdreg.h.  If it's there, use it. If
-       not, provide the necessary definitions ourselves.
-  [PW] Removed warning for IBM Deskstar 40GV & 75GXP series drives
-       with TXAOA5AA firmware
-  [PW] Added IBM Travelstar 25GS, 18GT, and 12GN family to knowndrives
-       table.
-  [PW] Added IBM/Hitachi Travelstar 60GH & 40GN family to knowndrives
-       table.
-  [BA] smartd: made '-s' Directive more efficient.  Now store
-       compiled regex, and re-use.  If device lacks certain self-test
-       capabilities, track it and don't try again.
-  [BA] smartd: made memory allocation for device lists completely
-       dynamic (eliminating compile-time maximum length constants).
-  [PW] Removed warning for SAMSUNG SP0802N with TK100-23 firmware
-  [PW] Added Seagate Barracuda ATA IV family to knowndrives table.
-  [BA] smartd: reduce per-device memory footprint by making
-       mail-warning info dynamically allocated.  Also remove
-       potential memory leak if use has -m Directive twice and
-       keeps reloading the config file (highly unlikely this would
-       ever be noticed!)  
-  [DG] smartd: added SCSI scheduled self-tests (Background
-       short or extended).
-  [BA] smartd: can now run scheduled offline immediate and
-       self-tests.  See man page and -s Directive for details.
-  [GG] don't include manpages in make-dist-tarball.
-  [BA] smartctl: on-line examples given with -h are now correct
-       for solaris and linux, but wrong for freebsd.  Ed?
-  [BA] smartd: man page now explains device scanning for solaris as
-       well as linux and freebsd.
-  [BA] smartd/smartctl: man pages now report correct CVS tag release
-       date, and executables '-V' options reports more build info.
-
-* Sat Nov 29 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-  [BA] Improved user messages that appear from 'make install'
-  [PW] Removed warning for SAMSUNG SP1213N with firmware TL100-23
-  [BA] incorporated SuSE init script from user.
-  [DG] if SCSI device is read only, then open it read only.
-  [BA] when compiled on non-supported system (NOT linux, freebsd or solaris) then
-       the run-time error messages now clearly say 'your system is not supported'
-       and give clear directions.
-  [BA] ./configure script now works correctly on SuSE linux boxes
-  [BA] minor improvements to man pages
-  [BA] simplified detection of packet (ATAPI, CD) devices.
-  [BA] init script (redhat, mandrake, yellowdog) now uses correct
-       strings for translation and is slightly more standard.
-  [DG] smartctl: output scsi Seagate vendor pages for disks (not tapes)
-* Wed Nov 19 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-  [DG] smartd/smartctl: changed scsiClearControlGLTSD() to
-       scsiSetControlGLTSD() with an 'enabled' argument so '-S on'
-       and '-S off' work for SCSI devices (if changing GLTSD supported).
-  [BA] smartd/smartctl: wired in scsiClearControlGLTSD(). Could still
-       use a corresponding Set function.  Left stubs for this purpose.
-  [DG] scsicmds: added scsiClearControlGLTSD() [still to be wired in]
-  [BA] smartctl: make SCSI -T options behave the same way as the
-       ATA ones.
-  [DG] smartctl: output scsi transport protocol if available
-  [DG] scsi: stop device scan in smartd and smartctl if badly formed
-       mode response [heuristic to filter out USB devices before we
-       (potentially) lock them up].
-  [BA] smartd: deviceclose()->CloseDevice(). Got rid of SCSIDEVELOPMENT
-       macro-enabled code.  Added -W to list of gcc specific options to
-       always enable. Made code clean for -W warnings.
-  [PW] Added Maxtor DiamondMax VL 30 family to knowndrives table.
-  [DG] scsi: add warning (when '-l error' active) if Control mode page
-       GLTSD bit is set (global disable of saving log counters)
-  [DG] scsi: remember mode sense cmd length. Output trip temperature
-       from IE lpage (IBM extension) when unavailable from temp lpage.
-  [BA] smartd: for both SCSI and ATA now warns user if either
-       the number of self-test errors OR timestamp of most
-       recent self-test error have increased.
-  [DG] smartctl: output Seagate scsi Cache and Factory log pages (if
-       available) when vendor attributes chosen
-  [DG] smartd: add scsiCountFailedSelfTests() function.
-  [DG] Do more sanity checking of scsi log page responses.
-  [BA] smartd: now warns user if number of self-test errors has
-       increased for SCSI devices.
-  [BA] smartd: warn user if number of ATA self-test errors increases
-       (as before) OR if hour time stamp of most recent self-test
-       error changes.
-  [DG] More checks for well formed mode page responses. This has the side
-       effect of stopping scans on bad SCSI implementations (e.g. some
-       USB disks) prior to sending commands (typically log sense) that
-       locks them up.
-  [PW] Added Western Digital Caviar family and Caviar SE family to
-       knowndrives table.
-  [BA] smartd: added -l daemon (which is the default value if -l
-       is not used).
-  [PW] Added Seagate Barracuda ATA V family to knowndrives table.
-  [BA] smartd: added additional command line argument -l FACILITY
-       or --logfacility FACILITY.  This can be used to redirect
-       messages from smartd to a different file than the one used
-       by other system daemons.
-  [PW] Added Seagate Barracuda 7200.7, Western Digital Protege WD400EB,
-       and Western Digital Caviar AC38400 to knowndrives table.
-  [BA] smartd: scanning should now also work correctly for
-       devfs WITHOUT traditional links /dev/hd[a-t] or /dev/sd[a-z].
-  [PW] Added Maxtor 4W040H3, Seagate Barracuda 7200.7 Plus,
-       IBM Deskstar 120GXP (40GB), Seagate U Series 20410,
-       Fujitsu MHM2100AT, MHL2300AT, MHM2150AT, and IBM-DARA-212000
-       to knowndrives table.
-  [PW] Added remaining Maxtor DiamondMax Plus 9 models to knowndrives
-       table.
-  [EM] smartd: If no matches found, then return 0, rather than an error
-       indication, as it just means no devices of the given type exist.
-       Adjust FreeBSD scan code to mirror Linux version.
-  [BA] smartd: made device scan code simpler and more robust. If
-       too many devices detected, warn user but scan as many
-       as possible.  If error in scanning, warn user but don't
-       die right away.
-  [EM] smartd: To keep as consistent as possible, migrate FreeBSD
-       devicescan code to also use glob(3). Also verified clean 
-       compile on a 4.7 FreeBSD system.
-  [BA] smartd: Modified device scan code to use glob(3). Previously
-       it appeared to have trouble when scanning devices on an XFS
-       file system, and used non-public interface to directory
-       entries. Problems were also reported when /dev/ was on an
-       ext2/3 file system, but there was a JFS partition on the same
-       disk.
-  [BA] Clearer error messages when device scanning finds no suitable
-       devices.
-  [EM] FreeBSD:	Fixup code to allow for proper compilation under 
-       -STABLE branch.
-
-* Fri Oct 31 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartd: didn't close file descriptors of ATA packet devices
-       that are scanned. Fixed.
-- [BA] Added reload/report targets to the smartmontools init script.
-       reload: reloads config file
-       report: send SIGUSR1 to check devices now
-
-* Mon Oct 27 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [EM] Fix compile issues for FreeBSD < 5-CURRENT.
-- [PW] Added Fujitsu MHM2200AT to knowndrives table.
-- [BA] To help catch bugs, clear ATA error structures before all
-       ioctl calls.  Disable code that attempted to time-out on SCSI
-       devices when they hung (doesn't work).
-- [BA] Documented STATUS/ERROR flags added by [PW] below.
-- [BA] Improved algorithm to recognize ATA packet devices. Should
-       no longer generate SYSLOG kernel noise when user tries either
-       smartd or smartctl on packet device (CD-ROM or DVD).  Clearer
-       warning messages from smartd when scanning ATA packet device.
-- [PW] Added TOSHIBA MK4025GAS to knowndrives table.
-- [PW] Added a textual interpretation of the status and error registers
-       in the SMART error log (ATA).  The interpretation is
-       command-dependent and currently only eight commands are supported
-       (those which produced errors in the error logs that I happen to
-       have seen).
-- [BA] added memory allocation tracking to solaris code.
-       Fixed solaris signal handling (reset handler to default
-       after first call to handler) by using sigset. Added
-       HAVE_SIGSET to configure.in
-- [CD] solaris port: added SCSI functionality to solaris
-       stubs.
-- [BA] smartd: attempt to address bug report about smartd
-       hanging on USB devices when scanning:
-       https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=107615
-       Set a timeout of SCSITIMEOUT (nominally 7 seconds) before
-       giving up.
-- [EM] smartd: DEVICESCAN will follow links in a devfs filesystem and
-       make sure the end point is a disc.  Update documentation, added
-       note about FreeBSD scanning
-- [BA] smartd: DEVICESCAN also looks for block devices in
-       /dev.  Updated documentation.  Now scans for up to
-       20 ATA devices /dev/hda-t rather than previous 12
-       /dev/hda-l.
-- [EM] smartd: mirror the FreeBSD DEVICESCAN logic for Linux,
-       so that smartd now scans only devices found in /dev/. Also,
-       make utility memory functions take a line number and file so
-       that we report errors with the correct location.
-- [GG] add a note about Debian bug #208964 to WARNINGS.
-- [BA] smartctl: -T verypermissive option broken.  Use
-       -T verpermissive until the next release, please.
-- [BA] Syntax mods so that code also compiles on Solaris using
-       Sun Workshop compiler.  Need -xmemalign 1i -xCC flags
-       for cc.
-
-* Wed Oct 15 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-  [DK] Changed configure.in so -Wall is only included if gcc
-       is used (this is a gcc specific flag) and -fsignedchar
-       is not used at all (this is a gcc specific compiler 
-       flag).
-  [BA] Modifications so that code now compiles under solaris. Now
-       all that's needed (:-) is to fill in os_solaris.[hc].  Added
-       os_generic.[hc] as guide to future ports.  Fixed -D option
-       of smartd (no file name).  Modified -h opt of smartd/smartctl
-       to work properly with solaris getopt().
-  [EM] Update MAN pages with notes that 3ware drives are NOT supported
-	under FreeBSD. Cleanup FreeBSD warning message handling.
-  [EM] FreeBSD only: Fix first user found bug....I guess I was making
-       the wrong assumption on how to convert ATA devnames to
-       channel/unit numbers.
-  [EM] Allow for option --enable-sample to append '.sample' to installed
-	smartd.conf and rc script files. Also, let rc script shell setting
-	be determined by configure
-  [EM] Minor autoconf update to include -lcam for FreeBSD
-  [EM] Add conditional logic to allow FreeBSD to compile pre-ATAng.
-	-- note, not tested
-	Add some documentation to INSTALL for FreeBSD.
-  [EM] Implement SCSI CAM support for FreeBSD.  NOTE: I am not an expert
-	in the use of CAM.  It seems to work for me, but I may be doing
-	something horribly wrong, so please exercise caution.
-  [EM] Switch over to using 'atexit' rather than 'on_exit' routine. This also
-  	meant we needed to save the exit status elsewhere so our 'Goodbye'
-	routine could examine it.
-  [EM] Move the DEVICESCAN code to os specific files. Also moved some of the
-	smartd Memory functions to utility.c to make available to smartctl.
-  [EM] Code janitor work on os_freebsd.c.
-  [EM] Added os_freebsd.[hc] code.  Additional code janitor
-       work.
-  [BA] Code janitor working, moving OS dependent code into
-       os_linux.[hc].
-  [GG] conditionally compile os_{freebsd,linux}.o depending on
-       host architecture
-  [PW] Print estimated completion time for tests
-  [BA] Added -F samsung2 flag to correct firmware byte swap.
-       All samsung drives with *-23 firmware revision string.
-
-* Sun Oct 05 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [GG] Fixed broken Makefile.am (zero length smartd.conf.5
-       was being created)
-- [FM] Improved Slackware init script added to /etc/smartd.initd
-
-* Fri Oct 03 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartctl: added '-T verypermissive' option which is
-       equivalent to giving '-T permissive' many times.
-- [BA] Try harder to identify from IDENTIFY DEVICE structure
-       if SMART supported/enabled.  smartd now does a more
-       thorough job of trying to assess this before sending
-       a SMART status command to find out for sure.
-- [BA] smartctl: it's now possible to override the program's
-       guess of the device type (ATA or SCSI) with -d option.
-- [BA] try hard to avoid sending IDENTIFY DEVICE to packet
-       devices (CDROMS).  They can't do SMART, and this generates
-       annoying syslog messages. At the same time, identify type
-       of Packet device.
-- [BA] smartctl: Can now use permissive option more
-       than once, to control how far to go before giving up.
-- [BA] smartd: if user asked to monitor either error or self-test
-       logs (-l error or -l selftest) WITHOUT monitoring any of the
-       Attribute values, code will SEGV.  For 5.1-18 and earlier,
-       a good workaround is to enable Auto offline (-o on).
-- [BA] smartctl: If enable auto offline command given, update auto
-       offline status before printing capabilities.
-- [GG] Make autotools build the default, remove autotools.diff
-- [GG] Add auto{conf,make} support, not enabled by default. 
-- [BA] Eliminated #include <linux/hdreg.h> from code. This
-       should simplify porting to solaris, FreeBSD, etc. The
-       only linux-specific code is now isolated to three routines,
-       one for SCSI, one for Escalade, one for ATA.
-
-* Fri Aug 22 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartd: fixed serious bug - Attributes not monitored unless
-       user told smartd to ignore at least one of them!
-
-* Tue Aug 19 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] Default runlevels for smartd changed from 3 and 5 to
-       2, 3, 4, and 5.
-- [BA] Removed as much dynamic memory allocation as possible from
-       configuration file parsing. Reloading config file, even in
-       presence of syntax errors etc. should not cause memory leaks.
-- [PW] It is no longer permissible for the integer part (if any) of
-       arguments to --report and --device to be followed by non-digits.
-       For example, the "foo" in --report=ioctl,2foo was previously
-       ignored, but now causes an error.
-- [BA] smartd: added -q/--quit command line option to specify
-       under what circumstances smartd should exit.  The old
-       -c/--checkonce option is now obsoleted by this more
-       general-purpose option.
-- [BA] smartd now responds to a HUP signal by re-reading its
-       configuration file /etc/smartd.conf.  If there are
-       errors in this file, then the configuration file is
-       ignored and smartd continues to monitor the devices that
-       it was monitoring prior to receiving the HUP signal.
-- [BA] Now correctly get SMART status from disks behind 3ware
-       controllers, thanks to Adam Radford. Need 3w-xxxx driver
-       version 1.02.00.037 or later. Previously the smartmontools
-       SMART status always returned "OK" for 3ware controllers.
-- [BA] Additional work on dynamic memory allocation/deallocation.
-       This should have no effect on smartctl, but clears that way
-       for smartd to dynamically add and remove entries.  It should
-       also now be easier to modify smartd to re-read its config
-       file on HUP (which is easy) without leaking memory (which is
-       harder). The philosophy is that memory for data structures in
-       smartd is now allocated only on demand, the first time it
-       is needed.
-- [BA] smartd: finished cleanup.  Now use create/rm functions for
-       cfgentries and dynamic memory allocation almost everywhere.
-       Philosophy: aggresively try and provoke SEGV to help find
-       bad code.
-- [BA] Added SAMSUNG SV0412H to knowndrives table.
-- [BA] smartd: if DEVICESCAN used then knowndrives table might not set
-       the -v attributes correctly -- may have been the same for all
-       the drives.  Cleaned up some data structures and memory
-       allocation to try and ensure segvs if such problems are
-       introduced again.
-- [BA] Now allow -S on and -o on for the 3ware device type.  For these
-       commands to be passed through, the stock 3ware 3w-xxxx driver
-       must be patched (8 lines).  I'll post a patch on the smartmontools
-       home page after it's been tested by a few other people and 3ware
-       have had a chance to look it over.
-
-* Wed Aug 06 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartd - can now monitor ATA drives behind 3ware controllers.
-- [BA] smartd - changed some FATAL out of memory error messages from
-       syslog level LOG_INFO to LOG_CRIT.
-- [BA] smartctl - added code to look at ATA drives behind 3ware RAID
-       controllers using the 3w-xxxx driver.  Note that for technical
-       reasons related to the 3w-xxxx driver, the "Enable Autosave",
-       "Enable Automatic Offline" commands are not implemented.
-       I will add this to smartd shortly.
-- [BA] smartd - modified sleep loop, so that smartd no longer comes
-       on the run queue every second.  Instead, unless interrupted,
-       it sleeps until the next polling time, when it wakes up. Now
-       smartd also tries to wake up at exactly the right
-       intervals (nominally 30 min) even if the user has been sending
-       signals to it.
-- [GG] add Fujitsu MHN2300AT to vendoropts_9_seconds.
-- [EB] Fujitsu change in knowndrives ... match the whole MPD and
-       MPE series for vendoropts_9_seconds.
-- [BA] smartd bug, might cause segv if a device can not be opened. Was
-       due to missing comma in char* list.  Consequence is that email
-       failure messages might have had the wrong Subject: heading for
-       errorcount, FAILEDhealthcheck, FAILEDreadsmartdata, FAILEDreadsmarterrorlog,
-       FAILEDreadsmartsefltestlog, FAILEDopendevice were all displaced by
-       one.  And FAILEDopendevice might have caused a segv if -m was being
-       used as a smartd Directive.
-
-* Wed Jul 23 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] Cleaned up smartmontools.spec so that upgrading, removing
-       and other such operations correctly preserve running behavior
-       and booting behavior of smartd.
-- [BA] Improved formatting of ATA Error Log printout, and added
-       listing of names of commands that caused the error. Added
-       obsolete ATA-4 SMART feature commands to table, along with
-       obsolete SFF-8035i SMART feature command.
-- [PW] Added atacmdnames.[hc], which turn command register &
-       feature register pairs into ATA command names.
-- [BA] Added conveyance self-test.  Some code added for selective
-       self-tests, but #ifdefed out.
-- [BA] Modified smartd exit status and log levels.  If smartd is
-       "cleanly" terminated, for example with SIGTERM, then its
-       exit messages are now logged at LOG_INFO not LOG_CRIT
-- [BA] Added Attribute IDs  (Fujitsu) 0xCA - 0xCE.  This is decimal
-       202-206. Added -v switches for interpretation of Attributes
-       192, 198 and 201. 
-- [BA] Made smartmontools work with any endian order machine for:
-       - SMART selftest log
-       - SMART ATA error log
-       - SMART Attributes values
-       - SMART Attributes thesholds
-       - IDENTIFY DEVICE information
-       - LOG DIRECTORY
-       Smartmontools is now free of endian bias and works correctly
-       on both little- and big-endian hardware.  This has been tested by
-       three independent PPC users on a variety of ATA and SCSI hardware.
-- [DG] Check that certain SCSI command responses are well formed. If
-       IEC mode page response is not well formed exit smartctl. This
-       is to protect aacraid. smartd should ignore a aacraid device.
-
-* Mon Jun 16 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartctl: added column to -A output to show if Attributes are
-       updated only during off-line testing or also during normal
-       operation.
-
-* Thu Jun 10 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartd: attempt to enable/disable automatic offline testing even
-       if the disk appears not to support it.  Now the same logic
-       as smartctl.
-- [BA] Added definition of Attribute 201, soft read error rate.
-- [BA] Added IBM/Hitachi IC35L120AVV207-1 (GXP-180) and corresponding
-       8MB Cache GXP-120 to drive database.
-- [BA] smartd: if DEVICESCAN Directive used in smartd.conf, and
-       -I, -R or -r Directives used in conjunction with this, got
-       segv errors.  Fixed by correcting memory allocation calls.
-- [BA] smartd: enable automatic offline testing was broken due
-       to cut-and-paste error that disabled it instead of
-       enabling it.  Thanks to Maciej W. Rozycki for pointing
-       out the problem and solution.
-- [BA] Fixed "spelling" of some Attribute names to replace spaces
-       in names by underscores. (Fixed field width easier for awk
-       style parsing.)
-- [BA] Added mods submitted by Guilhem Frezou to support Attribute 193
-       being load/unload cycles. Add -v 193,loadunload option, useful
-       for Hitachi drive DK23EA-30, and add this drive to knowndrive.c
-       Add meaning of attribute 250 : Read error retry rate
-- [BA] Added another entry for Samsung drives to knowndrive table.
-- [DG] Refine SCSI log sense command to do a double fetch in most cases
-       (but not for the TapeAlert log page). Fix TapeAlert and Self Test
-       log pgae response truncation.
-- [PW] Added 'removable' argument to -d Directive for smartd.  This indicates
-       that smartd should continue (rather than exit) if the device does not 
-       appear to be present.
-- [BA] Modified smartmontools.spec [Man pages location] and
-       smartd.initd [Extra space kills chkconfig!] for Redhat 6.x
-       compatibility (thanks to Gerald Schnabel).
-
-* Wed May 7 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [EB] Add another Fujitsu disk to knowndrives.c
-- [GG] match for scsi/ and ide/ in case of devfs to exclude false postives
-- [BA] If SCSI device listed in /etc/smartd.conf fails to open or do
-       SMART stuff correctly, or not enough space
-       to list all SCSI devices, fail with error unless
-       -DSCSIDEVELOPMENT set during compile-time.
-- [BA] Added automatic recognition of /dev/i* (example: /dev/ide/...)
-       as an ATA device.
-- [DG] Add "Device type: [disk | tape | medium changer | ...]" line to
-       smartctl -i output for SCSI devices.
-- [PW] Fixed bug in smartd where test email would be sent regularly (for
-       example, daily if the user had specified -M daily) instead of just
-       once on startup.
-- [KM] More TapeAlert work. Added translations for media changer
-       alerts. TapeAlert support reported according to the log page
-       presence. ModeSense not attempted for non-ready tapes (all
-       drives do not support this after all). Get peripheral type from
-       Inquiry even if drive info is not printed. Add QUIETON()
-       QUIETOFF() to TapeAlert log check.
-- [BA] Stupid bug in atacmds.c minor_str[] affected ataVersionInfo().
-       Two missing commas meant that minor_str[] had two few elements,
-       leading to output like this:
-       Device Model:     Maxtor 6Y120L0
-       Serial Number:    Y40BF74E
-       Firmware Version: YAR41VW0
-       Device is:        Not in smartctl database [for details use: -P showall]
-       ATA Version is:   7
-       ATA Standard is:  9,minutes
-                         ^^^^^^^^^
-       Missing commas inserted.
-- [BA] Fixed smartd bug.  On device registration, if ATA device did
-       not support SMART error or self-test logs but user had asked to
-       monitor them, an attempt would be made to read them anyway,
-       possibly generating "Drive Seek" errors.  We now check that
-       the self-test and error logs are supported before trying to
-       access them the first time.
-- [GG/BA] Fixed bug where if SMART ATA error log not supported,
-       command was tried anyway. Changed some error printing to use
-       print handlers.
-- [GG] Makefile modifications to ease packaging
-- [DG] Did work for TapeAlerts (SCSI). Now can detect /dev/nst0 as a
-       SCSI device. Also open SCSI devices O_NONBLOCK so they don't
-       hang on open awaiting media. The ATA side should worry about
-       this also: during a DEVICESCAN a cd/dvd device without media
-       will hang. Added some TapeAlert code suggested by Kai Makisara.
-
-* Mon Apr 21 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [PW] Extended the -F option/Directive to potentially fix other firmware
-       bugs in addition to the Samsung byte-order bug.  Long option name is
-       now --firmwarebug and the option/Directive accepts an argument
-       indicating the type of firmware bug to fix.
-- [BA] Fixed a bug that prevented the enable automatic off-line
-       test feature from enabling.  It also prevented the enable Attribute
-       autosave from working.  See CVS entry for additional details.
-- [PW] Modified the -r/--report option (smartctl and smartd) to allow the
-       user to specify the debug level as a positive integer.
-- [BA] Added --log directory option to smartctl.  If the disk
-       supports the general-purpose logging feature set (ATA-6/7)
-       then this option enables the Log Directory to be printed.
-       This Log Directory shows which device logs are available, and
-       their lengths in sectors.
-- [PW] Added -P/--presets option to smartctl and -P Directive to smartd.
-- [GG] Introduce different exit codes indicating the type of problem
-       encountered for smartd.
-- [DG] Add non-medium error count to '-l error' and extended self test
-       duration to '-l selftest'. Get scsi IEs and temperature changes
-       working in smartd. Step over various scsi disk problems rather
-       than abort smartd startup.
-- [DG] Support -l error for SCSI disks (and tapes). Output error counter
-       log pages.
-- [BA] Added -F/--fixbyteorder option to smartctl.  This allows us to read
-       SMART data from some disks that have byte-reversed two- and four-
-       byte quantities in their SMART data structures.
-- [BA] Fixed serious bug: the -v options in smartd.conf were all put
-       together and used together, not drive-by-drive.
-- [PW] Added knowndrives.h and knowndrives.c.  The knowndrives array
-       supersedes the drivewarnings array.
-- [GG] add {-p,--pidfile} option to smartd to write a PID file on
-       startup. Update the manpage accordingly.
-- [DG] Fix scsi smartd problem detecting SMART support. More cleaning
-       and fix (and rename) scsiTestUnitReady(). More scsi renaming.
-- [BA] Fixed smartd so that if a disk that is explictily listed is not
-       found, then smartd will exit with nonzero status BEFORE forking.
-       If a disk can't be registered, this will also be detected before
-       forking, so that init scripts can react correctly.
-- [BA] Replaced all linux-specific ioctl() calls in atacmds.c with
-       a generic handler smartcommandhandler().  Now the only routine
-       that needs to be implemented for a given OS is os_specific_handler().
-       Also implemented the --report ataioctl. This provides 
-       two levels of reporting.  Using the option once gives a summary
-       report of device IOCTL transactions.  Using the option twice give
-       additional info (a printout of ALL device raw 512 byte SMART
-       data structures).  This is useful for debugging.
-- [DG] more scsi cleanup. Output scsi device serial number (VPD page
-       0x80) if available as part of '-i'. Implement '-t offline' as
-       default self test (only self test older disks support).
-- [BA] Changed crit to info in loglevel of smartd complaint to syslog
-       if DEVICESCAN enabled and device not found.
-- [BA] Added -v 194,10xCelsius option/Directive. Raw Attribute number
-       194 is ten times the disk temperature in Celsius.
-- [DG] scsicmds.[hc] + scsiprint.c: clean up indentation, remove tabs.
-       Introduce new intermediate interface based on "struct scsi_cmnd_io"
-       to isolate SCSI generic commands + responses from Linux details;
-       should help port to FreeBSD of SCSI part of smartmontools.
-       Make SCSI command builders more parametric.
-
-* Thu Mar 13 2003  Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartctl: if HDIO_DRIVE_TASK ioctl() is not implemented (no
-       kernel support) then try to assess drive health by examining
-       Attribute values/thresholds directly.
-- [BA] smartd/smartctl: added -v 200,writeerrorcount option/Directive
-       for Fujitsu disks.
-- [BA] smartd: Now send email if any of the SMART commands fails,
-       or if open()ing the device fails.  This is often noted
-       as a common disk failure mode.
-- [BA] smartd/smartctl: Added -v N,raw8 -v N,raw16 and -v N,raw48
-       Directives/Options for printing Raw Attributes in different
-       Formats.
-- [BA] smartd: Added -r ID and -R ID for reporting/tracking Raw
-       values of Attributes.
-- [BA] smartd/smartctl: Changed printing of spin-up-time attribute
-       raw value to reflect current/average as per IBM standard.
-- [BA] smartd/smartctl: Added -v 9,seconds option for disks which
-       use Attribute 9 for power-on lifetime in seconds.
-- [BA] smartctl: Added a warning message so that users of some IBM
-       disks are warned to update their firmware.  Note: we may want
-       to add a command-line flag to disable the warning messages.
-       I have done this in a general way, using regexp, so that we
-       can add warnings about any type of disk that we wish..
-
-* Wed Feb 12 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] smartd: Created a subdirectory examplescripts/ of source
-       directory that contains executable scripts for the -M exec PATH
-       Directive of smartd.
-- [BA] smartd: DEVICESCAN in /etc/smartd.conf
-       can now be followed by all the same Directives as a regular
-       device name like /dev/hda takes.  This allows one to use
-       (for example):
-       DEVICESCAN -m root@example.com
-       in the /etc/smartd.conf file.
-- [BA] smartd: Added -c (--checkonce) command-line option. This checks
-       all devices once, then exits.  The exit status can be
-       used to learn if devices were detected, and if smartd is
-       functioning correctly. This is primarily for Distribution
-       scripters.
-- [BA] smartd: Implemented -M exec Directive for
-       smartd.conf.  This makes it possible to run an
-       arbitrary script or mailing program with the
-       -m option.
-- [PW] smartd: Modified -M Directive so that it can be given
-       multiple times.  Added -M exec Directive.
-
-* Tue Jan 21 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] Fixed bug in smartctl pointed out by Pierre Gentile.
-       -d scsi didn't work because tryata and tryscsi were 
-       reversed -- now works on /devfs SCSI devices.
-- [BA] Fixed bug in smartctl pointed out by Gregory Goddard
-       <ggoddard@ufl.edu>.  Manual says that bit 6 of return
-       value turned on if errors found in smart error log.  But
-       this wasn't implemented.
-- [BA] Modified printing format for 9,minutes to read
-       Xh+Ym not X h + Y m, so that fields are fixed width.
-- [BA] Added Attribute 240 "head flying hours"
-
-* Sun Jan 12 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [BA] As requested, local time/date now printed by smartctl -i
-
-* Thu Jan 9 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [PW] Added 'help' argument to -v for smartctl
-- [PW] Added -D, --showdirectives option to smartd
-
-* Sat Jan 4 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [DG] add '-l selftest' capability for SCSI devices (update smartctl.8)
-- [BA] smartd,smartctl: added additional Attribute modification option
-  -v 220,temp and -v 9,temp.
-- [PW] Renamed smartd option -X to -d
-- [PW] Changed smartd.conf Directives -- see man page
-- [BA/DG] Fixed uncommented comment in smartd.conf
-- [DG] Correct 'Recommended start stop count' for SCSI devices
-- [PW] Replaced smartd.conf directive -C with smartd option -i
-- [PW] Changed options for smartctl -- see man page.
-- [BA] Use strerror() to generate system call error messages.
-- [BA] smartd: fflush() all open streams before fork().
-- [BA] smartctl, smartd simplified internal handling of checksums
-  for simpler porting and less code.
-
-* Sun Dec 8 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- [PW] smartd --debugmode changed to --debug
-- [BA] smartd/smartctl added attribute 230 Head Amplitude from
-  IBM DPTA-353750.
-- [PW] Added list of proposed new options for smartctl to README.
-- [PW] smartd: ParseOpts() now uses getopt_long() if HAVE_GETOPT_LONG is
-  defined and uses getopt() otherwise.  This is controlled by CPPFLAGS in
-  the Makefile.
-- [BA] smartd: Fixed a couple of error messages done with perror()
-  to redirect them as needed.
-- [BA] smartctl: The -O option to enable an Immediate off-line test
-  did not print out the correct time that the test would take to
-  complete.  This is because the test timer is volatile and not
-  fixed.  This has been fixed, and the smartctl.8 man page has been
-  updated to explain how to track the Immediate offline test as it
-  progresses, and to further emphasize the differences between the
-  off-line immediate test and the self-tests.
-- [BA] smartd/smartctl: Added new attribute (200) Multi_Zone_Error_Rate
-- [BA] smartctl: modified so that arguments could have either a single -
-  as in -ea or multiple ones as in -e -a.  Improved warning message for
-  device not opened, and fixed error in redirection of error output of
-  HD identity command.
-- [PW] smartd: added support for long options.  All short options are still
-  supported; see manpage for available long options.
-- [BA] smartctl.  When raw Attribute value was 2^31 or larger, did
-  not print correctly.
-
-* Fri Nov 22 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- Allen: smartd: added smartd.conf Directives -T and -s.  The -T Directive
-  enables/disables Automatic Offline Testing.  The -s Directive
-  enables/disables Attribute Autosave. Documentation and
-  example configuration file updated to agree.
-- Allen: smartd: user can make smartd check the disks at any time
-  (ie, interrupt sleep) by sending signal SIGUSR1 to smartd.  This
-  can be done for example with:
-  kill -USR1 <pid>
-  where <pid> is the process ID number of smartd.
-- Bolso: scsi: don't trust the data we receive from the drive too
-  much. It very well might have errors (like zero response length).
-  Seen on Megaraid logical drive, and verified in the driver source.
-- Allen: smartd: added Directive -m for sending test email and
-  for modifying email reminder behavior.  Updated manual, and sample
-  configuration file to illustrate & explain this.
-- Allen: smartd: increased size of a continued smartd.conf line to
-  1023 characters.
-- Allen: Simplified Directive parsers and improved warning/error
-  messages.
-
-* Sun Nov 17 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- Fixed bug in smartd where testunitready logic inverted
-  prevented functioning on scsi devices.
-- Added testunitnotready to smartctl for symmetry with smartd.
-- Brabec: added Czech descriptions to .spec file
-- Brabec: corrected comment in smartd.conf example
-- Changed way that entries in the ATA error log are printed,
-  to make it clearer which is the most recent error and
-  which is the oldest one.
-- Changed Temperature_Centigrade to Temperature_Celsius.
-  The term "Centigrade" ceased to exist in 1948.  (c.f
-  http://www.bartleby.com/64/C004/016.html).
-
-* Wed Nov 13 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- smartd SCSI devices: can now send warning email message on failure
-- Added a new smartd configuration file Directive: -M ADDRESS.
-  This sends a single warning email to ADDRESS for failures or
-  errors detected with the -c, -L, -l, or -f Directives.
-
-* Mon Nov 11 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- Modified perror() statements in atacmds.c so that printout for SMART
-  commands errors is properly suppressed or queued depending upon users
-  choices for error reporting modes.
-- Added Italian descriptions to smartmontools.spec file.
-- Started impementing send-mail-on-error for smartd; not yet enabled.
- 
-* Sun Nov 10 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- Added -P (Permissive) Directive to smartd.conf file to allow SMART monitoring of
-  pre-ATA-3 Rev 4 disks that have SMART but do not have a SMART capability bit.
-
-* Thu Nov 7 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- Added a Man section 5 page for smartd.conf
-- Changed Makefile so that the -V option does not reflect file state
-  before commit!
-- modified .spec file so that locale information now contains
-  character set definition.   Changed pt_BR to pt since we do not use any
-  aspect other than language.  See man setlocale.
-- smartctl: added new options -W, -U, and -P to control if and how the
-  smartctl exits if an error is detected in either a SMART data
-  structure checksum, or a SMART command returns an error.
-- modified manual page to break options into slightly more logical
-  categories.
-- reformatted 'usage' message order to agree with man page ordering
-
-* Mon Nov 4 2002 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-- smartctl: added new options -n and -N to force device to be ATA or SCSI
-- smartctl: no longer dies silently if device path does not start/dev/X
-- smartctl: now handles arbitrary device paths
-- Added additional macros for manual and sbin paths in this SPEC file.
-- Modified Makefile to install /etc/smartd.conf, but without overwriting existing config file
-- Modified this specfile to do the same, and to not remove any files that it did not install
-
-* Thu Oct 30 2002 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-- Fixed typesetting error in man page smartd.8
-- Removed redundant variable (harmless) from smartd.c
-
-* Wed Oct 29 2002 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-- Added a new directive for the configuration file.  If the word
-  DEVICESCAN appears before any non-commented material in the
-  configuration file, then the confi file will be ignored and the
-  devices wil be scanned.
-- Note: it has now been confirmed that the code modifications between
-  5.0.23 and 5.0.24 have eliminated the GCC 3.2 problems.  Note that
-  there is a GCC bug howerver, see #848 at
-  http://gcc.gnu.org/cgi-bin/gnatsweb.pl?database=gcc&cmd=query
-- Added new Directive for Configuration file:
-  -C <N> This sets the time in between disk checks to be <N>
-  seconds apart.  Note that  although  you  can  give
-  this Directive multiple times on different lines of
-  the configuration file, only the final  value  that
-  is  given  has  an  effect,  and applies to all the
-  disks.  The default value of <N> is 1800  sec,  and
-  the minimum allowed value is ten seconds.
-- Problem wasn't the print format. F.L.W. Meunier <0@pervalidus.net>
-  sent me a gcc 3.2 build and I ran it under a debugger.  The
-  problem seems to be with passing the very large (2x512+4) byte
-  data structures as arguments.  I never liked this anyway; it was
-  inherited from smartsuite.  So I've changed all the heavyweight
-  functions (ATA ones, anyone) to just passing pointers, not hideous
-  kB size structures on the stack.  Hopefully this will now build OK
-  under gcc 3.2 with any sensible compilation options.
-- Because of reported problems with GCC 3.2 compile, I have gone
-  thorough the code and explicitly changed all print format
-  parameters to correspond EXACTLY to int unless they have to be
-  promoted to long longs.  To quote from the glibc bible: [From
-  GLIBC Manual: Since the prototype doesn't specify types for
-  optional arguments, in a call to a variadic function the default
-  argument promotions are performed on the optional argument
-  values. This means the objects of type char or short int (whether
-  signed or not) are promoted to either int or unsigned int, as
-  required.
-- smartd, smartctl now warn if they find an attribute whose ID
-  number does not match between Data and Threshold structures.
-- Fixed nasty bug which led to wrong number of arguments for a
-  varargs statement, with attendent stack corruption.  Sheesh!
-  Have added script to CVS attic to help find such nasties in the
-  future.
-
-* Tue Oct 29 2002 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-- Eliminated some global variables out of header files and other
-  minor cleanup of smartd.
-- Did some revision of the man page for smartd and made the usage
-  messages for Directives consistent.
-- smartd: prints warning message when it gets SIGHUP, saying that it is
-  NOT re-reading the config file.
-- smartctl: updated man page to say self-test commands -O,x,X,s,S,A
-  appear to be supported in the code.  [I can't test these,  can anyone
-  report?]
-- smartctl: smartctl would previously print the LBA of a self-test
-  if it completed, and the LBA was not 0 or 0xff...f However
-  according to the specs this is not correct.  According to the
-  specs, if the self-test completed without error then LBA is
-  undefined.  This version fixes that.  LBA value only printed if
-  self-test encountered an error.
-- smartd has changed significantly. This is the first CVS checkin of
-  code that extends the options available for smartd.  The following
-  options can be placed into the /etc/smartd.conf file, and control the
-  behavior of smartd.
-- Configuration file Directives (following device name):
-  -A     Device is an ATA device
-  -S     Device is a SCSI device
-  -c     Monitor SMART Health Status
-  -l     Monitor SMART Error Log for changes
-  -L     Monitor SMART Self-Test Log for new errors
-  -f     Monitor for failure of any 'Usage' Attributes
-  -p     Report changes in 'Prefailure' Attributes
-  -u     Report changes in 'Usage' Attributes
-  -t     Equivalent to -p and -u Directives
-  -a     Equivalent to -c -l -L -f -t Directives
-  -i ID  Ignore Attribute ID for -f Directive
-  -I ID  Ignore Attribute ID for -p, -u or -t Directive
-  #      Comment: text after a hash sign is ignored
-  \      Line continuation character
-- cleaned up functions used for printing CVS IDs.  Now use string
-  library, as it should be.
-- modified length of device name string in smartd internal structure
-  to accomodate max length device name strings
-- removed un-implemented (-e = Email notification) option from
-  command line arg list.  We'll put it back on when implemeneted.
-- smartd now logs serious (fatal) conditions in its operation at
-  loglevel LOG_CRIT rather than LOG_INFO before exiting with error.
-- smartd used to open a file descriptor for each SMART enabled
-- device, and then keep it open the entire time smartd was running.
-  This meant that some commands, like IOREADBLKPART did not work,
-  since the fd to the device was open.  smartd now opens the device
-  when it needs to read values, then closes it.  Also, if one time
-  around it can't open the device, it simply prints a warning
-  message but does not give up.  Have eliminated the .fd field from
-  data structures -- no longer gets used.
-- smartd now opens SCSI devices as well using O_RDONLY rather than
-  O_RDWR.  If someone can no longer monitor a SCSI device that used
-  to be readable, this may well be the reason why.
-- smartd never checked if the number of ata or scsi devices detected
-  was greater than the max number it could monitor.  Now it does.
-
-* Fri Oct 25 2002 Bruce Allen  <smartmontools-support@lists.sourceforge.net>
-- changes to the Makefile and spec file so that if there are ungzipped manual
-  pages in place these will be removed so that the new gzipped man pages are
-  visible.
-- smartd on startup now looks in the configuration file /etc/smartd.conf for
-  a list of devices which to include in its monitoring list.  See man page
-  (man smartd) for syntax. If not found, try all ata and ide devices.
-- smartd: close file descriptors of SCSI device if not SMART capable
-  Closes ALL file descriptors after forking to daemon.
-- added new temperature attribute (231, temperature)
-- smartd: now open ATA disks using O_RDONLY
-
-* Thu Oct 24 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-- smartd now prints the name of a failed or changed attribute into logfile,
-  not just ID number
-- Changed name of -p (print version) option to -V
-- Minor change in philosophy: if a SMART command fails or the device
-    appears incapable of a SMART command that the user has asked for,
-    complain by printing an error message, but go ahead and try
-    anyway.  Since unimplemented SMART commands should just return an
-    error but not cause disk problems, this should't cause any
-    difficulty.
-- Added two new flags: q and Q.  q is quiet mode - only print: For
-    the -l option, errors recorded in the SMART error log; For the -L
-    option, errors recorded in the device self-test log; For the -c
-    SMART "disk failing" status or device attributes (pre-failure or
-    usage) which failed either now or in the past; For the -v option
-    device attributes (pre-failure or usage) which failed either now
-    or in the past.  Q is Very Quiet mode: Print no ouput.  The only
-    way to learn about what was found is to use the exit status of
-    smartctl.
-- smartctl now returns sensible values (bitmask).  See smartctl.h
-    for the values, and the man page for documentation.
-- The SMART status check now uses the correct ATA call.  If failure
-    is detected we search through attributes to list the failed ones.
-    If the SMART status check shows GOOD, we then look to see if their
-    are any usage attributes or prefail attributes have failed at any
-    time.  If so we print them.
-- Modified function that prints vendor attributes to say if the
-    attribute has currently failed or has ever failed.
-- -p option now prints out license info and CVS strings for all
-    modules in the code, nicely formatted.
-- Previous versions of this code (and Smartsuite) only generate
-    SMART failure errors if the value of an attribute is below the
-    threshold and the prefailure bit is set.  However the ATA Spec
-    (ATA4 <=Rev 4) says that it is a SMART failure if the value of an
-    attribute is LESS THAN OR EQUAL to the threshold and the
-    prefailure bit is set.  This is now fixed in both smartctl and
-    smartd.  Note that this is a troubled subject -- the original
-    SFF 8035i specification defining SMART was inconsistent about
-    this.  One section says that Attribute==Threshold is pass,
-    and another section says it is fail.  However the ATA specs are
-    consistent and say Attribute==Threshold is a fail.
-- smartd did not print the correct value of any failing SMART attribute.  It
-    printed the index in the attribute table, not the attribute
-    ID. This is fixed.
-- when starting self-tests in captive mode ioctl returns EIO because
-    the drive has been busied out.  Detect this and don't return an eror
-    in this case.  Check this this is correct (or how to fix it?)
- - fixed possible error in how to determine ATA standard support
-    for devices with no ATA minor revision number.
-- device opened only in read-only not read-write mode.  Don't need R/W 
-    access to get smart data. Check this with Andre.
-- smartctl now handles all possible choices of "multiple options"
-    gracefully.  It goes through the following phases of operation,
-    in order: INFORMATION, ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
-    Documentation has bee updated to explain the different phases of
-    operation.  Control flow through ataPrintMain()
-    simplified.
-- If reading device identity information fails, try seeing if the info
-    can be accessed using a "DEVICE PACKET" command.  This way we can
-    at least get device info.
-- Modified Makefile to automatically tag CVS archive on issuance of
-    a release
-- Modified drive detection so minor device ID code showing ATA-3 rev
-    0 (no SMART) is known to not be SMART capable.
-- Now verify the checksum of the device ID data structure, and of the
-    attributes threshold structure.  Before neither of these
-    structures had their checksums verified.
-- New behavior vis-a-vis checksums.  If they are wrong, we log
-    warning messages to stdout, stderr, and syslog, but carry on
-    anyway.  All functions now call a checksumwarning routine if the
-    checksum doesn't vanish as it should.
-- Changed Read Hard Disk Identity function to get fresh info from
-    the disk on each call rather than to use the values that were read
-    upon boot-up into the BIOS.  This is the biggest change in this
-    release.  The ioctl(device, HDIO_GET_IDENTITY, buf ) call should
-    be avoided in such code.  Note that if people get garbled strings
-    for the model, serial no and firmware versions of their drives,
-    then blame goes here (the BIOS does the byte swapping for you,
-    apparently!)
-- Function ataSmartSupport now looks at correct bits in drive
-    identity structure to verify first that these bits are valid,
-    before using them.
-- Function ataIsSmartEnabled() written which uses the Drive ID state
-    information to tell if SMART is enabled or not.  We'll carry this
-    along for the moment without using it.
-- Function ataDoesSmartWork() guaranteed to work if the device
-    supports SMART.
-- Replace some numbers by #define MACROS
-- Wrote Function TestTime to return test time associated with each
-    different type of test.
-- Thinking of the future, have added a new function called
-    ataSmartStatus2().  Eventually when I understand how to use the
-    TASKFILE API and am sure that this works correctly, it will
-    replace ataSmartStatus().  This queries the drive directly to
-    see if the SMART status is OK, rather than comparing thresholds to
-    attribute values ourselves. But I need to get some drives that fail
-    their SMART status to check it.
-
-* Thu Oct 17 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
--   Removed extraneous space before some error message printing.
--   Fixed some character buffers that were too short for contents.
-    Only used for unrecognized drives, so probably damage was minimal.
-
-* Wed Oct 16 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
--   Initial release.  Code is derived from smartsuite, and is
-    intended to be compatible with the ATA/ATAPI-5 specifications.
--   For IBM disks whose raw temp data includes three temps. print all
-    three
--   print timestamps for error log to msec precision
--   added -m option for Hitachi disks that store power on life in
-    minutes
--   added -L option for printing self-test error logs
--   in -l option, now print power on lifetime, so that one can see
-    when the error took place
--   updated SMART structure definitions to ATA-5 spec
--   added -p option
--   added -f and -F options to enable/disable autosave threshold
-    parameters
-
diff --git a/sm5/tweio.h b/sm5/tweio.h
deleted file mode 100644
index 430157fba707664d82619415ee462107e6e77799..0000000000000000000000000000000000000000
--- a/sm5/tweio.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2003 Paul Saab
- * Copyright (c) 2003 Vinod Kashyap
- * Copyright (c) 2000 BSDi
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	$FreeBSD: src/sys/dev/twe/tweio.h,v 1.3 2003/12/02 07:57:20 ps Exp $
- */
-
-
-/*
- * User-space command
- *
- * Note that the command's scatter/gather list will be computed by the
- * driver, and cannot be filled in by the consumer.
- */
-struct twe_usercommand {
-    TWE_Command	tu_command;	/* command ready for the controller */
-    void	*tu_data;	/* pointer to data in userspace */
-    size_t	tu_size;	/* userspace data length */
-};
-
-#define TWEIO_COMMAND		_IOWR('T', 100, struct twe_usercommand)
-
-/*
- * Command queue statistics
- */
-#define TWEQ_FREE	0
-#define TWEQ_BIO	1
-#define TWEQ_READY	2
-#define TWEQ_BUSY	3
-#define TWEQ_COMPLETE	4
-#define TWEQ_COUNT	5	/* total number of queues */
-
-struct twe_qstat {
-    u_int32_t	q_length;
-    u_int32_t	q_max;
-    u_int32_t	q_min;
-};
-
-/*
- * Statistics request
- */
-union twe_statrequest {
-    u_int32_t		ts_item;
-    struct twe_qstat	ts_qstat;
-};
-
-#define TWEIO_STATS		_IOWR('T', 101, union twe_statrequest)
-
-/*
- * AEN listen
- */
-#define TWEIO_AEN_POLL		_IOR('T', 102, u_int16_t)
-#define TWEIO_AEN_WAIT		_IOR('T', 103, u_int16_t)
-
-/*
- * Controller parameter access
- */
-struct twe_paramcommand {
-    u_int16_t	tp_table_id;
-    u_int8_t	tp_param_id;
-    void	*tp_data;
-    u_int8_t	tp_size;
-};
-
-#define TWEIO_SET_PARAM		_IOW ('T', 104, struct twe_paramcommand)
-#define TWEIO_GET_PARAM		_IOW ('T', 105, struct twe_paramcommand)
-
-/*
- * Request a controller soft-reset
- */
-#define TWEIO_RESET		_IO  ('T', 106)
-
-/*
- * Request a drive addition or deletion
- */
-struct twe_drivecommand {
-    int		td_unit;
-};
-
-#define TWEIO_ADD_UNIT		_IOW ('U', 107, int)
-#define TWEIO_DEL_UNIT		_IOW ('U', 108, int)
diff --git a/sm5/twereg.h b/sm5/twereg.h
deleted file mode 100644
index 2eea8f542c401d6444332b0c766ac17a4905b32b..0000000000000000000000000000000000000000
--- a/sm5/twereg.h
+++ /dev/null
@@ -1,495 +0,0 @@
-/*-
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2003 Paul Saab
- * Copyright (c) 2003 Vinod Kashyap
- * Copyright (c) 2000 BSDi
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      $FreeBSD: src/sys/dev/twe/twereg.h,v 1.10 2003/12/02 07:57:20 ps Exp $
- */
-
-/* 
- * Register names, bit definitions, structure names and members are
- * identical with those in the Linux driver where possible and sane 
- * for simplicity's sake.  (The TW_ prefix has become TWE_)
- * Some defines that are clearly irrelevant to FreeBSD have been
- * removed.
- */
-
-/* control register bit definitions */
-#define TWE_CONTROL_CLEAR_HOST_INTERRUPT	0x00080000
-#define TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT	0x00040000
-#define TWE_CONTROL_MASK_COMMAND_INTERRUPT	0x00020000
-#define TWE_CONTROL_MASK_RESPONSE_INTERRUPT	0x00010000
-#define TWE_CONTROL_UNMASK_COMMAND_INTERRUPT	0x00008000
-#define TWE_CONTROL_UNMASK_RESPONSE_INTERRUPT	0x00004000
-#define TWE_CONTROL_CLEAR_ERROR_STATUS		0x00000200
-#define TWE_CONTROL_ISSUE_SOFT_RESET		0x00000100
-#define TWE_CONTROL_ENABLE_INTERRUPTS		0x00000080
-#define TWE_CONTROL_DISABLE_INTERRUPTS		0x00000040
-#define TWE_CONTROL_ISSUE_HOST_INTERRUPT	0x00000020
-#define TWE_CONTROL_CLEAR_PARITY_ERROR		0x00800000
-#define TWE_CONTROL_CLEAR_PCI_ABORT		0x00100000
-
-#define TWE_SOFT_RESET(sc)	TWE_CONTROL(sc, TWE_CONTROL_ISSUE_SOFT_RESET |		\
-					   TWE_CONTROL_CLEAR_HOST_INTERRUPT |		\
-					   TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT |	\
-					   TWE_CONTROL_MASK_COMMAND_INTERRUPT |		\
-					   TWE_CONTROL_MASK_RESPONSE_INTERRUPT |	\
-					   TWE_CONTROL_CLEAR_ERROR_STATUS |		\
-					   TWE_CONTROL_DISABLE_INTERRUPTS)
-
-/* status register bit definitions */
-#define TWE_STATUS_MAJOR_VERSION_MASK		0xF0000000
-#define TWE_STATUS_MINOR_VERSION_MASK		0x0F000000
-#define TWE_STATUS_PCI_PARITY_ERROR		0x00800000
-#define TWE_STATUS_QUEUE_ERROR			0x00400000
-#define TWE_STATUS_MICROCONTROLLER_ERROR	0x00200000
-#define TWE_STATUS_PCI_ABORT			0x00100000
-#define TWE_STATUS_HOST_INTERRUPT		0x00080000
-#define TWE_STATUS_ATTENTION_INTERRUPT		0x00040000
-#define TWE_STATUS_COMMAND_INTERRUPT		0x00020000
-#define TWE_STATUS_RESPONSE_INTERRUPT		0x00010000
-#define TWE_STATUS_COMMAND_QUEUE_FULL		0x00008000
-#define TWE_STATUS_RESPONSE_QUEUE_EMPTY		0x00004000
-#define TWE_STATUS_MICROCONTROLLER_READY	0x00002000
-#define TWE_STATUS_COMMAND_QUEUE_EMPTY		0x00001000
-#define TWE_STATUS_ALL_INTERRUPTS		0x000F0000
-#define TWE_STATUS_CLEARABLE_BITS		0x00D00000
-#define TWE_STATUS_EXPECTED_BITS		0x00002000
-#define TWE_STATUS_UNEXPECTED_BITS		0x00F80000
-
-/* XXX this is a little harsh, but necessary to chase down firmware problems */
-#define TWE_STATUS_PANIC_BITS			(TWE_STATUS_MICROCONTROLLER_ERROR)
-
-/* for use with the %b printf format */
-#define TWE_STATUS_BITS_DESCRIPTION \
-	"\20\15CQEMPTY\16UCREADY\17RQEMPTY\20CQFULL\21RINTR\22CINTR\23AINTR\24HINTR\25PCIABRT\26MCERR\27QERR\30PCIPERR\n"
-
-/* detect inconsistencies in the status register */
-#define TWE_STATUS_ERRORS(x)				\
-	(((x & TWE_STATUS_PCI_ABORT) 		||	\
-	  (x & TWE_STATUS_PCI_PARITY_ERROR) 	||	\
-	  (x & TWE_STATUS_QUEUE_ERROR)		||	\
-	  (x & TWE_STATUS_MICROCONTROLLER_ERROR)) &&	\
-	 (x & TWE_STATUS_MICROCONTROLLER_READY))
-
-/* Response queue bit definitions */
-#define TWE_RESPONSE_ID_MASK		0x00000FF0
-
-/* PCI related defines */
-#define TWE_IO_CONFIG_REG		0x10
-#define TWE_DEVICE_NAME			"3ware 7000 series Storage Controller"
-#define TWE_VENDOR_ID			0x13C1
-#define TWE_DEVICE_ID			0x1000
-#define TWE_DEVICE_ID_ASIC		0x1001
-#define TWE_PCI_CLEAR_PARITY_ERROR	0xc100
-#define TWE_PCI_CLEAR_PCI_ABORT		0x2000
-
-/* command packet opcodes */
-#define TWE_OP_NOP			0x00
-#define TWE_OP_INIT_CONNECTION		0x01
-#define TWE_OP_READ			0x02
-#define TWE_OP_WRITE			0x03
-#define TWE_OP_READVERIFY		0x04
-#define TWE_OP_VERIFY			0x05
-#define TWE_OP_ZEROUNIT			0x08
-#define TWE_OP_REPLACEUNIT		0x09
-#define TWE_OP_HOTSWAP			0x0a
-#define TWE_OP_SETATAFEATURE		0x0c
-#define TWE_OP_FLUSH			0x0e
-#define TWE_OP_ABORT			0x0f
-#define TWE_OP_CHECKSTATUS		0x10
-#define TWE_OP_ATA_PASSTHROUGH		0x11
-#define TWE_OP_GET_PARAM		0x12
-#define TWE_OP_SET_PARAM		0x13
-#define TWE_OP_CREATEUNIT		0x14
-#define TWE_OP_DELETEUNIT		0x15
-#define TWE_OP_REBUILDUNIT		0x17
-#define TWE_OP_SECTOR_INFO		0x1a
-#define TWE_OP_AEN_LISTEN		0x1c
-#define TWE_OP_CMD_PACKET		0x1d
-#define TWE_OP_CMD_WITH_DATA		0x1f
-
-/* command status values */
-#define TWE_STATUS_RESET		0xff	/* controller requests reset */
-#define TWE_STATUS_FATAL		0xc0	/* fatal errors not requiring reset */
-#define TWE_STATUS_WARNING		0x80	/* warnings */
-#define TWE_STAUS_INFO			0x40	/* informative status */
-
-/* misc defines */
-#define TWE_ALIGNMENT			0x200
-#define TWE_MAX_UNITS			16
-#define TWE_COMMAND_ALIGNMENT_MASK	0x1ff
-#define TWE_INIT_MESSAGE_CREDITS	0xff	/* older firmware has issues with 256 commands */
-#define TWE_SHUTDOWN_MESSAGE_CREDITS	0x001
-#define TWE_INIT_COMMAND_PACKET_SIZE	0x3
-#define TWE_MAX_SGL_LENGTH		62
-#define TWE_MAX_ATA_SGL_LENGTH		60
-#define TWE_MAX_PASSTHROUGH		4096
-#define TWE_Q_LENGTH			TWE_INIT_MESSAGE_CREDITS
-#define TWE_Q_START			0
-#define TWE_MAX_RESET_TRIES		3
-#define TWE_BLOCK_SIZE			0x200	/* 512-byte blocks */
-#define TWE_SECTOR_SIZE			0x200	/* generic I/O bufffer */
-#define TWE_IOCTL			0x80
-#define TWE_MAX_AEN_TRIES		100
-#define TWE_UNIT_ONLINE			1
-
-/* scatter/gather list entry */
-typedef struct
-{
-    u_int32_t	address;
-    u_int32_t	length;
-} __packed TWE_SG_Entry;
-
-typedef struct {
-    u_int8_t	opcode:5;		/* TWE_OP_INITCONNECTION */
-    u_int8_t	res1:3;		
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	res2:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int16_t	message_credits;
-    u_int32_t	response_queue_pointer;
-} __packed TWE_Command_INITCONNECTION;
-
-typedef struct
-{
-    u_int8_t	opcode:5;		/* TWE_OP_READ/TWE_OP_WRITE */
-    u_int8_t	res1:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int16_t	block_count;
-    u_int32_t	lba;
-    TWE_SG_Entry sgl[TWE_MAX_SGL_LENGTH];
-} __packed TWE_Command_IO;
-
-typedef struct
-{
-    u_int8_t	opcode:5;		/* TWE_OP_HOTSWAP */
-    u_int8_t	res1:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int8_t	action;
-#define TWE_OP_HOTSWAP_REMOVE		0x00	/* remove assumed-degraded unit */
-#define TWE_OP_HOTSWAP_ADD_CBOD		0x01	/* add CBOD to empty port */
-#define TWE_OP_HOTSWAP_ADD_SPARE	0x02	/* add spare to empty port */
-    u_int8_t	aport;
-} __packed TWE_Command_HOTSWAP;
-
-typedef struct
-{
-    u_int8_t	opcode:5;		/* TWE_OP_SETATAFEATURE */
-    u_int8_t	res1:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int8_t	feature;
-#define TWE_OP_SETATAFEATURE_WCE	0x02
-#define TWE_OP_SETATAFEATURE_DIS_WCE	0x82
-    u_int8_t	feature_mode;
-    u_int16_t	all_units;
-    u_int16_t	persistence;
-} __packed TWE_Command_SETATAFEATURE;
-
-typedef struct
-{
-    u_int8_t	opcode:5;		/* TWE_OP_CHECKSTATUS */
-    u_int8_t	res1:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	res2:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int16_t	target_status;		/* set low byte to target request's ID */
-} __packed TWE_Command_CHECKSTATUS;
-
-typedef struct
-{
-    u_int8_t	opcode:5;		/* TWE_OP_GETPARAM, TWE_OP_SETPARAM */
-    u_int8_t	res1:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int16_t	param_count;
-    TWE_SG_Entry sgl[TWE_MAX_SGL_LENGTH];
-} __packed TWE_Command_PARAM;
-
-typedef struct
-{
-    u_int8_t	opcode:5;		/* TWE_OP_REBUILDUNIT */
-    u_int8_t	res1:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	src_unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int8_t	action:7;
-#define TWE_OP_REBUILDUNIT_NOP		0
-#define TWE_OP_REBUILDUNIT_STOP		2	/* stop all rebuilds */
-#define TWE_OP_REBUILDUNIT_START	4	/* start rebuild with lowest unit */
-#define TWE_OP_REBUILDUNIT_STARTUNIT	5	/* rebuild src_unit (not supported) */
-    u_int8_t	cs:1;				/* request state change on src_unit */
-    u_int8_t	logical_subunit;		/* for RAID10 rebuild of logical subunit */
-} __packed TWE_Command_REBUILDUNIT;
-
-typedef struct
-{
-    u_int8_t	opcode:5;
-    u_int8_t	sgl_offset:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-    u_int16_t	param;
-    u_int16_t	features;
-    u_int16_t	sector_count;
-    u_int16_t	sector_num;
-    u_int16_t	cylinder_lo;
-    u_int16_t	cylinder_hi;
-    u_int8_t	drive_head;
-    u_int8_t	command;
-    TWE_SG_Entry sgl[TWE_MAX_ATA_SGL_LENGTH];
-} __packed TWE_Command_ATA;
-
-typedef struct
-{
-    u_int8_t	opcode:5;
-    u_int8_t	sgl_offset:3;
-    u_int8_t	size;
-    u_int8_t	request_id;
-    u_int8_t	unit:4;
-    u_int8_t	host_id:4;
-    u_int8_t	status;
-    u_int8_t	flags;
-#define TWE_FLAGS_SUCCESS	0x00
-#define TWE_FLAGS_INFORMATIONAL	0x01
-#define TWE_FLAGS_WARNING	0x02
-#define TWE_FLAGS_FATAL		0x03
-#define TWE_FLAGS_PERCENTAGE	(1<<8)	/* bits 0-6 indicate completion percentage */
-    u_int16_t	count;			/* block count, parameter count, message credits */
-} __packed TWE_Command_Generic;
-
-/* command packet - must be TWE_ALIGNMENT aligned */
-typedef union
-{
-    TWE_Command_INITCONNECTION	initconnection;
-    TWE_Command_IO		io;
-    TWE_Command_PARAM		param;
-    TWE_Command_CHECKSTATUS	checkstatus;
-    TWE_Command_REBUILDUNIT	rebuildunit;
-    TWE_Command_SETATAFEATURE	setatafeature;
-    TWE_Command_ATA		ata;
-    TWE_Command_Generic		generic;
-    u_int8_t			pad[512];
-} TWE_Command;
-
-/* response queue entry */
-typedef union
-{
-    struct 
-    {
-	u_int32_t	undefined_1:4;
-	u_int32_t	response_id:8;
-	u_int32_t	undefined_2:20;
-    } u;
-    u_int32_t	value;
-} TWE_Response_Queue;
-
-/*
- * From 3ware's documentation:
- *   All parameters maintained by the controller are grouped into related tables.
- *   Tables are are accessed indirectly via get and set parameter commands.
- *   To access a specific parameter in a table, the table ID and parameter index
- *   are used to uniquely identify a parameter.  Table 0xffff is the directory
- *   table and provides a list of the table IDs and sizes of all other tables.
- *   Index zero in each table specifies the entire table, and index one specifies
- *   the size of the table.  An entire table can be read or set by using index zero.
- */
-
-#define TWE_PARAM_PARAM_ALL	0
-#define TWE_PARAM_PARAM_SIZE	1
-
-#define TWE_PARAM_DIRECTORY	0xffff			/* size is 4 * number of tables */
-#define TWE_PARAM_DIRECTORY_TABLES		2	/* 16 bits * number of tables */
-#define TWE_PARAM_DIRECTORY_SIZES		3	/* 16 bits * number of tables */
-
-#define TWE_PARAM_DRIVESUMMARY	0x0002
-#define TWE_PARAM_DRIVESUMMARY_Num		2	/* number of physical drives [2] */
-#define TWE_PARAM_DRIVESUMMARY_Status		3	/* array giving drive status per aport */
-#define TWE_PARAM_DRIVESTATUS_Missing	0x00
-#define TWE_PARAM_DRIVESTATUS_NotSupp	0xfe
-#define TWE_PARAM_DRIVESTATUS_Present	0xff
-
-#define TWE_PARAM_UNITSUMMARY	0x0003
-#define TWE_PARAM_UNITSUMMARY_Num		2	/* number of logical units [2] */
-#define TWE_PARAM_UNITSUMMARY_Status		3	/* array giving unit status [16] */
-#define TWE_PARAM_UNITSTATUS_Online		(1<<0)
-#define TWE_PARAM_UNITSTATUS_Complete		(1<<1)
-#define TWE_PARAM_UNITSTATUS_MASK		0xfc
-#define TWE_PARAM_UNITSTATUS_Normal		0xfc
-#define TWE_PARAM_UNITSTATUS_Initialising	0xf4	/* cannot be incomplete */
-#define TWE_PARAM_UNITSTATUS_Degraded		0xec
-#define TWE_PARAM_UNITSTATUS_Rebuilding		0xdc	/* cannot be incomplete */
-#define TWE_PARAM_UNITSTATUS_Verifying		0xcc	/* cannot be incomplete */
-#define TWE_PARAM_UNITSTATUS_Corrupt		0xbc	/* cannot be complete */
-#define TWE_PARAM_UNITSTATUS_Missing		0x00	/* cannot be complete or online */
-
-#define TWE_PARAM_DRIVEINFO	0x0200			/* add drive number 0x00-0x0f XXX docco confused 0x0100 vs 0x0200 */
-#define TWE_PARAM_DRIVEINFO_Size		2	/* size in blocks [4] */
-#define TWE_PARAM_DRIVEINFO_Model		3	/* drive model string [40] */
-#define TWE_PARAM_DRIVEINFO_Serial		4	/* drive serial number [20] */
-#define TWE_PARAM_DRIVEINFO_PhysCylNum		5	/* physical geometry [2] */
-#define TWE_PARAM_DRIVEINFO_PhysHeadNum		6	/* [2] */
-#define TWE_PARAM_DRIVEINFO_PhysSectorNym	7	/* [2] */
-#define TWE_PARAM_DRIVEINFO_LogCylNum		8	/* logical geometry [2] */
-#define TWE_PARAM_DRIVEINFO_LogHeadNum		9	/* [2] */
-#define TWE_PARAM_DRIVEINFO_LogSectorNum	10	/* [2] */
-#define TWE_PARAM_DRIVEINFO_UnitNum		11	/* unit number this drive is associated with or 0xff [1] */
-#define TWE_PARAM_DRIVEINFO_DriveFlags		12	/* N/A [1] */
-
-#define TWE_PARAM_APORTTIMEOUT	0x02c0			/* add (aport_number * 3) to parameter index */
-#define TWE_PARAM_APORTTIMEOUT_READ		2	/* read timeouts last 24hrs [2] */
-#define TWE_PARAM_APORTTIMEOUT_WRITE		3	/* write timeouts last 24hrs [2] */
-#define TWE_PARAM_APORTTIMEOUT_DEGRADE		4	/* degrade threshold [2] */
-
-#define TWE_PARAM_UNITINFO	0x0300			/* add unit number 0x00-0x0f */
-#define TWE_PARAM_UNITINFO_Number		2	/* unit number [1] */
-#define TWE_PARAM_UNITINFO_Status		3	/* unit status [1] */
-#define TWE_PARAM_UNITINFO_Capacity		4	/* unit capacity in blocks [4] */
-#define TWE_PARAM_UNITINFO_DescriptorSize	5	/* unit descriptor size + 3 bytes [2] */
-#define TWE_PARAM_UNITINFO_Descriptor		6	/* unit descriptor, TWE_UnitDescriptor or TWE_Array_Descriptor */
-#define TWE_PARAM_UNITINFO_Flags		7	/* unit flags [1] */
-#define TWE_PARAM_UNITFLAGS_WCE			(1<<0)
-
-#define TWE_PARAM_AEN		0x0401
-#define TWE_PARAM_AEN_UnitCode			2	/* (unit number << 8) | AEN code [2] */
-#define TWE_AEN_QUEUE_EMPTY		0x00
-#define TWE_AEN_SOFT_RESET		0x01
-#define TWE_AEN_DEGRADED_MIRROR		0x02	/* reports unit */
-#define TWE_AEN_CONTROLLER_ERROR	0x03
-#define TWE_AEN_REBUILD_FAIL		0x04	/* reports unit */
-#define TWE_AEN_REBUILD_DONE		0x05	/* reports unit */
-#define TWE_AEN_INCOMP_UNIT		0x06	/* reports unit */
-#define TWE_AEN_INIT_DONE		0x07	/* reports unit */
-#define TWE_AEN_UNCLEAN_SHUTDOWN	0x08	/* reports unit */
-#define TWE_AEN_APORT_TIMEOUT		0x09	/* reports unit, rate limited to 1 per 2^16 errors */
-#define TWE_AEN_DRIVE_ERROR		0x0a	/* reports unit */
-#define TWE_AEN_REBUILD_STARTED		0x0b	/* reports unit */
-#define TWE_AEN_QUEUE_FULL		0xff
-#define TWE_AEN_TABLE_UNDEFINED		0x15
-#define TWE_AEN_CODE(x)			((x) & 0xff)
-#define TWE_AEN_UNIT(x)			((x) >> 8)
-
-#define TWE_PARAM_VERSION	0x0402
-#define TWE_PARAM_VERSION_Mon			2	/* monitor version [16] */
-#define TWE_PARAM_VERSION_FW			3	/* firmware version [16] */
-#define TWE_PARAM_VERSION_BIOS			4	/* BIOSs version [16] */
-#define TWE_PARAM_VERSION_PCB			5	/* PCB version [8] */
-#define TWE_PARAM_VERSION_ATA			6	/* A-chip version [8] */
-#define TWE_PARAM_VERSION_PCI			7	/* P-chip version [8] */
-#define TWE_PARAM_VERSION_CtrlModel		8	/* N/A */
-#define TWE_PARAM_VERSION_CtrlSerial		9	/* N/A */
-#define TWE_PARAM_VERSION_SBufSize		10	/* N/A */
-#define TWE_PARAM_VERSION_CompCode		11	/* compatibility code [4] */
-
-#define TWE_PARAM_CONTROLLER	0x0403
-#define TWE_PARAM_CONTROLLER_DCBSectors		2	/* # sectors reserved for DCB per drive [2] */
-#define TWE_PARAM_CONTROLLER_PortCount		3	/* number of drive ports [1] */
-
-#define TWE_PARAM_FEATURES	0x404
-#define TWE_PARAM_FEATURES_DriverShutdown	2	/* set to 1 if driver supports shutdown notification [1] */
-
-typedef struct
-{
-    u_int8_t		num_subunits;	/* must be zero */
-    u_int8_t		configuration;
-#define TWE_UD_CONFIG_CBOD	0x0c	/* JBOD with DCB, used for mirrors */
-#define TWE_UD_CONFIG_SPARE	0x0d	/* same as CBOD, but firmware will use as spare */
-#define TWE_UD_CONFIG_SUBUNIT	0x0e	/* drive is a subunit in an array */
-#define TWE_UD_CONFIG_JBOD	0x0f	/* plain drive */
-    u_int8_t		phys_drv_num;	/* may be 0xff if port can't be determined at runtime */
-    u_int8_t		log_drv_num;	/* must be zero for configuration == 0x0f */
-    u_int32_t		start_lba;
-    u_int32_t		block_count;	/* actual drive size if configuration == 0x0f, otherwise less DCB size */
-} __packed TWE_Unit_Descriptor;
-
-typedef struct
-{
-    u_int8_t		flag;			/* must be 0xff */
-    u_int8_t		res1;
-    u_int8_t		mirunit_status[4];	/* bitmap of functional subunits in each mirror */
-    u_int8_t		res2[6];
-} __packed TWE_Mirror_Descriptor;
-
-typedef struct
-{
-    u_int8_t		num_subunits;	/* number of subunits, or number of mirror units in RAID10 */
-    u_int8_t		configuration;
-#define TWE_UD_CONFIG_RAID0	0x00
-#define TWE_UD_CONFIG_RAID1	0x01
-#define TWE_UD_CONFIG_TwinStor	0x02
-#define TWE_UD_CONFIG_RAID5	0x05
-#define TWE_UD_CONFIG_RAID10	0x06
-    u_int8_t		stripe_size;
-#define TWE_UD_STRIPE_4k	0x03
-#define TWE_UD_STRIPE_8k	0x04
-#define TWE_UD_STRIPE_16k	0x05
-#define TWE_UD_STRIPE_32k	0x06
-#define TWE_UD_STRIPE_64k	0x07
-    u_int8_t		log_drv_status;	/* bitmap of functional subunits, or mirror units in RAID10 */
-    u_int32_t		start_lba;
-    u_int32_t		block_count;	/* actual drive size if configuration == 0x0f, otherwise less DCB size */
-    TWE_Unit_Descriptor	subunit[0];	/* subunit descriptors, in RAID10 mode is [mirunit][subunit] */
-} __packed TWE_Array_Descriptor;
-
-typedef struct
-{
-    u_int16_t	table_id;
-    u_int8_t	parameter_id;
-    u_int8_t	parameter_size_bytes;
-    u_int8_t	data[0];
-} __packed TWE_Param;
-
diff --git a/sm5/utility.c b/sm5/utility.c
deleted file mode 100644
index f1e54ee89ce5e0fd83344f45ad9726d8b28aef74..0000000000000000000000000000000000000000
--- a/sm5/utility.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * utility.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-// THIS FILE IS INTENDED FOR UTILITY ROUTINES THAT ARE APPLICABLE TO
-// BOTH SCSI AND ATA DEVICES, AND THAT MAY BE USED IN SMARTD,
-// SMARTCTL, OR BOTH.
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-
-#include "config.h"
-#include "int64.h"
-#include "utility.h"
-
-// Any local header files should be represented by a CVSIDX just below.
-const char* utility_c_cvsid="$Id: utility.c,v 1.53 2004/07/29 21:00:36 chrfranke Exp $"
-CONFIG_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
-
-const char * packet_types[] = {
-        "Direct-access (disk)",
-        "Sequential-access (tape)",
-        "Printer",
-        "Processor",
-        "Write-once (optical disk)",
-        "CD/DVD",
-        "Scanner",
-        "Optical memory (optical disk)",
-        "Medium changer",
-        "Communications",
-        "Graphic arts pre-press (10)",
-        "Graphic arts pre-press (11)",
-        "Array controller",
-        "Enclosure services",
-        "Reduced block command (simplified disk)",
-        "Optical card reader/writer"
-};
-
-// Whenever exit() status is EXIT_BADCODE, please print this message
-const char *reportbug="Please report this bug to the Smartmontools developers at " PACKAGE_BUGREPORT ".\n";
-
-
-// hang on to exit code, so we can make use of more generic 'atexit()'
-// functionality and still check our exit code
-int exitstatus = 0;
-
-// command-line argument: are we running in debug mode?.
-unsigned char debugmode = 0;
-
-
-// Solaris only: Get site-default timezone. This is called from
-// UpdateTimezone() when TZ environment variable is unset at startup.
-#if defined (__SVR4) && defined (__sun)
-static const char *TIMEZONE_FILE = "/etc/TIMEZONE";
-
-static char *ReadSiteDefaultTimezone(){
-  FILE *fp;
-  char buf[512], *tz;
-  int n;
-
-  tz = NULL;
-  fp = fopen(TIMEZONE_FILE, "r");
-  if(fp == NULL) return NULL;
-  while(fgets(buf, sizeof(buf), fp)) {
-    if (strncmp(buf, "TZ=", 3))    // searches last "TZ=" line
-      continue;
-    n = strlen(buf) - 1;
-    if (buf[n] == '\n') buf[n] = 0;
-    if (tz) free(tz);
-    tz = strdup(buf);
-  }
-  fclose(fp);
-  return tz;
-}
-#endif
-
-// Make sure that this executable is aware if the user has changed the
-// time-zone since the last time we polled devices. The cannonical
-// example is a user who starts smartd on a laptop, then flies across
-// time-zones with a laptop, and then changes the timezone, WITHOUT
-// restarting smartd. This is a work-around for a bug in
-// GLIBC. Yuk. See bug number 48184 at http://bugs.debian.org and
-// thanks to Ian Redfern for posting a workaround.
-
-// Please refer to the smartd manual page, in the section labeled LOG
-// TIMESTAMP TIMEZONE.
-void FixGlibcTimeZoneBug(){
-#if __GLIBC__  
-  if (!getenv("TZ")) {
-    putenv("TZ=GMT");
-    tzset();
-    putenv("TZ");
-    tzset();
-  }
-#elif _WIN32
-  if (!getenv("TZ")) {
-    putenv("TZ=GMT");
-    tzset();
-    putenv("TZ=");  // empty value removes TZ, putenv("TZ") does nothing
-    tzset();
-  }
-#elif defined (__SVR4) && defined (__sun)
-  // In Solaris, putenv("TZ=") sets null string and invalid timezone.
-  // putenv("TZ") does nothing.  With invalid TZ, tzset() do as if
-  // TZ=GMT.  With TZ unset, /etc/TIMEZONE will be read only _once_ at
-  // first tzset() call.  Conclusion: Unlike glibc, dynamic
-  // configuration of timezone can be done only by changing actual
-  // value of TZ environment value.
-  enum tzstate { NOT_CALLED_YET, USER_TIMEZONE, TRACK_TIMEZONE };
-  static enum tzstate state = NOT_CALLED_YET;
-
-  static struct stat prev_stat;
-  static char *prev_tz;
-  struct stat curr_stat;
-  char *curr_tz;
-
-  if(state == NOT_CALLED_YET) {
-    if(getenv("TZ")) {
-      state = USER_TIMEZONE; // use supplied timezone
-    } else {
-      state = TRACK_TIMEZONE;
-      if(stat(TIMEZONE_FILE, &prev_stat)) {
-	state = USER_TIMEZONE;	// no TZ, no timezone file; use GMT forever
-      } else {
-	prev_tz = ReadSiteDefaultTimezone(); // track timezone file change
-	if(prev_tz) putenv(prev_tz);
-      }
-    }
-    tzset();
-  } else if(state == TRACK_TIMEZONE) {
-    if(stat(TIMEZONE_FILE, &curr_stat) == 0
-       && (curr_stat.st_ctime != prev_stat.st_ctime
-	    || curr_stat.st_mtime != prev_stat.st_mtime)) {
-      // timezone file changed
-      curr_tz = ReadSiteDefaultTimezone();
-      if(curr_tz) {
-	putenv(curr_tz);
-	if(prev_tz) free(prev_tz);
-	prev_tz = curr_tz; prev_stat = curr_stat; 
-      }
-    }
-    tzset();
-  }
-#endif
-  // OTHER OS/LIBRARY FIXES SHOULD GO HERE, IF DESIRED.  PLEASE TRY TO
-  // KEEP THEM INDEPENDENT.
-  return;
-}
-
-// This value follows the peripheral device type value as defined in
-// SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in
-// the ATA standard for packet devices to define the device type.
-const char *packetdevicetype(int type){
-  if (type<0x10)
-    return packet_types[type];
-  
-  if (type<0x20)
-    return "Reserved";
-  
-  return "Unknown";
-}
-
-
-// Returns 1 if machine is big endian, else zero.  This is a run-time
-// rather than a compile-time function.  We could do it at
-// compile-time but in principle there are architectures that can run
-// with either byte-ordering.
-int isbigendian(){
-  short i=0x0100;
-  char *tmp=(char *)&i;
-  return *tmp;
-}
-
-// Utility function prints date and time and timezone into a character
-// buffer of length>=64.  All the fuss is needed to get the right
-// timezone info (sigh).
-void dateandtimezoneepoch(char *buffer, time_t tval){
-  struct tm *tmval;
-  char *timezonename;
-  char datebuffer[DATEANDEPOCHLEN];
-  int lenm1;
-
-  FixGlibcTimeZoneBug();
-  
-  // Get the time structure.  We need this to determine if we are in
-  // daylight savings time or not.
-  tmval=localtime(&tval);
-  
-  // Convert to an ASCII string, put in datebuffer
-  // same as: asctime_r(tmval, datebuffer);
-  strncpy(datebuffer, asctime(tmval), DATEANDEPOCHLEN);
-  datebuffer[DATEANDEPOCHLEN-1]='\0';
-  
-  // Remove newline
-  lenm1=strlen(datebuffer)-1;
-  datebuffer[lenm1>=0?lenm1:0]='\0';
-  
-  // correct timezone name
-  if (tmval->tm_isdst==0)
-    // standard time zone
-    timezonename=tzname[0];
-  else if (tmval->tm_isdst>0)
-    // daylight savings in effect
-    timezonename=tzname[1];
-  else
-    // unable to determine if daylight savings in effect
-    timezonename="";
-  
-  // Finally put the information into the buffer as needed.
-  snprintf(buffer, DATEANDEPOCHLEN, "%s %s", datebuffer, timezonename);
-  
-  return;
-}
-
-// Date and timezone gets printed into string pointed to by buffer
-void dateandtimezone(char *buffer){
-  
-  // Get the epoch (time in seconds since Jan 1 1970)
-  time_t tval=time(NULL);
-  
-  dateandtimezoneepoch(buffer, tval);
-  return;
-}
-
-// These are two utility functions for printing CVS IDs. Massagecvs()
-// returns distance that it has moved ahead in the input string
-int massagecvs(char *out, const char *cvsid){
-  char *copy,*filename,*date,*version;
-  int retVal=0;
-  const char delimiters[] = " ,$";
-
-  // make a copy on the heap, go to first token,
-  if (!(copy=strdup(cvsid)))
-    return 0;
-
-  if (!(filename=strtok(copy, delimiters))){
-    free(copy);
-    return 0;
-  }
-
-  // move to first instance of "Id:"
-  while (strcmp(filename,"Id:"))
-    if (!(filename=strtok(NULL, delimiters))){
-      free(copy);
-      return 0;
-    }
-  
-  // get filename, skip "v", get version and date
-  if (!(  filename=strtok(NULL, delimiters)  ) ||
-      !(           strtok(NULL, delimiters)  ) ||
-      !(   version=strtok(NULL, delimiters)  ) ||
-      !(      date=strtok(NULL, delimiters)  ) ) {
-    free(copy);
-    return 0;
-  }
-  
-  sprintf(out,"%-16s revision: %-5s date: %-15s", filename, version, date);
-  retVal = (date-copy)+strlen(date);
-  free(copy);
-  return  retVal;
-}
-
-// prints a single set of CVS ids
-void printone(char *block, const char *cvsid){
-  char strings[CVSMAXLEN];
-  const char *here=cvsid;
-  int line=1,len=strlen(cvsid)+1;
-
-  // check that the size of the output block is sufficient
-  if (len>=CVSMAXLEN) {
-    pout("CVSMAXLEN=%d must be at least %d\n",CVSMAXLEN,len+1);
-    EXIT(1);
-  }
-
-  // loop through the different strings
-  while ((len=massagecvs(strings,here))){
-    switch (line++){
-    case 1:
-      block+=snprintf(block,CVSMAXLEN,"Module:");
-      break;
-    default:
-      block+=snprintf(block,CVSMAXLEN,"  uses:");
-    } 
-    block+=snprintf(block,CVSMAXLEN," %s\n",strings);
-    here+=len;
-  }
-  return;
-}
-
-
-// A replacement for perror() that sends output to our choice of
-// printing.
-void syserror(const char *message){
-  const char *errormessage;
-  
-  // Get the correct system error message:
-  errormessage=strerror(errno);
-
-  // Check that caller has handed a sensible string, and provide
-  // appropriate output. See perrror(3) man page to understand better.
-    if (message && *message)
-      pout("%s: %s\n",message, errormessage);
-    else
-      pout("%s\n",errormessage);
-        
-    return;
-}
-
-// Prints a warning message for a failed regular expression compilation from
-// regcomp().
-void printregexwarning(int errcode, regex_t *compiled){
-  size_t length = regerror(errcode, compiled, NULL, 0);
-  char *buffer = malloc(length);
-  if (!buffer){
-    pout("Out of memory in printregexwarning()\n");
-    return;
-  }
-  regerror(errcode, compiled, buffer, length);
-  pout("%s\n", buffer);
-  free(buffer);
-  return;
-}
-
-// A wrapper for regcomp().  Returns zero for success, non-zero otherwise.
-int compileregex(regex_t *compiled, const char *pattern, int cflags)
-{ 
-  int errorcode;
-
-  if ((errorcode = regcomp(compiled, pattern, cflags))) {
-    pout("Internal error: unable to compile regular expression %s", pattern);
-    printregexwarning(errorcode, compiled);
-    pout("Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n");
-    return 1;
-  }
-  return 0;
-}
-
-// Splits an argument to the -r option into a name part and an (optional) 
-// positive integer part.  s is a pointer to a string containing the
-// argument.  After the call, s will point to the name part and *i the
-// integer part if there is one or 1 otherwise.  Note that the string s may
-// be changed by this function.  Returns zero if successful and non-zero
-// otherwise.
-int split_report_arg(char *s, int *i)
-{
-  if ((s = strchr(s, ','))) {
-    // Looks like there's a name part and an integer part.
-    char *tailptr;
-
-    *s++ = '\0';
-    if (*s == '0' || !isdigit((int)*s))  // The integer part must be positive
-      return 1;
-    errno = 0;
-    *i = (int) strtol(s, &tailptr, 10);
-    if (errno || *tailptr != '\0')
-      return 1;
-  } else {
-    // There's no integer part.
-    *i = 1;
-  }
-
-  return 0;
-}
-
-// same as above but sets *i to -1 if missing , argument
-int split_report_arg2(char *s, int *i){
-  char *tailptr;
-  s+=6;
-
-  if (*s=='\0' || !isdigit((int)*s)) { 
-    // What's left must be integer
-    *i=-1;
-    return 1;
-  }
-
-  errno = 0;
-  *i = (int) strtol(s, &tailptr, 10);
-  if (errno || *tailptr != '\0') {
-    *i=-1;
-    return 1;
-  }
-
-  return 0;
-}
-
-#ifndef HAVE_STRTOULL
-// Replacement for missing strtoull() (Linux with libc < 6, MSVC 6.0)
-// Functionality reduced to split_selective_arg()'s requirements.
-
-static uint64_t strtoull(const char * p, char * * endp, int base)
-{
-  uint64_t result, maxres;
-  int i = 0;
-  char c = p[i++];
-  // assume base == 0
-  if (c == '0') {
-    if (p[i] == 'x' || p[i] == 'X') {
-      base = 16; i++;
-    }
-    else
-      base = 8;
-    c = p[i++];
-  }
-  else
-    base = 10;
-
-  result = 0;
-  maxres = ~(uint64_t)0 / (unsigned)base;
-  for (;;) {
-    unsigned digit;
-    if ('0' <= c && c <= '9')
-      digit = c - '0';
-    else if ('A' <= c && c <= 'Z')
-      digit = c - 'A' + 10;
-    else if ('a' <= c && c <= 'z')
-      digit = c - 'a' + 10;
-    else
-      break;
-    if (digit >= (unsigned)base)
-      break;
-    if (!(   result < maxres
-          || (result == maxres && digit <= ~(uint64_t)0 % (unsigned)base))) {
-      result = ~(uint64_t)0; errno = ERANGE; // return on overflow
-      break;
-    }
-    result = result * (unsigned)base + digit;
-    c = p[i++];
-  }
-  *endp = (char *)p + i - 1;
-  return result;
-}
-#endif // HAVE_STRTOLL
-
-// Splits an argument to the -t option that is assumed to be of the form
-// "selective,%lld-%lld" (prefixes of "0" (for octal) and "0x"/"0X" (for hex)
-// are allowed).  The first long long int is assigned to *start and the second
-// to *stop.  Returns zero if successful and non-zero otherwise.
-int split_selective_arg(char *s, uint64_t *start,
-                        uint64_t *stop)
-{
-  char *tailptr;
-
-  if (!(s = strchr(s, ',')))
-    return 1;
-  if (!isdigit((int)(*++s)))
-    return 1;
-  errno = 0;
-  // Last argument to strtoull (the base) is 0 meaning that decimal is assumed
-  // unless prefixes of "0" (for octal) or "0x"/"0X" (for hex) are used.
-  *start = strtoull(s, &tailptr, 0);
-
-  s = tailptr;
-  if (errno || *s++ != '-')
-    return 1;
-  *stop = strtoull(s, &tailptr, 0);
-  if (errno || *tailptr != '\0')
-    return 1;
-  return 0;
-}
-
-int64_t bytes = 0;
-// Helps debugging.  If the second argument is non-negative, then
-// decrement bytes by that amount.  Else decrement bytes by (one plus)
-// length of null terminated string.
-void *FreeNonZero(void *address, int size, int line, const char* file){
-  if (address) {
-    if (size<0)
-      bytes-=1+strlen(address);
-    else
-      bytes-=size;
-    return CheckFree(address, line, file);
-  }
-  return NULL;
-}
-
-// To help with memory checking.  Use when it is known that address is
-// NOT null.
-void *CheckFree(void *address, int whatline, const char* file){
-  if (address){
-    free(address);
-    return NULL;
-  }
-  
-  PrintOut(LOG_CRIT, "Internal error in CheckFree() at line %d of file %s\n%s", 
-           whatline, file, reportbug);
-  EXIT(EXIT_BADCODE);
-}
-
-// A custom version of calloc() that tracks memory use
-void *Calloc(size_t nmemb, size_t size) { 
-  void *ptr=calloc(nmemb, size);
-  
-  if (ptr)
-    bytes+=nmemb*size;
-
-  return ptr;
-}
-
-// A custom version of strdup() that keeps track of how much memory is
-// being allocated. If mustexist is set, it also throws an error if we
-// try to duplicate a NULL string.
-char *CustomStrDup(char *ptr, int mustexist, int whatline, const char* file){
-  char *tmp;
-
-  // report error if ptr is NULL and mustexist is set
-  if (ptr==NULL){
-    if (mustexist) {
-      PrintOut(LOG_CRIT, "Internal error in CustomStrDup() at line %d of file %s\n%s", 
-               whatline, file, reportbug);
-      EXIT(EXIT_BADCODE);
-    }
-    else
-      return NULL;
-  }
-
-  // make a copy of the string...
-  tmp=strdup(ptr);
-  
-  if (!tmp) {
-    PrintOut(LOG_CRIT, "No memory to duplicate string %s at line %d of file %s\n", ptr, whatline, file);
-    EXIT(EXIT_NOMEM);
-  }
-  
-  // and track memory usage
-  bytes+=1+strlen(ptr);
-  
-  return tmp;
-}
-
-// Returns nonzero if region of memory contains non-zero entries
-int nonempty(unsigned char *testarea,int n){
-  int i;
-  for (i=0;i<n;i++)
-    if (testarea[i])
-      return 1;
-  return 0;
-}
-
-
-// This routine converts an integer number of milliseconds into a test
-// string of the form Xd+Yh+Zm+Ts.msec.  The resulting text string is
-// written to the array.
-void MsecToText(unsigned int msec, char *txt){
-  int start=0;
-  unsigned int days, hours, min, sec;
-
-  days       = msec/86400000U;
-  msec      -= days*86400000U;
-
-  hours      = msec/3600000U; 
-  msec      -= hours*3600000U;
-
-  min        = msec/60000U;
-  msec      -= min*60000U;
-
-  sec        = msec/1000U;
-  msec      -= sec*1000U;
-
-  if (days) {
-    txt += sprintf(txt, "%2dd+", (int)days);
-    start=1;
-  }
-
-  sprintf(txt, "%02d:%02d:%02d.%03d", (int)hours, (int)min, (int)sec, (int)msec);  
-  return;
-}
-
-
-
diff --git a/sm5/utility.cpp b/sm5/utility.cpp
deleted file mode 100644
index 57e862049a9993486be30320288f8b01f6ab599b..0000000000000000000000000000000000000000
--- a/sm5/utility.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * utility.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-// THIS FILE IS INTENDED FOR UTILITY ROUTINES THAT ARE APPLICABLE TO
-// BOTH SCSI AND ATA DEVICES, AND THAT MAY BE USED IN SMARTD,
-// SMARTCTL, OR BOTH.
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-
-#include "config.h"
-#include "int64.h"
-#include "utility.h"
-
-// Any local header files should be represented by a CVSIDX just below.
-const char* utility_c_cvsid="$Id: utility.cpp,v 1.53 2004/07/29 21:00:36 chrfranke Exp $"
-CONFIG_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
-
-const char * packet_types[] = {
-        "Direct-access (disk)",
-        "Sequential-access (tape)",
-        "Printer",
-        "Processor",
-        "Write-once (optical disk)",
-        "CD/DVD",
-        "Scanner",
-        "Optical memory (optical disk)",
-        "Medium changer",
-        "Communications",
-        "Graphic arts pre-press (10)",
-        "Graphic arts pre-press (11)",
-        "Array controller",
-        "Enclosure services",
-        "Reduced block command (simplified disk)",
-        "Optical card reader/writer"
-};
-
-// Whenever exit() status is EXIT_BADCODE, please print this message
-const char *reportbug="Please report this bug to the Smartmontools developers at " PACKAGE_BUGREPORT ".\n";
-
-
-// hang on to exit code, so we can make use of more generic 'atexit()'
-// functionality and still check our exit code
-int exitstatus = 0;
-
-// command-line argument: are we running in debug mode?.
-unsigned char debugmode = 0;
-
-
-// Solaris only: Get site-default timezone. This is called from
-// UpdateTimezone() when TZ environment variable is unset at startup.
-#if defined (__SVR4) && defined (__sun)
-static const char *TIMEZONE_FILE = "/etc/TIMEZONE";
-
-static char *ReadSiteDefaultTimezone(){
-  FILE *fp;
-  char buf[512], *tz;
-  int n;
-
-  tz = NULL;
-  fp = fopen(TIMEZONE_FILE, "r");
-  if(fp == NULL) return NULL;
-  while(fgets(buf, sizeof(buf), fp)) {
-    if (strncmp(buf, "TZ=", 3))    // searches last "TZ=" line
-      continue;
-    n = strlen(buf) - 1;
-    if (buf[n] == '\n') buf[n] = 0;
-    if (tz) free(tz);
-    tz = strdup(buf);
-  }
-  fclose(fp);
-  return tz;
-}
-#endif
-
-// Make sure that this executable is aware if the user has changed the
-// time-zone since the last time we polled devices. The cannonical
-// example is a user who starts smartd on a laptop, then flies across
-// time-zones with a laptop, and then changes the timezone, WITHOUT
-// restarting smartd. This is a work-around for a bug in
-// GLIBC. Yuk. See bug number 48184 at http://bugs.debian.org and
-// thanks to Ian Redfern for posting a workaround.
-
-// Please refer to the smartd manual page, in the section labeled LOG
-// TIMESTAMP TIMEZONE.
-void FixGlibcTimeZoneBug(){
-#if __GLIBC__  
-  if (!getenv("TZ")) {
-    putenv("TZ=GMT");
-    tzset();
-    putenv("TZ");
-    tzset();
-  }
-#elif _WIN32
-  if (!getenv("TZ")) {
-    putenv("TZ=GMT");
-    tzset();
-    putenv("TZ=");  // empty value removes TZ, putenv("TZ") does nothing
-    tzset();
-  }
-#elif defined (__SVR4) && defined (__sun)
-  // In Solaris, putenv("TZ=") sets null string and invalid timezone.
-  // putenv("TZ") does nothing.  With invalid TZ, tzset() do as if
-  // TZ=GMT.  With TZ unset, /etc/TIMEZONE will be read only _once_ at
-  // first tzset() call.  Conclusion: Unlike glibc, dynamic
-  // configuration of timezone can be done only by changing actual
-  // value of TZ environment value.
-  enum tzstate { NOT_CALLED_YET, USER_TIMEZONE, TRACK_TIMEZONE };
-  static enum tzstate state = NOT_CALLED_YET;
-
-  static struct stat prev_stat;
-  static char *prev_tz;
-  struct stat curr_stat;
-  char *curr_tz;
-
-  if(state == NOT_CALLED_YET) {
-    if(getenv("TZ")) {
-      state = USER_TIMEZONE; // use supplied timezone
-    } else {
-      state = TRACK_TIMEZONE;
-      if(stat(TIMEZONE_FILE, &prev_stat)) {
-	state = USER_TIMEZONE;	// no TZ, no timezone file; use GMT forever
-      } else {
-	prev_tz = ReadSiteDefaultTimezone(); // track timezone file change
-	if(prev_tz) putenv(prev_tz);
-      }
-    }
-    tzset();
-  } else if(state == TRACK_TIMEZONE) {
-    if(stat(TIMEZONE_FILE, &curr_stat) == 0
-       && (curr_stat.st_ctime != prev_stat.st_ctime
-	    || curr_stat.st_mtime != prev_stat.st_mtime)) {
-      // timezone file changed
-      curr_tz = ReadSiteDefaultTimezone();
-      if(curr_tz) {
-	putenv(curr_tz);
-	if(prev_tz) free(prev_tz);
-	prev_tz = curr_tz; prev_stat = curr_stat; 
-      }
-    }
-    tzset();
-  }
-#endif
-  // OTHER OS/LIBRARY FIXES SHOULD GO HERE, IF DESIRED.  PLEASE TRY TO
-  // KEEP THEM INDEPENDENT.
-  return;
-}
-
-// This value follows the peripheral device type value as defined in
-// SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in
-// the ATA standard for packet devices to define the device type.
-const char *packetdevicetype(int type){
-  if (type<0x10)
-    return packet_types[type];
-  
-  if (type<0x20)
-    return "Reserved";
-  
-  return "Unknown";
-}
-
-
-// Returns 1 if machine is big endian, else zero.  This is a run-time
-// rather than a compile-time function.  We could do it at
-// compile-time but in principle there are architectures that can run
-// with either byte-ordering.
-int isbigendian(){
-  short i=0x0100;
-  char *tmp=(char *)&i;
-  return *tmp;
-}
-
-// Utility function prints date and time and timezone into a character
-// buffer of length>=64.  All the fuss is needed to get the right
-// timezone info (sigh).
-void dateandtimezoneepoch(char *buffer, time_t tval){
-  struct tm *tmval;
-  char *timezonename;
-  char datebuffer[DATEANDEPOCHLEN];
-  int lenm1;
-
-  FixGlibcTimeZoneBug();
-  
-  // Get the time structure.  We need this to determine if we are in
-  // daylight savings time or not.
-  tmval=localtime(&tval);
-  
-  // Convert to an ASCII string, put in datebuffer
-  // same as: asctime_r(tmval, datebuffer);
-  strncpy(datebuffer, asctime(tmval), DATEANDEPOCHLEN);
-  datebuffer[DATEANDEPOCHLEN-1]='\0';
-  
-  // Remove newline
-  lenm1=strlen(datebuffer)-1;
-  datebuffer[lenm1>=0?lenm1:0]='\0';
-  
-  // correct timezone name
-  if (tmval->tm_isdst==0)
-    // standard time zone
-    timezonename=tzname[0];
-  else if (tmval->tm_isdst>0)
-    // daylight savings in effect
-    timezonename=tzname[1];
-  else
-    // unable to determine if daylight savings in effect
-    timezonename="";
-  
-  // Finally put the information into the buffer as needed.
-  snprintf(buffer, DATEANDEPOCHLEN, "%s %s", datebuffer, timezonename);
-  
-  return;
-}
-
-// Date and timezone gets printed into string pointed to by buffer
-void dateandtimezone(char *buffer){
-  
-  // Get the epoch (time in seconds since Jan 1 1970)
-  time_t tval=time(NULL);
-  
-  dateandtimezoneepoch(buffer, tval);
-  return;
-}
-
-// These are two utility functions for printing CVS IDs. Massagecvs()
-// returns distance that it has moved ahead in the input string
-int massagecvs(char *out, const char *cvsid){
-  char *copy,*filename,*date,*version;
-  int retVal=0;
-  const char delimiters[] = " ,$";
-
-  // make a copy on the heap, go to first token,
-  if (!(copy=strdup(cvsid)))
-    return 0;
-
-  if (!(filename=strtok(copy, delimiters))){
-    free(copy);
-    return 0;
-  }
-
-  // move to first instance of "Id:"
-  while (strcmp(filename,"Id:"))
-    if (!(filename=strtok(NULL, delimiters))){
-      free(copy);
-      return 0;
-    }
-  
-  // get filename, skip "v", get version and date
-  if (!(  filename=strtok(NULL, delimiters)  ) ||
-      !(           strtok(NULL, delimiters)  ) ||
-      !(   version=strtok(NULL, delimiters)  ) ||
-      !(      date=strtok(NULL, delimiters)  ) ) {
-    free(copy);
-    return 0;
-  }
-  
-  sprintf(out,"%-16s revision: %-5s date: %-15s", filename, version, date);
-  retVal = (date-copy)+strlen(date);
-  free(copy);
-  return  retVal;
-}
-
-// prints a single set of CVS ids
-void printone(char *block, const char *cvsid){
-  char strings[CVSMAXLEN];
-  const char *here=cvsid;
-  int line=1,len=strlen(cvsid)+1;
-
-  // check that the size of the output block is sufficient
-  if (len>=CVSMAXLEN) {
-    pout("CVSMAXLEN=%d must be at least %d\n",CVSMAXLEN,len+1);
-    EXIT(1);
-  }
-
-  // loop through the different strings
-  while ((len=massagecvs(strings,here))){
-    switch (line++){
-    case 1:
-      block+=snprintf(block,CVSMAXLEN,"Module:");
-      break;
-    default:
-      block+=snprintf(block,CVSMAXLEN,"  uses:");
-    } 
-    block+=snprintf(block,CVSMAXLEN," %s\n",strings);
-    here+=len;
-  }
-  return;
-}
-
-
-// A replacement for perror() that sends output to our choice of
-// printing.
-void syserror(const char *message){
-  const char *errormessage;
-  
-  // Get the correct system error message:
-  errormessage=strerror(errno);
-
-  // Check that caller has handed a sensible string, and provide
-  // appropriate output. See perrror(3) man page to understand better.
-    if (message && *message)
-      pout("%s: %s\n",message, errormessage);
-    else
-      pout("%s\n",errormessage);
-        
-    return;
-}
-
-// Prints a warning message for a failed regular expression compilation from
-// regcomp().
-void printregexwarning(int errcode, regex_t *compiled){
-  size_t length = regerror(errcode, compiled, NULL, 0);
-  char *buffer = malloc(length);
-  if (!buffer){
-    pout("Out of memory in printregexwarning()\n");
-    return;
-  }
-  regerror(errcode, compiled, buffer, length);
-  pout("%s\n", buffer);
-  free(buffer);
-  return;
-}
-
-// A wrapper for regcomp().  Returns zero for success, non-zero otherwise.
-int compileregex(regex_t *compiled, const char *pattern, int cflags)
-{ 
-  int errorcode;
-
-  if ((errorcode = regcomp(compiled, pattern, cflags))) {
-    pout("Internal error: unable to compile regular expression %s", pattern);
-    printregexwarning(errorcode, compiled);
-    pout("Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n");
-    return 1;
-  }
-  return 0;
-}
-
-// Splits an argument to the -r option into a name part and an (optional) 
-// positive integer part.  s is a pointer to a string containing the
-// argument.  After the call, s will point to the name part and *i the
-// integer part if there is one or 1 otherwise.  Note that the string s may
-// be changed by this function.  Returns zero if successful and non-zero
-// otherwise.
-int split_report_arg(char *s, int *i)
-{
-  if ((s = strchr(s, ','))) {
-    // Looks like there's a name part and an integer part.
-    char *tailptr;
-
-    *s++ = '\0';
-    if (*s == '0' || !isdigit((int)*s))  // The integer part must be positive
-      return 1;
-    errno = 0;
-    *i = (int) strtol(s, &tailptr, 10);
-    if (errno || *tailptr != '\0')
-      return 1;
-  } else {
-    // There's no integer part.
-    *i = 1;
-  }
-
-  return 0;
-}
-
-// same as above but sets *i to -1 if missing , argument
-int split_report_arg2(char *s, int *i){
-  char *tailptr;
-  s+=6;
-
-  if (*s=='\0' || !isdigit((int)*s)) { 
-    // What's left must be integer
-    *i=-1;
-    return 1;
-  }
-
-  errno = 0;
-  *i = (int) strtol(s, &tailptr, 10);
-  if (errno || *tailptr != '\0') {
-    *i=-1;
-    return 1;
-  }
-
-  return 0;
-}
-
-#ifndef HAVE_STRTOULL
-// Replacement for missing strtoull() (Linux with libc < 6, MSVC 6.0)
-// Functionality reduced to split_selective_arg()'s requirements.
-
-static uint64_t strtoull(const char * p, char * * endp, int base)
-{
-  uint64_t result, maxres;
-  int i = 0;
-  char c = p[i++];
-  // assume base == 0
-  if (c == '0') {
-    if (p[i] == 'x' || p[i] == 'X') {
-      base = 16; i++;
-    }
-    else
-      base = 8;
-    c = p[i++];
-  }
-  else
-    base = 10;
-
-  result = 0;
-  maxres = ~(uint64_t)0 / (unsigned)base;
-  for (;;) {
-    unsigned digit;
-    if ('0' <= c && c <= '9')
-      digit = c - '0';
-    else if ('A' <= c && c <= 'Z')
-      digit = c - 'A' + 10;
-    else if ('a' <= c && c <= 'z')
-      digit = c - 'a' + 10;
-    else
-      break;
-    if (digit >= (unsigned)base)
-      break;
-    if (!(   result < maxres
-          || (result == maxres && digit <= ~(uint64_t)0 % (unsigned)base))) {
-      result = ~(uint64_t)0; errno = ERANGE; // return on overflow
-      break;
-    }
-    result = result * (unsigned)base + digit;
-    c = p[i++];
-  }
-  *endp = (char *)p + i - 1;
-  return result;
-}
-#endif // HAVE_STRTOLL
-
-// Splits an argument to the -t option that is assumed to be of the form
-// "selective,%lld-%lld" (prefixes of "0" (for octal) and "0x"/"0X" (for hex)
-// are allowed).  The first long long int is assigned to *start and the second
-// to *stop.  Returns zero if successful and non-zero otherwise.
-int split_selective_arg(char *s, uint64_t *start,
-                        uint64_t *stop)
-{
-  char *tailptr;
-
-  if (!(s = strchr(s, ',')))
-    return 1;
-  if (!isdigit((int)(*++s)))
-    return 1;
-  errno = 0;
-  // Last argument to strtoull (the base) is 0 meaning that decimal is assumed
-  // unless prefixes of "0" (for octal) or "0x"/"0X" (for hex) are used.
-  *start = strtoull(s, &tailptr, 0);
-
-  s = tailptr;
-  if (errno || *s++ != '-')
-    return 1;
-  *stop = strtoull(s, &tailptr, 0);
-  if (errno || *tailptr != '\0')
-    return 1;
-  return 0;
-}
-
-int64_t bytes = 0;
-// Helps debugging.  If the second argument is non-negative, then
-// decrement bytes by that amount.  Else decrement bytes by (one plus)
-// length of null terminated string.
-void *FreeNonZero(void *address, int size, int line, const char* file){
-  if (address) {
-    if (size<0)
-      bytes-=1+strlen(address);
-    else
-      bytes-=size;
-    return CheckFree(address, line, file);
-  }
-  return NULL;
-}
-
-// To help with memory checking.  Use when it is known that address is
-// NOT null.
-void *CheckFree(void *address, int whatline, const char* file){
-  if (address){
-    free(address);
-    return NULL;
-  }
-  
-  PrintOut(LOG_CRIT, "Internal error in CheckFree() at line %d of file %s\n%s", 
-           whatline, file, reportbug);
-  EXIT(EXIT_BADCODE);
-}
-
-// A custom version of calloc() that tracks memory use
-void *Calloc(size_t nmemb, size_t size) { 
-  void *ptr=calloc(nmemb, size);
-  
-  if (ptr)
-    bytes+=nmemb*size;
-
-  return ptr;
-}
-
-// A custom version of strdup() that keeps track of how much memory is
-// being allocated. If mustexist is set, it also throws an error if we
-// try to duplicate a NULL string.
-char *CustomStrDup(char *ptr, int mustexist, int whatline, const char* file){
-  char *tmp;
-
-  // report error if ptr is NULL and mustexist is set
-  if (ptr==NULL){
-    if (mustexist) {
-      PrintOut(LOG_CRIT, "Internal error in CustomStrDup() at line %d of file %s\n%s", 
-               whatline, file, reportbug);
-      EXIT(EXIT_BADCODE);
-    }
-    else
-      return NULL;
-  }
-
-  // make a copy of the string...
-  tmp=strdup(ptr);
-  
-  if (!tmp) {
-    PrintOut(LOG_CRIT, "No memory to duplicate string %s at line %d of file %s\n", ptr, whatline, file);
-    EXIT(EXIT_NOMEM);
-  }
-  
-  // and track memory usage
-  bytes+=1+strlen(ptr);
-  
-  return tmp;
-}
-
-// Returns nonzero if region of memory contains non-zero entries
-int nonempty(unsigned char *testarea,int n){
-  int i;
-  for (i=0;i<n;i++)
-    if (testarea[i])
-      return 1;
-  return 0;
-}
-
-
-// This routine converts an integer number of milliseconds into a test
-// string of the form Xd+Yh+Zm+Ts.msec.  The resulting text string is
-// written to the array.
-void MsecToText(unsigned int msec, char *txt){
-  int start=0;
-  unsigned int days, hours, min, sec;
-
-  days       = msec/86400000U;
-  msec      -= days*86400000U;
-
-  hours      = msec/3600000U; 
-  msec      -= hours*3600000U;
-
-  min        = msec/60000U;
-  msec      -= min*60000U;
-
-  sec        = msec/1000U;
-  msec      -= sec*1000U;
-
-  if (days) {
-    txt += sprintf(txt, "%2dd+", (int)days);
-    start=1;
-  }
-
-  sprintf(txt, "%02d:%02d:%02d.%03d", (int)hours, (int)min, (int)sec, (int)msec);  
-  return;
-}
-
-
-
diff --git a/sm5/utility.h b/sm5/utility.h
deleted file mode 100644
index 6eb82431307cae2d1033d004bf1ba137a8a3e004..0000000000000000000000000000000000000000
--- a/sm5/utility.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * utility.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * 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, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#ifndef UTILITY_H_
-#define UTILITY_H_
-
-#define UTILITY_H_CVSID "$Id: utility.h,v 1.37 2004/08/16 22:44:28 ballen4705 Exp $\n"
-
-#include <time.h>
-#include <sys/types.h> // for regex.h (according to POSIX)
-#include <regex.h>
-
-#include "int64.h"
-
-#if defined(_WIN32) && defined(_MSC_VER)
-#define snprintf  _snprintf
-#define vsnprintf  _vsnprintf
-#endif
-
-// Utility function prints current date and time and timezone into a
-// character buffer of length>=64.  All the fuss is needed to get the
-// right timezone info (sigh).
-#define DATEANDEPOCHLEN 64
-void dateandtimezone(char *buffer);
-// Same, but for time defined by epoch tval
-void dateandtimezoneepoch(char *buffer, time_t tval);
-
-// utility function for printing out CVS strings
-#define CVSMAXLEN 1024
-void printone(char *block, const char *cvsid);
-
-// like printf() except that we can control it better. Note --
-// although the prototype is given here in utility.h, the function
-// itself is defined differently in smartctl and smartd.  So the
-// function definition(s) are in smartd.c and in smartctl.c.
-#ifndef __GNUC__
-#define __attribute__(x)      /* nothing */
-#endif
-void pout(char *fmt, ...)  
-     __attribute__ ((format (printf, 1, 2)));
-
-// replacement for perror() with redirected output.
-void syserror(const char *message);
-
-// Prints a warning message for a failed regular expression compilation from
-// regcomp().
-void printregexwarning(int errcode, regex_t *compiled);
-
-// A wrapper for regcomp().  Returns zero for success, non-zero otherwise.
-int compileregex(regex_t *compiled, const char *pattern, int cflags);
-
-// Function for processing -r option in smartctl and smartd
-int split_report_arg(char *s, int *i);
-// Function for processing -c option in smartctl and smartd
-int split_report_arg2(char *s, int *i);
-// Function for processing -t selective... option in smartctl
-int split_selective_arg(char *s, uint64_t *start, uint64_t *stop);
-
-
-// Guess device type (ata or scsi) based on device name 
-// Guessing will now use Controller Type defines below
-
-int guess_device_type(const char * dev_name);
-
-// Create and return the list of devices to probe automatically
-// if the DEVICESCAN option is in the smartd config file
-int make_device_names (char ***devlist, const char* name);
-
-
-#define EXIT(x)  { exitstatus = (x); exit((x)); }
-
-// replacement for calloc() that tracks memory usage
-void *Calloc(size_t nmemb, size_t size);
-
-// Utility function to free memory
-void *FreeNonZero(void* address, int size, int whatline, const char* file);
-
-// A custom version of strdup() that keeps track of how much memory is
-// being allocated. If mustexist is set, it also throws an error if we
-// try to duplicate a NULL string.
-char *CustomStrDup(char *ptr, int mustexist, int whatline, const char* file);
-
-// To help with memory checking.  Use when it is known that address is
-// NOT null.
-void *CheckFree(void *address, int whatline, const char* file);
-
-// This function prints either to stdout or to the syslog as needed
-
-// [From GLIBC Manual: Since the prototype doesn't specify types for
-// optional arguments, in a call to a variadic function the default
-// argument promotions are performed on the optional argument
-// values. This means the objects of type char or short int (whether
-// signed or not) are promoted to either int or unsigned int, as
-// appropriate.]
-void PrintOut(int priority,char *fmt, ...);
-
-// run time, determine byte ordering
-int isbigendian();
-
-// This value follows the peripheral device type value as defined in
-// SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in
-// the ATA standard for packet devices to define the device type.
-const char *packetdevicetype(int type);
-
-int deviceopen(const char *pathname, char *type);
-
-int deviceclose(int fd);
-
-// returns 1 if any of the n bytes are nonzero, else zero.
-int nonempty(unsigned char *testarea,int n);
-
-// needed to fix glibc bug
-void FixGlibcTimeZoneBug();
-
-// convert time in msec to a text string
-void MsecToText(unsigned int msec, char *txt);
-
-// Exit codes
-#define EXIT_BADCMD    1   // command line did not parse
-#define EXIT_BADCONF   2   // syntax error in config file
-#define EXIT_STARTUP   3   // problem forking daemon
-#define EXIT_PID       4   // problem creating pid file
-#define EXIT_NOCONF    5   // config file does not exist
-#define EXIT_READCONF  6   // config file exists but cannot be read
-
-#define EXIT_NOMEM     8   // out of memory
-#define EXIT_BADCODE   10  // internal error - should NEVER happen
-
-#define EXIT_BADDEV    16  // we can't monitor this device
-#define EXIT_NODEV     17  // no devices to monitor
-
-#define EXIT_SIGNAL    254 // abort on signal
-
-
-// macros to control printing
-#define PRINT_ON(control)  {if (control->printing_switchable) control->dont_print=0;}
-#define PRINT_OFF(control) {if (control->printing_switchable) control->dont_print=1;}
-
-// possible values for controller_type in extern.h
-#define CONTROLLER_UNKNOWN              0x00
-#define CONTROLLER_ATA                  0x01
-#define CONTROLLER_SCSI                 0x02
-#define CONTROLLER_3WARE                0x03  // set by -d option, but converted to one of three types below
-#define CONTROLLER_3WARE_678K      0x04  // NOT set by guess_device_type()
-#define CONTROLLER_3WARE_9000_CHAR 0x05  // set by guess_device_type()
-#define CONTROLLER_3WARE_678K_CHAR 0x06  // set by guess_device_type()
-
-#endif
diff --git a/www/3w-xxxx.txt b/www/3w-xxxx.txt
deleted file mode 100644
index 5dde49c574c8ad84e69d89797ceeea17115f68e6..0000000000000000000000000000000000000000
--- a/www/3w-xxxx.txt
+++ /dev/null
@@ -1,157 +0,0 @@
----------------------------------------------------------------------------
-# November 27, 2003
-#
-# This patch is now against the official 3ware version 1.02.00.036 3w-xxxx.c driver
-# dated Wed Jul 16 20:30:28 2003. Instructions for use:
-# 
-# [1] download the 1.02.00.036 3w-xxxx.c driver from 
-#     http://www.3ware.com/support/download.asp
-#
-# [2] Unpack it:
-#       tar zxvf rh7x_8x.tgz (or su7x_8x.tgz for SuSE)
-#
-# [3] Unpack the source code, and move to the right directory:
-#       cd src/2.4
-#       tar zxvf 3w-xxxx.tgz
-#       cd driver
-#
-# [4] Copy THIS FILE (what you are reading!) into that
-#     directory and name it 3w-xxxx.txt
-#
-# [5] Patch the driver:
-#       patch < 3w-xxxx.txt
-#     You should get the response 'patching file 3w-xxxx.c'.
-#
-# [6] Build the driver with the command:
-#       make
-#     This will create the driver: a file named 3w-xxxx.o
-#
-# [7] Load the driver (you must be root to do this):
-#       /sbin/insmod ./3w-xxxx.o
-#     [Note: if '/sbin/lsmod' shows that the driver is loaded already,
-#     then unmount any file systems that use it, then unload the driver
-#     with '/sbin/rmmod 3w-xxxx' first!]
-#
-# [8] Copy the driver into place in the kernel tree:
-#       cp ./3w-xxxx.o /lib/modules/`uname -r`/kernel/drivers/scsi
-#     That's it!
-#
-# August 14, 2003
-#
-# Adam Radford has incorporated a change that now allows the 3w-xxxx
-# driver to return the Cylinder Low/High values.  These are needed to
-# get the SMART health status.  This patch incorporates those changes
-# as well.
-#
-# August 12, 2003
-#
-# 3ware has incorporated a more general version of this fix into their latest
-# 3w-xxxx driver release. Rather than using this patch, you can upgrade your 
-# 3w-xxxx driver to version 1.02.00.037 or greater.  Or you can use this patch.
-#
-# August 8, 2003
-# PATCH FOR 3WARE 3w-xxxx DRIVER
-# Bruce Allen ballen at gravity.phys.uwm.edu
-# CVS ID of this file: $Id: 3w-xxxx.txt,v 1.5 2003/11/28 17:58:50 ballen4705 Exp $
-# 
-# To apply this patch, save this entire file to 3w-xxxx.txt in a
-# directory containing the original unpatched 3w-xxxx.c file. Then
-# given the command:
-#                     patch < 3w-xxxx.txt
-# That's it!
-#
-# TECHNICAL EXPLANATION OF THE PATCH FOLLOWS.  SKIP IT IF YOU DON'T CARE.
-#
-# The 3w-xxxx SCSI RAID driver for 3ware Escalade controller cards has a bug
-# in the "passthru" ioctl() which prevents two SMART commands from being
-# passed to the ATA devices behind the controller. The commands are:
-# 
-#  SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE 
-#  (Command Register=0xB0/Feature Register=0xD2)
-# 
-#  SMART ENABLE/DISABLE AUTOMATIC OFF-LINE
-#  (Command Register=0xB0/Feature Register=0xDB)
-# 
-# [Note: the second of these commands is listed as "Obsolete" in the ATA
-# specifications.  It was originally defined in SFF-8035i.  Most vendors
-# (IBM/Hitachi, Maxtor, Samsung, WD, among others) still implement it for
-# backwards compatibility.]
-# 
-# The problem arises because in both cases (stupidly!) the ENABLE subcommand
-# is indicated with a nonzero value of the Sector Count Register.  For the
-# AUTOSAVE command one uses Sector Count Register=0xF1 and for the AUTOMATIC
-# OFF-LINE command one uses Sector Count Register=0xF8.
-# 
-# This provokes the following error messages from the 3w-xxxx driver:
-#   3w-xxxx: tw_ioctl(): Passthru size (123392) too big.
-#   3w-xxxx: tw_ioctl(): Passthru size (126976) too big.
-# and the driver doesn't pass the ATA command on.  This is because the
-# passthru part of the 3w-xxxx driver assumes that the value in the Sector
-# Count Register is the number of 512-byte blocks to transfer, and these
-# values exceed the internal buffer sizes.
-# 
-# In fact both of these are non-data commands, and so this is trivial to
-# fix.  I am attaching an 8-line patch for this purpose.  It looks for these
-# particular commands and then treats them as non-data commands. It has been
-# tested on both a 6800 and a 7500 controller, and should be endian-order
-# and 32/64-bit clean.
-# 
-# [Note: the normal linux ide drivers also assume that the Sector Count
-# Register is the number of 512-byte sectors to transfer to user space.  
-# But in that case the user can simply allocate a userland buffer large
-# enough to hold the 0xf1*0x200 or 0xf8*0x200 bytes, and then ignore the
-# contents.]
-#
-# -----------------------------------------------------------------------
-
---- 3w-xxxx.c.orig	Wed Jul 16 20:30:28 2003
-+++ 3w-xxxx.c	Thu Nov 27 11:20:25 2003
-@@ -173,6 +173,9 @@
-    1.02.00.035 - Improve tw_allocate_memory() memory allocation.
-                  Fix tw_chrdev_ioctl() to sleep correctly.
-    1.02.00.036 - Increase character ioctl timeout to 60 seconds.
-+   
-+   This version 1.02.00.036 3w-xxxx.c driver has been patched for full smartmontools support.
-+   
- */
- 
- #include <linux/module.h>
-@@ -1930,12 +1933,15 @@
- 			}
- 
- 			passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
--			passthru->sg_list[0].length = passthru->sector_count*512;
--			if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
--				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
--				return 1;
-+			/* Don't load sg_list for non-data ATA cmds */
-+			if ((passthru->param != 0) && (passthru->param != 0x8)) {
-+				passthru->sg_list[0].length = passthru->sector_count*512;
-+				if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
-+					printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
-+					return 1;
-+				}
-+				passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
- 			}
--			passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
- 			tw_post_command_packet(tw_dev, request_id);
- 			return 0;
- 		case TW_CMD_PACKET:
-@@ -2185,8 +2191,15 @@
- 	ioctl = (TW_Ioctl *)buff;
- 	switch (ioctl->opcode) {
- 		case TW_ATA_PASSTHRU:
--			passthru = (TW_Passthru *)ioctl->data;
--			memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
-+		        passthru = (TW_Passthru *)ioctl->data;
-+			/* Don't return data for non-data ATA cmds */
-+			if ((passthru->param != 0) && (passthru->param != 0x8))
-+				memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
-+			else {
-+			/* For non-data cmds, return cmd pkt */
-+				if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command))
-+					memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
-+			}
- 			break;
- 		case TW_CMD_PACKET_WITH_DATA:
- 			dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
diff --git a/www/BadBlockHowTo.txt b/www/BadBlockHowTo.txt
deleted file mode 100644
index f9782784634f6c5e9fcaa010ff9da865b6a3e3e5..0000000000000000000000000000000000000000
--- a/www/BadBlockHowTo.txt
+++ /dev/null
@@ -1,316 +0,0 @@
-THIS DOCUMENT SHOWS HOW TO IDENTIFY THE FILE ASSOCIATED WITH AN
-UNREADABLE DISK SECTOR, AND HOW TO FORCE THAT SECTOR TO REALLOCATE.
-
-Assumptions: Linux OS, ext2 or ext3 file system.
-
-Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
-Thanks to Sergey Vlasov, Theodore Ts'o, Michael Bendzick, and others
-for explaining this to me. I would like to add text showing how to do
-this for other file systems, in particular ReiserFS, XFS, and JFS:
-please email me if you can provide this information.
-
-
-
-In this example, the disk is failing self-tests at Logical Block
-Address LBA = 0x016561e9 = 23421417.  The LBA counts sectors in units
-of 512 bytes, and starts at zero.
-
------------------------------------------------------------------------------------------------
-root]# smartctl -l selftest /dev/hda:
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended offline    Completed: read failure       90%       217         0x016561e9
------------------------------------------------------------------------------------------------
-
-Note that other signs that there is a bad sector on the disk can be
-found in the non-zero value of the Current Pending Sector count:
------------------------------------------------------------------------------------------------
-root]# smartctl -A /dev/hda
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       0
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       1
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       1
------------------------------------------------------------------------------------------------
-
-First Step: We need to locate the partition on which this sector of
-the disk lives:
------------------------------------------------------------------------------------------------
-root]# fdisk -lu /dev/hda
-
-Disk /dev/hda: 123.5 GB, 123522416640 bytes
-255 heads, 63 sectors/track, 15017 cylinders, total 241254720 sectors
-Units = sectors of 1 * 512 = 512 bytes
-
-   Device Boot    Start       End    Blocks   Id  System
-/dev/hda1   *        63   4209029   2104483+  83  Linux
-/dev/hda2       4209030   5269319    530145   82  Linux swap
-/dev/hda3       5269320 238227884 116479282+  83  Linux
-/dev/hda4     238227885 241248104   1510110   83  Linux
------------------------------------------------------------------------------------------------
-
-The partition /dev/hda3 starts at LBA 5269320 and extends past the
-'problem' LBA.  The 'problem' LBA is offset 23421417 - 5269320 =
-18152097 sectors into the partition /dev/hda3.
-
-To verify the type of the file system and the mount point, look in
-/etc/fstab:
------------------------------------------------------------------------------------------------
-root]# grep hda3 /etc/fstab
-/dev/hda3 /data ext2 defaults 1 2
------------------------------------------------------------------------------------------------
-You can see that this is an ext2 file system, mounted at /data.
-
-Second Step: we need to find the blocksize of the file system
-(normally 4096 bytes for ext2):
------------------------------------------------------------------------------------------------
-root]# tune2fs -l /dev/hda3 | grep Block
-Block count:              29119820
-Block size:               4096
------------------------------------------------------------------------------------------------
-In this case the block size is 4096 bytes.
-
-Third Step: we need to determine which File System Block contains this
-LBA.  The formula is:
-  b = (int)((L-S)*512/B)
-where:
-b = File System block number
-B = File system block size in bytes
-L = LBA of bad sector
-S = Starting sector of partition as shown by fdisk -lu
-and (int) denotes the integer part.
-
-In our example, L=23421417, S=5269320, and B=4096.  Hence the
-'problem' LBA is in block number
-   b = (int)18152097*512/4096 = (int)2269012.125
-so b=2269012.
-
-Note: the fractional part of 0.125 indicates that this problem LBA is
-actually the second of the eight sectors that make up this file system
-block.
-
-Fourth Step: we use debugfs to locate the inode stored in this block,
-and the file that contains that inode:
------------------------------------------------------------------------------------------------
-root]# debugfs
-debugfs 1.32 (09-Nov-2002)
-debugfs:  open /dev/hda3
-debugfs:  icheck 2269012
-Block	Inode number
-2269012	41032
-debugfs:  ncheck 41032
-Inode	Pathname
-41032	/S1/R/H/714197568-714203359/H-R-714202192-16.gwf
------------------------------------------------------------------------------------------------
-
-In this example, you can see that the problematic file (with the mount
-point included in the path) is:
-/data/S1/R/H/714197568-714203359/H-R-714202192-16.gwf
-
-
-To force the disk to reallocate this bad block we'll write zeros to
-the bad block, and sync the disk:
------------------------------------------------------------------------------------------------
-root]# dd if=/dev/zero of=/dev/hda3 bs=4096 count=1 seek=2269012
-root]# sync
------------------------------------------------------------------------------------------------
-
-NOTE: THIS LAST STEP HAS PERMANENTLY AND IRRETREVIABLY DESTROYED SOME
-OF THE DATA THAT WAS IN THIS FILE.  DON'T DO THIS UNLESS YOU DON'T
-NEED THE FILE OR YOU CAN REPLACE IT WITH A FRESH OR CORRECT VERSION.
-
-
-Now everything is back to normal: the sector has been reallocated.
-Compare the output just below to similar output near the top of this
-article:
------------------------------------------------------------------------------------------------
-root]# smartctl -A /dev/hda
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       1
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       1
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       1
------------------------------------------------------------------------------------------------
-
-Note: for some disks it may be necessary to update the SMART Attribute values by using
-smartctl -t offline /dev/hda
-
-The disk now passes its self-tests again:
-
------------------------------------------------------------------------------------------------
-root]# smartctl -t long /dev/hda  [wait until test completes, then]
-root]# smartctl -l selftest /dev/hda
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended offline    Completed without error       00%       239         -
-# 2  Extended offline    Completed: read failure       90%       217         0x016561e9
-# 3  Extended offline    Completed: read failure       90%       212         0x016561e9
-# 4  Extended offline    Completed: read failure       90%       181         0x016561e9
-# 5  Extended offline    Completed without error       00%        14         -
-# 6  Extended offline    Completed without error       00%         4         -
------------------------------------------------------------------------------------------------
-
-and no longer shows any offline uncorrectable sectors:
-
------------------------------------------------------------------------------------------------
-root]# smartctl -A /dev/hda
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       1
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       1
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       0
------------------------------------------------------------------------------------------------
-
-
-
-A SECOND EXAMPLE
-
-On this drive, the first sign of trouble was this email from smartd:
-
-    To: ballen
-    Subject: SMART error (selftest) detected on host: medusa-slave166.medusa.phys.uwm.edu
-
-    This email was generated by the smartd daemon running on host:
-    medusa-slave166.medusa.phys.uwm.edu in the domain: master001-nis
-
-    The following warning/error was logged by the smartd daemon:
-    Device: /dev/hda, Self-Test Log error count increased from 0 to 1
-
-    
-Running smartctl -a /dev/hda confirmed the problem:
-    
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended offline    Completed: read failure       80%       682         0x021d9f44
-
-Note that the failing LBA reported is 0x021d9f44 (base 16) = 35495748 (base 10)
-    
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       0
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       3
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       3
-
-and one can see above that there are 3 sectors on the list of pending
-sectors that the disk can't read but would like to reallocate.
-
-The device also shows errors in the SMART error log:
-
-Error 212 occurred at disk power-on lifetime: 690 hours
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 12 46 9f 1d e2  Error: UNC 18 sectors at LBA = 0x021d9f46 = 35495750
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  25 00 12 46 9f 1d e0 00 2485545.000  READ DMA EXT
-
-Signs of trouble at this LBA may also be found in SYSLOG:
-
-[root]# grep LBA /var/log/messages | awk '{print $12}' | sort | uniq
- LBAsect=35495748
- LBAsect=35495750
-
-So I decide to do a quick check to see how many bad sectors there
-really are. Using the bash shell I check 70 sectors around the trouble
-area:
-    
-[root]# export i=35495730
-[root]# while [ $i -lt 35495800 ]
-        > do echo $i
-        > dd if=/dev/hda of=/dev/null bs=512 count=1 skip=$i
-        > let i+=1
-        > done
- 
-<SNIP>   
-
-35495734
-1+0 records in
-1+0 records out
-35495735
-dd: reading `/dev/hda': Input/output error
-0+0 records in
-0+0 records out
-
-<SNIP>
-
-35495751
-dd: reading `/dev/hda': Input/output error
-0+0 records in
-0+0 records out
-35495752
-1+0 records in
-1+0 records out
-
-<SNIP>
-
-which shows that the seventeen sectors 35495735-35495751 (inclusive)
-are not readable.
-
-Next, we identify the files at those locations.  The partitioning
-information on this disk is identical to the first example above, and
-as in that case the problem sectors are on the third partition
-/dev/hda3.  So we have:
-     L=35495735 to 35495751
-     S=5269320
-     B=4096
-so that b=3778301 to 3778303 are the three bad blocks in the file
-system.
-
-[root]# debugfs
-debugfs 1.32 (09-Nov-2002)
-debugfs:  open /dev/hda3
-debugfs:  icheck 3778301
-Block   Inode number
-3778301 45192
-debugfs:  icheck 3778302
-Block   Inode number
-3778302 45192
-debugfs:  icheck 3778303
-Block   Inode number
-3778303 45192
-debugfs:  ncheck 45192
-Inode   Pathname
-45192   /S1/R/H/714979488-714985279/H-R-714979984-16.gwf
-debugfs:  quit
-
-And finally, just to confirm that this is really the damaged file:
-
-[root]# md5sum /data/S1/R/H/714979488-714985279/H-R-714979984-16.gwf
-md5sum: /data/S1/R/H/714979488-714985279/H-R-714979984-16.gwf: Input/output error
-
-Finally we force the disk to reallocate the three bad blocks:
-[root]# dd if=/dev/zero of=/dev/hda3 bs=4096 count=3 seek=3778301
-[root]# sync
-
-We could also probably use:
-[root]# dd if=/dev/zero of=/dev/hda bs=512 count=17 seek=35495735
-
-At this point we now have:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       0
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       0
-
-which is encouraging, since the pending sectors count is now zero.
-Note that the drive reallocation count has not yet increased: the
-drive may now have confidence in these sectors and have decided not to
-reallocate them..
-
-A device self test: 
-  [root#] smartctl -t long /dev/hda
-(then wait about an hour) shows no unreadable sectors or errors:
-
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended offline    Completed without error       00%       692         -
-# 2  Extended offline    Completed: read failure       80%       682         0x021d9f44
-
-This document is version $Id: BadBlockHowTo.txt,v 1.4 2004/03/21 20:38:32 ballen4705 Exp $
-It is Copyright Bruce Allen (2004) and distributed under GPL2.
-
-
diff --git a/www/FAQ.xml b/www/FAQ.xml
deleted file mode 100644
index 51fd9fbbd56e1bc1cdc6e5504cfa9dfe6b6e8923..0000000000000000000000000000000000000000
--- a/www/FAQ.xml
+++ /dev/null
@@ -1,543 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" >
-
-<!--
-Layout borrowed from Doug's smartmontools_scsi.xml.  The following text
-is also from his file.
-
-This is DocBook XML that can be rendered into a single HTML page with a
-command like 'xmlto html-nochunks <this_file_name>'.  It can also be
-rendered into multi-page HTML (drop the "-nochunks") or pdf, ps, txt,
-etc.
--->
-
-<article id="index">
- <articleinfo>
-   <title>FAQ - Frequently Asked Questions</title>
-   <author>
-    <firstname>smartmontools</firstname>
-    <surname>developers</surname>
-    <affiliation>
-     <address>
-      <email>smartmontools-support@lists.sourceforge.net</email>
-     </address>
-    </affiliation>
-   </author>
-  <authorinitials>sd</authorinitials>
-  <pubdate>2003-09-24</pubdate>
-
-  <revhistory>
-     <revision>
-       <revnumber>1.0</revnumber>
-       <date>2003-10-22</date>
-       <authorinitials>sd</authorinitials>
-       <revremark>
-             Moved from index.html to XML
-       </revremark>
-     </revision>
-  </revhistory>
-
-  <copyright>
-   <year>2003</year>
-   <holder>Bruce Allen</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-      Permission is granted to copy, distribute and/or modify this
-      document under the terms of the GNU Free Documentation License,
-      Version 1.1 or any later version published by the Free Software
-      Foundation; with no Invariant Sections, with no Front-Cover Texts,
-      and with no Back-Cover Texts.
-   </para>
-   <para>
-    For an online copy of the license see
-    <ulink url="http://www.fsf.org/copyleft/fdl.html">
-    <literal>http://www.fsf.org/copyleft/fdl.html</literal></ulink> .
-   </para>
-
-  </legalnotice>
-
-  <abstract>
-  <para>
-   FAQ - Frequently Asked Questions
-  </para>
-  </abstract>
- </articleinfo>
-
-<!--
-<toc></toc>
--->
-
-
-<sect1 id="a">
-
-<title>What do I do if I have problems, or need support?  Suppose I want
-to become a developer, or suggest some new extensions?</title>
-
-<para>First, search the support mailing list archives to see if your
-question has been answered.  Instructions are in the following
-paragraph.  If you don't find an answer there, then please send an
-e-mail to the smartmontools-support mailing list.  Instructions are
-available at <ulink url="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">
-<literal>http://lists.sourceforge.net/mailman/listinfo/smartmontools-support</literal></ulink>
-. The list is moderated but you're not required to subscribe to it in
-order to post your question.</para>
-
-<para>To search the archives, first go to <ulink url="http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support">
-<literal>http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support</literal></ulink>
-. In the top left corner you will see a search box: use <emphasis
-role="bold">Mailing List</emphasis> as the type of search.  This tool
-works very well.</para>
-
-<para>Note that from time to time SourceForge has mailing problems and
-you'll get a message telling you that <emphasis role="italic">Either
-your mailing list name was misspelled or your mailing list has not been
-archived yet.  If this list has just been created, please retry in 2-4
-hours</emphasis>.  If this happens, you'll have to try again
-later.</para>
-
-</sect1>
-
-<sect1 id="b">
-
-<title>What are the future plans for smartmontools?</title>
-
-<para>My plan is that smartmontools-5.x will support ATA/ATAPI-5 disks. 
-Eventually, we'll do smartmontools-6.x to support ATA/ATAPI-6 disks,
-smartmontools-7.x for the ATA/ATAPI-7 standard, and so on.  The "x" will
-denote revision level, as bugs get found and fixed, and as enhancements
-get added.  If it's possible to maintain backwards compatibility, that
-would be nice, but I don't know if it will be possible or
-practical.</para>
-
-</sect1>
-
-<sect1 id="c">
-
-<title>Why are you doing this?</title>
-
-<para>My research group at U. Wisconsin - Milwaukee runs a beowulf
-cluster -  <ulink url="http://www.lsc-group.phys.uwm.edu/beowulf/medusa/">
-<literal>http://www.lsc-group.phys.uwm.edu/beowulf/medusa/</literal></ulink>
--  with 600 ATA-5 and -6 disks (300 IBM and 300 Maxtor).  We have more
-than 50 TB of data stored on the system.  I also help out with a cluster
--  <ulink url="http://pandora.aei.mpg.de/merlin/">
-<literal>http://pandora.aei.mpg.de/merlin/</literal></ulink> -  at the
-Albert Einstein Institute that has another 300 IBM ATA-6 disks (36 TB
-total).  It's nice to have advanced warning when a disk is going to
-fail.</para>
-
-</sect1>
-
-<sect1 id="d">
-
-<title>I see some strange output from smartctl.  What does it
-mean?</title>
-
-<para>The raw S.M.A.R.T. attributes (temperature, power-on lifetime, and
-so on) are stored in vendor-specific structures.  Sometime these are
-strange.  Hitachi disks (at least some of them) store power-on lifetime
-in minutes, rather than hours (see next question below).  IBM disks (at
-least some of them) have three temperatures stored in the raw structure,
-not just one.  And so on.  If you find strange output, or unknown
-attributes, please send an e-mail to the mailing list and we'll help you
-try and figure it out.</para>
-
-</sect1>
-
-<sect1 id="e">
-
-<title>What Kernel Version is needed? (Linux)</title>
-
-<para>Kernel versions 2.4.0 or later should work.  We recommend the
-latest 2.4 kernel.</para>
-
-<para>Vanilla kernel.org 2.2.X kernels do not support the
-HDIO_DRIVE_TASK ioctl(), which is needed for the ATA drive to execute
-the ATA SMART RETURN STATUS command.  So these kernels will not
-work.</para>
-
-<para>Vendor-supplied 2.2.X kernels, and vanilla 2.2.X kernels patched
-with Andre Hedrick's IDE patches -  <ulink url="http://www.funet.fi/pub/linux/kernel/people/hedrick/ide-2.2.20/">
-<literal>http://www.funet.fi/pub/linux/kernel/people/hedrick/ide-2.2.20/</literal></ulink>
-(also available from your local kernel.org mirror, not updated for
-2.2.21 or later, and probably still containing a few bugs) may support
-the needed ioctl().</para>
-
-<para>If the configuration option CONFIG_IDE_TASK_IOCTL exists in your
-2.2.X kernel source code tree, then your 2.2.X kernel will probably
-support smartmontools.  Note that this kernel configuration option does
-<emphasis role="italic">not</emphasis> need to be enabled.  Its presence
-merely indicates that the required HDIO_DRIVE_TASK ioctl() is
-supported.</para>
-
-</sect1>
-
-<sect1 id="f">
-
-<title>What attributes does smartmontools not yet recognize?</title>
-
-<para>From Maxtor disks (99), (100), (101)</para>
-
-<para>If you can attach names/meanings to these attributes, please send
-a note to the mailing list.  If you have access to other SMART utilities
-(especially manufacturer-specific ones, see below) and can send us
-comparison output from smartctl and the other utility, that's especially
-useful.</para>
-
-</sect1>
-
-<sect1 id="g">
-
-<title>My Maxtor/Hitachi/Fujitsu disk is only a few days old, yet
-smartctl reports its age (Attribute 9) as thousands of hours!</title>
-
-<para>On some recent disks, Maxtor has started to use Attribute 9 to
-store the lifetime in minutes rather than hours.  In this case, use the
--m option (smartctl versions 5.0.X) or the --vendorattribute=9,minutes
-(smartctl 5.1.X) option to correctly display hours and minutes.</para>
-
-<para>Some models of Fujitsu disks are known to use Attribute 9 for
-lifetime in seconds.  In that case, use the --vendorattribute=9,seconds
-option to correctly display hours, minutes and seconds.</para>
-
-</sect1>
-
-<sect1 id="h">
-
-<title>The power-on timer (Attribute 9 raw value) on my Maxtor disk acts
-strange.</title>
-
-<para>There are three related problems with Maxtor's SMART
-firmware:</para>
-
-<para><emphasis role="bold">1 - </emphasis>On some disks from 2001/2002,
-the raw value of Attribute 9 (Power On Time) is <emphasis
-role="italic">supposed</emphasis> to be minutes. But it advances at an
-unpredictable rate, always more slowly than one count per minute.  One
-(unconfirmed) theory is that when the disk is in idle mode, the counter
-stops advancing.  This is only supposed to happen in standby
-mode.</para>
-
-<para><emphasis role="bold">2 - </emphasis> In Maxtor disks that use the
-raw value of Attribute 9 as a minutes counter, only two bytes (of the
-six available) are used to store the raw value.  So it resets to zero
-once every 65536=2^16 minutes, or about once every 1092 hours.  This is
-fixed in all Maxtor disks manufactured after July 2003, where the raw
-value was extended to four bytes.</para>
-
-<para><emphasis role="bold">3 - </emphasis> In Maxtor disks that use the
-raw value of Attribute 9 as a minutes counter, the hour time-stamps in
-the self-test and ATA error logs are calculated by right shifting 6
-bits.  This is equivalent to dividing by 64 rather than by 60.  As a
-result, the hour time-stamps in these logs advance 7% more slowly than
-they should.  Thus, if you do self-tests once per week at the same time,
-instead of the time-stamps being 168 hours apart, they are 157 hours
-apart.  This is also fixed in all Maxtor disks manufactured after July
-2003.</para>
-
-</sect1>
-
-<sect1 id="i">
-
-<title>Where can I find manufacturer-specific disk-testing
-utilities?</title>
-
-<para>A good listing of such utilities can be found at <ulink url="http://www.benchmarkhq.ru/english.html?/be_hdd2.html">
-<literal>http://www.benchmarkhq.ru/english.html?/be_hdd2.html</literal></ulink>
-. Unfortunately most of these are for MS operating systems, but most can
-be run from an MS-DOS boot disk.  Note: if you do run one of these
-utilities, and it identifies the meanings of any SMART Attributes that
-are not known to smartmontools, please report them to the mailing
-list.</para>
-
-<para>These utilities have an important role to fill.  If your disk has
-bad sectors (for example, as revealed by running self-tests with
-smartmontools) and the disk is not able to recover the data from those
-sectors, then the disk will <emphasis role="italic">not</emphasis>
-automatically reallocate those damaged sectors from its set of spare
-sectors, because forcing the reallocation to take place may entail some
-loss of data.  Because the commands that force such reallocation are
-<emphasis role="italic">Vendor Specific</emphasis>, most manufactuers
-provide a utility for this purpose.  It may cause data loss but can
-repair damaged sectors (at least, until it runs out of replacement
-sectors).</para>
-
-</sect1>
-
-<sect1 id="j">
-
-<title>When I run <emphasis role="tt">smartd</emphasis>,
-the SYSLOG <emphasis role="tt">/var/log/messages</emphasis> contains
-messages like this:</title>
-
-<programlisting>
-smartd: Reading Device /dev/sdv
-modprobe: modprobe: Can't locate module block-major-65
-</programlisting>
-
-<para>This is because when <emphasis role="tt">smartd</emphasis> starts,
-it looks for all ATA and SCSI devices to monitor (matching the pattern
-<emphasis role="tt">/dev/hd[a-z]</emphasis> or <emphasis
-role="tt">/dev/sd[a-z]</emphasis>).  The log messages appear because
-your system doesn't have most of these devices.</para>
-
-<para>Recent releases of smartd can use a configuration file <emphasis
-role="tt">smartd.conf</emphasis> to specify which devices to include or
-exclude from start-up search.</para>
-
-</sect1>
-
-<sect1 id="k">
-
-<title>What's the story on IBM SMART disks?</title>
-
-<para>Apparently some of the older SMART firmware on IBM disks can
-interfere with the regular operation of the disk.   If you have this
-problem, a firmware upgrade that fixes the problem is avaialable at
-<ulink url="http://www.geocities.com/dtla_update/">
-<literal>http://www.geocities.com/dtla_update/</literal></ulink>
-.</para>
-
-</sect1>
-
-<sect1 id="l">
-
-<title>How can I check that the package hasn't been tampered
-with?</title>
-
-<para>Since the <emphasis role="tt">smartmontools</emphasis> utilities
-run as root, you might be concerned about something harmful being
-embedded within them. Starting with release 5.19 of <emphasis
-role="tt">smartmontools</emphasis>, the .rpm files and tarball have been
-GPG signed.  (The tarball's fingerprint is given in the SoureForge
-Release Notes.) Please verify these using the GPG Signing Key available
-at <ulink url="http://smartmontools.sourceforge.net/SmartmontoolsSigningKey.txt">
-<literal>http://smartmontools.sourceforge.net/SmartmontoolsSigningKey.txt</literal></ulink>
-.</para>
-
-</sect1>
-
-<sect1 id="m">
-
-<title>Is there a bootable standalone CD or floppy that contains
-smartmontools?</title>
-
-<para>If you have a system that is showing signs of disk trouble (for
-example, it's unbootable and the console is full of disk error messages)
-it can be handy to have a version of smartmontools that can be run off
-of a bootable CD or floppy to examine the disk's SMART data and run
-self-tests.  This is also useful if you want to run Captive Self-Tests
-(the <emphasis role="bold"><emphasis role="tt">-C</emphasis></emphasis>
-option of <emphasis role="bold"><emphasis
-role="tt">smartctl</emphasis></emphasis> ) on disks that can not easily
-be unmounted, such as those hosting the Operating System files.  Or you
-can use this to run <emphasis role="tt">smartctl</emphasis> on computers
-that don't use Linux as the day-to-day Operating System.</para>
-
-<para>At present I am only aware of three such bootable disks:</para>
-
-<itemizedlist>
-<listitem>
-<para>LNX-BBC Bootable CD - <ulink url="http://www.lnx-bbc.org/">
-<literal>http://www.lnx-bbc.org/</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>Stresslinux Bootable CD - <ulink url="http://www.stresslinux.org/">
-<literal>http://www.stresslinux.org/</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>RIP (Recovery Is Possible) Bootable CD/Floppy - <ulink url="http://www.tux.org/pub/people/kent-robotti/looplinux/rip/">
-<literal>http://www.tux.org/pub/people/kent-robotti/looplinux/rip/</literal></ulink></para>
-</listitem>
-</itemizedlist>
-
-<para> Please let us know if there are others, and we'll add them to
-this list.</para>
-
-</sect1>
-
-<sect1 id="n">
-
-<title>Can I monitor ATA disks behind SCSI RAID controllers?</title>
-
-<para>From release 5.1-16, smartmontools supports 3ware SCSI RAID
-controllers that use ATA disks internally.  To pass commands through the
-3ware controller, use the smartmontools <emphasis role="bold">-d
-3ware,N</emphasis> option or Directive.</para>
-
-<para>In smartmontools release 5.1-16, the SMART HEALTH STATUS
-(smartmontools <emphasis role="bold">-H</emphasis>) is not returned
-correctly for 3ware devices.  In this release, the ENABLE AUTOMATIC
-OFFLINE and ENABLE ATTRIBUTE AUTOSAVE commands (smartmontools <emphasis
-role="bold">-o on</emphasis> and <emphasis role="bold">-S on</emphasis>)
-are <emphasis role="italic">disabled</emphasis> for 3ware devices,
-because at the time 5.1-16 was released, the 3w-xxxx driver could not
-pass these commands through to the ATA disks.</para>
-
-<para>Later smartmontools CVS code and releases <emphasis
-role="italic">do</emphasis> correctly support <emphasis
-role="italic">all</emphasis> of these commands.  You may:</para>
-
-<itemizedlist>
-<listitem>
-<para>Use version <emphasis role="bold">1.02.00.037</emphasis> or
-greater of the 3w-xxxx driver, or</para>
-</listitem>
-
-<listitem>
-<para>Patch earlier 3ware 3w-xxxx drivers with <ulink url="http://smartmontools.sourceforge.net/3w-xxxx.txt">
-<literal>http://smartmontools.sourceforge.net/3w-xxxx.txt</literal></ulink>
-so that these commands reach the disks, or</para>
-</listitem>
-
-<listitem>
-<para>Use an <emphasis role="bold">unpatched</emphasis> earlier 3w-xxxx
-driver (which won't pass these commands to the disks but will instead
-print harmless warning messages to SYSLOG).</para>
-</listitem>
-</itemizedlist>
-
-<para>Since smartmontools 3ware support is new, please report positive
-or negative experiences to the mailing list, particularly for 64-bit
-and/or big-endian architectures.</para></sect1>
-
-<sect1 id="o">
-
-<title>SCSI disks and tapes (TapeAlert)</title>
-
-<para>smartmontools for SCSI disks and tapes (including medium changers)
-is discussed at <ulink url="http://smartmontools.sourceforge.net/smartmontools_scsi.html">
-<literal>http://smartmontools.sourceforge.net/smartmontools_scsi.html</literal></ulink>
-.</para>
-
-</sect1>
-
-<sect1 id="p">
-
-<title>FireWire, USB, and SATA disks/systems</title>
-
-<para>As for USB and FireWire (ieee1394) disks and tape drives, the news
-isn't good.  They appear to Linux as SCSI devices but their
-implementations do not usually support those SCSI commands needed by
-smartmontools.  The ieee1394 consortium recently certified the first
-external enclosure (containing a ATA disk and a protocol bridge) as
-being compliant to the relevant standards.  Such devices have already
-been on the market for about 3  years and they tend to only support the
-bare minimum of commands needed for device operation (i.e. S.M.A.R.T.
-support is an unsupported extra).</para>
-
-<para>I'd be very grateful to find someone who could help me test the
-smartmontools code on serial ATA (SATA) disks.  They should appear as
-normal ATA disks in Linux.</para>
-
-</sect1>
-
-<sect1 id="q">
-
-<title>How does smartmontools differ from smartsuite?</title>
-
-<para>The smartsuite code was originally developed as a Senior Thesis by
-Michael Cornwell at the Concurrent Systems Laboratory (now part of the
-Storage Systems Research Center - <ulink url="http://ssrc.soe.ucsc.edu/">
-<literal>http://ssrc.soe.ucsc.edu/</literal></ulink>), Jack Baskin
-School of Engineering, University of California, Santa Cruz.  You can
-find some information about the original smartsuite project here:</para>
-
-<itemizedlist>
-<listitem>
-<para>Press Release 1 - <ulink url="http://www.ucsc.edu/news_events/press_releases/archive/99-00/09-99/smart_software.htm">
-<literal>http://www.ucsc.edu/news_events/press_releases/archive/99-00/09-99/smart_software.htm</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>Press Release 2 - <ulink url="http://www.santa-cruz.com/archive/1999/September/22/local/stories/5local.htm">
-<literal>http://www.santa-cruz.com/archive/1999/September/22/local/stories/5local.htm</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>Press Release 3 - <ulink url="http://www.ucsc.edu/currents/99-00/09-27/smart.html">
-<literal>http://www.ucsc.edu/currents/99-00/09-27/smart.html</literal></ulink></para>
-</listitem>
-</itemizedlist>
-
-<para>smartmontools was derived directly from smartsuite.  It differs
-from smartsuite in that it supports the ATA/ATAPI-5 standard.  So for
-example <emphasis role="tt">smartctl</emphasis> from smartsuite has no
-facility for printing the SMART self-test logs, and doesn't print
-timestamp information in the most usable way.</para>
-
-<para>The <emphasis role="tt">smartctl</emphasis> utility in
-smartmontools has added functionality for this (<emphasis role="tt">-q,
--l selftest,-S, -T, -v and -m</emphasis> options), updated
-documentation, and also fixes small technical bugs in smartsuite.  [One
-example: smartsuite does not actually use the ATA SMART RETURN STATUS
-command to find out the health status of a disk.  It instead tries to
-infer this from the SMART Attribute values.]  See <ulink url="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?rev=HEAD&amp;content-type=text/plain">
-<literal>http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?rev=HEAD&amp;content-type=text/plain</literal></ulink> for a summary of what's been done.</para>
-
-<para>The <emphasis role="tt">smartd</emphasis> utility differs from the
-smartsuite <emphasis role="tt">smartd</emphasis> in major ways.  First,
-it prints somewhat more informative error messages to the syslog. 
-Second, on startup it looks for a configuration file <emphasis
-role="tt">smartd.conf</emphasis>, and if <emphasis
-role="tt">smartd</emphasis> finds this file, it monitors the list of
-devices therein, rather than querying all IDE and SCSI devices on your
-system.  (If the configuration file does not exist, then it does query
-all IDE and SCSI devices.)  Also, it's a well-behaved daemon and doesn't
-leave open file descriptors and other detrius behind.</para>
-
-<para>In addition, the <emphasis role="tt">smartmontools</emphasis>
-version of <emphasis role="tt">smartd</emphasis> can be instructed (via
-Directives in the configuration file) to monitor for changes in a number
-of different disk properties: the SMART status, failure or prefailure
-attributes going below threshold, new errors appearing in the ATA Error
-Log or the SMART Self-Test Log, and so on. <emphasis
-role="tt">smartd</emphasis> can also send an e-mail warning or run a
-user-specified executable if it detects a problem with the disk.</para>
-
-<para>The other principle difference is that smartmontools is an
-OpenSource development project, meaning that we keep the files in CVS,
-and that  other developers who wish to contribute can commit changes to
-the archive.  If you would like to contribute, please write to the
-mailing-list.</para>
-
-<para>But the bottom line is that the code in smartmontools is derived
-directly from smartsuite and is similar.  The smartsuite package can be
-found at <ulink url="http://sourceforge.net/projects/smartsuite/">
-<literal>http://sourceforge.net/projects/smartsuite/</literal></ulink>
-.</para></sect1>
-
-<sect1 id="r">
-
-<title>Does it work on Windows?</title>
-
-<para>Currently not, but we consider Cygwin - <ulink url="http://www.cygwin.com/">
-<literal>http://www.cygwin.com/</literal></ulink> -  the way to go,
-where CVS compiles almost out of the box but still lacks any specific
-code to make it work.  Write to the mailing list if you're interested in
-porting it.  Someone already sent some S.M.A.R.T. code for Windows,
-which may be of use.  Porting to other platforms may be easier as well
-now that any Linux specific code (like linux/hdreg.h) has been removed,
-and more will be done soon in that direction.</para>
-
-<para>A Cygwin port would probably only require and additional DLL,
-cygwin1.dll, to run on plain Windows.</para></sect1>
-
-<sect1 id="s">
-
-<title>Why has the versioning scheme changed?</title>
-
-<para>With the move to GNU Autoconf and GNU Automake it changed from
-5.X-Y (where X and Y are one or more numbers) to 5.Y.  This had to be
-done because the -Y extension is used by distributions to almost always
-denote a new build of the same version. So, the first version with that
-change will be 5.19 and not 5.1-19.</para>
-
-</sect1>
-
-</article>
diff --git a/www/Makefile b/www/Makefile
deleted file mode 100644
index 7af3daaef2868613ea340bf144be16aa79138be0..0000000000000000000000000000000000000000
--- a/www/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Manufactures HTML file from XML file. Note: do NOT edit the HTML
-# file, only the XML file.
-
-all: smartmontools_scsi.html
-
-smartmontools_scsi.html: smartmontools_scsi.xml 
-	xmlto html-nochunks smartmontools_scsi.xml
-
-upload: smartmontools_scsi.html index.html
-	scp smartmontools_scsi.html ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
-	scp 3w-xxxx.txt ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
-	scp index.html ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
-	scp examples/*.html ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs/examples
-	scp examples/*.txt ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs/examples
-	scp BadBlockHowTo.txt ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
diff --git a/www/SmartmontoolsSigningKey.txt b/www/SmartmontoolsSigningKey.txt
deleted file mode 100644
index 0ac19356f748d2b5f81b33962e588e8af28fb16d..0000000000000000000000000000000000000000
--- a/www/SmartmontoolsSigningKey.txt
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.0.7 (GNU/Linux)
-
-mQGiBD9XAXIRBACgLEphBmhUKWE1mRKzjkq/8vZHtJsVUiFivcbxaSLa9jBbJoZV
-sQk5fdcleVE6CcuodMetVE6Gl8uM4W4iymp0i35lwefdgmUzJYmza1ZD7Uk0x4zv
-tKi9xZ9Hc+yrf4SHRwLTZxuUyLf9TURwGXfLd2bxP1USYJVL4vOYoiBwBwCgq/w3
-EyO5PhlGp5rfE+WIoyy9GHcEAIYP3ctigHu6tnSobIGA77BFOv+v7DbXRjbKhEz1
-s4lPGQQP5h2t4VFRiy9RlD4GlEXD51cRFMmtFk4cBbOuONQbNOJFQQ/9JpVBU6/O
-CZrVMUqDnQMd2mdUU8pxM7cguaw5cPFxqqX5dkW1JikGrlG1QsH5UxuYhdadO+al
-1fTnA/9RMRscXd6aAdN66pZ9mGoqIxVUO6N+icXO7DP+ArIt7gu4GLgvvARlgMiS
-neRV4g7mvLm41kBDEv5gug+h2ha5ZI+P51oSRYs8yA5fVtl0GA2YRA2QercALv6C
-CtAvnFXWFqSeyW1ESdd2zFKBjhXlBVkmujOyKDS6LXRpZjwJXrRWU21hcnRtb250
-b29scyBTaWduaW5nIEtleSAodGhyb3VnaCAyMDA0KSA8c21hcnRtb250b29scy1z
-dXBwb3J0QGxpc3RzLnNvdXJjZWZvcmdlLm5ldD6IZAQTEQIAJAUCP1cBcgIbAwUJ
-AnjQAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAjPh86m7GaIlTQAJ9IsqaxHbqX
-BSd+xfJwUAZyKWqyLwCgoa2rMvHAHa/Pvpt4E0i0xF9NW3yITAQTEQIADAUCP1cB
-+QWDAnjPeQAKCRARGZEEN/UVgWa7AJ95rEDeEw9G3uqAZO7L9u650QPX6wCgoHJ9
-Hq/akQJZhOgSKyrgVEyAc8S5AQ0EP1cBeBAEAMLXV8RwVFDs5EvfkQNwasoKNS+N
-PvvhO/weED188XklZ3QTiToEp2b4JFaoUkTk1l2f9JxagDPaVHR6XU8H740x25LZ
-gC6XObKMBxqJ9CrBLGcMt/bCugquDu18KFlL3Y1rq9uBxq9JS6CJthUzeaaFdFQS
-V7tF2+3hBz/Okqo7AAMFA/9l0YcKnTKDy8jdOtNjky1NEbaF1LjyRc4laT6N4O6q
-Xg2oGD6MgS7zSK/ORcT3B0T5kpTo6gnKLTYDxEAvpNjrOjlwn08Jtm3xrQZLId/W
-RAo+Qqn5Or+sugZZpQPHrGGB9TTc0AL3MfCbK4mlssVhS0SAq35E/osCLQcor7Sx
-sohPBBgRAgAPBQI/VwF4AhsMBQkCeNAAAAoJECM+HzqbsZoi4WUAn2IQhEtHY/48
-4rljbro8yUwYlrXzAJ44VfTwmjLlI9aoYdRW/cTtZ0tPgw==
-=f2kQ
------END PGP PUBLIC KEY BLOCK-----
diff --git a/www/cvs-script b/www/cvs-script
deleted file mode 100755
index 42e4fa2e8d709db8ae2b49a1ff0739f5431dcc00..0000000000000000000000000000000000000000
--- a/www/cvs-script
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# execute this script in the current shell, using for example
-# . cvs_script
-unset CVS_SERVER
-export CVS_RSH=ssh
-export CVSROOT=:ext:ballen4705@cvs.sourceforge.net:/cvsroot/smartmontools
diff --git a/www/examples/FUJITSU1.txt b/www/examples/FUJITSU1.txt
deleted file mode 100644
index b10abf7a3b232514e1133510003645544d3ad932..0000000000000000000000000000000000000000
--- a/www/examples/FUJITSU1.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-[root/]# smartctl -v 9,seconds -v 200,writeerrorcount /dev/hda
-
-smartctl version 5.1-18 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     FUJITSU MHR2040AT
-Serial Number:    NJ41T291391J
-Firmware Version: 40BA
-Device is:        Not in smartctl database [for details use: -P showall]
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 1
-Local Time is:    Thu Sep  4 22:18:48 2003 CEST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-					Auto Off-line Data Collection: Disabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 ( 468) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine
-recommended polling time: 	 (  60) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000f   100   100   046    Pre-fail  Always       -       52685626284
-  2 Throughput_Performance  0x0005   100   100   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0003   093   093   025    Pre-fail  Always       -       24065
-  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       160
-  5 Reallocated_Sector_Ct   0x0033   099   099   024    Pre-fail  Always       -       31
-  7 Seek_Error_Rate         0x000f   100   100   047    Pre-fail  Always       -       131071
-  8 Seek_Time_Performance   0x0005   100   100   019    Pre-fail  Offline      -       0
-  9 Power_On_Seconds        0x0032   092   092   000    Old_age   Always       -       1335h+10m+34s
- 10 Spin_Retry_Count        0x0013   100   100   020    Pre-fail  Always       -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       150
-192 Power-Off_Retract_Count 0x0032   099   099   000    Old_age   Always       -       7
-193 Load_Cycle_Count        0x0032   074   074   000    Old_age   Always       -       95890
-194 Temperature_Celsius     0x0022   090   100   000    Old_age   Always       -       57
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       10141348
-196 Reallocated_Event_Count 0x0032   099   099   000    Old_age   Always       -       30
-197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
-200 Write_Error_Count       0x000f   036   033   060    Pre-fail  Always   FAILING_NOW 2883583
-203 Run_Out_Cancel          0x0002   091   091   000    Old_age   Always       -       2589872160305
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log structure revision number 1
-No self-tests have been logged
-
-
diff --git a/www/examples/FUJITSU_MHR2020AT.txt b/www/examples/FUJITSU_MHR2020AT.txt
deleted file mode 100644
index 4f8dc82b9c5b6858e849cf8e682dbe855fdb0c53..0000000000000000000000000000000000000000
--- a/www/examples/FUJITSU_MHR2020AT.txt
+++ /dev/null
@@ -1,158 +0,0 @@
-smartctl version 5.32 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     FUJITSU MHR2020AT
-Serial Number:    NJ13T2215TUH
-Firmware Version: 30B8
-Device is:        Not in smartctl database [for details use: -P showall]
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 1
-Local Time is:    Sun Aug 15 13:21:33 2004 MEST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Offline data collection status:  (0x00)	Offline data collection activity
-					was never started.
-					Auto Offline Data Collection: Disabled.
-Self-test execution status:      ( 105)	The previous self-test completed having
-					the servo (and/or seek) element of the 
-					test failed.
-Total time to complete Offline 
-data collection: 		 ( 234) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Auto Offline data collection on/off support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine
-recommended polling time: 	 (  30) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000f   007   001   046    Pre-fail  Always   FAILING_NOW 154618843423
-  2 Throughput_Performance  0x0005   100   100   020    Pre-fail  Offline      -       145
-  3 Spin_Up_Time            0x0003   094   083   025    Pre-fail  Always       -       24321
-  4 Start_Stop_Count        0x0032   097   097   000    Old_age   Always       -       1887
-  5 Reallocated_Sector_Ct   0x0033   099   099   024    Pre-fail  Always       -       1
-  7 Seek_Error_Rate         0x000f   100   100   047    Pre-fail  Always       -       458751
-  8 Seek_Time_Performance   0x0005   100   100   019    Pre-fail  Offline      -       0
-  9 Power_On_Seconds        0x0032   088   088   000    Old_age   Always       -       1819h+16m+52s
- 10 Spin_Retry_Count        0x0013   100   100   020    Pre-fail  Always       -       0
- 12 Power_Cycle_Count       0x0032   091   091   000    Old_age   Always       -       1467
-192 Power-Off_Retract_Count 0x0032   099   099   000    Old_age   Always       -       44
-193 Load_Cycle_Count        0x0032   086   086   000    Old_age   Always       -       49810
-194 Temperature_Celsius     0x0022   100   100   000    Old_age   Always       -       32
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       1221
-196 Reallocated_Event_Count 0x0032   099   099   000    Old_age   Always       -       1
-197 Current_Pending_Sector  0x0012   001   001   000    Old_age   Always       -       10
-198 Offline_Uncorrectable   0x0010   092   092   000    Old_age   Offline      -       17
-199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
-200 Multi_Zone_Error_Rate   0x000f   100   100   060    Pre-fail  Always       -       393215
-203 Run_Out_Cancel          0x0002   100   100   000    Old_age   Always       -       429515210380
-
-SMART Error Log Version: 1
-ATA Error Count: 6861 (device log contains only the most recent five errors)
-	CR = Command Register [HEX]
-	FR = Features Register [HEX]
-	SC = Sector Count Register [HEX]
-	SN = Sector Number Register [HEX]
-	CL = Cylinder Low Register [HEX]
-	CH = Cylinder High Register [HEX]
-	DH = Device/Head Register [HEX]
-	DC = Device Command Register [HEX]
-	ER = Error register [HEX]
-	ST = Status register [HEX]
-Powered_Up_Time is measured from power on, and printed as
-DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,
-SS=sec, and sss=millisec. It "wraps" after 49.710 days.
-
-Error 6861 occurred at disk power-on lifetime: 1818 hours (75 days + 18 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 8b 7d 16 51 f0  Error: UNC 139 sectors at LBA = 0x0051167d = 5314173
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 90 78 16 51 f0 00      08:22:32.857  READ DMA EXT
-
-Error 6860 occurred at disk power-on lifetime: 1818 hours (75 days + 18 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 8b 7d 16 51 f0  Error: UNC 139 sectors at LBA = 0x0051167d = 5314173
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 98 70 16 51 f0 00      08:22:27.700  READ DMA EXT
-
-Error 6859 occurred at disk power-on lifetime: 1818 hours (75 days + 18 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 8b 7d 16 51 f0  Error: UNC 139 sectors at LBA = 0x0051167d = 5314173
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 a0 68 16 51 f0 00      08:22:22.558  READ DMA EXT
-
-Error 6858 occurred at disk power-on lifetime: 1818 hours (75 days + 18 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 8b 7d 16 51 f0  Error: UNC 139 sectors at LBA = 0x0051167d = 5314173
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 a8 60 16 51 f0 00      08:22:17.458  READ DMA EXT
-
-Error 6857 occurred at disk power-on lifetime: 1818 hours (75 days + 18 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 8b 7d 16 51 f0  Error: UNC 139 sectors at LBA = 0x0051167d = 5314173
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 b0 58 16 51 f0 00      08:22:12.558  READ DMA EXT
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short offline       Completed: servo/seek failure 90%      1819         -
-# 2  Extended offline    Completed: servo/seek failure 90%      1816         -
-
-Device does not support Selective Self Tests/Logging
diff --git a/www/examples/HITACHI_DK23AA-12B.txt b/www/examples/HITACHI_DK23AA-12B.txt
deleted file mode 100644
index 6f9b62e60cff0d5751ceceeae48873b665319356..0000000000000000000000000000000000000000
--- a/www/examples/HITACHI_DK23AA-12B.txt
+++ /dev/null
@@ -1,173 +0,0 @@
-smartctl version 5.30 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     HITACHI_DK23AA-12B
-Serial Number:    xxxxxx
-Firmware Version: 00XDA0B6
-Device is:        Not in smartctl database [for details use: -P showall]
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Sat Apr 24 17:19:58 2004 EST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Offline data collection status:  (0x00)	Offline data collection activity was
-					never started.
-					Auto Offline Data Collection: Disabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete Offline 
-data collection: 		 (1110) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Auto Offline data collection on/off support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine
-recommended polling time: 	 (  19) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000d   099   099   050    Pre-fail  Offline      -       68719476757
-  4 Start_Stop_Count        0x0032   097   097   050    Old_age   Always       -       3259
-  5 Reallocated_Sector_Ct   0x0033   001   001   010    Pre-fail  Always   FAILING_NOW 1876
-  7 Seek_Error_Rate         0x000b   100   100   050    Pre-fail  Always       -       760
-  9 Power_On_Hours          0x0032   090   090   060    Old_age   Always       -       21783
- 10 Spin_Retry_Count        0x0013   100   100   050    Pre-fail  Always       -       0
-196 Reallocated_Event_Count 0x0032   001   001   001    Old_age   Always   FAILING_NOW 254
-197 Current_Pending_Sector  0x0032   097   093   001    Old_age   Always       -       3
-198 Offline_Uncorrectable   0x0010   100   100   001    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age   Always       -       0
-221 G-Sense_Error_Rate      0x000a   100   100   050    Old_age   Always       -       42
-223 Load_Retry_Count        0x0012   100   100   050    Old_age   Always       -       149
-225 Load_Cycle_Count        0x0032   050   050   050    Old_age   Always   FAILING_NOW 5110222858734
-250 Read_Error_Retry_Rate   0x000a   090   001   050    Old_age   Always   In_the_past 103
-
-SMART Error Log Version: 1
-ATA Error Count: 1151 (device log contains only the most recent five errors)
-	CR = Command Register [HEX]
-	FR = Features Register [HEX]
-	SC = Sector Count Register [HEX]
-	SN = Sector Number Register [HEX]
-	CL = Cylinder Low Register [HEX]
-	CH = Cylinder High Register [HEX]
-	DH = Device/Head Register [HEX]
-	DC = Device Command Register [HEX]
-	ER = Error register [HEX]
-	ST = Status register [HEX]
-Timestamp = decimal seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1151 occurred at disk power-on lifetime: 5445 hours
-  When the command that caused the error occurred, the device was doing SMART Offline or Self-test.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  01 51 01 01 4f c2 e0  Error: obs
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  b0 d5 01 01 4f c2 e0 00   46273.155  SMART READ LOG
-  b0 d1 01 01 4f c2 e0 00   46273.138  SMART READ ATTRIBUTE THRESHOLDS [OBS-4]
-  b0 d0 01 00 4f c2 e0 00   46273.009  SMART READ DATA
-  b0 da 00 00 4f c2 a0 00   46272.881  SMART RETURN STATUS
-  b0 da 00 00 4f c2 e0 00   46272.760  SMART RETURN STATUS
-
-Error 1150 occurred at disk power-on lifetime: 5354 hours
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  01 51 01 56 36 54 e1  Error: AMNF 1 sectors at LBA = 0x01543656 = 22296150
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 80 d7 35 54 e1 00    1517.332  READ DMA
-  c8 00 80 57 35 54 e1 00    1517.329  READ DMA
-  ca 00 08 67 1d cb e0 00    1516.014  WRITE DMA
-  ca 00 30 37 1d cb e0 00    1515.992  WRITE DMA
-  ca 00 10 2f e0 ca e0 00    1515.874  WRITE DMA
-
-Error 1149 occurred at disk power-on lifetime: 5352 hours
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  01 51 0c bb c5 57 e1  Error: AMNF 12 sectors at LBA = 0x0157c5bb = 22529467
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 20 a7 c5 57 e1 00     380.146  READ DMA
-  10 00 3f 00 00 00 e0 00     380.146  RECALIBRATE [OBS-4]
-  c8 00 20 a7 c5 57 e1 00     377.932  READ DMA
-  c8 00 20 a7 c5 57 e1 00     373.729  READ DMA
-  c8 00 80 6f 41 5f e1 00     371.776  READ DMA
-
-Error 1148 occurred at disk power-on lifetime: 5352 hours
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  01 51 0c bb c5 57 e1  Error: AMNF 12 sectors at LBA = 0x0157c5bb = 22529467
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 20 a7 c5 57 e1 00     377.932  READ DMA
-  c8 00 20 a7 c5 57 e1 00     373.729  READ DMA
-  c8 00 80 6f 41 5f e1 00     371.776  READ DMA
-  c8 00 80 ef 40 5f e1 00     371.742  READ DMA
-  ca 00 08 57 1f cb e0 00     371.291  WRITE DMA
-
-Error 1147 occurred at disk power-on lifetime: 5352 hours
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  01 51 0c bb c5 57 e1  Error: AMNF 12 sectors at LBA = 0x0157c5bb = 22529467
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 20 a7 c5 57 e1 00     373.729  READ DMA
-  c8 00 80 6f 41 5f e1 00     371.776  READ DMA
-  c8 00 80 ef 40 5f e1 00     371.742  READ DMA
-  ca 00 08 57 1f cb e0 00     371.291  WRITE DMA
-  ca 00 10 47 1f cb e0 00     371.262  WRITE DMA
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short offline       Completed without error       00%      5445         -
-# 2  Short offline       Completed without error       00%      5445         -
-# 3  Short offline       Aborted by host               90%      5445         -
-# 4  Short offline       Completed without error       00%      5445         -
-# 5  Short offline       Completed without error       00%      5445         -
-
diff --git a/www/examples/HITACHI_DK23BA-20-0.txt b/www/examples/HITACHI_DK23BA-20-0.txt
deleted file mode 100644
index 13e9cb0122e0c6e4e072ddfc91efba9d9a4a3d19..0000000000000000000000000000000000000000
--- a/www/examples/HITACHI_DK23BA-20-0.txt
+++ /dev/null
@@ -1,163 +0,0 @@
-[root@ballen www]# /usr/sbin/smartctl -am /dev/hda
-
-smartctl version 5.0-25 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     HITACHI_DK23BA-20                       
-Serial Number:    12H7M8
-Firmware Version: 00E0A0D2
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-See vendor-specific Attribute list for marginal Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (1530) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  26) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000d   100   083   050    Pre-fail     -       677
-  3 Spin_Up_Time            0x0007   100   100   050    Pre-fail     -       0
-  4 Start_Stop_Count        0x0032   100   100   050    Old_age      -       249
-  5 Reallocated_Sector_Ct   0x0033   099   099   010    Pre-fail     -       30
-  7 Seek_Error_Rate         0x000f   100   100   050    Pre-fail     -       319
-  9 Power_On_Hours          0x0032   099   099   060    Old_age      -       701 h + 42 m
- 10 Spin_Retry_Count        0x0013   100   100   050    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   050    Old_age      -       249
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       15
-195 Hardware_ECC_Recovered  0x001a   100   001   050    Old_age  In_the_past 559
-196 Reallocated_Event_Count 0x0032   097   097   001    Old_age      -       30
-197 Current_Pending_Sector  0x0032   095   095   001    Old_age      -       5
-198 Offline_Uncorrectable   0x0010   095   095   001    Old_age      -       31
-199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age      -       0
-221 G-Sense_Error_Rate      0x000a   100   100   050    Old_age      -       0
-223 Load_Retry_Count        0x0012   100   100   050    Old_age      -       0
-225 Load_Cycle_Count        0x0032   095   095   050    Old_age      -       18446744072753281791
-230 Unknown_Attribute       0x0032   100   100   060    Old_age      -       18484
-250 Unknown_Attribute       0x000a   100   070   050    Old_age      -       601
-
-SMART Error Log Version: 1
-ATA Error Count: 9 (device log contains only the most recent five errors)
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:01 SN:15 CL:be CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   01   15   be   2e    e0   c8     831.599
- 00   00   01   14   be   2e    e0   c8     831.594
- 00   00   01   13   be   2e    e0   c8     831.594
- 00   00   01   12   be   2e    e0   c8     831.594
- 00   00   01   11   be   2e    e0   c8     831.594
-
-Error 2 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:45 SN:15 CL:be CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   80   da   bd   2e    e0   c8     829.680
- 00   00   80   5a   bd   2e    e0   c8     829.677
- 00   00   80   da   bc   2e    e0   c8     829.673
- 00   00   80   5a   bc   2e    e0   c8     829.671
- 00   00   01   58   bc   2e    e0   c8     829.671
-
-Error 3 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:01 SN:47 CL:bc CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   01   47   bc   2e    e0   c8     826.962
- 00   00   01   46   bc   2e    e0   c8     826.961
- 00   00   01   45   bc   2e    e0   c8     826.961
- 00   00   01   44   bc   2e    e0   c8     826.961
- 00   00   01   43   bc   2e    e0   c8     826.961
-
-Error 4 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:13 SN:47 CL:bc CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   80   da   bb   2e    e0   c8     825.038
- 00   00   80   5a   bb   2e    e0   c8     825.033
- 00   00   80   da   ba   2e    e0   c8     825.030
- 00   00   80   5a   ba   2e    e0   c8     824.940
- 00   00   80   da   b9   2e    e0   c8     824.937
-
-Error 5 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:01 SN:85 CL:19 CH:2c D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   01   85   19   2c    e0   c8     816.487
- 00   00   01   84   19   2c    e0   c8     816.487
- 00   00   01   83   19   2c    e0   c8     816.486
- 00   00   01   82   19   2c    e0   c8     816.486
- 00   00   01   81   19   2c    e0   c8     816.486
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed                     00%       691         
-# 2  Extended off-line   Completed: read failure       40%       661         0x002c1985
-# 3  Extended off-line   Completed: read failure       40%       661         0x002c1985
-# 4  Short off-line      Completed                     00%       660         
-# 5  Extended off-line   Completed: read failure       40%       658         0x002c1985
-# 6  Short off-line      Completed                     00%       658         
-# 7  Short off-line      Completed                     00%       658         
-# 8  Extended off-line   Completed: read failure       40%       658         0x002c1985
-# 9  Extended off-line   Completed: read failure       40%       657         0x002c1985
-#10  Short off-line      Completed                     00%       647         
-#11  Short off-line      Completed                     00%       587         
-#12  Short off-line      Completed                     00%       583         
-#13  Short off-line      Completed                     00%       551         
-#14  Short captive       Interrupted (host reset)      40%       551         
-#15  Short off-line      Completed                     00%       551         
-#16  Extended off-line   Completed: read failure       40%       550         0x002c1985
-#17  Extended off-line   Aborted by host               50%       550         
-#18  Short off-line      Completed                     00%       550         
-#19  Short off-line      Completed                     00%       537         
-#20  Extended off-line   Completed: read failure       40%       536         0x002c1985
-#21  Short off-line      Completed                     00%       536         
diff --git a/www/examples/IC35L120AVV207-0.txt b/www/examples/IC35L120AVV207-0.txt
deleted file mode 100644
index 4e43e8c2d0976622c07e0e0cddc4507716f5cca6..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVV207-0.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-# smartctl -a /dev/hda
-smartctl version 5.0-45 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVV207-0                        
-Serial Number:    VNVD02G4G4BDEG
-Firmware Version: V24OA63A
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 3a
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (2855) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  48) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   060    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0007   102   102   024    Pre-fail     -       16974103
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age      -       14
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   020    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   100   100   000    Old_age      -       242
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       14
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       24
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age      -       24
-194 Temperature_Celsius     0x0002   203   203   000    Old_age      -       27 (Lifetime Min/Max 20/37)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%        54         
diff --git a/www/examples/IC35L120AVV207-1.txt b/www/examples/IC35L120AVV207-1.txt
deleted file mode 100644
index 48a69910371771d2fdf0b10b19e3ce0ea3d4aff6..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVV207-1.txt
+++ /dev/null
@@ -1,191 +0,0 @@
-smartctl version 5.31 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVV207-1
-Serial Number:    VNVD09G4H3HPMT
-Firmware Version: V24OA66A
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 3a
-Local Time is:    Tue Jun 15 23:38:56 2004 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Offline data collection status:  (0x84)	Offline data collection activity
-					was suspended by an interrupting command from host.
-					Auto Offline Data Collection: Enabled.
-Self-test execution status:      ( 121)	The previous self-test completed having
-					the read element of the test failed.
-Total time to complete Offline 
-data collection: 		 (2855) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Auto Offline data collection on/off support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					General Purpose Logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine
-recommended polling time: 	 (  48) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   089   089   060    Pre-fail  Always       -       1703986
-  2 Throughput_Performance  0x0005   015   015   050    Pre-fail  Offline  FAILING_NOW 5518
-  3 Spin_Up_Time            0x0007   100   100   024    Pre-fail  Always       -       278
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age   Always       -       9
-  5 Reallocated_Sector_Ct   0x0033   091   091   005    Pre-fail  Always       -       277
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail  Always       -       0
-  8 Seek_Time_Performance   0x0005   123   123   020    Pre-fail  Offline      -       37
-  9 Power_On_Hours          0x0012   100   100   000    Old_age   Always       -       2759
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail  Always       -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       9
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age   Always       -       45
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age   Always       -       45
-194 Temperature_Celsius     0x0002   166   166   000    Old_age   Always       -       33 (Lifetime Min/Max 23/44)
-196 Reallocated_Event_Count 0x0032   092   092   000    Old_age   Always       -       319
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       49
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       20
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age   Always       -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 161 (device log contains only the most recent five errors)
-	CR = Command Register [HEX]
-	FR = Features Register [HEX]
-	SC = Sector Count Register [HEX]
-	SN = Sector Number Register [HEX]
-	CL = Cylinder Low Register [HEX]
-	CH = Cylinder High Register [HEX]
-	DH = Device/Head Register [HEX]
-	DC = Device Command Register [HEX]
-	ER = Error register [HEX]
-	ST = Status register [HEX]
-Powered_Up_Time is measured from power on, and printed as
-DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,
-SS=sec, and sss=millisec. It "wraps" after 49.710 days.
-
-Error 161 occurred at disk power-on lifetime: 2752 hours (114 days + 16 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 46 c2 a7 02 e0  Error: UNC 70 sectors at LBA = 0x0002a7c2 = 174018
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 46 c2 a7 02 e0 00  23d+03:19:20.800  READ DMA EXT
-  25 00 48 c0 a7 02 e0 00  23d+03:19:16.000  READ DMA EXT
-  25 00 1c a4 a7 02 e0 00  23d+03:19:15.200  READ DMA EXT
-  25 00 1e a2 a7 02 e0 00  23d+03:19:10.400  READ DMA EXT
-  25 00 20 a0 a7 02 e0 00  23d+03:19:02.200  READ DMA EXT
-
-Error 160 occurred at disk power-on lifetime: 2752 hours (114 days + 16 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 47 c1 a7 02 e0  Error: UNC 71 sectors at LBA = 0x0002a7c1 = 174017
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 48 c0 a7 02 e0 00  23d+03:19:16.000  READ DMA EXT
-  25 00 1c a4 a7 02 e0 00  23d+03:19:15.200  READ DMA EXT
-  25 00 1e a2 a7 02 e0 00  23d+03:19:10.400  READ DMA EXT
-  25 00 20 a0 a7 02 e0 00  23d+03:19:02.200  READ DMA EXT
-  25 00 22 9e a7 02 e0 00  23d+03:18:57.400  READ DMA EXT
-
-Error 159 occurred at disk power-on lifetime: 2752 hours (114 days + 16 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 02 be a7 02 e0  Error: UNC 2 sectors at LBA = 0x0002a7be = 174014
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 1e a2 a7 02 e0 00  23d+03:19:10.400  READ DMA EXT
-  25 00 20 a0 a7 02 e0 00  23d+03:19:02.200  READ DMA EXT
-  25 00 22 9e a7 02 e0 00  23d+03:18:57.400  READ DMA EXT
-  25 00 24 9c a7 02 e0 00  23d+03:18:52.400  READ DMA EXT
-  25 00 26 9a a7 02 e0 00  23d+03:18:40.200  READ DMA EXT
-
-Error 158 occurred at disk power-on lifetime: 2752 hours (114 days + 16 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 02 be a7 02 e0  Error: UNC 2 sectors at LBA = 0x0002a7be = 174014
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 20 a0 a7 02 e0 00  23d+03:19:02.200  READ DMA EXT
-  25 00 22 9e a7 02 e0 00  23d+03:18:57.400  READ DMA EXT
-  25 00 24 9c a7 02 e0 00  23d+03:18:52.400  READ DMA EXT
-  25 00 26 9a a7 02 e0 00  23d+03:18:40.200  READ DMA EXT
-  25 00 28 98 a7 02 e0 00  23d+03:18:32.100  READ DMA EXT
-
-Error 157 occurred at disk power-on lifetime: 2752 hours (114 days + 16 hours)
-  When the command that caused the error occurred, the device was active or idle.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 03 bd a7 02 e0  Error: UNC 3 sectors at LBA = 0x0002a7bd = 174013
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Powered_Up_Time  Command/Feature_Name
-  -- -- -- -- -- -- -- --  ----------------  --------------------
-  25 00 22 9e a7 02 e0 00  23d+03:18:57.400  READ DMA EXT
-  25 00 24 9c a7 02 e0 00  23d+03:18:52.400  READ DMA EXT
-  25 00 26 9a a7 02 e0 00  23d+03:18:40.200  READ DMA EXT
-  25 00 28 98 a7 02 e0 00  23d+03:18:32.100  READ DMA EXT
-  25 00 2a 96 a7 02 e0 00  23d+03:18:26.400  READ DMA EXT
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended offline    Completed: read failure       90%      2692         173893
-# 2  Short offline       Completed: read failure       10%      2654         173911
-# 3  Extended offline    Completed: read failure       90%      2524         174132
-# 4  Extended offline    Completed without error       00%      2358         -
-# 5  Extended offline    Completed without error       00%      2192         -
-# 6  Extended offline    Completed without error       00%      2023         -
-# 7  Extended offline    Completed without error       00%      1857         -
-# 8  Extended offline    Completed without error       00%      1689         -
-# 9  Extended offline    Completed without error       00%      1521         -
-#10  Extended offline    Completed without error       00%      1355         -
-#11  Extended offline    Completed without error       00%      1187         -
-#12  Extended offline    Completed without error       00%      1020         -
-#13  Extended offline    Completed without error       00%       854         -
-#14  Extended offline    Completed without error       00%       685         -
-#15  Extended offline    Completed without error       00%       517         -
-#16  Extended offline    Completed without error       00%       349         -
-#17  Extended offline    Completed without error       00%       181         -
-#18  Extended offline    Completed without error       00%        13         -
-#19  Extended offline    Completed without error       00%         4         -
-
-Device does not support Selective Self Tests/Logging
diff --git a/www/examples/IC35L120AVVA07-0-0.txt b/www/examples/IC35L120AVVA07-0-0.txt
deleted file mode 100644
index 57926ccfba480e32daeec54bd0011e23ffdfc5e3..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVVA07-0-0.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVVA07-0                        
-Serial Number:    VNC605A6GG8W8A
-Firmware Version: VA6OA52A
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (3399) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  57) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   060    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   147   147   050    Pre-fail     -       266
-  3 Spin_Up_Time            0x0007   093   093   024    Pre-fail     -       23593335
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age      -       13
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   138   138   020    Pre-fail     -       30
-  9 Power_On_Hours          0x0012   100   100   000    Old_age      -       554
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       13
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       36
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age      -       36
-194 Temperature_Centigrade  0x0002   183   183   000    Old_age      -       30 (Lifetime Min/Max 23/39)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%       492         
-# 2  Short off-line      Completed                     00%       296         
-# 3  Extended off-line   Completed                     00%       169         
-# 4  Short off-line      Completed                     00%       168         
diff --git a/www/examples/IC35L120AVVA07-0-1.txt b/www/examples/IC35L120AVVA07-0-1.txt
deleted file mode 100644
index 992a620cec64e49651e672bbf8da46d9f6a57e77..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVVA07-0-1.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVVA07-0                        
-Serial Number:    VNC605A6GEWZDA
-Firmware Version: VA6OA52A
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (3399) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  57) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   060    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0007   098   098   024    Pre-fail     -       22348126
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age      -       13
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   020    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   100   100   000    Old_age      -       554
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       13
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       36
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age      -       36
-194 Temperature_Centigrade  0x0002   189   189   000    Old_age      -       29 (Lifetime Min/Max 23/36)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%       492         
-# 2  Extended off-line   Completed                     00%       169         
diff --git a/www/examples/MAXTOR-0.txt b/www/examples/MAXTOR-0.txt
deleted file mode 100644
index 13e0eb28e95d5c7d703ac975814277c44d1c525c..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-0.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674205306226        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x02)	Offline data collection activity 
-					completed without error.
-Self-test execution status:      ( 112)	The previous self-test completed having
-					the read element of the test failed.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   077   077   020    Pre-fail     -       2909
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       29
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       1
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   097   097   001    Old_age      -       1992
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       29
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   093   090   042    Old_age      -       19
-195 Hardware_ECC_Recovered  0x001a   100   006   000    Old_age      -       7683906
-196 Reallocated_Event_Count 0x0010   099   099   020    Old_age      -       1
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       1
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   198   198   000    Old_age      -       2
-
-SMART Error Log Version: 1
-ATA Error Count: 11 (device log contains only the most recent five errors)
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:02 SN:41 CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   02   41   2d   70    e8   c4     90.713
- 70   08   04   3f   2d   70    e8   c4     86.648
- 70   08   06   3d   2d   70    e8   c4     82.584
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
-
-Error 2 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:04 SN:3f CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   04   3f   2d   70    e8   c4     86.648
- 70   08   06   3d   2d   70    e8   c4     82.584
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
- 28   08   08   4b   2c   28    e8   c5     78.339
-
-Error 3 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:06 SN:3d CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   06   3d   2d   70    e8   c4     82.584
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
- 28   08   08   4b   2c   28    e8   c5     78.339
- 28   08   08   0b   2c   28    e8   c5     78.338
-
-Error 4 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:08 SN:3b CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
- 28   08   08   4b   2c   28    e8   c5     78.339
- 28   08   08   0b   2c   28    e8   c5     78.338
- 28   08   08   cb   2b   28    e8   c5     78.337
-
-Error 5 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:66 SN:41 CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   66   41   2d   70    e8   c4     69.020
- 70   08   68   3f   2d   70    e8   c4     64.956
- 70   08   6a   3d   2d   70    e8   c4     60.891
- 70   08   6c   3b   2d   70    e8   c4     56.826
- 70   08   fe   a9   2c   70    e8   c4     52.713
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed: read failure       90%      1965         0x08702f11
-# 2  Short off-line      Completed                     00%      1800         
-# 3  Short off-line      Completed                     00%      1778         
-# 4  Short off-line      Completed                     00%      1777         
diff --git a/www/examples/MAXTOR-1.txt b/www/examples/MAXTOR-1.txt
deleted file mode 100644
index b1ed8ace35f6f00813087682bb8b1d9177b3ad2f..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-1.txt
+++ /dev/null
@@ -1,143 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674119123435        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x04)	Offline data collection activity was 
-					suspended by an interrupting command from host.
-Self-test execution status:      (  89)	The previous self-test completed having
-					the electrical element of the test
-					failed.
-Total time to complete off-line 
-data collection: 		 (2536) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   074   074   020    Pre-fail     -       3294
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       32
-  5 Reallocated_Sector_Ct   0x0033   001   001   020    Pre-fail FAILING_NOW 499
-  7 Seek_Error_Rate         0x000b   100   001   023    Pre-fail In_the_past 0
-  9 Power_On_Hours          0x0012   086   086   001    Old_age      -       9812
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       32
- 13 Read_Soft_Error_Rate    0x000b   100   001   023    Pre-fail In_the_past 0
-194 Temperature_Centigrade  0x0022   091   086   042    Old_age      -       24
-195 Hardware_ECC_Recovered  0x001a   006   004   000    Old_age      -       417912090
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   033   032   020    Old_age      -       338
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 20255 (device log contains only the most recent five errors)
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:60 SN:b8 CL:c6 CH:02 D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 02   05   60   b8   c6   02    e5   c4     474.857
- 02   05   f8   20   c6   02    e5   c4     470.748
- 02   05   08   18   c6   02    e5   c4     470.746
- 00   00   f8   20   c5   02    e5   c4     470.732
- 00   00   08   18   c5   02    e5   c4     470.730
-
-Error 2 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:68 SN:b0 CL:c6 CH:02 D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 02   05   f8   20   c6   02    e5   c4     470.748
- 02   05   08   18   c6   02    e5   c4     470.746
- 00   00   f8   20   c5   02    e5   c4     470.732
- 00   00   08   18   c5   02    e5   c4     470.730
- 02   05   f8   20   c4   02    e5   c4     470.717
-
-Error 3 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:08 SN:c0 CL:3e CH:0e D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   05   08   c0   3e   0e    e5   c4     181.677
- d0   04   08   b0   67   d0    e4   c5     181.651
- 0e   05   08   a0   45   0e    e5   c4     181.646
- 0e   05   80   20   43   0e    e5   c4     181.635
- 0e   05   80   20   41   0e    e5   c4     181.622
-
-Error 4 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:60 SN:c0 CL:3e CH:0e D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   05   80   a0   3e   0e    e5   c4     172.530
- 0e   05   80   20   3d   0e    e5   c4     172.335
- 0e   05   80   20   3c   0e    e5   c4     164.744
- 0e   05   10   10   3b   0e    e5   c4     164.736
- 0e   05   f8   18   3a   0e    e5   c4     157.202
-
-Error 5 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:c0 SN:18 CL:04 CH:d3 D/H:e4 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- d3   04   c0   18   04   d3    e4   c4     502.837
- d3   04   f8   e0   03   d3    e4   c4     498.739
- d3   04   f8   e8   02   d3    e4   c4     498.716
- 55   01   c8   90   70   55    e1   c4     498.705
- 55   01   38   48   70   55    e1   c4     498.680
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed: electrical failure 90%      9786         
-# 2  Extended captive    Completed: servo/seek failure 90%      9676         0x04b7ed3d
-# 3  Extended captive    Completed                     00%      9575         
-# 4  Extended off-line   Completed                     00%      9432         
-# 5  Extended off-line   Completed                     00%      9415         
diff --git a/www/examples/MAXTOR-10.txt b/www/examples/MAXTOR-10.txt
deleted file mode 100644
index adb8beb9e75050ae872432eac6085f2878023613..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-10.txt
+++ /dev/null
@@ -1,188 +0,0 @@
-smartctl version 5.22 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4
-Serial Number:    674119014987
-Firmware Version: A08.1500
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Mon Oct 27 14:30:17 2003 CST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Offline data collection status:  (0x80)	Offline data collection activity was
-					never started.
-					Auto Offline Data Collection: Enabled.
-Self-test execution status:      ( 112)	The previous self-test completed having
-					the read element of the test failed.
-Total time to complete Offline 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Auto Offline data collection on/off support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0027   075   074   020    Pre-fail  Always       -       3135
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age   Always       -       54
-  5 Reallocated_Sector_Ct   0x0033   098   097   020    Pre-fail  Always       -       14
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail  Always       -       0
-  9 Power_On_Hours          0x0012   072   072   001    Old_age   Always       -       18875
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age   Always       -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail  Always       -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age   Always       -       53
- 13 Read_Soft_Error_Rate    0x000b   100   085   023    Pre-fail  Always       -       0
-194 Temperature_Celsius     0x0022   093   088   042    Old_age   Always       -       20
-195 Hardware_ECC_Recovered  0x001a   028   002   000    Old_age   Always       -       1472864733
-196 Reallocated_Event_Count 0x0010   100   099   020    Old_age   Offline      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age   Always       -       2
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age   Always       -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 28 (device log contains only the most recent five errors)
-	CR = Command Register [HEX]
-	FR = Features Register [HEX]
-	SC = Sector Count Register [HEX]
-	SN = Sector Number Register [HEX]
-	CL = Cylinder Low Register [HEX]
-	CH = Cylinder High Register [HEX]
-	DH = Device/Head Register [HEX]
-	DC = Device Command Register [HEX]
-	ER = Error register [HEX]
-	ST = Status register [HEX]
-Timestamp = decimal seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 28 occurred at disk power-on lifetime: 18785 hours
-  When the command that caused the error occurred, the device was in an unknown state.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 d1 38 ce 8f 40 e0  Error: UNC
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 38 ce 8f 40 e0 40     315.769  READ DMA
-  c8 00 40 c6 8f 40 e0 40     311.634  READ DMA
-  b0 00 01 01 4f c2 e0 1f     284.485  [Reserved SMART command]
-  b0 00 01 06 4f c2 e0 34     284.470  [Reserved SMART command]
-  b0 00 01 00 4f c2 e0 34     284.399  [Reserved SMART command]
-
-Error 27 occurred at disk power-on lifetime: 18785 hours
-  When the command that caused the error occurred, the device was in an unknown state.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 38 ce 8f 40 e0  Error: UNC
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 40 c6 8f 40 e0 40     311.634  READ DMA
-  b0 00 01 01 4f c2 e0 1f     284.485  [Reserved SMART command]
-  b0 00 01 06 4f c2 e0 34     284.470  [Reserved SMART command]
-  b0 00 01 00 4f c2 e0 34     284.399  [Reserved SMART command]
-  b0 00 00 00 4f c2 00 34     284.328  [Reserved SMART command]
-
-Error 26 occurred at disk power-on lifetime: 18744 hours
-  When the command that caused the error occurred, the device was in an unknown state.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 d1 08 bf 00 30 e0  Error: UNC
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 00 08 bf 00 30 e0 30     134.258  READ DMA
-  c8 00 08 cf 3d 34 e0 34     134.247  READ DMA
-  c8 00 08 af 00 34 e0 34     134.215  READ DMA
-  c8 00 28 6f 3e 28 e0 28     134.213  READ DMA
-  c8 00 08 67 3e 28 e0 28     134.201  READ DMA
-
-Error 25 occurred at disk power-on lifetime: 18619 hours
-  When the command that caused the error occurred, the device was in an unknown state.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 07 89 67 10 e3  Error: UNC
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 03 08 88 67 10 e3 10      54.493  READ DMA
-  c8 03 08 88 69 08 e3 08      54.483  READ DMA
-  c8 03 08 88 67 08 e3 08      54.471  READ DMA
-  c8 02 08 88 69 ec e2 ec      54.464  READ DMA
-  c8 02 08 88 67 ec e2 ec      54.439  READ DMA
-
-Error 24 occurred at disk power-on lifetime: 18619 hours
-  When the command that caused the error occurred, the device was in an unknown state.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 59 06 8a 67 0c e2  Error: UNC
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  c8 02 08 88 67 0c e2 0c      49.281  READ DMA
-  c8 02 08 88 69 08 e2 08      49.270  READ DMA
-  c8 02 08 88 69 04 e2 04      49.259  READ DMA
-  c8 02 08 88 69 00 e2 00      49.257  READ DMA
-  c8 02 08 50 5c 00 e2 00      49.254  READ DMA
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended offline    Completed: read failure       80%     18841         0x001f807f
-# 2  Extended offline    Completed: read failure       80%     18673         0x020c678a
-# 3  Extended offline    Completed: read failure       80%     18505         0x020c678a
-# 4  Extended offline    Completed: read failure       80%     18338         0x020c678a
-# 5  Extended offline    Completed: read failure       90%     18229         0x00408f96
-# 6  Extended offline    Completed: read failure       80%     18171         0x02386789
-# 7  Extended offline    Completed without error       00%     18051         -
-# 8  Short offline       Completed without error       00%     18051         -
-# 9  Extended offline    Completed without error       00%     18003         -
-#10  Extended offline    Completed without error       00%     17836         -
-#11  Extended offline    Completed without error       00%     17668         -
-#12  Extended offline    Completed without error       00%     17501         -
-#13  Extended offline    Completed without error       00%     17334         -
-#14  Extended offline    Completed without error       00%     17166         -
-#15  Extended offline    Completed without error       00%     16999         -
-#16  Extended offline    Completed without error       00%     16831         -
-#17  Extended offline    Completed without error       00%     16664         -
-#18  Extended offline    Completed without error       00%     16603         -
-#19  Extended offline    Completed without error       00%     16497         -
-#20  Extended offline    Completed without error       00%     16329         -
-#21  Extended offline    Completed without error       00%     16163         -
-
diff --git a/www/examples/MAXTOR-2.txt b/www/examples/MAXTOR-2.txt
deleted file mode 100644
index 9ff60ffcb3927d55bfa1c40ff5b803b9cc9ced87..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-2.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674119113862        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-See vendor-specific Attribute list for marginal Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x05)	Offline data collection activity was 
-					aborted by an interrupting command from host.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   075   075   020    Pre-fail     -       3249
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       31
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   001   023    Pre-fail In_the_past 0
-  9 Power_On_Hours          0x0012   086   086   001    Old_age      -       9754
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       31
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   035   032   042    Old_age  FAILING_NOW 168
-195 Hardware_ECC_Recovered  0x001a   100   002   000    Old_age      -       880099716
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed                     00%      9691         
-# 2  Short captive       Completed                     00%      9691         
-# 3  Extended captive    Completed                     00%      9618         
-# 4  Extended captive    Interrupted (host reset)      90%      9563         
-# 5  Short captive       Completed                     00%      9563         
-# 6  Short off-line      Completed                     00%      9563         
-# 7  Short captive       Completed                     00%      9545         
-# 8  Extended off-line   Completed                     00%      9541         
-# 9  Short captive       Completed                     00%      9541         
-#10  Extended off-line   Completed                     00%      9537         
-#11  Extended off-line   Completed                     00%      9536         
-#12  Extended off-line   Interrupted (host reset)      90%      9534         
-#13  Extended off-line   Completed                     00%      9517         
-#14  Extended off-line   Completed                     00%      9484         
diff --git a/www/examples/MAXTOR-3.txt b/www/examples/MAXTOR-3.txt
deleted file mode 100644
index 26df69e5977a8b4e46958290ac79b663d7246e4e..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-3.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 6L080J4                          
-Serial Number:    664201100034        
-Firmware Version: A93.0500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  35) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  40) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   069   066   020    Pre-fail     -       3984
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       110
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   099   099   001    Old_age      -       1294
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       110
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   092   087   042    Old_age      -       22
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age      -       1163
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%      1038         
-# 2  Extended off-line   Aborted by host               00%       786         
-# 3  Extended off-line   Aborted by host               00%       786         
diff --git a/www/examples/MAXTOR-4.txt b/www/examples/MAXTOR-4.txt
deleted file mode 100644
index 65ae2850d953448898079f827870b697f26dc07d..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-4.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 6L080J4                          
-Serial Number:    664205757172        
-Firmware Version: A93.0500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x04)	Offline data collection activity was 
-					suspended by an interrupting command from host.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  35) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  40) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   065   064   020    Pre-fail     -       4481
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       81
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   098   098   001    Old_age      -       1767
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       81
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   091   084   042    Old_age      -       24
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age      -       52795
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%      1283         
diff --git a/www/examples/MAXTOR-6.txt b/www/examples/MAXTOR-6.txt
deleted file mode 100644
index fe37f6541cc9b0f487578982b94f6a4931f984fd..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-6.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-# /usr/sbin/smartctl -a -m /dev/hda
-smartctl version 5.0-49 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     Maxtor 4R080J0                          
-Serial Number:    R20BZ3LE            
-Firmware Version: RAMB1TU0
-ATA Version is:   7
-ATA Standard is:  Unrecognized. Minor revision code: 0x1e
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x82)	Offline data collection activity 
-					completed without error.
-Self-test execution status:      (  33)	The self-test routine was interrupted
-					by the host with a hard or soft reset.
-Total time to complete off-line 
-data collection: 		 ( 241) seconds.
-Offline data collection
-capabilities: 			 (0x5b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  41) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  3 Spin_Up_Time            0x0027   252   252   063    Pre-fail     -       1621
-  4 Start_Stop_Count        0x0032   253   253   000    Old_age      -       18
-  5 Reallocated_Sector_Ct   0x0033   253   253   063    Pre-fail     -       0
-  6 Read_Channel_Margin     0x0001   253   253   100    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000a   253   252   000    Old_age      -       0
-  8 Seek_Time_Performance   0x0027   252   244   187    Pre-fail     -       41642
-  9 Power_On_Hours          0x0032   253   253   000    Old_age      -       27 h + 13 m
- 10 Spin_Retry_Count        0x002b   252   252   157    Pre-fail     -       0
- 11 Calibration_Retry_Count 0x002b   253   252   223    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   253   253   000    Old_age      -       24
-192 Power-Off_Retract_Count 0x0032   253   253   000    Old_age      -       0
-193 Load_Cycle_Count        0x0032   253   253   000    Old_age      -       0
-194 Temperature_Celsius     0x0032   253   253   000    Old_age      -       29
-195 Hardware_ECC_Recovered  0x000a   253   252   000    Old_age      -       31004
-196 Reallocated_Event_Count 0x0008   253   253   000    Old_age      -       0
-197 Current_Pending_Sector  0x0008   253   253   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   253   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0008   199   199   000    Old_age      -       0
-200 Multi_Zone_Error_Rate   0x000a   253   252   000    Old_age      -       0
-201 Unknown_Attribute       0x000a   253   252   000    Old_age      -       3
-202 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-203 Unknown_Attribute       0x000b   253   252   180    Pre-fail     -       2
-204 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-205 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-207 Unknown_Attribute       0x002a   252   252   000    Old_age      -       0
-208 Unknown_Attribute       0x002a   252   252   000    Old_age      -       0
-209 Unknown_Attribute       0x0024   079   063   000    Old_age      -       0
- 99 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-100 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-101 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 5
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 5 occurred at disk power-on lifetime: 4 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:01
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   d4   00   82   4f   c2    f0   b0     8907.296
- 08   d4   00   82   4f   c2    f0   b0     6260.832
- 08   d1   01   01   4f   c2    f0   b0     6260.800
- 08   d0   01   00   4f   c2    f0   b0     6260.768
- 08   da   00   00   4f   c2    10   b0     6260.736
-
-Error 4 occurred at disk power-on lifetime: 1 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:01
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   d4   00   82   4f   c2    f0   b0     1944.192
- 08   d4   00   82   4f   c2    f0   b0     1824.240
- 08   d1   01   01   4f   c2    f0   b0     1824.224
- 08   d0   01   00   4f   c2    f0   b0     1824.160
- 08   00   08   3f   00   00    f0   ca     1810.400
-
-Error 3 occurred at disk power-on lifetime: 1 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:01
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   d4   00   82   4f   c2    f0   b0     1456.432
- 08   d4   00   82   4f   c2    f0   b0     1379.456
- 08   d1   01   01   4f   c2    f0   b0     1379.440
- 08   d0   01   00   4f   c2    f0   b0     1379.376
- 08   00   08   f7   01   54    f0   ca     1378.544
-
-Error 2 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 08   d4   00   82   4f   c2    f0   b0     908.320
- 08   d1   01   01   4f   c2    f0   b0     908.320
- 08   d0   01   00   4f   c2    f0   b0     908.272
- 08   d4   00   7f   4f   c2    f0   b0     905.696
- 08   d1   01   01   4f   c2    f0   b0     905.664
-
-Error 1 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:50 SN:40 CL:97 CH:03 D/H:10 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    10   ef     137.184
- 00   3d   00   00   00   00    10   c3     137.136
- 00   e4   00   00   00   00    10   c3     137.088
- 00   3d   00   00   00   00    10   c3     137.088
- 00   00   00   00   5e   20    10   70     137.040
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended captive    Interrupted (host reset)      10%         4         
-# 2  Short off-line      Completed                     00%         2         
-# 3  Short captive       Completed                     00%         2         
-# 4  Extended captive    Interrupted (host reset)      40%         1         
-# 5  Extended captive    Interrupted (host reset)      70%         1         
-# 6  Extended captive    Interrupted (host reset)      40%         0         
diff --git a/www/examples/MAXTOR-7.txt b/www/examples/MAXTOR-7.txt
deleted file mode 100644
index 1d3fa00491946ea74388b37962bdac003ee8c829..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-7.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-smartctl version 5.1-4 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674119114160        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Tue May 13 08:59:49 2003 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x82) Offline data collection activity 
-                                        completed without error.
-Self-test execution status:      ( 112) The previous self-test completed having
-                                        the read element of the test failed.
-Total time to complete off-line 
-data collection:                 (  44) seconds.
-Offline data collection
-capabilities:                    (0x1b) SMART execute Offline immediate.
-                                        Automatic timer ON/OFF support.
-                                        Suspend Offline collection upon new
-                                        command.
-                                        Offline surface scan supported.
-                                        Self-test supported.
-SMART capabilities:            (0x0003) Saves SMART data before entering
-                                        power-saving mode.
-                                        Supports SMART auto save timer.
-Error logging capability:        (0x01) Error logging supported.
-Short self-test routine 
-recommended polling time:        (   2) minutes.
-Extended self-test routine 
-recommended polling time:        (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   075   075   020    Pre-fail     -       3214
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       58
-  5 Reallocated_Sector_Ct   0x0033   098   098   020    Pre-fail     -       12
-  7 Seek_Error_Rate         0x000b   001   001   023    Pre-fail FAILING_NOW 13
-  9 Power_On_Hours          0x0012   078   078   001    Old_age      -       14851
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   090   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       58
- 13 Read_Soft_Error_Rate    0x000b   100   085   023    Pre-fail     -       0
-194 Temperature_Celsius     0x0022   091   087   042    Old_age      -       24
-195 Hardware_ECC_Recovered  0x001a   004   003   000    Old_age      -       513691822
-196 Reallocated_Event_Count 0x0010   099   099   020    Old_age      -       1
-197 Current_Pending_Sector  0x0032   098   098   020    Old_age      -       12
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 25 (device log contains only the most recent five errors)
-        DCR = Device Control Register
-        FR  = Features Register
-        SC  = Sector Count Register
-        SN  = Sector Number Register
-        CL  = Cylinder Low Register
-        CH  = Cylinder High Register
-        D/H = Device/Head Register
-        CR  = Content written to Command Register
-        ER  = Error register
-        STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 25 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:04 SN:53 CL:1d CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   4f   1d   0c    e0   c8     0.523
- 0c   00   08   47   1d   0c    e0   c8     510.677
- 04   00   08   6f   04   04    e0   ca     510.675
- 04   00   08   4f   1c   04    e0   ca     510.674
- 04   00   08   6f   04   04    e0   ca     510.674
-
-Error 24 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:03 SN:44 CL:1d CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   3f   1d   0c    e0   c8     495.294
- 0c   00   08   37   1d   0c    e0   c8     491.239
- 0c   00   08   2f   1d   0c    e0   c8     488.433
- 14   00   08   17   04   14    e0   ca     488.432
- 0c   00   08   b7   00   0c    e0   ca     488.432
-
-Error 23 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:06 SN:21 CL:18 CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   1f   18   0c    e0   c8     392.659
- 00   00   08   17   18   0c    e0   c8     392.654
- 0c   00   08   0f   18   0c    e0   c8     392.624
- 00   00   08   07   18   0c    e0   c8     392.620
- 00   00   08   ff   17   0c    e0   c8     392.615
-
-Error 22 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:05 SN:b2 CL:16 CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   af   16   0c    e0   c8     385.889
- 04   00   08   6f   04   04    e0   ca     385.886
- 04   00   08   4f   1c   04    e0   ca     385.886
- 04   00   08   6f   04   04    e0   ca     385.886
- 04   00   08   4f   1c   04    e0   ca     385.885
-
-Error 21 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:06 SN:a9 CL:16 CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   a7   16   0c    e0   c8     381.795
- 04   00   08   6f   04   04    e0   ca     381.793
- 04   00   08   4f   1c   04    e0   ca     381.793
- 04   00   08   6f   04   04    e0   ca     381.792
- 04   00   08   4f   1c   04    e0   ca     381.792
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed: read failure       90%     14757         0x000409bb
-# 2  Extended off-line   Completed: read failure       90%     14755         0x000bf956
-# 3  Extended off-line   Completed                     00%     14305         -
-# 4  Extended off-line   Completed                     00%     14100         -
-# 5  Extended off-line   Completed                     00%     13721         -
-# 6  Extended off-line   Completed                     00%     13636         -
-# 7  Extended off-line   Completed                     00%     13233         -
-# 8  Extended off-line   Completed                     00%     13078         -
-# 9  Extended off-line   Completed                     00%     12093         -
-#10  Extended off-line   Completed                     00%     11926         -
-#11  Extended off-line   Completed                     00%     11428         -
-#12  Extended off-line   Completed                     00%     11030         -
-#13  Extended off-line   Completed                     00%     10888         -
-#14  Extended off-line   Completed                     00%     10728         -
-#15  Extended off-line   Completed                     00%     10435         -
-#16  Extended off-line   Completed                     00%     10267         -
-#17  Extended off-line   Completed                     00%     10098         -
-#18  Extended off-line   Completed                     00%      9930         -
-#19  Extended off-line   Completed                     00%      9599         -
diff --git a/www/examples/MAXTOR-8.txt b/www/examples/MAXTOR-8.txt
deleted file mode 100644
index 3ae4d87735563a46d403293ec5ce00b26d6bb3d0..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-8.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-smartctl version 5.1-14 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4
-Serial Number:    674119116076
-Firmware Version: A08.1500
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Tue Jun 17 14:46:37 2003 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x82)	Offline data collection activity was
-					completed without error.
-					Auto Off-line Data Collection: Enabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0027   075   075   020    Pre-fail  Always       -       3249
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age   Always       -       45
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail  Always       -       0
-  7 Seek_Error_Rate         0x000b   100   001   023    Pre-fail  Always   In_the_past 0
-  9 Power_On_Hours          0x0012   082   082   001    Old_age   Always       -       12223
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age   Always       -       0
- 11 Calibration_Retry_Count 0x0013   020   020   020    Pre-fail  Always   FAILING_NOW 8
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age   Always       -       45
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail  Always       -       0
-194 Temperature_Celsius     0x0022   094   088   042    Old_age   Always       -       17
-195 Hardware_ECC_Recovered  0x001a   100   007   000    Old_age   Always       -       494134044
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age   Offline      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age   Always       -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%     11610         -
-# 2  Extended off-line   Completed                     00%     11213         -
-# 3  Extended off-line   Completed                     00%     11072         -
-# 4  Extended off-line   Completed                     00%     10911         -
-# 5  Extended off-line   Completed                     00%     10618         -
-# 6  Extended off-line   Completed                     00%     10450         -
-# 7  Extended off-line   Completed                     00%     10282         -
-# 8  Extended off-line   Completed                     00%     10114         -
-# 9  Extended off-line   Completed                     00%      9783         -
-
diff --git a/www/examples/MAXTOR-9.txt b/www/examples/MAXTOR-9.txt
deleted file mode 100644
index 6a692423d766812c05a4c6f298bda322d780a655..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-9.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-smartctl version 5.1-14 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4
-Serial Number:    674119123112
-Firmware Version: A08.1500
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Tue Aug 19 02:06:11 2003 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x80)	Offline data collection activity was
-					never started.
-					Auto Off-line Data Collection: Enabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0027   075   074   020    Pre-fail  Always       -       3186
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age   Always       -       68
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail  Always       -       0
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail  Always       -       0
-  9 Power_On_Hours          0x0012   074   074   001    Old_age   Always       -       17202
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age   Always       -       0
- 11 Calibration_Retry_Count 0x0013   010   010   020    Pre-fail  Always   FAILING_NOW 9
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age   Always       -       68
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail  Always       -       0
-194 Temperature_Celsius     0x0022   092   087   042    Old_age   Always       -       22
-195 Hardware_ECC_Recovered  0x001a   018   003   000    Old_age   Always       -       1082933060
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age   Offline      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age   Always       -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%     17157         -
-# 2  Extended off-line   Completed                     00%     16990         -
-# 3  Extended off-line   Completed                     00%     16823         -
-# 4  Extended off-line   Completed                     00%     16657         -
-# 5  Extended off-line   Completed                     00%     16598         -
-# 6  Extended off-line   Completed                     00%     16490         -
-# 7  Extended off-line   Completed                     00%     16323         -
-# 8  Extended off-line   Completed                     00%     16157         -
-# 9  Extended off-line   Completed                     00%     15991         -
-#10  Extended off-line   Completed                     00%     15696         -
-#11  Extended off-line   Completed                     00%     15614         -
-#12  Extended off-line   Completed                     00%     15241         -
-#13  Extended off-line   Completed                     00%     15026         -
-#14  Extended off-line   Completed                     00%     14785         -
-#15  Extended off-line   Completed                     00%     14334         -
-#16  Extended off-line   Completed                     00%     14129         -
-#17  Extended off-line   Completed                     00%     13750         -
-#18  Extended off-line   Completed                     00%     13665         -
-#19  Extended off-line   Completed                     00%     13262         -
-#20  Extended off-line   Completed                     00%     13108         -
-#21  Extended off-line   Completed                     00%     12125         -
-
diff --git a/www/examples/Maxtor-5.txt b/www/examples/Maxtor-5.txt
deleted file mode 100644
index 3bb171eb6fd032d5ad56dea9925c85bec295c545..0000000000000000000000000000000000000000
--- a/www/examples/Maxtor-5.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-smartctl version 5.0-36 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     Maxtor 98196H8                          
-Serial Number:    V80HV6NC            
-Firmware Version: ZAH814Y0
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 0
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  30) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  60) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000a   253   252   000    Old_age      -       26
-  3 Spin_Up_Time            0x0027   208   206   063    Pre-fail     -       11285
-  4 Start_Stop_Count        0x0032   253   253   000    Old_age      -       62
-  5 Reallocated_Sector_Ct   0x0033   253   253   063    Pre-fail     -       0
-  6 Read_Channel_Margin     0x0001   253   253   100    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000a   253   252   000    Old_age      -       0
-  8 Seek_Time_Performance   0x0027   249   244   187    Pre-fail     -       50271
-  9 Power_On_Hours          0x0032   236   236   000    Old_age      -       32671
- 10 Spin_Retry_Count        0x002b   253   252   223    Pre-fail     -       0
- 11 Calibration_Retry_Count 0x002b   253   252   223    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   253   253   000    Old_age      -       67
-196 Reallocated_Event_Count 0x0008   253   253   000    Old_age      -       0
-197 Current_Pending_Sector  0x0008   253   253   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   253   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0008   199   199   000    Old_age      -       0
-200 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-201 Unknown_Attribute       0x000a   253   252   000    Old_age      -       1
-202 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-203 Unknown_Attribute       0x000b   253   252   180    Pre-fail     -       2
-204 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-205 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-207 Unknown_Attribute       0x002a   253   252   000    Old_age      -       0
-208 Unknown_Attribute       0x002a   253   252   000    Old_age      -       0
-209 Unknown_Attribute       0x0024   253   253   000    Old_age      -       0
- 96 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
- 97 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
- 98 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
- 99 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-100 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-101 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 3
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:40 SN:42 CL:97 CH:23 D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    00   ef     137.440
- 00   d9   00   00   4f   c2    00   b0     137.328
- 00   da   00   00   4f   c2    00   b0     137.232
- 00   d8   00   00   4f   c2    00   b0     137.152
- 00   db   00   00   4f   c2    00   b0     136.976
-
-Error 2 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:40 SN:40 CL:97 CH:23 D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    00   ef     342.432
- 00   e4   00   00   00   00    00   c3     342.368
- 00   d0   00   00   0a   00    00   c3     342.368
- 00   fe   00   00   00   00    00   ef     342.304
- 00   3d   00   00   00   00    00   c3     342.256
-
-Error 3 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:40 SN:40 CL:97 CH:03 D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    00   ef     342.304
- 00   3d   00   00   00   00    00   c3     342.256
- 00   e4   00   00   00   00    00   c3     342.192
- 00   3d   00   00   00   00    00   c3     342.192
- 00   00   01   01   00   00    00   ec     342.144
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed                     00%      5255         
diff --git a/www/examples/TOSHIBA-0.txt b/www/examples/TOSHIBA-0.txt
deleted file mode 100644
index 965e55d99af8af42a5d6592c3159dd9fbb70312a..0000000000000000000000000000000000000000
--- a/www/examples/TOSHIBA-0.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-smartctl version 5.0-31 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     TOSHIBA MK2018GAS                       
-Serial Number:    X22F7553T           
-Firmware Version: Q2.03 D 
-ATA Version is:   5
-ATA Standard is:  Unrecognized. Minor revision code: 0x00
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 ( 212) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  23) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   050    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   100   100   001    Pre-fail     -       910
-  4 Start_Stop_Count        0x0032   100   100   000    Old_age      -       18
-  5 Reallocated_Sector_Ct   0x0033   100   100   050    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   050    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   050    Pre-fail     -       0
-  9 Power_On_Hours          0x0032   100   100   000    Old_age      -       9
- 10 Spin_Retry_Count        0x0033   100   100   030    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       18
-192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age      -       6
-193 Load_Cycle_Count        0x0032   100   100   000    Old_age      -       437
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0030   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age      -       0
-220 Disk_Shift              0x0002   100   100   000    Old_age      -       4250
-222 Loaded_Hours            0x0032   100   100   000    Old_age      -       4
-223 Load_Retry_Count        0x0032   100   100   000    Old_age      -       0
-224 Load_Friction           0x0022   100   100   000    Old_age      -       0
-226 Load-in_Time            0x0026   100   100   000    Old_age      -       590
-240 Unknown_Attribute       0x0001   100   100   001    Pre-fail     -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%         4         
-# 2  Short captive       Completed                     00%         0         
-# 3  Short off-line      Completed                     00%         0         
diff --git a/www/examples/TOSHIBA-MK6021GAS.txt b/www/examples/TOSHIBA-MK6021GAS.txt
deleted file mode 100644
index 776cb3dcee4f794a875c763556a27b001893c597..0000000000000000000000000000000000000000
--- a/www/examples/TOSHIBA-MK6021GAS.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-smartctl version 5.1-7 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     TOSHIBA MK6021GAS                       
-Serial Number:    Y2MJ1530T           
-Firmware Version: GA023A  
-ATA Version is:   5
-ATA Standard is:  Unrecognized. Minor revision code: 0x00
-Local Time is:    Mon Feb 17 09:37:27 2003 CST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 ( 587) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  65) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   050    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   100   100   001    Pre-fail     -       1267
-  4 Start_Stop_Count        0x0032   100   100   000    Old_age      -       18
-  5 Reallocated_Sector_Ct   0x0033   100   100   050    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   050    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   050    Pre-fail     -       0
-  9 Power_On_Hours          0x0032   100   100   000    Old_age      -       39
- 10 Spin_Retry_Count        0x0033   100   100   030    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       16
-192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age      -       1
-193 Load_Cycle_Count        0x0032   100   100   000    Old_age      -       460
-194 Temperature_Celsius     0x0022   100   100   000    Old_age      -       40 (Lifetime Min/Max 17/51)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0030   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age      -       0
-220 Disk_Shift              0x0002   100   100   000    Old_age      -       8332
-222 Loaded_Hours            0x0032   100   100   000    Old_age      -       30
-223 Load_Retry_Count        0x0032   100   100   000    Old_age      -       0
-224 Load_Friction           0x0022   100   100   000    Old_age      -       0
-226 Load-in_Time            0x0026   100   100   000    Old_age      -       159
-240 Head flying hours       0x0001   100   100   001    Pre-fail     -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%         4         -
-
diff --git a/www/examples/WD2500JB.txt b/www/examples/WD2500JB.txt
deleted file mode 100644
index 04e963a8b2bbeff348eb643fcb2e4748c210356f..0000000000000000000000000000000000000000
--- a/www/examples/WD2500JB.txt
+++ /dev/null
@@ -1,192 +0,0 @@
-smartctl version 5.30 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     WDC WD2500JB-32EVA0
-Serial Number:    WD-WMAEH1156826
-Firmware Version: 15.05R15
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   6
-ATA Standard is:  Exact ATA specification draft version not indicated
-Local Time is:    Fri Jun 25 08:14:16 2004 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Offline data collection status:  (0x84)	Offline data collection activity was
-					suspended by an interrupting command from host.
-					Auto Offline Data Collection: Enabled.
-Self-test execution status:      (  73)	The previous self-test completed having
-					a test element that failed and the test
-					element that failed is not known.
-Total time to complete Offline 
-data collection: 		 (7608) seconds.
-Offline data collection
-capabilities: 			 (0x7b) SMART execute Offline immediate.
-					Auto Offline data collection on/off support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					Conveyance Self-test supported.
-					Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine
-recommended polling time: 	 (  95) minutes.
-Conveyance self-test routine
-recommended polling time: 	 (   5) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   001   001   051    Pre-fail  Always   FAILING_NOW 2777
-  3 Spin_Up_Time            0x0007   125   120   021    Pre-fail  Always       -       4283
-  4 Start_Stop_Count        0x0032   100   100   040    Old_age   Always       -       133
-  5 Reallocated_Sector_Ct   0x0033   199   199   140    Pre-fail  Always       -       1
-  7 Seek_Error_Rate         0x000b   200   200   051    Pre-fail  Always       -       0
-  9 Power_On_Hours          0x0032   092   092   000    Old_age   Always       -       6545
- 10 Spin_Retry_Count        0x0013   100   100   051    Pre-fail  Always       -       0
- 11 Calibration_Retry_Count 0x0013   100   100   051    Pre-fail  Always       -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       133
-194 Temperature_Celsius     0x0022   128   253   000    Old_age   Always       -       22
-196 Reallocated_Event_Count 0x0032   199   199   000    Old_age   Always       -       1
-197 Current_Pending_Sector  0x0012   200   200   000    Old_age   Always       -       13
-198 Offline_Uncorrectable   0x0012   200   200   000    Old_age   Always       -       0
-199 UDMA_CRC_Error_Count    0x000a   200   253   000    Old_age   Always       -       1
-200 Multi_Zone_Error_Rate   0x0009   200   155   051    Pre-fail  Offline      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 50 (device log contains only the most recent five errors)
-	CR = Command Register [HEX]
-	FR = Features Register [HEX]
-	SC = Sector Count Register [HEX]
-	SN = Sector Number Register [HEX]
-	CL = Cylinder Low Register [HEX]
-	CH = Cylinder High Register [HEX]
-	DH = Device/Head Register [HEX]
-	DC = Device Command Register [HEX]
-	ER = Error register [HEX]
-	ST = Status register [HEX]
-Timestamp = decimal seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 50 occurred at disk power-on lifetime: 1082 hours
-  When the command that caused the error occurred, the device was doing SMART Offline or Self-test.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 07 82 a9 ee e0  Error: 
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  00 00 25 00 00 07 00 00 2825901.100  NOP [Abort queued commands]
-  03 00 82 00 00 5f 67 00 2825901.100  CFA REQUEST EXTENDED ERROR CODE
-  00 00 25 00 00 01 00 00 2825901.100  NOP [Abort queued commands]
-  00 00 25 00 00 08 00 00 2825901.100  NOP [Abort queued commands]
-  12 00 ee 00 00 5f a9 00 2825901.100  RECALIBRATE [RET-4]
-
-Error 49 occurred at disk power-on lifetime: 1082 hours
-  When the command that caused the error occurred, the device was doing SMART Offline or Self-test.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 07 82 a9 ee e0  Error: 
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  00 00 25 00 00 07 00 00 2825899.350  NOP [Abort queued commands]
-  12 00 ee 00 00 7f a9 00 2825899.350  RECALIBRATE [RET-4]
-  00 00 25 00 00 08 00 00 2825899.350  NOP [Abort queued commands]
-  00 00 25 00 00 08 00 00 2825899.350  NOP [Abort queued commands]
-  12 00 ee 00 00 5f a9 00 2825899.350  RECALIBRATE [RET-4]
-
-Error 48 occurred at disk power-on lifetime: 1082 hours
-  When the command that caused the error occurred, the device was doing SMART Offline or Self-test.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 08 17 a9 ee e0  Error: 
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  00 00 25 00 00 08 00 00 2825880.900  NOP [Abort queued commands]
-  00 00 d6 00 00 77 ad 00 2825880.900  NOP [Abort queued commands]
-  00 00 25 00 00 08 00 00 2825880.900  NOP [Abort queued commands]
-  00 00 d0 00 00 5f 5c 00 2825880.900  NOP [Abort queued commands]
-  00 00 35 00 00 08 00 00 2825880.900  NOP [Abort queued commands]
-
-Error 47 occurred at disk power-on lifetime: 1082 hours
-  When the command that caused the error occurred, the device was doing SMART Offline or Self-test.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 08 17 a9 ee e0  Error: 
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  00 00 25 00 00 08 00 00 2825879.000  NOP [Abort queued commands]
-  00 00 d6 00 00 77 ad 00 2825879.000  NOP [Abort queued commands]
-  00 00 35 00 00 08 00 00 2825879.000  NOP [Abort queued commands]
-  00 00 35 00 00 08 00 00 2825879.000  NOP [Abort queued commands]
-  06 00 8a 00 00 4f 3b 00 2825879.000  [RESERVED]
-
-Error 46 occurred at disk power-on lifetime: 1082 hours
-  When the command that caused the error occurred, the device was doing SMART Offline or Self-test.
-
-  After command completion occurred, registers were:
-  ER ST SC SN CL CH DH
-  -- -- -- -- -- -- --
-  40 51 08 c5 a8 ee e0  Error: 
-
-  Commands leading to the command that caused the error were:
-  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name
-  -- -- -- -- -- -- -- --   ---------  --------------------
-  00 00 25 00 00 08 00 00 2825875.250  NOP [Abort queued commands]
-  00 00 25 00 00 08 00 00 2825875.250  NOP [Abort queued commands]
-  06 00 ba 00 00 f7 66 00 2825875.250  [RESERVED]
-  00 00 35 00 00 10 00 00 2825875.250  NOP [Abort queued commands]
-  06 00 ba 00 00 1f 66 00 2825875.250  [RESERVED]
-
-SMART Self-test log structure revision number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short offline       Completed: unknown failure    90%      1077         0xfff00000
-# 2  Short offline       Completed without error       00%      1053         -
-# 3  Short offline       Completed without error       00%      1030         -
-# 4  Short offline       Completed without error       00%      1007         -
-# 5  Short offline       Completed without error       00%       983         -
-# 6  Extended offline    Completed without error       00%       961         -
-# 7  Short offline       Completed without error       00%       938         -
-# 8  Short offline       Completed without error       00%       914         -
-# 9  Short offline       Completed without error       00%       891         -
-#10  Short offline       Completed without error       00%       868         -
-#11  Short offline       Completed without error       00%       844         -
-#12  Short offline       Completed without error       00%       821         -
-#13  Extended offline    Completed without error       00%       799         -
-#14  Short offline       Completed without error       00%       775         -
-#15  Short offline       Completed without error       00%       752         -
-#16  Short offline       Completed without error       00%       728         -
-#17  Short offline       Completed without error       00%       705         -
-#18  Short offline       Completed without error       00%       682         -
-#19  Short offline       Completed without error       00%       659         -
-#20  Extended offline    Completed without error       00%       637         -
-#21  Short offline       Completed without error       00%       613         -
-
diff --git a/www/examples/atapi_cdrw_smt_a.html b/www/examples/atapi_cdrw_smt_a.html
deleted file mode 100644
index 3e6cea3184ec067f6462097c24d5d00c78abf359..0000000000000000000000000000000000000000
--- a/www/examples/atapi_cdrw_smt_a.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>atapi_cdrw_smt_a</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device: ATAPI&nbsp;&nbsp;&nbsp;
-CD-RW 48X16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: A.RZ</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: CD/DVD</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-17:24:44 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support SMART</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support Error
-Counter logging</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support Self Test
-logging</span>
-</body>
-</html>
diff --git a/www/examples/ativ_36_smt_a.html b/www/examples/ativ_36_smt_a.html
deleted file mode 100644
index c5dc6b2b326e1020fdd4e59f7aac524fb2b4c796..0000000000000000000000000000000000000000
--- a/www/examples/ativ_36_smt_a.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>Atlas IV 36 WLS smartmontools output</title>
-</head>
-<body>
-<span style="font-family: monospace;">Device: QUANTUM&nbsp; ATLAS IV 36
-WLS&nbsp; Version: 0A0A </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: 363930037828 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sat May&nbsp; 3
-21:20:08 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Disabled </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Enabled </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Sense: Ok! </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 35 C </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log: </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-65535&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13</span>
-</body>
-</html>
diff --git a/www/examples/bnch_DLT1.html b/www/examples/bnch_DLT1.html
deleted file mode 100644
index efa6a371318df3b037a982309b3805b82d334752..0000000000000000000000000000000000000000
--- a/www/examples/bnch_DLT1.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>benchmark tape systems DLT1</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-11 Copyright
-(C) 2002-3 Bruce Allen </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is </span><a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/"
- style="font-family: monospace;">http://smartmontools.sourceforge.net/</a><span
- style="font-family: monospace;"> </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Device: BNCHMARK
-DLT1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Version: 391B </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: 0000052369<br>
-Device type: tape</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sun May&nbsp; 4
-11:53:27 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">device is NOT READY (media
-absent, spun down, etc) </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert Supported </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert: Ok! </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log: </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-5.920&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Warning: device does not support
-Self Test Logging</span>
-</body>
-</html>
diff --git a/www/examples/bnch_robot.html b/www/examples/bnch_robot.html
deleted file mode 100644
index 5069b96191292ddc95c1c81cc18c20c685b3d7d5..0000000000000000000000000000000000000000
--- a/www/examples/bnch_robot.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>Benchmark tape systems robot</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-11 Copyright
-(C) 2002-3 Bruce Allen </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is </span><a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/"
- style="font-family: monospace;">http://smartmontools.sourceforge.net/</a><span
- style="font-family: monospace;"> </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Device:
-STK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-L20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Version: 0207 </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: LLC02207812<br>
-Device type: medium changer</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sun May&nbsp; 4
-11:54:39 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Disabled or
-Not Supported </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert Supported </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert Errors (C=Critical,
-W=Warning, I=Informational): </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">[0x02] W: There is a problem with
-the library mechanism. If problem persists, </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;call the library supplier
-help line. </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">[0x0d] W: There is a potential
-problem with the drive ejecting cartridges or </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;with the library mechanism
-picking a cartridge from a slot. </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;1. No action needs to be
-taken at this time. </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;2. If the problem persists,
-call the library supplier help line. </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">[0x0e] W: There is a potential
-problem with the library mechanism placing a </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;cartridge into a slot. </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;1. No action needs to be
-taken at this time. </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;2. If the problem persists,
-call the library supplier help line. </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">No Error counter log to report </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Warning: device does not support
-Self Test Logging</span>
-</body>
-</html>
diff --git a/www/examples/ddrs_39130_smt_a.html b/www/examples/ddrs_39130_smt_a.html
deleted file mode 100644
index e920d71a1f8def59fe8d5930e2431dcfb3109511..0000000000000000000000000000000000000000
--- a/www/examples/ddrs_39130_smt_a.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>ddrs_39130_smt_a.html</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device:
-IBM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-DDRS-39130D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: DC1B</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: QE702689</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: disk</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-16:51:27 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Enabled</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Disabled or
-Not Supported</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: OK</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log:</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">verify:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support Self Test
-logging</span>
-</body>
-</html>
diff --git a/www/examples/hp_c5713a_smt_a.html b/www/examples/hp_c5713a_smt_a.html
deleted file mode 100644
index 4c4beea98338e0e74f5eb441caec307f1bb102e2..0000000000000000000000000000000000000000
--- a/www/examples/hp_c5713a_smt_a.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>HP DDS-4 drive smartmontools output</title>
-</head>
-<body>
-<pre wrap="">smartctl version 5.1-11 Copyright (C) 2002-3 Bruce Allen<br>Home page is <a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/">http://smartmontools.sourceforge.net/</a><br><br>Device: HP       C5713A           Version: H910<br>Local Time is: Thu May  1 23:26:38 2003 EEST<br>Temperature Warning Disabled or Not Supported<br>TapeAlert Supported<br>TapeAlert: Ok!<br><br>Error counter log:<br>          Errors Corrected    Total      Total   Correction     Gigabytes    Total<br>              delay:       [rereads/    errors   algorithm      processed    uncorrected<br>            minor | major  rewrites]  corrected  invocations   [10^9 bytes]  errors<br>read:          0        0         0         2          0          0.000           0<br>write:         0        0         0         0          0          0.000           0<br>Warning: device does not support Self Test Logging</pre>
-</body>
-</html>
diff --git a/www/examples/mam3184_smt_a.html b/www/examples/mam3184_smt_a.html
deleted file mode 100644
index b2896462e43f6c797e65f83180f7db7b6debc1d4..0000000000000000000000000000000000000000
--- a/www/examples/mam3184_smt_a.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title>mam3184_smt_a.html</title>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device: FUJITSU&nbsp;
-MAM3184MP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 0106</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: UKS0P2300CK0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: disk</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-15:35:10 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Enabled</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Enabled</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: OK</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 42 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Manufactured in week 10 of year
-2002</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Current start stop
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 280 times</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Recommended start stop
-count:&nbsp; 10000 times</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log:</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-510.626&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-769.950&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 855</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Self-test log</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Num&nbsp;
-Test&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-segment&nbsp; LifeTime&nbsp; LBA_first_err [SK ASC ASQ]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;
-Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-number&nbsp;&nbsp; (hours)</span><br style="font-family: monospace;">
-<span style="font-family: monospace;"># 1&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-980&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 2&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-788&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 3&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-768&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 4&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-665&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 5&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-635&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 6&nbsp; Foreground
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-635&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 7&nbsp; Foreground
-long&nbsp;&nbsp; Interrupted (bus reset ?)&nbsp;&nbsp; -&nbsp;&nbsp;
-634&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 8&nbsp; Foreground
-long&nbsp;&nbsp; Interrupted (bus reset ?)&nbsp;&nbsp; -&nbsp;&nbsp;
-634&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 9&nbsp; Foreground
-long&nbsp;&nbsp; Interrupted (bus reset ?)&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#10&nbsp; Foreground short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#11&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Long (extended) Self Test
-duration: 837 seconds [13.9 minutes]</span><br>
-<tt><br>
-</tt>
-</body>
-</html>
diff --git a/www/examples/mam3184_smt_health.html b/www/examples/mam3184_smt_health.html
deleted file mode 100644
index 37a41fb18685bd2b8a5c35ece46f9b56664d442a..0000000000000000000000000000000000000000
--- a/www/examples/mam3184_smt_health.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title>mam3184_smt_health.html</title>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: FAILURE
-PREDICTION THRESHOLD EXCEEDED (FALSE) [asc=5d,ascq=ff]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 42 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Manufactured in week 10 of year
-2002</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Current start stop
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 280 times</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Recommended start stop
-count:&nbsp; 10000 times</span><br>
-<tt><br>
-</tt>
-</body>
-</html>
diff --git a/www/examples/map3735_smt_a.html b/www/examples/map3735_smt_a.html
deleted file mode 100644
index 928904f1bd0e06b1a78b85815f93ae34c24bff38..0000000000000000000000000000000000000000
--- a/www/examples/map3735_smt_a.html
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>Fujitsu MAP 3735 smartmontools output</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-10 Copyright
-(C) 2002-3 Bruce Allen </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is </span><a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/"
- style="font-family: monospace;">http://smartmontools.sourceforge.net/</a><span
- style="font-family: monospace;"> </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Device: FUJITSU&nbsp;
-MAP3735NP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 0105 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: UPG0P2A00491 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sat May&nbsp; 3
-21:22:09 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Disabled </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Disabled or
-Not Supported </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Sense: Ok! </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 39 C </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Manufactured in week 40 of year
-2002 </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Current start stop
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14 times </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Recommended start stop
-count:&nbsp; 10000 times </span><br style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log: </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-810.959&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-72.300&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 27 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">No self-tests have been logged </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Long (extended) Self Test
-duration: 2872 seconds [47.9 minutes]</span>
-</body>
-</html>
diff --git a/www/examples/st318451_smt_a.html b/www/examples/st318451_smt_a.html
deleted file mode 100644
index fcbadaa880c2b67ad2e9431b3080bd83bb194176..0000000000000000000000000000000000000000
--- a/www/examples/st318451_smt_a.html
+++ /dev/null
@@ -1,185 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title>st318451_smt_a</title>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device: SEAGATE&nbsp;
-ST318451LW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 0003</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number:
-3CC01TTG000071033QEA</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: disk</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-17:12:14 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Enabled</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Enabled</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: OK</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 34 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log:</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-100.431&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">verify:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Self-test log</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Num&nbsp;
-Test&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-segment&nbsp; LifeTime&nbsp; LBA_first_err [SK ASC ASQ]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;
-Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-number&nbsp;&nbsp; (hours)</span><br style="font-family: monospace;">
-<span style="font-family: monospace;"># 1&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 2&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 3&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 4&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 5&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 6&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 7&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 8&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 9&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#10&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#11&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#12&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#13&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Long (extended) Self Test
-duration: 587 seconds [9.8 minutes]</span><br>
-<tt><br>
-</tt>
-</body>
-</html>
diff --git a/www/index.html b/www/index.html
deleted file mode 100644
index 281ccec9b62ab7261281336d29997b2ee7f3e91d..0000000000000000000000000000000000000000
--- a/www/index.html
+++ /dev/null
@@ -1,1119 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
- <title>smartmontools Home Page (last updated $Date: 2004/08/15 17:24:55 $)</title>
- <link rev="made" href="mailto:smartmontools-support&#64;sourceforge.net" />
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <meta name="description" content="smartmontools Home Page" />
- <meta name="keywords" content="S.M.A.R.T., SMART, FreeBSD, Linux, NetBSD, Solaris, Windows, disk, monitor, monitoring" />
-</head>
-<body>
-
-<!-- $Id: index.html,v 1.171 2004/08/15 17:24:55 ballen4705 Exp $ -->
-
-<div align="center">
-  <img src="smart_logo.gif" border="0" width="105" height="59" alt="SMART LOGO" />
-  <br />
-  <h1><font color="#3333ff">smartmontools Home Page</font></h1>
-</div>
-
-<p>Welcome! This is the home page for the smartmontools package.</p> 
-
-<p>
-<font color="#ff0000">
-NEWS FLASH:<br/> DARWIN support (ATA disks only) was added to
-smartmontools by Geoff Keating on July 16, 2004, and is experimental.
-The code may be downloaded from CVS following the directions below.
-Please report problems or success to the smartmontools-support mailing
-list.
-</font>
-</p>
-
-<p>The smartmontools package contains two utility programs
-(<font color="#3333ff"><b>smartctl</b></font> and
-<font color="#3333ff"><b>smartd</b></font>) to control and monitor storage
-systems using the Self-Monitoring, Analysis and Reporting Technology
-System (SMART) built into most modern ATA and SCSI hard
-disks.&#160; In many cases, these utilities will provide advanced warning
-of disk degradation and failure.</p> 
-
-<p>Smartmontools is derived from the <a
-href="http://sourceforge.net/projects/smartsuite/">smartsuite
-package</a>, and includes support for ATA/ATAPI-3 to -7 disks and SCSI
-disk and tape devices.  It should run on any modern Darwin, Linux, FreeBSD, 
-NetBSD, Solaris, or <a href="#windows">Windows</a> system.</p>
-
-<p>For printing convenience, everything except for the <a
-href="#sampleoutput">example output</a> is on a single page.</p>
-
-<hr size="2" />
-
-<ul>
-<li><a href="http://www.linuxjournal.com/article.php?sid=6983">
-Monitoring Hard Disks with SMART (Linux Journal, January 2004, page 74)</a></li>
-<li><a href="#howtodownload">How to download and install
-smartmontools</a></li>
-<li><a href="#PROBLEMS">Serious Problem Reports (system lockup, etc.)</a></li>
-<li><a href="#FAQ">Frequently Asked Questions</a></li>
-<li><a href="#scsi">SCSI disks and tapes (TapeAlert)</a></li>
-<li><a href="#testinghelp">FireWire, USB, and SATA disks/tapes</a></li>
-<li><a href="#differfromsmartsuite">How does smartmontools differ from
-smartsuite?</a></li>
-<li><a href="#references">Useful references on SMART and ATA/ATAPI-5,
--6, and -7</a></li>
-<li><a href="#sampleoutput">Example output from smartmontools</a>
-<b>smartctl</b> utility</li>
-<li><a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/">CVS
-repository</a> and <a href="http://sourceforge.net/projects/smartmontools/">SourceForge's
-Project Page</a></li>
-<li>Mailing List <a href="http://lists.sourceforge.net/lists/listinfo/smartmontools-support">Information</a>
-and <a href="http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support">Archives</a>
-(Archive has <b>Search Box</b> in top left corner). <a href="#altmail">Alternative</a> (and usually up to date) archives.</li>
-<li>Current <a href="man/smartctl.8.html">smartctl</a>, <a href="man/smartd.8.html">smartd</a>, and <a href="man/smartd.conf.5.html">smartd.conf</a> HTML man pages generated from CVS.</li>
-</ul>
-
-<hr size="2" />
-
-<b><a name="howtodownload"></a>How to download and install
-smartmontools</b>
-
-<p>There are different ways to get and install
-smartmontools.&#160; You can use any of the procedures below
-(the fourth is for Debian Linux only).&#160; Just after "Method 6" below are
-some instructions for trying out smartmontools once you have completed
-the installation. The 
-<b><a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/INSTALL?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">INSTALL</a></b> file contains additional information.
-</p>
-<b>First Method (Linux) - Install from the RPM file</b>
-<ul>
-<li>Download the latest binary RPM file (<tt>*.rpm</tt>) from <a href="http://sourceforge.net/project/showfiles.php?group_id=64297">here</a>.&#160;
-Don't get the SRPM file (<tt>*.src.rpm</tt>).</li>
-<li>Install it using RPM.&#160; <i>You must be root to do this</i>:
-<pre>su root (enter root password)
-rpm -ivh smartmontools-5.1-18.i386.rpm</pre>
-For most users, this is all that is needed.</li>
-<li>If you receive an error message, you have probably previously
-installed the <tt>smartsuite</tt> package, or RedHat's
-<tt>kernel-utils</tt> package, which provide older versions of the
-<tt>smartd</tt> and <tt>smartctl</tt> utilities.&#160; In this case you
-should use the <tt>--nodeps</tt> or <tt>--force</tt> arguments of rpm to
-replace these two utilities:
-<pre>rpm -ivh --nodeps --force smartmontools-5.1-18.i386.rpm</pre></li>
-<li>If you want to remove the package (<tt>rpm -e smartmontools</tt>)
-and your system does not have <tt>chkconfig</tt> installed, you may need
-to use:
-<pre>rpm -e --noscripts smartmontools</pre></li>
-</ul>
-
-<b>Second Method (Linux/Solaris/FreeBSD/NetBSD/Cygwin) - Install from the source tarball</b>
-<ul>
-<li>Download the latest source tarball from <a href="http://sourceforge.net/project/showfiles.php?group_id=64297">here</a>.
-Note: you probably want the most recent release.</li>
-<li>Uncompress the tarball:
-<pre>tar zxvf smartmontools-5.20.tar.gz</pre></li>
-<li>The previous step created a directory called <tt>smartmontools-5.20</tt>
-containing the code.&#160; Go to that directory, build, and install:
-<pre>cd smartmontools-5.20
-./configure
-make
-make install
-</pre></li>
-<li> Note that the <tt>./configure</tt> step above is not possible for releases &lt;=5.1-18, you 
-have to edit the Makefile by hand to change installation paths. For releases &gt;=5.19, <tt>./configure</tt>
-can take optional arguments. These optional arguments are fully explained in the
-<a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/INSTALL?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">INSTALL</a>
-file. The most important one is <tt>--prefix</tt> to change the default installation directories.<p>
-<i>Please note that the default installation location changed in versions &gt;=5.31.</i>
-If you don't pass any arguments to <tt>./configure</tt> all files will reside under
-<i>/usr/local</i> to not interfere with files from your distribution. For more detailed
-information please also refer to the 
-<a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/INSTALL?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">INSTALL</a>
-document.
-</p>
-</li>
-<li>To compile from another directory (avoids overwriting virgin files from the smartmontools package)
-replace <tt>./configure [options]</tt> by:
-<pre>
-mkdir objdir
-cd objdir
-../configure [options]
-</pre></li>
-<li>To install to another destination (useful for testing and to avoid overwriting an existing smartmontools installation)
-replace <tt>make install</tt> by:
-<pre>
-make DESTDIR=/home/myself/smartmontools-test install
-</pre>
-Use a full path: <tt>~/smartmontools-test</tt> won't work.
-</li>
-<li>Unless the destination directory is your home directory (or a location that you have write permission)
-only root can do <tt>make install</tt></li>
-</ul>
-
-<b>Third Method (Darwin/FreeBSD/Linux/NetBSD/Solaris/Cygwin) - Install from the CVS repository</b>
-<ul>
-<li><p>One of the really cool things about CVS is that you can get
-<i>any</i> version of the code you want, from the first release up the
-the most current development version.&#160; And it's trivial, because
-each release is <u>tagged</u> with a name like
-<tt>RELEASE_5_1_18</tt>.&#160; You can see what the different names are
-by looking at the <a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/">
-CVS repository</a>.&#160; You'll see the tag names in the little scroll
-window where it says "Show only files with tag".&#160; All you need to
-do to get the latest development code is
-(but note that the development code may be unstable, and that the
-documentation and code may be inconsistent):</p>
-
-<pre>cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools login (when prompted for a password, just press Enter)
-cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co sm5</pre></li>
-
-<li>To instead get the 5.1-16 release:
-
-<pre>cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co -r RELEASE_5_1_16 sm5</pre></li>
-
-<li><p>This will create a subdirectory called <tt>sm5/</tt> containing the
-code.&#160; Go to that directory, build, and install:</p>
-<pre>cd sm5
-./autogen.sh
-./configure
-make
-make install
-</pre>
-
-<ul>
-<li>See notes under <b>Second method - install from source tarball</b> for different options to <tt>./configure</tt>
-and other useful remarks.</li>
-<li>Skip <tt>./autogen.sh</tt> and <tt>./configure</tt> for tagged releases
-&lt;= 5.1-18 (RELEASE_5_X_Y, where X = 0 or 1 and Y = 0 to 18).</li>
-<li>If you get the current sources (<tt>cvs co</tt> with no arguments or do <tt>cvs up
--A</tt>) then you <i>will</i>  need those two additional steps.</li>
-</ul></li>
-
-<li>To update your sources to the 5.1-18 release:
-<pre>cd sm5
-cvs up -r RELEASE_5_1_18</pre></li>
-
-<li>To update any tagged release to the latest development code:
-
-<pre>cd sm5
-cvs up -A</pre></li>
-</ul>
-
-<b>Fourth Method (Debian Linux) - Install the Debian package</b>
-<ul>
-<li>
-The latest version of the smartmontools package in <i>.deb</i> format is
-available at the  <a href="http://packages.debian.org/unstable/utils/smartmontools.html">Debian smartmontools
-package page</a>.
-This package is for the (unreleased) <a href="http://www.debian.org/releases/">unstable</a>
-distribution.</li>
-<li>If you're running Debian <a
-href="http://www.debian.org/releases/stable/">stable</a> please download the
-package from <a
-href="http://honk.physik.uni-konstanz.de/~agx/linux-i386/debian/smartmontools/">here</a>.</li>
-<li>
-You can then install the package using:
-<pre>
-dpkg -i smartmontools_5.1.18-1.agx0_i386.deb
-</pre>
-But the preferred method is to add the following line to your
-<tt>/etc/apt/sources.list</tt>:
-<pre>deb http://honk.physik.uni-konstanz.de/~agx/linux-i386/debian smartmontools/
-</pre>
-and type <pre>
-apt-get update &amp;&amp; apt-get install smartmontools
-</pre> this will automatically download and install the package.
-</li>
-</ul>
-
-
-<b><a name="CygwinInstall"></a>
-Fifth Method (Windows with <a href="http://www.cygwin.com/">Cygwin</a>
-installed) - Install the Cygwin package
-</b>
-<ul>
-<li>To install it, use Cygwin's
-<a href="http://www.cygwin.com/setup.exe">setup.exe</a>.
-Add smartmontools download directory from any sourceforge mirror
-(<b>http://<i>{belnet,easynews,heanet,switch,...}</i>.dl.sourceforge.net/sourceforge/smartmontools/</b>)
-in <i>Choose Download Site(s)</i>
-and follow as usual (requires Cygwin <b>1.5.7 or greater</b>).
-</li>
-<li><p>If you want to manually install it (not recommended
-because, among others, you lose the ability to update and uninstall it),
-download the latest Cygwin package (<tt>*.cygwin.tar.bz2</tt>) from
-<a href="http://sourceforge.net/project/showfiles.php?group_id=64297">here</a>,
-and type:</p>
-<pre>
-tar jxf smartmontools-5.32-1.cygwin.tar.bz2 -C /
-</pre>
-from a Cygwin shell.
-</li>
-</ul>
-
-<b><a name="WindowsInstall"></a>
-Sixth Method (Windows) - Install the Windows package
-</b>
-<ul>
-<li>Download the latest Windows package (<tt>*.win32.zip</tt>) from
-<a href="http://sourceforge.net/project/showfiles.php?group_id=64297">here</a>.
-</li>
-<li><p>Unzip the files into a directory of your choice.
-A directory in the PATH is recommended for the <tt>*.exe</tt> files.</p>
-</li>
-</ul>
-
-
-<b>After installing it using Method 1, 2, 3, 4 or 5 above, you can read the
-man pages, and try out the commands:</b>
-
-<pre>
-man smartd.conf
-man smartctl
-man smartd
-/usr/sbin/smartctl -s on -o on -S on /dev/hda (only root can do this)
-/usr/sbin/smartctl -a /dev/hda (only root can do this)</pre>
-
-<p>Note that the default location for the manual pages are
-<tt>/usr/share/man/man5</tt> and <tt>/usr/share/man/man8</tt>.&#160; If
-"<tt>man</tt>" doesn't find them, then you may need to add
-<tt>/usr/share/man</tt> to your <tt>MANPATH</tt> environment
-variable.</p>
-
-<p>The Windows package (see Method 6 above) provides preformatted man pages
-in <tt>*.html</tt> and <tt>*.txt</tt> format.</p>
-
-<hr size="2" />
-
-<a name="PROBLEMS"></a><b>Serious Problem Reports</b>
-<p>If a serious problem gets reported to us, it gets added to the <a
-href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/WARNINGS?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">
-WARNINGS</a> file in smartmontools. So far there are only a few problem systems listed.</p>
-
-<hr size="2" />
-
-<a name="FAQ"></a><b>Frequently Asked Questions</b>
-
-<p>If your question is not here, please <a href="mailto:smartmontools-support&#64;lists.sourceforge.net">email
-me</a>.</p>
-
-<ul>
-<li><b>Is the smartmontools File Download/Mail List/Mail Archive/CVS server broken?</b>
-
-<p>SourceForge is a free service, which supports a very large number of
-users and projects. Please check the <a
-href="http://sourceforge.net/docman/display_doc.php?docid=2352&amp;group_id=1">
-SourceForge Site Status Page</a> to see the maintenance schedule and to
-learn if SourceForge is experiencing unscheduled system outages or other
-problems.</p>
-
-<p>
-<a name="altmail"></a>Alternative mailing-list archives are provided by
-<a href="http://gmane.org/find.php?list=smartmontools">Gmane</a> and MARC (<a
-href="http://marc.theaimsgroup.com/?l=smartmontools-support">smartmontools-support</a>
-and <a
-href="http://marc.theaimsgroup.com/?l=smartmontools-database">smartmontools-database</a>).</p>
-
-</li>
-
-<li><b>What do I do if I have problems, or need support?&#160; Suppose
-I want to become a developer, or suggest some new extensions?</b>
-
-<p>First, search the support mailing list archives to see if your
-question has been answered. Instructions are in the following
-paragraph.  If you don't find an answer there, then please send an
-email to the <a
-href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">smartmontools-support
-mailing list</a>.  This is a moderated forum: you are not
-required to subscribe to the list in order to post your question.
-</p>
-
-<p>To search the email archives, first go to the <a
-href="http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support">
-mailing list archive</a>.  In the top left corner you will see a
-search box: use <b>Mailing List</b> as the type of search. This tool
-works very well.</p>
-
-<p>Note that from time to time SourceForge has mailing list problems
-and you'll get a message telling you that <i>Either your mailing list
-name was misspelled or your mailing list has not been archived yet. If
-this list has just been created, please retry in 2-4 hours</i>.  If
-this happens, you'll have to try again later.  Or use <a
-href="#altmail">alternative</a> (and usually up to date) email
-archives.
-</p>
-
-</li>
-
-<li><b>What are the future plans for smartmontools?</b>
-
-<p>My plan is that smartmontools-5.x will support ATA/ATAPI-5
-disks.&#160; Eventually, we'll do smartmontools-6.x to support
-ATA/ATAPI-6 disks, smartmontools-7.x for the ATA/ATAPI-7 standard, and
-so on.&#160; The "x" will denote revision level, as bugs get found and
-fixed, and as enhancements get added.&#160; If it's possible to maintain
-backwards compatibility, that would be nice, but I don't know if it will
-be possible or practical.</p></li>
-
-<li><b>Why are you doing this?</b>
-
-<p>My research group at U. Wisconsin - Milwaukee runs a <a
-href="http://www.lsc-group.phys.uwm.edu/beowulf/medusa/">beowulf
-cluster</a> with 600 ATA-5 and -6 disks (300 IBM and 300
-Maxtor).&#160; We have more than 50 TB of data stored on the
-system.&#160; I also help out with a <a
-href="http://pandora.aei.mpg.de/merlin/"> cluster</a> at the Albert
-Einstein Institute that has 540 IBM ATA-6 disks (65 TB
-total). It's nice to have advanced warning when a disk is going to
-fail.</p></li>
-
-<li><b>Where can I find distribution-specific bug reports?</b>
-<p>
-The smartmontools package supports a number of different operating
-systems. Some of those operating systems are also distributed by
-multiple sources, and some of these maintain a database of bug
-reports.  Here are links:
-</p>
-
-<ul>
-<li><a href="https://bugzilla.redhat.com/bugzilla/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;bug_status=NEEDINFO&amp;bug_status=MODIFIED&amp;bug_status=CLOSED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;value0-0-0=smartctl&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=smartctl&amp;field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=smartctl&amp;field0-0-3=status_whiteboard&amp;type0-0-3=substring&amp;value0-0-3=smartctl&amp;field0-0-4=product&amp;type0-0-4=substring&amp;value0-0-4=smartd&amp;field0-0-5=component&amp;type0-0-5=substring&amp;value0-0-5=smartd&amp;field0-0-6=short_desc&amp;type0-0-6=substring&amp;value0-0-6=smartd&amp;field0-0-7=status_whiteboard&amp;type0-0-7=substring&amp;value0-0-7=smartd&amp;field0-0-8=product&amp;type0-0-8=substring&amp;value0-0-8=smartsuite&amp;field0-0-9=component&amp;type0-0-9=substring&amp;value0-0-9=smartsuite&amp;field0-0-10=short_desc&amp;type0-0-10=substring&amp;value0-0-10=smartsuite&amp;field0-0-11=status_whiteboard&amp;type0-0-11=substring&amp;value0-0-11=smartsuite&amp;field0-0-12=product&amp;type0-0-12=substring&amp;value0-0-12=smartmontools&amp;field0-0-13=component&amp;type0-0-13=substring&amp;value0-0-13=smartmontools&amp;field0-0-14=short_desc&amp;type0-0-14=substring&amp;value0-0-14=smartmontools&amp;field0-0-15=status_whiteboard&amp;type0-0-15=substring&amp;value0-0-15=smartmontools">Redhat/Fedora Bugzilla Database (Linux)</a> </li>
-<li><a href="http://bugs.debian.org/cgi-bin/pkgreport.cgi?which=pkg&amp;data=smartmontools&amp;archive=no">Debian Bug Database (Linux)</a></li>
-<li><a href="http://bugs.gentoo.org/buglist.cgi?bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;field0-0-0=product&amp;type0-0-0=substring&amp;value0-0-0=smartmontools&amp;field0-0-1=component&amp;type0-0-1=substring&amp;value0-0-1=smartmontools&amp;field0-0-2=short_desc&amp;type0-0-2=substring&amp;value0-0-2=smartmontools&amp;field0-0-3=status_whiteboard&amp;type0-0-3=substring&amp;value0-0-3=smartmontools">Gentoo Bug Database (Linux)</a></li>
-<li><a href="http://www.netbsd.org/cgi-bin/query-pr-list.pl?text=smartctl&amp;state=open&amp;state=feedback&amp;state=analyzed&amp;state=suspended">NetBSD smartctl bug database</a></li>
-<li><a href="http://www.netbsd.org/cgi-bin/query-pr-list.pl?text=smartd&amp;state=open&amp;state=feedback&amp;state=analyzed&amp;state=suspended">NetBSD smartd bug database</a></li>
-<li><a href="http://www.netbsd.org/cgi-bin/query-pr-list.pl?text=smartmontools&amp;state=open&amp;state=feedback&amp;state=analyzed&amp;state=suspended">NetBSD smartmontools bug database</a></li>
-</ul>
-<p>
-If you can provide additional distribution or OS-specific bug-database links, please send an email to smartmontools-support.
-</p></li>
-
-<li><b>I see some strange output from smartctl.  What does it mean?</b>
-
-<p>The raw SMART attributes (temperature, power-on lifetime, and so
-on) are stored in vendor-specific structures.&#160; Sometime these are
-strange.&#160; Hitachi disks (at least some of them) store power-on
-lifetime in minutes, rather than hours (see next question below).&#160; IBM disks (at least some
-of them) have three temperatures stored in the raw structure, not just
-one.&#160; And so on.&#160; If you find strange output, or unknown
-attributes, please send an email to <a href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support"> 
-smartmontools-support</a> and we'll help you try and figure it
-out.</p></li>
-
-<li><b>What are the operating system requirements?</b>
-<p>
-Please see the first section of the <a
-href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/INSTALL?view=markup">INSTALL</a>
-file.
-</p>
-</li>
-
-<li><b>What Attributes does smartmontools not yet recognize?</b>
-
-<p>From Maxtor disks (99), (100), and (101).  These are not used by
-Maxtor in SMART revision 5.  They will be used in SMART revision 6,
-but the engineering group has not yet decided what to monitor with
-these Attributes.
-</p>
-</li>
-
-<li><b>My Maxtor/Hitachi/Fujitsu disk is only a few days old, yet smartctl reports its age (Attribute 9) as thousands of hours!</b>
-
-<p>On recent disks, Maxtor has started to use Attribute 9 to
-store the power-on disk lifetime in minutes rather than hours.  In this case, use
-the:<br/>
-<tt>-v 9,minutes</tt><br/>
-option to correctly display hours and minutes.
-</p>
-<p>Some models of Fujitsu disks use Attribute 9 to store
-the power-on disk lifetime in seconds. In that case, use the:<br/>
-<tt>-v 9,seconds</tt><br/>
-option to correctly display hours, minutes and seconds.</p>
-</li>
-
-<li><b>The power-on timer (Attribute 9 raw value) on my Maxtor disk acts strange.</b>
-
-<p>There are three related problems with Maxtor's SMART firmware:
-</p>
-
-<p>
-<b>1 - </b> On some Maxtor disks, the raw value of Attribute 9 (Power
-On Time) is <i>supposed</i> to be minutes. But it advances at an
-unpredictable rate, always more slowly than one count per minute.
-This is because when the disk is in idle mode, the counter stops
-advancing.  This is only supposed to happen in standby mode.  This
-will be corrected in Maxtor product lines released after October 2004.
-</p>
-
-<p>
-<b>2 - </b> In Maxtor disks that use the raw value of Attribute 9 as a
-minutes counter, only two bytes (of the six available) are used to
-store the raw value.  So it resets to zero once every 65536=2^16
-minutes, or about once every 1092 hours. This is fixed in all Maxtor
-disks manufactured after July 2003, where the raw value was extended
-to four bytes.
-</p>
-
-<p>
-<b>3 - </b> In Maxtor disks that use the raw value of Attribute 9 as a
-minutes counter, the hour time-stamps in the self-test and ATA error
-logs are calculated by right shifting 6 bits.  This is equivalent to
-dividing by 64 rather than by 60.  As a result, the hour time stamps
-in these logs advance 7% more slowly than they should.  Thus, if you
-do self-tests once per week at the same time, instead of the
-time-stamps being 168 hours apart, they are 157 hours apart.  This is
-also fixed in all Maxtor disks manufactured after July 2003.
-</p>
-</li>
-
-<li><b>The time stamps in the self-test log of my Western Digital (WD) disk
-don't correspond to the power-on time when the test was run</b>
-
-<p>
-The self-test log timestamps in many WD disks roll back to zero every
-1092 hours (65536 minutes).  This problem is due to a WD firmware bug.
-The power-on lifetime in hours is correctly stored in Attribute
-9. However when the power-on lifetime is calculated for self-test log
-entries, the lifetime in minutes is put into a 16-bit register then
-divided by 60.  The 16-bit register overflows and wraps around every
-1092 hours.
-</p>
-
-<p>For WD drives that exhibit this firmware bug, the relationship between
-Attribute 9's raw value (H) and the time-stamps in the self-test log (h) are given by:<br/>
-Let H = power on hours as shown by Attribute 9 (correct)<br/>
-Let M = 60*H (power on minutes, correct)<br/>
-Let m = M mod 65536 (incorrect value of power on minutes, shown in self-test log)<br/>
-Let h = m/60 (incorrect value of power on hours)
-</p>
-</li>
-
-<li><b>The (normalized) WORST Attribute values of my Western Digital
-(WD) disk are <u>larger</u> than the (normalized) CURRENT Attribute
-values</b>
-<p>Western Digital firmware initializes SMART Attributes 10, 11, and
-199 after either 120 spin-ups or 8 power-on hours.  Until that time,
-they have the uninitialized value 253.
-</p>
-</li>
-
-<li><b>Where can I find manufacturer-specific disk-testing
-utilities?</b>
-
-<p>A good listing of such utilities can be found <a
-href="http://www.benchmarkhq.ru/english.html?/be_hdd2.html">here</a>.
-Unfortunately most of these are for MS operating systems, but most can
-be run from an MS-DOS boot disk. Note: if you do run one of these
-utilities, and it identifies the meanings of any SMART Attributes that
-are not known to smartmontools, please report them to the mailing list
-above.</p>
-
-<p>These utilities have an important role to fill.  If your disk has
-bad sectors (for example, as revealed by running self-tests with
-smartmontools) and the disk is not able to recover the data from those
-sectors, then the disk will <i>not</i> automatically reallocate those
-damaged sectors from its set of spare sectors, because
-forcing the reallocation to take place may entail some loss of data.
-Because the commands that force such reallocation are
-<i>Vendor Specific</i>, most manufactuers provide a utility for this
-purpose. It may cause data loss but can repair damaged sectors (at
-least, until it runs out of replacement sectors).
-</p>
-</li>
-
-<li><b>When I run <tt>smartd</tt>, the SYSLOG <tt>/var/log/messages</tt>
-contains messages like this:</b>
-<pre>smartd: Reading Device /dev/sdv
-modprobe: modprobe: Can't locate module block-major-65</pre>
-
-<p>This is because when <tt>smartd</tt> starts, if there is no
-configuration file, it looks for all ATA and SCSI devices to monitor
-(matching the pattern <tt>/dev/hd[a-t]</tt> or
-<tt>/dev/sd[a-z]</tt>).&#160; The log messages appear because your
-system doesn't have most of these devices.</p>
-
-<p>The solution is simple: use the <tt>smartd</tt> configuration file
-<tt>/etc/smartd.conf</tt> to specify which devices to monitor.</p></li>
-
-<li><b>What's the story on IBM SMART disks?</b>
-
-<p>Apparently some of the older SMART firmware on IBM disks can 
-interfere with the regular operation of the disk.&#160; If you have this
-problem, here are some links:<br/>
-<a href="http://www.geocities.com/dtla_update/">Geocities Site</a>,
-<a href="http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215">IBM Site #1</a>,
-<a href="http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215">IBM Site #2</a><br/>
-to an IBM Firmware Upgrade that fixes the problem.
-</p></li>
-
-<li><b>How can I check that the package hasn't been tampered with?</b>
-
-<p>Since the <tt>smartmontools</tt> utilities run as root, you might
-be concerned about something harmful being embedded within
-them. Starting with release 5.19 of <tt>smartmontools</tt>, the .rpm
-files and tarball have been GPG signed. The tarball's fingerprint is
-given in a file on the release page with a name like
-<tt>smartmontools-5.20.tar.gz.asc</tt>.  Please verify these using
-the <a href="SmartmontoolsSigningKey.txt">Smartmontools GPG Signing
-Key</a>
-</p></li>
-
-<li><b>Is there a bootable standalone CD or floppy that contains smartmontools?</b>
-
-<p>If you have a system that is showing signs of disk trouble (for
-example, it's unbootable and the console is full of disk error
-messages) it can be handy to have a version of smartmontools that can
-be run off of a bootable CD or floppy to examine the disk's SMART data and run
-self-tests.  This is also useful if you want to run Captive Self-Tests
-(the <b><tt>-<font size="+2">C</font></tt></b> option of
-<b><tt>smartctl</tt></b> ) on disks that can not easily be unmounted,
-such as those hosting the Operating System files. Or you can use
-this to run <tt>smartctl</tt> on computers that don't use Linux as the
-day-to-day operating system.</p>
-
-<p><a name="bootable"></a>Here is a list of such bootable CDs:</p>
-<ul>
-<li><a href="http://www.lnx-bbc.org/">LNX-BBC Bootable CD</a> </li>
-<li><a href="http://www.stresslinux.org/">Stresslinux Bootable CD</a></li>
-<li><a href="http://www.tux.org/pub/people/kent-robotti/looplinux/rip/">RIP (Recovery Is Possible) Bootable CD</a></li>
-<li><a href="http://www.sysresccd.org/">SystemRescueCd</a></li>
-<li><a href="http://www.gpstudio.com/stux/">STUX Bootable CD</a></li>
-<!-- <li><a href="http://www.knopper.net/knoppix/">Knoppix Bootable CD</a></li> -->
-</ul>
-<p>
-Please let me know if there are others, and I will add them to this
-list.
-</p>
-</li>
-
-<li><b>Can I monitor ATA disks behind SCSI RAID controllers?</b>
-
-<p>
-From release 5.1-18, smartmontools fully supports 3ware SCSI RAID
-controllers that use ATA disks internally. To pass commands through
-the 3ware controller, use the smartmontools <b>-d 3ware,N</b> option
-or Directive.
-</p>
-<p>
-3ware Linux device drivers (<tt>3w-xxxx</tt>) versions <b>1.02.00.036</b>
-and earlier do not return the SMART HEALTH STATUS (smartmontools
-<b>-H</b>) of the disks. In addition, the ENABLE AUTOMATIC OFFLINE and
-ENABLE ATTRIBUTE AUTOSAVE commands (smartmontools <b>-o on</b> and
-<b>-S on</b>) can not be passed through the driver to the disks.
-Later driver versions support <i>all</i> of these commands.  You may:
-</p>
-<ul>
-<li>use version <b>1.02.00.037</b> or greater of the <tt>3w-xxxx</tt> driver, or</li>
-<li><a href="3w-xxxx.txt">patch</a> earlier 3ware <tt>3w-xxxx</tt> drivers so that
-these commands reach the disks, or</li>
-<li> use an <b>unpatched</b> earlier <tt>3w-xxxx</tt> driver (which won't pass these
-commands to the disks but will instead print
-harmless warning messages to SYSLOG).</li>
-</ul>
-<p>
-To see if your system's <tt>3w-xxxx</tt> driver has been patched, give the
-command:<br/>
-<tt>smartctl -H -S on -o on -d 3ware,? /dev/sd?</tt>
-<br/>
-If you
-have an unpatched kernel, you'll see warning messages prompting you to
-patch the kernel.</p>
-<p>
-The 3ware <tt>3w-xxxx</tt> version 1.02.00.037 driver first appeared
-in kernel version 2.6.0-test5-bk11 on 24 September 2003 and in kernel
-version 2.4.23-bk2 on 3 December 2003.  It was officially released on
-the 3ware web site on December 19, 2003 as part of their
-driver/firmware/utility package version 7.7.0.
-</p>
-
-<p>
-Note (added 29 July 2004): starting with smartmontools (experimental)
-release 5.33, one can also access SMART data from drives behind 3ware
-controllers using the (character) devices /dev/twe0-15.  This should
-work correctly even with older versions of the 3w-xxxx driver. One can
-also access SMART data from drives behind 3ware 9000-series
-controllers (3w-9xxx driver) using the (character) devices
-/dev/twa0-15.
-</p>
-
-</li>
-
-<li><a name="windows"></a><b>Does it work on Windows?</b>
-
-<p>Yes, finally it does. A windows port of smartctl 5.26 by
-<a href="http://sourceforge.net/users/chrfranke/">Christian Franke</a>
-was first checked in 2004/02/23 on CVS branch
-<a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/?only_with_tag=RELEASE_5_26_WIN32_BRANCH">
-RELEASE_5_26_WIN32_BRANCH</a> and has been merged to the CVS trunk later.</p>
-
-<p>The <a href="http://www.cygwin.com/">Cygwin</a> environment can be
-used to built both Cygwin and Windows (using <a href="http://www.mingw.org/">MinGW</a>)
-versions of smartctl and smartd.
-Installation instructions for binary distributions can be found
-<a href="#CygwinInstall">here</a> and <a href="#WindowsInstall">here</a>.</p>
-
-<p>Alternatively, you can also run it from a
-<a href="#bootable">bootable CD</a></p>
-
-<p>Some code showing how to access SMART data under Windows 98, NT 4,
-2000, and XP can be found <a
-href="ftp://ftp.heise.de/pub/ct/listings/0207-218.zip">here</a>.
-Additional information from Microsoft can be found <a
-href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q208048">here</a>.
-A related newsgroup thread (with pointers to additional documentation,
-etc.) is <a
-href="http://groups.google.com/groups?hl=en&amp;lr=&amp;ie=UTF-8&amp;oe=UTF-8&amp;th=18cdac9d90f6bda1&amp;rnum=1">here</a>.
-</p>
-</li>
-
-<li><b>Why did the release version scheme change?</b>
-
-<p>It was non-standard.  So with the move to GNU Autoconf and GNU
-Automake it changed from 5.X-Y (where X and Y are one or more digits)
-to 5.Y. Starting with the first release, and moving forward in time, the releases are
-numbered as follows:<br/>
-<tt>
-5.0-1,&nbsp;
-5.0-2,&nbsp;
-...,&nbsp;
-5.0-45,&nbsp;
-5.1-1,&nbsp;
-...,&nbsp;
-5.1-18,&nbsp;
-5.19,&nbsp;
-5.20,&nbsp;
-...
-</tt>
-</p>
-</li>
-
-<li><a name="FAQ-database"></a><b>My ATA drive is not in the smartctl/smartd database.  Does this break anything? How do I get it added?</b>
-<p>
- If your drive is not in the database, then the
- <i>names</i> of the Attributes (displayed in the <tt>ID#</tt> column of
- <tt>smartctl -A /dev/hd?</tt>) and the <i>format</i> of the the raw Attribute
- values shown in the <tt>RAW_VALUE</tt> column may be incorrect.  This
- is mostly cosmetic: the essential drive health monitoring/testing
- functionality of <b>smartmontools</b> does <i>not</i> depend upon the
- database.
-</p>
-
-<p>
-<b>
- If your drive is not in the database, pleaes check <a
- href="http://sourceforge.net/project/showfiles.php?group_id=64297">here</a>
- to be sure that you are using the latest smartmontools release.  Each
- new release has additional drives added to the database.  Please do
- not submit a new drive for the database without checking to see if it
- is already in the database of the current smartmontools release
- version.
-</b>
-</p>
-
-<p>
-<b> If your drive is not in the database of the current release,</b>
- to have it added to the database, first use the command:<br/>
- <tt>smartctl -t short /dev/hd?</tt><br/> to run a short self-test on
- the drive, and wait a few minutes for the test to complete.  Then
- email the entire output from:<br/> <tt>smartctl -a /dev/hd?</tt><br/>
- to <a
- href="https://lists.sourceforge.net/lists/listinfo/smartmontools-database">smartmontools-database</a>
- as a plain-text email attachment (file type: ".txt").  The timestamp
- in the self-test log will help us to determine whether Attribute 9 is
- being used to store the lifetime in hours, minutes, or seconds.
-</p>
-<p>
-If you need to use any of the vendor-specific display options
- (<tt>-v</tt> options) with the drive, or if any of the Attributes are
- behaving strangely, please include that information as well.
-</p>
-</li>
-
-<li><b>My ATA drive is failing its self-tests, but its SMART health status is 'PASS'. What's going on?</b>
-
-<p>
-If your ATA drive supports self-tests, you should run them on a
-regular basis, for example one per week:
-<br/><tt>smartctl -t long /dev/hd?</tt><br/>
-After the test has completed, you should examine the results with:
-<br/><tt>smartctl -l selftest /dev/hd?</tt><br/>
-</p>
-
-<p>
-If the drive fails a self-test, but still has 'PASS' SMART health
-status, this usually means that there is a corrupted sector on the
-disk, which can not be read.  If the disk were able to read that
-sector of data, even once, then the disk firmware would mark the
-sector as 'bad' and then allocate a spare sectors to replace it.  But
-if the disk can't read the sector even once, then it won't reallocate
-the sector, in hopes of being able, at some time in the future, to
-read the data from it.  See <a
-href="http://smartmontools.sourceforge.net/BadBlockHowTo.txt">BadBlockHowTo</a>
-for instructions about how to force this sector to reallocate (Linux
-only).
-</p>
-<p>
-The disk still has passing health status because the firmware has not
-found other signs of trouble, such as a failing servo.
-</p>
-<p>
-Such disks can often be repaired by using the disk manufaturer's 'disk
-evaluation and repair' utility.  Beware: this may force reallocation
-of the lost sector and thus corrupt or destroy any file system on the
-disk. See <a
-href="http://smartmontools.sourceforge.net/BadBlockHowTo.txt">BadBlockHowTo</a>
-for generic Linux instructions.
-</p>
-
-</li>
-
-<li><b>smartd is warning that my ATA disk has unreadable or uncorrectable or pending sectors. What's going on?</b>
-
-<p>
-Disk drives store data in blocks (sectors) of 512 bytes.  Each 512
-bytes has additional bytes appended to it (usually 40 to 60) which are
-used internally by the disk firmware for error checking/detection and
-correction.  These are called ECC bytes.
-</p>
-<p>
-Sometimes the data in a sector gets corrupted.  This can happen
-because a speck of dust scratched the disk, or because the disk was
-powered down while writing data to that sector, or for other reasons.
-Usually the ECC bytes can be used to correct the corrupted data.
-However if the ECC bytes are inconsistent or can't be used to correct
-the bad data, then the 512 bytes of data are lost.  Such a sector is
-called unreadable or uncorrectable.
-</p>
-<p>
-If your disk has an unreadable sector, this means that some of your
-data can't be retrieved.  You can force the disk to replace the
-unreadable sector with a spare good sector, but only at the price of
-losing the 512 bytes of data forever.
-</p>
-<p>
-Disks with uncorrectable sectors can often be repaired by using the
-disk manufaturer's 'disk evaluation and repair' utility (see previous
-FAQ entry).  Beware: this may force reallocation of the lost sector
-and thus corrupt or destroy any file system on the disk. See <a
-href="http://smartmontools.sourceforge.net/BadBlockHowTo.txt">BadBlockHowTo</a>
-for generic Linux instructions.
-</p>
-<p>
-Normally when an uncorrectable sector is found, the disk puts this
-onto a 'pending sector list' to indicate that it should be replaced
-with a spare good sector.  However this replacement won't take place
-until either the disk can read the data on the bad sector, or is
-commanded to write new data to that bad sector.
-</p>
-
-</li>
-
-
-<li><b>My computer's BIOS has a SMART enable/disable setting.  What
-does it do, and how should I set it?</b>
-<p>
-Some type of BIOS can check the SMART health status of a disk at
-bootup: the equivalent of '<tt>smartctl -H /dev/hd?</tt>'.  This one-time check on
-bootup is done if the BIOS SMART setting is set to 'ENABLE', and is
-not done if the setting is set to 'DISABLE'.
-</p>
-
-<p>
-If this one-time check is done, and the disk's health status is found
-to be 'FAIL', then typically the BIOS will display an error message
-and refuse to boot the machine.
-</p>
-
-<p>
-For the proper functioning of smartmontools, either BIOS setting may
-be used.
-</p>
-</li>
-
-
-<li><b>My Fedora Core Linux system displays the startup message: smartd [FAILED]</b>
-<p>
-Fedora Core is distributed with a smartd configuration file
-/etc/smartd.conf that monitors the first IDE disk /dev/hda.  If this
-device does not exist (or lacks SMART capability) you will get the
-error message above.  Look in SYSLOG (/var/log/messages) for
-additional details about what is going wrong.
-</p>
-<p>
-The solution: If your system has only SCSI disks, or has IDE disk(s)
-on a non-primary controller, just edit /etc/smartd.conf to reflect the
-correct location of the drive(s).  Please also read the 'smartd.conf'
-man page for additional information.
-</p>
-</li>
-
-<li><b>Attribute 194 (Temperature Celsius) behaves strangely on my Seagate disk</b>
-<p>
-Some Seagate disks store the current temperature Celsius in both the
-RAW and NORMALIZED Attribute 194 values, and the maximum lifetime
-temperature in Celsius in the WORST value.  Since cooler is better,
-this means that in this case, <i>lower</i> NORMALIZED Attribute values
-are farther from failure, and that over time the WORST Attribute
-values get <i>larger</i>, not <i>smaller</i> (as with other
-Attributes).
-</p>
-</li>
-
-<li><b>What's this smartctl message mean?: Warning: ATA error count 9 inconsistent with error log pointer 5</b>
-<p>
-The ATA error log is stored in a circular buffer, and the ATA
-specifications are unambiguous about how the entries should be
-ordered.  This warning message means that the disk's firmware does not
-strictly obey the ATA specification regarding the ordering of the
-error log entries in the circular buffer.  Smartmontools will correct
-for this oversight, so this warning message can be safely ignored by
-users.  (On the other hand, firmware engineers: please read the ATA
-specs more closely then fix your code!).
-</p>
-</li>
-</ul>
-
-<hr size="2" /><a name="scsi"></a><b>SCSI disks and tapes
-(TapeAlert)</b>
-<p>Smartmontools for SCSI disks and tapes (including medium changers) is
-discussed on a separate <a href="smartmontools_scsi.html">page</a>.
-</p>
-
-<hr size="2" /><a name="testinghelp"></a><b>FireWire, USB, and SATA 
-disks/systems</b>
-<p>As for USB and FireWire (ieee1394) disks and tape drives, the news
-is not good. They appear to Linux as SCSI devices but their
-implementations do not usually support those SCSI commands needed by
-smartmontools. The ieee1394 consortium recently certified the <span
- style="font-style: italic;">first</span> external enclosure (containing
-a ATA disk and a protocol bridge) as being compliant to the relevant
-standards. Such devices have already been on the market for about 3 
-years and they tend to only support the bare minimum of commands
-needed for device operation (i.e. SMART support is an unsupported
-extra).<br />
-</p>
-<p>Smartmontools should work correctly with SATA drives under both
-Linux 2.4 and 2.6 kernels, <i>if</i> you use the standard IDE drivers
-in <tt>drivers/ide</tt>. If you use the new <tt>libata</tt> drivers,
-it won't work correctly because <tt>libata</tt> doesn't yet support
-the needed ATA-passthrough ioctl() calls.  Jeff Garzik, the
-<tt>libata</tt> developer, says that this support will be added to
-libata in the future.  When this happens, we'll add support to
-smartmontools for a new SATA/libata device type <tt>'-d sata'</tt>.
-Typically, to force an SATA disk to run using the standard
-(non-libata) drivers, you must use the BIOS to select "legacy mode"
-for the controller.  If the IDE driver doesn't support your particular
-SATA controller, or the controller doesn't have a legacy interface,
-then only libata can be used.  Unless the hard disk controller on the
-system motherboard is Intel, VIA or nVidia, standard IDE drivers may
-not work
-</p>
-
-<hr size="2" /><a name="differfromsmartsuite"></a><b>How does
-smartmontools differ from smartsuite?</b>
-
-<p>The smartsuite code was originally developed as a Senior Thesis by
-Michael Cornwell at the Concurrent Systems Laboratory (now part of the
-<a href="http://ssrc.soe.ucsc.edu/">Storage Systems Research
-Center</a>), Jack Baskin School of Engineering, University of
-California, Santa Cruz.
-You can find some information about the original smartsuite project here:
-<a href="http://www.ucsc.edu/news_events/press_releases/archive/99-00/09-99/smart_software.htm">Press Release 1</a>, 
-<a href="http://www.santa-cruz.com/archive/1999/September/22/local/stories/5local.htm">Press Release 2</a>, 
-<a href="http://www.ucsc.edu/currents/99-00/09-27/smart.html">Press Release 3</a>.
-</p>
-
-<p>
-<a href="http://csl.cse.ucsc.edu/smart.shtml">According to UCSC</a>
-smartsuite is no longer maintained; the last release was in 2001.
-</p>
-
-<p>Smartmontools was derived directly from smartsuite.&#160; It differs
-from smartsuite in that it supports the ATA/ATAPI-5 standard.&#160; So
-for example <tt>smartctl</tt> from smartsuite has no facility for
-printing the SMART self-test logs, and doesn't print timestamp
-information in the most usable way.&#160; The <tt>smartctl</tt> utility
-in smartmontools has added functionality for this (<tt>-q, -l selftest,-S,
--T, -v and -m</tt> options), updated documentation, and also fixes small
-technical bugs in smartsuite. [One example: smartsuite does not actually use the
-ATA SMART RETURN STATUS command to find out the health status of a disk.  It instead tries to infer this from the
-SMART Attribute values.]&#160; See the 
-<a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?rev=HEAD&amp;content-type=text/plain">CHANGELOG</a>
-file in CVS for a summary of what's been done.&#160; The <tt>smartd</tt>
-utility differs from the smartsuite <tt>smartd</tt> in major ways.&#160;
-First, it prints somewhat more informative error messages to the syslog.
-&#160; Second, on startup it looks for a configuration file
-<tt>/etc/smartd.conf</tt>, and if <tt>smartd</tt> finds this file, it
-monitors the list of devices therein, rather than querying all IDE and
-SCSI devices on your system.&#160; (If the configuration file does not
-exist, then it does query all IDE and SCSI devices.)&#160; Also, it's
-a well-behaved daemon and doesn't leave open file descriptors and other
-detrius behind.&#160; In addition, the <tt>smartmontools</tt> version of
-<tt>smartd</tt> can be instructed (via Directives in the configuration
-file) to monitor for changes in a number of different disk properties:
-the SMART status, failure or prefailure attributes going below
-threshold, new errors appearing in the ATA Error Log or the SMART
-Self-Test Log, and so on. <tt>smartd</tt> can also send an email warning or run a
-user-specified executable if it detects a problem with the disk.
-</p>
-
-<p>The other principle difference is that smartmontools is an
-OpenSource development project, meaning that we keep the files in CVS,
-and that other developers who wish to contribute can commit changes to
-the archive. If you would like to contribute, please write to to <a
-href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">smartmontools-support</a>.</p>
-
-<p>But the bottom line is that the code in smartmontools is derived
-directly from smartsuite and is similar.&#160; The smartsuite package
-can be found <a href="http://sourceforge.net/projects/smartsuite/">here</a>.</p>
-
-<hr size="2" /><a name="references"></a><b><big>Useful references on
-SMART and the  ATA/ATAPI standards</big></b>
-
-<p><big>If you are having trouble understanding the output of smartctl
-or smartd, please first read the manual pages installed on your
-system:</big></p>
-
-<pre>
-man 8 smartctl
-man 8 smartd
-man 5 smartd.conf
-</pre>
-
-<p>
-Here are on-line versions of the smartmontools man pages:<br/> <a
-href="man/smartctl.8.html">smartctl manual page</a><br/> <a
-href="man/smartd.8.html">smartd manual page</a><br/> <a
-href="man/smartd.conf.5.html">smartd.conf manual page</a><br/> Note
-that these are the manual pages for the <b><i>current version</i></b>
-of smartmontools in the developers CVS repository; they might not
-correspond to the (possibly older) version of smartmontools installed
-on <i>your</i> system.  So the manual pages installed on your system
-should be regarded as definitive for your installation.</p>
-
-<p><big>If you'd like to know more about SMART, then the following
-references may be helpful:</big></p>
-
-<ul>
-<li><a href="http://www.linuxjournal.com/article.php?sid=6983">Monitoring Hard Disks with SMART (Linux Journal, Jan 2004)</a></li>
- <li>The <a href="http://www.t13.org/project/d1321r1c.pdf"> ATAPI/ATA-5
-Revision 1 specification</a> (start with Section 8.41)</li>
- <li>The <a href="http://www.t13.org/docs2002/d1410r3b.pdf"> ATAPI/ATA-6
-Revision 3b specification</a></li>
- <li>The  ATAPI/ATA-7 specification (Draft 4b) 
-  <a href="http://www.t13.org/docs2004/d1532v1r4b%20ATA-ATAPI-7.pdf">Volume 1 (has SMART documentation)</a>,
-  <a href="http://www.t13.org/docs2004/d1532v2r4b%20ATA-ATAPI-7.pdf">Volume 2</a>,
-  <a href="http://www.t13.org/docs2004/d1532v3r4b%20ATA-ATAPI-7.pdf">Volume 3</a></li>
- <li><a href="http://www.t13.org/#FTP_site">Other revisions
-of the ATAPI/ATA Specs</a></li>
-<li>SCSI References:
-<ul>
- <li>The <a href="http://www.t10.org">homepage of the T10 project</a>.</li>
- <li>The <a href="ftp://ftp.t10.org/t10/drafts/s2/">SCSI-2 draft</a> by the T10 project.</li>
- <li>See also other subdirectories <a href="ftp://ftp.t10.org/t10/drafts/">here</a>.</li>
-</ul>
-</li>
-<li>
-  The original SMART specification is SFF-8035i from the <a href="http://www.sffcommittee.com/ns/">
-  Small Form Factors (SFF) Committee</a>.&#160; 
-  <ul>
-    <li>
-      Here is the SFF <a href="ftp://ftp.seagate.com/sff/INF-8035.TXT"> "link"</a>
-     (they have "expired" the document).
-    </li>
-    <li>
-      Version 1.0 of <a href="ftp://ftp3.ds.pg.gda.pl/people/macro/S.M.A.R.T./SFF-8035i.pdf">
-      SFF-8035i "Self-Monitoring, Analysis and Reporting Technology (S.M.A.R.T.)". </a>
-    </li>
-    <li>
-      Revision 2.0 of <a href="ftp://ftp3.ds.pg.gda.pl/people/macro/S.M.A.R.T./8035R2_0.PDF">
-      SFF-8035i "Self-Monitoring, Analysis and Reporting Technology (S.M.A.R.T.)". </a>
-    </li>
-    <li>
-      Revision 1.4 of <a href="ftp://ftp3.ds.pg.gda.pl/people/macro/S.M.A.R.T./8055.PDF">
-      SFF-8055i "S.M.A.R.T. Applications Guide for the ATA and SCSI Interfaces" </a>
-    </li>
-  </ul>
-</li>
-<li>From the <a href="http://cmrr.ucsd.edu/smart/">UCSD SMART Project</a>:
-<ul> 
- <li><a href="http://cmrr.ucsd.edu/smart/tech_papr/HamerlySmartPaper.pdf">Bayesian
-Approaches to Failure Prediction for Disk Drives</a></li>
-  <li><a href="http://cmrr.ucsd.edu/smart/tech_papr/SmtPapTransReliFinalWeb.pdf">Improved
-Disk-Drive Failure Warnings</a></li>
- </ul>
- </li>
- <li>From the Seagate Corporation:
- <ul>
-  <li><a href="http://www.seagate.com/newsinfo/docs/disc/drive_reliability.pdf" target="_blank">Estimating Drive Reliability in Desktop Computers and
-Consumer Electronics Systems</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/enhanced_smart.pdf" target="_blank">Enhanced SMART - Get SMART For Reliability</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/smart_u8.pdf" target="_blank">Playing it SMART</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/Enhanced_DST_Tech_Paper.pdf" target="_blank">Enhanced Drive Self-Test</a></li>
- </ul>
- </li>
- <li><u>Specifying Reliability in the Disk Drive Industry: No More
-MTBF's</u>, Jon G. Elerath (IBM Storage Systems Division) in
-<i>Proceedings of the IEEE 2000 Annual Reliability and Maintainability
-Symposium, pg 194, 0-7803-5848-1/00/$10.00.</i></li>
- <li><a href="http://freepgs.com/smart">Zbigniew Chlondowski's SMART Information Site.</a>
-This includes a useful list of <a href="http://freepgs.com/smart/attributes.php">Attributes and their meanings.</a>
-</li>
-</ul>
-
-<hr size="2" /><a name="sampleoutput"></a><b>Example output
-from smartmontools smartctl utility:</b>
-
-<ul>
- <li><a href="examples/MAXTOR-0.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM</li>
- <li><a href="examples/MAXTOR-1.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status - reallocated sector count)</li>
- <li><a href="examples/MAXTOR-2.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has had failing SMART test in the past.  Look at the Seek Error Rate)</li>
- <li><a href="examples/MAXTOR-7.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status, some failed self-tests)</li>
- <li><a href="examples/MAXTOR-8.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status - calibration retry count)</li>
- <li><a href="examples/MAXTOR-9.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status - calibration retry count)</li>
- <li><a href="examples/MAXTOR-10.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (failing self-tests. Note Current_Pending_Sector raw value and Uncorrectable (UNC) read errors)</li>
- <li><a href="examples/MAXTOR-3.txt">MAXTOR 6L080J4</a> 80 GB 7200 RPM</li>
- <li><a href="examples/MAXTOR-4.txt">MAXTOR 6L080J4</a> 80 GB 7200 RPM</li>
- <li><a href="examples/Maxtor-5.txt">Maxtor 98196H8</a> 80 GB 5400 RPM</li>
- <li><a href="examples/MAXTOR-6.txt">Maxtor 4R080J0</a> Note: Attribute 9 (lifetime) stored in minutes!</li>
- <li><a href="examples/IC35L120AVVA07-0-0.txt">IBM IC35L120AVVA07 (GXP 120 series)</a> 120 GB 7200 RPM (note 3 temperatures)</li>
- <li><a href="examples/IC35L120AVVA07-0-1.txt">IBM IC35L120AVVA07 (GXP 120 series)</a> 120 GB 7200 RPM (note 3 temperatures)</li>
- <li><a href="examples/IC35L120AVV207-0.txt">IBM IC35L120AVV207 (GXP 180 series)</a> 120 GB 7200 RPM (note 3 temperatures)</li>
- <li><a href="examples/IC35L120AVV207-1.txt">IBM IC35L120AVV207 (GXP 180 series)</a> (failing SMART status and self-tests)</li>
- <li><a href="examples/HITACHI_DK23BA-20-0.txt">HITACHI_DK23BA-20</a> Hitachi 20 GB Laptop Disk</li>
- <li><a href="examples/HITACHI_DK23AA-12B.txt">HITACHI_DK23AA-12B</a> Really sick failing Hitachi Laptop Disk</li>
- <li><a href="examples/TOSHIBA-0.txt">TOSHIBA MK2018GAS</a> Toshiba 20 GB Laptop Disk</li>
- <li><a href="examples/TOSHIBA-MK6021GAS.txt">TOSHIBA MK6021GAS</a> Toshiba 60 GB Laptop Disk (note 3 temperatures)</li>
- <li><a href="examples/FUJITSU1.txt">Fujitsu MHR2040AT</a> Fujitsu Laptop Disk (has failing SMART status - write error count)</li>
- <li><a href="examples/FUJITSU_MHR2020AT.txt">Fujitsu MHR2020AT</a> Fujitsu Laptop Disk (has failing SMART status and self-tests)</li>
- <li><a href="examples/WD2500JB.txt">Western Digital WD2500JB</a>Western Digital Disk (failing SMART status and self-tests)</li>
-</ul>
-
-<hr size="2" />
-
-Maintained by: <a href="mailto:smartmontools-support&#64;lists.sourceforge.net">Bruce Allen</a><br />
-Copyright (C) 2002-4 Bruce Allen<br />
-Last updated: <tt>$Date: 2004/08/15 17:24:55 $</tt><br />
-CVS tag: <tt>$Id: index.html,v 1.171 2004/08/15 17:24:55 ballen4705 Exp $</tt>
-
-<hr size="2" />
-
-<div align="center">Hosted by</div>
-
-<div align="center"><a href="http://sourceforge.net/"><img style="border:0;width=:88px;height:31px"
-   src="http://sourceforge.net/sflogo.php?group_id=64297&amp;type=5" alt="SourceForge.net" /></a></div>
-
-<br />
-
-<div align="center"><a href="http://validator.w3.org/check/referer"><img style="border:0;width=:88px;height:31px"
-   src="http://www.w3.org/Icons/valid-xhtml10.png" alt="Valid XHTML 1.0!" /></a></div>
-
-<br />
-
-<div align="center"><a href="http://validator.w3.org/check?uri=http%3A%2F%2Fsmartmontools.sourceforge.net">
-Validate XHTML 1.0 Transitional.</a></div>
-
-<br />
-
-<div align="center"><a href="http://validator.w3.org/checklink?uri=http%3A%2F%2Fsmartmontools.sourceforge.net&amp;hide_type=all&amp;depth=&amp;check=Check">Check/Validate all links on this page.</a></div>
-
-</body>
-</html>
diff --git a/www/script b/www/script
deleted file mode 100755
index fa7cd8c224367b6aba467f81fc960da4efc80375..0000000000000000000000000000000000000000
--- a/www/script
+++ /dev/null
@@ -1,24 +0,0 @@
-#! /bin/bash
-
-# This is a script to wrap smartctl output into http:// displayable form
-# It requires a filename as input, and produces an file with a .html extension as output
-
-if [ $# -ne 1 ] ; then
-	echo This script requires one a file as input
-	exit 1
-fi
-
-model=`grep "Device Model"  $1  | awk '{print $3}' `
-
-# see if file name in use
-let i=0
-while [ -f $model-$i.html ] ; do
-	let i+=1
-done
-
-filename=$model-$i
-echo -e "<pre><tt>\n"    > $filename.html
-cat $1                  >> $filename.html
-echo -e "</tt></pre>\n" >> $filename.html
-
-echo created file $filename.html
diff --git a/www/smart_logo.gif b/www/smart_logo.gif
deleted file mode 100644
index 16a179c824bb4205d117f371eec0500eaf4d4c50..0000000000000000000000000000000000000000
Binary files a/www/smart_logo.gif and /dev/null differ
diff --git a/www/smartmontools_scsi.xml b/www/smartmontools_scsi.xml
deleted file mode 100644
index c2ee2a2d91d2c7ea6771d5086e00be0659e6c5b4..0000000000000000000000000000000000000000
--- a/www/smartmontools_scsi.xml
+++ /dev/null
@@ -1,1089 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" >
-
-<!--
-This is DocBook XML that can be rendered into a single HTML page with a
-command like 'xmlto html-nochunks <this_file_name>'. It can
-also be rendered into multi-page HTML (drop the "-nochunks") or pdf,
-ps, txt, etc.
--->
-
-<article id="index">
- <articleinfo>
-   <title>Smartmontools for SCSI devices</title>
-   <author>
-    <firstname>Douglas</firstname>
-    <surname>Gilbert</surname>
-    <affiliation>
-     <address>
-      <email>dgilbert at interlog dot com</email>
-     </address>
-    </affiliation>
-   </author>
-  <authorinitials>dpg</authorinitials>
-  <pubdate>2004-05-06</pubdate>
-
-  <revhistory>
-     <revision>
-       <revnumber>1.2</revnumber>
-       <date>2004-05-06</date>
-       <authorinitials>dpg</authorinitials>
-       <revremark>
-             reorganise, details in appendix, version 5.31
-       </revremark>
-     </revision>
-     <revision>
-       <revnumber>1.1</revnumber>
-       <date>2003-10-13</date>
-       <authorinitials>dpg</authorinitials>
-       <revremark>
-             freebsd, timestamp
-       </revremark>
-     </revision>
-     <revision>
-       <revnumber>1.0</revnumber>
-       <date>2003-05-26</date>
-       <authorinitials>dpg</authorinitials>
-       <revremark>
-             first cut
-       </revremark>
-     </revision>
-  </revhistory>
-
-  <copyright>
-   <year>2003</year>
-   <year>2004</year>
-   <holder>Douglas Gilbert</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-      Permission is granted to copy, distribute and/or modify this document
-      under the terms of the GNU Free Documentation License, Version 1.1
-      or any later version published by the Free Software Foundation;
-      with no Invariant Sections, with no Front-Cover Texts, and with
-      no Back-Cover Texts.
-   </para>
-   <para>
-    For an online copy of the license see
-    <ulink url="http://www.fsf.org/copyleft/fdl.html">
-    <literal>www.fsf.org/copyleft/fdl.html</literal></ulink>.
-   </para>
-
-  </legalnotice>
-
-  <abstract>
-  <para>
-    This article describes how smartmontools interacts with SCSI 
-    storage devices (including tapes). Smartmontools is a SMART
-    utility toolset. <acronym>SMART</acronym> is an acronym for
-    Self-Monitoring, Analysis and Reporting Technology. Smartmontools
-    is available for the these operating systems: Linux, FreeBSD, NetBSD,
-    Solaris and Windows.
-  </para>
-  </abstract>
- </articleinfo>
-
-<!--
-<toc></toc>
--->
-
-  <sect1 id="intro">
-      <title>Introduction</title>
-<para>
-Smartmontools controls and monitors storage devices using the
-Self-Monitoring, Analysis and Reporting Technology 
-(<acronym>SMART</acronym>) system. This toolset was originally built
-for Linux and has been ported to FreeBSD, NetBSD, Solaris and
-Windows. 
-This article describes how smartmontools interacts with SCSI devices.
-Passing reference is also made to devices that use the SCSI command
-set such as USB mass storage devices and IEEE1394 devices that use
-the "sbp2" protocol.
-</para>
-<para>
-The primary web site for smartmontools is at
-<ulink url="http://smartmontools.sourceforge.net">
-<literal>smartmontools.sourceforge.net</literal></ulink> from which the
-latest versions (both source and binaries) can be obtained. Smartmontools
-grew out of the now dormant <emphasis>smartsuite</emphasis> project which
-is still available on its sourceforge site. The smartmontools main page
-concentrates on ATA devices.
-This article supplies some SCSI specific information for
-those users of smartmontools that wish to monitor SCSI storage devices.
-</para>
-<para>
-This document outlines the features found in smartmontools
-version 5.31 that are relevant to SCSI disks and tape drives.
-This document was last altered on 6th May 2004.
-</para>
-</sect1>
-
-<sect1 id="overv">
-      <title>Overview of Smartmontools</title>
-<para>
-Smartmontools is made up of two executable programs, a configuration file
-and online documentation (on Unix systems in the form of "man" pages).
-The two executable programs are:
-<itemizedlist>
-<listitem><para><command>smartctl</command>: a command line utility
-</para></listitem>
-<listitem><para><command>smartd</command>: a daemon program providing a
-monitoring service
-</para></listitem>
-</itemizedlist>
-</para>
-<para>
-SCSI disks and tape drives allow self tests of their media, often monitor
-the temperature of the device, maintain error counters and report when
-various failure prediction thresholds are exceeded. To view the information
-available try a command like: <command>smartctl -a /dev/sda</command>. If
-<acronym>SMART</acronym> reporting has not been turned on for this disk 
-then use this command
-first: <command>smartctl -s on /dev/sda</command>. [For operating systems
-other than Linux replace <filename>/dev/sda</filename> with a SCSI disk 
-device name.]
-</para>
-<para>
-The <command>smartd</command> daemon program is a service typically started
-when a machine boots up. In can monitor multiple disks (both ATA and SCSI).
-In Unix systems its configuration file can
-be found <filename>/etc/smartd.conf</filename>. It sends alerts to the
-system logs and can be configured to email system administrators when
-pending failures are reported.
-</para>
-</sect1>
-
-<sect1 id="oses">
-      <title>Operating Systems</title>
-<para>
-Smartmontools was originally written for Linux. Since then it has been
-ported to various other Unix based system and Windows. The names of
-SCSI disk and tape devices vary. Here is a summary:
-
-<table frame="all"><title>SCSI device names in various systems</title>
-<tgroup cols="4" align="left" colsep="1" rowsep="1">
-<thead>
-<row>
-<entry/>
-<entry>disks</entry>
-<entry>tapes</entry>
-<entry>Notes</entry>
-</row>
-</thead>
-<tbody>
-<row>
-<entry><command>Linux</command></entry>
-<entry><filename>/dev/sd[a-z]</filename></entry>
-<entry><filename>/dev/[n]st[0-9]</filename></entry>
-</row>
-<row>
-<entry><command>FreeBSD</command></entry>
-<entry><filename>/dev/da[0-9]</filename></entry>
-<entry><filename>/dev/[n|e]sa[0-9]</filename></entry>
-</row>
-<row>
-<entry><command>NetBSD</command></entry>
-<entry><filename>/dev/sd[0-9]</filename></entry>
-<entry><filename>/dev/enrst[0-9]</filename></entry>
-</row>
-<row>
-<entry><command>Solaris</command></entry>
-<entry><filename>/dev/rdsk/c?t?d?s?</filename></entry>
-<entry><filename>/dev/rmt/*</filename></entry>
-</row>
-<row>
-<entry><command>Windows</command></entry>
-<entry><filename>/dev/scsi[0-9][0-f]</filename></entry>
-<entry><filename>/dev/scsi[0-9][0-f]</filename></entry>
-<entry>ASPI adapter: 0-9, ID: 0-15, <filename>/dev/</filename> optional
-</entry>
-</row>
-</tbody>
-</tgroup>
-</table>
-</para>
-<para>
-The above list is a simplification of course. In Linux there can be multiple
-drive letters followed by a partition number (1 to 15). Smartmontools will
-ignore the partition number if it is given and query the underlying device.
-In Linux the SCSI tape device name can be "nst" and a letter can be
-appended to the device name, both decorations are ignored by smartmontools
-as it accesses the underlying tape drive. Also in Linux, SCSI devices can
-be accessed via their generic name which is of the form
-<filename>/dev/sg[0-9]</filename>.
-</para>
-<para>
-Linux also has an optional Solaris like
-naming scheme for SCSI device (scsidev), devfs (mainly used in the lk 2.4
-series) and udev (its replacement in the lk 2.6 series). In short, device
-naming is a complex area and smartmontools does its best to find
-and identify (i.e. whether ATA or SCSI) a device depending on its name. In 
-some cases smartmontools needs guidance from the user and this can be given
-by the '-d ata|scsi|3ware' option in the <command>smartctl</command> 
-utility and in <command>smartd</command> daemon's configuration file.
-</para>
-</sect1>
-
-<sect1 id="scsidisk">
-      <title>SCSI disks</title>
-<para>
-What is a SCSI disk? A SCSI disk is a storage device that "talks" the SCSI
-command set. An ATA disk is a storage device that "talks" the ATA 
-command set. That seems pretty clear. However by the time an operating
-system sees the device the situation can be more complicated.
-</para>
-<para>
-The ATA command set is used over native ATA transports which are
-parallel ATA (PATA) up to 133 MB/sec and serial ATA (SATA) up to 1.5 Gbps
-(approximately 150 MB/sec). In the past
-when ATA disks needed to use some other transport (e.g. USB and IEEE1394)
-the SCSI command set was sent over the foreign transport. So in this
-case the operating system sees a device "talking" the SCSI command set
-but the device is really an ATA disk. Many current disk external enclosures
-contains ATA disks yet seen from the operating systems view point are
-USB mass storage devices talking the SCSI command set.  
-</para>
-<para>
-The SCSI command set is used over various transports: the SCSI Parallel
-Interface (SPI), Fibre Channel (FCP), Serial Attached SCSI (SAS),
-IEEE1394 (SBP) and USB (mass storage). Many of these transports can
-convey multiple command sets (i.e. not just the SCSI command set). The
-forthcoming SAS transport is interesting as it can convey both the SCSI
-and ATA command sets. There is also the case of a RAID made up of ATA
-disks which communicates to host operating system with the SCSI command
-set (e.g. 3ware RAID controller).
-</para>
-<para>
-So what does all this mean for smartmontools? In most cases the answer is
-not good news. Devices such as USB external disk enclosures translate 
-incoming (from the host) SCSI commands to their ATA equivalents and process
-responses as required. This translation is limited typically to a small
-number of SCSI commands (e.g. READ and WRITE) but <emphasis>not</emphasis>
-those commands needed by smartmontools. The author does not know of any 
-SCSI_over_USB devices that support Smartmontools. The 3ware RAID (6000, 7000 
-and 8000 series Escalade) controllers are supported
-on several operating systems with special code.
-<footnote><para>
-The 3ware RAID solution tunnels the ATA commands needed for
-smartmontools (together with a disk number) through a vendor specific 
-SCSI command.
-</para></footnote>
-</para>
-</sect1>
-
-<sect1 id="smart">
-      <title>SMART</title>
-<para>
-<acronym>SMART</acronym> never attained the status
-of "standard" and its original documents have been withdrawn. Its catchy
-name lives on, especially on vendors' web sites and obviously in the
-name of this toolset. Luckily the good ideas in <acronym>SMART</acronym>
-have been incorporated into the ATA and SCSI standards albeit in
-slightly different forms.
-</para>
-<para>
-Initially <acronym>SMART</acronym> began on SCSI disks as vendor
-specific extensions. Gradually the <acronym>SMART</acronym> functionality has
-moved into the standards (often by other names) and vendors are improving
-their standards' compliance. [In the vendors' defence some of the
-"standards" are drafts and are yet to be ratified.]
-Some SCSI disk vendors have product manuals (available on the net)
-that cover the parts of the SCSI command set
-that their disk supports. Some of these manuals fill in details that are
-left deliberately vague in the the standards.
-<footnote><para>
-For example: Seagate's "Cheetah 15K.3 Product Manual, Rev F" contains 
-sections on <acronym>SMART</acronym>,
-thermal monitor, and drive self test (section 5.2.7 to 5.2.9). It also
-lists the supported mode pages with their default and changeable values.
-</para></footnote>
-</para>
-<para>
-SCSI standards (found at <ulink url="http://www.t10.org">
-<literal>www.t10.org</literal></ulink>) only make one footnote
-reference to the term <acronym>SMART</acronym>.
-Instead the awkward term "Informational Exceptions" is used.
-For SCSI tapes the term "TapeAlert" is used.
-</para>
-</sect1>
-
-<sect1 id="smartctl">
-      <title>smartctl command line utility</title>
-<para>
-The <command>smartctl</command> command line utility gets
-<acronym>SMART</acronym> information from the nominated device. In some
-cases <acronym>SMART</acronym> information held by the nominated device 
-can be modified by the <command>smartctl</command> command. The command 
-has many options that can be viewed by the long usage message output be
-either of these invocations: <command>smartctl -h</command> or
-<command>smartctl --help</command>. Those options that are only
-available to ATA disks (i.e. not available to SCSI disks or tape drives)
-are marked with "[ATA]". So called "man" page documentation is also
-available online.
-</para>
-<para>
-The following options are currently available for SCSI disks and tape
-drives unless otherwise noted:
-<itemizedlist>
-<listitem><para><command>-a | --all</command>: equivalent to the
-combination <command>-i -H -A -l error -l selftest</command> options
-invoked in that order.
-</para></listitem>
-<listitem><para><command>-A | --attributes</command>: outputs the
-current device temperature, trip temperature and data from the
-start-stop log page. Outputs some vendor specific information if
-available.
-</para></listitem>
-<listitem><para><command>-C | --captive</command>: used in conjunction
-with <command>-t short</command> or <command>-t long</command> options to
-do short or long self tests in the foreground. [Has no effect on tape
-drives.]
-</para></listitem>
-<listitem><para><command>-d TYPE | --device=TYPE</command> where TYPE 
-is "ata", "scsi" or "3ware. Overrides utility's guess about the class 
-of the device which is based on the form of the nominated device's name.
-</para></listitem>
-<listitem><para><command>-h | --help</command>: outputs lengthy usage
-message and exits without any other action.
-</para></listitem>
-<listitem><para><command>-H | --health</command>: outputs single device
-health metric determined by the device manufacturer. This will be "OK"
-or a failure message. 
-</para></listitem>
-<listitem><para><command>-i | --info</command>: outputs device 
-identification information (derived from a SCSI INQUIRY command) and
-whether the device supports <acronym>SMART</acronym> (and temperature 
-warnings) and if those facilities are currently enabled.
-</para></listitem>
-<listitem><para><command>-l TYPE | --log=TYPE</command> where TYPE is
-either "selftest" or "error". Outputs either the selftest log or the
-error log. 
-</para></listitem>
-<listitem><para><command>-q TYPE | --quietmode=TYPE</command> where TYPE is
-either "silent" or "errorsonly". When the type is silent then nothing is
-output to the console but the exit status is set (so it is suitable for
-scripts). For "errorsonly" only errors are output to the console. The
-exit status is always set. [See the smartctl man page.]
-</para></listitem>
-<listitem><para><command>-r TYPE | --report=TYPE</command> where TYPE is
-either "ioctl[,&lt;n&gt;]" or "scsiioctl[,&lt;n&gt;]". Turns on low level
-debugging of issued commands and responses. These commands are issued
-through a system command called an "ioctl" in Unix. The debug can be for
-all issued commands (i.e. "ioctl") or only SCSI commands ("scsiioctl").
-Optionally the TYPE can have a comma and a number post pended to increase
-the volume of debug. See this <link linkend="ctldebug">section</link> for
-more details.
-</para></listitem>
-<listitem><para><command>-s VALUE | --smart=VALUE</command> where VALUE is
-either "on" or "off". Enables or disables <acronym>SMART</acronym> 
-monitoring (and temperature warnings).
-</para></listitem>
-<listitem><para><command>-S VALUE | --saveauto=VALUE</command> where VALUE
-is either "on" or "off". Controls whether the error log values are
-preserved across device power cycles.
-</para></listitem>
-<listitem><para><command>-t TEST | --test=TEST</command> where TEST
-is either "offline", "short" or "long". Despite its name "offline" is
-a short foreground test that all SCSI devices should support. A "short"
-self test is typically 2 minutes or less. A "long" self test will be
-considerably longer that 2 minutes, depending on the size of the media.
-</para></listitem>
-<listitem><para><command>-V | --version</command>: outputs the smartctl
-version number (including the cvs version of all its source files)
-and build information then exits without any other action.
-</para></listitem>
-<listitem><para><command>-X | --abort</command>: will terminate a
-background short or long self test. Usually the self test log notes
-that a self test has been aborted. [Has no effect on tape drives.]
-</para></listitem>
-</itemizedlist>
-</para>
-<para>
-After the options <command>smartctl</command> expects a device name.
-This device name is not required for the '--help' or '--version' options.
-If no options are given and a valid device name is given then the copyright
-notice is output and the program exits. If the device name is invalid
-then that is reported. Only one device name can be given.
-</para>
-<para>
-Examples of various invocations of <command>smartctl</command> on a
-SCSI disk follow:
-<programlisting>
-# smartctl -i /dev/sda
-smartctl version 5.31 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-Device: SEAGATE  ST318451LW       Version: 0003
-Serial number: xxxxxxxxxx
-Device type: disk
-Local Time is: Sat May  1 21:17:14 2004 EST
-Device supports SMART and is Enabled
-Temperature Warning Enabled
-</programlisting>
-</para>
-<para>
-<programlisting>
-# smartctl -H /dev/sda
-smartctl version 5.31 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-SMART Health Status: OK
-</programlisting>
-<programlisting>
-# smartctl -A /dev/sda
-smartctl version 5.31 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-Current Drive Temperature:     33 C
-Drive Trip Temperature:        65 C
-Vendor (Seagate) cache information
-  Blocks sent to initiator = 177230717
-  Blocks received from initiator = 11929237
-  Blocks read from cache and sent to initiator = 28677864
-  Number of read and write commands whose size &lt;= segment size = 2454038
-  Number of read and write commands whose size &gt; segment size = 1388
-Vendor (Seagate) factory information
-  number of hours powered up = 107.90
-  number of minutes until next internal SMART test = 104
-</programlisting>
-</para>
-</sect1>
-
-<sect1 id="selftest">
-      <title>Self Tests</title>
-<para>
-Rather than wait for thresholds to be triggered, an administrator can
-request a self test or program one to happen periodically (e.g. at 3 a.m.
-every night or perhaps weekly) with <command>smartd</command>. All SCSI 
-disks and tape drives should support a <emphasis>default</emphasis> self
-test since it is mandatory. This can
-be invoked with the <command>smartctl -t offline &lt;device&gt;</command>
-command. Despite the term "offline" this is actually a foreground test
-of less than 2 minutes. On completion the default self test yields any 
-errors detected and makes no entry into the self test log.
-</para>
-<para>
-The other self tests that are optionally supported by the device are listed
-here with the <command>smartctl</command> invocation in brackets:
-<itemizedlist>
-<listitem><para>
-background short [<command>smartctl -t short &lt;device&gt;</command>]
-</para></listitem>
-<listitem><para>
-background extended [<command>smartctl -t long &lt;device&gt;</command>]
-</para></listitem>
-<listitem><para>
-foreground short [<command>smartctl -C -t short &lt;device&gt;</command>]
-</para></listitem>
-<listitem><para>
-foreground extended [<command>smartctl -C -t long &lt;device&gt;</command>]
-</para></listitem>
-</itemizedlist>
-Short self tests should take less than two minutes to complete. The extended
-self tests have been known to take more than one hour for disks that are over 
-100 GBytes in size. Care should be taken with foreground tests on disks
-with mounted file systems as the OS may not take kindly to an hour delay
-on a simple READ command.
-<footnote><para>
-Linux has an additional problem with the foreground extended self tests:
-it will attempt to time out the command after 10 seconds. This will appear
-in the self test log page as an aborted self test. This problem is fixed
-in lk 2.4.22 and the lk 2.6 series (by extending the
-timeout to 2 hours). To be on the safe side use the background extended
-test instead. Also some disks silently ignore foreground self 
-tests (e.g. Seagate Cheetah 15K.1).
-</para></footnote>
-</para>
-<para>
-Background self tests can be aborted with the <command>smartctl -X 
-&lt;device&gt; </command> command. The self test log will note that an
-abort was requested.
-</para>
-<para>
-Self tests other than the default self test cause an entry to be placed
-in the self test results log page. The 20 most recent self tests are
-held. The self test results can be viewed with the
-<command>smartctl -l selftest &lt;device&gt;</command> command. All tests
-output the accumulated power on hours when the test was performed and
-the success or otherwise (e.g. the self test was aborted by the user's
-request) of the test. Unsuccessful self tests output a self test segment 
-number (vendor specific), the logical block address of the first failure
-(if appropriate) and a sense_key,asc,ascq triple (see appendix). Following
-the self test result table is the expected duration of an uninterrupted 
-extended self test (when that figure is provided by the device). 
-</para>
-<para>
-Here is an example of a self test log:
-<programlisting>
-# smartctl -l selftest /dev/sda
-smartctl version 5.31 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-SMART Self-test log
-Num  Test              Status         segment  LifeTime  LBA_first_err [SK ASC ASQ]
-     Description                      number   (hours)
-# 1  Background short  Completed           -    30                   - [-   -    -]
-# 2  Background long   Completed           -    18                   - [-   -    -]
-# 3  Background long   Completed           -    11                   - [-   -    -]
-# 4  Background long   Completed           -    11                   - [-   -    -]
-# 5  Background short  Completed           -    11                   - [-   -    -]
-# 6  Background short  Completed           -    10                   - [-   -    -]
-# 7  Background short  Completed           -     6                   - [-   -    -]
-# 8  Background long   Completed           -     6                   - [-   -    -]
-# 9  Background short  Completed           -     6                   - [-   -    -]
-#10  Background short  Completed           -     5                   - [-   -    -]
-#11  Background long   Completed           -     3                   - [-   -    -]
-#12  Background short  Completed           -     3                   - [-   -    -]
-#13  Background short  Completed           -     2                   - [-   -    -]
-#14  Background short  Completed           -     0                   - [-   -    -]
-#15  Background short  Completed           -     0                   - [-   -    -]
-#16  Background short  Completed           -     0                   - [-   -    -]
-#17  Background short  Completed           -     0                   - [-   -    -]
-#18  Background short  Completed           -     0                   - [-   -    -]
-#19  Background short  Completed           -     0                   - [-   -    -]
-
-Long (extended) Self Test duration: 587 seconds [9.8 minutes]
-</programlisting>
-</para>
-</sect1>
-
-<sect1 id="errorlog">
-      <title>Error Logs</title>
-<para>
-The <command>smartctl -l error &lt;device&gt;</command> command displays
-the error counters maintained in the device's log pages. Here is an
-example of an error log:
-<programlisting>
-# smartctl -l error /dev/sda
-smartctl version 5.31 Copyright (C) 2002-4 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-Error counter log:
-          Errors Corrected    Total      Total   Correction     Gigabytes    Total
-              delay:       [rereads/    errors   algorithm      processed    uncorrected
-            minor | major  rewrites]  corrected  invocations   [10^9 bytes]  errors
-read:       2213        0         0      2213       2213        257.214           0
-write:         0        0         0         0          0         29.212           0
-verify:        0        0         0         0          0          0.010           0
-
-Non-medium error count:        0
-</programlisting>
-The displayed error logs (if available) are displayed on separate lines:
-<itemizedlist>
-<listitem><para>
-write error counters
-</para></listitem>
-<listitem><para>
-read error counters
-</para></listitem>
-<listitem><para>
-verify error counters (only displayed if non-zero)
-</para></listitem>
-<listitem><para>
-non-medium error counter (only a single number displayed)
-</para></listitem>
-</itemizedlist>
-Each of the write, read and verify error counter logs has various
-parameters codes. They are itemized below with the smartctl column
-name followed, in brackets, with SCSI standard's description:
-<itemizedlist>
-<listitem><para>
-Error Corrected delay: minor [Errors corrected without substantial delay]
-</para></listitem>
-<listitem><para>
-Error Corrected delay: major [Errors corrected with possible delays]
-</para></listitem>
-<listitem><para>
-Total rereads/rewrites [Total (e.g. rewrites and rereads)]
-</para></listitem>
-<listitem><para>
-Total errors corrected [Total errors corrected]
-</para></listitem>
-<listitem><para>
-Correction algorithm invocations [Total times correction algorithm processed]
-</para></listitem>
-<listitem><para>
-Gigabytes processed {10^9} [Total bytes processed]
-</para></listitem>
-<listitem><para>
-Total uncorrected errors [Total uncorrected errors]
-</para></listitem>
-</itemizedlist>
-</para>
-<para>
-The SCSI standard then goes on to caution that the
-<emphasis>exact</emphasis> definitions of the error counters is not
-part of the standard (i.e. they are vendor specific). Unfortunately
-the current batch of SCSI disk manufacturers' product manuals have
-little or no additional information concerning log pages.
-The disk product manuals do imply that the disk firmware collects
-these counter values and periodically commit them to persistent
-storage (disk or non-volatile RAM).
-<footnote><para>
-This is why some models spring to life after minutes of inactivity and
-perform some operation even though there are no external commands
-pending.
-</para></footnote>
-They also imply that their firmware is monitoring these error counters
-and if they exceed some threshold (e.g. in a certain time interval)
-then the firmware will report a thresholds exceeded.
-</para>
-</sect1>
-
-<sect1 id="smartd">
-      <title>smartd daemon</title>
-<para>
-<command>smartd</command> is a daemon for monitoring disks (both ATA and
-SCSI). It is recommended that tape drives and medium changers are monitored
-in a more manual fashion with the <command>smartctl</command> command
-as discussed in <xref linkend="tapes"/>.
-</para>
-<para>
-The configuration file for <command>smartd</command>
-is called <filename>/etc/smartd.conf</filename> and has a man page (as does
-the <command>smartd</command> command). The controlling daemon script
-is placed in the normal place for a distribution, typically
-<filename>/etc/rc.d/init.d/smartd</filename>.
-</para>
-<para>
-<command>smartd</command> polls the devices it has recognized when it
-was started. By default it polls every 30 minutes. It reports any adverse
-finding and noteworthy occurrences (e.g. disk drive temperature changes)
-to a log file (<filename>/var/log/messages</filename>). <command>smartd
-</command> can be configured to take other actions, for example send
-email to a system administrator.
-</para>
-<para>
-SCSI disks can be discovered by <command>smartd</command> via a scan of 
-device nodes (for linux: <filename>/dev/sda</filename> through to 
-<filename>/dev/sdz</filename>) by placing the word "DEVICESCAN" in
-<filename>/etc/smartd.conf</filename> file. Alternatively the
-"DEVICESCAN" word can be removed (or commented out) and SCSI devices
-named explicitly:
-<programlisting>
-/dev/sda -d scsi
-/dev/sdb -d scsi
-</programlisting>
-The "-d scsi" argument overrides what <command>smartd</command> would
-guess as the device class (i.e. "ata", "scsi" or "3ware"). 
-</para>
-</sect1>
-
-<sect1 id="tapes">
-      <title>TapeAlert</title>
-<para>
-TapeAlert (or "tape alerts") is closely related to the 
-<acronym>SMART</acronym> infrastructure provided for SCSI disks.
-TapeAlert is specialized for tape and medium changer devices. An example of
-a TapeAlert is an indication that the tape drive heads need to be cleaned.
-</para>
-<para>
-Pending TapeAlert errors can be read from the TapeAlert log page
-(using <command>smartctl</command>). This can be done even when 
-<acronym>SMART</acronym>
-monitoring is disabled (e.g. after <command>smartctl -s off &lt;tape_device
-&gt;</command>).  In fact, the best way to use the TapeAlert mechanism is 
-to poll the flags (with <command>smartctl</command>) at relevant times when
-using the tape, for example:
-<itemizedlist>
-<listitem><para>
-when starting a new job using the tape drive
-</para></listitem>
-<listitem><para>
-after an unrecoverable error
-</para></listitem>
-<listitem><para>
-at the end of using each tape (and before it is unloaded)
-</para></listitem>
-</itemizedlist>
-</para>
-<para>
-The TapeAlert information is divided into three severity classes:
-Critical, Warning, and Information. The critical messages require
-urgent user intervention. Both critical and warning errors may lead to
-loss of data. Some of the errors are related to the medium and others
-to the tape drive itself. This is why the TapeAlert information should be
-checked when the tape is in use and not polled periodically (i.e. the 
-<command>smartd</command> daemon with its periodic polling is not
-particularly useful for TapeAlert mechanism).
-</para>
-<para>
-Different sets of flags are defined for tape drives and media
-changers. Most of the flags are optional and the set of flags
-supported depends on the device. TapeAlert is being included into the
-SCSI-3 standards. Many SCSI-2 drives support TapeAlert but the
-implementation may not fully conform to the SCSI-3 draft definition
-used by smartmontools.
-</para>
-<para>
-It is important that only one application
-(or OS driver) is monitoring tape alerts since reading the TapeAlert log 
-page deactivates all flags after they are read. 
-<footnote><para>
-In a multi initiator environment (e.g. several computers sharing the same
-tape jukebox) there should only be one application monitoring tape alerts
-per initiator.
-</para></footnote>
-Currently the Linux SCSI tape drivers (st and osst) do not check the 
-TapeAlert log page. In Linux, a medium changer device (i.e. the robot in
-a tape jukebox) is accessed via its SCSI generic (sg) device name.
-</para>
-<para>
-Code and information on the TapeAlert mechanism have been provided by 
-Kai M&auml;kisara <email>Kai.Makisara at kolumbus dot fi</email>.
-</para>
-</sect1>
-
-<sect1 id="examples">
-      <title>Examples</title>
-<para>
-Here is some output from the <command>smartctl</command>
-command. Mostly it is for the '--all' option.
-<itemizedlist>
-<listitem><para>
-StorageTek LT20 tape 'jukebox': the
-<ulink url="examples/bnch_DLT1.html">
-<literal>tape reading mechanism</literal></ulink>
-and the
-<ulink url="examples/bnch_robot.html">
-<literal>medium changer</literal></ulink> (robot).
-Note the TapeAlert warnings in the medium changer output.
-</para></listitem>
-<listitem><para>
-HP DDS-4 
-<ulink url="examples/hp_c5713a_smt_a.html">
-<literal>tape</literal></ulink>
-drive.
-</para></listitem>
-<listitem><para>
-Generic ATAPI CD-RW
-<ulink url="examples/atapi_cdrw_smt_a.html">
-<literal>cd writer</literal></ulink> is an example of a device that
-does not support <acronym>SMART</acronym>.
-</para></listitem>
-<listitem><para>
-IBM DDRS 39130
-<ulink url="examples/ddrs_39130_smt_a.html">
-<literal>disk</literal></ulink>
- manufactured in 1998. 
-</para></listitem>
-<listitem><para>
-Fujitsu MAM3184MP 18 GigaByte 
-<ulink url="examples/mam3184_smt_a.html">
-<literal>disk</literal></ulink> when all is well. Here is the output from
-the <command>smartctl -H</command> command after the IEC Test bit has been 
-set (with the <command>smartctl -s on -r ioctl,3</command> command) on the
-same Fujitsu <ulink url="examples/mam3184_smt_health.html">
-<literal>disk</literal></ulink> .
-</para></listitem>
-<listitem><para>
-Fujitsu MAP3735NP 73 GigaByte 
-<ulink url="examples/map3735_smt_a.html">
-<literal>disk</literal></ulink>
-</para></listitem>
-<listitem><para>
-Quantum ATLAS IV 36 WLS, 36 GigaByte 
-<ulink url="examples/ativ_36_smt_a.html">
-<literal>disk</literal></ulink>
-</para></listitem>
-<listitem><para>
-Seagate Cheetah ST318451LW 18 GigaByte 
-<ulink url="examples/st318451_smt_a.html">
-<literal>disk</literal></ulink>. It would seem that the total count of bytes
-written is reset every time the disk is power cycled. However the total
-count of bytes read seems to accumulate over power cycles.
-</para></listitem>
-</itemizedlist>
-
-</para>
-</sect1>
-
-<sect1 id="raid">
-      <title>RAID</title>
-<para>
-It is unlikely that a hardware RAID controller will directly support 
-smartmontools. A SCSI RAID controller is a virtual target device that 
-essentially remaps the SCSI commands it receives to the physical disks on its 
-internal buses. The physical disks in a "SCSI" RAID could be ATA or sATA
-disks, in this case a SCSI bus is used between the host computer and an
-external RAID controller since LVD SCSI buses (SPI-2,3 and 4) can run 
-up to 25 metres (plus other protocol related issues).
-</para>
-<para>
-Some SCSI RAIDs equipped internally with SCSI disks allow access to the 
-physical disks via logical unit numbers (LUNs) greater than 0. The SCSI RAID
-controller itself takes a LUN equal to 0. In this case smartmontools could
-be applied to the LUNs greater than 0 that refer to physical disks.
-</para>
-<para>
-Some SCSI RAIDs equipped internally ATA disks have a mechanism that
-allows ATA commands to be tunnelled to the ATA disks. The 3ware 6000
-and 7000 series Escalade controllers are examples. In this case,
-special provision has been made in smartmontools (starting with
-release 5.1-16) to tunnel the ATA command required through to the
-physical disks.  This is done by using the <command>-d 3ware,N</command>
-option/Directive. See the <command>smartctl</command> 
-and <command>smartd</command> man pages for details.
-</para>
-</sect1>
-
-<appendix id="Details">
-      <title>Details</title>
-<sect1 id="stand">
-      <title>Standards</title>
-<para>
-One of the first surprises working with SCSI devices and smartmontools
-is that the SCSI standards (found at <ulink url="http://www.t10.org">
-<literal>www.t10.org</literal></ulink>)
-do <emphasis>not</emphasis> use
-the term <acronym>SMART</acronym>. Instead the awkward term "Informational
-Exceptions" (IE) is used.
-</para>
-<para>
-The original SCSI standard (over 20 years old now) and the SCSI-2 standard
-were monolithic documents. In SCSI-3 and beyond the SCSI standards have
-been sub-divided and three categories of interest are the:
-<itemizedlist>
-<listitem><para>architectural model [SAM-3]</para></listitem>
-<listitem><para>command sets [SPC-3, SBC-2, SSC-2, SMC-2, etc]
-</para></listitem>
-<listitem><para>transports [SPI-4, SBP-2, FCP-3, SAS, etc]</para></listitem>
-</itemizedlist>
-The architectural model while interesting says nothing specific about
-Informational Exceptions or related topics. With respect to the transports
-the term <emphasis>SCSI</emphasis> has often been synonymous with one
-of the SCSI Parallel Interface transports (e.g. SPI-4 which is often know
-as "Ultra320") however this is unhelpful. For the purpose of smartmontools
-the SCSI command sets are more interesting. The main reference is the
-SCSI Primary Commands (SPC-3) document, specifically these sections:
-<itemizedlist>
-<listitem><para>self test operations; SEND DIAGNOSTIC command (which is
-the mechanism for requesting self tests)
-</para></listitem>
-<listitem><para>MODE SENSE and MODE SELECT commands (both 6 and 10 byte
-variants); Mode parameters [the Informational Exceptions Control (IEC) mode
-page and the Control mode page]
-</para></listitem>
-<listitem><para>LOG SENSE and LOG SELECT commands;
-Log parameters [these log pages: Informational exceptions,
-read/write/verify error counters, non medium error count, temperature, 
-start-stop cycle counter and the self test results]
-</para></listitem>
-</itemizedlist>
-The SCSI Block Commands (SBC-2) document covers random access storage
-devices such as disks (but excluding CD/DVD readers and writers which are
-covered by MMC-3) while the SCSI Streaming Commands (SSC-2) document covers 
-tape systems.  The SBC-2 standard does not contain any additional 
-information (compared with SPC-3) about Informational Exceptions. 
-The SSC-2 standard covers TapeAlert (section 4.2.15), some extra facilities in
-the IEC mode page (see the mode parameters section) and some additional
-log pages. Medium changers, typically the "robots" in jukebox tape systems,
-often support the TapeAlert mechanism and are described in the SMC-2 standard. 
-</para>
-</sect1>
-
-<sect1 id="infoexc">
-      <title>Informational Exceptions</title>
-<para>
-So what are Informational Exceptions in the SCSI context? They are a
-set of vendor specific parameters that the device firmware monitors and 
-if a "failure prediction threshold" is exceeded then an exception is
-reported. A user is also able to set thresholds on error counters and
-have an exception reported if a condition is met. Additionally most
-modern disks monitor their temperature and will issue a warning if
-a temperature threshold is exceeded.
-</para>
-<para>
-The "failure prediction threshold" exception reporting and the temperature
-warning are separately controlled (in byte 2 of the Informational Exceptions
-Control (IEC) mode page).
-<footnote><para>
-Henceforth the term <emphasis>Informational Exceptions</emphasis>
-(or IE) will include both Informational Exceptions and the
-temperature (or "enclosure degraded") warnings.
-</para></footnote>
-In smartmontools the
-<command>smartctl -s on &lt;device&gt;</command> command turns on IE.
-There are various reasons why this may not (fully) work (e.g. IEC mode
-page not available or not changeable) so this command queries the device
-again after it has attempted the change and reports the state.
-The <command>smartctl -s off &lt;device&gt;</command> command turns off
-IE reporting.
-<footnote><para>
-IE have a (minor) performance impact on a disk. There are various other
-settings in the IEC mode page (e.g. PERF, EBF and LOGERR) that address
-this. The standard gives a lot of latitude to the vendor in implementing
-these additional flags. This finer level of control may be added to 
-smartmontools if the need arises.
-</para></footnote>
-</para>
-<sect2 id="iereport">
-      <title>IE reporting</title>
-<para>
-Informational Exceptions are reported via the standard SCSI status
-reporting mechanism of an additional sense code (asc) and an additional
-sense code qualifier (ascq) pair. A selection of these pairs and the 
-associated message (there is full list in the SPC-3 document) is listed 
-here:
-<programlisting>
-asc    ascq   message
--------------------------------------------------------
-0xb    0x1    Warning - specified temperature exceeded
-0x5d   0x0    Failure prediction threshold exceeded
-0x5d   0x2    Media failure prediction threshold exceeded
-0x5d   0x10   Hardware impending failure general hard drive failure
-0x5d   0x11   Hardware impending failure drive error rate too high
-0x5d   0x56   Spindle impending failure start unit times too high
-0x5d   0xff   Failure prediction threshold exceeded (false)
-</programlisting>
-The last entry in the above table results from setting the TEST bit and
-is for exercising the reporting mechanism rather than the indication
-of an actual error.
-See this <link linkend="testbit">footnote</link> for more information.
-</para>
-<para>
-One difficulty is that the device firmware may detect these conditions
-independently of any command executing. Even if it detects an informational
-exception during a command it needs to be careful sending IE error
-notifications back with a command especially if that command succeeded
-(Linux will not handle this too well in the 2.4 kernel series). 
-There is asynchronous event notification (AEN) in SCSI but it is not
-reliably supported across all transports. So smartmontools relies
-on a poll from the <command>smartd</command> daemon (the default
-is every 30 minutes) to detect informational exceptions.
-</para>
-<para>
-The additional sense code and its qualifier are part of what is termed as
-the <emphasis>sense buffer</emphasis> which is the response to a 
-REQUEST SENSE command. The sense key is also found in the sense buffer.
-Synchronous SCSI commands that fail return a single byte status code of
-CHECK CONDITION. An OS kernel would see this error/warning status and
-then check the sense buffer (by doing a REQUEST SENSE or by other means)
-and decide how to continue. From smartmontools's point of view, its
-<command>smartd</command> daemon would like to process Informational 
-Exceptions without interference from the OS. This is done by setting up
-the IEC mode page's MRIE field set to 6. This instructs the SCSI 
-device to hold a pending exception until an unsolicited REQUEST SENSE is 
-sent. If an exception is pending then the sense key will be "NO SENSE"
-and the asc, ascq pair will be set accordingly. In the case of no pending
-exception the asc,ascq pair will both be zero. The pending exception is 
-also visible in the IE log page, if that is supported. So 
-<command>smartd</command> can check the device during its normal polling 
-cycle.
-</para>
-<para>
-Pending informational exceptions can also be checked by running
-<command>smartctl -H &lt;device&gt;</command>. A message of
-"SMART Health Status: OK" indicates that there is no pending IE.
-<footnote><para>
-<anchor id="testbit"/>
-One might worry whether the <command>smartd</command> daemon is properly set
-up or if the device really will issue IE when the need arises. The mechanism
-can be tested by setting the TEST bit in the IEC mode page. That is
-done by this command: <command>smartctl -r ioctl,3 -s on &lt;device&gt;
-</command> [ignore the extra debugging output that "-r ioctl,3" causes]. A
-special asc/ascq pair is reserved for testing (0x5d,0xff)
-and the standard associates with it this awkward message: "Failure prediction 
-threshold exceeded (false)". A call to 
-<command>smartctl -H &lt;device&gt;</command> or waiting until the next 
-<command>smartd</command> poll should produce that message if the mechanism 
-is working. The IEC mode page TEST bit can be turned off (i.e. back to normal
-IE) with <command>smartctl -s on &lt;device&gt;</command>. The output
-after the TEST bit has been activated is shown in the 
-Examples section for the Fujitsu MAM3184 disk.
-</para></footnote>
-</para>
-</sect2>
-</sect1>
-
-<sect1 id="ctldebug">
-      <title>smartctl debug</title>
-<para>
-Debug information for <command>smartctl</command> is output when 
-the <command>-r ioctl</command> or the <command>-r scsiioctl</command>
-option is used.  More debug is output when the <command>-r ioctl,&lt;n&gt;
-</command> form is used (where "n" is a number greater or equal to 1). Both 
-<command>-r ioctl</command> and <command>r scsiioctl,1</command> select
-the same amount of SCSI debug information. The debug levels currently 
-defined are:
-<itemizedlist>
-<listitem><para>
-1 - output SCSI commands sent to the device and the status received from
-the device
-</para></listitem>
-<listitem><para>
-2 - additionally, output the first 64 bytes of data sent to or received from
-the device
-</para></listitem>
-<listitem><para>
-3 - additionally, set the IEC mode page TEST bit if accompanying the '-s on'
-option
-</para></listitem>
-</itemizedlist>
-See this <link linkend="testbit">footnote</link> for more information about the
-use of the IEC mode page TEST bit.
-</para>
-<para>
-One shortcoming of the Informational Exception data provided by
-SCSI devices (at least as defined in the current standard) is that
-no LOG SENSE page tells the user how many hours the device has been
-in use for. The device needs to track its "age" for applying timestamps
-to self test results (seen in the "Lifetime (hours)" column of the
-<command>smartctl -l selftest</command> command) if they are supported.
-So one way to circumvent this shortcoming is to do dummy self 
-tests. Hence do a <command>smartctl -t short</command> command and then
-wait 2 minutes to see the result in the self test log in which the most
-recent self test row (i.e. the first) will have the current lifetime of
-the device.
-</para>
-</sect1>
-
-<sect1 id="links">
-      <title>Links</title>
-<para>
-Here are some links to related projects and packages:
-<itemizedlist>
-<listitem><para>
-<anchor id="t10"/>
-primary reference site for SCSI architecture, command sets and transports
-<ulink url="http://www.t10.org">
-<literal>www.t10.org</literal></ulink>.
-<footnote><para>
-The documents found on the t10 site are actually <emphasis>draft</emphasis>
-standards. Once they are ratified they become available from ANSI for
-a fee. The t10 site maintains the last draft prior to ratification and
-the most recent draft of yet to be ratified standards.
-</para></footnote>
-</para></listitem>
-<listitem><para>
-<anchor id="scsirastools"/>
-SCSI raid monitoring tools plus a firmware update utility and other low level
-tools <ulink url="http://scsirastools.sourceforge.net">
-<literal>scsirastools.sourceforge.net</literal></ulink> .
-</para></listitem>
-<listitem><para>
-<anchor id="sg3utils"/>
-A package of SCSI low level tools for Linux called sg3_utils can be found
-on this page <ulink url="http://www.torque.net/sg">
-<literal>www.torque.net/sg</literal></ulink> (the most recent version
-is sg3_utils-1.06). Allows command level access to SCSI devices.
-</para></listitem>
-<listitem><para>
-<anchor id="howto"/>
-There is a HOWTO on the Linux SCSI subsystem in the 2.4 series here:
-<ulink url="http://www.tldp.org/HOWTO/SCSI-2.4-HOWTO">
-<literal>www.tldp.org/HOWTO/SCSI-2.4-HOWTO</literal></ulink>.
-</para></listitem>
-</itemizedlist>
-</para>
-
-<para>
-CVS $Id: smartmontools_scsi.xml,v 1.9 2004/05/05 23:00:24 dpgilbert Exp $
-</para>
-</sect1>
-</appendix>
-
-</article>
-