From 61d36f42851b7cffc5d9a1681d7844064d65a432 Mon Sep 17 00:00:00 2001
From: "(no author)" <(no author)@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Thu, 1 May 2003 08:51:47 +0000
Subject: [PATCH] This commit was manufactured by cvs2svn to create branch
 'unlabeled-1.76.2'.

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/branches/unlabeled-1.76.2@721 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 CVSROOT/checkoutlist                 |   13 -
 CVSROOT/commitinfo                   |   15 -
 CVSROOT/config                       |   14 -
 CVSROOT/cvswrappers                  |   23 -
 CVSROOT/editinfo                     |   21 -
 CVSROOT/loginfo                      |   28 -
 CVSROOT/modules                      |   26 -
 CVSROOT/notify                       |   12 -
 CVSROOT/rcsinfo                      |   13 -
 CVSROOT/taginfo                      |   20 -
 CVSROOT/verifymsg                    |   21 -
 sm5/CHANGELOG                        |  755 ---------
 sm5/COPYING                          |  340 ----
 sm5/Makefile                         |  182 ---
 sm5/README                           |  263 ----
 sm5/TODO                             |   73 -
 sm5/VERSION                          |    1 -
 sm5/WARNINGS                         |   16 -
 sm5/add                              |    8 -
 sm5/atacmds.c                        | 1530 ------------------
 sm5/atacmds.cpp                      | 1530 ------------------
 sm5/atacmds.h                        |  426 -----
 sm5/ataprint.c                       | 1225 ---------------
 sm5/ataprint.cpp                     | 1225 ---------------
 sm5/ataprint.h                       |   70 -
 sm5/cvs-script                       |    6 -
 sm5/examplescripts/Example1          |   41 -
 sm5/examplescripts/Example2          |   21 -
 sm5/examplescripts/Example3          |   25 -
 sm5/examplescripts/README            |   50 -
 sm5/extern.h                         |   82 -
 sm5/knowndrives.c                    |  412 -----
 sm5/knowndrives.cpp                  |  412 -----
 sm5/knowndrives.h                    |   82 -
 sm5/scsicmds.c                       | 1631 -------------------
 sm5/scsicmds.cpp                     | 1631 -------------------
 sm5/scsicmds.h                       |  299 ----
 sm5/scsiprint.c                      |  707 ---------
 sm5/scsiprint.cpp                    |  707 ---------
 sm5/scsiprint.h                      |   40 -
 sm5/smartctl.8                       |  890 -----------
 sm5/smartctl.c                       |  714 ---------
 sm5/smartctl.h                       |   72 -
 sm5/smartd.8                         | 1248 ---------------
 sm5/smartd.c                         | 2180 --------------------------
 sm5/smartd.conf                      |   65 -
 sm5/smartd.conf.5                    |  867 ----------
 sm5/smartd.cpp                       | 2180 --------------------------
 sm5/smartd.h                         |  179 ---
 sm5/smartd.initd                     |   55 -
 sm5/smartmontools.spec               |  727 ---------
 sm5/utility.c                        |  254 ---
 sm5/utility.cpp                      |  254 ---
 sm5/utility.h                        |   74 -
 www/cvs-script                       |    6 -
 www/examples/HITACHI_DK23BA-20-0.txt |  163 --
 www/examples/IC35L120AVV207-0.txt    |   67 -
 www/examples/IC35L120AVVA07-0-0.txt  |   69 -
 www/examples/IC35L120AVVA07-0-1.txt  |   67 -
 www/examples/MAXTOR-0.txt            |  139 --
 www/examples/MAXTOR-1.txt            |  143 --
 www/examples/MAXTOR-2.txt            |   79 -
 www/examples/MAXTOR-3.txt            |   67 -
 www/examples/MAXTOR-4.txt            |   65 -
 www/examples/MAXTOR-6.txt            |  156 --
 www/examples/Maxtor-5.txt            |  127 --
 www/examples/TOSHIBA-0.txt           |   73 -
 www/examples/TOSHIBA-MK6021GAS.txt   |   74 -
 www/index.html                       |  467 ------
 www/script                           |   24 -
 70 files changed, 25541 deletions(-)
 delete mode 100644 CVSROOT/checkoutlist
 delete mode 100644 CVSROOT/commitinfo
 delete mode 100644 CVSROOT/config
 delete mode 100644 CVSROOT/cvswrappers
 delete mode 100644 CVSROOT/editinfo
 delete mode 100644 CVSROOT/loginfo
 delete mode 100644 CVSROOT/modules
 delete mode 100644 CVSROOT/notify
 delete mode 100644 CVSROOT/rcsinfo
 delete mode 100644 CVSROOT/taginfo
 delete mode 100644 CVSROOT/verifymsg
 delete mode 100644 sm5/CHANGELOG
 delete mode 100644 sm5/COPYING
 delete mode 100644 sm5/Makefile
 delete mode 100644 sm5/README
 delete mode 100644 sm5/TODO
 delete mode 100644 sm5/VERSION
 delete mode 100644 sm5/WARNINGS
 delete mode 100755 sm5/add
 delete mode 100644 sm5/atacmds.c
 delete mode 100644 sm5/atacmds.cpp
 delete mode 100644 sm5/atacmds.h
 delete mode 100644 sm5/ataprint.c
 delete mode 100644 sm5/ataprint.cpp
 delete mode 100644 sm5/ataprint.h
 delete mode 100755 sm5/cvs-script
 delete mode 100755 sm5/examplescripts/Example1
 delete mode 100755 sm5/examplescripts/Example2
 delete mode 100755 sm5/examplescripts/Example3
 delete mode 100644 sm5/examplescripts/README
 delete mode 100644 sm5/extern.h
 delete mode 100644 sm5/knowndrives.c
 delete mode 100644 sm5/knowndrives.cpp
 delete mode 100644 sm5/knowndrives.h
 delete mode 100644 sm5/scsicmds.c
 delete mode 100644 sm5/scsicmds.cpp
 delete mode 100644 sm5/scsicmds.h
 delete mode 100644 sm5/scsiprint.c
 delete mode 100644 sm5/scsiprint.cpp
 delete mode 100644 sm5/scsiprint.h
 delete mode 100644 sm5/smartctl.8
 delete mode 100644 sm5/smartctl.c
 delete mode 100644 sm5/smartctl.h
 delete mode 100644 sm5/smartd.8
 delete mode 100644 sm5/smartd.c
 delete mode 100644 sm5/smartd.conf
 delete mode 100644 sm5/smartd.conf.5
 delete mode 100644 sm5/smartd.cpp
 delete mode 100644 sm5/smartd.h
 delete mode 100755 sm5/smartd.initd
 delete mode 100644 sm5/smartmontools.spec
 delete mode 100644 sm5/utility.c
 delete mode 100644 sm5/utility.cpp
 delete mode 100644 sm5/utility.h
 delete mode 100755 www/cvs-script
 delete mode 100644 www/examples/HITACHI_DK23BA-20-0.txt
 delete mode 100644 www/examples/IC35L120AVV207-0.txt
 delete mode 100644 www/examples/IC35L120AVVA07-0-0.txt
 delete mode 100644 www/examples/IC35L120AVVA07-0-1.txt
 delete mode 100644 www/examples/MAXTOR-0.txt
 delete mode 100644 www/examples/MAXTOR-1.txt
 delete mode 100644 www/examples/MAXTOR-2.txt
 delete mode 100644 www/examples/MAXTOR-3.txt
 delete mode 100644 www/examples/MAXTOR-4.txt
 delete mode 100644 www/examples/MAXTOR-6.txt
 delete mode 100644 www/examples/Maxtor-5.txt
 delete mode 100644 www/examples/TOSHIBA-0.txt
 delete mode 100644 www/examples/TOSHIBA-MK6021GAS.txt
 delete mode 100644 www/index.html
 delete mode 100755 www/script

diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist
deleted file mode 100644
index b04b3501f..000000000
--- 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 b19e7b7a6..000000000
--- 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 ff43ec005..000000000
--- 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 0accaf1b1..000000000
--- 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 d78886c15..000000000
--- 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 f31e552dd..000000000
--- a/CVSROOT/loginfo
+++ /dev/null
@@ -1,28 +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
-^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 cb9e9efc9..000000000
--- 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 34f0bc288..000000000
--- 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 49e59f4d0..000000000
--- 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 274a46dd5..000000000
--- 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 86f747ce2..000000000
--- 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/CHANGELOG b/sm5/CHANGELOG
deleted file mode 100644
index e5b31072c..000000000
--- a/sm5/CHANGELOG
+++ /dev/null
@@ -1,755 +0,0 @@
-CHANGELOG for smartmontools
-
-$Id: CHANGELOG,v 1.133 2003/04/30 10:16:03 makisara Exp $
-
-Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
-Home page of code is: 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/
-
-Maintainers/Developers Key:
-[BA] Bruce Allen            <smartmontools-support@lists.sourceforge.net>
-[EB] Erik Inge Bols�        <knan@mo.himolde.no>
-[SB] Stanislav Brabec       <sbrabec@suse.cz>
-[PC] Peter Cassidy          <pcassidy@mac.com>
-[FM] Frederic L. W. Meunier <0@pervalidus.net>
-[PW] Phil Williams          <phil@subbacultcha.demon.co.uk>
-[DG] Douglas Gilbert        <dougg@torque.net>
-[GG] Guido Guenther         <agx@sigxcpu.org>
-[KM] Kai M�kisara	    <kai.makisara@kolumbus.fi>
-
-NOTES FOR FUTURE RELEASES: see TODO file.
-
-CURRENT DEVELOPMENT VERSION (see VERSION file in this directory):
- 
-  <ADDITIONS TO THE CHANGE LOG SHOULD BE ADDED HERE, PLEASE>
-  [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@yoyodyne.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 60549be51..000000000
--- 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) 19yy  <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) 19yy 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/Makefile b/sm5/Makefile
deleted file mode 100644
index cd000723a..000000000
--- a/sm5/Makefile
+++ /dev/null
@@ -1,182 +0,0 @@
-# Makefile for smartmontools
-#
-# Home page: http://smartmontools.sourceforge.net
-#
-# $Id: Makefile,v 1.65 2003/04/23 13:19:40 guidog Exp $
-#
-# Copyright (C) 2002-3 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/
-
-CC	= gcc
-
-# Debugging
-# CFLAGS = -fsigned-char -Wall -g
-
-# Build against kernel header files.  Change linux-2.4 to correct path for your system
-# CFLAGS	= -fsigned-char -Wall -O2 -I./usr/src/linux-2.4/include
-
-# Normal build NOTE: I have had reports that with gcc 3.2 this code
-# fails if you use anything but -Os.  I'll remove this comment when
-# this is resolved, or I am reminded of it! GCC GNATS bug report
-# #8404.  If you are getting strange output from gcc 3.2 try
-# uncommenting LDFLAGS -s below.  Stripping the symbols seems to fix
-# the problem.
-CFLAGS	 = -fsigned-char -Wall -O2
-CPPFLAGS = -DHAVE_GETOPT_H -DHAVE_GETOPT_LONG
-LDFLAGS  = # -s
-
-GZIP=/bin/gzip
-INSTALL = install
-INSTALL_PROGRAM = ${INSTALL}
-INSTALL_DATA = ${INSTALL} -m 644
-
-releasefiles=atacmds.c atacmds.h ataprint.c ataprint.h CHANGELOG COPYING \
-  extern.h knowndrives.c knowndrives.h Makefile README scsicmds.c scsicmds.h \
-  scsiprint.c scsiprint.h smartctl.8 smartctl.c smartctl.h smartd.8 smartd.c \
-  smartd.h smartd.initd TODO WARNINGS VERSION smartd.conf smartd.conf.5 \
-  utility.c utility.h examplescripts/
-
-counter=$(shell cat VERSION)
-pkgname=smartmontools-5.1
-pkgname2=$(pkgname)-$(counter)
-
-docdir=/usr/share/doc/$(pkgname)
-es=examplescripts
-examplesdir=$(docdir)/$(es)
-
-all: smartd smartctl
-	@echo -e "\n\nSmartd can now use a configuration file /etc/smartd.conf. Do:\n\n\tman ./smartctl.8\n\tman ./smartd.8\n\tman ./smartd.conf.5\n"
-	@echo -e "to read the manual pages now.  Unless you do a \"make install\" the manual pages won't be installed.\n"
-
-smartctl: smartctl.c atacmds.o ataprint.o scsicmds.o scsiprint.o utility.o knowndrives.o\
-          smartctl.h atacmds.h ataprint.h scsicmds.h scsiprint.h \
-          utility.h extern.h knowndrives.h VERSION Makefile
-	$(CC) -DSMARTMONTOOLS_VERSION=$(counter) -o smartctl $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) smartctl.c \
-                                      atacmds.o ataprint.o knowndrives.o scsicmds.o scsiprint.o utility.o
-
-smartd:  smartd.c atacmds.o ataprint.o scsicmds.o utility.o knowndrives.o \
-         smartd.h atacmds.h ataprint.h knowndrives.h scsicmds.h utility.h extern.h VERSION \
-         Makefile
-	$(CC) -DSMARTMONTOOLS_VERSION=$(counter) -o smartd $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) smartd.c \
-                                      atacmds.o ataprint.o knowndrives.o scsicmds.o utility.o 
-
-atacmds.o: atacmds.c atacmds.h utility.h extern.h Makefile
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c atacmds.c 
-
-ataprint.o: ataprint.c atacmds.h ataprint.h knowndrives.h smartctl.h extern.h utility.h \
-            Makefile
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c ataprint.c
-
-scsicmds.o: scsicmds.c scsicmds.h extern.h Makefile
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c scsicmds.c
-
-scsiprint.o: scsiprint.c extern.h scsicmds.h scsiprint.h smartctl.h utility.h Makefile
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c scsiprint.c
-
-utility.o: utility.c utility.h Makefile
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c utility.c
-
-knowndrives.o: knowndrives.c knowndrives.h utility.h atacmds.h ataprint.h Makefile
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c knowndrives.c
-
-
-
-# This extracts the configuration file directives from smartd.8 and
-# inserts them into smartd.conf.5
-smartd.conf.5: smartd.8
-	sed '1,/STARTINCLUDE/ D;/ENDINCLUDE/,$$D' < smartd.8 > tmp.directives
-	sed '/STARTINCLUDE/,$$D'  < smartd.conf.5 > tmp.head
-	sed '1,/ENDINCLUDE/D'   < smartd.conf.5 > tmp.tail
-	cat tmp.head            > smartd.conf.5
-	echo "\# STARTINCLUDE" >> smartd.conf.5
-	cat tmp.directives     >> smartd.conf.5
-	echo "\# ENDINCLUDE"   >> smartd.conf.5
-	cat tmp.tail           >> smartd.conf.5
-	rm -f tmp.head tmp.tail tmp.directives
-clean:
-	rm -f *.o smartctl smartd *~ \#*\# smartmontools*.tar.gz smartmontools*.rpm temp.* smart*.8.gz smart*.5.gz
-
-install:
-	if [ ! -f smartd -o ! -f smartctl ] ; then echo -e "\n\nYOU MUST FIRST DO \"make\"\n" ; exit 1 ; fi
-	$(GZIP) -c smartctl.8 > smartctl.8.gz
-	$(GZIP) -c smartd.8   > smartd.8.gz
-	$(GZIP) -c smartd.conf.5 > smartd.conf.5.gz
-	rm -f $(DESTDIR)/usr/share/man/man8/smartctl.8
-	rm -f $(DESTDIR)/usr/share/man/man8/smartd.8
-	$(INSTALL_PROGRAM) -D smartctl         $(DESTDIR)/usr/sbin/smartctl
-	$(INSTALL_PROGRAM) -D smartd           $(DESTDIR)/usr/sbin/smartd
-	$(INSTALL_PROGRAM) -D smartd.initd     $(DESTDIR)/etc/rc.d/init.d/smartd
-	$(INSTALL_DATA) -D smartctl.8.gz    $(DESTDIR)/usr/share/man/man8/smartctl.8.gz
-	$(INSTALL_DATA) -D smartd.8.gz      $(DESTDIR)/usr/share/man/man8/smartd.8.gz
-	$(INSTALL_DATA) -D smartd.conf.5.gz $(DESTDIR)/usr/share/man/man5/smartd.conf.5.gz
-	$(INSTALL_DATA) -D CHANGELOG        $(DESTDIR)/$(docdir)/CHANGELOG
-	$(INSTALL_DATA) -D COPYING          $(DESTDIR)/$(docdir)/COPYING
-	$(INSTALL_DATA) -D README           $(DESTDIR)/$(docdir)/README
-	$(INSTALL_DATA) -D TODO             $(DESTDIR)/$(docdir)/TODO
-	$(INSTALL_DATA) -D VERSION          $(DESTDIR)/$(docdir)/VERSION
-	$(INSTALL_DATA) -D WARNINGS         $(DESTDIR)/$(docdir)/WARNINGS
-	$(INSTALL_DATA) -D smartd.conf      $(DESTDIR)/$(docdir)/smartd.conf
-	$(INSTALL_DATA) -D $(es)/README     $(DESTDIR)/$(docdir)/$(es)/README
-	$(INSTALL_PROGRAM) -D $(es)/Example1   $(DESTDIR)/$(examplesdir)/Example1
-	$(INSTALL_PROGRAM) -D $(es)/Example2   $(DESTDIR)/$(examplesdir)/Example2
-	$(INSTALL_PROGRAM) -D $(es)/Example3   $(DESTDIR)/$(examplesdir)/Example3
-	if [ ! -f $(DESTDIR)/etc/smartd.conf ]; then			      \
-	    $(INSTALL_DATA) -D smartd.conf $(DESTDIR)/etc/smartd.conf; \
-	else								      \
-	    $(INSTALL_DATA) -D smartd.conf $(DESTDIR)/etc/smartd.conf.example;\
-	fi
-	@echo -e "\n\nTo manually start smartd on bootup, run /etc/rc.d/init.d/smartd start"
-	@echo "To automatically start smartd on bootup, run /sbin/chkconfig --add smartd"
-	@echo -e "\n\nSmartd can now use a configuration file /etc/smartd.conf. Do:\nman 8 smartd\n."
-	@echo -e "A sample configuration file may be found in ${docdir}.\n\n"
-
-# perhaps for consistency I should also have $(DESTDIR) for the uninstall...
-uninstall:
-	rm -f /usr/share/man/man8/smartctl.8 /usr/share/man/man8/smartd.8 /usr/sbin/smartctl \
-              /usr/share/man/man8/smartctl.8.gz /usr/share/man/man8/smartd.8.gz \
-              /usr/share/man/man5/smartd.conf.5.gz /usr/sbin/smartd 
-	rm -rf /usr/share/doc/smartmontools-5.1/
-	if [ -f /var/lock/subsys/smartd -a -f /etc/rc.d/init.d/smartd ] ; then /etc/rc.d/init.d/smartd stop ; fi
-	if [ -f /etc/rc.d/init.d/smartd ] ; then /sbin/chkconfig --del smartd ; fi
-	if [ -f /etc/rc.d/init.d/smartd ] ; then  rm -f /etc/rc.d/init.d/smartd ; fi
-	if [ -f /etc/smartd.conf.example ] ; then rm -f /etc/smartd.conf.example ; fi
-	if [ -f /etc/smartd.conf ] ; then echo -e "\n\nWe have NOT REMOVED /etc/smartd.conf\n\n" ; fi
-
-
-# Some of this mess is to automatically increment the release numbers.
-# The number of the next release is kept in the file "VERSION"
-release: smartd.conf.5
-	if [ ! -f add -o ! -d CVS ] ; then echo "The make release target requires files checked out of CVS" ; exit 1 ; fi
-	cat smartmontools.spec | sed '/Release:/d' > temp.spec
-	echo "Release: " $(counter) > temp.version
-	cat temp.version temp.spec > smartmontools.spec
-	rm -f temp.spec temp.version
-	. cvs-script && cvs commit -m "Release 5.1.$(counter)"
-	. cvs-script && cvs tag -d "RELEASE_5_1_$(counter)" && cvs tag "RELEASE_5_1_$(counter)"
-	rm -rf $(pkgname)
-	mkdir $(pkgname)
-	cp -a $(releasefiles) $(pkgname)
-	rm -rf $(pkgname)/examplescripts/CVS
-	tar zcvf $(pkgname).tar.gz $(pkgname)
-	mv -f $(pkgname) $(pkgname2)
-	tar zcvf $(pkgname2).tar.gz $(pkgname2)
-	rm -rf $(pkgname2)
-	mv -f $(pkgname).tar.gz /usr/src/redhat/SOURCES/
-	rpm -ba smartmontools.spec
-	mv /usr/src/redhat/RPMS/i386/$(pkgname)*.rpm .
-	mv /usr/src/redhat/SRPMS/$(pkgname)*rpm .
-	rm -f /usr/src/redhat/SOURCES/$(pkgname).tar.gz
-	echo `hostname` | grep -q lap && echo $(shell ./add) > VERSION
diff --git a/sm5/README b/sm5/README
deleted file mode 100644
index 29ca307aa..000000000
--- a/sm5/README
+++ /dev/null
@@ -1,263 +0,0 @@
-===============================================
-SMARTMONTOOLS - SMART utility toolset for Linux
-===============================================
-
-== 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-3 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.
-
-SEE THE FILE "WARNINGS" FOR REPORTS OF HARDWARE WHERE THESE UTILITIES MIGHT
-CAUSE SERIOUS PROBLEMS SUCH AS LOCKUPS.
-
-If you have just downloaded smartmontools from the URL above, then
-you can read about these commands using the man pages.  Within this
-directory the commands:
-  man ./smartctl.8
-and
-  man ./smartd.8
-
-will display the manual pages for the two commands.  If you have
-already installed the package on your system, then:
-  man smartctl
-and
-  man smartd
-will display the same information.
-
-
-== INSTALLATION ==
-To install, use the commands:
-  make
-  make install
-
-Any recent Linux distribution should support this package.  Note that
-smartmontools requires Linux kernel 2.2.14 or greater in order to run
-at all.  But to give the ATA RETURN SMART STATUS command, the kernel
-needs to support the HDIO_DRIVE_TASK ioctl().  Any 2.4 series kernel
-should provide this support.  I am told that some of the 2.2.20 and
-later kernels also provide this support if they are properly
-patched/configured.
-
-Seventeen files are installed:
-/usr/sbin/smartd                                [Executable daemon]
-/usr/sbin/smartctl                              [Executable command-line utility]
-/etc/rc.d/init.d/smartd                         [Init/Startup script for smartd]
-/usr/share/man/man8/smartctl.8.gz               [Manual page]
-/usr/share/man/man8/smartd.8.gz                 [Manual page]
-/usr/share/man/man5/smartd.conf.5.gz            [Manual page]
-/usr/share/doc/smartmontools-5.1/README         [What you are reading!]
-/usr/share/doc/smartmontools-5.1/TODO           [Things that need to be done/fixed]
-/usr/share/doc/smartmontools-5.1/CHANGELOG      [A log of changes. Also see CVS]
-/usr/share/doc/smartmontools-5.1/COPYING        [GNU Public License.] 
-/usr/share/doc/smartmontools-5.1/VERSION        [Version number]
-/usr/share/doc/smartmontools-5.1/WARNINGS       [Systems where lockups or other serious problems reported]
-/usr/share/doc/smartmontools-5.1/smartd.conf    [Example Configuration file for /etc/]
-/usr/share/doc/smartmontools-5.1/examplescripts [Executable scripts for -M exec of smartd.conf (4 files)]
-
-Source and binary RPM files are available at the website listed above.
-
-PLEASE READ THE MANUAL PAGES FOR SMARTCTL AND SMARTD FOR MORE INFORMATION.
-
-
-STARTING WITH SMARTMONTOOLS 5.1.X, THE COMMAND LINE OPTIONS AND THE
-SMARTD.CONF DIRECTIVES HAVE BEEN RENAMED.  WHAT FOLLOWS IS A SUMMARY
-TABLE SHOWING THE COMPARISON BETWEEN THE OLD AND THE NEW OPTION AND
-DIRECTIVE NAMES.
-
-== NEW OPTION NAMES FOR SMARTCTL 5.1 ==
-The following is a synopsis of the new options in smartctl 5.1 -- please see the
-man pages for more information.
-
-  -h, --help, --usage
-        Show usage and syntax help
-
-  -V, --version, --copyright, --license
-        Show version, copyright, and license info then exit
-
-  -q MODE, --quietmode=MODE
-        Set the quiet mode to one of: errorsonly, silent
-
-  -d TYPE, --device=TYPE
-        Set the device type to one of: ata, scsi
-
-  -T TYPE, --tolerance=TYPE
-        Set tolerance level to one of:
-                normal       - Exit if a mandatory SMART command fails [DEFAULT]
-                conservative - Exit if any SMART command fails
-                permissive   - Continue even if a mandatory SMART command fails
-
-  -b TYPE, --badsum=TYPE
-        Action to take on a bad checksum.  TYPE and its meaning are:
-                warn   - Issue a warning, but continue [DEFAULT] 
-                exit   - Exit smartctl
-                ignore - Continue silently without issuing a warning [NEW]
-
-  -s VALUE, --smart=VALUE
-        Enable/disable SMART.  VALUE is one of: on, off 
-
-  -o VALUE, --offlineauto=VALUE
-        Enable/disable automatic offline testing.  VALUE is one of: on, off 
-
-  -S VALUE, --saveauto=VALUE
-        Enable/disable attribute autosave.  VALUE is one of: on, off 
-
-  -H, --health
-        Show SMART health status
-
-  -c, --capabilities
-        Show SMART capabilities
-
-  -A, --attributes
-        Show SMART vendor-specific attributes and values.
-
-  -l TYPE, --log=TYPE
-        Show device log. Type is one of: error, selftest
-
-  -i, --info
-        Show drive information
-
-  -a, --all
-        Show all SMART information.  Equivalent to -HcAi -l error -l selftest
-
-  -v N,OPTION , --vendorattribute=N,OPTION
-        Set vendor specific OPTION for attribute N.  Currently supported are:
-
-                  N     OPTION          Effect
-                -----------------------------------------------------------
-                009     minutes         Display in minutes instead of hours
-
-        Note that in the future this option may be used multiple times
-        with different arguments, to modify options for different
-        attributes.
-
-  -t TEST, --test=TEST
-        Perform TEST immediately.  TEST is one of: offline, short, long
-
-  -C, --captive
-        When used with -t, performs test in captive mode.  Has no effect on
-        offline test, or when used without -t option.
-
-  -X, --abort
-        Abort any non-captive test
-
-The following table shows the mapping of old to new smartctl options and of
-old to new smartd.conf directives:
-
-  -------------------------------------------------------------------------------------------------------------------
-  smartctl      smartctl options        smartctl options                  smartd.conf               smartd.conf
-  options       Versions >= 5.1         Versions >= 5.1                   DIRECTIVES                DIRECTIVES
-  Versons<=5.0  (short options)         (long options)                    Versions <= 5.0           Versions >= 5.1
-  -------------------------------------------------------------------------------------------------------------------
-  -h, -?        -h, -?                  --help
-  -V            -V                      --version, --copyright, --license
-  -i            -i                      --info                                                          CONFLICT
-  -q            -q errorsonly           --quietmode=errorsonly
-  -Q            -q silent               --quietmode=silent
-  -n            -d ata                  --device=ata                       -A				-d ata
-  -N            -d scsi                 --device=scsi                      -S                           -d scsi
-  -P            -T permissive           --tolerance=permissive             -P                           -T permissive
-  -U            -T conservative         --tolerance=conservative
-  -W            -b                      --badsum=exit
-                -r                      --report=TYPE
-  -e            -s on                   --smart=on
-  -d            -s off                  --smart=off
-  -t            -o on                   --offlineauto=on                   -T 1                         -o on
-  -T            -o off                  --offlineauto=off                  -T 0                         -o off
-  -f            -S on                   --saveauto=on                      -s 1                         -S on
-  -F            -S off                  --saveauto=off                     -s 0                         -S off
-  -c            -H                      --health                           -c                           -H
-  -g            -c                      --capabilities
-  -v            -A                      --attributes                       -p, -u, -f, -t               -p, -u, -t
-  -l            -l error                --log=error                        -l                           -l error
-  -L            -l selftest             --log=selftest                     -L                           -l selftest
-  -a            -a                      --all                              -a                           -a
-  -m            -v 9,minutes            --vendorattribute=9,minutes
-  -O            -t offline              --test=offline
-  -S            -t short                --test=short
-  -s            -t short -C             --test=short --captive
-  -X            -t long                 --test=long
-  -x            -t long -C              --test=long --captive
-  -A            -X                      --abort
-
-
- NOW A COMMAND-LINE OPTION (-i N, --interval N) =======>                   -C N    Set checktime        CMD LINE: -i N
-                                                                           -f      usage attributes     -f
-                                                                           -M ADD  Email addresses     -m ADD
-                                                                           -m -3   Email mode          -M diminishing -M test
-                                                                           -m -2   Email mode          -M daily -M test
-                                                                           -m -1   Email mode          -M once -M test
-                            If no -M is given, this is the DEFAULT =====>  -m 0    Email mode          -M once
-                                                                           -m 1    Email mode          -M once
-                                                                           -m 2    Email mode          -M daily
-                                                                           -m 3    Email mode          -M diminishing
-                            New feature (see man page) =====>                                          -M exec SCRIPT
-                                                                           -i N    Ignore              -i N
-                                                                           -I N    Ignore              -I N
-                                                                            #      Comment              #
-                                                                            \      Line continuation    \
-  -------------------------------------------------------------------------------------------------------------------
-
-Changes to smartd options:
-
-  ----------------------------------------------------------------------------------------------------------
-  5.0 short     5.0 long                                     5.1 short     5.1 long
-  option        option                                       option        option
-  ----------------------------------------------------------------------------------------------------------
-  -h, -?        --help                                       -h, -?        --help
-  -V            --version, --copyright, --license            -V            --version, --copyright, --license
-  -X            --debug                                      -d            --debug
-                                                             -i N          --interval=N
-                                                             -D            --showdirectives
-                                                             -r            --report=TYPE
-  ----------------------------------------------------------------------------------------------------------
-
diff --git a/sm5/TODO b/sm5/TODO
deleted file mode 100644
index 9b405e2dd..000000000
--- a/sm5/TODO
+++ /dev/null
@@ -1,73 +0,0 @@
-TODO list for smartmontools:
-
-Home page of code is: http://smartmontools.sourceforge.net
-
-Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-
-$Id: TODO,v 1.36 2003/04/14 22:32:02 guidog 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/.
-
-
-Testing
--------
-Test with SCSI, FireWire, USB, and SATA devices.  Doug Gilbert is now
-doing some of this.
-
-Extensions
-----------
-Produce version for ATA/ATAPI-6 (support for extended error logs)
-
-Produce version for ATA/ATAPI-7
-
-
-smartctl: 
----------
-
-Handle extended error and self-test logs gracefully.  Can someone tell
-me a disk that supports more than ATA log pages 1 and 6?  I need to
-get a disk so I can test this functionality, when I add it.
-
-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 more attribute flag meanings (IBM ones, eg performance
-etc).
-
-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!).
-
-General Fixes
--------------
-
-Fix lots of syntax like if (a != 0).  This is now pretty much confined
-to the SCSI-only parts of the code.
-
-Use consistent error codes in exit() calls
diff --git a/sm5/VERSION b/sm5/VERSION
deleted file mode 100644
index b4de39476..000000000
--- a/sm5/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-11
diff --git a/sm5/WARNINGS b/sm5/WARNINGS
deleted file mode 100644
index f46bde5ea..000000000
--- a/sm5/WARNINGS
+++ /dev/null
@@ -1,16 +0,0 @@
-The following are controllers/drives where there have been reports of
-serious problems (eg system lockup):
-
-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 pcdx maintainers.  If you enable the the Promise-BIOS (ATA100-BIOS) then
-          everything will work fine.  But if you disable it, then the machine will hang.
diff --git a/sm5/add b/sm5/add
deleted file mode 100755
index 7f635870d..000000000
--- a/sm5/add
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-#
-# This is a utility called in the Makefile.  It's used together with
-# the file "counter" to automatically increment release numbers.
-#
-a=`cat VERSION`
-let a+=1
-echo $a
diff --git a/sm5/atacmds.c b/sm5/atacmds.c
deleted file mode 100644
index d8e82d534..000000000
--- a/sm5/atacmds.c
+++ /dev/null
@@ -1,1530 +0,0 @@
-/*
- * atacmds.c
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 "utility.h"
-#include "extern.h"
-
-const char *atacmds_c_cvsid="$Id: atacmds.c,v 1.98 2003/04/28 18:37:02 ballen4705 Exp $" ATACMDS_H_CVSID EXTERN_H_CVSID UTILITY_H_CVSID;
-
-// 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 0x1e
-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	*/
-};
-
-// 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:	*/
-};
-
-// When you add additional items to this list, you should then:
-// 0 -- update this list
-// 1 -- modify the following function parse_attribute_def()
-// 2 -- modify ataPrintSmartAttribRawValue()
-// 3 -  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",
-  // NULL should always terminate the array
-  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 *defs){
-  int i,j;
-  char temp[32];
-
-  // 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<256; j++)
-      defs[j]=253;
-    return 0;
-  case 5:
-    // print all attributes in raw 16-bit form
-    for (j=0; j<256; j++)
-      defs[j]=254;
-    return 0;
-  case 6:
-    // print all attributes in raw 48-bit form
-    for (j=0; j<256; 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;
-  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(*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(sorted);
-
-  // Return a pointer to the string
-  return s;
-}
-
-
-// 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 SMART_AUTOSAVE and
-// 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 os_specific_handler(int device, smart_command_set command, int select, char *data){
-  unsigned char buff[STRANGE_BUFFER_LENGTH];
-  int retval, copydata=0;
-
-  // See struct hd_drive_cmd_hdr in hdreg.h
-  // buff[0]: ATA COMMAND CODE REGISTER
-  // buff[1]: ATA SECTOR NUMBER REGISTER
-  // buff[2]: ATA FEATURES REGISTER
-  // buff[3]: ATA SECTOR COUNT REGISTER
-  
-  // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
-  memset(buff, 0, STRANGE_BUFFER_LENGTH);
-
-  buff[0]=WIN_SMART;
-  switch (command){
-  case READ_VALUES:
-    buff[2]=SMART_READ_VALUES;
-    copydata=buff[3]=1;
-    break;
-  case READ_THRESHOLDS:
-    buff[2]=SMART_READ_THRESHOLDS;
-    copydata=buff[1]=buff[3]=1;
-    break;
-  case READ_LOG:
-    buff[2]=SMART_READ_LOG_SECTOR;
-    buff[1]=select;
-    copydata=buff[3]=1;
-    break;
-  case IDENTIFY:
-    buff[0]=WIN_IDENTIFY;
-    copydata=buff[3]=1;
-    break;
-  case PIDENTIFY:
-    buff[0]=WIN_PIDENTIFY;
-    copydata=buff[3]=1;
-    break;
-  case ENABLE:
-    buff[2]=SMART_ENABLE;
-    buff[1]=1;
-    break;
-  case DISABLE:
-    buff[2]=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]=SMART_STATUS;
-    break;
-  case AUTO_OFFLINE:
-    buff[2]=SMART_AUTO_OFFLINE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case AUTOSAVE:
-    buff[2]=SMART_AUTOSAVE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case IMMEDIATE_OFFLINE:
-    buff[2]=SMART_IMMEDIATE_OFFLINE;
-    buff[1]=select;
-    break;
-    // the command uses HDIO_DRIVE_TASK and has different syntax than
-    // the other commands.
-  case STATUS_CHECK:
-    buff[1]=SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in os_specific_handler()\n", command);
-    exit(1);
-    break;
-  }
-  
-  // There are two different types of ioctls().  The HDIO_DRIVE_TASK
-  // one is this:
-  if (command==STATUS_CHECK){
-    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;
-    
-    // HDIO_DRIVE_TASK IOCTL
-#ifdef HDIO_DRIVE_TASK
-    if ((retval=ioctl(device, HDIO_DRIVE_TASK, buff)))
-#endif
-      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 %s\n",PROJECTHOME);
-    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;   
-  }
-  
-  // We are now doing the HDIO_DRIVE_CMD type ioctl.
-  if ((retval=ioctl(device, HDIO_DRIVE_CMD, buff)))
-    return -1;
-  
-  if (copydata)
-    memcpy(data, buff+4, 512);
-  
-  return 0; 
-}
-
-static char *commandstrings[]={
-  [ENABLE]=           "SMART ENABLE",
-  [DISABLE]=          "SMART DISABLE",
-  [AUTOSAVE]=         "SMART AUTOMATIC ATTRIBUTE SAVE",
-  [IMMEDIATE_OFFLINE]="SMART IMMEDIATE OFFLINE",
-  [AUTO_OFFLINE]=     "SMART AUTO OFFLINE",
-  [STATUS]=           "SMART STATUS",
-  [STATUS_CHECK]=     "SMART STATUS CHECK",
-  [READ_VALUES]=      "SMART READ ATTRIBUTE VALUES",
-  [READ_THRESHOLDS]=  "SMART READ ATTRIBUTE THRESHOLDS",
-  [READ_LOG]=         "SMART READ LOG",
-  [IDENTIFY]=         "IDENTIFY DEVICE" ,
-  [PIDENTIFY]=        "IDENTIFY PACKET DEVICE" 
-};
-
-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
-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);
-  
-  // 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);
-		  
-    pout("\nREPORT-IOCTL: DeviceFD=%d Command=%s", device, commandstrings[command]);
-    if (usesparam)
-      pout(" InputParameter=%d\n", select);
-    else
-      pout("\n");
-  }
-  
-  if (getsdata && data==NULL){
-    pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
-    return -1;
-  }
-  
-  // now execute the command
-  retval=os_specific_handler(device, command, select, data);
-  
-  // If reporting is enabled, say what output was produced by the command
-  if (con->reportataioctl){
-    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)
-      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;
-}
-
-// Reads current Device Identity info (512 bytes) into buf
-int ataReadHDIdentity (int device, struct hd_driveid *buf){
-  unsigned short driveidchecksum;
-  
-  if (smartcommandhandler(device, IDENTIFY, 0, (char *)buf)){
-    // See if device responds to packet command...
-    if (smartcommandhandler(device, PIDENTIFY, 0, (char *)buf)){
-      syserror("Error ATA GET HD Identity Failed");
-      return -1; 
-    }
-  }
-  
-#if 0
-  // The following ifdef is a HACK to distinguish different versions
-  // of the header file defining hd_driveid
-#ifdef CFA_REQ_EXT_ERROR_CODE
-  driveidchecksum=buf->integrity_word;
-#else
-  // Note -- the declaration that appears in
-  // /usr/include/linux/hdreg.h: short words160_255[95], is WRONG.
-  // It should say: short words160_255[96]. I have written to Andre
-  // Hedrick about this on Oct 17 2002.  Please remove this comment
-  // once the fix has made it into the stock kernel tree.
-  driveidchecksum=buf->words160_255[95];
-#endif
-#else
-  // This way is ugly and you may feel ill -- but it always works...
-  {
-    unsigned short *rawstructure=
-      (unsigned short *)buf;
-    driveidchecksum=rawstructure[255];
-  }
-#endif
-  
-  if ((driveidchecksum & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
-    checksumwarning("Drive Identity Structure");
-  
-  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 hd_driveid *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", 
-	 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",
-	 sizeof(actual_ver)/sizeof(int), MINOR_MAX+1);
-    fflush(NULL);
-    abort();
-  }
-
-  // get major and minor ATA revision numbers
-#ifdef __NEW_HD_DRIVE_ID
-  major=drive->major_rev_num;
-  *minor=drive->minor_rev_num;
-#else
-  major=drive->word80;
-  *minor=drive->word81;
-#endif
-  
-  // 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 not supported or can't tell
-int ataSmartSupport(struct hd_driveid *drive){
-  unsigned short word82,word83;
-
-  // get correct bits of IDENTIFY DEVICE structure
-#ifdef __NEW_HD_DRIVE_ID
-  word82=drive->command_set_1;
-  word83=drive->command_set_2;
-#else
-  word82=drive->command_sets;
-  word83=drive->word83;
-#endif
-
-  // Note this does not work for ATA3 < Revision 6, when word82 and word83 were added
-  // we should check for ATA3 Rev 0 in minor identity code...  
-  return (word83 & 0x0001<<14) && !(word83 & 0x0001<<15) && (word82 & 0x0001);
-}
-
-// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
-int ataIsSmartEnabled(struct hd_driveid *drive){
-    unsigned short word85,word87;
-
-  // Get correct bits of IDENTIFY DRIVE structure
-#ifdef __NEW_HD_DRIVE_ID
-  word85=drive->cfs_enable_1;
-  word87=drive->csf_default;
-#else
-  word85=drive->word85;
-  word87=drive->word87;
-#endif
-  
-  if ((word87 & 0x0001<<14) && !(word87 & 0x0001<<15))
-    // word85 contains valid information, so
-    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");
-  
-  return 0;
-}
-
-// 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;
-}
-
-// This corrects some quantities that are byte reversed in the SMART
-// SELF TEST LOG
-void fixsamsungselftestlog(struct ata_smart_selftestlog *data){
-  int i;
-  
-  // swap with one byte of reserved
-  swap2((char *)&(data->mostrecenttest));
-
-  // LBA low register (here called 'selftestnumber") is byte swapped
-  // with Self-test execution status byte.
-  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);
-
-  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;
-  }  
-  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;
-  
-  // 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));
-  }
-}
-
-// Reads the Error Log (log #1)
-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);
-
-  return 0;
-}
-
-int ataReadSmartThresholds (int device, struct ata_smart_thresholds *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");
-  
-  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;
-}
-
-// Note that in the ATA-5 standard the Enable/Disable AutoOffline
-// command is marked "OBSOLETE".  Curiously, I could not find it
-// documented in ANY of the ATA specifications.  In other words, it's
-// been obsolete forever. However some vendors (eg, IBM) seem to be
-// using this command anyway.  For example see the IBM Travelstar
-// 40GNX hard disk drive specifications page 164 Revision 1.1 22 Apr
-// 2002.  This gives a detailed description of the command, although
-// the drive claims to comply with the ATA/ATAPI-5 Revision 3
-// standard!  The latter document makes no mention of this command at
-// all, other than to say that it is "obsolete".
-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;
-}
-
-
-// This function does NOTHING except tell us if SMART is working &
-// enabled on the device.  See ataSmartStatus2() for one that actually
-// returns SMART status.
-int ataSmartStatus (int device ){	
-  
-  if (smartcommandhandler(device, STATUS, 0, NULL)){
-    syserror("Error Return SMART Status via HDIO_DRIVE_CMD 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);
-}
-
-#ifdef HDIO_DRIVE_TASK
-// This function uses a different interface (DRIVE_TASK) than the
-// other commands in this file.
-int ataSmartStatus2(int device){
-
-  int returnval=smartcommandhandler(device, STATUS_CHECK, 0, NULL);
-  
-  if (returnval==-1){
-    syserror("Error SMART Status command via HDIO_DRIVE_TASK failed");
-    pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support enabled\n");
-  }
-  
-  return returnval;
-}
-#else
-// Just a hack so that the code compiles on 
-// 2.2 kernels without HDIO_DRIVE TASK support.  
-// Should be fixed by putting in a call to code 
-// that compares smart data to thresholds.
-int ataSmartStatus2(int device){
-  pout("This code was compiled on a machine whose kernel header\n"
-       "files do not support the HDIO_DRIVE_TASK ioctl().\n"
-       "Compile on a linux 2.2 kernel box with HDIO_DRIVE_TASK\n"
-       "support enabled, or on a 2.4 kernel box, please.\n");
-  return ataSmartStatus(device);
-}
-#endif
-
-
-// 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){	
-  char cmdmsg[128],*type,*captive;
-  int errornum;
-  int cap;
-
-  // 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 (testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)
-    type="Selective self-test";
-  else
-    type="[Unrecognized] self-test";
-    
-  //  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);
-
-  // 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;
-  default:
-    return 0;
-  }
-}
-
-// This function tells you both about the ATA error log and the
-// self-test error log capability.  The bit is poorly documented in
-// the ATA/ATAPI standard.
-int isSmartErrorLogCapable ( struct ata_smart_values *data){
-   return data->errorlog_capability & 0x01;
-}
-int isSupportExecuteOfflineImmediate(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x01;
-}
-
-int isGeneralPurposeLoggingCapable(struct hd_driveid *identity){
-  unsigned short *rawwords=(unsigned short *)identity;
-  unsigned short word84, word87;
-
-  word84=rawwords[84];
-  word87=rawwords[87];
-
-  // 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;
-}
-
-
-// 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 *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 && disk->status.flag.prefailure)
-	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 *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 (disk->status.flag.prefailure)
-    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.
-
-long long ataPrintSmartAttribRawValue(char *out, 
-				      struct ata_smart_attribute *attribute,
-				      unsigned char *defs){
-  long long rawvalue;
-  unsigned word[3];
-  int j;
-  
-  // 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.
-    long long 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];
-  }
-  
-  // Print six one-byte quantities.
-  if (defs[attribute->id]==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 (defs[attribute->id]==254){
-    out+=sprintf(out, "%d %d %d", word[2], word[1], word[0]); 
-    return rawvalue;
-  } 
-  
-  // Print one six-byte quantity
-  if (defs[attribute->id]==255){
-    out+=sprintf(out, "%llu", 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 (defs[9]==1){
-      // minutes
-      long long tmp1=rawvalue/60;
-      long long tmp2=rawvalue%60;
-      out+=sprintf(out, "%lluh+%02llum", tmp1, tmp2);
-    }
-    else if (defs[9]==3){
-      // seconds
-      long long hours=rawvalue/3600;
-      long long minutes=(rawvalue-3600*hours)/60;
-      long long seconds=rawvalue%60;
-      out+=sprintf(out, "%lluh+%02llum+%02llus", hours, minutes, seconds);
-    }
-    else if (defs[9]==4){
-      // 30-second counter
-      long long tmp1=rawvalue/120;
-      long long tmp2=(rawvalue-120*tmp1)/2;
-      out+=sprintf(out, "%lluh+%02llum", tmp1, tmp2);
-    }
-    else
-      // hours
-      out+=sprintf(out, "%llu", rawvalue);  //stored in hours
-    break;
-    // Temperature
-  case 194:
-    if (defs[194]==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 (defs[194]==2)
-      // unknown attribute
-      out+=sprintf(out, "%llu", rawvalue);
-    else {
-      out+=sprintf(out, "%d", word[0]);
-      if (!(rawvalue==word[0]))
-	// The other bytes are in use. Try IBM's model
-	out+=sprintf(out, " (Lifetime Min/Max %d/%d)", word[1], word[2]);
-    }
-    break;
-  default:
-    out+=sprintf(out, "%llu", 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 val){
-  char *name;
-  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:
-    name="Power-Off_Retract_Count";
-    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:
-    name="Hardware_ECC_Recovered";
-    break;
-  case 196:
-    name="Reallocated_Event_Count";
-    break;
-  case 197:
-    name="Current_Pending_Sector";
-    break;
-  case 198:
-    name="Offline_Uncorrectable";
-    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 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;
-  default:
-    name="Unknown_Attribute";
-    break;
-  }
-  sprintf(out,"%3hhu %s",id,name);
-  return;
-}
diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp
deleted file mode 100644
index 50dc8484f..000000000
--- a/sm5/atacmds.cpp
+++ /dev/null
@@ -1,1530 +0,0 @@
-/*
- * atacmds.c
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 "utility.h"
-#include "extern.h"
-
-const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.98 2003/04/28 18:37:02 ballen4705 Exp $" ATACMDS_H_CVSID EXTERN_H_CVSID UTILITY_H_CVSID;
-
-// 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 0x1e
-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	*/
-};
-
-// 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:	*/
-};
-
-// When you add additional items to this list, you should then:
-// 0 -- update this list
-// 1 -- modify the following function parse_attribute_def()
-// 2 -- modify ataPrintSmartAttribRawValue()
-// 3 -  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",
-  // NULL should always terminate the array
-  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 *defs){
-  int i,j;
-  char temp[32];
-
-  // 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<256; j++)
-      defs[j]=253;
-    return 0;
-  case 5:
-    // print all attributes in raw 16-bit form
-    for (j=0; j<256; j++)
-      defs[j]=254;
-    return 0;
-  case 6:
-    // print all attributes in raw 48-bit form
-    for (j=0; j<256; 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;
-  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(*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(sorted);
-
-  // Return a pointer to the string
-  return s;
-}
-
-
-// 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 SMART_AUTOSAVE and
-// 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 os_specific_handler(int device, smart_command_set command, int select, char *data){
-  unsigned char buff[STRANGE_BUFFER_LENGTH];
-  int retval, copydata=0;
-
-  // See struct hd_drive_cmd_hdr in hdreg.h
-  // buff[0]: ATA COMMAND CODE REGISTER
-  // buff[1]: ATA SECTOR NUMBER REGISTER
-  // buff[2]: ATA FEATURES REGISTER
-  // buff[3]: ATA SECTOR COUNT REGISTER
-  
-  // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
-  memset(buff, 0, STRANGE_BUFFER_LENGTH);
-
-  buff[0]=WIN_SMART;
-  switch (command){
-  case READ_VALUES:
-    buff[2]=SMART_READ_VALUES;
-    copydata=buff[3]=1;
-    break;
-  case READ_THRESHOLDS:
-    buff[2]=SMART_READ_THRESHOLDS;
-    copydata=buff[1]=buff[3]=1;
-    break;
-  case READ_LOG:
-    buff[2]=SMART_READ_LOG_SECTOR;
-    buff[1]=select;
-    copydata=buff[3]=1;
-    break;
-  case IDENTIFY:
-    buff[0]=WIN_IDENTIFY;
-    copydata=buff[3]=1;
-    break;
-  case PIDENTIFY:
-    buff[0]=WIN_PIDENTIFY;
-    copydata=buff[3]=1;
-    break;
-  case ENABLE:
-    buff[2]=SMART_ENABLE;
-    buff[1]=1;
-    break;
-  case DISABLE:
-    buff[2]=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]=SMART_STATUS;
-    break;
-  case AUTO_OFFLINE:
-    buff[2]=SMART_AUTO_OFFLINE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case AUTOSAVE:
-    buff[2]=SMART_AUTOSAVE;
-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
-    break;
-  case IMMEDIATE_OFFLINE:
-    buff[2]=SMART_IMMEDIATE_OFFLINE;
-    buff[1]=select;
-    break;
-    // the command uses HDIO_DRIVE_TASK and has different syntax than
-    // the other commands.
-  case STATUS_CHECK:
-    buff[1]=SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in os_specific_handler()\n", command);
-    exit(1);
-    break;
-  }
-  
-  // There are two different types of ioctls().  The HDIO_DRIVE_TASK
-  // one is this:
-  if (command==STATUS_CHECK){
-    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;
-    
-    // HDIO_DRIVE_TASK IOCTL
-#ifdef HDIO_DRIVE_TASK
-    if ((retval=ioctl(device, HDIO_DRIVE_TASK, buff)))
-#endif
-      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 %s\n",PROJECTHOME);
-    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;   
-  }
-  
-  // We are now doing the HDIO_DRIVE_CMD type ioctl.
-  if ((retval=ioctl(device, HDIO_DRIVE_CMD, buff)))
-    return -1;
-  
-  if (copydata)
-    memcpy(data, buff+4, 512);
-  
-  return 0; 
-}
-
-static char *commandstrings[]={
-  [ENABLE]=           "SMART ENABLE",
-  [DISABLE]=          "SMART DISABLE",
-  [AUTOSAVE]=         "SMART AUTOMATIC ATTRIBUTE SAVE",
-  [IMMEDIATE_OFFLINE]="SMART IMMEDIATE OFFLINE",
-  [AUTO_OFFLINE]=     "SMART AUTO OFFLINE",
-  [STATUS]=           "SMART STATUS",
-  [STATUS_CHECK]=     "SMART STATUS CHECK",
-  [READ_VALUES]=      "SMART READ ATTRIBUTE VALUES",
-  [READ_THRESHOLDS]=  "SMART READ ATTRIBUTE THRESHOLDS",
-  [READ_LOG]=         "SMART READ LOG",
-  [IDENTIFY]=         "IDENTIFY DEVICE" ,
-  [PIDENTIFY]=        "IDENTIFY PACKET DEVICE" 
-};
-
-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
-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);
-  
-  // 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);
-		  
-    pout("\nREPORT-IOCTL: DeviceFD=%d Command=%s", device, commandstrings[command]);
-    if (usesparam)
-      pout(" InputParameter=%d\n", select);
-    else
-      pout("\n");
-  }
-  
-  if (getsdata && data==NULL){
-    pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
-    return -1;
-  }
-  
-  // now execute the command
-  retval=os_specific_handler(device, command, select, data);
-  
-  // If reporting is enabled, say what output was produced by the command
-  if (con->reportataioctl){
-    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)
-      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;
-}
-
-// Reads current Device Identity info (512 bytes) into buf
-int ataReadHDIdentity (int device, struct hd_driveid *buf){
-  unsigned short driveidchecksum;
-  
-  if (smartcommandhandler(device, IDENTIFY, 0, (char *)buf)){
-    // See if device responds to packet command...
-    if (smartcommandhandler(device, PIDENTIFY, 0, (char *)buf)){
-      syserror("Error ATA GET HD Identity Failed");
-      return -1; 
-    }
-  }
-  
-#if 0
-  // The following ifdef is a HACK to distinguish different versions
-  // of the header file defining hd_driveid
-#ifdef CFA_REQ_EXT_ERROR_CODE
-  driveidchecksum=buf->integrity_word;
-#else
-  // Note -- the declaration that appears in
-  // /usr/include/linux/hdreg.h: short words160_255[95], is WRONG.
-  // It should say: short words160_255[96]. I have written to Andre
-  // Hedrick about this on Oct 17 2002.  Please remove this comment
-  // once the fix has made it into the stock kernel tree.
-  driveidchecksum=buf->words160_255[95];
-#endif
-#else
-  // This way is ugly and you may feel ill -- but it always works...
-  {
-    unsigned short *rawstructure=
-      (unsigned short *)buf;
-    driveidchecksum=rawstructure[255];
-  }
-#endif
-  
-  if ((driveidchecksum & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
-    checksumwarning("Drive Identity Structure");
-  
-  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 hd_driveid *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", 
-	 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",
-	 sizeof(actual_ver)/sizeof(int), MINOR_MAX+1);
-    fflush(NULL);
-    abort();
-  }
-
-  // get major and minor ATA revision numbers
-#ifdef __NEW_HD_DRIVE_ID
-  major=drive->major_rev_num;
-  *minor=drive->minor_rev_num;
-#else
-  major=drive->word80;
-  *minor=drive->word81;
-#endif
-  
-  // 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 not supported or can't tell
-int ataSmartSupport(struct hd_driveid *drive){
-  unsigned short word82,word83;
-
-  // get correct bits of IDENTIFY DEVICE structure
-#ifdef __NEW_HD_DRIVE_ID
-  word82=drive->command_set_1;
-  word83=drive->command_set_2;
-#else
-  word82=drive->command_sets;
-  word83=drive->word83;
-#endif
-
-  // Note this does not work for ATA3 < Revision 6, when word82 and word83 were added
-  // we should check for ATA3 Rev 0 in minor identity code...  
-  return (word83 & 0x0001<<14) && !(word83 & 0x0001<<15) && (word82 & 0x0001);
-}
-
-// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
-int ataIsSmartEnabled(struct hd_driveid *drive){
-    unsigned short word85,word87;
-
-  // Get correct bits of IDENTIFY DRIVE structure
-#ifdef __NEW_HD_DRIVE_ID
-  word85=drive->cfs_enable_1;
-  word87=drive->csf_default;
-#else
-  word85=drive->word85;
-  word87=drive->word87;
-#endif
-  
-  if ((word87 & 0x0001<<14) && !(word87 & 0x0001<<15))
-    // word85 contains valid information, so
-    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");
-  
-  return 0;
-}
-
-// 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;
-}
-
-// This corrects some quantities that are byte reversed in the SMART
-// SELF TEST LOG
-void fixsamsungselftestlog(struct ata_smart_selftestlog *data){
-  int i;
-  
-  // swap with one byte of reserved
-  swap2((char *)&(data->mostrecenttest));
-
-  // LBA low register (here called 'selftestnumber") is byte swapped
-  // with Self-test execution status byte.
-  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);
-
-  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;
-  }  
-  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;
-  
-  // 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));
-  }
-}
-
-// Reads the Error Log (log #1)
-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);
-
-  return 0;
-}
-
-int ataReadSmartThresholds (int device, struct ata_smart_thresholds *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");
-  
-  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;
-}
-
-// Note that in the ATA-5 standard the Enable/Disable AutoOffline
-// command is marked "OBSOLETE".  Curiously, I could not find it
-// documented in ANY of the ATA specifications.  In other words, it's
-// been obsolete forever. However some vendors (eg, IBM) seem to be
-// using this command anyway.  For example see the IBM Travelstar
-// 40GNX hard disk drive specifications page 164 Revision 1.1 22 Apr
-// 2002.  This gives a detailed description of the command, although
-// the drive claims to comply with the ATA/ATAPI-5 Revision 3
-// standard!  The latter document makes no mention of this command at
-// all, other than to say that it is "obsolete".
-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;
-}
-
-
-// This function does NOTHING except tell us if SMART is working &
-// enabled on the device.  See ataSmartStatus2() for one that actually
-// returns SMART status.
-int ataSmartStatus (int device ){	
-  
-  if (smartcommandhandler(device, STATUS, 0, NULL)){
-    syserror("Error Return SMART Status via HDIO_DRIVE_CMD 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);
-}
-
-#ifdef HDIO_DRIVE_TASK
-// This function uses a different interface (DRIVE_TASK) than the
-// other commands in this file.
-int ataSmartStatus2(int device){
-
-  int returnval=smartcommandhandler(device, STATUS_CHECK, 0, NULL);
-  
-  if (returnval==-1){
-    syserror("Error SMART Status command via HDIO_DRIVE_TASK failed");
-    pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support enabled\n");
-  }
-  
-  return returnval;
-}
-#else
-// Just a hack so that the code compiles on 
-// 2.2 kernels without HDIO_DRIVE TASK support.  
-// Should be fixed by putting in a call to code 
-// that compares smart data to thresholds.
-int ataSmartStatus2(int device){
-  pout("This code was compiled on a machine whose kernel header\n"
-       "files do not support the HDIO_DRIVE_TASK ioctl().\n"
-       "Compile on a linux 2.2 kernel box with HDIO_DRIVE_TASK\n"
-       "support enabled, or on a 2.4 kernel box, please.\n");
-  return ataSmartStatus(device);
-}
-#endif
-
-
-// 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){	
-  char cmdmsg[128],*type,*captive;
-  int errornum;
-  int cap;
-
-  // 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 (testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)
-    type="Selective self-test";
-  else
-    type="[Unrecognized] self-test";
-    
-  //  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);
-
-  // 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;
-  default:
-    return 0;
-  }
-}
-
-// This function tells you both about the ATA error log and the
-// self-test error log capability.  The bit is poorly documented in
-// the ATA/ATAPI standard.
-int isSmartErrorLogCapable ( struct ata_smart_values *data){
-   return data->errorlog_capability & 0x01;
-}
-int isSupportExecuteOfflineImmediate(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x01;
-}
-
-int isGeneralPurposeLoggingCapable(struct hd_driveid *identity){
-  unsigned short *rawwords=(unsigned short *)identity;
-  unsigned short word84, word87;
-
-  word84=rawwords[84];
-  word87=rawwords[87];
-
-  // 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;
-}
-
-
-// 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 *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 && disk->status.flag.prefailure)
-	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 *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 (disk->status.flag.prefailure)
-    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.
-
-long long ataPrintSmartAttribRawValue(char *out, 
-				      struct ata_smart_attribute *attribute,
-				      unsigned char *defs){
-  long long rawvalue;
-  unsigned word[3];
-  int j;
-  
-  // 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.
-    long long 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];
-  }
-  
-  // Print six one-byte quantities.
-  if (defs[attribute->id]==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 (defs[attribute->id]==254){
-    out+=sprintf(out, "%d %d %d", word[2], word[1], word[0]); 
-    return rawvalue;
-  } 
-  
-  // Print one six-byte quantity
-  if (defs[attribute->id]==255){
-    out+=sprintf(out, "%llu", 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 (defs[9]==1){
-      // minutes
-      long long tmp1=rawvalue/60;
-      long long tmp2=rawvalue%60;
-      out+=sprintf(out, "%lluh+%02llum", tmp1, tmp2);
-    }
-    else if (defs[9]==3){
-      // seconds
-      long long hours=rawvalue/3600;
-      long long minutes=(rawvalue-3600*hours)/60;
-      long long seconds=rawvalue%60;
-      out+=sprintf(out, "%lluh+%02llum+%02llus", hours, minutes, seconds);
-    }
-    else if (defs[9]==4){
-      // 30-second counter
-      long long tmp1=rawvalue/120;
-      long long tmp2=(rawvalue-120*tmp1)/2;
-      out+=sprintf(out, "%lluh+%02llum", tmp1, tmp2);
-    }
-    else
-      // hours
-      out+=sprintf(out, "%llu", rawvalue);  //stored in hours
-    break;
-    // Temperature
-  case 194:
-    if (defs[194]==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 (defs[194]==2)
-      // unknown attribute
-      out+=sprintf(out, "%llu", rawvalue);
-    else {
-      out+=sprintf(out, "%d", word[0]);
-      if (!(rawvalue==word[0]))
-	// The other bytes are in use. Try IBM's model
-	out+=sprintf(out, " (Lifetime Min/Max %d/%d)", word[1], word[2]);
-    }
-    break;
-  default:
-    out+=sprintf(out, "%llu", 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 val){
-  char *name;
-  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:
-    name="Power-Off_Retract_Count";
-    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:
-    name="Hardware_ECC_Recovered";
-    break;
-  case 196:
-    name="Reallocated_Event_Count";
-    break;
-  case 197:
-    name="Current_Pending_Sector";
-    break;
-  case 198:
-    name="Offline_Uncorrectable";
-    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 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;
-  default:
-    name="Unknown_Attribute";
-    break;
-  }
-  sprintf(out,"%3hhu %s",id,name);
-  return;
-}
diff --git a/sm5/atacmds.h b/sm5/atacmds.h
deleted file mode 100644
index 61176bb07..000000000
--- a/sm5/atacmds.h
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * atacmds.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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_
-
-#ifndef ATACMDS_H_CVSID
-#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.43 2003/04/18 12:37:14 ballen4705 Exp $\n"
-#endif
-
-// These are the major and minor versions for smartd and smartctl
-#define PROJECTHOME "http://smartmontools.sourceforge.net/"
-#define RELEASE_MAJOR 5
-#define RELEASE_MINOR 1
-
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-#include <sys/fcntl.h>
-#include <sys/types.h>
-
-
-typedef enum {
-  // returns no data, just succeeds or fails
-  ENABLE,
-  DISABLE,
-  AUTOSAVE,
-  IMMEDIATE_OFFLINE,
-  AUTO_OFFLINE,
-  STATUS,
-  STATUS_CHECK,
-  // return 512 bytes of data:
-  READ_VALUES,
-  READ_THRESHOLDS,
-  READ_LOG,
-  IDENTIFY,
-  PIDENTIFY
-} smart_command_set;
-
-/* These defines SHOULD BE in the kernel
-   if not we define them */
-							  
-#ifndef WIN_SMART
-#define WIN_SMART		0xb0	
-#endif
-
-#ifndef SMART_READ_VALUES
-#define SMART_READ_VALUES	0xd0
-#endif
-
-#ifndef SMART_READ_THRESHOLDS	
-#define SMART_READ_THRESHOLDS	0xd1
-#endif
-
-#ifndef SMART_AUTOSAVE 
-#define SMART_AUTOSAVE		0xd2
-#endif
-
-#ifndef SMART_SAVE
-#define SMART_SAVE		0xd3
-#endif
-
-#ifndef SMART_IMMEDIATE_OFFLINE	
-#define SMART_IMMEDIATE_OFFLINE	0xd4
-#endif
-
-#ifndef SMART_READ_LOG_SECTOR
-#define SMART_READ_LOG_SECTOR 0xd5
-#endif
-
-#ifndef SMART_WRITE_LOG_SECTOR
-#define SMART_WRITE_LOG_SECTOR 0xd6
-#endif
-
-// The following is obsolete -- don't use it!
-#ifndef SMART_WRITE_THRESHOLDS
-#define SMART_WRITE_THRESHOLDS  0xd7
-#endif
-
-
-#ifndef SMART_ENABLE
-#define SMART_ENABLE		0xd8
-#endif
-
-#ifndef SMART_DISABLE
-#define SMART_DISABLE		0xd9
-#endif
-
-#ifndef SMART_STATUS
-#define SMART_STATUS		0xda
-#endif
-
-// The following is also marked obsolete in ATA-5
-#ifndef SMART_AUTO_OFFLINE
-#define SMART_AUTO_OFFLINE	0xdb
-#endif
-
-#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)
-
-#define NUMBER_ATA_SMART_ATTRIBUTES 	30
-
-#define ATA_SMART_SEC_SIZE		512
-
-#ifndef HDIO_DRIVE_CMD_HDR_SIZE
-#define HDIO_DRIVE_CMD_HDR_SIZE 	4
-#endif
-
-#ifndef HDIO_DRIVE_TASK_HDR_SIZE
-#define HDIO_DRIVE_TASK_HDR_SIZE	7
-#endif
-
-/* ata_smart_attribute is the vendor specific in SFF-8035 spec */ 
-struct ata_smart_attribute {
-  unsigned char id;
-  union {
-    unsigned short all; 
-    struct {
-      unsigned prefailure:1;   // 0=> low attribute from age/usage
-			       // exceeding design limit,
-			       // 1==prefailure
-      
-      unsigned online:1;       // 0==> attribute only updated during
-			       // off-line testing. 1==>only updated
-			       // during on-line testing
-      unsigned performance:1;
-      unsigned errorrate:1;	
-      unsigned eventcount:1 ;
-      unsigned selfperserving:1;
-      unsigned reserved:10;	
-    } __attribute__ ((packed)) flag;
-  } status ; 
-  unsigned char current;
-  unsigned char worst;
-  unsigned char raw[6];
-  unsigned char reserv;
-} __attribute__ ((packed));
-
-
-// What follows is the ATA/ATAPI-4 Rev 13 data structure equivalent:
-// Table 23 DEVICE SMART DATA STRUCTURE
-#if 0
-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 vendor_specific_363;  //IBM # segments for offline collection
-  unsigned short int total_time_to_complete_off_line; // IBM different
-  unsigned char vendor_specific_366; // IBM curent segment pointer
-  unsigned char offline_data_collection_capability;
-  unsigned short int smart_capability;
-  unsigned char reserved_370_385;;
-  unsigned char vendor_specific_386-510;  // IBM: self-test failure checkpoint
-  unsigned char chksum;
-} __attribute__ ((packed));
-#endif
-
-
-/* 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 */
-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; // IBM curent segment pointer
-  unsigned char offline_data_collection_capability;
-  unsigned short int smart_capability;
-  unsigned char errorlog_capability;
-  unsigned char vendor_specific_371;  // IBM: self-test failure checkpoint
-  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];
-  unsigned char chksum;
-} __attribute__ ((packed));
-
-/* Smart Threshold data structures */
-
-/* Vendor attribute of SMART Threshold (compare to ata_smart_attribute above) */
-struct ata_smart_threshold_entry {
-  unsigned char id;
-  unsigned char threshold;
-  unsigned char reserved[10];
-} __attribute__ ((packed));
-
-
-/* Format of Read SMART THreshold Command */
-/* Compare to ata_smart_values above */
-struct ata_smart_thresholds {
-  unsigned short int revnumber;
-  struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES];
-  unsigned char reserved[149];
-  unsigned char chksum;
-} __attribute__ ((packed));
-
-
-// Table 42 of T13/1321D Rev 1 spec (Error Data Structure)
-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;
-} __attribute__ ((packed));
-
-// Table 41 of T13/1321D Rev 1 spec (Command Data Structure)
-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;
-} __attribute__ ((packed));
-
-// Table 40 of T13/1321D Rev 1 spec (Error log data structure)
-struct ata_smart_errorlog_struct {
-  struct ata_smart_errorlog_command_struct commands[5];
-  struct ata_smart_errorlog_error_struct error_struct;
-}  __attribute__ ((packed));
-
-// Table 39 of T13/1321D Rev 1 spec (SMART error log sector)
-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;
-} __attribute__ ((packed));
-
-// Table 45 of T13/1321D Rev 1 spec (Self-test log descriptor entry)
-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];
-} __attribute__ ((packed));
-
-// Table 44 of T13/1321D Rev 1 spec (Self-test log data structure)
-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;
-} __attribute__ ((packed));
-
-
-
-// SMART LOG DIRECTORY Table 52 of T13/1532D Vol 1 Rev 1a
-struct ata_smart_log_entry {
-  unsigned char numsectors;
-  unsigned char reserved;
-} __attribute__ ((packed));
-
-struct ata_smart_log_directory {
-  unsigned short int logversion;
-  struct ata_smart_log_entry entry[255];
-} __attribute__ ((packed));
-
-
-/* Read S.M.A.R.T information from drive */
-int ataReadHDIdentity(int device, struct hd_driveid *buf);
-int ataReadSmartValues(int device,struct ata_smart_values *);
-int ataReadSmartThresholds(int device, struct ata_smart_thresholds *);
-int ataReadErrorLog(int device, struct ata_smart_errorlog *);
-int ataReadSelfTestLog(int device, struct ata_smart_selftestlog *);
-int ataSmartStatus(int device);
-int ataSetSmartThresholds(int device, struct ata_smart_thresholds *);
-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 hd_driveid *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 hd_driveid *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 hd_driveid *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 *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);
-
-int isGeneralPurposeLoggingCapable(struct hd_driveid *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);
-
-int TestTime(struct ata_smart_values *data,int testtype);
-
-// Prints the raw value (with appropriate formatting) into the
-// character string out.
-long long 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 val);
-
-// 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 *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);
-
-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.
-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);
-
-#endif /* _ATACMDS_H_ */
diff --git a/sm5/ataprint.c b/sm5/ataprint.c
deleted file mode 100644
index a8a279e0f..000000000
--- a/sm5/ataprint.c
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * ataprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 <syslog.h>
-#include <string.h>
-#include "atacmds.h"
-#include "ataprint.h"
-#include "smartctl.h"
-#include "extern.h"
-#include "utility.h"
-#include "knowndrives.h"
-
-const char *ataprint_c_cvsid="$Id: ataprint.c,v 1.85 2003/04/25 22:31:41 ballen4705 Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// 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(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(in[i]); i--)
-    ;
-  last = i;
-
-  strncpy(out, in+first, last-first+1);
-  out[last-first+1] = '\0';
-}
-
-// Convenience function for formatting strings from hd_driveid.
-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. This is needed on little-endian architectures, eg Intel,
-// Alpha. If someone wants to run this on SPARC they'll need to test
-// for the Endian-ness and skip the byte swapping if it's big-endian.
-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");
-}
-
-void ataPrintDriveInfo (struct hd_driveid *drive){
-  int version, drivetype;
-  const char *description;
-  char unknown[64], timedatetz[64];
-  unsigned short minorrev;
-  char model[64], serial[64], firm[64];
-  
-
-  // print out model, serial # and firmware versions  (byte-swap ASCI strings)
-  pout("Device Model:     ");
-  printswap(model, drive->model,40);
-
-  pout("Serial Number:    ");
-  printswap(serial, drive->serial_no,20);
-
-  pout("Firmware Version: ");
-  printswap(firm, drive->fw_rev,8);
-
-  // 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;
-}
-
-
-/*  prints verbose value Off-line data collection status byte */
-void PrintSmartOfflineStatus(struct ata_smart_values *data){
-
-  pout("Off-line data collection status: ");	
-  
-  switch(data->offline_data_collection_status){
-  case 0x00:
-  case 0x80:
-    pout("(0x%02x)\tOffline data collection activity was\n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("never started.\n");
-    break;
-  case 0x01:
-  case 0x81:
-    pout("(0x%02x)\tReserved.\n",
-	 (int)data->offline_data_collection_status);
-    break;
-  case 0x02:
-  case 0x82:
-    pout("(0x%02x)\tOffline data collection activity \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("completed without error.\n");
-    break;
-  case 0x03:
-  case 0x83:
-    pout("(0x%02x)\tReserved.\n",
-	 (int)data->offline_data_collection_status);
-    break;
-  case 0x04:
-  case 0x84:
-    pout("(0x%02x)\tOffline data collection activity was \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("suspended by an interrupting command from host.\n");
-    break;
-  case 0x05:
-  case 0x85:
-    pout("(0x%02x)\tOffline data collection activity was \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("aborted by an interrupting command from host.\n");
-    break;
-  case 0x06:
-  case 0x86:
-    pout("(0x%02x)\tOffline data collection activity was \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("aborted by the device with a fatal error.\n");
-    break;
-  default:
-    if ( ((data->offline_data_collection_status >= 0x07) &&
-	  (data->offline_data_collection_status <= 0x3f)) ||
-	 ((data->offline_data_collection_status >= 0xc0) &&
-	  (data->offline_data_collection_status <= 0xff)) )
-      pout("(0x%02x)\tVendor Specific.\n",(int)data->offline_data_collection_status);
-    else
-      pout("(0x%02x)\tReserved.\n",(int)data->offline_data_collection_status);
-  }
-
-  // report on Automatic Data Collection Status.  Only IBM documents
-  // this bit.
-  if (data->offline_data_collection_status & 0x80)
-    pout("\t\t\t\t\tAuto Off-line Data Collection: Enabled.\n");
-  else
-    pout("\t\t\t\t\tAuto Off-line 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 off-line \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("\tOff-line 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)? 
-	  "Automatic timer ON/OFF support.":
-	  "No Automatic timer ON/OFF 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)
-{
-
-   pout("Error logging capability:       ");
-    
-   if ( isSmartErrorLogCapable(data) )
-   {
-      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){
-  if (isSupportSelfTest(data)){
-    pout("Short self-test routine \n");
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->short_test_completion_time);
-  }
-  else {
-    pout("Short self-test routine \n");
-    pout("recommended polling time: \t        Not Supported.\n");
-  }
-}
-
-void PrintSmartExtendedSelfTestPollingTime(struct ata_smart_values *data){
-  if (isSupportSelfTest(data)){
-    pout("Extended self-test routine \n");
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->extend_test_completion_time);
-  }
-  else {
-    pout("Extended self-test routine \n");
-    pout("recommended polling time: \t        Not Supported.\n");
-  }
-}
-
-void PrintSmartConveyanceSelfTestPollingTime(struct ata_smart_values *data){
-  if (isSupportConveyanceSelfTest(data)){
-    pout("Extended self-test routine \n");
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->conveyance_test_completion_time);
-  }
-  else {
-    pout("Extended self-test routine \n");
-    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 *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;
-      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 && (!disk->status.flag.prefailure || !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     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[disk->id]);
-      pout("%-28s",attributename);
-
-      // printing line for each valid attribute
-      type=disk->status.flag.prefailure?"Pre-fail":"Old_age";
-      pout("0x%04x   %.3d   %.3d   %.3d    %-9s%-12s", 
-	     (int)disk->status.all, (int)disk->current, (int)disk->worst,
-	     (int)thre->threshold, type, 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[disk->id]);
-	ataPrintSmartAttribName(atthr, thre->id, con->attributedefs[thre->id]);
-	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 hd_driveid *drive){
-  pout("General SMART Values:\n");
-  
-  PrintSmartOfflineStatus(data); 
-  
-  if (isSupportSelfTest(data)){
-    PrintSmartSelfExecStatus (data);
-  }
-  
-  PrintSmartTotalTimeCompleteOffline(data);
-  PrintSmartOfflineCollectCap(data);
-  PrintSmartCapability(data);
-  
-  PrintSmartErrorLogCapability(data);
-
-  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");
-}
-
-// 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;
-}
-
-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 i,j,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;
-  }
-  QUIETON(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) {
-    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);
-  QUIETOFF(con);
-  pout("\tDCR = Device Control Register\n");
-  pout("\tFR  = Features Register\n");
-  pout("\tSC  = Sector Count Register\n");
-  pout("\tSN  = Sector Number Register\n");
-  pout("\tCL  = Cylinder Low Register\n");
-  pout("\tCH  = Cylinder High Register\n");
-  pout("\tD/H = Device/Head Register\n");
-  pout("\tCR  = Content written to Command Register\n");
-  pout("\tER  = Error register\n");
-  pout("\tSTA = Status register\n");
-  pout("Timestamp is seconds since the previous disk power-on.\n");
-  pout("Note: timestamp \"wraps\" after 2^32 msec = 49.710 days.\n\n");
-  
-  // now step through the five error log data structures (table 39 of spec)
-  for (k = 4; k >= 0; k-- ) {
-    
-    // The error log data structure entries are a circular buffer
-    i=(data->error_log_pointer+k)%5;
-    
-    // Spec says: unused error log structures shall be zero filled
-    if (nonempty((unsigned char*)&(data->errorlog_struct[i]),sizeof(data->errorlog_struct[i]))){
-      char *msgstate;
-      switch (data->errorlog_struct[i].error_struct.state){
-      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 off-line or self test"; break;
-      default:   msgstate="in a vendor specific or reserved state";
-      }
-      // See table 42 of ATA5 spec
-      QUIETON(con);
-      pout("Error %d occurred at disk power-on lifetime: %d hours\n",
-	     (int)(data->ata_error_count+k-4), (int)data->errorlog_struct[i].error_struct.timestamp);
-      QUIETOFF(con);
-      pout("When the command that caused the error occurred, the device was %s.\n",msgstate);
-      pout("After command completion occurred, registers were:\n");
-      pout("ER:%02x SC:%02x SN:%02x CL:%02x CH:%02x D/H:%02x ST:%02x\n",
-	   (int)data->errorlog_struct[i].error_struct.error_register,
-	   (int)data->errorlog_struct[i].error_struct.sector_count,
-	   (int)data->errorlog_struct[i].error_struct.sector_number,
-	   (int)data->errorlog_struct[i].error_struct.cylinder_low,
-	   (int)data->errorlog_struct[i].error_struct.cylinder_high,
-	   (int)data->errorlog_struct[i].error_struct.drive_head,
-	   (int)data->errorlog_struct[i].error_struct.status);
-      pout("Sequence of commands leading to the command that caused the error were:\n");
-      pout("DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp\n");
-      for ( j = 4; j >= 0; j--){
-	struct ata_smart_errorlog_command_struct *thiscommand=&(data->errorlog_struct[i].commands[j]);
-	
-	// Spec says: unused data command structures shall be zero filled
-	if (nonempty((unsigned char*)thiscommand,sizeof(*thiscommand)))
-	  pout(" %02x   %02x   %02x   %02x   %02x   %02x    %02x   %02x     %d.%03d\n", 
-	       (int)thiscommand->devicecontrolreg,
-	       (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->commandreg,
-	       (unsigned int)(thiscommand->timestamp / 1000U),
-	       (unsigned int)(thiscommand->timestamp % 1000U)); 
-      }
-      pout("\n");
-    }
-  }
-  QUIETON(con);
-  if (con->quietmode)
-    pout("\n");
-  QUIETOFF(con);
-  return data->ata_error_count;  
-}
-
-// return value is number of entries found where the self-test showed an error
-int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *data,int allentries){
-  int i,j,noheaderprinted=1;
-  int retval=0;
-
-  if (allentries)
-    pout("SMART Self-test log, version number %d\n",(int)data->revnumber);
-  if ((data->revnumber!=0x0001) && allentries && con->fixfirmwarebug != FIX_SAMSUNG)
-    pout("Warning - structure revision number does not match spec!\n");
-  if (data->mostrecenttest==0){
-    if (allentries)
-      pout("No self-tests have been logged\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;
-
-      // test name
-      switch(log->selftestnumber){
-      case   0: msgtest="Off-line           "; break;
-      case   1: msgtest="Short off-line     "; break;
-      case   2: msgtest="Extended off-line  "; break;
-      case 127: msgtest="Abort off-line test"; break;
-      case 129: msgtest="Short captive      "; break;
-      case 130: msgtest="Extended captive   "; break;
-      default:  msgtest="Unknown test       ";
-      }
-      
-      // test status
-      switch((log->selfteststatus)>>4){
-      case  0:msgstat="Completed                    "; 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="Test 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,"0x%08x",log->lbafirstfailure);
-
-      if (noheaderprinted && (allentries || errorfound)){
-	pout("Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error\n");
-	noheaderprinted=0;
-      }
-      
-      if (allentries || errorfound)
-	pout("#%2d  %s %s %s  %8d         %s\n",21-i,msgtest,msgstat,
-	     percent,(int)log->timestamp,firstlba);
-    }
-  }
-  if (!allentries && retval)
-    pout("\n");
-  return retval;
-}
-
-void ataPseudoCheckSmart ( struct ata_smart_values *data, 
-                           struct ata_smart_thresholds *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 &&
-	data->vendor_attributes[i].status.flag.prefailure &&
-	(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 has failed: exiting.  To continue, set the tolerance level to something other than 'conservative'\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 has failed: exiting. To continue, use the -T option to set the tolerance level to 'permissive'\n");
-    exit(returnvalue);
-  }
-
-  pout("Smartctl internal error in failuretest(type=%d). Please contact %s\n",type,PROJECTHOME);
-  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 hd_driveid drive;
-struct ata_smart_values smartval;
-struct ata_smart_thresholds smartthres;
-struct ata_smart_errorlog smarterror;
-struct ata_smart_selftestlog smartselftest;
-
-int ataPrintMain (int fd){
-  int timewait,code;
-  int returnval=0;
-
-  // Start by getting Drive ID information.  We need this, to know if SMART is supported.
-  if (ataReadHDIdentity(fd,&drive)){
-    pout("Smartctl: Hard Drive Read Identity Failed\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)
-    applypresets(&drive, con->attributedefs, con);
-
-  // Print most drive identity information if requested
-  if (con->driveinfo){
-    pout("=== START OF INFORMATION SECTION ===\n");
-    ataPrintDriveInfo(&drive);
-  }
-  
-  // now check if drive supports SMART; otherwise time to exit
-  if (!ataSmartSupport(&drive)){
-    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");
-    if (ataEnableSmart(fd)){
-      pout("                  No SMART functionality found. Sorry.\n");
-      failuretest(MANDATORY_CMD,returnval|=FAILSMART);
-    }
-    else
-      pout("                  SMART appears to work.  Continuing.\n"); 
-    if (!con->driveinfo) pout("\n");
-  }
-  
-  // Now print remaining drive info: is SMART enabled?    
-  if (con->driveinfo){
-    pout("SMART support is: Available - device has SMART capability.\n");
-    if (ataDoesSmartWork(fd))
-      pout("SMART support is: Enabled\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);
-    }
-    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);
-    }
-    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");
-  }
-
-  // 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 {
-	  QUIETON(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
-      QUIETON(con);
-      pout("SMART overall-health self-assessment test result: FAILED!\n"
-	   "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-      QUIETOFF(con);
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-	returnval|=FAILATTR;
-	if (con->smartvendorattrib)
-	  pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-	else {
-	  QUIETON(con);
-	  pout("Failed Attributes:\n");
-	  PrintSmartAttribWithThres(&smartval, &smartthres,1);
-	}
-      }
-      else
-	pout("No failed Attributes found.\n\n");   
-      returnval|=FAILSTATUS;
-      QUIETOFF(con);
-      break;
-
-    case -1:
-    default:
-      // The case where something went wrong with HDIO_DRIVE_TASK ioctl()
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-	QUIETON(con);
-	pout("SMART overall-health self-assessment test result: FAILED!\n"
-	     "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-	QUIETOFF(con);
-	returnval|=FAILATTR;
-	returnval|=FAILSTATUS;
-	if (con->smartvendorattrib)
-	  pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-	else {
-	  QUIETON(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 {
-	    QUIETON(con);
-	    pout("Please note the following marginal Attributes:\n");
-	    PrintSmartAttribWithThres(&smartval, &smartthres,2);
-	  } 
-	  returnval|=FAILAGE;
-	}
-	else
-	  pout("\n");
-      } 
-      QUIETOFF(con);
-      break;
-    } // end of switch statement
-    
-    QUIETOFF(con);
-  } // end of checking SMART Status
-  
-  // Print general SMART values
-  if (con->generalsmartvalues)
-    ataPrintGeneralSmartValues(&smartval, &drive); 
-
-  // Print vendor-specific attributes
-  if (con->smartvendorattrib){
-    QUIETON(con);
-    PrintSmartAttribWithThres(&smartval, &smartthres,con->quietmode?2:0);
-    QUIETOFF(con);
-  }
-
-  // Print SMART log Directory.  For the moment this command is hidden
-  if (con->smartlogdirectory){
-    struct ata_smart_log_directory smartlogdirectory;
-    if (!isGeneralPurposeLoggingCapable(&drive)){
-      pout("Warning: device does not support General Purpose Logging\n");
-    }
-    else {
-      QUIETON(con);
-      pout("Log Directory Supported\n");
-      if (ataReadLogDirectory(fd, &smartlogdirectory)){
-	QUIETOFF(con);
-	pout("Read Log Directory failed.\n\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else
-	ataPrintLogDirectory( &smartlogdirectory);
-    }
-    QUIETOFF(con);
-  }
-  
-  // Print SMART error log
-  if (con->smarterrorlog){
-    if (!isSmartErrorLogCapable(&smartval)){
-      pout("Warning: device does not support Error Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      if (ataReadErrorLog(fd, &smarterror)){
-	pout("Smartctl: SMART Errorlog Read Failed\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else {
-	// quiet mode is turned on inside ataPrintSmartErrorLog()
-	if (ataPrintSmartErrorlog(&smarterror))
-	  returnval|=FAILERR;
-	QUIETOFF(con);
-      }
-    }
-  }
-  
-  // Print SMART self-test log
-  if (con->smartselftestlog){
-    // Note that in spite of its name, isSmartErrorLogCapable() is
-    // the CORRECT way to see if a device supports the self-test log.
-    // The ATA spec says "if this command (READ LOG) is implemented,
-    // all address values for which the contents are defined shall be
-    // implemented...".  Since both the SMART self-test logs AND the
-    // SMART error logs are defined, if one will work then so will the
-    // other.
-    if (!isSmartErrorLogCapable(&smartval)){
-      pout("Warning: device does not support Self Test Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }    
-    else {
-      if(ataReadSelfTestLog(fd, &smartselftest)){
-	pout("Smartctl: SMART Self Test Log Read Failed\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else {
-	QUIETON(con);
-	if (ataPrintSmartSelfTestlog(&smartselftest,!con->quietmode))
-	  returnval|=FAILLOG;
-	QUIETOFF(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
-  if (con->testcase==OFFLINE_FULL_SCAN &&  !isSupportExecuteOfflineImmediate(&smartval)){
-    pout("Warning: device does not support Execute Off-Line Immediate function.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  else if (!isSupportSelfTest(&smartval)){
-    pout("Warning: device does not support Self-Test functions.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  // Now do the test.  Note ataSmartTest prints its own error/success
-  // messages
-  if (ataSmartTest(fd, con->testcase))
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  
-  // 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))){ 
-    pout("Please wait %d %s for test to complete.\n",
-	 (int)timewait, con->testcase==OFFLINE_FULL_SCAN?"seconds":"minutes");
-    
-    if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && con->testcase!=EXTEND_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 726110bb2..000000000
--- a/sm5/ataprint.cpp
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * ataprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 <syslog.h>
-#include <string.h>
-#include "atacmds.h"
-#include "ataprint.h"
-#include "smartctl.h"
-#include "extern.h"
-#include "utility.h"
-#include "knowndrives.h"
-
-const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.85 2003/04/25 22:31:41 ballen4705 Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// 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(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(in[i]); i--)
-    ;
-  last = i;
-
-  strncpy(out, in+first, last-first+1);
-  out[last-first+1] = '\0';
-}
-
-// Convenience function for formatting strings from hd_driveid.
-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. This is needed on little-endian architectures, eg Intel,
-// Alpha. If someone wants to run this on SPARC they'll need to test
-// for the Endian-ness and skip the byte swapping if it's big-endian.
-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");
-}
-
-void ataPrintDriveInfo (struct hd_driveid *drive){
-  int version, drivetype;
-  const char *description;
-  char unknown[64], timedatetz[64];
-  unsigned short minorrev;
-  char model[64], serial[64], firm[64];
-  
-
-  // print out model, serial # and firmware versions  (byte-swap ASCI strings)
-  pout("Device Model:     ");
-  printswap(model, drive->model,40);
-
-  pout("Serial Number:    ");
-  printswap(serial, drive->serial_no,20);
-
-  pout("Firmware Version: ");
-  printswap(firm, drive->fw_rev,8);
-
-  // 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;
-}
-
-
-/*  prints verbose value Off-line data collection status byte */
-void PrintSmartOfflineStatus(struct ata_smart_values *data){
-
-  pout("Off-line data collection status: ");	
-  
-  switch(data->offline_data_collection_status){
-  case 0x00:
-  case 0x80:
-    pout("(0x%02x)\tOffline data collection activity was\n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("never started.\n");
-    break;
-  case 0x01:
-  case 0x81:
-    pout("(0x%02x)\tReserved.\n",
-	 (int)data->offline_data_collection_status);
-    break;
-  case 0x02:
-  case 0x82:
-    pout("(0x%02x)\tOffline data collection activity \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("completed without error.\n");
-    break;
-  case 0x03:
-  case 0x83:
-    pout("(0x%02x)\tReserved.\n",
-	 (int)data->offline_data_collection_status);
-    break;
-  case 0x04:
-  case 0x84:
-    pout("(0x%02x)\tOffline data collection activity was \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("suspended by an interrupting command from host.\n");
-    break;
-  case 0x05:
-  case 0x85:
-    pout("(0x%02x)\tOffline data collection activity was \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("aborted by an interrupting command from host.\n");
-    break;
-  case 0x06:
-  case 0x86:
-    pout("(0x%02x)\tOffline data collection activity was \n\t\t\t\t\t",
-	 (int)data->offline_data_collection_status);
-    pout("aborted by the device with a fatal error.\n");
-    break;
-  default:
-    if ( ((data->offline_data_collection_status >= 0x07) &&
-	  (data->offline_data_collection_status <= 0x3f)) ||
-	 ((data->offline_data_collection_status >= 0xc0) &&
-	  (data->offline_data_collection_status <= 0xff)) )
-      pout("(0x%02x)\tVendor Specific.\n",(int)data->offline_data_collection_status);
-    else
-      pout("(0x%02x)\tReserved.\n",(int)data->offline_data_collection_status);
-  }
-
-  // report on Automatic Data Collection Status.  Only IBM documents
-  // this bit.
-  if (data->offline_data_collection_status & 0x80)
-    pout("\t\t\t\t\tAuto Off-line Data Collection: Enabled.\n");
-  else
-    pout("\t\t\t\t\tAuto Off-line 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 off-line \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("\tOff-line 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)? 
-	  "Automatic timer ON/OFF support.":
-	  "No Automatic timer ON/OFF 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)
-{
-
-   pout("Error logging capability:       ");
-    
-   if ( isSmartErrorLogCapable(data) )
-   {
-      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){
-  if (isSupportSelfTest(data)){
-    pout("Short self-test routine \n");
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->short_test_completion_time);
-  }
-  else {
-    pout("Short self-test routine \n");
-    pout("recommended polling time: \t        Not Supported.\n");
-  }
-}
-
-void PrintSmartExtendedSelfTestPollingTime(struct ata_smart_values *data){
-  if (isSupportSelfTest(data)){
-    pout("Extended self-test routine \n");
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->extend_test_completion_time);
-  }
-  else {
-    pout("Extended self-test routine \n");
-    pout("recommended polling time: \t        Not Supported.\n");
-  }
-}
-
-void PrintSmartConveyanceSelfTestPollingTime(struct ata_smart_values *data){
-  if (isSupportConveyanceSelfTest(data)){
-    pout("Extended self-test routine \n");
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->conveyance_test_completion_time);
-  }
-  else {
-    pout("Extended self-test routine \n");
-    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 *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;
-      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 && (!disk->status.flag.prefailure || !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     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[disk->id]);
-      pout("%-28s",attributename);
-
-      // printing line for each valid attribute
-      type=disk->status.flag.prefailure?"Pre-fail":"Old_age";
-      pout("0x%04x   %.3d   %.3d   %.3d    %-9s%-12s", 
-	     (int)disk->status.all, (int)disk->current, (int)disk->worst,
-	     (int)thre->threshold, type, 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[disk->id]);
-	ataPrintSmartAttribName(atthr, thre->id, con->attributedefs[thre->id]);
-	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 hd_driveid *drive){
-  pout("General SMART Values:\n");
-  
-  PrintSmartOfflineStatus(data); 
-  
-  if (isSupportSelfTest(data)){
-    PrintSmartSelfExecStatus (data);
-  }
-  
-  PrintSmartTotalTimeCompleteOffline(data);
-  PrintSmartOfflineCollectCap(data);
-  PrintSmartCapability(data);
-  
-  PrintSmartErrorLogCapability(data);
-
-  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");
-}
-
-// 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;
-}
-
-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 i,j,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;
-  }
-  QUIETON(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) {
-    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);
-  QUIETOFF(con);
-  pout("\tDCR = Device Control Register\n");
-  pout("\tFR  = Features Register\n");
-  pout("\tSC  = Sector Count Register\n");
-  pout("\tSN  = Sector Number Register\n");
-  pout("\tCL  = Cylinder Low Register\n");
-  pout("\tCH  = Cylinder High Register\n");
-  pout("\tD/H = Device/Head Register\n");
-  pout("\tCR  = Content written to Command Register\n");
-  pout("\tER  = Error register\n");
-  pout("\tSTA = Status register\n");
-  pout("Timestamp is seconds since the previous disk power-on.\n");
-  pout("Note: timestamp \"wraps\" after 2^32 msec = 49.710 days.\n\n");
-  
-  // now step through the five error log data structures (table 39 of spec)
-  for (k = 4; k >= 0; k-- ) {
-    
-    // The error log data structure entries are a circular buffer
-    i=(data->error_log_pointer+k)%5;
-    
-    // Spec says: unused error log structures shall be zero filled
-    if (nonempty((unsigned char*)&(data->errorlog_struct[i]),sizeof(data->errorlog_struct[i]))){
-      char *msgstate;
-      switch (data->errorlog_struct[i].error_struct.state){
-      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 off-line or self test"; break;
-      default:   msgstate="in a vendor specific or reserved state";
-      }
-      // See table 42 of ATA5 spec
-      QUIETON(con);
-      pout("Error %d occurred at disk power-on lifetime: %d hours\n",
-	     (int)(data->ata_error_count+k-4), (int)data->errorlog_struct[i].error_struct.timestamp);
-      QUIETOFF(con);
-      pout("When the command that caused the error occurred, the device was %s.\n",msgstate);
-      pout("After command completion occurred, registers were:\n");
-      pout("ER:%02x SC:%02x SN:%02x CL:%02x CH:%02x D/H:%02x ST:%02x\n",
-	   (int)data->errorlog_struct[i].error_struct.error_register,
-	   (int)data->errorlog_struct[i].error_struct.sector_count,
-	   (int)data->errorlog_struct[i].error_struct.sector_number,
-	   (int)data->errorlog_struct[i].error_struct.cylinder_low,
-	   (int)data->errorlog_struct[i].error_struct.cylinder_high,
-	   (int)data->errorlog_struct[i].error_struct.drive_head,
-	   (int)data->errorlog_struct[i].error_struct.status);
-      pout("Sequence of commands leading to the command that caused the error were:\n");
-      pout("DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp\n");
-      for ( j = 4; j >= 0; j--){
-	struct ata_smart_errorlog_command_struct *thiscommand=&(data->errorlog_struct[i].commands[j]);
-	
-	// Spec says: unused data command structures shall be zero filled
-	if (nonempty((unsigned char*)thiscommand,sizeof(*thiscommand)))
-	  pout(" %02x   %02x   %02x   %02x   %02x   %02x    %02x   %02x     %d.%03d\n", 
-	       (int)thiscommand->devicecontrolreg,
-	       (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->commandreg,
-	       (unsigned int)(thiscommand->timestamp / 1000U),
-	       (unsigned int)(thiscommand->timestamp % 1000U)); 
-      }
-      pout("\n");
-    }
-  }
-  QUIETON(con);
-  if (con->quietmode)
-    pout("\n");
-  QUIETOFF(con);
-  return data->ata_error_count;  
-}
-
-// return value is number of entries found where the self-test showed an error
-int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *data,int allentries){
-  int i,j,noheaderprinted=1;
-  int retval=0;
-
-  if (allentries)
-    pout("SMART Self-test log, version number %d\n",(int)data->revnumber);
-  if ((data->revnumber!=0x0001) && allentries && con->fixfirmwarebug != FIX_SAMSUNG)
-    pout("Warning - structure revision number does not match spec!\n");
-  if (data->mostrecenttest==0){
-    if (allentries)
-      pout("No self-tests have been logged\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;
-
-      // test name
-      switch(log->selftestnumber){
-      case   0: msgtest="Off-line           "; break;
-      case   1: msgtest="Short off-line     "; break;
-      case   2: msgtest="Extended off-line  "; break;
-      case 127: msgtest="Abort off-line test"; break;
-      case 129: msgtest="Short captive      "; break;
-      case 130: msgtest="Extended captive   "; break;
-      default:  msgtest="Unknown test       ";
-      }
-      
-      // test status
-      switch((log->selfteststatus)>>4){
-      case  0:msgstat="Completed                    "; 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="Test 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,"0x%08x",log->lbafirstfailure);
-
-      if (noheaderprinted && (allentries || errorfound)){
-	pout("Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error\n");
-	noheaderprinted=0;
-      }
-      
-      if (allentries || errorfound)
-	pout("#%2d  %s %s %s  %8d         %s\n",21-i,msgtest,msgstat,
-	     percent,(int)log->timestamp,firstlba);
-    }
-  }
-  if (!allentries && retval)
-    pout("\n");
-  return retval;
-}
-
-void ataPseudoCheckSmart ( struct ata_smart_values *data, 
-                           struct ata_smart_thresholds *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 &&
-	data->vendor_attributes[i].status.flag.prefailure &&
-	(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 has failed: exiting.  To continue, set the tolerance level to something other than 'conservative'\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 has failed: exiting. To continue, use the -T option to set the tolerance level to 'permissive'\n");
-    exit(returnvalue);
-  }
-
-  pout("Smartctl internal error in failuretest(type=%d). Please contact %s\n",type,PROJECTHOME);
-  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 hd_driveid drive;
-struct ata_smart_values smartval;
-struct ata_smart_thresholds smartthres;
-struct ata_smart_errorlog smarterror;
-struct ata_smart_selftestlog smartselftest;
-
-int ataPrintMain (int fd){
-  int timewait,code;
-  int returnval=0;
-
-  // Start by getting Drive ID information.  We need this, to know if SMART is supported.
-  if (ataReadHDIdentity(fd,&drive)){
-    pout("Smartctl: Hard Drive Read Identity Failed\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)
-    applypresets(&drive, con->attributedefs, con);
-
-  // Print most drive identity information if requested
-  if (con->driveinfo){
-    pout("=== START OF INFORMATION SECTION ===\n");
-    ataPrintDriveInfo(&drive);
-  }
-  
-  // now check if drive supports SMART; otherwise time to exit
-  if (!ataSmartSupport(&drive)){
-    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");
-    if (ataEnableSmart(fd)){
-      pout("                  No SMART functionality found. Sorry.\n");
-      failuretest(MANDATORY_CMD,returnval|=FAILSMART);
-    }
-    else
-      pout("                  SMART appears to work.  Continuing.\n"); 
-    if (!con->driveinfo) pout("\n");
-  }
-  
-  // Now print remaining drive info: is SMART enabled?    
-  if (con->driveinfo){
-    pout("SMART support is: Available - device has SMART capability.\n");
-    if (ataDoesSmartWork(fd))
-      pout("SMART support is: Enabled\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);
-    }
-    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);
-    }
-    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");
-  }
-
-  // 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 {
-	  QUIETON(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
-      QUIETON(con);
-      pout("SMART overall-health self-assessment test result: FAILED!\n"
-	   "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-      QUIETOFF(con);
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-	returnval|=FAILATTR;
-	if (con->smartvendorattrib)
-	  pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-	else {
-	  QUIETON(con);
-	  pout("Failed Attributes:\n");
-	  PrintSmartAttribWithThres(&smartval, &smartthres,1);
-	}
-      }
-      else
-	pout("No failed Attributes found.\n\n");   
-      returnval|=FAILSTATUS;
-      QUIETOFF(con);
-      break;
-
-    case -1:
-    default:
-      // The case where something went wrong with HDIO_DRIVE_TASK ioctl()
-      if (ataCheckSmart(&smartval, &smartthres,1)){
-	QUIETON(con);
-	pout("SMART overall-health self-assessment test result: FAILED!\n"
-	     "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
-	QUIETOFF(con);
-	returnval|=FAILATTR;
-	returnval|=FAILSTATUS;
-	if (con->smartvendorattrib)
-	  pout("See vendor-specific Attribute list for failed Attributes.\n\n");
-	else {
-	  QUIETON(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 {
-	    QUIETON(con);
-	    pout("Please note the following marginal Attributes:\n");
-	    PrintSmartAttribWithThres(&smartval, &smartthres,2);
-	  } 
-	  returnval|=FAILAGE;
-	}
-	else
-	  pout("\n");
-      } 
-      QUIETOFF(con);
-      break;
-    } // end of switch statement
-    
-    QUIETOFF(con);
-  } // end of checking SMART Status
-  
-  // Print general SMART values
-  if (con->generalsmartvalues)
-    ataPrintGeneralSmartValues(&smartval, &drive); 
-
-  // Print vendor-specific attributes
-  if (con->smartvendorattrib){
-    QUIETON(con);
-    PrintSmartAttribWithThres(&smartval, &smartthres,con->quietmode?2:0);
-    QUIETOFF(con);
-  }
-
-  // Print SMART log Directory.  For the moment this command is hidden
-  if (con->smartlogdirectory){
-    struct ata_smart_log_directory smartlogdirectory;
-    if (!isGeneralPurposeLoggingCapable(&drive)){
-      pout("Warning: device does not support General Purpose Logging\n");
-    }
-    else {
-      QUIETON(con);
-      pout("Log Directory Supported\n");
-      if (ataReadLogDirectory(fd, &smartlogdirectory)){
-	QUIETOFF(con);
-	pout("Read Log Directory failed.\n\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else
-	ataPrintLogDirectory( &smartlogdirectory);
-    }
-    QUIETOFF(con);
-  }
-  
-  // Print SMART error log
-  if (con->smarterrorlog){
-    if (!isSmartErrorLogCapable(&smartval)){
-      pout("Warning: device does not support Error Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      if (ataReadErrorLog(fd, &smarterror)){
-	pout("Smartctl: SMART Errorlog Read Failed\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else {
-	// quiet mode is turned on inside ataPrintSmartErrorLog()
-	if (ataPrintSmartErrorlog(&smarterror))
-	  returnval|=FAILERR;
-	QUIETOFF(con);
-      }
-    }
-  }
-  
-  // Print SMART self-test log
-  if (con->smartselftestlog){
-    // Note that in spite of its name, isSmartErrorLogCapable() is
-    // the CORRECT way to see if a device supports the self-test log.
-    // The ATA spec says "if this command (READ LOG) is implemented,
-    // all address values for which the contents are defined shall be
-    // implemented...".  Since both the SMART self-test logs AND the
-    // SMART error logs are defined, if one will work then so will the
-    // other.
-    if (!isSmartErrorLogCapable(&smartval)){
-      pout("Warning: device does not support Self Test Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }    
-    else {
-      if(ataReadSelfTestLog(fd, &smartselftest)){
-	pout("Smartctl: SMART Self Test Log Read Failed\n");
-	failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-      }
-      else {
-	QUIETON(con);
-	if (ataPrintSmartSelfTestlog(&smartselftest,!con->quietmode))
-	  returnval|=FAILLOG;
-	QUIETOFF(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
-  if (con->testcase==OFFLINE_FULL_SCAN &&  !isSupportExecuteOfflineImmediate(&smartval)){
-    pout("Warning: device does not support Execute Off-Line Immediate function.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  else if (!isSupportSelfTest(&smartval)){
-    pout("Warning: device does not support Self-Test functions.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  // Now do the test.  Note ataSmartTest prints its own error/success
-  // messages
-  if (ataSmartTest(fd, con->testcase))
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  
-  // 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))){ 
-    pout("Please wait %d %s for test to complete.\n",
-	 (int)timewait, con->testcase==OFFLINE_FULL_SCAN?"seconds":"minutes");
-    
-    if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && con->testcase!=EXTEND_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 5dbfd6b28..000000000
--- a/sm5/ataprint.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ataprint.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 _SMART_PRINT_H_
-#define _SMART_PRINT_H_
-
-#ifndef ATAPRINT_H_CVSID
-#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.20 2003/04/18 12:37:14 ballen4705 Exp $\n"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-// MACROS to control printing behavior
-#define QUIETON(control)  {if (control->quietmode) control->veryquietmode=0;}
-#define QUIETOFF(control) {if (control->quietmode && !control->veryquietmode) control->veryquietmode=1;}
-
-
-
-
-/* Prints ATA Drive Information and S.M.A.R.T. Capability */
-void ataPrintDriveInfo(struct hd_driveid *);
-
-void ataPrintGeneralSmartValues(struct ata_smart_values *, struct hd_driveid *);
-
-void ataPrintSmartThresholds(struct ata_smart_thresholds *);
-
-// 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 *,
-				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 *);
-
-// Convenience function for formatting strings from hd_driveid.
-void formatdriveidstring(char *out, const char *in, int n);
-
-int ataPrintMain(int fd);
-
-#endif
diff --git a/sm5/cvs-script b/sm5/cvs-script
deleted file mode 100755
index 6974e72e2..000000000
--- a/sm5/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.smartmontools.sourceforge.net:/cvsroot/smartmontools
diff --git a/sm5/examplescripts/Example1 b/sm5/examplescripts/Example1
deleted file mode 100755
index 5efb0287c..000000000
--- a/sm5/examplescripts/Example1
+++ /dev/null
@@ -1,41 +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.2 2003/02/12 20:01:45 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_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 $SMARTD_DEVICE >> /root/tempfile
-
-# Email the contents of the temp file
-/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile > /dev/null 2> /dev/null
-
-# And exit
-exit 0
diff --git a/sm5/examplescripts/Example2 b/sm5/examplescripts/Example2
deleted file mode 100755
index 754dc9a26..000000000
--- a/sm5/examplescripts/Example2
+++ /dev/null
@@ -1,21 +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.2 2003/02/12 20:01:45 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 $SMARTD_DEVICE >> /root/msg
-
-# Now email the message to the user at address ADD:
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
-
diff --git a/sm5/examplescripts/Example3 b/sm5/examplescripts/Example3
deleted file mode 100755
index 12b6660e0..000000000
--- 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.2 2003/02/12 20:01:45 ballen4705 Exp $
-
-# Warn all users of a problem     
-wall 'Problem detected with disk: ' $SMARTD_DEVICE      
-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!)
-
-# /usr/sbin/shutdown -hf now
-
diff --git a/sm5/examplescripts/README b/sm5/examplescripts/README
deleted file mode 100644
index dd6cc2f5b..000000000
--- a/sm5/examplescripts/README
+++ /dev/null
@@ -1,50 +0,0 @@
-# Home page: http://smartmontools.sourceforge.net
-#
-# $Id: README,v 1.1 2003/02/12 19:58:33 ballen4705 Exp $
-#
-# Copyright (C) 2002 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 74c7cb89a..000000000
--- a/sm5/extern.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * extern.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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_
-
-
-#ifndef EXTERN_H_CVSID
-#define EXTERN_H_CVSID "$Id: extern.h,v 1.24 2003/04/19 09:53:41 pjwilliams Exp $\n"
-#endif
-
-// Possible values for fixfirmwarebug
-#define FIX_NONE             0
-#define FIX_SAMSUNG          1
-
-// 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 {
-  unsigned char driveinfo;
-  unsigned char checksmart;
-  unsigned char smartvendorattrib;
-  unsigned char generalsmartvalues;
-  unsigned char smartlogdirectory;
-  unsigned char smartselftestlog;
-  unsigned char smarterrorlog;
-  unsigned char smartdisable;
-  unsigned char smartenable; 
-  unsigned char smartstatus;
-  unsigned char smartexeoffimmediate;
-  unsigned char smartshortselftest;
-  unsigned char smartextendselftest;
-  unsigned char smartshortcapselftest;
-  unsigned char smartextendcapselftest;
-  unsigned char smartselftestabort;
-  unsigned char smartautoofflineenable;
-  unsigned char smartautoofflinedisable;
-  unsigned char smartautosaveenable;
-  unsigned char smartautosavedisable;
-  int           testcase;
-  unsigned char quietmode;
-  unsigned char veryquietmode;
-  unsigned char permissive;
-  unsigned char conservative;
-  unsigned char checksumfail;
-  unsigned char checksumignore;
-  unsigned char reportataioctl;
-  unsigned char reportscsiioctl;
-  unsigned char fixfirmwarebug;
-  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/knowndrives.c b/sm5/knowndrives.c
deleted file mode 100644
index 84698b1a9..000000000
--- a/sm5/knowndrives.c
+++ /dev/null
@@ -1,412 +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 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 <regex.h>
-#include "atacmds.h"
-#include "ataprint.h"
-#include "knowndrives.h"
-#include "utility.h"
-
-const char *knowndrives_c_cvsid="$Id: knowndrives.c,v 1.21 2003/04/22 03:13:43 ballen4705 Exp $" ATACMDS_H_CVSID ATAPRINT_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_194_10XCELSIUS              { 194,  1 }
-#define PRESET_194_UNKNOWN                 { 194,  2 }
-#define PRESET_200_WRITEERRORCOUNT         { 200,  1 }
-#define PRESET_220_TEMP                    { 220,  1 }
-
-/* Arrays of preset vendor-specific attribute options for use in
- * knowndrives[]. */
-
-// This one is common to several models.
-const unsigned char vendoropts_9_minutes[][2] = {
-  PRESET_9_MINUTES,
-  {0,0}
-};
-
-const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_194_UNKNOWN,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MPE3204AT[][2] = {
-  PRESET_9_SECONDS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
-  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}
-};
-
-/* Special-purpose functions for use in knowndrives[]. */
-void specialpurpose_reverse_samsung(smartmonctrl *con)
-{
-  con->fixfirmwarebug = FIX_SAMSUNG;
-}
-
-/* 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",
-    NULL, NULL, NULL
-  },
-  { // IBM Deskstar 40GV & 75GXP series
-    "(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/",
-    NULL, NULL, NULL
-  },
-  { // Fujitsu MPE3204AT
-    "^FUJITSU MPE3204AT$",
-    ".*",    // Tested on ED-03-04
-    NULL,
-    vendoropts_Fujitsu_MPE3204AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHS2020AT
-    "^FUJITSU MHS2020AT$",
-    ".*",    // Tested on 8004
-    NULL,
-    vendoropts_Fujitsu_MHS2020AT,
-    NULL, NULL
-  },
-  { // Samsung SV4012H (known firmware)
-    "^SAMSUNG SV4012H$",
-    "^RM100-08",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { // Samsung SV4012H (all other firmware)
-    "^SAMSUNG SV4012H$",
-    ".*",
-    "Contact developers; may need -F disabled",
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { // Samsung SV1204H (known firmware)
-    "^SAMSUNG SV1204H$",
-    "^RK100-1[3-5]$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { //Samsung SV1204H (all other firmware)
-    "^SAMSUNG SV1204H$",
-    ".*",
-    "Contact developers; may need -F disabled",
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { // Samsung ALL OTHER DRIVES
-    "^SAMSUNG.*",
-    ".*",
-    "Contact developers; may need -F enabled.\n",
-    NULL, NULL, NULL
-  },
-  { // Maxtor 6L080J4 and 4K080H4
-    "^MAXTOR (6L080J4|4K080H4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor 4D080H4
-    "^Maxtor 4D080H4$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor 4R080J0
-    "^Maxtor 4R080J0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor 6Y120P0 (known firmware)
-    "^Maxtor 6Y120P0$",
-    "^YAR41VW0$",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor 6Y120P0 (any other firmware)
-    "^Maxtor 6Y120P0$",
-    ".*",
-    "Contact developers; may need -v 9,minutes enabled.\n",
-    NULL,
-    NULL, NULL
-  },
-  { // HITACHI_DK23BA-20
-    "^HITACHI_DK23BA-20$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // IBM GXP-180
-    "^IC35L120AVV207-0$",
-    ".*", 
-    NULL, NULL, NULL, NULL 
-  },
-  {
-    //  IBM Deskstar 120GXP  [Phil -- use for testing]
-    "^IC35L060AVVA07-0$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-  },
-  {
-    // TOSHIBA MK6021GAS [Bruce -- use for testing on laptop]
-    "^TOSHIBA MK6021GAS$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-  },
-  /*------------------------------------------------------------
-   *  End of table.  Do not add entries below this marker.
-   *------------------------------------------------------------ */
-  {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.\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[64];
-    const int attr = (*presets)[0], val  = (*presets)[1];
-    
-    // if we are at the end of the attribute list, break out
-    if (!attr)  
-      break;
-    
-    ataPrintSmartAttribName(out, attr, val);
-    // 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");
-  }
-  return;
-}
-
-// Shows the presets (if any) that are available for the given drive.
-void showpresets(const struct hd_driveid *drive){
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, 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 hd_driveid *drive, unsigned char opts[256],
-                  smartmonctrl *con) {
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-  
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, drive->fw_rev, FIRMWARE_STRING_LENGTH);
-
-  // Look up the drive in knowndrives[] and check vendoropts is non-NULL.
-  if ((i = lookupdrive(model, firmware)) >= 0 && 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 function is defined for this drive then call it.
-    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 3375167e1..000000000
--- a/sm5/knowndrives.cpp
+++ /dev/null
@@ -1,412 +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 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 <regex.h>
-#include "atacmds.h"
-#include "ataprint.h"
-#include "knowndrives.h"
-#include "utility.h"
-
-const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.21 2003/04/22 03:13:43 ballen4705 Exp $" ATACMDS_H_CVSID ATAPRINT_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_194_10XCELSIUS              { 194,  1 }
-#define PRESET_194_UNKNOWN                 { 194,  2 }
-#define PRESET_200_WRITEERRORCOUNT         { 200,  1 }
-#define PRESET_220_TEMP                    { 220,  1 }
-
-/* Arrays of preset vendor-specific attribute options for use in
- * knowndrives[]. */
-
-// This one is common to several models.
-const unsigned char vendoropts_9_minutes[][2] = {
-  PRESET_9_MINUTES,
-  {0,0}
-};
-
-const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_194_UNKNOWN,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MPE3204AT[][2] = {
-  PRESET_9_SECONDS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
-  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}
-};
-
-/* Special-purpose functions for use in knowndrives[]. */
-void specialpurpose_reverse_samsung(smartmonctrl *con)
-{
-  con->fixfirmwarebug = FIX_SAMSUNG;
-}
-
-/* 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",
-    NULL, NULL, NULL
-  },
-  { // IBM Deskstar 40GV & 75GXP series
-    "(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/",
-    NULL, NULL, NULL
-  },
-  { // Fujitsu MPE3204AT
-    "^FUJITSU MPE3204AT$",
-    ".*",    // Tested on ED-03-04
-    NULL,
-    vendoropts_Fujitsu_MPE3204AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHS2020AT
-    "^FUJITSU MHS2020AT$",
-    ".*",    // Tested on 8004
-    NULL,
-    vendoropts_Fujitsu_MHS2020AT,
-    NULL, NULL
-  },
-  { // Samsung SV4012H (known firmware)
-    "^SAMSUNG SV4012H$",
-    "^RM100-08",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { // Samsung SV4012H (all other firmware)
-    "^SAMSUNG SV4012H$",
-    ".*",
-    "Contact developers; may need -F disabled",
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { // Samsung SV1204H (known firmware)
-    "^SAMSUNG SV1204H$",
-    "^RK100-1[3-5]$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { //Samsung SV1204H (all other firmware)
-    "^SAMSUNG SV1204H$",
-    ".*",
-    "Contact developers; may need -F disabled",
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    "Fixes byte order in some SMART data (same as -F)"
-  },
-  { // Samsung ALL OTHER DRIVES
-    "^SAMSUNG.*",
-    ".*",
-    "Contact developers; may need -F enabled.\n",
-    NULL, NULL, NULL
-  },
-  { // Maxtor 6L080J4 and 4K080H4
-    "^MAXTOR (6L080J4|4K080H4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor 4D080H4
-    "^Maxtor 4D080H4$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor 4R080J0
-    "^Maxtor 4R080J0$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor 6Y120P0 (known firmware)
-    "^Maxtor 6Y120P0$",
-    "^YAR41VW0$",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // Maxtor 6Y120P0 (any other firmware)
-    "^Maxtor 6Y120P0$",
-    ".*",
-    "Contact developers; may need -v 9,minutes enabled.\n",
-    NULL,
-    NULL, NULL
-  },
-  { // HITACHI_DK23BA-20
-    "^HITACHI_DK23BA-20$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // IBM GXP-180
-    "^IC35L120AVV207-0$",
-    ".*", 
-    NULL, NULL, NULL, NULL 
-  },
-  {
-    //  IBM Deskstar 120GXP  [Phil -- use for testing]
-    "^IC35L060AVVA07-0$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-  },
-  {
-    // TOSHIBA MK6021GAS [Bruce -- use for testing on laptop]
-    "^TOSHIBA MK6021GAS$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-  },
-  /*------------------------------------------------------------
-   *  End of table.  Do not add entries below this marker.
-   *------------------------------------------------------------ */
-  {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.\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[64];
-    const int attr = (*presets)[0], val  = (*presets)[1];
-    
-    // if we are at the end of the attribute list, break out
-    if (!attr)  
-      break;
-    
-    ataPrintSmartAttribName(out, attr, val);
-    // 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");
-  }
-  return;
-}
-
-// Shows the presets (if any) that are available for the given drive.
-void showpresets(const struct hd_driveid *drive){
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, 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 hd_driveid *drive, unsigned char opts[256],
-                  smartmonctrl *con) {
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-  
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, drive->fw_rev, FIRMWARE_STRING_LENGTH);
-
-  // Look up the drive in knowndrives[] and check vendoropts is non-NULL.
-  if ((i = lookupdrive(model, firmware)) >= 0 && 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 function is defined for this drive then call it.
-    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 afeeb2565..000000000
--- a/sm5/knowndrives.h
+++ /dev/null
@@ -1,82 +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 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.6 2003/04/20 15:38:38 ballen4705 Exp $\n"
-
-#include <linux/hdreg.h>
-#include "extern.h"
-
-/* 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 hd_driveid *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 hd_driveid *drive, unsigned char opts[256],
-                  smartmonctrl *con);
-
-#endif
diff --git a/sm5/scsicmds.c b/sm5/scsicmds.c
deleted file mode 100644
index f757f7d6e..000000000
--- a/sm5/scsicmds.c
+++ /dev/null
@@ -1,1631 +0,0 @@
-/*
- * scsicmds.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003 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 <getopt.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include "scsicmds.h"
-#include "utility.h"
-#include "extern.h"
-
-const char *scsicmds_c_cvsid="$Id: scsicmds.c,v 1.42 2003/04/29 16:01:09 makisara Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID;
-
-/* for passing global control variables */
-extern smartmonctrl *con;
-
-/* output binary in hex and optionally ascii */
-static 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;
-}
-
-/* SCSI command transmission interface function, implementation is OS
- * specific. */
-static int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop);
-
-/* <<<<<<<<<<<<<<<< Start of Linux specific code >>>>>>>>>>>>>>>>> */
-#if 1   
-/* Linux specific code, FreeBSD could conditionally compile in CAM stuff 
- * instead of this. */
-
-/* #include <scsi/scsi.h>       bypass for now */
-/* #include <scsi/scsi_ioctl.h> bypass for now */
-
-#define MAX_DXFER_LEN 1024      /* can be increased if necessary */
-#define SEND_IOCTL_RESP_SENSE_LEN 16    /* ioctl limitation */
-#define DRIVER_SENSE  0x8       /* alternate CHECK CONDITION indication */
-
-#ifndef SCSI_IOCTL_SEND_COMMAND
-#define SCSI_IOCTL_SEND_COMMAND 1
-#endif
-#ifndef SCSI_IOCTL_TEST_UNIT_READY
-#define SCSI_IOCTL_TEST_UNIT_READY 2
-#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 pending in Linux 2.4 and 2.5 to extend SEND DIAGNOSTIC timeout
- * to 2 hours in order to allow long foreground extended self tests. */
-static int linux_do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop)
-{
-    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 (con->reportscsiioctl > 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 < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((con->reportscsiioctl > 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", iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-    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 (con->reportscsiioctl)
-            pout("  status=-1, errno=%d [%s]\n", errno, strerror(errno));
-        return -errno;
-    }
-    if (0 == status) {
-        if (con->reportscsiioctl > 0)
-            pout("  status=0\n");
-        if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-            memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
-            if (con->reportscsiioctl > 1) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex(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 (DRIVER_SENSE == ((status >> 24) & 0xff))
-        iop->scsi_status = 2;
-    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 (con->reportscsiioctl > 1) {
-            pout("  >>> Sense buffer, len=%d:\n", len);
-            dStrHex(wrk.buff, len , 1);
-        }
-    }
-    if (con->reportscsiioctl) {
-        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 (con->reportscsiioctl > 0)
-            pout("  ioctl status=0x%x but scsi status=0, fail with ENODEV\n", 
-                 status);
-        return -ENODEV;      /* give up, assume no device there */
-    }
-}
-
-static int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop)
-{
-    return linux_do_scsi_cmnd_io(dev_fd, iop);
-}
-#endif
-/* <<<<<<<<<<<<<<<< End of Linux specific code >>>>>>>>>>>>>>>>> */
-
-void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
-                          struct scsi_sense_disect * out)
-{
-    memset(out, 0, sizeof(out));
-    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)
-        return 1;
-    else if (SCSI_SK_ILLEGAL_REQUEST == sinfo->sense_key) {
-        if (SCSI_ASC_UNKNOWN_OPCODE == sinfo->asc)
-            return 2;
-        else if (SCSI_ASC_UNKNOWN_FIELD == sinfo->asc)
-            return 3;
-        else if (SCSI_ASC_UNKNOWN_PARAM == sinfo->asc)
-            return 4;
-    }
-    return 0;
-}
-
-const char * scsiErrString(int scsiErr)
-{
-    if (scsiErr < 0)
-        return strerror(-scsiErr);
-    switch (scsiErr) {
-        case 0: 
-            return "no error";
-        case 1: 
-            return "device not ready";
-        case 2: 
-            return "unsupported scsi opcode";
-        case 3: 
-            return "bad value in scsi command";
-        case 4: 
-            return "badly formed scsi parameters";
-        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 */
-int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status, res;
-
-    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] = LOG_SENSE;
-    cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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 */
-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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    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 pagenum, 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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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 */
-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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    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 pagenum, 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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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_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);
-    return status;
-}
-
-/* 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 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));
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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);
-    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, res;
-
-    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 = 5 * 60 * 60;   /* five hours because a foreground 
-                    extended self tests can take 1 hour plus */
-    
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, sinfo);
-    return status;
-}
-
-/* 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 (SCSI_SK_NOT_READY == sinfo.sense_key)
-        return 1;
-    else if (SCSI_SK_UNIT_ATTENTION == sinfo.sense_key) {
-        /* power on reset, media changed, ok ... try again */
-        status = _testunitready(device, &sinfo);        
-        if (SCSI_SK_NOT_READY == sinfo.sense_key)
-            return 1;
-    }
-    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 */
-static int scsiModePageOffset(const UINT8 * resp, int len, int modese_10)
-{
-    int resp_len, bd_len;
-    int offset = -1;
-
-    if (resp) {
-        if (modese_10) {
-            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: bad 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
-
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp)
-{
-    int err;
-
-    memset(iecp, 0, sizeof(*iecp));
-    iecp->requestedCurrent = 1;
-    if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                             0, iecp->raw_curr, sizeof(iecp->raw_curr)))) {
-        if (2 == err) { /* opcode no good so try 10 byte mode sense */
-            err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                             0, iecp->raw_curr, sizeof(iecp->raw_curr));
-            if (0 == err)
-                iecp->modese_10 = 1;
-            else
-                return err;
-        } else
-            return err;
-    } 
-    iecp->gotCurrent = 1;
-    iecp->requestedChangeable = 1;
-    if (iecp->modese_10) {
-        if (0 == scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                                 1, iecp->raw_chg, sizeof(iecp->raw_chg)))
-            iecp->gotChangeable = 1;
-    } else {
-        if (0 == scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                               1, iecp->raw_chg, sizeof(iecp->raw_chg)))
-            iecp->gotChangeable = 1;
-    }
-    return 0;
-}
-
-/* Return 0 if ok, -EINVAL if problems */
-int scsiDecodeIEModePage(const struct scsi_iec_mode_page *iecp,
-                UINT8 *byte_2p, UINT8 *mrie_p, unsigned int *interval_timer_p,
-                unsigned int *report_count_p)
-{
-    int offset, len;
-
-    if (iecp && iecp->gotCurrent) {
-        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                    iecp->modese_10);
-        if (offset >= 0) {
-            len = iecp->raw_curr[offset + 1] + 2;
-            if (byte_2p)
-                *byte_2p = iecp->raw_curr[offset + 2];
-            if (mrie_p)
-                *mrie_p = iecp->raw_curr[offset + 3] & 0xf;
-            if (interval_timer_p && (len > 7))
-                *interval_timer_p = (iecp->raw_curr[offset + 4] << 24) +
-                                    (iecp->raw_curr[offset + 5] << 16) +
-                                    (iecp->raw_curr[offset + 6] << 8) +
-                                    iecp->raw_curr[offset + 7];
-            else if (interval_timer_p)
-                *interval_timer_p = 0;
-            if (report_count_p && (len > 11))
-                *report_count_p = (iecp->raw_curr[offset + 8] << 24) +
-                                  (iecp->raw_curr[offset + 9] << 16) +
-                                  (iecp->raw_curr[offset + 10] << 8) +
-                                  iecp->raw_curr[offset + 11];
-            else if (report_count_p)
-                *report_count_p = 0;
-            return 0;
-        } else
-            return -EINVAL;
-    } else
-        return -EINVAL;
-}
-
-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_10);
-        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_10);
-        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, err;
-    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_10);
-    if (offset < 0)
-        return -EINVAL;
-    memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
-    rout[0] = 0;     /* Mode Data Length reserved in MODE SELECTs */
-    if (iecp->modese_10)
-        rout[1] = 0;
-    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 (iecp->modese_10)
-        err = scsiModeSelect10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                               sp, rout, sizeof(rout));
-    else
-        err = scsiModeSelect(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                             sp, rout, sizeof(rout));
-    return err;
-}
-
-int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
-{
-    UINT8 tBuf[252];
-    int err;
-
-    if ((err = scsiLogSense(device, TEMPERATURE_PAGE, tBuf, sizeof(tBuf)))) {
-        *currenttemp = 0;
-        *triptemp = 0;
-        pout("Log Sense for temperature failed [%s]\n", scsiErrString(err));
-        return 1;
-    }
-    *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
- * (Centigrade) if for temperature not available. */
-int scsiCheckIE(int device, int method, int hasTempLogPage,
-                UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp)
-{
-    UINT8 tBuf[252];
-    struct scsi_sense_disect sense_info;
-    int err;
-    int temperatureSet = 0;
-    unsigned short pagesize;
-    UINT8 currTemp, tripTemp;
- 
-    *asc = 0;
-    *ascq = 0;
-    *currenttemp = 0;
-    memset(&sense_info, 0, sizeof(sense_info));
-    if (method == CHECK_SMART_BY_LGPG_2F) {
-        if ((err = scsiLogSense(device, IE_LOG_PAGE, tBuf, sizeof(tBuf)))) {
-            pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
-            return 5;
-        }
-        pagesize = (unsigned short) (tBuf[2] << 8) | tBuf[3];
-        if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
-            pout("Log Sense failed, IE page, bad parameter code or length\n");
-            return 5;
-        }
-        if (tBuf[7] > 1) {
-            sense_info.asc = tBuf[8]; 
-            sense_info.ascq = tBuf[9];
-            if (tBuf[7] > 2) { 
-                *currenttemp = tBuf[10];
-                temperatureSet = 1;
-            }
-        } 
-    }
-    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 5;
-        }
-    }
-    *asc = sense_info.asc;
-    *ascq = sense_info.ascq;
-    if ((! temperatureSet) && hasTempLogPage) {
-        if (0 == scsiGetTemp(device, &currTemp, &tripTemp))
-            *currenttemp = currTemp;
-    }
-    return 0;
-}
-
-static const char * TapeAlertsMessageTable[]= {  
-    " ",
-   "The tape drive is having problems reading data. No data has been lost, "
-       "but there has been a reduction in the performance of the tape.",
-   "The tape drive is having problems writing data. No data has been lost, "
-       "but there has been a reduction in the performance of the tape.",
-   "The operation has stopped because an error has occurred while reading "
-       "or writing data which the drive cannot correct.",
-   "Your data is at risk:\n1. 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.",
-   "The tape is damaged or the drive is faulty. Call the tape drive "
-       "supplier helpline.",
-   "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.",
-   "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.",
-   "The tape cartridge is not data-grade. Any data you back up to the tape "
-       "is at risk. Replace the cartridge with a data-grade tape.",
-   "You are trying to write to a write-protected cartridge. Remove the "
-       "write-protection or use another tape.",
-   "You cannot eject the cartridge because the tape drive is in use. Wait "
-       "until the operation is complete before ejecting the cartridge.",
-   "The tape in the drive is a cleaning cartridge.",
-   "You have tried to load a cartridge of a type which is not supported "
-       "by this drive.",
-   "The operation has failed because the tape in the drive has snapped:\n"
-       "1. Discard the old tape.\n"
-       "2. Restart the operation with a different tape.",
-   "The operation has failed because the tape in the drive has snapped:\n"
-       "1. Do not attempt to extract the tape cartridge\n"
-       "2. Call the tape drive supplier helpline.",
-   "The memory in the tape cartridge has failed, which reduces performance. "
-       "Do not use the cartridge for further backup operations.",
-   "The operation has failed because the tape cartridge was manually "
-       "ejected while the tape drive was actively writing or reading.",
-   "You have loaded of a type that is read-only in this drive. The "
-       "cartridge will appear as write-protected.",
-   "The directory on the tape cartridge has been corrupted. File search "
-       "performance will be degraded. The tape directory can be rebuilt "
-       "by reading all the data on the cartridge.",
-   "The tape cartridge is nearing the end of its calculated life. It is "
-       "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.",
-   "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 "
-       "clean the drive. Check the tape drive users manual for device "
-       "specific cleaning instructions.",
-   "The tape drive is due for routine cleaning:\n"
-       "1. Wait for the current operation to finish.\n"
-       "2. The use a cleaning cartridge. Check the tape drive users manual "
-       "for device specific cleaning instructions.",
-   "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.",
-   "The last cleaning cartridge used in the tape drive was an invalid 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.",
-   "The tape drive has requested a retention operation",
-   "A redundant interface port on the tape drive has failed",
-   "A tape drive cooling fan has failed",
-   "A redundant power supply has failed inside the tape drive enclosure. "
-       "Check the enclosure users manual for instructions on replacing the "
-       "failed power supply.",
-   "The tape drive power consumption is outside the specified range.",
-   "Preventive maintenance of the tape drive is required. Check the tape "
-       "drive users manual for device specific preventive maintenance "
-       "tasks or call the tape drive supplier helpline.",
-   "The tape drive has a hardware fault:\n"
-       "1. Eject the tape or magazine.\n"
-       "2. Reset the drive.\n"
-       "3. Restart the operation.",
-   "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.\n"
-       " Check the tape drive users manual for device specific instructions "
-       "on turning the device power in and off.",
-   "The tape drive has a problem with the host interface:\n"
-       "1. Check the cables and cable connections.\n"
-       "2. Restart the operation.",
-   "The operation has failed:\n"
-       "1. Eject the tape or magazine.\n"
-       "2. Insert the tape or magazine again.\n"
-       "3. Restart the operation.",
-   "The firmware download has failed because you have tried to use the "
-       "incorrect firmware for this tape drive. Obtain the correct "
-       "firmware and try again.",
-   "Environmental conditions inside the tape drive are outside the "
-       "specified humidity range.",
-   "Environmental conditions inside the tape drive are outside the "
-       "specified temperature range.",
-   "The voltage supply to the tape drive is outside the specified range.",
-   "A hardware failure of the tape drive is predicted. Call the tape "
-       "drive supplier helpline.",
-   "The tape drive may have a fault. Check for availability of diagnostic "
-       "information and run extended diagnostics if applicable. Check the "
-       "tape drive users manual for instruction on running extended "
-       "diagnostic tests and retrieving diagnostic data",
-   "The changer mechanism is having difficulty communicating with the tape "
-       "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.",
-   "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 "
-       "on again.\n"
-       "3. If the problem persists, call the tape drive supplier helpline.",
-   "There is a problem with the autoloader mechanism.",
-   "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 "
-       "on again.\n"
-       "4. If the problem persists, call the tape drive supplier helpline.",
-   "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 "
-       "on turning the device power on and off.",
-   "The autoloader cannot operate without the magazine,\n"
-       "1. Insert the magazine into the autoloader.\n"
-       "2. Restart the operation.",
-   "A hardware failure of the changer mechanism is predicted. Call the "
-       "tape drive supplier helpline.",
-   " ",
-   " ",
-   " ",
-   "Media statistics have been lost at some time in the past",
-   "The tape directory on the tape cartridge just unloaded has been "
-       "corrupted. File search performance will be degraded. The tape "
-       "directory can be rebuilt by reading all the data.",
-   "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.",
-   "The tape system are could not be read successfully at load time:\n"
-       "1. Copy data to another tape cartridge.\n"
-       "2. Discard the old cartridge.",
-   "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 you supplier",
-    };
-
-const char * scsiTapeAlertsTapeDevice(unsigned short code)
-{
-    const int num = sizeof(TapeAlertsMessageTable) /
-                        sizeof(TapeAlertsMessageTable[0]);
-
-    return (code < num) ?  TapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-static const char * ChangerTapeAlertsMessageTable[]= {  
-    " ",
-    "The library mechanism is having difficulty communicating with the 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.",
-    "There is a problem with the library mechanism. If problem persists,\n"
-        "call the library supplier help line.",
-    "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.",
-    "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.",
-    "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.",
-    "The library has a problem with the host interface:\n"
-        "1. Check the cables and connections.\n"
-        "2. Restart the operation.",
-    "A hardware failure of the library is predicted. Call the library\n"
-        "supplier help line.",
-    "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.",
-    "General environmental conditions inside the library are outside the\n"
-        "specified humidity range.",
-    "General environmental conditions inside the library are outside the\n"
-        "specified temperature range.",
-    "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.",
-    "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.",
-    "There is a potential problem with the drive ejecting cartridges or with\n"
-        "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.",
-    "There is a potential problem with the library mechanism placing a cartridge\n"
-        "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.",
-    "There is a potential problem with the drive or the library mechanism\n"
-        "loading cartridges, or an incompatible cartridge.",
-    "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.",
-    "There is a mechanical problem with the library media import/export\n"
-        "mailslot.",
-    "The library cannot operate without the magazine.\n"
-        "1. Insert the magazine into the library.\n"
-        "2. Restart the operation.",
-    "Library security has been compromised.",
-    "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.",
-    "The library has been manually turned offline and is unavailable for use.",
-    "A drive inside the library has been taken offline.\n"
-        "This is for information purposes only. No action is required.",
-    "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.",
-    "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.",
-    "A library operation has been attempted that is invalid at this time.",
-    "A redundant interface port on the library has failed.",
-    "A library cooling fan has failed.",
-    "A redundant power supply has failed inside the library. Check the\n"
-        "library users manual for instructions on replacing the failed power supply.",
-    "The library power consumption is outside the specified range.",
-    "A failure has occurred in the cartridge pass-through mechanism between\n"
-        "two library modules.",
-    "A cartridge has been left in the pass-through mechanism from a previous\n"
-        "hardware fault. Check the library users guide for instructions on clearing\n"
-        "this fault.",
-    "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);
-}
-
-int scsiFetchExtendedSelfTestTime(int device, int * durationSec)
-{
-    int err, offset, res;
-    UINT8 buff[64];
-    int modese_10 = 0;
-
-    memset(buff, 0, sizeof(buff));
-    if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS, 
-                             0, buff, sizeof(buff)))) {
-        if (2 == err) { /* opcode no good so try 10 byte mode sense */
-            err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS, 
-                             0, buff, sizeof(buff));
-            if (0 == err)
-                modese_10 = 1;
-            else
-                return err;
-        } else
-            return err;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_10);
-    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;
-    unsigned long long * 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 > 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;
-    }
-}
diff --git a/sm5/scsicmds.cpp b/sm5/scsicmds.cpp
deleted file mode 100644
index 1583d83ad..000000000
--- a/sm5/scsicmds.cpp
+++ /dev/null
@@ -1,1631 +0,0 @@
-/*
- * scsicmds.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003 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 <getopt.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include "scsicmds.h"
-#include "utility.h"
-#include "extern.h"
-
-const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.42 2003/04/29 16:01:09 makisara Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID;
-
-/* for passing global control variables */
-extern smartmonctrl *con;
-
-/* output binary in hex and optionally ascii */
-static 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;
-}
-
-/* SCSI command transmission interface function, implementation is OS
- * specific. */
-static int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop);
-
-/* <<<<<<<<<<<<<<<< Start of Linux specific code >>>>>>>>>>>>>>>>> */
-#if 1   
-/* Linux specific code, FreeBSD could conditionally compile in CAM stuff 
- * instead of this. */
-
-/* #include <scsi/scsi.h>       bypass for now */
-/* #include <scsi/scsi_ioctl.h> bypass for now */
-
-#define MAX_DXFER_LEN 1024      /* can be increased if necessary */
-#define SEND_IOCTL_RESP_SENSE_LEN 16    /* ioctl limitation */
-#define DRIVER_SENSE  0x8       /* alternate CHECK CONDITION indication */
-
-#ifndef SCSI_IOCTL_SEND_COMMAND
-#define SCSI_IOCTL_SEND_COMMAND 1
-#endif
-#ifndef SCSI_IOCTL_TEST_UNIT_READY
-#define SCSI_IOCTL_TEST_UNIT_READY 2
-#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 pending in Linux 2.4 and 2.5 to extend SEND DIAGNOSTIC timeout
- * to 2 hours in order to allow long foreground extended self tests. */
-static int linux_do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop)
-{
-    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 (con->reportscsiioctl > 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 < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((con->reportscsiioctl > 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", iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-    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 (con->reportscsiioctl)
-            pout("  status=-1, errno=%d [%s]\n", errno, strerror(errno));
-        return -errno;
-    }
-    if (0 == status) {
-        if (con->reportscsiioctl > 0)
-            pout("  status=0\n");
-        if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-            memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
-            if (con->reportscsiioctl > 1) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex(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 (DRIVER_SENSE == ((status >> 24) & 0xff))
-        iop->scsi_status = 2;
-    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 (con->reportscsiioctl > 1) {
-            pout("  >>> Sense buffer, len=%d:\n", len);
-            dStrHex(wrk.buff, len , 1);
-        }
-    }
-    if (con->reportscsiioctl) {
-        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 (con->reportscsiioctl > 0)
-            pout("  ioctl status=0x%x but scsi status=0, fail with ENODEV\n", 
-                 status);
-        return -ENODEV;      /* give up, assume no device there */
-    }
-}
-
-static int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop)
-{
-    return linux_do_scsi_cmnd_io(dev_fd, iop);
-}
-#endif
-/* <<<<<<<<<<<<<<<< End of Linux specific code >>>>>>>>>>>>>>>>> */
-
-void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
-                          struct scsi_sense_disect * out)
-{
-    memset(out, 0, sizeof(out));
-    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)
-        return 1;
-    else if (SCSI_SK_ILLEGAL_REQUEST == sinfo->sense_key) {
-        if (SCSI_ASC_UNKNOWN_OPCODE == sinfo->asc)
-            return 2;
-        else if (SCSI_ASC_UNKNOWN_FIELD == sinfo->asc)
-            return 3;
-        else if (SCSI_ASC_UNKNOWN_PARAM == sinfo->asc)
-            return 4;
-    }
-    return 0;
-}
-
-const char * scsiErrString(int scsiErr)
-{
-    if (scsiErr < 0)
-        return strerror(-scsiErr);
-    switch (scsiErr) {
-        case 0: 
-            return "no error";
-        case 1: 
-            return "device not ready";
-        case 2: 
-            return "unsupported scsi opcode";
-        case 3: 
-            return "bad value in scsi command";
-        case 4: 
-            return "badly formed scsi parameters";
-        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 */
-int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status, res;
-
-    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] = LOG_SENSE;
-    cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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 */
-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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    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 pagenum, 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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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 */
-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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    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 pagenum, 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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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_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);
-    return status;
-}
-
-/* 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 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));
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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);
-    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, res;
-
-    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 = 5 * 60 * 60;   /* five hours because a foreground 
-                    extended self tests can take 1 hour plus */
-    
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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, res;
-
-    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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    if (status > 0)
-        status = -EIO;
-    return status;
-}
-
-/* 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);
-
-    status = do_scsi_cmnd_io(device, &io_hdr);
-    scsi_do_sense_disect(&io_hdr, sinfo);
-    return status;
-}
-
-/* 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 (SCSI_SK_NOT_READY == sinfo.sense_key)
-        return 1;
-    else if (SCSI_SK_UNIT_ATTENTION == sinfo.sense_key) {
-        /* power on reset, media changed, ok ... try again */
-        status = _testunitready(device, &sinfo);        
-        if (SCSI_SK_NOT_READY == sinfo.sense_key)
-            return 1;
-    }
-    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 */
-static int scsiModePageOffset(const UINT8 * resp, int len, int modese_10)
-{
-    int resp_len, bd_len;
-    int offset = -1;
-
-    if (resp) {
-        if (modese_10) {
-            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: bad 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
-
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp)
-{
-    int err;
-
-    memset(iecp, 0, sizeof(*iecp));
-    iecp->requestedCurrent = 1;
-    if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                             0, iecp->raw_curr, sizeof(iecp->raw_curr)))) {
-        if (2 == err) { /* opcode no good so try 10 byte mode sense */
-            err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                             0, iecp->raw_curr, sizeof(iecp->raw_curr));
-            if (0 == err)
-                iecp->modese_10 = 1;
-            else
-                return err;
-        } else
-            return err;
-    } 
-    iecp->gotCurrent = 1;
-    iecp->requestedChangeable = 1;
-    if (iecp->modese_10) {
-        if (0 == scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                                 1, iecp->raw_chg, sizeof(iecp->raw_chg)))
-            iecp->gotChangeable = 1;
-    } else {
-        if (0 == scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                               1, iecp->raw_chg, sizeof(iecp->raw_chg)))
-            iecp->gotChangeable = 1;
-    }
-    return 0;
-}
-
-/* Return 0 if ok, -EINVAL if problems */
-int scsiDecodeIEModePage(const struct scsi_iec_mode_page *iecp,
-                UINT8 *byte_2p, UINT8 *mrie_p, unsigned int *interval_timer_p,
-                unsigned int *report_count_p)
-{
-    int offset, len;
-
-    if (iecp && iecp->gotCurrent) {
-        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
-                                    iecp->modese_10);
-        if (offset >= 0) {
-            len = iecp->raw_curr[offset + 1] + 2;
-            if (byte_2p)
-                *byte_2p = iecp->raw_curr[offset + 2];
-            if (mrie_p)
-                *mrie_p = iecp->raw_curr[offset + 3] & 0xf;
-            if (interval_timer_p && (len > 7))
-                *interval_timer_p = (iecp->raw_curr[offset + 4] << 24) +
-                                    (iecp->raw_curr[offset + 5] << 16) +
-                                    (iecp->raw_curr[offset + 6] << 8) +
-                                    iecp->raw_curr[offset + 7];
-            else if (interval_timer_p)
-                *interval_timer_p = 0;
-            if (report_count_p && (len > 11))
-                *report_count_p = (iecp->raw_curr[offset + 8] << 24) +
-                                  (iecp->raw_curr[offset + 9] << 16) +
-                                  (iecp->raw_curr[offset + 10] << 8) +
-                                  iecp->raw_curr[offset + 11];
-            else if (report_count_p)
-                *report_count_p = 0;
-            return 0;
-        } else
-            return -EINVAL;
-    } else
-        return -EINVAL;
-}
-
-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_10);
-        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_10);
-        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, err;
-    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_10);
-    if (offset < 0)
-        return -EINVAL;
-    memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
-    rout[0] = 0;     /* Mode Data Length reserved in MODE SELECTs */
-    if (iecp->modese_10)
-        rout[1] = 0;
-    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 (iecp->modese_10)
-        err = scsiModeSelect10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                               sp, rout, sizeof(rout));
-    else
-        err = scsiModeSelect(device, INFORMATIONAL_EXCEPTIONS_CONTROL, 
-                             sp, rout, sizeof(rout));
-    return err;
-}
-
-int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
-{
-    UINT8 tBuf[252];
-    int err;
-
-    if ((err = scsiLogSense(device, TEMPERATURE_PAGE, tBuf, sizeof(tBuf)))) {
-        *currenttemp = 0;
-        *triptemp = 0;
-        pout("Log Sense for temperature failed [%s]\n", scsiErrString(err));
-        return 1;
-    }
-    *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
- * (Centigrade) if for temperature not available. */
-int scsiCheckIE(int device, int method, int hasTempLogPage,
-                UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp)
-{
-    UINT8 tBuf[252];
-    struct scsi_sense_disect sense_info;
-    int err;
-    int temperatureSet = 0;
-    unsigned short pagesize;
-    UINT8 currTemp, tripTemp;
- 
-    *asc = 0;
-    *ascq = 0;
-    *currenttemp = 0;
-    memset(&sense_info, 0, sizeof(sense_info));
-    if (method == CHECK_SMART_BY_LGPG_2F) {
-        if ((err = scsiLogSense(device, IE_LOG_PAGE, tBuf, sizeof(tBuf)))) {
-            pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
-            return 5;
-        }
-        pagesize = (unsigned short) (tBuf[2] << 8) | tBuf[3];
-        if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
-            pout("Log Sense failed, IE page, bad parameter code or length\n");
-            return 5;
-        }
-        if (tBuf[7] > 1) {
-            sense_info.asc = tBuf[8]; 
-            sense_info.ascq = tBuf[9];
-            if (tBuf[7] > 2) { 
-                *currenttemp = tBuf[10];
-                temperatureSet = 1;
-            }
-        } 
-    }
-    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 5;
-        }
-    }
-    *asc = sense_info.asc;
-    *ascq = sense_info.ascq;
-    if ((! temperatureSet) && hasTempLogPage) {
-        if (0 == scsiGetTemp(device, &currTemp, &tripTemp))
-            *currenttemp = currTemp;
-    }
-    return 0;
-}
-
-static const char * TapeAlertsMessageTable[]= {  
-    " ",
-   "The tape drive is having problems reading data. No data has been lost, "
-       "but there has been a reduction in the performance of the tape.",
-   "The tape drive is having problems writing data. No data has been lost, "
-       "but there has been a reduction in the performance of the tape.",
-   "The operation has stopped because an error has occurred while reading "
-       "or writing data which the drive cannot correct.",
-   "Your data is at risk:\n1. 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.",
-   "The tape is damaged or the drive is faulty. Call the tape drive "
-       "supplier helpline.",
-   "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.",
-   "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.",
-   "The tape cartridge is not data-grade. Any data you back up to the tape "
-       "is at risk. Replace the cartridge with a data-grade tape.",
-   "You are trying to write to a write-protected cartridge. Remove the "
-       "write-protection or use another tape.",
-   "You cannot eject the cartridge because the tape drive is in use. Wait "
-       "until the operation is complete before ejecting the cartridge.",
-   "The tape in the drive is a cleaning cartridge.",
-   "You have tried to load a cartridge of a type which is not supported "
-       "by this drive.",
-   "The operation has failed because the tape in the drive has snapped:\n"
-       "1. Discard the old tape.\n"
-       "2. Restart the operation with a different tape.",
-   "The operation has failed because the tape in the drive has snapped:\n"
-       "1. Do not attempt to extract the tape cartridge\n"
-       "2. Call the tape drive supplier helpline.",
-   "The memory in the tape cartridge has failed, which reduces performance. "
-       "Do not use the cartridge for further backup operations.",
-   "The operation has failed because the tape cartridge was manually "
-       "ejected while the tape drive was actively writing or reading.",
-   "You have loaded of a type that is read-only in this drive. The "
-       "cartridge will appear as write-protected.",
-   "The directory on the tape cartridge has been corrupted. File search "
-       "performance will be degraded. The tape directory can be rebuilt "
-       "by reading all the data on the cartridge.",
-   "The tape cartridge is nearing the end of its calculated life. It is "
-       "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.",
-   "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 "
-       "clean the drive. Check the tape drive users manual for device "
-       "specific cleaning instructions.",
-   "The tape drive is due for routine cleaning:\n"
-       "1. Wait for the current operation to finish.\n"
-       "2. The use a cleaning cartridge. Check the tape drive users manual "
-       "for device specific cleaning instructions.",
-   "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.",
-   "The last cleaning cartridge used in the tape drive was an invalid 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.",
-   "The tape drive has requested a retention operation",
-   "A redundant interface port on the tape drive has failed",
-   "A tape drive cooling fan has failed",
-   "A redundant power supply has failed inside the tape drive enclosure. "
-       "Check the enclosure users manual for instructions on replacing the "
-       "failed power supply.",
-   "The tape drive power consumption is outside the specified range.",
-   "Preventive maintenance of the tape drive is required. Check the tape "
-       "drive users manual for device specific preventive maintenance "
-       "tasks or call the tape drive supplier helpline.",
-   "The tape drive has a hardware fault:\n"
-       "1. Eject the tape or magazine.\n"
-       "2. Reset the drive.\n"
-       "3. Restart the operation.",
-   "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.\n"
-       " Check the tape drive users manual for device specific instructions "
-       "on turning the device power in and off.",
-   "The tape drive has a problem with the host interface:\n"
-       "1. Check the cables and cable connections.\n"
-       "2. Restart the operation.",
-   "The operation has failed:\n"
-       "1. Eject the tape or magazine.\n"
-       "2. Insert the tape or magazine again.\n"
-       "3. Restart the operation.",
-   "The firmware download has failed because you have tried to use the "
-       "incorrect firmware for this tape drive. Obtain the correct "
-       "firmware and try again.",
-   "Environmental conditions inside the tape drive are outside the "
-       "specified humidity range.",
-   "Environmental conditions inside the tape drive are outside the "
-       "specified temperature range.",
-   "The voltage supply to the tape drive is outside the specified range.",
-   "A hardware failure of the tape drive is predicted. Call the tape "
-       "drive supplier helpline.",
-   "The tape drive may have a fault. Check for availability of diagnostic "
-       "information and run extended diagnostics if applicable. Check the "
-       "tape drive users manual for instruction on running extended "
-       "diagnostic tests and retrieving diagnostic data",
-   "The changer mechanism is having difficulty communicating with the tape "
-       "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.",
-   "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 "
-       "on again.\n"
-       "3. If the problem persists, call the tape drive supplier helpline.",
-   "There is a problem with the autoloader mechanism.",
-   "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 "
-       "on again.\n"
-       "4. If the problem persists, call the tape drive supplier helpline.",
-   "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 "
-       "on turning the device power on and off.",
-   "The autoloader cannot operate without the magazine,\n"
-       "1. Insert the magazine into the autoloader.\n"
-       "2. Restart the operation.",
-   "A hardware failure of the changer mechanism is predicted. Call the "
-       "tape drive supplier helpline.",
-   " ",
-   " ",
-   " ",
-   "Media statistics have been lost at some time in the past",
-   "The tape directory on the tape cartridge just unloaded has been "
-       "corrupted. File search performance will be degraded. The tape "
-       "directory can be rebuilt by reading all the data.",
-   "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.",
-   "The tape system are could not be read successfully at load time:\n"
-       "1. Copy data to another tape cartridge.\n"
-       "2. Discard the old cartridge.",
-   "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 you supplier",
-    };
-
-const char * scsiTapeAlertsTapeDevice(unsigned short code)
-{
-    const int num = sizeof(TapeAlertsMessageTable) /
-                        sizeof(TapeAlertsMessageTable[0]);
-
-    return (code < num) ?  TapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-static const char * ChangerTapeAlertsMessageTable[]= {  
-    " ",
-    "The library mechanism is having difficulty communicating with the 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.",
-    "There is a problem with the library mechanism. If problem persists,\n"
-        "call the library supplier help line.",
-    "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.",
-    "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.",
-    "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.",
-    "The library has a problem with the host interface:\n"
-        "1. Check the cables and connections.\n"
-        "2. Restart the operation.",
-    "A hardware failure of the library is predicted. Call the library\n"
-        "supplier help line.",
-    "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.",
-    "General environmental conditions inside the library are outside the\n"
-        "specified humidity range.",
-    "General environmental conditions inside the library are outside the\n"
-        "specified temperature range.",
-    "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.",
-    "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.",
-    "There is a potential problem with the drive ejecting cartridges or with\n"
-        "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.",
-    "There is a potential problem with the library mechanism placing a cartridge\n"
-        "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.",
-    "There is a potential problem with the drive or the library mechanism\n"
-        "loading cartridges, or an incompatible cartridge.",
-    "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.",
-    "There is a mechanical problem with the library media import/export\n"
-        "mailslot.",
-    "The library cannot operate without the magazine.\n"
-        "1. Insert the magazine into the library.\n"
-        "2. Restart the operation.",
-    "Library security has been compromised.",
-    "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.",
-    "The library has been manually turned offline and is unavailable for use.",
-    "A drive inside the library has been taken offline.\n"
-        "This is for information purposes only. No action is required.",
-    "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.",
-    "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.",
-    "A library operation has been attempted that is invalid at this time.",
-    "A redundant interface port on the library has failed.",
-    "A library cooling fan has failed.",
-    "A redundant power supply has failed inside the library. Check the\n"
-        "library users manual for instructions on replacing the failed power supply.",
-    "The library power consumption is outside the specified range.",
-    "A failure has occurred in the cartridge pass-through mechanism between\n"
-        "two library modules.",
-    "A cartridge has been left in the pass-through mechanism from a previous\n"
-        "hardware fault. Check the library users guide for instructions on clearing\n"
-        "this fault.",
-    "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);
-}
-
-int scsiFetchExtendedSelfTestTime(int device, int * durationSec)
-{
-    int err, offset, res;
-    UINT8 buff[64];
-    int modese_10 = 0;
-
-    memset(buff, 0, sizeof(buff));
-    if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS, 
-                             0, buff, sizeof(buff)))) {
-        if (2 == err) { /* opcode no good so try 10 byte mode sense */
-            err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS, 
-                             0, buff, sizeof(buff));
-            if (0 == err)
-                modese_10 = 1;
-            else
-                return err;
-        } else
-            return err;
-    } 
-    offset = scsiModePageOffset(buff, sizeof(buff), modese_10);
-    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;
-    unsigned long long * 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 > 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;
-    }
-}
diff --git a/sm5/scsicmds.h b/sm5/scsicmds.h
deleted file mode 100644
index d8420a850..000000000
--- a/sm5/scsicmds.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * scsicmds.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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/
- *
- * 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_
-
-#ifndef SCSICMDS_H_CVSID
-#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.27 2003/04/29 16:01:11 makisara Exp $\n"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.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;
-    size_t  cmnd_len;
-    int dxfer_dir;     /* DXFER_NONE, DXFER_FROM_DEVICE, or DXFER_TO_DEVICE */
-    UINT8 * dxferp;
-    size_t dxfer_len;
-    UINT8 * sensep;     /* ptr to sense buffer when CHECK CONDITION status */
-    size_t max_sense_len;
-    unsigned timeout;   /* in seconds, 0-> default timeout (60 seconds?) */
-    size_t resp_sense_len;  /* output: sense buffer length */
-    UINT8 scsi_status;  /* output: 0->ok, 2->CHECK CONDITION, etc ... */
-    int resid;          /* 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_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;
-    unsigned long long counter[8];
-};
-
-/* Carrier for Non-medium error log page */
-struct scsiNonMediumError {
-    UINT8 gotPC0;
-    UINT8 gotExtraPC;
-    unsigned long long 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_LOG_PAGES                     0x00
-#define BUFFER_OVERRUN_PAGE                     0x01
-#define WRITE_ERROR_COUNTER_PAGE                0x02
-#define READ_ERROR_COUNTER_PAGE                 0x03
-#define READ_REVERSE_ERROR_COUNTER_PAGE         0x04
-#define VERIFY_ERROR_COUNTER_PAGE               0x05
-#define NON_MEDIUM_ERROR_PAGE                   0x06
-#define LAST_N_ERROR_PAGE                       0x07
-#define FORMAT_STATUS_PAGE                      0x08
-#define TEMPERATURE_PAGE                        0x0d
-#define STARTSTOP_CYCLE_COUNTER_PAGE            0x0e
-#define APPLICATION_CLIENT_PAGE                 0x0f
-#define SELFTEST_RESULTS_PAGE                   0x10
-#define IE_LOG_PAGE                             0x2f
-
-/* 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_PAGE                         0x2e
-
-/* ANSI SCSI-3 Mode Pages */
-#define VENDOR_UNIQUE_PARAMETERS                 0x00
-#define READ_WRITE_ERROR_RECOVERY_PARAMETERS     0x01
-#define DISCONNECT_RECONNECT_PARAMETERS          0x02
-#define FORMAT_DEVICE_PARAMETERS                 0x03
-#define RIGID_DISK_DRIVE_GEOMETRY_PARAMETERS     0x04
-#define FLEXIBLE_DISK_PARAMETERS                 0x05
-#define VERIFY_ERROR_RECOVERY_PARAMETERS         0x07
-#define CACHING_PARAMETERS                       0x08
-#define PERIPHERAL_DEVICE                        0x09
-#define XOR_CONTROL_MODE_PARAMETERS              0x10
-#define CONTROL_MODE_PAGE_PARAMETERS             0x0a
-#define MEDIUM_TYPES_SUPPORTED                   0x0b
-#define NOTCH_PARAMETERS                         0x0c
-#define POWER_CONDITION_PARAMETERS               0x0d
-#define CD_DEVICE_PARAMETERS                     0x0d
-#define CD_AUDIO_CONTROL_PAGE                    0x0e
-#define DATA_COMPRESSION_PARAMETERS              0x0f
-#define MEDIUM_PARTITION_MODE_PARAMTERES_1       0x11
-#define MEDIUM_PARTITION_MODE_PARAMTERES_2       0x12
-#define MEDIUM_PARTITION_MODE_PARAMTERES_3       0x13
-#define MEDIUM_PARTITION_MODE_PARAMTERES_4       0x14
-#define ENCLOSURE_SERVICES_MANAGEMENT            0x14
-#define LUN_CONTROL                              0x18
-#define PORT_CONTROL                             0x19
-#define POWER_CONTROL                            0x1a
-#define LUN_MAPPING_PAGE                         0x1b
-#define INFORMATIONAL_EXCEPTIONS_CONTROL         0x1c
-#define FAULT_FAILURE_REPORTING_PAGE             0x1c
-#define ELEMENT_ADDRESS_ASSIGNMENT               0x1d
-#define TIMEOUT_AND_PROTECT_PARAMETERS           0x1d
-#define TRANSPORT_GEOMETRY_PARAMETERS            0x1e
-#define DEVICE_CAPABILITIES                      0x1f
-#define CD_CAPABILITIES_AND_MECHANISM_STATUS     0x2a
-
-#define ALL_PARAMETERS                           0x3f
-
-/* 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_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
-
-
-/* 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
-
-
-
-#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 scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen);
-
-int scsiModeSelect(int device, int pagenum, int sp, UINT8 *pBuf, int bufLen);
-
-int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen);
-
-int scsiModeSelect10(int device, int pagenum, int sp, UINT8 *pBuf, int bufLen);
-
-int scsiRequestSense(int device, struct scsi_sense_disect * sense_info);
-
-int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen);
-
-int scsiReceiveSiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf,
-                      int bufLen);
-/* SMART specific commands */
-
-#define CHECK_SMART_BY_LGPG_2F  0x01
-#define CHECK_SMART_BY_REQSENSE 0x00
-
-int scsiCheckIE(int device, int method, int hasTempLogPage,
-                UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp);
-
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp);
-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);
-int scsiDecodeIEModePage(const struct scsi_iec_mode_page *iecp,
-        UINT8 *byte_2p, UINT8 *mrie_p, unsigned int *interval_timer_p,
-        unsigned int *report_count_p);
-void scsiDecodeErrCounterPage(unsigned char * resp,
-                              struct scsiErrorCounter *ecp);
-void scsiDecodeNonMediumErrPage(unsigned char * resp,
-                                struct scsiNonMediumError *nmep);
-int scsiFetchExtendedSelfTestTime(int device, int * durationSec);
-
-/* 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);
-#endif
-
diff --git a/sm5/scsiprint.c b/sm5/scsiprint.c
deleted file mode 100644
index b14659357..000000000
--- a/sm5/scsiprint.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * scsiprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003 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 <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.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.42 2003/05/01 08:50:17 dpgilbert Exp $"
-EXTERN_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;
-
-UINT8 gBuf[GBUF_SIZE];
-#define LOG_RESP_LEN 252
-
-/* Log pages supported */
-static int gSmartPage = 0;
-static int gTempPage = 0;
-static int gSelfTestPage = 0;
-static int gStartStopPage = 0;
-static int gTapeAlertsPage = 0;
-
-
-static void scsiGetSupportedLogPages(int device)
-{
-    int i, err;
-
-    if ((err = scsiLogSense(device, SUPPORTED_LOG_PAGES, gBuf, 
-                            LOG_RESP_LEN))) {
-        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_PAGE:
-                gTempPage = 1;
-                break;
-            case STARTSTOP_CYCLE_COUNTER_PAGE:
-                gStartStopPage = 1;
-                break;
-            case SELFTEST_RESULTS_PAGE:
-                gSelfTestPage = 1;
-                break;
-            case IE_LOG_PAGE:
-                gSmartPage = 1;
-                break;
-            case TAPE_ALERTS_PAGE:
-                gTapeAlertsPage = 1;
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-void scsiGetSmartData(int device)
-{
-    UINT8 asc;
-    UINT8 ascq;
-    UINT8 currenttemp = 0;
-    const char * cp;
-    int err;
-
-    QUIETON(con);
-    if ((err = scsiCheckIE(device, gSmartPage, gTempPage,
-                           &asc, &ascq, &currenttemp))) {
-        /* error message already announced */
-        QUIETOFF(con);
-        return;
-    }
-    QUIETOFF(con);
-    cp = scsiGetIEString(asc, ascq);
-    if (cp) {
-        QUIETON(con);
-        pout("SMART Sense: %s [asc=%x,ascq=%x]\n", cp, asc, ascq); 
-        QUIETOFF(con);
-    } else
-        pout("SMART Sense: Ok!\n");
-
-    if (currenttemp && !gTempPage) {
-        if (255 != currenttemp)
-            pout("Current Drive Temperature:     %d C\n", currenttemp);
-        else
-            pout("Current Drive Temperature:     <not available>\n");
-    }
-}
-
-
-// Returns number of logged errors or zero if none or -1 if fetching
-// TapeAlerts fails
-static int scsiGetTapeAlertsData(int device, int peripheral_type)
-{
-    unsigned short pagelength;
-    unsigned short parametercode;
-    int i, err;
-    int failures = 0;
-
-    QUIETON(con);
-    if ((err = scsiLogSense(device, TAPE_ALERTS_PAGE, gBuf, LOG_RESP_LEN))) {
-        pout("scsiGetTapesAlertData Failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return -1;
-    }
-    if (gBuf[0] != 0x2e) {
-        pout("TapeAlerts Log Sense Failed\n");
-        QUIETOFF(con);
-        return -1;
-    }
-    pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3];
-
-    for (i = 4; i < pagelength; i += 5) {
-        parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1];
-
-        if (gBuf[i + 4]) {
-	    if (!failures)
-		pout("TapeAlert Errors:\n");
-            pout("[0x%02x] %s\n", parametercode,
-		   SCSI_PT_MEDIUM_CHANGER == peripheral_type ?
-		   scsiTapeAlertsChangerDevice(parametercode) :
-                   scsiTapeAlertsTapeDevice(parametercode));
-            failures += 1; 
-        }          
-    }
-    QUIETOFF(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_PAGE, gBuf,
-                            LOG_RESP_LEN))) {
-        QUIETON(con);
-        pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return;
-    }
-    if (gBuf[0] != STARTSTOP_CYCLE_COUNTER_PAGE) {
-        QUIETON(con);
-        pout("StartStop Log Sense Failed, page mismatch\n");
-        QUIETOFF(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 start stop count:  %u times\n", 
-             recommendedStartStop);
-    }
-} 
-
-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_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[0]);
-        found[0] = 1;
-    }
-    if (0 == scsiLogSense(device, WRITE_ERROR_COUNTER_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[1]);
-        found[1] = 1;
-    }
-    if (0 == scsiLogSense(device, VERIFY_ERROR_COUNTER_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        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%8llu %8llu  %8llu  %8llu   %8llu", 
-                 pageNames[k], ecp->counter[0], ecp->counter[1], 
-                 ecp->counter[2], ecp->counter[3], ecp->counter[4]);
-            processed_gb = ecp->counter[5] / 1000000000.0;
-            pout("   %12.3f    %8llu\n", processed_gb, ecp->counter[6]);
-        }
-    }
-    else 
-        pout("\nNo Error counter log to report\n");
-    if (0 == scsiLogSense(device, NON_MEDIUM_ERROR_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        scsiDecodeNonMediumErrPage(gBuf, &nme);
-        if (nme.gotPC0)
-            pout("\nNon-medium error count: %8llu\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;
-    unsigned long long ull=0;
-
-    if ((err = scsiLogSense(device, SELFTEST_RESULTS_PAGE, gBuf, 
-                            LOG_RESP_LEN))) {
-        QUIETON(con);
-        pout("scsiPrintSelfTest Failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    if (gBuf[0] != SELFTEST_RESULTS_PAGE) {
-        QUIETON(con);
-        pout("Self-test Log Sense Failed, page mismatch\n");
-        QUIETOFF(con);
-        return 1;
-    }
-    // compute page length
-    num = (gBuf[2] << 8) + gBuf[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        QUIETON(con);
-        pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n",num);
-        QUIETOFF(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 ((0xffffffffffffffffULL != ull) && (res > 0) && ( res < 0xf))
-            pout("  0x%16llx", 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)) &&
-        (durationSec > 0))
-        pout("Long (extended) Self Test duration: %d seconds "
-             "[%.1f minutes]\n", durationSec, durationSec / 60.0);
-    return 0;
-}
- 
-/* 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[64];
-    struct scsi_iec_mode_page iec;
-    int err, len;
-    int is_tape = 0;
-        
-    memset(gBuf, 0, 36);
-    if ((err = scsiStdInquiry(device, gBuf, 36))) {
-        QUIETON(con);
-        pout("Standard Inquiry failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    len = gBuf[4] + 5;
-    if (peripheral_type)
-        *peripheral_type = gBuf[0] & 0x1f;
-    if (!all)
-	return 0;
-
-    if (len >= 36) {
-        memset(manufacturer, 0, sizeof(manufacturer));
-        strncpy(manufacturer, &gBuf[8], 8);
-     
-        memset(product, 0, sizeof(product));
-        strncpy(product, &gBuf[16], 16);
-            
-        memset(revision, 0, sizeof(revision));
-        strncpy(revision, &gBuf[32], 4);
-        pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
-        if (0 == 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 {
-        QUIETON(con);
-        pout("Short INQUIRY response, skip product id\n");
-        QUIETOFF(con);
-    }
-
-    // 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 (1 == err) {
-            QUIETON(con);
-            pout("device is NOT READY (media absent, spun down, etc)\n");
-            QUIETOFF(con);
-        } else {
-            QUIETON(con);
-            pout("device Test Unit Ready  [%s]\n", scsiErrString(err));
-            QUIETOFF(con);
-        }
-	return 0;
-    }
-   
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-	if (!is_tape) {
-            QUIETON(con);
-	    pout("Device does not support SMART [%s]\n", 
-		 scsiErrString(err));
-            QUIETOFF(con);
-        }
-        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))) {
-        QUIETON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    if ((err = scsiSetExceptionControlAndWarning(device, 1, &iec))) {
-        QUIETON(con);
-        pout("unable to enable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    }
-    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))) {
-        QUIETON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    if ((err = scsiSetExceptionControlAndWarning(device, 0, &iec))) {
-        QUIETON(con);
-        pout("unable to disable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    }
-    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);
-}
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-static 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 has failed: exiting.\n"
-                 "To continue, set the tolerance level to something other "
-                 "than 'conservative'\n");
-            exit(returnvalue);
-        }
-    }
-    return;
-}
-
-
-/* Main entry point used by smartctl command. Return 0 for success */
-int scsiPrintMain(const char *dev_name, int fd)
-{
-    int checkedSupportedLogPages = 0;
-    UINT8 peripheral_type = 0;
-    int returnval=0;
-    int res;
-
-    if (scsiGetDriveInfo(fd, &peripheral_type, con->driveinfo)) {
-        pout("Smartctl: SCSI device INQUIRY Failed\n\n");
-        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->checksmart) {
-        scsiGetSupportedLogPages(fd);
-        checkedSupportedLogPages = 1;
-        if ((SCSI_PT_SEQUENTIAL_ACCESS == peripheral_type) ||
-            (SCSI_PT_MEDIUM_CHANGER == peripheral_type)) { /* tape device */
-            if (gTapeAlertsPage) {
-		if (con->driveinfo)
-		    pout("TapeAlert Supported\n");
-                if (-1 == scsiGetTapeAlertsData(fd, peripheral_type))
-                    failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
-	    }
-	    else
-		pout("TapeAlert Not Supported\n");
-            if (gTempPage)
-                scsiPrintTemp(fd);         
-            if (gStartStopPage)
-                scsiGetStartStopData(fd);
-        } else { /* disk, cd/dvd, enclosure, etc */
-            scsiGetSmartData(fd);
-            if (gTempPage)
-                scsiPrintTemp(fd);         
-            if (gStartStopPage)
-                scsiGetStartStopData(fd);
-        }
-    }   
-    if (con->smarterrorlog)
-        scsiPrintErrorCounterLog(fd);
-    if (con->smartselftestlog) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        res = 0;
-        if (gSelfTestPage)
-            res = scsiPrintSelfTest(fd);
-        else {
-            pout("Warning: 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");
-        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 181434ca7..000000000
--- a/sm5/scsiprint.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * scsiprint.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- *
- * Additional SCSI work:
- * Copyright (C) 2003 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 <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.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.42 2003/05/01 08:50:17 dpgilbert Exp $"
-EXTERN_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;
-
-UINT8 gBuf[GBUF_SIZE];
-#define LOG_RESP_LEN 252
-
-/* Log pages supported */
-static int gSmartPage = 0;
-static int gTempPage = 0;
-static int gSelfTestPage = 0;
-static int gStartStopPage = 0;
-static int gTapeAlertsPage = 0;
-
-
-static void scsiGetSupportedLogPages(int device)
-{
-    int i, err;
-
-    if ((err = scsiLogSense(device, SUPPORTED_LOG_PAGES, gBuf, 
-                            LOG_RESP_LEN))) {
-        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_PAGE:
-                gTempPage = 1;
-                break;
-            case STARTSTOP_CYCLE_COUNTER_PAGE:
-                gStartStopPage = 1;
-                break;
-            case SELFTEST_RESULTS_PAGE:
-                gSelfTestPage = 1;
-                break;
-            case IE_LOG_PAGE:
-                gSmartPage = 1;
-                break;
-            case TAPE_ALERTS_PAGE:
-                gTapeAlertsPage = 1;
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-void scsiGetSmartData(int device)
-{
-    UINT8 asc;
-    UINT8 ascq;
-    UINT8 currenttemp = 0;
-    const char * cp;
-    int err;
-
-    QUIETON(con);
-    if ((err = scsiCheckIE(device, gSmartPage, gTempPage,
-                           &asc, &ascq, &currenttemp))) {
-        /* error message already announced */
-        QUIETOFF(con);
-        return;
-    }
-    QUIETOFF(con);
-    cp = scsiGetIEString(asc, ascq);
-    if (cp) {
-        QUIETON(con);
-        pout("SMART Sense: %s [asc=%x,ascq=%x]\n", cp, asc, ascq); 
-        QUIETOFF(con);
-    } else
-        pout("SMART Sense: Ok!\n");
-
-    if (currenttemp && !gTempPage) {
-        if (255 != currenttemp)
-            pout("Current Drive Temperature:     %d C\n", currenttemp);
-        else
-            pout("Current Drive Temperature:     <not available>\n");
-    }
-}
-
-
-// Returns number of logged errors or zero if none or -1 if fetching
-// TapeAlerts fails
-static int scsiGetTapeAlertsData(int device, int peripheral_type)
-{
-    unsigned short pagelength;
-    unsigned short parametercode;
-    int i, err;
-    int failures = 0;
-
-    QUIETON(con);
-    if ((err = scsiLogSense(device, TAPE_ALERTS_PAGE, gBuf, LOG_RESP_LEN))) {
-        pout("scsiGetTapesAlertData Failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return -1;
-    }
-    if (gBuf[0] != 0x2e) {
-        pout("TapeAlerts Log Sense Failed\n");
-        QUIETOFF(con);
-        return -1;
-    }
-    pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3];
-
-    for (i = 4; i < pagelength; i += 5) {
-        parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1];
-
-        if (gBuf[i + 4]) {
-	    if (!failures)
-		pout("TapeAlert Errors:\n");
-            pout("[0x%02x] %s\n", parametercode,
-		   SCSI_PT_MEDIUM_CHANGER == peripheral_type ?
-		   scsiTapeAlertsChangerDevice(parametercode) :
-                   scsiTapeAlertsTapeDevice(parametercode));
-            failures += 1; 
-        }          
-    }
-    QUIETOFF(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_PAGE, gBuf,
-                            LOG_RESP_LEN))) {
-        QUIETON(con);
-        pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return;
-    }
-    if (gBuf[0] != STARTSTOP_CYCLE_COUNTER_PAGE) {
-        QUIETON(con);
-        pout("StartStop Log Sense Failed, page mismatch\n");
-        QUIETOFF(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 start stop count:  %u times\n", 
-             recommendedStartStop);
-    }
-} 
-
-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_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[0]);
-        found[0] = 1;
-    }
-    if (0 == scsiLogSense(device, WRITE_ERROR_COUNTER_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[1]);
-        found[1] = 1;
-    }
-    if (0 == scsiLogSense(device, VERIFY_ERROR_COUNTER_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        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%8llu %8llu  %8llu  %8llu   %8llu", 
-                 pageNames[k], ecp->counter[0], ecp->counter[1], 
-                 ecp->counter[2], ecp->counter[3], ecp->counter[4]);
-            processed_gb = ecp->counter[5] / 1000000000.0;
-            pout("   %12.3f    %8llu\n", processed_gb, ecp->counter[6]);
-        }
-    }
-    else 
-        pout("\nNo Error counter log to report\n");
-    if (0 == scsiLogSense(device, NON_MEDIUM_ERROR_PAGE, gBuf, 
-                          LOG_RESP_LEN)) {
-        scsiDecodeNonMediumErrPage(gBuf, &nme);
-        if (nme.gotPC0)
-            pout("\nNon-medium error count: %8llu\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;
-    unsigned long long ull=0;
-
-    if ((err = scsiLogSense(device, SELFTEST_RESULTS_PAGE, gBuf, 
-                            LOG_RESP_LEN))) {
-        QUIETON(con);
-        pout("scsiPrintSelfTest Failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    if (gBuf[0] != SELFTEST_RESULTS_PAGE) {
-        QUIETON(con);
-        pout("Self-test Log Sense Failed, page mismatch\n");
-        QUIETOFF(con);
-        return 1;
-    }
-    // compute page length
-    num = (gBuf[2] << 8) + gBuf[3];
-    // Log sense page length 0x190 bytes
-    if (num != 0x190) {
-        QUIETON(con);
-        pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n",num);
-        QUIETOFF(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 ((0xffffffffffffffffULL != ull) && (res > 0) && ( res < 0xf))
-            pout("  0x%16llx", 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)) &&
-        (durationSec > 0))
-        pout("Long (extended) Self Test duration: %d seconds "
-             "[%.1f minutes]\n", durationSec, durationSec / 60.0);
-    return 0;
-}
- 
-/* 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[64];
-    struct scsi_iec_mode_page iec;
-    int err, len;
-    int is_tape = 0;
-        
-    memset(gBuf, 0, 36);
-    if ((err = scsiStdInquiry(device, gBuf, 36))) {
-        QUIETON(con);
-        pout("Standard Inquiry failed [%s]\n", scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    len = gBuf[4] + 5;
-    if (peripheral_type)
-        *peripheral_type = gBuf[0] & 0x1f;
-    if (!all)
-	return 0;
-
-    if (len >= 36) {
-        memset(manufacturer, 0, sizeof(manufacturer));
-        strncpy(manufacturer, &gBuf[8], 8);
-     
-        memset(product, 0, sizeof(product));
-        strncpy(product, &gBuf[16], 16);
-            
-        memset(revision, 0, sizeof(revision));
-        strncpy(revision, &gBuf[32], 4);
-        pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
-        if (0 == 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 {
-        QUIETON(con);
-        pout("Short INQUIRY response, skip product id\n");
-        QUIETOFF(con);
-    }
-
-    // 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 (1 == err) {
-            QUIETON(con);
-            pout("device is NOT READY (media absent, spun down, etc)\n");
-            QUIETOFF(con);
-        } else {
-            QUIETON(con);
-            pout("device Test Unit Ready  [%s]\n", scsiErrString(err));
-            QUIETOFF(con);
-        }
-	return 0;
-    }
-   
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-	if (!is_tape) {
-            QUIETON(con);
-	    pout("Device does not support SMART [%s]\n", 
-		 scsiErrString(err));
-            QUIETOFF(con);
-        }
-        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))) {
-        QUIETON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    if ((err = scsiSetExceptionControlAndWarning(device, 1, &iec))) {
-        QUIETON(con);
-        pout("unable to enable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    }
-    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))) {
-        QUIETON(con);
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    if ((err = scsiSetExceptionControlAndWarning(device, 0, &iec))) {
-        QUIETON(con);
-        pout("unable to disable Exception control and warning [%s]\n",
-             scsiErrString(err));
-        QUIETOFF(con);
-        return 1;
-    }
-    /* Need to refetch 'iec' since could be modified by previous call */
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-        pout("unable to fetch IEC (SMART) mode page [%s]\n", 
-             scsiErrString(err));
-        return 1;
-    }
-    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);
-}
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-static 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 has failed: exiting.\n"
-                 "To continue, set the tolerance level to something other "
-                 "than 'conservative'\n");
-            exit(returnvalue);
-        }
-    }
-    return;
-}
-
-
-/* Main entry point used by smartctl command. Return 0 for success */
-int scsiPrintMain(const char *dev_name, int fd)
-{
-    int checkedSupportedLogPages = 0;
-    UINT8 peripheral_type = 0;
-    int returnval=0;
-    int res;
-
-    if (scsiGetDriveInfo(fd, &peripheral_type, con->driveinfo)) {
-        pout("Smartctl: SCSI device INQUIRY Failed\n\n");
-        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->checksmart) {
-        scsiGetSupportedLogPages(fd);
-        checkedSupportedLogPages = 1;
-        if ((SCSI_PT_SEQUENTIAL_ACCESS == peripheral_type) ||
-            (SCSI_PT_MEDIUM_CHANGER == peripheral_type)) { /* tape device */
-            if (gTapeAlertsPage) {
-		if (con->driveinfo)
-		    pout("TapeAlert Supported\n");
-                if (-1 == scsiGetTapeAlertsData(fd, peripheral_type))
-                    failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
-	    }
-	    else
-		pout("TapeAlert Not Supported\n");
-            if (gTempPage)
-                scsiPrintTemp(fd);         
-            if (gStartStopPage)
-                scsiGetStartStopData(fd);
-        } else { /* disk, cd/dvd, enclosure, etc */
-            scsiGetSmartData(fd);
-            if (gTempPage)
-                scsiPrintTemp(fd);         
-            if (gStartStopPage)
-                scsiGetStartStopData(fd);
-        }
-    }   
-    if (con->smarterrorlog)
-        scsiPrintErrorCounterLog(fd);
-    if (con->smartselftestlog) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        res = 0;
-        if (gSelfTestPage)
-            res = scsiPrintSelfTest(fd);
-        else {
-            pout("Warning: 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");
-        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 e5b410365..000000000
--- a/sm5/scsiprint.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * scsiprint.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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/
- *
- */
-
-
-/* scsismart version number */
-#ifndef SCSI_PRINT_H_
-#define SCSI_PRINT_H_
-
-#ifndef SCSIPRINT_H_CVSID
-#define SCSIPRINT_H_CVSID "$Id: scsiprint.h,v 1.13 2003/05/01 08:49:04 dpgilbert Exp $\n"
-#endif
-
-// MACROS to control printing behavior (from ataprint.h)
-#define QUIETON(control)  {if (control->quietmode) control->veryquietmode=0;}
-#define QUIETOFF(control) {if (control->quietmode && !control->veryquietmode) control->veryquietmode=1;}
-
-int scsiPrintMain(const char * dev_name, int fd);
-
-#endif
diff --git a/sm5/smartctl.8 b/sm5/smartctl.8
deleted file mode 100644
index e6fb01311..000000000
--- a/sm5/smartctl.8
+++ /dev/null
@@ -1,890 +0,0 @@
-\# Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-\#
-\# $Id: smartctl.8,v 1.68 2003/04/21 22:43:04 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  "$Date: 2003/04/21 22:43:04 $" "smartmontools-5.1"
-.SH NAME
-smartctl \- Control and Monitor Utility for SMART Disks
-.SH SYNOPSIS
-.B smartctl [options] device
-
-.SH DESCRIPTION
-.B smartctl
-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 \fB smartctl\fP is
-compatible with ATA/ATAPI-5 and earlier standards (see REFERENCES
-below)
-
-.B smartctl
-is a command line utility designed to perform SMART tasks such as
-printing the SMART self-test and error logs, and enabling and
-disabling SMART automatic testing. Note: if the user issues a
-SMART command that is (apparently) not implemented by the device,
-.B smartctl
-will print a warning message but issue the command anyway.  This should
-not cause problems: unimplemented SMART commands issued to a
-drive are ignored and return an error.
-
-.B smartctl
-also provides limited TapeAlerts support for some SCSI tape drives and
-changers.
-
-The user must specify the device to be controlled or interrogated as the final
-argument to
-.B smartctl.
-ATA devices use the form "/dev/hd*" and SCSI devices use the form "/dev/sd*".
-For SCSI Tape Drives and Changers with TapeAlerts support use the devices
-"/dev/st*" and "/dev/sg*".  More general paths may also be specified.
-.B smartctl
-will attempt to guess the device type, but the '\-d' option can be used to
-specify a device type of ATA or SCSI if required.
-
-Note that the printed output of
-.B smartctl
-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
-.B "0x"
-for example: "0xff". This man page follows the same convention.
-
-.PP
-.SH OPTIONS
-.PP
-The options are grouped below into several categories.
-.B smartctl
-will execute the corresponding commands in the order: INFORMATION,
-ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
-
-SCSI devices only accept the options 
-.B \-h, \-?, \-V, \-i, \-a, \-d, \-s, \-H, \-t, \-C, \-l selftest, \-l error
-and 
-.B \-X. 
-TapeAlerts devices only accept the options 
-.B \-h, \-?, \-V, \-i, \-a, \-d, \-s, \-t, \-l selftest, \-l error
-and 
-.B \-H.
-
-Long options  are  not  supported  on  all  systems.   Use
-.B 'smartctl \-h'
-to see the available options.
-
-.TP
-.B SHOW INFORMATION:
-.TP
-.B \-h, \-\-help, \-\-usage
-Prints a usage message to STDOUT and exits.
-.TP
-.B \-?
-Same as
-.B \-h.
-.TP
-.B \-V, \-\-version, \-\-copyright, \-\-license
-Prints version, copyright, license, home page and CVS-id information for your
-copy of
-.B smartctl
-to STDOUT and then exits.  Please include this information if you are
-reporting bugs or problems.
-.TP
-.B \-i, \-\-info
-Prints the disk 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.
-.TP
-.B \-a, \-\-all
-Prints all SMART information about the disk.  This is equivalent to '\-H
-\-i \-c \-A \-l error \-l selftest' (for SCSI, '\-H \-i \-l error
-\-l selftest').
-.TP
-.B RUN-TIME BEHAVIOR:
-.TP
-.B \-q TYPE, \-\-quietmode=TYPE
-Specifies that
-.B smartctl
-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
-.B smartctl
-(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 and \fIscsi\fP.  If this option is not used then
-.B smartctl
-will attempt to guess the device type from the device name.
-.TP
-.B \-T TYPE, \-\-tolerance=TYPE
-Specifies how tolerant
-.B smartctl
-should be of SMART command failures.  The valid arguments to this option
-are:
-
-.I normal
-\- exit on failure of a mandatory SMART command, but not on failure of an
-optional SMART command.  This is the default.  
-
-.I conservative
-\- exit on failure of any SMART command.
-
-.I permissive
-\- ignore failure of any SMART command.
-
-Here "mandatory" means "required by the ATA/ATAPI-5 Specification if the
-device implements the SMART command set" and "optional" means "not
-required by the ATA/ATAPI-5 Specification even if the device implements
-the SMART command set."  The 'mandatory' SMART commands are: (1)
-Enable/Disable Attribute Autosave, (2) Enable/Disable SMART, and (3)
-SMART Return Status.
-
-.TP
-.B \-b TYPE, \-\-badsum=TYPE
-Specifies the action 
-.B smartctl
-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
-.B smartctl.
-
-.I ignore
-\- continue silently without issuing a warning.
-
-.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
-.B smartctl
-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.
-.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
-that I can find.  However it is implemented and used by some
-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 tell if automatic offline testing is supported by seeing if
-this command enables and disables it, as indicated by the SMART
-capabilities (displayed with '\-c').
-
-SMART provides
-.B three basic categories of testing.
-The 
-.B first category,
-called 'online' testing, has no effect on the performance of
-the device.  It is turned on by the '\-s on' option.
-
-The 
-.B second 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.
-
-Any errors detected in automatic or immediate offline testing are
-reflected in the values of the SMART Attributes; some types of
-errors may also appear in the SMART error log. These are visible
-with the '\-A' and '\-l error' options respectively.
-
-The 
-.B third category of testing
-is the '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.
-
-.B Note:
-in this manual page, the word 
-.B "Test"
-is used in connection with the second category 
-just described, e.g. for the 'offline' testing.  The words 
-.B "Self-test"
-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.
-.TP
-.B SMART READ AND DISPLAY DATA OPTIONS:
-.TP
-.B \-H, \-\-health
-Check: Ask the device to report its SMART health status.  It does
-this using information that it has gathered from online and offline
-tests, which were used to determine/update its
-SMART vendor-specific Attribute values.
-
-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. 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:
-.B smartctl
-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.  Note that
-.B smartctl
-only reports the different Attribute values and thresholds.  It does
-.B not
-carry out the conversion between 'Raw' and 'Normalized' values.
-
-Note that 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
-.B smartctl
-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
-.B less than or equal to
-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 will have firmware which will
-.B increase
-the 'Worst' value for some "rate-type" Attributes.]
-
-The Attribute table printed out by 
-.B smartctl
-also shows the 'Type' of the Attribute.  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.
-
-If the Attribute's current Normalized value is <= threshold, then the 'Ever
-failed' column will display 'FAILED NOW!'.  If not, but the worst
-recorded value is <= threshold, then this column will display 'In the
-past'.
-
-So to summarize: the 'Raw' 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 worst (lowest
-measured) of these Normalized Attribute values is 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.
-.B smartctl
-does not calculate any of these values, it merely reports them from
-the SMART data on the disk.
-
-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.
-.TP
-.B \-l TYPE, \-\-log=TYPE
-Prints either the SMART error log or the SMART self-test log.  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.  Finally, up to the last five commands that preceded the
-error are also recorded, along with a timestamp measured in seconds
-from when the disk was powered up during the session where the error
-took place.  [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 ATA Specification (ATA-5 Revision 1c, Section 8.41.6.8.2 to be
-precise) says "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."
-
-.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 only the SMART self-test log.  The disk maintains a 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.
-
-.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. 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 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
-smartmontools 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 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 200,writeerrorcount
-\- Raw Attribute number 200 is the Write Error 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
-.B smartctl
-to compensate for some known and understood device firmware bug.  The
-valid arguments to this option are:
-
-.I none
-Assume that the device firmware obeys the ATA specifications.  This is
-the default.
-
-.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
-.B smartctl
-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 erorr log; (3) strange and impossible values for
-the ATA error log timestamps.
-
-.TP
-.B \-P TYPE, \-\-presets=TYPE
-Specifies whether
-.B smartctl
-should use any preset options that are available for this drive. By
-default, if the drive is recognized in the smartmontools database,
-then the presets are used.
-
-.B smartctl
-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
-.B smartctl
-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
-.B smartctl
-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 smartmontools 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
-.B smartctl
-to display correct values) then please contact the
-.B smartmontools
-developers so that this information can be added to the smartmontools
-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.
-
-.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 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
-.B smartctl
-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
-.B smartctl.
-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).
-
-.TP
-.B \-C, \-\-captive
-With '\-t short' or '\-t long', runs the self-test 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.]
-
-.B WARNING: Tests run in captive mode may busy out the drive for the length
-.B of the test.  Only run captive tests on drives without any mounted partitions!
-
-.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
-.SH RETURN VALUES
-The return values of smartctl are defined by a bitmask.  For the
-moment this only works on ATA disks.  The different bits in the return
-value are as follows:
-.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 AUTHOR
-Bruce Allen
-.B smartmontools-support@lists.sourceforge.net
-.fi
-University of Wisconsin \- Milwaukee Physics Department
-
-.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. http://ssrc.soe.ucsc.edu/.
-.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:
-.B
-smartd (8)
-.SH
-REFERENCES FOR SMART
-.fi
-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:
-.nf
-.B
-http://www.t13.org/project/d1321r1c.pdf
-.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:
-.nf
-.B
-http://www.t13.org/#FTP_site
-
-.fi
-The functioning of SMART is also described by the SFF-8035i
-revision 2 specification.  This is a publication of the Small Form
-Factors (SFF) Committee, and can be obtained from:
-.TP
-\ 
-SFF Committee
-.nf
-14426 Black Walnut Ct.
-.nf
-Saratoga, CA 95070, USA
-.nf
-SFF FaxAccess: +01 408-741-1600
-.nf
-Ph: +01 408-867-6630
-.nf
-Fax: +01 408-867-2115
-.nf
-E-Mail: 250-1752@mcimail.com.
-.PP
-Please let us know if there is an on\-line source for this document.
-
-.SH
-CVS ID OF THIS PAGE:
-$Id: smartctl.8,v 1.68 2003/04/21 22:43:04 ballen4705 Exp $
diff --git a/sm5/smartctl.c b/sm5/smartctl.c
deleted file mode 100644
index 8fbdf0a1f..000000000
--- a/sm5/smartctl.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * smartctl.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 <stdio.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-#include <sys/fcntl.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "scsiprint.h"
-#include "smartctl.h"
-#include "utility.h"
-
-extern const char *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid; 
-const char* smartctl_c_cvsid="$Id: smartctl.c,v 1.76 2003/05/01 08:51:46 dpgilbert Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID EXTERN_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;
-
-
-void printslogan(){
-  pout("smartctl version %d.%d-%d Copyright (C) 2002-3 Bruce Allen\n",
-      (int)RELEASE_MAJOR, (int)RELEASE_MINOR, (int)SMARTMONTOOLS_VERSION);
-  pout("Home page is %s\n\n",PROJECTHOME);
-  return;
-}
-
-
-void printcopy(){
-  char out[CVSMAXLEN];
-  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");
-  printone(out,atacmds_c_cvsid);
-  pout("%s",out);
-  printone(out,ataprint_c_cvsid);
-  pout("%s",out);
-  printone(out,knowndrives_c_cvsid);
-  pout("%s",out);
-  printone(out,scsicmds_c_cvsid);
-  pout("%s",out);
-  printone(out,scsiprint_c_cvsid);
-  pout("%s",out);
-  printone(out,smartctl_c_cvsid);
-  pout("%s",out);
-  printone(out,utility_c_cvsid);
-  pout("%s",out);
-  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\n\n"
-"  -T TYPE, --tolerance=TYPE                                           (ATA)\n"
-"         Set tolerance to one of: normal, conservative, permissive\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\n"
-"  -T TYPE   Set tolerance to one of: normal, conservative, permissive (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                                                    (ATA)\n"
-"        Show device SMART vendor-specific Attributes and values\n\n"
-"  -l TYPE, --log=TYPE\n"
-"        Show device log. Type is one of: error, selftest\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. Type is one of: none, samsung\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 is one of: error, selftest\n"
-"  -v N,OPT  Set display OPTion for vendor Attribute N (see man page)  (ATA)\n"
-"  -F TYPE   Use firmware bug workaround. Type is one of: none, samsung(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 on device.  TEST is one of: offline, short, long\n\n"
-"  -C, --captive\n"
-"        With -t, performs test in captive mode (short/long only)\n\n"
-"  -X, --abort\n"
-"        Abort any non-captive test on device\n\n"
-);
-#else
-  printf(
-"  -t TEST   Run test on device.  TEST is one of: offline, short, long   \n"
-"  -C        With -t, performs test in captive mode (short/long only)  \n"
-"  -X        Abort any non-captive test                                \n\n"
-  );
-#endif
-  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"
-  );
-#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"
-  );
-#endif
-}
-
-/* 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) {
-  static char *v_list = NULL;
-  char *s;
-
-  switch (opt) {
-  case 'q':
-    return "errorsonly, silent";
-  case 'd':
-    return "ata, scsi";
-  case 'T':
-    return "normal, conservative, permissive";
-  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, directory";
-  case 'v':
-    if (v_list) 
-      return v_list;
-    if (!(s = create_vendor_attribute_arg_list()))
-      return NULL;
-    // Allocate space for tab + "help" + newline + s + terminating 0
-    v_list = (char *)malloc(7+strlen(s));
-    sprintf(v_list, "\thelp\n%s", s);
-    free(s);
-    return v_list;
-  case 'P':
-    return "use, ignore, show, showall";
-  case 't':
-    return "offline, short, long";
-  case 'F':
-    return "none, samsung";
-  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) {
-  const char *s;
-  char separator;
-
-  if (!(s = getvalidarglist(opt))) {
-    pout("Error whilst constructing argument list for option %c", opt);
-    return;
-  }
-
-  // getvalidarglist() might produce a multiline or single line string.  We
-  // need to figure out which to get the formatting right.
-  separator = strchr(s, '\n') ? '\n' : ' ';
-
-  pout("=======> VALID ARGUMENTS ARE:%c%s%c<=======\n", separator, (char *)s,
-    separator);
-}
-
-unsigned char tryata=0,tryscsi=0;
-
-/*      Takes command options and sets features to be run */	
-void ParseOpts (int argc, char** argv){
-  int optchar;
-  int badarg;
-  int captive;
-  extern char *optarg;
-  extern int optopt, optind, opterr;
-  // 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(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->veryquietmode=FALSE;
-      printslogan();
-      printcopy();
-      exit(0);
-      break;
-    case 'q':
-      if (!strcmp(optarg,"errorsonly")) {
-        con->quietmode     = TRUE;
-        con->veryquietmode = FALSE;
-      } else if (!strcmp(optarg,"silent")) {
-        con->veryquietmode = TRUE;
-        con->quietmode     = TRUE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'd':
-      if (!strcmp(optarg,"ata")) {
-        tryata  = TRUE;
-        tryscsi = FALSE;
-      } else if (!strcmp(optarg,"scsi")) {
-        tryata  = FALSE;
-        tryscsi = TRUE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'T':
-      if (!strcmp(optarg,"normal")) {
-        con->conservative = FALSE;
-        con->permissive   = FALSE;
-      } else if (!strcmp(optarg,"conservative")) {
-        con->conservative = TRUE;
-        con->permissive   = FALSE;
-      } else if (!strcmp(optarg,"permissive")) {
-        con->permissive   = TRUE;
-        con->conservative = FALSE;
-      } 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->veryquietmode = 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 {
-        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,"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;
-      break;
-    case 'v':
-      // parse vendor-specific definitions of attributes
-      if (!strcmp(optarg,"help")) {
-        char *s;
-        con->veryquietmode=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);
-      }
-      if (parse_attribute_def(optarg, con->attributedefs))
-	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 {
-        badarg = TRUE;
-      }
-      break;
-    case 'C':
-      captive = TRUE;
-      break;
-    case 'X':
-      con->smartselftestabort = TRUE;
-      con->testcase           = ABORT_SELF_TEST;
-      break;
-    case 'h':
-    case '?':
-    default:
-      con->veryquietmode=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);
-	pout("\nUse smartctl --help to get a usage summary\n\n");
-	exit(FAILCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (strchr(shortopts, optopt) != NULL) {
-          pout("=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n", optopt);
-          printvalidarglistmessage(optopt);
-        } else
-	  pout("=======> UNRECOGNIZED OPTION: %c <=======\n",optopt);
-	pout("\nUse smartctl -h to get a usage summary\n\n");
-	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);
-      pout("\nUse smartctl -h to get a usage summary\n\n");
-      exit(FAILCMD);
-    }
-  }
-  // At this point we have processed all command-line options.
-
-  // Do this here, so results are independent of argument order	
-  if (con->quietmode)
-    con->veryquietmode=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->veryquietmode=FALSE;
-    printslogan();
-    pout("\nERROR: smartctl can only run a single test (or abort) at a time.\n");
-    pout("Use smartctl -h to get a usage summary\n\n");
-    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;
-  }
-
-  // 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");
-    pout("Use smartctl -h to get a usage summary\n\n");
-    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]);
-    pout("Use smartctl -h to get a usage summary\n\n");
-    exit(FAILCMD);
-  }  
-}
-
-// Printing function (controlled by global con->veryquietmode) 
-// [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->veryquietmode){
-    va_end(ap);
-    return;
-  }
-
-  // print out
-  vprintf(fmt,ap);
-  va_end(ap);
-  fflush(stdout);
-  return;
-}
-
-
-/* Main Program */
-int main (int argc, char **argv){
-  int fd,retval=0;
-  char *device;
-  smartmonctrl control;
-  int dev_type, flags;
-
-  // define control block for external functions
-  con=&control;
-
-  // Part input arguments
-  ParseOpts(argc,argv);
-
-  device = argv[argc-1];
-  dev_type = guess_linux_device_type(device);
-  if (GUESS_DEVTYPE_SCSI == dev_type) {
-    flags = O_RDWR | O_NONBLOCK;
-    tryscsi = 1;
-  } else { /* treat "don't know" case as an ATA device as well */
-    flags = O_RDONLY | O_NONBLOCK;
-    tryata = 1;
-  }
-
-  // open device - SCSI devices are opened (O_RDWR | O_NONBLOCK) so the
-  // scsi generci 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). 
-  fd = open(device, flags);
-  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
-  if (tryata)
-    retval = ataPrintMain(fd);
-  else if (tryscsi)
-    retval = scsiPrintMain(device, fd);
-  else {
-    pout("Smartctl: specify if this is an ATA or SCSI device with the -d option.\n");
-    Usage();
-    return FAILCMD;
-  }
-
-  return retval;
-}
diff --git a/sm5/smartctl.h b/sm5/smartctl.h
deleted file mode 100644
index 1ef52f48a..000000000
--- a/sm5/smartctl.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * smartctl.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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_
-
-#ifndef SMARTCTL_H_CVSID
-#define SMARTCTL_H_CVSID "$Id: smartctl.h,v 1.17 2003/03/06 07:27:17 ballen4705 Exp $\n"
-#endif
-
-/* Boolean Values */
-#define TRUE 0x01
-#define FALSE 0x00
-
-// Return codes (bitmask)
-
-// command line did not parse
-#define FAILCMD   (0x01<<0)
-
-// device open failed or could not get identity info
-#define FAILDEV   (0x01<<1)
-#define FAILID    (0x01<<1)
-
-// smart command failed
-#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
-
-#endif
diff --git a/sm5/smartd.8 b/sm5/smartd.8
deleted file mode 100644
index 9b2c184f9..000000000
--- a/sm5/smartd.8
+++ /dev/null
@@ -1,1248 +0,0 @@
-\# Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-\# 
-\# $Id: smartd.8,v 1.94 2003/04/23 13:19:40 guidog 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  "$Date: 2003/04/23 13:19:40 $" "smartmontools-5.1"
-.SH NAME
-smartd \- SMART Disk Monitoring Daemon
-.SH SYNOPSIS
-.B smartd [options]
-
-.SH DESCRIPTION
-.B smartd
-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
-.B smartd
-is compatible with ATA/ATAPI-5 and earlier standards (see 
-.B REFERENCES
-below)
-
-.B smartd
-will attempt to enable SMART monitoring on ATA devices (equivalent to
-.B smartctl -s on
-) 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
-.B /var/log/messages. 
-
-.B smartd
-can be configured at start-up using the file
-.B /etc/smartd.conf.
-Note that
-.B smartd
-only reads the configuration file at start-up: changes to the
-configuration file take effect only after the
-.B smartd
-daemon is restarted.
-If you send a 
-.B HUP
-signal to
-.B smartd
-it will log a polite message saying that it ignores this signal and
-that it has
-.I not
-re-read the configuration file.
-
-If you send a 
-.B USR1 
-signal to
-.B smartd
-it will immediately check the status of the disks, and then return to
-polling the disks every 30 minutes. See the
-.B '\-i'
-option below for additional details.
-
-On startup, in the absence of the configuration file
-.B /etc/smartd.conf,
-the 
-.B smartd
-daemon first scans for all devices that support SMART, using
-.B "/dev/hd[a-l]"
-for IDE/ATA devices, and 
-.B "/dev/sd[a-z]"
-for SCSI devices. It then monitors for
-.I all 
-possible SMART errors (corresponding to the 
-.B '\-a' 
-Directive in the configuration file; see
-.B CONFIGURATION FILE
-below). Note that when there is no configuration file, and
-.B smartd
-scans for devices on startup,
-.B warning messages may appear in SYSLOG
-(by default
-.B /var/log/messages)
-about missing block-major-xx devices.  These messages are usually
-harmless. Alternatively, the configuration file can be used to exclude
-non-existent devices by giving a list of devices to monitor at
-start-up.
-
-.SH 
-OPTIONS
-Long options are not supported on all systems.  Use
-.B 'smartd \-h'
-to see the available options.
-.TP
-.B \-d, \-\-debug
-Runs 
-.B smartd 
-in ""debug"" mode. In this mode, it does not 
-.B fork
-(2) and displays status information to STDOUT.  It also prints more
-verbose information about what it is doing.
-.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 \-i N, \-\-interval=N
-Sets the interval between disk checks to
-.I N
-seconds, where
-.I N
-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
-.B smartd
-check the status of the disks at any time by sending it the 
-.B SIGUSR1
-signal, for example with the command:
-.nf
-.B kill -SIGUSR1 <pid>
-.fi
-where 
-.B <pid> 
-is the process id number of
-.B smartd.
-One may also use:
-.nf
-.B killall -USR1 smartd
-.fi
-for the same purpose.
-
-.TP
-.B \-p NAME, \-\-pidfile=NAME
-Writes pidfile
-.I NAME
-containing the
-.B smartd
-Process ID number (PID).
-To avoid symlink attacks make sure the directory to which
-pidfile is written is only writeable for root.  Without this option,
-or if the --debug option is given, no PID file is written on startup.
-If
-.B smartd
-is killed with a maskable signal then the pidfile is removed.
-
-.TP
-.B \-c, \-\-checkonce
-Start
-.B smartd
-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 option is intended for 'distribution-writers' who
-want to create automated scripts to determine whether or not to
-automatically start up
-.B smartd
-after installing smartmontools.  After starting
-.B smartd
-with this command-line option, the distribution's install scripts should
-wait a reasonable length of time (say ten seconds).  If
-.B smartd
-has not exited with zero status by that time, the script should send
-.B smartd
-a SIGTERM or SIGKILL and assume that
-.B smartd
-will not operate correctly on the host.  Conversely, if
-.B smartd
-exits with zero status, then it is safe to run
-.B smartd
-in normal daemon mode.
-
-Note that if
-.B smartd
-is unable to monitor any devices or encounters other problems then it
-will return with non-zero exit status.
-
-.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
-.B smartd.
-.TP
-.B \-h, \-\-help, \-\-usage
-Prints usage message to STDOUT and exits.
-.TP
-.B \-?
-Same as
-.B -h.
-
-
-.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
-.B smartd
-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.  Whe 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, 
-.I ataioctl,2
-The default
-level is 1, so '\-r ataioctl,1' and '\-r ataioctl' are equivalent.
-
-
-.SH EXAMPLES
-
-.B
-smartd
-.fi
-Runs the daemon in forked mode. This is the normal way to run
-.B smartd.
-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 -c
-.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 
-.B smartmontools
-provides a start-up script in
-.B /etc/rc.d/init.d/smartd
-which is responsible for starting and stopping the daemon via the
-normal init interface. 
-Using this script, you can start
-.B smartd
-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
-.B smartd
-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
-
-\# 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,
-.B smartd 
-will try to open the 12 ATA devices 
-.B /dev/hd[a-l] 
-and the 26 SCSI devices
-.B /dev/sd[a-z]. 
-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
-.B smartd,
-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
-There should be one device listed per line, although you may have
-lines that are entirely comments or white space.
-
-Any text following a hash sign (#) and up to the end of the line is
-taken to be a comment, and ignored.
-
-Lines may be continued by using a backslash (\(rs) as the last
-non-whitespace or non-comment item on a 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
-.B # ATA disks and two SCSI disks.
-.B #
-.nf
-.B # First ATA disk on each of two interfaces:
-.B #
-.B \ \ /dev/hda -a -m admin@yoyodyne.com,root@localhost 
-.B \ \ /dev/hdc -a -I 194 -I 5 -i 12
-.B #
-.nf
-.B # SCSI disks.  Send a TEST warning email to admin on
-.B # startup.
-.B #
-.B \ \ /dev/sda
-.B \ \ /dev/sdc -m admin@yoyodyne.com -M test
-.B #
-.nf
-.B # Strange device.  It's SCSI:
-.B #
-.B \ \ /dev/weird -d scsi
-.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\ \(rs
-.B \ \ \ \ \ \ \ \ \ \ \ -l\ selftest\ \(rs
-.B \ \ \ \ \ \ \ \ \ \ \ -t\ \(rs\ \ \ \ \ \ # Attributes not tracked:
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 194\ \(rs\ \ # temperature
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 231\ \(rs\ \ # 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
-.B smartd
-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 
-.B smartd.
-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 only implemented level: roughly equivalent
-to using the '\-H' option for an ATA disk.  So with the exception of '\-d', '\-m', 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, or if the SCSI inquiry about disk status fails.
-
-.TP
-.B \-d TYPE
-Specifies the type of the device.  This will prevent
-.B smartd
-from issuing SCSI commands to an ATA device and vice versa.  The valid
-arguments to this Directive are \fIata\fP and \fIscsi\fP.
-
-In the absence of this Directive,
-.B smartd
-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.  If
-.B smartd
-can't guess from this sixth character, then it will simply try to
-access the device using first ATA and then SCSI ioctl()s.
-.TP
-.B \-T TYPE
-Specifies how tolerant
-.B smartd
-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.
-
-[Please see the
-.B smartctl \-T
-command-line option.]
-.TP
-.B \-o VALUE
-Enables or disables SMART Automatic Offline Testing when
-.B smartd
-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.
-[Please see the
-.B smartctl \-o
-command-line option.]
-.TP
-.B \-S VALUE
-Enables or disables Attribute Autosave when
-.B smartd
-starts up and has no further effect.  The valid arguments to this
-Directive are \fIon\fP and \fIoff\fP.  [Please see the
-.B smartctl \-S
-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 priority
-.B '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 that the number of ATA errors reported in the ATA Error Log has
-increased since the last check.
-
-.I selftest
-\- report if that the number of errors reported in the SMART Self-Test Log
-has increased since the last check.  Note that such errors will
-.B only
-be logged if you run self-tests on the disk (and it fails the tests!).
-[Self-Tests can be run by using the
-.B '\-t\ short'
-and
-.B '\-t\ long'
-options of
-.B smartctl
-and the results of the testing can be observed using the
-.B smartctl '\-l\ selftest'
-command-line option.]
-
-[Please see the
-.B smartctl \-l
-command-line option.]
-.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
-.B smartctl \-A
-command-line option.]
-
-.TP
-.B \-m ADD
-Send a warning email to the email address
-.B ADD
-if the '\-H', '\-l', or '\-f' Directives detect a failure or a new
-error, or is 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 test types, '\-H', '\-l', or '\-f', 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 form for
-the address:
-.B  user1@add1,user2@add2,...,userN@addN
-(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
-.B smartd
-startup.
-
-By default, email is sent using the system 
-.B mail
-command.  In order that
-.B smartd
-find the mail command (normally /bin/mail) an executable named
-.B 'mail'
-must be in the path of the shell or environment from which
-.B smartd
-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 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.
-
-.TP
-.B \-M TYPE
-These Directives modify the behavior of the
-.B smartd
-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
-.B smartd
-startup.  This allows one to verify that any email is correctly delivered.
-
-.I exec PATH
-\- run the executable PATH instead of the default mail command, when
-.B smartd
-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
-.B smartd
-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.
-.B smartd
-will
-.B block
-until the executable PATH returns, so if your executable hangs, then
-.B smartd
-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
-.B smartd
-in SYSLOG, but the executable's STDOUT and STDERR are directed to
-/dev/null, so if you wish to leave some other record behind, the
-executable must send mail or write to a file or device.
-
-Before running the executable,
-.B smartd
-sets a number of environment variables.  These environment variables
-may be used to control the executable's behavior.  The environment
-variables exported by
-.B smartd
-are:
-.nf
-.fi
-.B SMARTD_MAILER
-is set to the argument of -M exec, if present or else to 'mail'
-(examples: /bin/mail, mail).
-.nf
-.fi
-.B SMARTD_DEVICE
-is set to the device path (examples: /dev/hda, /dev/sdb).
-.nf
-.fi
-.B SMARTD_DEVICETYPE
-is set to the device type (possible values: ata, scsi).
-.nf
-.fi
-.B SMARTD_FAILTYPE
-gives the reason for the warning or message email.  The possible values that
-it takes, and their significance, are:
-.I emailtest
-(this is an email test message);
-.I health
-(the SMART health status indicates imminent failure);
-.I usage
-(a usage Attribute has failed);
-.I selftest
-(the number of self-test failures has increased);
-.I errorcount
-(the number of errors in the ATA error log has increased);
-.I FAILEDhealthcheck
-(the SMART health status command failed);
-.I FAILEDreadsmartdata
-(the command to read SMART Attribute data failed);
-.I FAILEDreadsmarterrorlog
-(the command to read the SMART error log failed);
-.I FAILEDreadsmartsefltestlog
-(the command to read the SMART self-test log failed); abd
-.I FAILEDopendevice
-(the open() command to the device failed).
-.nf
-.fi
-.B SMARTD_ADDRESS
-is set to the address argument ADD of the '\-m' Directive, unless ADD
-is
-.B <nomailer>.
-This is a comma-delineated list of email addresses (example:
-admin@yoyodyne.com).
-.nf
-.fi
-.B SMARTD_MESSAGE
-is set to the warning email message string from
-.B smartd. 
-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.
-.nf
-.fi
-.B SMARTD_TFIRST
-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
-.nf
-.fi
-.B SMARTD_TFIRSTEPOCH
-is an integer, which is the unix epoch (number of seconds since Jan 1,
-1970) for
-.B SMARTD_TFIRST.
-
-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 system (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 \(dq$SMARTD_SUBJECT\(dq $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
-
-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
-
-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 \-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
-.I all
-device Attributes (both Prefailure and Usage). [Please see the
-.B smartctl \-A
-command-line option.]
-.TP
-.B \-i ID
-Ignore device Attribute number
-.B ID
-when checking for failure of Usage Attributes.
-.B ID
-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
-.B ID
-when tracking changes in the Attribute values.
-.B ID
-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
-.I Raw
-value of Attribute
-.B ID
-along with its (normally reported)
-.I Normalized
-value.
-.B ID
-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
-.I Raw
-value of Attribute
-.B ID
-changes.  (Normally
-.B smartd
-only tracks/reports changes of the
-.I Normalized
-Attribute values.)
-.B ID
-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 \-F TYPE, \-\-firmwarebug=TYPE
-Modifies the behavior of
-.B smartctl
-to compensate for some known and understood device firmware bug.  The
-valid arguments to this option are:
-
-.I none
-Assume that the device firmware obeys the ATA specifications.  This is
-the default.
-
-.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
-.B smartctl
-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 erorr log; (3) strange and impossible values for
-the ATA error log timestamps.
-
-[Please see the
-.B smartctl \-F
-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 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 200,writeerrorcount
-\- Raw Attribute number 200 is the Write Error 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
-.B smartd
-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, and
-.B '\-l\ error' 
-to report increases in the number of ATA errors.
-
-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 \(rs
-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
-.B smartd
-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
-.B DEVICESCAN
-in capital letters, then
-.B smartd
-will ignore any remaining lines in the configuration file, and will
-scan for devices.
-
-If
-.B DEVICESCAN 
-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.
-
-.B DEVICESCAN
-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@yoyodyne.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@yoyodyne.com
-.fi
-will do the same, but restricts the scan to ATA devices only.  
-.nf
-.B  DEVICESCAN -H -d ata -m root@yoyodyne.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
-.B #! /bin/bash
-
-.B # Save the email message (STDIN) to a file:
-.B cat > /root/msg
- 
-.B # Append the output of smartctl -a to the message:
-.B /usr/sbin/smartctl -a $SMARTD_DEVICE >> /root/msg
- 
-.B # Now email the message to the user at address ADD:
-.B /bin/mail -s \(dq$SMARTD_SUBJECT\(dq $SMARTD_ADDRESS < /root/msg
-.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
-.B #! /bin/bash
-
-.B # Warn all users of a problem
-.B wall 'Problem detected with disk: ' $SMARTD_DEVICE
-.B wall 'Warning message from smartd is: ' \(dq$SMARTD_MESSAGE\(dq
-.B wall 'Shutting down machine in 30 seconds... '
- 
-.B # Wait half a minute
-.B sleep 30
- 
-.B # Power down the machine
-.B /usr/sbin/shutdown -hf now
-.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.
-
-\# ENDINCLUDE
-\# DO NOT MODIFY THIS OR PREVIOUS/NEXT LINES. THIS DEFINES THE 
-\# END OF THE INCLUDE SECTION FOR smartd.conf.5
-
-.SH NOTES
-.B smartd
-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.
-
-.B smartd
-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. 
-
-.SH RETURN VALUES
-The return value (exit status) of 
-.B smartd
-can have the following values:
-.TP
-.B 0:
-Daemon startup successful.
-.TP
-.B 1:
-Commandline did not parse.
-.TP
-.B 2:
-There was a problem opening or parsing \fB/etc/smartd.conf\fP.
-.TP
-.B 3:
-Forking the daemon failed.
-.TP
-.B 4:
-Couldn't create PID file.
-.TP
-.B 8:
-.B smartd
-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 16:
-A device specified in
-.B /etc/smartd.conf
-can't be monitored.
-.TP
-.B 17:
-.B smartd
-didn't find any device to monitor.
-.TP
-.B 254:
-.B smartd
-received a fatal signal.
-
-.PP
-.SH AUTHOR
-Bruce Allen
-.B smartmontools-support@lists.sourceforge.net
-.fi
-University of Wisconsin - Milwaukee Physics Department
-
-.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. http://ssrc.soe.ucsc.edu/.
-.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:
-.B smartd.conf
-(5),
-.B smartctl
-(8),
-.B syslogd
-(8)
-.SH
-REFERENCES FOR SMART
-.fi
-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 
-.B smartmontools
-utilities provide access to.  You can find Revision 1 of this document
-at:
-.nf
-.B
-http://www.t13.org/project/d1321r1c.pdf
-.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:
-.nf
-.B
-http://www.t13.org/#FTP_site
-
-.fi
-The functioning of SMART is also described by the SFF-8035i
-revision 2 specification.  This is a publication of the Small Form
-Factors (SFF) Committee, and can be obtained from:
-.TP
-\ 
-SFF Committee
-.nf
-14426 Black Walnut Ct.
-.nf
-Saratoga, CA 95070, USA
-.nf
-SFF FaxAccess: +01 408-741-1600
-.nf
-Ph: +01 408-867-6630
-.nf
-Fax: +01 408-867-2115
-.nf
-E-Mail: 250-1752@mcimail.com.
-.PP
-Please let us know if there is an on\-line source for this document.
-
-.SH
-CVS ID OF THIS PAGE:
-$Id: smartd.8,v 1.94 2003/04/23 13:19:40 guidog Exp $
diff --git a/sm5/smartd.c b/sm5/smartd.c
deleted file mode 100644
index 4f9fe0cb6..000000000
--- a/sm5/smartd.c
+++ /dev/null
@@ -1,2180 +0,0 @@
-/*
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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/
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <linux/hdreg.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "smartd.h"
-#include "utility.h"
-
-extern const char *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
-const char *smartd_c_cvsid="$Id: smartd.c,v 1.158 2003/04/26 11:20:22 ballen4705 Exp $" 
-ATACMDS_H_CVSID ATAPRINT_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID; 
-
-// Forward declaration
-const char *getvalidarglist(char opt);
-
-// global variable used for control of printing, passing arguments, etc.
-smartmonctrl *con=NULL;
-
-// Two other globals -- number of ATA and SCSI devices being monitored
-int numatadevices=0;
-int numscsidevices=0;
-
-// How long to sleep between checks.  Handy as global variable for
-// debugging
-int checktime=CHECKTIME;
-
-// name of PID file (== NULL if no pid_file is used)
-char* pid_file=NULL;
-
-// If set, we should exit after checking all disks once
-int checkonce=0;
-
-// Needed to interrupt sleep when catching SIGUSR1.  Unix Gurus: I
-// know that this can be done better.  Please tell me how -- use email
-// address for Bruce Allen at the top of this file.  Search for
-// "sleeptime" to see what I am doing.
-volatile int sleeptime=CHECKTIME;
-
-// Interrupt sleep if we get a SIGUSR1.  Unix Gurus: I know that this
-// can be done better.  Please tell me how -- use email address for
-// Bruce Allen at the top of this file. Search for "sleeptime" to see
-// what I am doing.
-void sleephandler(int sig){
-  int oldsleeptime=sleeptime;
-  sleeptime=0;
-  printout(LOG_CRIT,"Signal USR1 - checking devices now rather than in %d seconds.\n",oldsleeptime<0?0:oldsleeptime);
-  return;
-}
-
-// Global Variables for command line options. These should go into a
-// structure at some point.
-unsigned char debugmode               = FALSE;
-
-// 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, ...){
-  va_list ap;
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  if (debugmode) 
-    vprintf(fmt,ap);
-  else {
-    openlog("smartd",LOG_PID,LOG_DAEMON);
-    vsyslog(priority,fmt,ap);
-    closelog();
-  }
-  va_end(ap);
-  return;
-}
-
-// If either address or executable path is non-null then send and log
-// a warning email, or execute executable
-void printandmail(cfgfile *cfg, int which, int priority, char *fmt, ...){
-  char command[2048], message[256], hostname[256], additional[256];
-  char original[256], further[256], domainname[256], subject[256],dates[64];
-  int status;
-  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
-    "FAILEDreadsmartsefltestlog",//8
-    "FAILEDopendevice"           //9
-  };
-  
-  char *address=cfg->address;
-  char *executable=cfg->emailcmdline;
-  mailinfo *mail=cfg->maildata+which;
-  
-  // See if user wants us to send mail
-  if (!address && !executable)
-    return;
-
-  // checks for sanity
-  if (cfg->emailfreq<1 || cfg->emailfreq>3) {
-    printout(LOG_INFO,"internal error in printandmail(): cfg->emailfreq=%d\n",cfg->emailfreq);
-    return;
-  }
-  if (which<0 || which>9) {
-    printout(LOG_INFO,"internal error in printandmail(): which=%d\n",which);
-    return;
-  }
-  
-  // Return if a single warning mail has been sent.
-  if ((cfg->emailfreq==1) && 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 (cfg->emailfreq==2 && mail->logged && epoch<(mail->lastsent+day))
-    return;
-
-  // Return if less than 2^(logged-1) days have gone by
-  if (cfg->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) 
-  if (gethostname(hostname, 256))
-    sprintf(hostname,"Unknown host");
-  else
-    hostname[255]='\0';
-  if (getdomainname(domainname, 256))
-    sprintf(hostname,"Unknown domain");
-  else
-    domainname[255]='\0';
-  
-  // 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 (cfg->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 (cfg->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".
-  if (!executable)
-    executable="mail";
-    
-  // Export information in environment variables that will be useful
-  // for user scripts
-  setenv("SMARTD_MAILER", executable, 1);
-  setenv("SMARTD_DEVICE", cfg->name, 1);
-  setenv("SMARTD_DEVICETYPE", cfg->tryata?"ata":"scsi", 1);
-  setenv("SMARTD_MESSAGE", message, 1);
-  setenv("SMARTD_SUBJECT", subject, 1);
-  dateandtimezoneepoch(dates, mail->firstsent);
-  setenv("SMARTD_TFIRST", dates, 1);
-  snprintf(dates, 64,"%d", (int)mail->firstsent);
-  setenv("SMARTD_TFIRSTEPOCH", dates, 1);
-  setenv("SMARTD_FAILTYPE", whichfail[which], 1);
-  if (address)
-    setenv("SMARTD_ADDRESS", address, 1);
-
-  // now construct a command to send this as EMAIL
-  if (address)
-    snprintf(command, 2048, 
-             "$SMARTD_MAILER -s '%s' %s > /dev/null 2> /dev/null << \"ENDMAIL\"\n"
-             "This email was generated by the smartd daemon running on host:\n"
-             "%s\n"
-             "in the domain:\n"
-             "%s\n\n"
-             "The following warning/error was logged by the smartd daemon:\n"
-             "%s\n\n"
-             "For details see the SYSLOG (default: /var/log/messages) for host:\n"
-             "%s\n\n"
-             "%s%s%s"
-             "ENDMAIL\n",
-           subject, address, hostname, domainname, message, hostname, further, original, additional);
-  else
-    snprintf(command, 2048, "%s", executable);
-  
-  // tell SYSLOG what we are about to do...
-  printout(LOG_INFO,"%s %s to %s ...\n",
-           which?"Sending warning via ":"Executing test of", executable, address?address:"<nomailer>");
-
-  // issue the command to send mail or to run the user's executable
-  status=system(command);
-  
-  // now tell SYSLOG what happened.
-  if (status==-1){
-    printout(LOG_CRIT,"%s %s to %s failed (unable to fork new process)\n", 
-             which?"Warning via":"Test of", executable, address?address:"<nomailer>");
-  }
-  else {
-    int status8;
-    // check and report exit status of command
-#ifdef WEXITSTATUS
-    status8=WEXITSTATUS(status);
-#else
-    status8=(status>>8) & 0xff;
-#endif 
-    if (status8)  
-      printout(LOG_CRIT,"%s %s to %s failed (32-bit/8-bit exit status: %d/%d)\n", 
-               which?"Warning via":"Test of", executable, address?address:"<nomailer>", status, status8);
-    else
-      printout(LOG_INFO,"%s %s to %s successful\n",
-               which?"Warning via":"Test of", executable, address?address:"<nomailer>");
-  } 
-  // increment mail sent counter
-  mail->logged++;
-  
-  return;
-}
-
-// Printing function for watching ataprint commands, or losing them
-void pout(char *fmt, ...){
-  va_list ap;
-  // 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)
-    vprintf(fmt,ap);
-  // in debug==2 mode we print output from knowndrives.o functions
-  else if (debugmode==2 || con->reportataioctl || con->reportscsiioctl) {
-    openlog("smartd", LOG_PID, LOG_DAEMON);
-    vsyslog(LOG_INFO, fmt, ap);
-    closelog();
-  }
-  va_end(ap);
-  fflush(NULL);
-  return;
-}
-
-// tell user that we ignore HUP signals
-void huphandler(int sig){
-  printout(LOG_CRIT,"HUP ignored: smartd does NOT re-read /etc/smartd.conf.\n");
-  return;
-}
-
-// signal handler that tells users about signals that were caught
-void sighandler(int sig){
-    printout(LOG_CRIT,"smartd received signal %d: %s\n",
-             sig, strsignal(sig));
-    exit(EXIT_SIGNAL);
-}
-
-// remove the PID file
-void remove_pid_file(){
-  if (pid_file) {
-    if ( -1==unlink(pid_file) )
-      printout(LOG_INFO,"Can't unlink PID file %s (%s).\n", 
-	       pid_file, strerror(errno));
-    free(pid_file);
-  }
-  return;
-}
-
-// signal handler that prints goodbye message and removes pidfile
-void goodbye(){
-  printout(LOG_CRIT,"smartd is exiting\n");
-  remove_pid_file();
-  return;
-}
-
-// Forks new process, closes all file descriptors, redirects stdin,
-// stdout, stderr
-void daemon_init(){
-  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("/");
-  
-  return;
-}
-
-// create a PID file containing the current process id
-void write_pid_file() {
-  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", 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, pid);
-  }
-  return;
-}
-
-// Prints header identifying version of code and home
-void printhead(){
-  printout(LOG_INFO,"smartd version %d.%d-%d Copyright (C) 2002-3 Bruce Allen\n",
-           (int)RELEASE_MAJOR, (int)RELEASE_MINOR, (int)SMARTMONTOOLS_VERSION);
-  printout(LOG_INFO,"Home page is %s\n\n",PROJECTHOME);
-  return;
-}
-
-
-// prints help info for configuration file Directives
-void Directives() {
-  printout(LOG_INFO,"Configuration file (/etc/smartd.conf) Directives (after device name):\n");
-  printout(LOG_INFO,"  -d TYPE Set the device type to one of: ata, scsi\n");
-  printout(LOG_INFO,"  -T TYPE set the tolerance to one of: normal, permissive\n");
-  printout(LOG_INFO,"  -o VAL  Enable/disable automatic offline tests (on/off)\n");
-  printout(LOG_INFO,"  -S VAL  Enable/disable attribute autosave (on/off)\n");
-  printout(LOG_INFO,"  -H      Monitor SMART Health Status, report if failed\n");
-  printout(LOG_INFO,"  -l TYPE Monitor SMART log.  Type is one of: error, selftest\n");
-  printout(LOG_INFO,"  -f      Monitor 'Usage' Attributes, report failures\n");
-  printout(LOG_INFO,"  -m ADD  Send email warning to address ADD\n");
-  printout(LOG_INFO,"  -M TYPE Modify email warning behavior (see man page)\n");
-  printout(LOG_INFO,"  -p      Report changes in 'Prefailure' Attributes\n");
-  printout(LOG_INFO,"  -u      Report changes in 'Usage' Attributes\n");
-  printout(LOG_INFO,"  -t      Equivalent to -p and -u Directives\n");
-  printout(LOG_INFO,"  -r ID   Also report Raw values of Attribute ID with -p, -u or -t\n");
-  printout(LOG_INFO,"  -R ID   Track changes in Attribute ID Raw value with -p, -u or -t\n");
-  printout(LOG_INFO,"  -i ID   Ignore Attribute ID for -f Directive\n");
-  printout(LOG_INFO,"  -I ID   Ignore Attribute ID for -p, -u or -t Directive\n");
-  printout(LOG_INFO,"  -v N,ST Modifies labeling of Attribute N (see man page)  \n");
-  printout(LOG_INFO,"  -P TYPE Drive-specific presets: use, ignore, show, showall\n");
-  printout(LOG_INFO,"  -a      Default: equivalent to -H -f -t -l error -l selftest\n");
-  printout(LOG_INFO,"  -F TYPE Use firmware bug workaround. Type is one of: none, samsung\n");
-  printout(LOG_INFO,"   #      Comment: text after a hash sign is ignored\n");
-  printout(LOG_INFO,"   \\      Line continuation character\n");
-  printout(LOG_INFO,"Attribute ID is a decimal integer 1 <= ID <= 255\n");
-  printout(LOG_INFO,"SCSI devices: only -d, -m, and -M Directives allowed.\n");
-  printout(LOG_INFO,"Example: /dev/hda -a\n");
-return;
-}
-
-/* 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, --checkonce\n");
-  printout(LOG_INFO,"        Check all devices once, then exit\n\n");
-  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,"  -p NAME, --pidfile=NAME\n");
-  printout(LOG_INFO,"        Write PID file NAME\n\n");
-  printout(LOG_INFO,"  -r, --report=TYPE\n");
-  printout(LOG_INFO,"        Report transactions for one of: %s\n\n", getvalidarglist('r'));
-  printout(LOG_INFO,"  -V, --version, --license, --copyright\n");
-  printout(LOG_INFO,"        Print License, Copyright, and version information\n");
-#else
-  printout(LOG_INFO,"  -c      Check all devices once, then exit\n");
-  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,"  -p NAME Write PID file NAME\n");
-  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");
-  printout(LOG_INFO,"  -?      Same as -h\n");
-#endif
-}
-
-// returns negative if problem, else fd>=0
-static int opendevice(char *device, int flags)
-{
-  int fd;
- 
-  fd = open(device, flags);
-  if (fd < 0) {
-    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 (close(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
-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 atadevicescan2(atadevices_t *devices, cfgfile *cfg){
-  int fd;
-  struct hd_driveid drive;
-  char *device=cfg->name;
-  
-  // should we try to register this as an ATA device?
-  if (!(cfg->tryata))
-    return 1;
-  
-  // open the device
-  if ((fd=opendevice(device, O_RDONLY | O_NONBLOCK))<0)
-    // device open failed
-    return 1;
-  printout(LOG_INFO,"Device: %s, opened\n", device);
-  
-  // Get drive identity structure
-  if (ataReadHDIdentity (fd,&drive)){
-    // Unable to read Identity structure
-    printout(LOG_INFO,"Device: %s, unable to read Device Identity Structure\n",device);
-    close(fd);
-    return 2; 
-  }
-  
-  // pass user setings on to low-level ATA commands
-  con->fixfirmwarebug = cfg->fixfirmwarebug;
-
-  // Show if device in database, and use preset vendor attribute
-  // options unless user has requested otherwise.
-  if (!cfg->ignorepresets){
-
-    // do whatever applypresets decides to do
-    if (applypresets(&drive, cfg->attributedefs, con)<0)
-      printout(LOG_INFO, "Device: %s, not found in smartd database.\n", device);
-    else
-      printout(LOG_INFO, "Device: %s, found in smartd database.\n", device);
-
-    // then save the correct state of the flag (applypresets may have changed it)
-    cfg->fixfirmwarebug = con->fixfirmwarebug;
-  }
-  else
-    printout(LOG_INFO, "Device: %s, smartd database not searched (Directive: -P ignore).\n", device);
-
-  // 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", device);
-    if (!debugmode)
-      debugmode=2;
-    showpresets(&drive);
-    debugmode=savedebugmode;
-  }
-
-  if (!cfg->permissive && !ataSmartSupport(&drive)){
-    // SMART not supported
-    printout(LOG_INFO,"Device: %s, appears to lack SMART, use '-T permissive' Directive to try anyway.\n",device);
-    close(fd);
-    return 2; 
-  }
-  
-  if (ataEnableSmart(fd)){
-    // Enable SMART command has failed
-    printout(LOG_INFO,"Device: %s, could not enable SMART capability\n",device);
-    close(fd);
-    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",device);
-    else
-      printout(LOG_INFO,"Device: %s, disabled SMART Attribute Autosave.\n",device);
-  }
-
-  // or enable device attribute autosave
-  if (cfg->autosave==2){
-    if (ataEnableAutoSave(fd))
-      printout(LOG_INFO,"Device: %s, could not enable SMART Attribute Autosave.\n",device);
-    else
-      printout(LOG_INFO,"Device: %s, enabled SMART Attribute Autosave.\n",device);
-  }
-
-  // capability check: SMART status
-  if (cfg->smartcheck && ataSmartStatus2(fd)==-1){
-    printout(LOG_INFO,"Device: %s, not capable of SMART Health Status check\n",device);
-    cfg->smartcheck=0;
-  }
-  
-  // capability check: Read smart values and thresholds
-  if (cfg->usagefailed || cfg->prefail || cfg->usage || cfg->autoofflinetest) {
-    devices->smartval=(struct ata_smart_values *)calloc(1,sizeof(struct ata_smart_values));
-    devices->smartthres=(struct ata_smart_thresholds *)calloc(1,sizeof(struct ata_smart_thresholds));
-    
-    if (!devices->smartval || !devices->smartthres){
-      printout(LOG_CRIT,"Not enough memory to obtain SMART data\n");
-      exit(EXIT_NOMEM);
-    }
-    
-    if (ataReadSmartValues(fd,devices->smartval) ||
-        ataReadSmartThresholds (fd,devices->smartthres)){
-      printout(LOG_INFO,"Device: %s, Read SMART Values and/or Thresholds Failed\n",device);
-      free(devices->smartval);
-      free(devices->smartthres);
-
-      // make it easy to recognize that we've deallocated
-      devices->smartval=NULL;
-      devices->smartthres=NULL;
-      cfg->usagefailed=cfg->prefail=cfg->usage=0;
-    }
-  }
-
-  // disable automatic on-line testing
-  if (cfg->autoofflinetest==1){
-    if (devices->smartval && isSupportAutomaticTimer(devices->smartval) && !ataDisableAutoOffline(fd))
-      printout(LOG_INFO,"Device: %s, disabled SMART Automatic Offline Testing .\n",device);
-    else
-      printout(LOG_INFO,"Device: %s, could not disable SMART Automatic Offline Testing.\n",device);
-  }
-
-  // enable automatic on-line testing
-  if (cfg->autoofflinetest==2){
-    if (devices->smartval && isSupportAutomaticTimer(devices->smartval) && !ataDisableAutoOffline(fd))
-      printout(LOG_INFO,"Device: %s, enabled SMART Automatic Offline Testing.\n",device);
-    else
-      printout(LOG_INFO,"Device: %s, could not enable SMART Automatic Offline Testing.\n",device);
-  }
-
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int val;
-
-    // see if device supports Self-test logging.  Note that the
-    // following line is not a typo: Device supports self-test log if
-    // and only if it also supports error log.
-    if (!isSmartErrorLogCapable(devices->smartval)){
-      printout(LOG_INFO, "Device: %s, does not support SMART Self-test Log.\n", device);
-      cfg->selftest=0;
-      cfg->selflogcount=0;
-    }
-    else {
-      // get number of Self-test errors logged
-      val=selftesterrorcount(fd, device);
-      if (val>=0)
-	cfg->selflogcount=val;
-      else
-	cfg->selftest=0;
-    }
-  }
-  
-  // capability check: ATA error log
-  if (cfg->errorlog){
-    int val;
-
-    // see if device supports error logging
-    if (!isSmartErrorLogCapable(devices->smartval)){
-      printout(LOG_INFO, "Device: %s, does not support SMART Error Log.\n", device);
-      cfg->errorlog=0;
-      cfg->ataerrorcount=0;
-    }
-    else {
-      // get number of ATA errors logged
-      val=ataerrorcount(fd, device);
-      if (val>=0)
-	cfg->ataerrorcount=val;
-      else
-	cfg->errorlog=0;
-    }
-  }
-  
-  // If no tests available or selected, return
-  if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck || 
-        cfg->usagefailed || cfg->prefail || cfg->usage)) {
-    close(fd);
-    return 3;
-  }
-  
-  // Do we still have entries available?
-  if (numatadevices>=MAXATADEVICES){
-    printout(LOG_CRIT,"smartd has found more than MAXATADEVICES=%d ATA devices.\n"
-             "Recompile code from " PROJECTHOME " with larger MAXATADEVICES\n",(int)numatadevices);
-    exit(EXIT_CCONST);
-  }
-  
-  // register device
-  printout(LOG_INFO,"Device: %s, is SMART capable. Adding to \"monitor\" list.\n",device);
-  
-  // we were called from a routine that has global storage for the name.  Keep pointer.
-  devices->devicename=device;
-  devices->cfg=cfg;
-  
-  // record number of device, type of device, increment device count
-  cfg->tryscsi=0;
-  cfg->tryata=1;
-  cfg->atadevicenum=numatadevices;
-  cfg->scsidevicenum=-1;
-  numatadevices++;
-
-  // close file descriptor
-  closedevice(fd, device);
-  return 0;
-}
-
-
-static int scsidevicescan(scsidevices_t *devices, cfgfile *cfg,
-                          int scandirective)
-{
-    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?
-    if (! cfg->tryscsi)
-        return 1;
-    // open the device
-    if ((fd = opendevice(device, O_RDWR | O_NONBLOCK)) < 0) {
-        if (scandirective)
-            return 1;
-        printout(LOG_WARNING, "Device: %s, skip\n", device);
-        return 0; // device open failed
-    }
-    printout(LOG_INFO,"Device: %s, opened\n", device);
-  
-    // check that it's ready for commands. IE stores its stuff on the media.
-    if ((err = scsiTestUnitReady(fd))) {
-        if (1 == err) {
-            printout(LOG_WARNING, "Device: %s, NOT READY (media absent, spun "
-                     "down); skip\n", device);
-            close(fd);
-            return scandirective ? 1 : 0;
-        } else {
-           printout(LOG_ERR, "Device: %s, failed Test Unit Ready [err=%d]\n", 
-                    device, err);
-           close(fd);
-           return 2;
-        }
-    }
-  
-    if ((err = scsiFetchIECmpage(fd, &iec))) {
-        printout(LOG_WARNING, "Device: %s, Fetch of IEC (SMART) mode page "
-                 "failed, err=%d, skip device\n", device, err);
-        return 0;
-    }
-    if (! scsi_IsExceptionControlEnabled(&iec)) {
-        printout(LOG_WARNING, "Device: %s, IE (SMART) not enabled, "
-                 "skip device\n", device);
-        close(fd);
-        return 0;
-    }
-
-    // Device exists, and does SMART.  Add to list
-    if (numscsidevices >= MAXSCSIDEVICES) {
-        printout(LOG_ERR, "smartd has found more than MAXSCSIDEVICES=%d "
-                 "SCSI devices.\n" "Recompile code from " PROJECTHOME 
-                 " with larger MAXSCSIDEVICES\n", (int)numscsidevices);
-        return 0;
-    }
-
-    // now we can proceed to register the device
-    printout(LOG_INFO, "Device: %s, is SMART capable. Adding "
-             "to \"monitor\" list.\n",device);
- 
-    // since device points to global memory, just keep that address
-    devices->devicename = device;
-    devices->cfg = cfg;
-
-    // Flag that certain log pages are supported (information may be
-    // available from other sources).
-    if (0 == scsiLogSense(fd, SUPPORTED_LOG_PAGES, tBuf, sizeof(tBuf))) {
-        for (k = 4; k < tBuf[3] + LOGPAGEHDRSIZE; ++k) {
-            switch (tBuf[k]) { 
-                case TEMPERATURE_PAGE:
-                    devices->TempPageSupported = 1;
-                    break;
-                case IE_LOG_PAGE:
-                    devices->SmartPageSupported = 1;
-                    break;
-                default:
-                    break;
-            }
-        }   
-    }
-
-    // record number of device, type of device, increment device count
-    cfg->tryata = 0;
-    cfg->tryscsi = 1;
-    cfg->scsidevicenum = numscsidevices;
-    cfg->atadevicenum = -1;
-    ++numscsidevices;
-
-    // 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  ataCompareSmartValues(changedattribute_t *delta,
-                            struct ata_smart_values *new,
-                            struct ata_smart_values *old,
-                            struct ata_smart_thresholds *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=now->status.flag.prefailure;
-  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 isattoff(unsigned char attr,unsigned char *data, int set){
-  // locate correct attribute
-  int loc=attr>>3;
-  int bit=attr & 0x07;
-  unsigned char mask=0x01<<bit;
-
-  // attribute zero is always OFF
-  if (!attr)
-    return 1;
-
-  if (!set)
-    return (data[loc] & mask);
-  
-  data[loc]|=mask;
-  // return value when setting makes no sense!
-  return 0;
-}
-
-
-int ataCheckDevice(atadevices_t *drive){
-  int fd,i;
-  char *name=drive->devicename;
-  cfgfile *cfg=drive->cfg;
-  
-  // fix firmware bug if requested
-  con->fixfirmwarebug=cfg->fixfirmwarebug;
-
-  // If user has asked, test the email warning system
-  if (cfg->emailtest){
-    printandmail(cfg, 0, LOG_CRIT, "TEST EMAIL from smartd for device: %s", drive->devicename);
-  }
-
-  // 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, O_RDONLY | O_NONBLOCK))<0){
-    printandmail(cfg, 9, LOG_CRIT, "Device: %s, unable to open device", name);
-    return 1;
-  }
-
-  // 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);
-      printandmail(cfg, 5, LOG_CRIT, "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);
-      printandmail(cfg, 1, LOG_CRIT, "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){
-    struct ata_smart_values     curval;
-    struct ata_smart_thresholds *thresh=drive->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);
-      printandmail(cfg, 6, LOG_CRIT, "Device: %s, failed to read SMART Attribute Data", name);
-    }
-    else {  
-      // 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 (!isattoff(att, cfg->monitorattflags, 0)){
-            char attname[64], *loc=attname;
-            
-            // get attribute name & skip white space
-            ataPrintSmartAttribName(loc, att, cfg->attributedefs[att]);
-            while (*loc && *loc==' ') loc++;
-            
-            // warning message
-            printout(LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc);
-            printandmail(cfg, 2, LOG_CRIT, "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) && ataCompareSmartValues(&delta, &curval, drive->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 && !isattoff(id, cfg->monitorattflags+96, 0))
-            continue;
-
-          // are we tracking this attribute?
-          if (!isattoff(id, cfg->monitorattflags+32, 0)){
-            char newrawstring[64], oldrawstring[64], attname[64], *loc=attname;
-
-            // get attribute name, skip spaces
-            ataPrintSmartAttribName(loc, id, cfg->attributedefs[id]);
-            while (*loc && *loc==' ') loc++;
-            
-            // has the user asked for us to print raw values?
-            if (isattoff(id, cfg->monitorattflags+64, 0)) {
-              // 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, drive->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
-      *drive->smartval=curval;
-    } 
-  }
-  
-  // check if number of selftest errors has increased (note: may also DECREASE)
-  if (cfg->selftest){
-    int new;
-    unsigned char old=cfg->selflogcount;
-    
-    // new self test error count
-    new=selftesterrorcount(fd, name);
-    
-    // did command fail?
-    if (new<0)
-      printandmail(cfg, 8, LOG_CRIT, "Device: %s, Read SMART Self Test Log Failed", name);
-    
-    // hsa self-test error count increased?
-    if (new>old){
-      printout(LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d\n",
-               name, (int)old, new);
-      printandmail(cfg, 3, LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d",
-                   name, (int)old, new);
-    }
-
-    // Needed since self-test error count may  DECREASE
-    if (new>=0)
-      cfg->selflogcount=new;
-  }
-
-  
-  // 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)
-      printandmail(cfg, 7, LOG_CRIT, "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);
-      printandmail(cfg, 4, LOG_CRIT, "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;
-  }
-  
-  // Don't leave device open -- the OS/user may want to access it
-  // before the next smartd cycle!
-  closedevice(fd, name);
-  return 0;
-}
-
-
-int scsiCheckDevice(scsidevices_t *drive)
-{
-    UINT8 asc, ascq;
-    UINT8 currenttemp;
-    int fd;
-    cfgfile *cfg=drive->cfg;
-    char *name=drive->devicename;
-    const char *cp;
-
-    // If the user has asked for it, test the email warning system
-    if (cfg->emailtest)
-        printandmail(cfg, 0, LOG_CRIT, 
-                     "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, O_RDWR | O_NONBLOCK))<0) {
-        printandmail(cfg, 9, LOG_CRIT, "Device: %s, unable to open device",
-                      name);
-        return 1;
-    }
-    currenttemp = 0;
-    asc = 0;
-    ascq = 0;
-    if (scsiCheckIE(fd, drive->SmartPageSupported, drive->TempPageSupported,
-                    &asc, &ascq, &currenttemp)) {
-        printout(LOG_INFO, "Device: %s, failed to read SMART values\n", name);
-        printandmail(cfg, 6, LOG_CRIT, 
-                     "Device: %s, failed to read SMART values", name);
-    }
-    if (asc > 0) {
-        cp = scsiGetIEString(asc, ascq);
-        if (cp) {
-            printout(LOG_CRIT, "Device: %s, SMART Failure: %s\n", name, cp);
-            printandmail(cfg, 1, LOG_CRIT, "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);  
-  
-    // Seems to completely ignore what capabilities were found on the
-    // device when scanned
-    if (currenttemp) {
-        if (255 == currenttemp) /* this means temperature unavailable */
-            currenttemp = 0;    /* less likely to worry people */
-        if ((currenttemp != drive->Temperature) && (drive->Temperature))
-            printout(LOG_INFO, "Device: %s, Temperature changed %d degrees "
-                     "to %d degrees since last reading\n", name, 
-                     (int)(currenttemp - drive->Temperature), 
-                     (int)currenttemp);
-        drive->Temperature = currenttemp;
-    }
-    closedevice(fd, name);
-    return 0;
-}
-
-void CheckDevices(atadevices_t *atadevices, scsidevices_t *scsidevices){
-  static int firstpass=1;
-  int i;
-
-  // Infinite loop, which checks devices
-  printout(LOG_INFO,"Started monitoring %d ATA and %d SCSI devices\n",numatadevices,numscsidevices);
-  while (1){
-    for (i=0; i<numatadevices; i++) 
-      ataCheckDevice(atadevices+i);
-    
-    for (i=0; i<numscsidevices; i++)
-      scsiCheckDevice(scsidevices+i);
-
-    // This option is primarily for distribution developers who want
-    // an automated procedure for seeing if smartd works correctly.
-    // Use the -c/--checkonce option and verify zero exit status.
-    if (checkonce) {
-      printout(LOG_INFO,"Started with '-c' option. All devices sucessfully checked once.\n");
-      exit(0);
-    }
-
-    // Initialization setup
-    if (firstpass){
-      
-      // If in background as a daemon, fork and close file descriptors
-      if (!debugmode)
-	daemon_init();
-      
-      // install goobye message and remove pidfile handler
-      atexit(goodbye);
-      
-      // write PID file only after installing exit handler
-      if (!debugmode)
-	write_pid_file();
-      
-      // install signal handlers
-      if (signal(SIGINT, sighandler)==SIG_IGN)
-	signal(SIGINT, SIG_IGN);
-      if (signal(SIGTERM, sighandler)==SIG_IGN)
-	signal(SIGTERM, SIG_IGN);
-      if (signal(SIGQUIT, sighandler)==SIG_IGN)
-	signal(SIGQUIT, SIG_IGN);
-      if (signal(SIGHUP, huphandler)==SIG_IGN)
-	signal(SIGHUP, SIG_IGN);
-      if (signal(SIGUSR1, sleephandler)==SIG_IGN)
-	signal(SIGUSR1, SIG_IGN);
-            
-      // done with initialization setup
-      firstpass=0;
-    }
-
-    // Unix Gurus: I know that this can be done better.  Please tell
-    // me how -- use email address for Bruce Allen at the top of this
-    // file. Search for "sleeptime" to see what I am doing.  I think
-    // that when done "right" I should not have to call sleep once per
-    // second, but just set an alarm for checktime in the future, and
-    // then have an additional alarm sent if the user does SIGUSR1,
-    // which arrives first to cause another device check.  Please help
-    // me out.
-    
-    // Sleep until next check. Note that since sleeptime can be set to
-    // zero by an EXTERNAL signal SIGUSR1, it's possible for sleeptime
-    // to be negative.  Don't use while (sleeptime)!
-    sleeptime=checktime;
-    while (sleeptime-->0)
-      sleep(1); 
-  }
-}
-
-// Print out a list of valid arguments for the Directive d
-void printoutvaliddirectiveargs(int priority, char d) {
-  char *s;
-
-  switch (d) {
-  case 'd':
-    printout(priority, "ata, scsi");
-    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");
-      break;
-    }
-    printout(priority, "\n%s\n", s);
-    free(s);
-    break;
-  case 'P':
-    printout(priority, "use, ignore, show, showall");
-    break;
-  case 'F':
-    printout(priority, "none, samsung");
-    break;
-  }
-}
-
-char copyleftstring[]=
-"smartd comes with ABSOLUTELY NO WARRANTY. This\n"
-"is free software, and you are welcome to redistribute it\n"
-"under the terms of the GNU General Public License Version 2.\n"
-"See http://www.gnu.org for further details.\n\n";
-
-cfgfile config[MAXENTRIES];
-
-// exits with an error message, or returns integer value of token
-int inttoken(char *arg, char *name, char *token, int lineno, char *configfile, int min, int max){
-  char *endptr;
-  int val;
-  
-  // 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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-  
-  // 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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-
-  // all is well; return value
-  return val;
-}
-
-// This function returns non-zero if it has correctly parsed a token,
-// else zero if it has failed to parse a token.  Or it exits with a
-// Directive message if there is a token-parsing problem.
-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;
-
-  // 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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-  
-  // let's parse the token and swallow its argument
-  switch (sym=token[1]) {
-    int val;
-
-  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.
-      ;
-    } 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->tryata  = 1;
-      cfg->tryscsi = 0;
-    } else if (!strcmp(arg, "scsi")) {
-      cfg->tryscsi = 1;
-      cfg->tryata  = 0;
-    } else {
-      badarg = 1;
-    }
-    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 {
-      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':
-    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 'S':
-    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 'M':
-    // email warning option
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "once")) {
-      cfg->emailfreq = 1;
-    } else if (!strcmp(arg, "daily")) {
-      cfg->emailfreq = 2;
-    } else if (!strcmp(arg, "diminishing")) {
-      cfg->emailfreq = 3;
-    } else if (!strcmp(arg, "test")) {
-      cfg->emailtest = 1;
-    } else if (!strcmp(arg, "exec")) {
-      // Get the next argument (the command line)
-      if ((arg = strtok(NULL, delim)) == NULL) {
-        printout(LOG_CRIT, "File %s line %d (drive %s): Directive %s 'exec' argument must be followed by executable path.\n",
-                 CONFIGFILE, lineno, name, token);
-        Directives();
-        exit(EXIT_BADCONF);
-      }
-      // Free the last cmd line given if any
-      if (cfg->emailcmdline) {
-        printout(LOG_INFO, "File %s line %d (drive %s): found multiple -M exec Directives on line - ignoring all but the last\n", CONFIGFILE, lineno, name);
-        free(cfg->emailcmdline);
-      }
-      // Attempt to copy the argument
-      if (!(cfg->emailcmdline = strdup(arg))) {
-        printout(LOG_CRIT, "File %s line %d (drive %s): no free memory for command line argument to exec: %s\n",
-          CONFIGFILE, lineno, name, arg);
-          Directives();
-          exit(EXIT_NOMEM);
-      }
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'i':
-    // ignore failure of usage attribute
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags,1);
-    break;
-  case 'I':
-    // ignore attribute for tracking purposes
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags+32,1);
-    break;
-  case 'r':
-    // print raw value when tracking
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags+64,1);
-    break;
-  case 'R':
-    // track changes in raw value (forces printing of raw value)
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags+64,1);
-    isattoff(val,cfg->monitorattflags+96,1);
-    break;
-  case 'm':
-    // send email to address that follows
-    if ((arg = strtok(NULL,delim)) == NULL) {
-      printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s needs email address(es)\n",
-               CONFIGFILE, lineno, name, token);
-      Directives();
-      exit(EXIT_BADCONF);
-    }
-    if (!(cfg->address=strdup(arg))){
-      printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s: no free memory for email address(es) %s\n",
-               CONFIGFILE, lineno, name, token, arg);
-      Directives();
-      exit(EXIT_NOMEM);
-    }
-    break;
-  case 'v':
-    // non-default vendor-specific attribute meaning
-    if ((arg=strtok(NULL,delim)) == NULL) {
-      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)) == NULL) {
-      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")) {
-      debugmode = TRUE;
-      showallpresets();
-      exit(0);
-    } 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();
-    exit(EXIT_BADCONF);
-  }
-  if (missingarg) {
-    printout(LOG_CRIT, "File %s line %d (drive %s): Missing argument to Directive: %s\n", CONFIGFILE, lineno, name, token);
-  }
-  if (badarg) {
-    printout(LOG_CRIT, "File %s line %d (drive %s): Invalid argument: %s\n", CONFIGFILE, lineno, name, arg);
-  }
-  if (missingarg || badarg) {
-      printout(LOG_CRIT, "Valid arguments to %s Directive are: ", token);
-      printoutvaliddirectiveargs(LOG_CRIT, sym);
-      printout(LOG_CRIT, "\n");
-      Directives();
-      exit(EXIT_BADCONF);
-  }
-  return 1;
-}
-
-int parseconfigline(int entry, int lineno,char *line){
-  char *token,*copy;
-  char *name;
-  char *delim = " \n\t";
-  cfgfile *cfg;
-  static int numtokens=0;
-  int devscan=0;
-
-  if (!(copy=strdup(line))){
-    printout(LOG_INFO,"No memory to parse file: %s line %d, %s\n", CONFIGFILE, lineno, strerror(errno));
-    exit(EXIT_NOMEM);
-  }
-  
-  // get first token -- device name
-  if (!(name=strtok(copy,delim)) || *name=='#') {
-    free(copy);
-    return 0;
-  }
-
-  // Have we detected the DEVICESCAN directive?
-  if (!strcmp(SCANDIRECTIVE,name)){
-    devscan=1;
-    if (numtokens) {
-      printout(LOG_INFO,"Scan Directive %s must be the first entry in %s\n",name,CONFIGFILE);
-      exit(EXIT_BADCONF);
-    }
-    else
-      printout(LOG_INFO,"Scan Directive %s found in %s. Will scan for devices.\n",name,CONFIGFILE);
-  }
-  numtokens++;
-
-  // Is there space for another entry?
-  if (entry>=MAXENTRIES){
-    printout(LOG_CRIT,"Error: configuration file %s can have no more than MAXENTRIES=%d entries\n",
-             CONFIGFILE,MAXENTRIES);
-    exit(EXIT_CCONST);
-  }
-
-  // We've got a legit entry, clear structure
-  cfg=config+entry;
-  memset(cfg,0,sizeof(*config));
-
-  // Save info to process memory for after forking 32 bytes contains 1
-  // bit per possible attribute ID.  See isattoff()
-  cfg->name=strdup(name);
-  if (!devscan){
-    cfg->monitorattflags=(unsigned char *)calloc(NMONITOR*32,1);
-    cfg->attributedefs=(unsigned char *)calloc(256,1);
-  }
-
-  // check that all memory allocations were sucessful
-  if (!cfg->name || (!devscan && (!cfg->monitorattflags || !cfg->attributedefs))) {
-    printout(LOG_INFO,"No memory to store file: %s line %d, %s\n", CONFIGFILE, lineno, strerror(errno));
-    exit(EXIT_NOMEM);
-  }
-
-  // Store line number, and by default check for both device types.
-  cfg->lineno=lineno;
-  cfg->tryscsi=1;
-  cfg->tryata=1;
-  
-  // Try and recognize if a IDE or SCSI device.  These can be
-  // overwritten by configuration file directives.
-  if (GUESS_DEVTYPE_ATA == guess_linux_device_type(name))
-    cfg->tryscsi=0;
-  else if (GUESS_DEVTYPE_SCSI == guess_linux_device_type(name))
-    cfg->tryata=0;
-  /* in "don't know" case leave both tryata and tryscsi set */
-  
-  // parse tokens one at a time from the file.  This line actually
-  // parses ALL the tokens.
-  while ((token=strtok(NULL,delim)) && parsetoken(token,cfg)){
-#if 0
-    printout(LOG_INFO,"Parsed token %s\n",token);
-#endif
-  }
-
-  // If no ATA monitoring directives are set, then set all of them.
-  if (cfg->tryata && !(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->address && (cfg->emailcmdline || cfg->emailfreq || cfg->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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-  
-  // has the user has set <nomailer>?
-  if (cfg->address && !strcmp(cfg->address,"<nomailer>")){
-    // check that -M exec is also set
-    if (!cfg->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);
-      Directives();
-      exit(EXIT_BADCONF);
-    }
-    // now free memory.  From here on the sign of <nomailer> is
-    // address==NULL and cfg->emailcmdline!=NULL
-    free(cfg->address);
-    cfg->address=NULL;
-  }
-
-  // set cfg->emailfreq to 1 (once) if user hasn't set it
-  if (!cfg->emailfreq)
-    cfg->emailfreq = 1;
-
-  entry++;
-  free(copy);
-
-  // Return:
-  if (devscan)
-    return -1;
-  else
-    return 1;
-}
-
-// returns number of entries in config file, or 0 if no config file
-// exists.  A config file with zero entries will cause an error
-// message and an exit.  Returns -1 if it found a SCANDEVICE directive
-// in the config file.
-int parseconfigfile(){
-  FILE *fp;
-  int entry=0,lineno=1,cont=0,contlineno=0;
-  char line[MAXLINELEN+2];
-  char fullline[MAXCONTLINE+1];
-
-  // Open config file, if it exists
-  fp=fopen(CONFIGFILE,"r");
-  if (fp==NULL && errno!=ENOENT){
-    // file exists but we can't read it
-    printout(LOG_CRIT,"%s: Unable to open configuration file %s\n",
-             strerror(errno),CONFIGFILE);
-    exit(EXIT_BADCONF);
-  }
-  
-  // No config file
-  if (fp==NULL)
-    return 0;
-  
-  // configuration file exists
-  printout(LOG_INFO,"Using 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,lineno,fullline);
-        // See if we found a SCANDEVICE directive
-        if (scandevice<0)
-          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 %d characters.\n",
-               (int)contlineno,CONFIGFILE,warn,(int)MAXLINELEN);
-      exit(EXIT_CCONST);
-    }
-
-    // Ignore anything after comment symbol
-    if ((comment=index(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 %d characters.\n",
-               lineno, (int)contlineno, CONFIGFILE, (int)MAXCONTLINE);
-      exit(EXIT_CCONST);
-    }
-    
-    // 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=rindex(line,'\\')) && !strtok(lastslash+1," \n\t")){
-      *(fullline+(cont-len)+(lastslash-line))=' ';
-      continue;
-    }
-
-    // Not a continuation line. Parse it
-    scandevice=parseconfigline(entry,lineno,fullline);
-
-    // did we find a scandevice directive?
-    if (scandevice<0)
-      return -1;
-
-    entry+=scandevice;
-    lineno++;
-    cont=0;
-  }
-  fclose(fp);
-  if (entry)
-    return entry;
-  
-  printout(LOG_CRIT,"Configuration file %s contains no devices (like /dev/hda)\n",CONFIGFILE);
-  exit(EXIT_BADCONF);
-}
-
-// Prints copyright, license and version information
-void PrintCopyleft(void){
-  char out[CVSMAXLEN];
-  debugmode=1;
-  printhead();
-  printout(LOG_INFO,copyleftstring);
-  printout(LOG_INFO,"CVS version IDs of files used to build this code are:\n");
-  printone(out,atacmds_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,ataprint_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,knowndrives_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,scsicmds_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,smartd_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,utility_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-
-}
-
-/* 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 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 'p':
-    return "<FILE_NAME>";
-  case 'i':
-    return "<INTEGER_SECONDS>";
-  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) {
-  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 = "cdDi:p:r:Vh?";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update getvalidarglist() if you edit longopts
-  struct option longopts[] = {
-    { "checkonce",      no_argument,       0, 'c' },
-    { "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' },
-    { "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:
-#ifdef HAVE_GETOPT_LONG
-  while (-1 != (optchar = getopt_long(argc, argv, shortopts, longopts, NULL))){
-#else
-  while (-1 != (optchar = getopt(argc, argv, shortopts))){
-#endif
-    switch(optchar) {
-    case 'c':
-      checkonce = TRUE;
-      debugmode = TRUE;
-      break;
-    case 'd':
-      debugmode = TRUE;
-      break;
-    case 'D':
-      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':
-      {
-        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, "Can't allocate memory to copy argument to"
-                             " -r option - exiting\n");
-          exit(EXIT_NOMEM);
-        }
-        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 'p':
-      if( -1 == asprintf(&pid_file, "%s", optarg)) {
-	printout(LOG_CRIT, "Can't allocate memory for pid file name %s - exiting.\n", optarg);
-	pid_file = NULL;
-	exit(EXIT_NOMEM);
-      }
-      break;
-    case 'V':
-      PrintCopyleft();
-      exit(0);
-      break;
-    case '?':
-    case 'h':
-    default:
-      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);
-          printvalidarglistmessage(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);
-          printvalidarglistmessage(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);
-      printvalidarglistmessage(optchar);
-      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) {
-    printout(LOG_INFO, "warning: pid file %s not written in debug mode\n", pid_file);
-    free(pid_file);
-    pid_file = NULL;
-  }
-  
-  // print header
-  printhead();
-  
-  return;
-}
-  
-// Function we call if no configuration file was found or if the
-// DEVICESCAN Directive was found.  It makes entries for /dev/hd[a-l]
-// and /dev/sd[a-z].
-int makeconfigentries(int num, char *name, int isata, int start, int scandirective){
-  int i;
-  
-  // check that we still have space for entries
-  if (MAXENTRIES<(start+num)){
-    printout(LOG_CRIT,"Error: simulated config file can have no more than %d entries\n",(int)MAXENTRIES);
-    exit(EXIT_CCONST);
-  }
-  
-  // loop over the number of entries that we should create
-  for(i=0; i<num; i++){
-    cfgfile *cfg=config+start+i;
-    
-    // If user has given the scan directive, copy config files entries
-    if (scandirective){
-      memcpy(cfg, config, sizeof(*cfg));
-    }
-    else {
-      // no config file was used: all structure entries need to be set
-      memset(cfg,0,sizeof(*cfg));
-      
-      // enable all possible tests
-      cfg->smartcheck=1;
-      cfg->prefail=1;
-      cfg->usagefailed=1;
-      cfg->usage=1;
-      cfg->selftest=1;
-      cfg->errorlog=1;
-      
-      // lineno==0 is our clue that the device was not found in a
-      // config file!
-      cfg->lineno=0;    
-    }
-    
-    // select if it's a SCSI or ATA device
-    cfg->tryata=isata;
-    cfg->tryscsi=!isata;
-    
-    // put in the device name
-    cfg->name=strdup(name);
-    cfg->monitorattflags=(unsigned char *)calloc(NMONITOR*32,1);
-    cfg->attributedefs=(unsigned char *)calloc(256,1);
-    if (!cfg->name || !cfg->monitorattflags || !cfg->attributedefs) {
-      printout(LOG_INFO,"No memory for %d'th device after %s, %s\n", i, name, strerror(errno));
-      exit(EXIT_NOMEM);
-    }
-    
-    // increment final character of the name
-    cfg->name[strlen(name)-1]+=i;
-  }
-  return i;
-}
-
-void cantregister(char *name, char *type, int line, int scandirective){
-  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;
-}
- 
- 
-/* Main Program */
-int main (int argc, char **argv){
-  atadevices_t atadevices[MAXATADEVICES], *atadevicesptr=atadevices;
-  scsidevices_t scsidevices[MAXSCSIDEVICES], *scsidevicesptr=scsidevices;
-  int i, entries, scandirective=0, scanning=0;
-  smartmonctrl control;
-  
-  // initialize global communications variables
-  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->quietmode=0;
-  con->veryquietmode=debugmode?0:1;
-  con->checksumfail=0;
-
-  // look in configuration file CONFIGFILE (normally /etc/smartd.conf)
-  entries=parseconfigfile();
-  
-  // if SCANDEVICE used or there was no /etc/smartd.conf config file,
-  // then create needed entries for scanning
-  if (entries<=0){
-    int doscsi, doata;
-
-    scanning=1;
-
-    // Was SCANDEVICE Directive given?
-    scandirective=entries;
-    if (scandirective){
-      printout(LOG_INFO,"smartd: Scanning for devices.\n");
-      // free up storage used for SCANDIRECTIVE string
-      free(config->name);
-      config->name=NULL;
-    }
-    else {
-      // No config file given, so scan for both ATA and SCSI devices
-      printout(LOG_INFO,"smartd: file %s not found. Searching for ATA & SCSI devices.\n",CONFIGFILE);
-      config->tryata=1;
-      config->tryscsi=1;
-    }
-
-    // initialize total number of entries to seach for
-    entries=0;
-    doata=config->tryata;
-    doscsi=config->tryscsi;
-
-    // make list of ATA devices to search for
-    if (doata)
-      entries+=makeconfigentries(MAXATADEVICES,  "/dev/hda", 1, entries, scandirective);
-    // make list of SCSI devices to search for
-    if (doscsi)
-      entries+=makeconfigentries(MAXSCSIDEVICES, "/dev/sda", 0, entries, scandirective);
-  }
-
-  // Register entries
-  for (i=0;i<entries;i++){
-    int notregistered=1;
-    
-    // register ATA devices
-    if (config[i].tryata){
-      if (atadevicescan2(atadevicesptr+numatadevices, config+i))
-	cantregister(config[i].name, "ATA", config[i].lineno, scandirective);
-      else
-	notregistered=0;
-    }
-    
-    // then register SCSI devices
-    if (config[i].tryscsi){
-      if (scsidevicescan(scsidevicesptr+numscsidevices, config+i, 
-                         scandirective))
-	cantregister(config[i].name, "SCSI", config[i].lineno, scandirective);
-      else
-	notregistered=0;
-    }
-    
-    // if device explictly listed and we can't register it, then exit
-    if (notregistered && !scanning){
-      printout(LOG_CRIT, "Unable to register device %s - exiting.\n", config[i].name);
-      exit(EXIT_BADDEV);
-    }
-  } // done registering entries
-
-  // If there are no devices to monitor, then exit
-  if (!numatadevices && !numscsidevices){
-    printout(LOG_INFO,"Unable to monitor any SMART enabled ATA or SCSI devices.\n");
-    exit(EXIT_BADDEV);
-  }
-
-  // Now start an infinite loop that checks all devices
-  CheckDevices(atadevicesptr, scsidevicesptr); 
-  return 0;
-}
-
diff --git a/sm5/smartd.conf b/sm5/smartd.conf
deleted file mode 100644
index 19a3a16d2..000000000
--- a/sm5/smartd.conf
+++ /dev/null
@@ -1,65 +0,0 @@
-# /etc/smartd.conf
-
-# Sample configuration file for smartd.  See man 5 smartd.conf.
-# Home page is: http://smartmontools.sourceforge.net
-
-# 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
-/dev/hda -a
-
-# 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@yoyodyne.com
-
-# First two SCSI disks.  This will monitor everything that smartd can
-# monitor.
-/dev/sda -d scsi
-/dev/sdb -d scsi
-
-# HERE IS A LIST OF DIRECTIVES FOR THIS CONFIGURATION FILE
-#   -d TYPE Set the device type to one of: ata, scsi
-#   -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)
-#   -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)
-#   -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
-#   -v N,ST Modifies labeling of Attribute N (see man page)
-#   -a      Default: equivalent to -H -f -t -l error -l selftest
-#   -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
-# 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 b/sm5/smartd.conf.5
deleted file mode 100644
index 629d6c35e..000000000
--- a/sm5/smartd.conf.5
+++ /dev/null
@@ -1,867 +0,0 @@
-\# Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-\# 
-\# $Id: smartd.conf.5,v 1.47 2003/04/23 13:19:40 guidog 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  "$Date: 2003/04/23 13:19:40 $" "smartmontools-5.1"
-.SH NAME
-smartd.conf \- SMART Disk Monitoring Daemon Configuration File
-
-.SH DESCRIPTION
-.B /etc/smartd.conf
-is the configuration file for the
-.B smartd
-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.
-
-Note that
-.B smartd
-only reads the configuration file at start-up: changes to the
-configuration file take effect only after the
-.B smartd
-daemon is restarted.  If you send a HUP signal to
-.B smartd
-it will log a polite message saying that it ignores this signal and
-that it has
-.I not
-re-read the configuration file.
-
-\# DO NOT MODIFY THIS OR THE FOLLOWING TWO LINES. WHAT FOLLOWS
-\# IS AUTOMATICALLY INCLUDED FROM THE FILE smartd.8
-\# STARTINCLUDE
-
-.SH CONFIGURATION FILE /etc/smartd.conf
-In the absence of a configuration file,
-.B smartd 
-will try to open the 12 ATA devices 
-.B /dev/hd[a-l] 
-and the 26 SCSI devices
-.B /dev/sd[a-z]. 
-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
-.B smartd,
-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
-There should be one device listed per line, although you may have
-lines that are entirely comments or white space.
-
-Any text following a hash sign (#) and up to the end of the line is
-taken to be a comment, and ignored.
-
-Lines may be continued by using a backslash (\(rs) as the last
-non-whitespace or non-comment item on a 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
-.B # ATA disks and two SCSI disks.
-.B #
-.nf
-.B # First ATA disk on each of two interfaces:
-.B #
-.B \ \ /dev/hda -a -m admin@yoyodyne.com,root@localhost 
-.B \ \ /dev/hdc -a -I 194 -I 5 -i 12
-.B #
-.nf
-.B # SCSI disks.  Send a TEST warning email to admin on
-.B # startup.
-.B #
-.B \ \ /dev/sda
-.B \ \ /dev/sdc -m admin@yoyodyne.com -M test
-.B #
-.nf
-.B # Strange device.  It's SCSI:
-.B #
-.B \ \ /dev/weird -d scsi
-.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\ \(rs
-.B \ \ \ \ \ \ \ \ \ \ \ -l\ selftest\ \(rs
-.B \ \ \ \ \ \ \ \ \ \ \ -t\ \(rs\ \ \ \ \ \ # Attributes not tracked:
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 194\ \(rs\ \ # temperature
-.B \ \ \ \ \ \ \ \ \ \ \ -I\ 231\ \(rs\ \ # 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
-.B smartd
-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 
-.B smartd.
-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 only implemented level: roughly equivalent
-to using the '\-H' option for an ATA disk.  So with the exception of '\-d', '\-m', 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, or if the SCSI inquiry about disk status fails.
-
-.TP
-.B \-d TYPE
-Specifies the type of the device.  This will prevent
-.B smartd
-from issuing SCSI commands to an ATA device and vice versa.  The valid
-arguments to this Directive are \fIata\fP and \fIscsi\fP.
-
-In the absence of this Directive,
-.B smartd
-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.  If
-.B smartd
-can't guess from this sixth character, then it will simply try to
-access the device using first ATA and then SCSI ioctl()s.
-.TP
-.B \-T TYPE
-Specifies how tolerant
-.B smartd
-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.
-
-[Please see the
-.B smartctl \-T
-command-line option.]
-.TP
-.B \-o VALUE
-Enables or disables SMART Automatic Offline Testing when
-.B smartd
-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.
-[Please see the
-.B smartctl \-o
-command-line option.]
-.TP
-.B \-S VALUE
-Enables or disables Attribute Autosave when
-.B smartd
-starts up and has no further effect.  The valid arguments to this
-Directive are \fIon\fP and \fIoff\fP.  [Please see the
-.B smartctl \-S
-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 priority
-.B '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 that the number of ATA errors reported in the ATA Error Log has
-increased since the last check.
-
-.I selftest
-\- report if that the number of errors reported in the SMART Self-Test Log
-has increased since the last check.  Note that such errors will
-.B only
-be logged if you run self-tests on the disk (and it fails the tests!).
-[Self-Tests can be run by using the
-.B '\-t\ short'
-and
-.B '\-t\ long'
-options of
-.B smartctl
-and the results of the testing can be observed using the
-.B smartctl '\-l\ selftest'
-command-line option.]
-
-[Please see the
-.B smartctl \-l
-command-line option.]
-.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
-.B smartctl \-A
-command-line option.]
-
-.TP
-.B \-m ADD
-Send a warning email to the email address
-.B ADD
-if the '\-H', '\-l', or '\-f' Directives detect a failure or a new
-error, or is 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 test types, '\-H', '\-l', or '\-f', 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 form for
-the address:
-.B  user1@add1,user2@add2,...,userN@addN
-(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
-.B smartd
-startup.
-
-By default, email is sent using the system 
-.B mail
-command.  In order that
-.B smartd
-find the mail command (normally /bin/mail) an executable named
-.B 'mail'
-must be in the path of the shell or environment from which
-.B smartd
-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 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.
-
-.TP
-.B \-M TYPE
-These Directives modify the behavior of the
-.B smartd
-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
-.B smartd
-startup.  This allows one to verify that any email is correctly delivered.
-
-.I exec PATH
-\- run the executable PATH instead of the default mail command, when
-.B smartd
-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
-.B smartd
-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.
-.B smartd
-will
-.B block
-until the executable PATH returns, so if your executable hangs, then
-.B smartd
-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
-.B smartd
-in SYSLOG, but the executable's STDOUT and STDERR are directed to
-/dev/null, so if you wish to leave some other record behind, the
-executable must send mail or write to a file or device.
-
-Before running the executable,
-.B smartd
-sets a number of environment variables.  These environment variables
-may be used to control the executable's behavior.  The environment
-variables exported by
-.B smartd
-are:
-.nf
-.fi
-.B SMARTD_MAILER
-is set to the argument of -M exec, if present or else to 'mail'
-(examples: /bin/mail, mail).
-.nf
-.fi
-.B SMARTD_DEVICE
-is set to the device path (examples: /dev/hda, /dev/sdb).
-.nf
-.fi
-.B SMARTD_DEVICETYPE
-is set to the device type (possible values: ata, scsi).
-.nf
-.fi
-.B SMARTD_FAILTYPE
-gives the reason for the warning or message email.  The possible values that
-it takes, and their significance, are:
-.I emailtest
-(this is an email test message);
-.I health
-(the SMART health status indicates imminent failure);
-.I usage
-(a usage Attribute has failed);
-.I selftest
-(the number of self-test failures has increased);
-.I errorcount
-(the number of errors in the ATA error log has increased);
-.I FAILEDhealthcheck
-(the SMART health status command failed);
-.I FAILEDreadsmartdata
-(the command to read SMART Attribute data failed);
-.I FAILEDreadsmarterrorlog
-(the command to read the SMART error log failed);
-.I FAILEDreadsmartsefltestlog
-(the command to read the SMART self-test log failed); abd
-.I FAILEDopendevice
-(the open() command to the device failed).
-.nf
-.fi
-.B SMARTD_ADDRESS
-is set to the address argument ADD of the '\-m' Directive, unless ADD
-is
-.B <nomailer>.
-This is a comma-delineated list of email addresses (example:
-admin@yoyodyne.com).
-.nf
-.fi
-.B SMARTD_MESSAGE
-is set to the warning email message string from
-.B smartd. 
-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.
-.nf
-.fi
-.B SMARTD_TFIRST
-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
-.nf
-.fi
-.B SMARTD_TFIRSTEPOCH
-is an integer, which is the unix epoch (number of seconds since Jan 1,
-1970) for
-.B SMARTD_TFIRST.
-
-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 system (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 \(dq$SMARTD_SUBJECT\(dq $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
-
-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
-
-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 \-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
-.I all
-device Attributes (both Prefailure and Usage). [Please see the
-.B smartctl \-A
-command-line option.]
-.TP
-.B \-i ID
-Ignore device Attribute number
-.B ID
-when checking for failure of Usage Attributes.
-.B ID
-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
-.B ID
-when tracking changes in the Attribute values.
-.B ID
-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
-.I Raw
-value of Attribute
-.B ID
-along with its (normally reported)
-.I Normalized
-value.
-.B ID
-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
-.I Raw
-value of Attribute
-.B ID
-changes.  (Normally
-.B smartd
-only tracks/reports changes of the
-.I Normalized
-Attribute values.)
-.B ID
-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 \-F TYPE, \-\-firmwarebug=TYPE
-Modifies the behavior of
-.B smartctl
-to compensate for some known and understood device firmware bug.  The
-valid arguments to this option are:
-
-.I none
-Assume that the device firmware obeys the ATA specifications.  This is
-the default.
-
-.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
-.B smartctl
-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 erorr log; (3) strange and impossible values for
-the ATA error log timestamps.
-
-[Please see the
-.B smartctl \-F
-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 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 200,writeerrorcount
-\- Raw Attribute number 200 is the Write Error 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
-.B smartd
-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, and
-.B '\-l\ error' 
-to report increases in the number of ATA errors.
-
-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 \(rs
-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
-.B smartd
-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
-.B DEVICESCAN
-in capital letters, then
-.B smartd
-will ignore any remaining lines in the configuration file, and will
-scan for devices.
-
-If
-.B DEVICESCAN 
-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.
-
-.B DEVICESCAN
-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@yoyodyne.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@yoyodyne.com
-.fi
-will do the same, but restricts the scan to ATA devices only.  
-.nf
-.B  DEVICESCAN -H -d ata -m root@yoyodyne.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
-.B #! /bin/bash
-
-.B # Save the email message (STDIN) to a file:
-.B cat > /root/msg
- 
-.B # Append the output of smartctl -a to the message:
-.B /usr/sbin/smartctl -a $SMARTD_DEVICE >> /root/msg
- 
-.B # Now email the message to the user at address ADD:
-.B /bin/mail -s \(dq$SMARTD_SUBJECT\(dq $SMARTD_ADDRESS < /root/msg
-.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
-.B #! /bin/bash
-
-.B # Warn all users of a problem
-.B wall 'Problem detected with disk: ' $SMARTD_DEVICE
-.B wall 'Warning message from smartd is: ' \(dq$SMARTD_MESSAGE\(dq
-.B wall 'Shutting down machine in 30 seconds... '
- 
-.B # Wait half a minute
-.B sleep 30
- 
-.B # Power down the machine
-.B /usr/sbin/shutdown -hf now
-.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.
-
-\# ENDINCLUDE
-\# DO NOT MODIFY THIS OR PREVIOUS/NEXT LINES. THIS DEFINES THE 
-\# END OF THE INCLUDED SECTION FROM smartd.8
-
-.PP
-.SH AUTHOR
-Bruce Allen
-.B smartmontools-support@lists.sourceforge.net
-.fi
-University of Wisconsin - Milwaukee Physics Department
-
-.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. http://ssrc.soe.ucsc.edu/.
-.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:
-.B smartd
-(8),
-.B smartctl
-(8),
-.B syslogd
-(8)
-
-
-
-.SH
-CVS ID OF THIS PAGE:
-$Id: smartd.conf.5,v 1.47 2003/04/23 13:19:40 guidog Exp $
diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp
deleted file mode 100644
index 7c9609883..000000000
--- a/sm5/smartd.cpp
+++ /dev/null
@@ -1,2180 +0,0 @@
-/*
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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/
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <linux/hdreg.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "smartd.h"
-#include "utility.h"
-
-extern const char *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
-const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.158 2003/04/26 11:20:22 ballen4705 Exp $" 
-ATACMDS_H_CVSID ATAPRINT_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID; 
-
-// Forward declaration
-const char *getvalidarglist(char opt);
-
-// global variable used for control of printing, passing arguments, etc.
-smartmonctrl *con=NULL;
-
-// Two other globals -- number of ATA and SCSI devices being monitored
-int numatadevices=0;
-int numscsidevices=0;
-
-// How long to sleep between checks.  Handy as global variable for
-// debugging
-int checktime=CHECKTIME;
-
-// name of PID file (== NULL if no pid_file is used)
-char* pid_file=NULL;
-
-// If set, we should exit after checking all disks once
-int checkonce=0;
-
-// Needed to interrupt sleep when catching SIGUSR1.  Unix Gurus: I
-// know that this can be done better.  Please tell me how -- use email
-// address for Bruce Allen at the top of this file.  Search for
-// "sleeptime" to see what I am doing.
-volatile int sleeptime=CHECKTIME;
-
-// Interrupt sleep if we get a SIGUSR1.  Unix Gurus: I know that this
-// can be done better.  Please tell me how -- use email address for
-// Bruce Allen at the top of this file. Search for "sleeptime" to see
-// what I am doing.
-void sleephandler(int sig){
-  int oldsleeptime=sleeptime;
-  sleeptime=0;
-  printout(LOG_CRIT,"Signal USR1 - checking devices now rather than in %d seconds.\n",oldsleeptime<0?0:oldsleeptime);
-  return;
-}
-
-// Global Variables for command line options. These should go into a
-// structure at some point.
-unsigned char debugmode               = FALSE;
-
-// 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, ...){
-  va_list ap;
-  // initialize variable argument list 
-  va_start(ap,fmt);
-  if (debugmode) 
-    vprintf(fmt,ap);
-  else {
-    openlog("smartd",LOG_PID,LOG_DAEMON);
-    vsyslog(priority,fmt,ap);
-    closelog();
-  }
-  va_end(ap);
-  return;
-}
-
-// If either address or executable path is non-null then send and log
-// a warning email, or execute executable
-void printandmail(cfgfile *cfg, int which, int priority, char *fmt, ...){
-  char command[2048], message[256], hostname[256], additional[256];
-  char original[256], further[256], domainname[256], subject[256],dates[64];
-  int status;
-  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
-    "FAILEDreadsmartsefltestlog",//8
-    "FAILEDopendevice"           //9
-  };
-  
-  char *address=cfg->address;
-  char *executable=cfg->emailcmdline;
-  mailinfo *mail=cfg->maildata+which;
-  
-  // See if user wants us to send mail
-  if (!address && !executable)
-    return;
-
-  // checks for sanity
-  if (cfg->emailfreq<1 || cfg->emailfreq>3) {
-    printout(LOG_INFO,"internal error in printandmail(): cfg->emailfreq=%d\n",cfg->emailfreq);
-    return;
-  }
-  if (which<0 || which>9) {
-    printout(LOG_INFO,"internal error in printandmail(): which=%d\n",which);
-    return;
-  }
-  
-  // Return if a single warning mail has been sent.
-  if ((cfg->emailfreq==1) && 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 (cfg->emailfreq==2 && mail->logged && epoch<(mail->lastsent+day))
-    return;
-
-  // Return if less than 2^(logged-1) days have gone by
-  if (cfg->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) 
-  if (gethostname(hostname, 256))
-    sprintf(hostname,"Unknown host");
-  else
-    hostname[255]='\0';
-  if (getdomainname(domainname, 256))
-    sprintf(hostname,"Unknown domain");
-  else
-    domainname[255]='\0';
-  
-  // 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 (cfg->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 (cfg->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".
-  if (!executable)
-    executable="mail";
-    
-  // Export information in environment variables that will be useful
-  // for user scripts
-  setenv("SMARTD_MAILER", executable, 1);
-  setenv("SMARTD_DEVICE", cfg->name, 1);
-  setenv("SMARTD_DEVICETYPE", cfg->tryata?"ata":"scsi", 1);
-  setenv("SMARTD_MESSAGE", message, 1);
-  setenv("SMARTD_SUBJECT", subject, 1);
-  dateandtimezoneepoch(dates, mail->firstsent);
-  setenv("SMARTD_TFIRST", dates, 1);
-  snprintf(dates, 64,"%d", (int)mail->firstsent);
-  setenv("SMARTD_TFIRSTEPOCH", dates, 1);
-  setenv("SMARTD_FAILTYPE", whichfail[which], 1);
-  if (address)
-    setenv("SMARTD_ADDRESS", address, 1);
-
-  // now construct a command to send this as EMAIL
-  if (address)
-    snprintf(command, 2048, 
-             "$SMARTD_MAILER -s '%s' %s > /dev/null 2> /dev/null << \"ENDMAIL\"\n"
-             "This email was generated by the smartd daemon running on host:\n"
-             "%s\n"
-             "in the domain:\n"
-             "%s\n\n"
-             "The following warning/error was logged by the smartd daemon:\n"
-             "%s\n\n"
-             "For details see the SYSLOG (default: /var/log/messages) for host:\n"
-             "%s\n\n"
-             "%s%s%s"
-             "ENDMAIL\n",
-           subject, address, hostname, domainname, message, hostname, further, original, additional);
-  else
-    snprintf(command, 2048, "%s", executable);
-  
-  // tell SYSLOG what we are about to do...
-  printout(LOG_INFO,"%s %s to %s ...\n",
-           which?"Sending warning via ":"Executing test of", executable, address?address:"<nomailer>");
-
-  // issue the command to send mail or to run the user's executable
-  status=system(command);
-  
-  // now tell SYSLOG what happened.
-  if (status==-1){
-    printout(LOG_CRIT,"%s %s to %s failed (unable to fork new process)\n", 
-             which?"Warning via":"Test of", executable, address?address:"<nomailer>");
-  }
-  else {
-    int status8;
-    // check and report exit status of command
-#ifdef WEXITSTATUS
-    status8=WEXITSTATUS(status);
-#else
-    status8=(status>>8) & 0xff;
-#endif 
-    if (status8)  
-      printout(LOG_CRIT,"%s %s to %s failed (32-bit/8-bit exit status: %d/%d)\n", 
-               which?"Warning via":"Test of", executable, address?address:"<nomailer>", status, status8);
-    else
-      printout(LOG_INFO,"%s %s to %s successful\n",
-               which?"Warning via":"Test of", executable, address?address:"<nomailer>");
-  } 
-  // increment mail sent counter
-  mail->logged++;
-  
-  return;
-}
-
-// Printing function for watching ataprint commands, or losing them
-void pout(char *fmt, ...){
-  va_list ap;
-  // 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)
-    vprintf(fmt,ap);
-  // in debug==2 mode we print output from knowndrives.o functions
-  else if (debugmode==2 || con->reportataioctl || con->reportscsiioctl) {
-    openlog("smartd", LOG_PID, LOG_DAEMON);
-    vsyslog(LOG_INFO, fmt, ap);
-    closelog();
-  }
-  va_end(ap);
-  fflush(NULL);
-  return;
-}
-
-// tell user that we ignore HUP signals
-void huphandler(int sig){
-  printout(LOG_CRIT,"HUP ignored: smartd does NOT re-read /etc/smartd.conf.\n");
-  return;
-}
-
-// signal handler that tells users about signals that were caught
-void sighandler(int sig){
-    printout(LOG_CRIT,"smartd received signal %d: %s\n",
-             sig, strsignal(sig));
-    exit(EXIT_SIGNAL);
-}
-
-// remove the PID file
-void remove_pid_file(){
-  if (pid_file) {
-    if ( -1==unlink(pid_file) )
-      printout(LOG_INFO,"Can't unlink PID file %s (%s).\n", 
-	       pid_file, strerror(errno));
-    free(pid_file);
-  }
-  return;
-}
-
-// signal handler that prints goodbye message and removes pidfile
-void goodbye(){
-  printout(LOG_CRIT,"smartd is exiting\n");
-  remove_pid_file();
-  return;
-}
-
-// Forks new process, closes all file descriptors, redirects stdin,
-// stdout, stderr
-void daemon_init(){
-  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("/");
-  
-  return;
-}
-
-// create a PID file containing the current process id
-void write_pid_file() {
-  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", 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, pid);
-  }
-  return;
-}
-
-// Prints header identifying version of code and home
-void printhead(){
-  printout(LOG_INFO,"smartd version %d.%d-%d Copyright (C) 2002-3 Bruce Allen\n",
-           (int)RELEASE_MAJOR, (int)RELEASE_MINOR, (int)SMARTMONTOOLS_VERSION);
-  printout(LOG_INFO,"Home page is %s\n\n",PROJECTHOME);
-  return;
-}
-
-
-// prints help info for configuration file Directives
-void Directives() {
-  printout(LOG_INFO,"Configuration file (/etc/smartd.conf) Directives (after device name):\n");
-  printout(LOG_INFO,"  -d TYPE Set the device type to one of: ata, scsi\n");
-  printout(LOG_INFO,"  -T TYPE set the tolerance to one of: normal, permissive\n");
-  printout(LOG_INFO,"  -o VAL  Enable/disable automatic offline tests (on/off)\n");
-  printout(LOG_INFO,"  -S VAL  Enable/disable attribute autosave (on/off)\n");
-  printout(LOG_INFO,"  -H      Monitor SMART Health Status, report if failed\n");
-  printout(LOG_INFO,"  -l TYPE Monitor SMART log.  Type is one of: error, selftest\n");
-  printout(LOG_INFO,"  -f      Monitor 'Usage' Attributes, report failures\n");
-  printout(LOG_INFO,"  -m ADD  Send email warning to address ADD\n");
-  printout(LOG_INFO,"  -M TYPE Modify email warning behavior (see man page)\n");
-  printout(LOG_INFO,"  -p      Report changes in 'Prefailure' Attributes\n");
-  printout(LOG_INFO,"  -u      Report changes in 'Usage' Attributes\n");
-  printout(LOG_INFO,"  -t      Equivalent to -p and -u Directives\n");
-  printout(LOG_INFO,"  -r ID   Also report Raw values of Attribute ID with -p, -u or -t\n");
-  printout(LOG_INFO,"  -R ID   Track changes in Attribute ID Raw value with -p, -u or -t\n");
-  printout(LOG_INFO,"  -i ID   Ignore Attribute ID for -f Directive\n");
-  printout(LOG_INFO,"  -I ID   Ignore Attribute ID for -p, -u or -t Directive\n");
-  printout(LOG_INFO,"  -v N,ST Modifies labeling of Attribute N (see man page)  \n");
-  printout(LOG_INFO,"  -P TYPE Drive-specific presets: use, ignore, show, showall\n");
-  printout(LOG_INFO,"  -a      Default: equivalent to -H -f -t -l error -l selftest\n");
-  printout(LOG_INFO,"  -F TYPE Use firmware bug workaround. Type is one of: none, samsung\n");
-  printout(LOG_INFO,"   #      Comment: text after a hash sign is ignored\n");
-  printout(LOG_INFO,"   \\      Line continuation character\n");
-  printout(LOG_INFO,"Attribute ID is a decimal integer 1 <= ID <= 255\n");
-  printout(LOG_INFO,"SCSI devices: only -d, -m, and -M Directives allowed.\n");
-  printout(LOG_INFO,"Example: /dev/hda -a\n");
-return;
-}
-
-/* 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, --checkonce\n");
-  printout(LOG_INFO,"        Check all devices once, then exit\n\n");
-  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,"  -p NAME, --pidfile=NAME\n");
-  printout(LOG_INFO,"        Write PID file NAME\n\n");
-  printout(LOG_INFO,"  -r, --report=TYPE\n");
-  printout(LOG_INFO,"        Report transactions for one of: %s\n\n", getvalidarglist('r'));
-  printout(LOG_INFO,"  -V, --version, --license, --copyright\n");
-  printout(LOG_INFO,"        Print License, Copyright, and version information\n");
-#else
-  printout(LOG_INFO,"  -c      Check all devices once, then exit\n");
-  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,"  -p NAME Write PID file NAME\n");
-  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");
-  printout(LOG_INFO,"  -?      Same as -h\n");
-#endif
-}
-
-// returns negative if problem, else fd>=0
-static int opendevice(char *device, int flags)
-{
-  int fd;
- 
-  fd = open(device, flags);
-  if (fd < 0) {
-    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 (close(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
-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 atadevicescan2(atadevices_t *devices, cfgfile *cfg){
-  int fd;
-  struct hd_driveid drive;
-  char *device=cfg->name;
-  
-  // should we try to register this as an ATA device?
-  if (!(cfg->tryata))
-    return 1;
-  
-  // open the device
-  if ((fd=opendevice(device, O_RDONLY | O_NONBLOCK))<0)
-    // device open failed
-    return 1;
-  printout(LOG_INFO,"Device: %s, opened\n", device);
-  
-  // Get drive identity structure
-  if (ataReadHDIdentity (fd,&drive)){
-    // Unable to read Identity structure
-    printout(LOG_INFO,"Device: %s, unable to read Device Identity Structure\n",device);
-    close(fd);
-    return 2; 
-  }
-  
-  // pass user setings on to low-level ATA commands
-  con->fixfirmwarebug = cfg->fixfirmwarebug;
-
-  // Show if device in database, and use preset vendor attribute
-  // options unless user has requested otherwise.
-  if (!cfg->ignorepresets){
-
-    // do whatever applypresets decides to do
-    if (applypresets(&drive, cfg->attributedefs, con)<0)
-      printout(LOG_INFO, "Device: %s, not found in smartd database.\n", device);
-    else
-      printout(LOG_INFO, "Device: %s, found in smartd database.\n", device);
-
-    // then save the correct state of the flag (applypresets may have changed it)
-    cfg->fixfirmwarebug = con->fixfirmwarebug;
-  }
-  else
-    printout(LOG_INFO, "Device: %s, smartd database not searched (Directive: -P ignore).\n", device);
-
-  // 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", device);
-    if (!debugmode)
-      debugmode=2;
-    showpresets(&drive);
-    debugmode=savedebugmode;
-  }
-
-  if (!cfg->permissive && !ataSmartSupport(&drive)){
-    // SMART not supported
-    printout(LOG_INFO,"Device: %s, appears to lack SMART, use '-T permissive' Directive to try anyway.\n",device);
-    close(fd);
-    return 2; 
-  }
-  
-  if (ataEnableSmart(fd)){
-    // Enable SMART command has failed
-    printout(LOG_INFO,"Device: %s, could not enable SMART capability\n",device);
-    close(fd);
-    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",device);
-    else
-      printout(LOG_INFO,"Device: %s, disabled SMART Attribute Autosave.\n",device);
-  }
-
-  // or enable device attribute autosave
-  if (cfg->autosave==2){
-    if (ataEnableAutoSave(fd))
-      printout(LOG_INFO,"Device: %s, could not enable SMART Attribute Autosave.\n",device);
-    else
-      printout(LOG_INFO,"Device: %s, enabled SMART Attribute Autosave.\n",device);
-  }
-
-  // capability check: SMART status
-  if (cfg->smartcheck && ataSmartStatus2(fd)==-1){
-    printout(LOG_INFO,"Device: %s, not capable of SMART Health Status check\n",device);
-    cfg->smartcheck=0;
-  }
-  
-  // capability check: Read smart values and thresholds
-  if (cfg->usagefailed || cfg->prefail || cfg->usage || cfg->autoofflinetest) {
-    devices->smartval=(struct ata_smart_values *)calloc(1,sizeof(struct ata_smart_values));
-    devices->smartthres=(struct ata_smart_thresholds *)calloc(1,sizeof(struct ata_smart_thresholds));
-    
-    if (!devices->smartval || !devices->smartthres){
-      printout(LOG_CRIT,"Not enough memory to obtain SMART data\n");
-      exit(EXIT_NOMEM);
-    }
-    
-    if (ataReadSmartValues(fd,devices->smartval) ||
-        ataReadSmartThresholds (fd,devices->smartthres)){
-      printout(LOG_INFO,"Device: %s, Read SMART Values and/or Thresholds Failed\n",device);
-      free(devices->smartval);
-      free(devices->smartthres);
-
-      // make it easy to recognize that we've deallocated
-      devices->smartval=NULL;
-      devices->smartthres=NULL;
-      cfg->usagefailed=cfg->prefail=cfg->usage=0;
-    }
-  }
-
-  // disable automatic on-line testing
-  if (cfg->autoofflinetest==1){
-    if (devices->smartval && isSupportAutomaticTimer(devices->smartval) && !ataDisableAutoOffline(fd))
-      printout(LOG_INFO,"Device: %s, disabled SMART Automatic Offline Testing .\n",device);
-    else
-      printout(LOG_INFO,"Device: %s, could not disable SMART Automatic Offline Testing.\n",device);
-  }
-
-  // enable automatic on-line testing
-  if (cfg->autoofflinetest==2){
-    if (devices->smartval && isSupportAutomaticTimer(devices->smartval) && !ataDisableAutoOffline(fd))
-      printout(LOG_INFO,"Device: %s, enabled SMART Automatic Offline Testing.\n",device);
-    else
-      printout(LOG_INFO,"Device: %s, could not enable SMART Automatic Offline Testing.\n",device);
-  }
-
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int val;
-
-    // see if device supports Self-test logging.  Note that the
-    // following line is not a typo: Device supports self-test log if
-    // and only if it also supports error log.
-    if (!isSmartErrorLogCapable(devices->smartval)){
-      printout(LOG_INFO, "Device: %s, does not support SMART Self-test Log.\n", device);
-      cfg->selftest=0;
-      cfg->selflogcount=0;
-    }
-    else {
-      // get number of Self-test errors logged
-      val=selftesterrorcount(fd, device);
-      if (val>=0)
-	cfg->selflogcount=val;
-      else
-	cfg->selftest=0;
-    }
-  }
-  
-  // capability check: ATA error log
-  if (cfg->errorlog){
-    int val;
-
-    // see if device supports error logging
-    if (!isSmartErrorLogCapable(devices->smartval)){
-      printout(LOG_INFO, "Device: %s, does not support SMART Error Log.\n", device);
-      cfg->errorlog=0;
-      cfg->ataerrorcount=0;
-    }
-    else {
-      // get number of ATA errors logged
-      val=ataerrorcount(fd, device);
-      if (val>=0)
-	cfg->ataerrorcount=val;
-      else
-	cfg->errorlog=0;
-    }
-  }
-  
-  // If no tests available or selected, return
-  if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck || 
-        cfg->usagefailed || cfg->prefail || cfg->usage)) {
-    close(fd);
-    return 3;
-  }
-  
-  // Do we still have entries available?
-  if (numatadevices>=MAXATADEVICES){
-    printout(LOG_CRIT,"smartd has found more than MAXATADEVICES=%d ATA devices.\n"
-             "Recompile code from " PROJECTHOME " with larger MAXATADEVICES\n",(int)numatadevices);
-    exit(EXIT_CCONST);
-  }
-  
-  // register device
-  printout(LOG_INFO,"Device: %s, is SMART capable. Adding to \"monitor\" list.\n",device);
-  
-  // we were called from a routine that has global storage for the name.  Keep pointer.
-  devices->devicename=device;
-  devices->cfg=cfg;
-  
-  // record number of device, type of device, increment device count
-  cfg->tryscsi=0;
-  cfg->tryata=1;
-  cfg->atadevicenum=numatadevices;
-  cfg->scsidevicenum=-1;
-  numatadevices++;
-
-  // close file descriptor
-  closedevice(fd, device);
-  return 0;
-}
-
-
-static int scsidevicescan(scsidevices_t *devices, cfgfile *cfg,
-                          int scandirective)
-{
-    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?
-    if (! cfg->tryscsi)
-        return 1;
-    // open the device
-    if ((fd = opendevice(device, O_RDWR | O_NONBLOCK)) < 0) {
-        if (scandirective)
-            return 1;
-        printout(LOG_WARNING, "Device: %s, skip\n", device);
-        return 0; // device open failed
-    }
-    printout(LOG_INFO,"Device: %s, opened\n", device);
-  
-    // check that it's ready for commands. IE stores its stuff on the media.
-    if ((err = scsiTestUnitReady(fd))) {
-        if (1 == err) {
-            printout(LOG_WARNING, "Device: %s, NOT READY (media absent, spun "
-                     "down); skip\n", device);
-            close(fd);
-            return scandirective ? 1 : 0;
-        } else {
-           printout(LOG_ERR, "Device: %s, failed Test Unit Ready [err=%d]\n", 
-                    device, err);
-           close(fd);
-           return 2;
-        }
-    }
-  
-    if ((err = scsiFetchIECmpage(fd, &iec))) {
-        printout(LOG_WARNING, "Device: %s, Fetch of IEC (SMART) mode page "
-                 "failed, err=%d, skip device\n", device, err);
-        return 0;
-    }
-    if (! scsi_IsExceptionControlEnabled(&iec)) {
-        printout(LOG_WARNING, "Device: %s, IE (SMART) not enabled, "
-                 "skip device\n", device);
-        close(fd);
-        return 0;
-    }
-
-    // Device exists, and does SMART.  Add to list
-    if (numscsidevices >= MAXSCSIDEVICES) {
-        printout(LOG_ERR, "smartd has found more than MAXSCSIDEVICES=%d "
-                 "SCSI devices.\n" "Recompile code from " PROJECTHOME 
-                 " with larger MAXSCSIDEVICES\n", (int)numscsidevices);
-        return 0;
-    }
-
-    // now we can proceed to register the device
-    printout(LOG_INFO, "Device: %s, is SMART capable. Adding "
-             "to \"monitor\" list.\n",device);
- 
-    // since device points to global memory, just keep that address
-    devices->devicename = device;
-    devices->cfg = cfg;
-
-    // Flag that certain log pages are supported (information may be
-    // available from other sources).
-    if (0 == scsiLogSense(fd, SUPPORTED_LOG_PAGES, tBuf, sizeof(tBuf))) {
-        for (k = 4; k < tBuf[3] + LOGPAGEHDRSIZE; ++k) {
-            switch (tBuf[k]) { 
-                case TEMPERATURE_PAGE:
-                    devices->TempPageSupported = 1;
-                    break;
-                case IE_LOG_PAGE:
-                    devices->SmartPageSupported = 1;
-                    break;
-                default:
-                    break;
-            }
-        }   
-    }
-
-    // record number of device, type of device, increment device count
-    cfg->tryata = 0;
-    cfg->tryscsi = 1;
-    cfg->scsidevicenum = numscsidevices;
-    cfg->atadevicenum = -1;
-    ++numscsidevices;
-
-    // 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  ataCompareSmartValues(changedattribute_t *delta,
-                            struct ata_smart_values *new,
-                            struct ata_smart_values *old,
-                            struct ata_smart_thresholds *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=now->status.flag.prefailure;
-  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 isattoff(unsigned char attr,unsigned char *data, int set){
-  // locate correct attribute
-  int loc=attr>>3;
-  int bit=attr & 0x07;
-  unsigned char mask=0x01<<bit;
-
-  // attribute zero is always OFF
-  if (!attr)
-    return 1;
-
-  if (!set)
-    return (data[loc] & mask);
-  
-  data[loc]|=mask;
-  // return value when setting makes no sense!
-  return 0;
-}
-
-
-int ataCheckDevice(atadevices_t *drive){
-  int fd,i;
-  char *name=drive->devicename;
-  cfgfile *cfg=drive->cfg;
-  
-  // fix firmware bug if requested
-  con->fixfirmwarebug=cfg->fixfirmwarebug;
-
-  // If user has asked, test the email warning system
-  if (cfg->emailtest){
-    printandmail(cfg, 0, LOG_CRIT, "TEST EMAIL from smartd for device: %s", drive->devicename);
-  }
-
-  // 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, O_RDONLY | O_NONBLOCK))<0){
-    printandmail(cfg, 9, LOG_CRIT, "Device: %s, unable to open device", name);
-    return 1;
-  }
-
-  // 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);
-      printandmail(cfg, 5, LOG_CRIT, "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);
-      printandmail(cfg, 1, LOG_CRIT, "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){
-    struct ata_smart_values     curval;
-    struct ata_smart_thresholds *thresh=drive->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);
-      printandmail(cfg, 6, LOG_CRIT, "Device: %s, failed to read SMART Attribute Data", name);
-    }
-    else {  
-      // 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 (!isattoff(att, cfg->monitorattflags, 0)){
-            char attname[64], *loc=attname;
-            
-            // get attribute name & skip white space
-            ataPrintSmartAttribName(loc, att, cfg->attributedefs[att]);
-            while (*loc && *loc==' ') loc++;
-            
-            // warning message
-            printout(LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc);
-            printandmail(cfg, 2, LOG_CRIT, "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) && ataCompareSmartValues(&delta, &curval, drive->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 && !isattoff(id, cfg->monitorattflags+96, 0))
-            continue;
-
-          // are we tracking this attribute?
-          if (!isattoff(id, cfg->monitorattflags+32, 0)){
-            char newrawstring[64], oldrawstring[64], attname[64], *loc=attname;
-
-            // get attribute name, skip spaces
-            ataPrintSmartAttribName(loc, id, cfg->attributedefs[id]);
-            while (*loc && *loc==' ') loc++;
-            
-            // has the user asked for us to print raw values?
-            if (isattoff(id, cfg->monitorattflags+64, 0)) {
-              // 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, drive->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
-      *drive->smartval=curval;
-    } 
-  }
-  
-  // check if number of selftest errors has increased (note: may also DECREASE)
-  if (cfg->selftest){
-    int new;
-    unsigned char old=cfg->selflogcount;
-    
-    // new self test error count
-    new=selftesterrorcount(fd, name);
-    
-    // did command fail?
-    if (new<0)
-      printandmail(cfg, 8, LOG_CRIT, "Device: %s, Read SMART Self Test Log Failed", name);
-    
-    // hsa self-test error count increased?
-    if (new>old){
-      printout(LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d\n",
-               name, (int)old, new);
-      printandmail(cfg, 3, LOG_CRIT, "Device: %s, Self-Test Log error count increased from %d to %d",
-                   name, (int)old, new);
-    }
-
-    // Needed since self-test error count may  DECREASE
-    if (new>=0)
-      cfg->selflogcount=new;
-  }
-
-  
-  // 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)
-      printandmail(cfg, 7, LOG_CRIT, "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);
-      printandmail(cfg, 4, LOG_CRIT, "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;
-  }
-  
-  // Don't leave device open -- the OS/user may want to access it
-  // before the next smartd cycle!
-  closedevice(fd, name);
-  return 0;
-}
-
-
-int scsiCheckDevice(scsidevices_t *drive)
-{
-    UINT8 asc, ascq;
-    UINT8 currenttemp;
-    int fd;
-    cfgfile *cfg=drive->cfg;
-    char *name=drive->devicename;
-    const char *cp;
-
-    // If the user has asked for it, test the email warning system
-    if (cfg->emailtest)
-        printandmail(cfg, 0, LOG_CRIT, 
-                     "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, O_RDWR | O_NONBLOCK))<0) {
-        printandmail(cfg, 9, LOG_CRIT, "Device: %s, unable to open device",
-                      name);
-        return 1;
-    }
-    currenttemp = 0;
-    asc = 0;
-    ascq = 0;
-    if (scsiCheckIE(fd, drive->SmartPageSupported, drive->TempPageSupported,
-                    &asc, &ascq, &currenttemp)) {
-        printout(LOG_INFO, "Device: %s, failed to read SMART values\n", name);
-        printandmail(cfg, 6, LOG_CRIT, 
-                     "Device: %s, failed to read SMART values", name);
-    }
-    if (asc > 0) {
-        cp = scsiGetIEString(asc, ascq);
-        if (cp) {
-            printout(LOG_CRIT, "Device: %s, SMART Failure: %s\n", name, cp);
-            printandmail(cfg, 1, LOG_CRIT, "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);  
-  
-    // Seems to completely ignore what capabilities were found on the
-    // device when scanned
-    if (currenttemp) {
-        if (255 == currenttemp) /* this means temperature unavailable */
-            currenttemp = 0;    /* less likely to worry people */
-        if ((currenttemp != drive->Temperature) && (drive->Temperature))
-            printout(LOG_INFO, "Device: %s, Temperature changed %d degrees "
-                     "to %d degrees since last reading\n", name, 
-                     (int)(currenttemp - drive->Temperature), 
-                     (int)currenttemp);
-        drive->Temperature = currenttemp;
-    }
-    closedevice(fd, name);
-    return 0;
-}
-
-void CheckDevices(atadevices_t *atadevices, scsidevices_t *scsidevices){
-  static int firstpass=1;
-  int i;
-
-  // Infinite loop, which checks devices
-  printout(LOG_INFO,"Started monitoring %d ATA and %d SCSI devices\n",numatadevices,numscsidevices);
-  while (1){
-    for (i=0; i<numatadevices; i++) 
-      ataCheckDevice(atadevices+i);
-    
-    for (i=0; i<numscsidevices; i++)
-      scsiCheckDevice(scsidevices+i);
-
-    // This option is primarily for distribution developers who want
-    // an automated procedure for seeing if smartd works correctly.
-    // Use the -c/--checkonce option and verify zero exit status.
-    if (checkonce) {
-      printout(LOG_INFO,"Started with '-c' option. All devices sucessfully checked once.\n");
-      exit(0);
-    }
-
-    // Initialization setup
-    if (firstpass){
-      
-      // If in background as a daemon, fork and close file descriptors
-      if (!debugmode)
-	daemon_init();
-      
-      // install goobye message and remove pidfile handler
-      atexit(goodbye);
-      
-      // write PID file only after installing exit handler
-      if (!debugmode)
-	write_pid_file();
-      
-      // install signal handlers
-      if (signal(SIGINT, sighandler)==SIG_IGN)
-	signal(SIGINT, SIG_IGN);
-      if (signal(SIGTERM, sighandler)==SIG_IGN)
-	signal(SIGTERM, SIG_IGN);
-      if (signal(SIGQUIT, sighandler)==SIG_IGN)
-	signal(SIGQUIT, SIG_IGN);
-      if (signal(SIGHUP, huphandler)==SIG_IGN)
-	signal(SIGHUP, SIG_IGN);
-      if (signal(SIGUSR1, sleephandler)==SIG_IGN)
-	signal(SIGUSR1, SIG_IGN);
-            
-      // done with initialization setup
-      firstpass=0;
-    }
-
-    // Unix Gurus: I know that this can be done better.  Please tell
-    // me how -- use email address for Bruce Allen at the top of this
-    // file. Search for "sleeptime" to see what I am doing.  I think
-    // that when done "right" I should not have to call sleep once per
-    // second, but just set an alarm for checktime in the future, and
-    // then have an additional alarm sent if the user does SIGUSR1,
-    // which arrives first to cause another device check.  Please help
-    // me out.
-    
-    // Sleep until next check. Note that since sleeptime can be set to
-    // zero by an EXTERNAL signal SIGUSR1, it's possible for sleeptime
-    // to be negative.  Don't use while (sleeptime)!
-    sleeptime=checktime;
-    while (sleeptime-->0)
-      sleep(1); 
-  }
-}
-
-// Print out a list of valid arguments for the Directive d
-void printoutvaliddirectiveargs(int priority, char d) {
-  char *s;
-
-  switch (d) {
-  case 'd':
-    printout(priority, "ata, scsi");
-    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");
-      break;
-    }
-    printout(priority, "\n%s\n", s);
-    free(s);
-    break;
-  case 'P':
-    printout(priority, "use, ignore, show, showall");
-    break;
-  case 'F':
-    printout(priority, "none, samsung");
-    break;
-  }
-}
-
-char copyleftstring[]=
-"smartd comes with ABSOLUTELY NO WARRANTY. This\n"
-"is free software, and you are welcome to redistribute it\n"
-"under the terms of the GNU General Public License Version 2.\n"
-"See http://www.gnu.org for further details.\n\n";
-
-cfgfile config[MAXENTRIES];
-
-// exits with an error message, or returns integer value of token
-int inttoken(char *arg, char *name, char *token, int lineno, char *configfile, int min, int max){
-  char *endptr;
-  int val;
-  
-  // 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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-  
-  // 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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-
-  // all is well; return value
-  return val;
-}
-
-// This function returns non-zero if it has correctly parsed a token,
-// else zero if it has failed to parse a token.  Or it exits with a
-// Directive message if there is a token-parsing problem.
-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;
-
-  // 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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-  
-  // let's parse the token and swallow its argument
-  switch (sym=token[1]) {
-    int val;
-
-  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.
-      ;
-    } 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->tryata  = 1;
-      cfg->tryscsi = 0;
-    } else if (!strcmp(arg, "scsi")) {
-      cfg->tryscsi = 1;
-      cfg->tryata  = 0;
-    } else {
-      badarg = 1;
-    }
-    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 {
-      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':
-    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 'S':
-    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 'M':
-    // email warning option
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "once")) {
-      cfg->emailfreq = 1;
-    } else if (!strcmp(arg, "daily")) {
-      cfg->emailfreq = 2;
-    } else if (!strcmp(arg, "diminishing")) {
-      cfg->emailfreq = 3;
-    } else if (!strcmp(arg, "test")) {
-      cfg->emailtest = 1;
-    } else if (!strcmp(arg, "exec")) {
-      // Get the next argument (the command line)
-      if ((arg = strtok(NULL, delim)) == NULL) {
-        printout(LOG_CRIT, "File %s line %d (drive %s): Directive %s 'exec' argument must be followed by executable path.\n",
-                 CONFIGFILE, lineno, name, token);
-        Directives();
-        exit(EXIT_BADCONF);
-      }
-      // Free the last cmd line given if any
-      if (cfg->emailcmdline) {
-        printout(LOG_INFO, "File %s line %d (drive %s): found multiple -M exec Directives on line - ignoring all but the last\n", CONFIGFILE, lineno, name);
-        free(cfg->emailcmdline);
-      }
-      // Attempt to copy the argument
-      if (!(cfg->emailcmdline = strdup(arg))) {
-        printout(LOG_CRIT, "File %s line %d (drive %s): no free memory for command line argument to exec: %s\n",
-          CONFIGFILE, lineno, name, arg);
-          Directives();
-          exit(EXIT_NOMEM);
-      }
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'i':
-    // ignore failure of usage attribute
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags,1);
-    break;
-  case 'I':
-    // ignore attribute for tracking purposes
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags+32,1);
-    break;
-  case 'r':
-    // print raw value when tracking
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags+64,1);
-    break;
-  case 'R':
-    // track changes in raw value (forces printing of raw value)
-    val=inttoken(arg=strtok(NULL,delim), name, token, lineno, CONFIGFILE, 1, 255);
-    isattoff(val,cfg->monitorattflags+64,1);
-    isattoff(val,cfg->monitorattflags+96,1);
-    break;
-  case 'm':
-    // send email to address that follows
-    if ((arg = strtok(NULL,delim)) == NULL) {
-      printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s needs email address(es)\n",
-               CONFIGFILE, lineno, name, token);
-      Directives();
-      exit(EXIT_BADCONF);
-    }
-    if (!(cfg->address=strdup(arg))){
-      printout(LOG_CRIT,"File %s line %d (drive %s): Directive: %s: no free memory for email address(es) %s\n",
-               CONFIGFILE, lineno, name, token, arg);
-      Directives();
-      exit(EXIT_NOMEM);
-    }
-    break;
-  case 'v':
-    // non-default vendor-specific attribute meaning
-    if ((arg=strtok(NULL,delim)) == NULL) {
-      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)) == NULL) {
-      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")) {
-      debugmode = TRUE;
-      showallpresets();
-      exit(0);
-    } 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();
-    exit(EXIT_BADCONF);
-  }
-  if (missingarg) {
-    printout(LOG_CRIT, "File %s line %d (drive %s): Missing argument to Directive: %s\n", CONFIGFILE, lineno, name, token);
-  }
-  if (badarg) {
-    printout(LOG_CRIT, "File %s line %d (drive %s): Invalid argument: %s\n", CONFIGFILE, lineno, name, arg);
-  }
-  if (missingarg || badarg) {
-      printout(LOG_CRIT, "Valid arguments to %s Directive are: ", token);
-      printoutvaliddirectiveargs(LOG_CRIT, sym);
-      printout(LOG_CRIT, "\n");
-      Directives();
-      exit(EXIT_BADCONF);
-  }
-  return 1;
-}
-
-int parseconfigline(int entry, int lineno,char *line){
-  char *token,*copy;
-  char *name;
-  char *delim = " \n\t";
-  cfgfile *cfg;
-  static int numtokens=0;
-  int devscan=0;
-
-  if (!(copy=strdup(line))){
-    printout(LOG_INFO,"No memory to parse file: %s line %d, %s\n", CONFIGFILE, lineno, strerror(errno));
-    exit(EXIT_NOMEM);
-  }
-  
-  // get first token -- device name
-  if (!(name=strtok(copy,delim)) || *name=='#') {
-    free(copy);
-    return 0;
-  }
-
-  // Have we detected the DEVICESCAN directive?
-  if (!strcmp(SCANDIRECTIVE,name)){
-    devscan=1;
-    if (numtokens) {
-      printout(LOG_INFO,"Scan Directive %s must be the first entry in %s\n",name,CONFIGFILE);
-      exit(EXIT_BADCONF);
-    }
-    else
-      printout(LOG_INFO,"Scan Directive %s found in %s. Will scan for devices.\n",name,CONFIGFILE);
-  }
-  numtokens++;
-
-  // Is there space for another entry?
-  if (entry>=MAXENTRIES){
-    printout(LOG_CRIT,"Error: configuration file %s can have no more than MAXENTRIES=%d entries\n",
-             CONFIGFILE,MAXENTRIES);
-    exit(EXIT_CCONST);
-  }
-
-  // We've got a legit entry, clear structure
-  cfg=config+entry;
-  memset(cfg,0,sizeof(*config));
-
-  // Save info to process memory for after forking 32 bytes contains 1
-  // bit per possible attribute ID.  See isattoff()
-  cfg->name=strdup(name);
-  if (!devscan){
-    cfg->monitorattflags=(unsigned char *)calloc(NMONITOR*32,1);
-    cfg->attributedefs=(unsigned char *)calloc(256,1);
-  }
-
-  // check that all memory allocations were sucessful
-  if (!cfg->name || (!devscan && (!cfg->monitorattflags || !cfg->attributedefs))) {
-    printout(LOG_INFO,"No memory to store file: %s line %d, %s\n", CONFIGFILE, lineno, strerror(errno));
-    exit(EXIT_NOMEM);
-  }
-
-  // Store line number, and by default check for both device types.
-  cfg->lineno=lineno;
-  cfg->tryscsi=1;
-  cfg->tryata=1;
-  
-  // Try and recognize if a IDE or SCSI device.  These can be
-  // overwritten by configuration file directives.
-  if (GUESS_DEVTYPE_ATA == guess_linux_device_type(name))
-    cfg->tryscsi=0;
-  else if (GUESS_DEVTYPE_SCSI == guess_linux_device_type(name))
-    cfg->tryata=0;
-  /* in "don't know" case leave both tryata and tryscsi set */
-  
-  // parse tokens one at a time from the file.  This line actually
-  // parses ALL the tokens.
-  while ((token=strtok(NULL,delim)) && parsetoken(token,cfg)){
-#if 0
-    printout(LOG_INFO,"Parsed token %s\n",token);
-#endif
-  }
-
-  // If no ATA monitoring directives are set, then set all of them.
-  if (cfg->tryata && !(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->address && (cfg->emailcmdline || cfg->emailfreq || cfg->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);
-    Directives();
-    exit(EXIT_BADCONF);
-  }
-  
-  // has the user has set <nomailer>?
-  if (cfg->address && !strcmp(cfg->address,"<nomailer>")){
-    // check that -M exec is also set
-    if (!cfg->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);
-      Directives();
-      exit(EXIT_BADCONF);
-    }
-    // now free memory.  From here on the sign of <nomailer> is
-    // address==NULL and cfg->emailcmdline!=NULL
-    free(cfg->address);
-    cfg->address=NULL;
-  }
-
-  // set cfg->emailfreq to 1 (once) if user hasn't set it
-  if (!cfg->emailfreq)
-    cfg->emailfreq = 1;
-
-  entry++;
-  free(copy);
-
-  // Return:
-  if (devscan)
-    return -1;
-  else
-    return 1;
-}
-
-// returns number of entries in config file, or 0 if no config file
-// exists.  A config file with zero entries will cause an error
-// message and an exit.  Returns -1 if it found a SCANDEVICE directive
-// in the config file.
-int parseconfigfile(){
-  FILE *fp;
-  int entry=0,lineno=1,cont=0,contlineno=0;
-  char line[MAXLINELEN+2];
-  char fullline[MAXCONTLINE+1];
-
-  // Open config file, if it exists
-  fp=fopen(CONFIGFILE,"r");
-  if (fp==NULL && errno!=ENOENT){
-    // file exists but we can't read it
-    printout(LOG_CRIT,"%s: Unable to open configuration file %s\n",
-             strerror(errno),CONFIGFILE);
-    exit(EXIT_BADCONF);
-  }
-  
-  // No config file
-  if (fp==NULL)
-    return 0;
-  
-  // configuration file exists
-  printout(LOG_INFO,"Using 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,lineno,fullline);
-        // See if we found a SCANDEVICE directive
-        if (scandevice<0)
-          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 %d characters.\n",
-               (int)contlineno,CONFIGFILE,warn,(int)MAXLINELEN);
-      exit(EXIT_CCONST);
-    }
-
-    // Ignore anything after comment symbol
-    if ((comment=index(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 %d characters.\n",
-               lineno, (int)contlineno, CONFIGFILE, (int)MAXCONTLINE);
-      exit(EXIT_CCONST);
-    }
-    
-    // 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=rindex(line,'\\')) && !strtok(lastslash+1," \n\t")){
-      *(fullline+(cont-len)+(lastslash-line))=' ';
-      continue;
-    }
-
-    // Not a continuation line. Parse it
-    scandevice=parseconfigline(entry,lineno,fullline);
-
-    // did we find a scandevice directive?
-    if (scandevice<0)
-      return -1;
-
-    entry+=scandevice;
-    lineno++;
-    cont=0;
-  }
-  fclose(fp);
-  if (entry)
-    return entry;
-  
-  printout(LOG_CRIT,"Configuration file %s contains no devices (like /dev/hda)\n",CONFIGFILE);
-  exit(EXIT_BADCONF);
-}
-
-// Prints copyright, license and version information
-void PrintCopyleft(void){
-  char out[CVSMAXLEN];
-  debugmode=1;
-  printhead();
-  printout(LOG_INFO,copyleftstring);
-  printout(LOG_INFO,"CVS version IDs of files used to build this code are:\n");
-  printone(out,atacmds_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,ataprint_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,knowndrives_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,scsicmds_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,smartd_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-  printone(out,utility_c_cvsid);
-  printout(LOG_INFO,"%s",out);
-
-}
-
-/* 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 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 'p':
-    return "<FILE_NAME>";
-  case 'i':
-    return "<INTEGER_SECONDS>";
-  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) {
-  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 = "cdDi:p:r:Vh?";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update getvalidarglist() if you edit longopts
-  struct option longopts[] = {
-    { "checkonce",      no_argument,       0, 'c' },
-    { "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' },
-    { "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:
-#ifdef HAVE_GETOPT_LONG
-  while (-1 != (optchar = getopt_long(argc, argv, shortopts, longopts, NULL))){
-#else
-  while (-1 != (optchar = getopt(argc, argv, shortopts))){
-#endif
-    switch(optchar) {
-    case 'c':
-      checkonce = TRUE;
-      debugmode = TRUE;
-      break;
-    case 'd':
-      debugmode = TRUE;
-      break;
-    case 'D':
-      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':
-      {
-        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, "Can't allocate memory to copy argument to"
-                             " -r option - exiting\n");
-          exit(EXIT_NOMEM);
-        }
-        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 'p':
-      if( -1 == asprintf(&pid_file, "%s", optarg)) {
-	printout(LOG_CRIT, "Can't allocate memory for pid file name %s - exiting.\n", optarg);
-	pid_file = NULL;
-	exit(EXIT_NOMEM);
-      }
-      break;
-    case 'V':
-      PrintCopyleft();
-      exit(0);
-      break;
-    case '?':
-    case 'h':
-    default:
-      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);
-          printvalidarglistmessage(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);
-          printvalidarglistmessage(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);
-      printvalidarglistmessage(optchar);
-      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) {
-    printout(LOG_INFO, "warning: pid file %s not written in debug mode\n", pid_file);
-    free(pid_file);
-    pid_file = NULL;
-  }
-  
-  // print header
-  printhead();
-  
-  return;
-}
-  
-// Function we call if no configuration file was found or if the
-// DEVICESCAN Directive was found.  It makes entries for /dev/hd[a-l]
-// and /dev/sd[a-z].
-int makeconfigentries(int num, char *name, int isata, int start, int scandirective){
-  int i;
-  
-  // check that we still have space for entries
-  if (MAXENTRIES<(start+num)){
-    printout(LOG_CRIT,"Error: simulated config file can have no more than %d entries\n",(int)MAXENTRIES);
-    exit(EXIT_CCONST);
-  }
-  
-  // loop over the number of entries that we should create
-  for(i=0; i<num; i++){
-    cfgfile *cfg=config+start+i;
-    
-    // If user has given the scan directive, copy config files entries
-    if (scandirective){
-      memcpy(cfg, config, sizeof(*cfg));
-    }
-    else {
-      // no config file was used: all structure entries need to be set
-      memset(cfg,0,sizeof(*cfg));
-      
-      // enable all possible tests
-      cfg->smartcheck=1;
-      cfg->prefail=1;
-      cfg->usagefailed=1;
-      cfg->usage=1;
-      cfg->selftest=1;
-      cfg->errorlog=1;
-      
-      // lineno==0 is our clue that the device was not found in a
-      // config file!
-      cfg->lineno=0;    
-    }
-    
-    // select if it's a SCSI or ATA device
-    cfg->tryata=isata;
-    cfg->tryscsi=!isata;
-    
-    // put in the device name
-    cfg->name=strdup(name);
-    cfg->monitorattflags=(unsigned char *)calloc(NMONITOR*32,1);
-    cfg->attributedefs=(unsigned char *)calloc(256,1);
-    if (!cfg->name || !cfg->monitorattflags || !cfg->attributedefs) {
-      printout(LOG_INFO,"No memory for %d'th device after %s, %s\n", i, name, strerror(errno));
-      exit(EXIT_NOMEM);
-    }
-    
-    // increment final character of the name
-    cfg->name[strlen(name)-1]+=i;
-  }
-  return i;
-}
-
-void cantregister(char *name, char *type, int line, int scandirective){
-  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;
-}
- 
- 
-/* Main Program */
-int main (int argc, char **argv){
-  atadevices_t atadevices[MAXATADEVICES], *atadevicesptr=atadevices;
-  scsidevices_t scsidevices[MAXSCSIDEVICES], *scsidevicesptr=scsidevices;
-  int i, entries, scandirective=0, scanning=0;
-  smartmonctrl control;
-  
-  // initialize global communications variables
-  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->quietmode=0;
-  con->veryquietmode=debugmode?0:1;
-  con->checksumfail=0;
-
-  // look in configuration file CONFIGFILE (normally /etc/smartd.conf)
-  entries=parseconfigfile();
-  
-  // if SCANDEVICE used or there was no /etc/smartd.conf config file,
-  // then create needed entries for scanning
-  if (entries<=0){
-    int doscsi, doata;
-
-    scanning=1;
-
-    // Was SCANDEVICE Directive given?
-    scandirective=entries;
-    if (scandirective){
-      printout(LOG_INFO,"smartd: Scanning for devices.\n");
-      // free up storage used for SCANDIRECTIVE string
-      free(config->name);
-      config->name=NULL;
-    }
-    else {
-      // No config file given, so scan for both ATA and SCSI devices
-      printout(LOG_INFO,"smartd: file %s not found. Searching for ATA & SCSI devices.\n",CONFIGFILE);
-      config->tryata=1;
-      config->tryscsi=1;
-    }
-
-    // initialize total number of entries to seach for
-    entries=0;
-    doata=config->tryata;
-    doscsi=config->tryscsi;
-
-    // make list of ATA devices to search for
-    if (doata)
-      entries+=makeconfigentries(MAXATADEVICES,  "/dev/hda", 1, entries, scandirective);
-    // make list of SCSI devices to search for
-    if (doscsi)
-      entries+=makeconfigentries(MAXSCSIDEVICES, "/dev/sda", 0, entries, scandirective);
-  }
-
-  // Register entries
-  for (i=0;i<entries;i++){
-    int notregistered=1;
-    
-    // register ATA devices
-    if (config[i].tryata){
-      if (atadevicescan2(atadevicesptr+numatadevices, config+i))
-	cantregister(config[i].name, "ATA", config[i].lineno, scandirective);
-      else
-	notregistered=0;
-    }
-    
-    // then register SCSI devices
-    if (config[i].tryscsi){
-      if (scsidevicescan(scsidevicesptr+numscsidevices, config+i, 
-                         scandirective))
-	cantregister(config[i].name, "SCSI", config[i].lineno, scandirective);
-      else
-	notregistered=0;
-    }
-    
-    // if device explictly listed and we can't register it, then exit
-    if (notregistered && !scanning){
-      printout(LOG_CRIT, "Unable to register device %s - exiting.\n", config[i].name);
-      exit(EXIT_BADDEV);
-    }
-  } // done registering entries
-
-  // If there are no devices to monitor, then exit
-  if (!numatadevices && !numscsidevices){
-    printout(LOG_INFO,"Unable to monitor any SMART enabled ATA or SCSI devices.\n");
-    exit(EXIT_BADDEV);
-  }
-
-  // Now start an infinite loop that checks all devices
-  CheckDevices(atadevicesptr, scsidevicesptr); 
-  return 0;
-}
-
diff --git a/sm5/smartd.h b/sm5/smartd.h
deleted file mode 100644
index 31d99d6df..000000000
--- a/sm5/smartd.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * smartd.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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_CVSID
-#define SMARTD_H_CVSID "$Id: smartd.h,v 1.35 2003/04/19 09:53:42 pjwilliams Exp $\n"
-#endif
-
-// Configuration file
-#define CONFIGFILE "/etc/smartd.conf"
-
-// Scan directive for configuration file
-#define SCANDIRECTIVE "DEVICESCAN"
-
-// maximum line length in configuration file
-#define MAXLINELEN 128
-
-// maximum number of device entries in configuration file.
-#define MAXENTRIES 64
-
-// 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
-
-// maximum number of ATA devices to monitor
-#define MAXATADEVICES	12
-
-// maximum number of SCSI devices to monitor
-#define MAXSCSIDEVICES	26
-
-/* Boolean Values */
-#define TRUE 0x01
-#define FALSE 0x00
-
-// Number of monitoring flags per Attribute.  See monitorattflags
-// below.
-#define NMONITOR 4
-
-// Exit codes
-#define EXIT_BADCMD    1   // command line did not parse
-#define EXIT_BADCONF   2   // problem reading/parsing config file
-#define EXIT_STARTUP   3   // problem forking daemon
-#define EXIT_PID       4   // problem creating pid file
-
-#define EXIT_NOMEM     8   // out of memory
-#define EXIT_CCONST    9   // we hit a compile time constant
-
-#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
-
-// If user has requested email warning messages, then this structure
-// stores the information about them.
-typedef struct mailinfo {
-  // number of times an email has been sent
-  int logged;
-  // time last email was sent, as defined by man 2 time
-  time_t lastsent;
-  // time problem initially logged
-  time_t firstsent;
-} mailinfo;
-
-// Used to store a list of devices and options that were in the
-// configuration file.
-typedef struct configfile_s {
-  // Shich line was entry in file; what device type and name?
-  int lineno;
-  // Indicates corresponding entry number in the list of ata or scsi
-  // devices to monitor
-  int scsidevicenum;
-  int atadevicenum;
-  // Initially, tryata and tryscsi indicate which device to try.
-  // Ultimately, one is set and the other not set, depending upon
-  // which type of device was detected.
-  char tryata;
-  char tryscsi;
-  char *name;
-  // which tests have been enabled?
-  char smartcheck;
-  char usagefailed;
-  char prefail;
-  char usage;
-  char selftest;
-  char errorlog;
-  // Should we ignore missing capabilities/SMART errors
-  char permissive;
-  // Disable (1) or Enable (2) device attribute autosave
-  char autosave;
-  // Disable (1) or Enable (2) autmatic offline testing
-  char autoofflinetest;
-  // mailing information for four of the previous error types plus mailtest
-  mailinfo maildata[10];
-  // Frequency with which to send emails: 1 - once, 2 - daily, 3 - diminishing
-  unsigned char emailfreq;
-  // Should we send a test email
-  unsigned char emailtest;
-  // Execute this command line and include output in emails
-  char *emailcmdline;
-  // address to send email to
-  char *address;
-  // counts of ata and self-test errors.  Perhaps ought to be in the
-  // atadevices_t structure.
-  unsigned char selflogcount;
-  int  ataerrorcount;
-  // 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 means ignore failure if it's a usage attribute
-  // monitorattflats+32 set means don't track attribute
-  // monitorattflags+64 set means print raw value when tracking
-  // monitorattflags+96 set means track changes in raw value
-  unsigned char *monitorattflags;
-  // See the end of extern.h for a definition of the array of 256
-  // bytes that this points to.
-  unsigned char *attributedefs;
-  // enables equivalent of -F option for smartctl
-  unsigned char fixfirmwarebug;
-  // Don't use the preset vendor options from knowndrives[] for this device.
-  char ignorepresets;
-  // Show the preset vendor options from knowndrives[] for this device.
-  char showpresets;
-} cfgfile;
-
-
-// Used to store list of ATA devices to monitor.
-typedef struct atadevices_s {
-  struct ata_smart_values *smartval;
-  struct ata_smart_thresholds *smartthres;
-  cfgfile *cfg;
-  char *devicename;
-}  atadevices_t;
-
-// used to store a list of SCSI devices to monitor.  Devicename points
-// to a malloced name string.
-typedef struct scsidevices_s {
-  unsigned char SmartPageSupported;
-  unsigned char TempPageSupported;
-  unsigned char Temperature;
-  char *devicename;
-  cfgfile *cfg;
-} scsidevices_t;
-
-
-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...
-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)));   
-
-int ataCheckDevice(atadevices_t *drive);
diff --git a/sm5/smartd.initd b/sm5/smartd.initd
deleted file mode 100755
index 973a98cfb..000000000
--- a/sm5/smartd.initd
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-# chkconfig: 35 40 40 
-# smartmontools init file for smartd
-#
-# description: Self Monitoring and Reporting Technology (SMART) Daemon
-#
-# processname: smartd 
-#
-# $Id: smartd.initd,v 1.5 2003/03/06 07:27:18 ballen4705 Exp $
-#
-# Copyright (C) 2002-3 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/.
-#
-# source function library
-. /etc/rc.d/init.d/functions
-
-case "$1" in
-  start)
-	echo -n "Starting smartd: "
-        daemon /usr/sbin/smartd
-	touch /var/lock/subsys/smartd
-	echo
-	;;
-  stop)
-	echo -n "Shutting down smartd: "
-	killproc smartd
-	rm -f /var/lock/subsys/smartd
-	echo
-	;;
-  restart)
-        $0 stop
-        $0 start
-        ;;
-  status)
-        status smartd
-        ;;
-  *)
-	echo "Usage: smartd {start|stop|restart|status}"
-	exit 1
-esac
-
-exit 0
diff --git a/sm5/smartmontools.spec b/sm5/smartmontools.spec
deleted file mode 100644
index 5a4512dc5..000000000
--- a/sm5/smartmontools.spec
+++ /dev/null
@@ -1,727 +0,0 @@
-Release:  10
-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.1
-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>
-
-# 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.97 2003/04/23 13:19:40 guidog Exp $
-
-# Copyright (C) 2002-3 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
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%files
-%defattr(-,root,root)
-%attr(755,root,root) %{_sbindir}/smartd
-%attr(755,root,root) %{_sbindir}/smartctl
-%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 WARNINGS CHANGELOG COPYING TODO README VERSION smartd.conf examplescripts
-%config(noreplace) %{_sysconfdir}/smartd.conf
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-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.
-%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
-
-%post
-if [ -f /var/lock/subsys/smartd ]; then
-        /etc/rc.d/init.d/smartd restart 1>&2
-	echo "Restarted smartd services"
-else
-        echo "Run \"/etc/rc.d/init.d/smartd start\" to start smartd service now."
-	echo "Run \"/sbin/chkconfig --add smartd\", to start smartd service on system boot"
-fi
-echo "Note that you can now use a configuration file /etc/smartd.conf to control the"
-echo "startup behavior of the smartd daemon.  See man 8 smartd for details."
-
-%preun
-if [ -f /var/lock/subsys/smartd ]; then
-        /etc/rc.d/init.d/smartd stop 1>&2
-	echo "Stopping smartd services"
-fi
-/sbin/chkconfig --del smartd
-
-%define date	%(echo `LC_ALL="C" date +"%a %b %d %Y"`)
-%changelog
-* 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@yoyodyne.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/utility.c b/sm5/utility.c
deleted file mode 100644
index f5698bb54..000000000
--- a/sm5/utility.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * utility.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <ctype.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.9 2003/04/25 22:22:56 ballen4705 Exp $" UTILITY_H_CVSID;
-
-
-// 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[64];
-  
-  // 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
-  asctime_r(tmval, datebuffer);
-  
-  // Remove newline
-  datebuffer[strlen(datebuffer)-1]='\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, 64, "%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;
-  const char delimiters[] = " ,$";
-
-  // make a copy on stack, go to first token,
-  if (!(copy=strdup(cvsid)) || !(filename=strtok(copy, delimiters))) 
-    return 0;
-
-  // move to first instance of "Id:"
-  while (strcmp(filename,"Id:"))
-    if (!(filename=strtok(NULL, delimiters)))
-      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)  ) )
-    return 0;
-
-   sprintf(out,"%-13s revision: %-6s date: %-15s", filename, version, date);
-   free(copy);
-   return  (date-copy)+strlen(date);
-}
-
-// 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\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.
-    *s++ = '\0';
-    if (*s == '0' || !isdigit(*s))  // The integer part must be positive
-      return 1;
-    errno = 0;
-    *i = atoi(s);
-    if (errno)
-      return 1;
-  } else {
-    // There's no integer part.
-    *i = 1;
-  }
-
-  return 0;
-}
-
-// 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.
-// #define GUESS_DEVTYPE_ATA       0
-// #define GUESS_DEVTYPE_SCSI      1
-// #define GUESS_DEVTYPE_DONT_KNOW 2
-static const char * lin_dev_prefix = "/dev/";
-static const char * lin_dev_ata_disk_plus = "h";
-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";
-
-int guess_linux_device_type(const char * dev_name)
-{
-    int len;
-    int dev_prefix_len = strlen(lin_dev_prefix);
-
-    if (dev_name && ((len = strlen(dev_name)) > 0)) {
-        if (0 == strncmp(lin_dev_prefix, dev_name, dev_prefix_len)) {
-            if (len <= dev_prefix_len)
-                return 2;
-            dev_name += dev_prefix_len;
-        }
-        if (0 == strncmp(lin_dev_ata_disk_plus, dev_name,
-                         strlen(lin_dev_ata_disk_plus)))
-            return 0;
-        else if (0 == strncmp(lin_dev_scsi_disk_plus, dev_name,
-                         strlen(lin_dev_scsi_disk_plus)))
-            return 1;
-        else if (0 == strncmp(lin_dev_scsi_tape1, dev_name,
-                         strlen(lin_dev_scsi_tape1)))
-            return 1;
-        else if (0 == strncmp(lin_dev_scsi_tape2, dev_name,
-                         strlen(lin_dev_scsi_tape2)))
-            return 1;
-        else if (0 == strncmp(lin_dev_scsi_tape3, dev_name,
-                         strlen(lin_dev_scsi_tape3)))
-            return 1;
-    }
-    return 2;
-}
diff --git a/sm5/utility.cpp b/sm5/utility.cpp
deleted file mode 100644
index 7e0290248..000000000
--- a/sm5/utility.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * utility.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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 <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <ctype.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.9 2003/04/25 22:22:56 ballen4705 Exp $" UTILITY_H_CVSID;
-
-
-// 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[64];
-  
-  // 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
-  asctime_r(tmval, datebuffer);
-  
-  // Remove newline
-  datebuffer[strlen(datebuffer)-1]='\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, 64, "%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;
-  const char delimiters[] = " ,$";
-
-  // make a copy on stack, go to first token,
-  if (!(copy=strdup(cvsid)) || !(filename=strtok(copy, delimiters))) 
-    return 0;
-
-  // move to first instance of "Id:"
-  while (strcmp(filename,"Id:"))
-    if (!(filename=strtok(NULL, delimiters)))
-      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)  ) )
-    return 0;
-
-   sprintf(out,"%-13s revision: %-6s date: %-15s", filename, version, date);
-   free(copy);
-   return  (date-copy)+strlen(date);
-}
-
-// 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\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.
-    *s++ = '\0';
-    if (*s == '0' || !isdigit(*s))  // The integer part must be positive
-      return 1;
-    errno = 0;
-    *i = atoi(s);
-    if (errno)
-      return 1;
-  } else {
-    // There's no integer part.
-    *i = 1;
-  }
-
-  return 0;
-}
-
-// 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.
-// #define GUESS_DEVTYPE_ATA       0
-// #define GUESS_DEVTYPE_SCSI      1
-// #define GUESS_DEVTYPE_DONT_KNOW 2
-static const char * lin_dev_prefix = "/dev/";
-static const char * lin_dev_ata_disk_plus = "h";
-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";
-
-int guess_linux_device_type(const char * dev_name)
-{
-    int len;
-    int dev_prefix_len = strlen(lin_dev_prefix);
-
-    if (dev_name && ((len = strlen(dev_name)) > 0)) {
-        if (0 == strncmp(lin_dev_prefix, dev_name, dev_prefix_len)) {
-            if (len <= dev_prefix_len)
-                return 2;
-            dev_name += dev_prefix_len;
-        }
-        if (0 == strncmp(lin_dev_ata_disk_plus, dev_name,
-                         strlen(lin_dev_ata_disk_plus)))
-            return 0;
-        else if (0 == strncmp(lin_dev_scsi_disk_plus, dev_name,
-                         strlen(lin_dev_scsi_disk_plus)))
-            return 1;
-        else if (0 == strncmp(lin_dev_scsi_tape1, dev_name,
-                         strlen(lin_dev_scsi_tape1)))
-            return 1;
-        else if (0 == strncmp(lin_dev_scsi_tape2, dev_name,
-                         strlen(lin_dev_scsi_tape2)))
-            return 1;
-        else if (0 == strncmp(lin_dev_scsi_tape3, dev_name,
-                         strlen(lin_dev_scsi_tape3)))
-            return 1;
-    }
-    return 2;
-}
diff --git a/sm5/utility.h b/sm5/utility.h
deleted file mode 100644
index 9b0812a1e..000000000
--- a/sm5/utility.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * utility.h
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2002-3 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_
-
-#ifndef UTILITY_H_CVSID
-#define UTILITY_H_CVSID "$Id: utility.h,v 1.9 2003/04/22 04:23:29 dpgilbert Exp $\n"
-#endif
-
-#include <time.h>
-#include <regex.h>
-
-// 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).
-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 is in smartd.c and in smartctl.c.
-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);
-
-// Guess device type (ata or scsi) based on device name (Linux specific)
-#define GUESS_DEVTYPE_ATA       0
-#define GUESS_DEVTYPE_SCSI      1
-#define GUESS_DEVTYPE_DONT_KNOW 2
-int guess_linux_device_type(const char * dev_name);
-
-#endif
diff --git a/www/cvs-script b/www/cvs-script
deleted file mode 100755
index 6974e72e2..000000000
--- 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.smartmontools.sourceforge.net:/cvsroot/smartmontools
diff --git a/www/examples/HITACHI_DK23BA-20-0.txt b/www/examples/HITACHI_DK23BA-20-0.txt
deleted file mode 100644
index 13e9cb012..000000000
--- 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 4e43e8c2d..000000000
--- 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/IC35L120AVVA07-0-0.txt b/www/examples/IC35L120AVVA07-0-0.txt
deleted file mode 100644
index 57926ccfb..000000000
--- 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 992a620ce..000000000
--- 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 13e0eb28e..000000000
--- 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 b1ed8ace3..000000000
--- 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-2.txt b/www/examples/MAXTOR-2.txt
deleted file mode 100644
index 9ff60ffcb..000000000
--- 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 26df69e59..000000000
--- 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 65ae2850d..000000000
--- 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 fe37f6541..000000000
--- 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-5.txt b/www/examples/Maxtor-5.txt
deleted file mode 100644
index 3bb171eb6..000000000
--- 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 965e55d99..000000000
--- 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 776cb3dce..000000000
--- 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/index.html b/www/index.html
deleted file mode 100644
index cb191ad0e..000000000
--- a/www/index.html
+++ /dev/null
@@ -1,467 +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</title>
- <link rev="made" href="mailto:smartmontools-support@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="SMART, S.M.A.R.T., Linux, disk monitoring" />
-</head>
-<body>
-
-<div align="center"><h1><font color="#3333ff">smartmontools Home Page</font></h1></div>
-
-<p>This is the home page for smartmontools.&#160; 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 (S.M.A.R.T.) built into most modern ATA and SCSI hard
-disks.&#160; It is derived from the smartsuite package, and includes
-support for ATA/ATAPI-5 disks.&#160; It should run on any modern Linux
-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="#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="#testinghelp">The code needs to be tested on SCSI,
-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 S.M.A.R.T. 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/cgi-bin/viewcvs.cgi/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></li>
-</ul>
-
-<hr size="2" />
-
-<b><a name="howtodownload"></a>How to download and install
-smartmontools</b>
-
-<p>There are four different ways to get and install
-smartmontools.&#160; You can use any of the first three procedures
-(the fourth is for Debian only).&#160; Just after "Method 4" below are
-some instructions for trying out smartmontools once you have completed
-the installation.</p>
-
-<b>First Method - 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.0-1.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.0-1.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 - 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.0-1.tar.gz</pre></li>
-<li>The previous step created a directory called smartmontools-5.0-1
-containing the code.&#160; Go to that directory, build, and install:
-<pre>cd smartmontools-5.0-1
-make
-make install (only root can do this)</pre></li>
-</ul>
-
-<b>Third Method - 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_0_26</tt>.&#160; You can see what the different names are
-by looking at the <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/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.smartmontools.sourceforge.net:/cvsroot/smartmontools login (when prompted for a password, just press Enter)
-cvs -d:pserver:anonymous@cvs.smartmontools.sourceforge.net:/cvsroot/smartmontools co sm5</pre></li>
-
-<li>To instead get the 5.0-26 release:
-
-<pre>cvs -d:pserver:anonymous@cvs.smartmontools.sourceforge.net:/cvsroot/smartmontools co -r RELEASE_5_0_26 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
-make
-make install (only root can do this)</pre></li>
-
-<li>To update your sources to the 5.0-30 release:
-
-<pre>cd sm5
-cvs up -r RELEASE_5_0_30</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 - Install the Debian package (for machines using the Debian linux distribution)</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.4-2.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>After installing smartmontools using Method 1, 2, 3 or 4 above, you can read the man
-pages, and try out the commands:</b>
-
-<pre>man 8 smartctl
-man 8 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 in
-<tt>/usr/share/man/man8</tt>.&#160; If "<tt>man</tt>" does not find the
-manual pages, then you may need to add <tt>/usr/share/man</tt> to your
-<tt>MANPATH</tt> environment variable.</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/cgi-bin/viewcvs.cgi/smartmontools/sm5/WARNINGS?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">
-WARNINGS</a> file in smartmontools. So far there are only two problem systems listed.</p>
-
-<a name="FAQ"></a><b>Frequently Asked Questions</b>
-
-<p>If your question is not here, please <a href="mailto:smartmontools-support@lists.sourceforge.net">email
-me</a>.</p>
-
-<ul>
-<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>Please send an email to the <a href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">smartmontools-support
-mailing list</a>.&#160; Please take a look through the archives to see
-if your question has been answered.</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 another 300 IBM ATA-6 disks (36 TB
-total). It's nice to have advanced warning when a disk is going to
-fail.</p></li>
-
-<li><b>I see some strange output from smartctl.  What does it mean?</b>
-
-<p>The raw S.M.A.R.T. 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>My Maxtor/Hitachi disk is only a few days old, yet smartctl reports its age (Attribute 9) as thousands of hours!</b>
-
-<p>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.
-</p></li>
-
-<li><b>What Kernel Version is needed?</b>
-
-<p>
-Unfortunately I can't give a definitive answer to this question.  In
-principle the 2.4 series kernels all provide the needed support.  The
-later 2.2 series kernels should work OK.  However, depending upon the
-2.2 kernel version, patch level, and configuration options, they may
-not support the HDIO_DRIVE_TASK ioctl().  This is needed for the drive
-to execute the ATA SMART RETURN STATUS command.
-</p></li>
-
-<li><b>What attributes does smartmontools not yet recognize?</b>
-
-<p>From a Hitachi disk: (250). From
-Maxtor disks (99), (100), (101), (201), (202), (203), (204), (205), (207), (208), (209).
-</p>
-
-<p>If you can attach names/meanings to these attributes, please send a
-note to <a
-href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">
-smartmontools-support</a>.  If you have access to other
-S.M.A.R.T. utilities (especially manufacturer-specific ones, see
-below) and can send us comparison output from smartctl and the other
-utility, that's especially useful.</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.  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></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, it looks for all ATA and
-SCSI devices to monitor (matching the pattern <tt>/dev/hd[a-z]</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>Recent releases of smartd can use a configuration file
-<tt>/etc/smartd.conf</tt> to specify which devices to include or exclude
-from start-up search.</p></li>
-
-<li><b>What's the story on IBM S.M.A.R.T. disks?</b>
-
-<p>Apparently some of the older S.M.A.R.T. firmware on IBM disks can 
-interfere with the regular operation of the disk.&#160; If you have this
-problem, here is an <a href="http://www.geocities.com/dtla_update/">IBM
-DISK FIRMWARE UPGRADE</a> that fixes the problem.
-</p></li>
-</ul>
-
-<hr size="2" /><a name="testinghelp"></a><b>Help needed in testing
-smartmontools, especially on SCSI, FireWire, USB, and SATA disks/systems</b>
-<p>I have access to a number of systems with ATA S.M.A.R.T. disks, but
-I don't have any access to systems with SCSI, FireWire, USB, and SATA
-S.M.A.R.T. devices. <br />
-</p>
-<p>Work on smartmontools support for SCSI disks and SCSI tape drives
-(TapeAlerts) is progressing. See this <a
- href="http://www.torque.net/scsi/smartmontools_scsi.html">article</a>
-for more details and examples. Do you have a beowulf cluster with a few
-hundred SCSI disks and tape jukeboxes? We are looking for testers.</p>
-<p>A package of SCSI utilities including one to examine SCSI log
-information can be found on the <a href="http://www.torque.net/sg/">scsi
-generic (sg) driver home page</a>. The package is called <tt>sg3_utils</tt>.<br />
-</p>
-<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 commands needed for
-S.M.A.R.T. support. 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 been on the market for about 3 years!<br />
-</p>
-<p>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.</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>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 S.M.A.R.T. 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/cgi-bin/viewcvs.cgi/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.&#160; 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
-S.M.A.R.T. 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:</big></p>
-
-<pre>
-man 8 smartctl
-man 8 smartd
-</pre>
-
-<p><big>If you'd like to know more about S.M.A.R.T., then the following
-references may be helpful:</big></p>
-
-<ul>
- <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 2a) <a href="http://www.t13.org/docs2003/d1532v1r2a.pdf">Volume 1</a>,
-  <a href="http://www.t13.org/docs2003/d1532v2r2a.pdf">Volume 2</a>,
-  <a href="http://www.t13.org/docs2003/d1532v3r2a.pdf">Volume 3</a></li>
- <li><a href="http://www.t13.org/#FTP_site">Earlier 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 S.M.A.R.T. specification is SFF-8035i from the <a href="http://www.sffcommittee.com/ns/">SFF Committee</a>.&#160; 
-Here is their <a href="ftp://ftp.seagate.com/sff/INF-8035.TXT"> "link"</a>.
-Revision 1 of the SFF-8035i document can be purchased from <a href="http://global.ihs.com/">Global Engineering Documents</a>.
-Enter "SFF 8035i" in the "DOCUMENT NUMBER" search box in the top left corner.
-</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/docs/pdf/whitepaper/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 S.M.A.R.T. For Reliability</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/smart_u8.pdf" target="_blank">Playing it S.M.A.R.T.</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><a href="http://www.maxtor.com/products/DiamondMax/software/maxsafe.pdf" target="_blank">Drive reliability and safety system: MaxSafe</a> (Maxtor)</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>
-</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)</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-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/HITACHI_DK23BA-20-0.txt">HITACHI_DK23BA-20</a> Hitachi 20 GB 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>
-</ul>
-
-<hr size="2" />
-
-Maintained by <a href="mailto:smartmontools-support@lists.sourceforge.net">Bruce Allen</a>
-
-<br />
-
-<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>
-
-</body>
-</html>
diff --git a/www/script b/www/script
deleted file mode 100755
index fa7cd8c22..000000000
--- 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
-- 
GitLab