diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist
deleted file mode 100644
index b04b3501f5efd94313942eb7439457bc82f5a2f5..0000000000000000000000000000000000000000
--- a/CVSROOT/checkoutlist
+++ /dev/null
@@ -1,13 +0,0 @@
-# The "checkoutlist" file is used to support additional version controlled
-# administrative files in $CVSROOT/CVSROOT, such as template files.
-#
-# The first entry on a line is a filename which will be checked out from
-# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
-# The remainder of the line is an error message to use if the file cannot
-# be checked out.
-#
-# File format:
-#
-#	[<whitespace>]<filename><whitespace><error message><end-of-line>
-#
-# comment lines begin with '#'
diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo
deleted file mode 100644
index b19e7b7a63e8e90cdb49c43f02035646c4a76e0a..0000000000000000000000000000000000000000
--- a/CVSROOT/commitinfo
+++ /dev/null
@@ -1,15 +0,0 @@
-# The "commitinfo" file is used to control pre-commit checks.
-# The filter on the right is invoked with the repository and a list 
-# of files to check.  A non-zero exit of the filter program will 
-# cause the commit to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT.  For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/config b/CVSROOT/config
deleted file mode 100644
index ff43ec005ab332bc2aa7e1378754180e75a4b049..0000000000000000000000000000000000000000
--- a/CVSROOT/config
+++ /dev/null
@@ -1,14 +0,0 @@
-# Set this to "no" if pserver shouldn't check system users/passwords
-#SystemAuth=no
-
-# Put CVS lock files in this directory rather than directly in the repository.
-#LockDir=/var/lock/cvs
-
-# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
-# level of the new working directory when using the `cvs checkout'
-# command.
-#TopLevelAdmin=no
-
-# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
-# history file, or a subset as needed (ie `TMAR' logs all write operations)
-#LogHistory=TOFEWGCMAR
diff --git a/CVSROOT/cvswrappers b/CVSROOT/cvswrappers
deleted file mode 100644
index 0accaf1b1532448d633d8a183cd8e3a5dd3b4a75..0000000000000000000000000000000000000000
--- a/CVSROOT/cvswrappers
+++ /dev/null
@@ -1,23 +0,0 @@
-# This file affects handling of files based on their names.
-#
-# The -t/-f options allow one to treat directories of files
-# as a single file, or to transform a file in other ways on
-# its way in and out of CVS.
-#
-# The -m option specifies whether CVS attempts to merge files.
-#
-# The -k option specifies keyword expansion (e.g. -kb for binary).
-#
-# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
-#
-#  wildcard	[option value][option value]...
-#
-#  where option is one of
-#  -f		from cvs filter		value: path to filter
-#  -t		to cvs filter		value: path to filter
-#  -m		update methodology	value: MERGE or COPY
-#  -k		expansion mode		value: b, o, kkv, &c
-#
-#  and value is a single-quote delimited value.
-# For example:
-#*.gif -k 'b'
diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo
deleted file mode 100644
index d78886c1522b6eae3470c13da218c3d8e197cf71..0000000000000000000000000000000000000000
--- a/CVSROOT/editinfo
+++ /dev/null
@@ -1,21 +0,0 @@
-# The "editinfo" file is used to allow verification of logging
-# information.  It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure.  Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-#   Making sure that the entered bug-id number is correct.
-#   Validating that the code that was reviewed is indeed the code being
-#       checked in (using the bug-id number or a seperate review
-#       number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported.  There can be only one entry that matches a given
-# repository.
diff --git a/CVSROOT/loginfo b/CVSROOT/loginfo
deleted file mode 100644
index f31e552dd63fcfb0dcdd8e290040b9934fd3ce5a..0000000000000000000000000000000000000000
--- 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 cb9e9efc94b342879a5fff24b425473fc11edd01..0000000000000000000000000000000000000000
--- a/CVSROOT/modules
+++ /dev/null
@@ -1,26 +0,0 @@
-# Three different line formats are valid:
-#	key	-a    aliases...
-#	key [options] directory
-#	key [options] directory files...
-#
-# Where "options" are composed of:
-#	-i prog		Run "prog" on "cvs commit" from top-level of module.
-#	-o prog		Run "prog" on "cvs checkout" of module.
-#	-e prog		Run "prog" on "cvs export" of module.
-#	-t prog		Run "prog" on "cvs rtag" of module.
-#	-u prog		Run "prog" on "cvs update" of module.
-#	-d dir		Place module in directory "dir" instead of module name.
-#	-l		Top-level directory only -- do not recurse.
-#
-# NOTE:  If you change any of the "Run" options above, you'll have to
-# release and re-checkout any working directories of these modules.
-#
-# And "directory" is a path to a directory relative to $CVSROOT.
-#
-# The "-a" option specifies an alias.  An alias is interpreted as if
-# everything on the right of the "-a" had been typed on the command line.
-#
-# You can encode a module within a module by using the special '&'
-# character to interpose another module into the current module.  This
-# can be useful for creating a module that consists of many directories
-# spread out over the entire source repository.
diff --git a/CVSROOT/notify b/CVSROOT/notify
deleted file mode 100644
index 34f0bc288808e56e499d0852a9bfc9a3214b02d9..0000000000000000000000000000000000000000
--- a/CVSROOT/notify
+++ /dev/null
@@ -1,12 +0,0 @@
-# The "notify" file controls where notifications from watches set by
-# "cvs watch add" or "cvs edit" are sent.  The first entry on a line is
-# a regular expression which is tested against the directory that the
-# change is being made to, relative to the $CVSROOT.  If it matches,
-# then the remainder of the line is a filter program that should contain
-# one occurrence of %s for the user to notify, and information on its
-# standard input.
-#
-# "ALL" or "DEFAULT" can be used in place of the regular expression.
-#
-# For example:
-#ALL mail %s -s "CVS notification"
diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo
deleted file mode 100644
index 49e59f4d0df9b432c5b99c0b806378a77c9cd870..0000000000000000000000000000000000000000
--- a/CVSROOT/rcsinfo
+++ /dev/null
@@ -1,13 +0,0 @@
-# The "rcsinfo" file is used to control templates with which the editor
-# is invoked on commit and import.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being made to, relative to the
-# $CVSROOT.  For the first match that is found, then the remainder of the
-# line is the name of the file that contains the template.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo
deleted file mode 100644
index 274a46dd5b61069f1cea62395178b09aa3120248..0000000000000000000000000000000000000000
--- a/CVSROOT/taginfo
+++ /dev/null
@@ -1,20 +0,0 @@
-# The "taginfo" file is used to control pre-tag checks.
-# The filter on the right is invoked with the following arguments:
-#
-# $1 -- tagname
-# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
-# $3 -- repository
-# $4->  file revision [file revision ...]
-#
-# A non-zero exit of the filter program will cause the tag to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT.  For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg
deleted file mode 100644
index 86f747ce222390e6aa7a488074e372030d57a479..0000000000000000000000000000000000000000
--- a/CVSROOT/verifymsg
+++ /dev/null
@@ -1,21 +0,0 @@
-# The "verifymsg" file is used to allow verification of logging
-# information.  It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure.  Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-#   Making sure that the entered bug-id number is correct.
-#   Validating that the code that was reviewed is indeed the code being
-#       checked in (using the bug-id number or a seperate review
-#       number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported.  There can be only one entry that matches a given
-# repository.
diff --git a/sm5/atacmdnames.cpp b/sm5/atacmdnames.cpp
deleted file mode 100644
index 8291fc3dc487cf12b6448a09afcfeef705e82d64..0000000000000000000000000000000000000000
--- a/sm5/atacmdnames.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * atacmdnames.c
- *
- * This module is based on the T13/1532D Volume 1 Revision 3 (ATA/ATAPI-7)
- * specification, which is available from http://www.t13.org/#FTP_site
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- * Address of support mailing list: smartmontools-support@lists.sourceforge.net
- *
- * Copyright (C) 2003 Philip Williams
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "atacmdnames.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-#define COMMAND_TABLE_SIZE 256
-
-const char *atacmdnames_c_cvsid="$Id: atacmdnames.cpp,v 1.9 2003/08/13 12:33:22 ballen4705 Exp $" ATACMDNAMES_H_CVSID;
-
-const char cmd_reserved[]        = "[RESERVED]";
-const char cmd_vendor_specific[] = "[VENDOR SPECIFIC]";
-const char cmd_reserved_sa[]     = "[RESERVED FOR SERIAL ATA]";
-const char cmd_reserved_cf[]     = "[RESERVED FOR COMPACTFLASH ASSOCIATION]";
-const char cmd_reserved_mcpt[]   = "[RESERVED FOR MEDIA CARD PASS THROUGH]";
-const char cmd_recalibrate_ret4[]= "RECALIBRATE [RET-4]";
-const char cmd_seek_ret4[]       = "SEEK [RET-4]";
-
-const char *command_table[COMMAND_TABLE_SIZE] = {
-/*-------------------------------------------------- 00h-0Fh -----*/
-  "NOP",
-  cmd_reserved,
-  cmd_reserved,
-  "CFA REQUEST EXTENDED ERROR CODE",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "DEVICE RESET",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 10h-1Fh -----*/
-  "RECALIBRATE [OBS-4]",
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-  cmd_recalibrate_ret4,
-/*-------------------------------------------------- 20h-2Fh -----*/
-  "READ SECTOR(S)",
-  "READ SECTOR(S) [OBS-5]",
-  "READ LONG (w/ retry) [OBS-4]",
-  "READ LONG (w/o retry) [OBS-4]",
-  "READ SECTOR(S) EXT",
-  "READ DMA EXT",
-  "READ DMA QUEUED EXT",
-  "READ NATIVE MAX ADDRESS EXT",
-  cmd_reserved,
-  "READ MULTIPLE EXT",
-  "READ STREAM DMA",
-  "READ STREAM PIO",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "READ LOG EXT",
-/*-------------------------------------------------- 30h-3Fh -----*/
-  "WRITE SECTOR(S)",
-  "WRITE SECTOR(S) [OBS-5]",
-  "WRITE LONG(w/ retry) [OBS-4]",
-  "WRITE LONG(w/o retry) [OBS-4]",
-  "WRITE SECTORS(S) EXT",
-  "WRITE DMA EXT",
-  "WRITE DMA QUEUED EXT",
-  "SET MAX ADDRESS EXT",
-  "CFA WRITE SECTORS WITHOUT ERASE",
-  "WRITE MULTIPLE EXT",
-  "WRITE STREAM DMA",
-  "WRITE STREAM PIO",
-  "WRITE VERIFY [OBS-4]",
-  "WRITE DMA FUA EXT",
-  "WRITE DMA QUEUED FUA EXT",
-  "WRITE LOG EXT",
-/*-------------------------------------------------- 40h-4Fh -----*/
-  "READ VERIFY SECTOR(S)",
-  "READ VERIFY SECTOR(S) [OBS-5]",
-  "READ VERIFY SECTOR(S) EXT",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 50h-5Fh -----*/
-  "FORMAT TRACK [OBS-4]",
-  "CONFIGURE STREAM",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 60h-6Fh -----*/
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved_sa,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- 70h-7Fh -----*/
-  "SEEK [OBS-7]",
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-  cmd_seek_ret4,
-/*-------------------------------------------------- 80h-8Fh -----*/
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  "CFA TRANSLATE SECTOR [VS IF NO CFA]",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-/*-------------------------------------------------- 90h-9Fh -----*/
-  "EXECUTE DEVICE DIAGNOSTIC",
-  "INITIALIZE DEVICE PARAMETERS [OBS-6]",
-  "DOWNLOAD MICROCODE",
-  cmd_reserved,
-  "STANDBY IMMEDIATE [RET-4]",
-  "IDLE IMMEDIATE [RET-4]",
-  "STANDBY [RET-4]",
-  "IDLE [RET-4]",
-  "CHECK POWER MODE [RET-4]",
-  "SLEEP [RET-4]",
-  cmd_vendor_specific,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- A0h-AFh -----*/
-  "PACKET",
-  "IDENTIFY PACKET DEVICE",
-  "SERVICE",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-/*-------------------------------------------------- B0h-BFh -----*/
-  "SMART",
-  "DEVICE CONFIGURATION",
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-  cmd_reserved_cf,
-/*-------------------------------------------------- C0h-CFh -----*/
-  "CFA ERASE SECTORS [VS IF NO CFA]",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  "READ MULTIPLE",
-  "WRITE MULTIPLE",
-  "SET MULTIPLE MODE",
-  "READ DMA QUEUED",
-  "READ DMA",
-  "READ DMA [OBS-5]",
-  "WRITE DMA",
-  "WRITE DMA [OBS-5]",
-  "WRITE DMA QUEUED",
-  "CFA WRITE MULTIPLE WITHOUT ERASE",
-  "WRITE MULTIPLE FUA EXT",
-  cmd_reserved,
-/*-------------------------------------------------- D0h-DFh -----*/
-  cmd_reserved,
-  "CHECK MEDIA CARD TYPE",
-  cmd_reserved_mcpt,
-  cmd_reserved_mcpt,
-  cmd_reserved_mcpt,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  cmd_reserved,
-  "GET MEDIA STATUS",
-  "ACKNOWLEDGE MEDIA CHANGE [RET-4]",
-  "BOOT POST-BOOT [RET-4]",
-  "BOOT PRE-BOOT [RET-4]",
-  "MEDIA LOCK",
-  "MEDIA UNLOCK",
-/*-------------------------------------------------- E0h-EFh -----*/
-  "STANDBY IMMEDIATE",
-  "IDLE IMMEDIATE",
-  "STANDBY",
-  "IDLE",
-  "READ BUFFER",
-  "CHECK POWER MODE",
-  "SLEEP",
-  "FLUSH CACHE",
-  "WRITE BUFFER",
-  "WRITE SAME [RET-4]",  /* Warning!  This command is retired but the value of
-                            f_reg is used in look_up_ata_command().  If this
-                            command code is reclaimed in a future standard then
-                            be sure to update look_up_ata_command(). */
-  "FLUSH CACHE EXIT",
-  cmd_reserved,
-  "IDENTIFY DEVICE",
-  "MEDIA EJECT",
-  "IDENTIFY DEVICE DMA [OBS-4]",
-  "SET FEATURES",
-/*-------------------------------------------------- F0h-FFh -----*/
-  cmd_vendor_specific,
-  "SECURITY SET PASSWORD",
-  "SECURITY UNLOCK",
-  "SECURITY ERASE PREPARE",
-  "SECURITY ERASE UNIT",
-  "SECURITY FREEZE LOCK",
-  "SECURITY DISABLE PASSWORD",
-  cmd_vendor_specific,
-  "READ NATIVE MAX ADDRESS",
-  "SET MAX",
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific,
-  cmd_vendor_specific
-};
-
-/* Returns the name of the command (and possibly sub-command) with the given
-   command code and feature register values.   For most command codes this
-   simply returns the corresponding entry in the command_table array, but for
-   others the value of the feature register specifies a subcommand or
-   distinguishes commands. */
-const char *look_up_ata_command(unsigned char c_code, unsigned char f_reg) {
-
-  // check that command table not messed up.  The compiler will issue
-  // warnings if there are too many array elements, but won't issue
-  // warnings if there are not enough of them.
-  if (sizeof(command_table) != sizeof(char *)*COMMAND_TABLE_SIZE){
-    fprintf(stderr, 
-	    "Problem in atacmdnames.c.  Command Table command_table[] does\n"
-	    "not have %d entries!  It has %d entries. Please fix it.\n",
-	    COMMAND_TABLE_SIZE, (int)(sizeof(command_table)/sizeof(char *)));
-    abort();
-  }
-
-  switch (c_code) {
-  case 0x00:  /* NOP */
-    switch (f_reg) {
-    case 0x00:
-      return "NOP [Abort queued commands]";
-    case 0x01:
-      return "NOP [Don't abort queued commands]";
-    default:
-      return "NOP [Reserved subcommand]";
-    }
-  case 0x92:  /* DOWNLOAD MICROCODE */
-    switch (f_reg) {
-    case 0x01:
-      return "DOWNLOAD MICROCODE [Temporary]";
-    case 0x07:
-      return "DOWNLOAD MICROCODE [Save]";
-    default:
-      return "DOWNLOAD MICROCODE [Reserved subcommand]";
-    }
-  case 0xB0:  /* SMART */
-    switch (f_reg) {
-    case 0xD0:
-      return "SMART READ DATA";
-    case 0xD1:
-      return "SMART READ ATTRIBUTE THRESHOLDS [OBS-4]";
-    case 0xD2:
-      return "SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE";
-    case 0xD3:
-      return "SMART SAVE ATTRIBUTE VALUES [OBS-6]";
-    case 0xD4:
-      return "SMART EXECUTE OFF-LINE IMMEDIATE";
-    case 0xD5:
-      return "SMART READ LOG";
-    case 0xD6:
-      return "SMART WRITE LOG";
-    case 0xD7:
-      return "SMART WRITE ATTRIBUTE THRESHOLDS [NS, OBS-4]";
-    case 0xD8:
-      return "SMART ENABLE OPERATIONS";
-    case 0xD9:
-      return "SMART DISABLE OPERATIONS";
-    case 0xDA:
-      return "SMART RETURN STATUS";
-    case 0xDB:
-      return "SMART EN/DISABLE AUTO OFFLINE [NS (SFF-8035i)]";
-    default:
-        if (f_reg >= 0xE0)
-          return "[Vendor specific SMART command]";
-        else
-          return "[Reserved SMART command]";
-    }
-  case 0xB1:  /* DEVICE CONFIGURATION */
-    switch (f_reg) {
-    case 0xC0:
-      return "DEVICE CONFIGURATION RESTORE";
-    case 0xC1:
-      return "DEVICE CONFIGURATION FREEZE LOCK";
-    case 0xC2:
-      return "DEVICE CONFIGURATION IDENTIFY";
-    case 0xC3:
-      return "DEVICE CONFIGURATION SET";
-    default:
-      return "DEVICE CONFIGURATION [Reserved command]";
-    }
-  case 0xE9:  /* WRITE SAME */
-    switch (f_reg) {
-    case 0x22:
-      return "WRITE SAME [Start specified] [RET-4]";
-    case 0xDD:
-      return "WRITE SAME [Start unspecified] [RET-4]";
-    default:
-      return "WRITE SAME [Invalid subcommand] [RET-4]";
-    } 
-  case 0xEF:  /* SET FEATURES */
-    switch (f_reg) {
-    case 0x01:
-      return "SET FEATURES [Enable 8-bit PIO]";
-    case 0x02:
-      return "SET FEATURES [Enable write cache]";
-    case 0x03:
-      return "SET FEATURES [Set transfer mode]";
-    case 0x04:
-      return "SET FEATURES [Enable auto DR] [OBS-4]";
-    case 0x05:
-      return "SET FEATURES [Enable APM]";
-    case 0x06:
-      return "SET FEATURES [Enable Pwr-Up In Standby]";
-    case 0x07:
-      return "SET FEATURES [Set device spin-up]";
-    case 0x09:
-      return "SET FEATURES [Reserved (address offset)]";
-    case 0x0A:
-      return "SET FEATURES [Enable CFA power mode 1]";
-    case 0x10:
-      return "SET FEATURES [Reserved for Serial ATA]";
-    case 0x20:
-      return "SET FEATURES [Set Time-ltd R/W WCT]";
-    case 0x21:
-      return "SET FEATURES [Set Time-ltd R/W EH]";
-    case 0x31:
-      return "SET FEATURES [Disable Media Status Notf]";
-    case 0x33:
-      return "SET FEATURES [Disable retry] [OBS-4]";
-    case 0x42:
-      return "SET FEATURES [Enable AAM]";
-    case 0x43:
-      return "SET FEATURES [Set Max Host I/F S Times]";
-    case 0x44:
-      return "SET FEATURES [Length of VS data] [OBS-4]";
-    case 0x54:
-      return "SET FEATURES [Set cache segs] [OBS-4]";
-    case 0x55:
-      return "SET FEATURES [Disable read look-ahead]";
-    case 0x5D:
-      return "SET FEATURES [Enable release interrupt]";
-    case 0x5E:
-      return "SET FEATURES [Enable SERVICE interrupt]";
-    case 0x66:
-      return "SET FEATURES [Disable revert defaults]";
-    case 0x77:
-      return "SET FEATURES [Disable ECC] [OBS-4]";
-    case 0x81:
-      return "SET FEATURES [Disable 8-bit PIO]";
-    case 0x82:
-      return "SET FEATURES [Disable write cache]";
-    case 0x84:
-      return "SET FEATURES [Disable auto DR] [OBS-4]";
-    case 0x85:
-      return "SET FEATURES [Disable APM]";
-    case 0x86:
-      return "SET FEATURES [Disable Pwr-Up In Standby]";
-    case 0x88:
-      return "SET FEATURES [Disable ECC] [OBS-4]";
-    case 0x89:
-      return "SET FEATURES [Reserved (address offset)]";
-    case 0x8A:
-      return "SET FEATURES [Disable CFA power mode 1]";
-    case 0x90:
-      return "SET FEATURES [Reserved for Serial ATA]";
-    case 0x95:
-      return "SET FEATURES [Enable Media Status Notf]";
-    case 0x99:
-      return "SET FEATURES [Enable retries] [OBS-4]";
-    case 0x9A:
-      return "SET FEATURES [Set max avg curr] [OBS-4]";
-    case 0xAA:
-      return "SET FEATURES [Enable read look-ahead]";
-    case 0xAB:
-      return "SET FEATURES [Set max prefetch] [OBS-4]";
-    case 0xBB:
-      return "SET FEATURES [4 bytes VS data] [OBS-4]";
-    case 0xC2:
-      return "SET FEATURES [Disable AAM]";
-    case 0xCC:
-      return "SET FEATURES [Enable revert to defaults]";
-    case 0xDD:
-      return "SET FEATURES [Disable release interrupt]";
-    case 0xDE:
-      return "SET FEATURES [Disable SERVICE interrupt]";
-    case 0xE0:
-      return "SET FEATURES [Obsolete subcommand]";
-    default:
-      if (f_reg >= 0xF0)
-        return "SET FEATURES [Reserved for CFA]";
-      else
-        return "SET FEATURES [Reserved subcommand]";
-    }
-  case 0xF9:  /* SET MAX */
-    switch (f_reg) {
-    case 0x00:
-      return "SET MAX ADDRESS [OBS-6]";
-    case 0x01:
-      return "SET MAX SET PASSWORD";
-    case 0x02:
-      return "SET MAX LOCK";
-    case 0x03:
-      return "SET MAX UNLOCK";
-    case 0x04:
-      return "SET MAX FREEZE LOCK";
-    default:
-      return "[Reserved SET MAX command]";
-    }
-  default:
-    return command_table[c_code];
-  }
-}
diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp
deleted file mode 100644
index 553a54c90d79fa1de6c2c80074354e1a5face568..0000000000000000000000000000000000000000
--- a/sm5/atacmds.cpp
+++ /dev/null
@@ -1,1680 +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 "extern.h"
-#include "utility.h"
-
-const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.129 2003/10/27 11:11:57 ballen4705 Exp $" ATACMDS_H_CVSID EXTERN_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// These Drive Identity tables are taken from hdparm 5.2, and are also
-// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command.  Note
-// that SMART was first added into the ATA/ATAPI-3 Standard with
-// Revision 3 of the document, July 25, 1995.  Look at the "Document
-// Status" revision commands at the beginning of
-// http://www.t13.org/project/d2008r6.pdf to see this.
-#define NOVAL_0			0x0000
-#define NOVAL_1			0xffff
-/* word 81: minor version number */
-#define MINOR_MAX 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 -- if needed, modify ataPrintSmartAttribRawValue()
-// 3 -  if needed, modify ataPrintSmartAttribName()
-// 4 -- add #define PRESET_N_DESCRIPTION at top of knowndrives.c
-// 5 -- add drive in question into knowndrives[] table in knowndrives.c
-// 6 -- update smartctl.8
-// 7 -- update smartd.8
-// 8 -- do "make smartd.conf.5" to update smartd.conf.5
-// 9 -- update CHANGELOG file
-const char *vendorattributeargs[] = {
-  // 0  defs[9]=1
-  "9,minutes",
-  // 1  defs[9]=3
-  "9,seconds",
-  // 2  defs[9]=2
-  "9,temp",
-  // 3  defs[220]=1
-  "220,temp",
-  // 4  defs[*]=253
-  "N,raw8",
-  // 5  defs[*]=254
-  "N,raw16",
-  // 6  defs[*]=255
-  "N,raw48",
-  // 7  defs[200]=1
-  "200,writeerrorcount",
-  // 8  defs[9]=4
-  "9,halfminutes",
-  // 9  defs[194]=1
-  "194,10xCelsius",
-  // 10 defs[194]=2
-  "194,unknown",
-  // 11 defs[193]=1
-  "193,loadunload",
-  // 12 defs[201]=1
-  "201,detectedtacount",
-  // 13 defs[192]=1
-  "192,emergencyretractcyclect",
-  // 14 defs[198]=1
-  "198,offlinescanuncsectorct",
-  // NULL should always terminate the array
-  NULL
-};
-
-// This is a utility function for parsing pairs like "9,minutes" or
-// "220,temp", and putting the correct flag into the attributedefs
-// array.  Returns 1 if problem, 0 if pair has been recongized.
-int parse_attribute_def(char *pair, unsigned char **defsptr){
-  int i,j;
-  char temp[32];
-  unsigned char *defs;
-
-  // If array does not exist, allocate it
-  if (!*defsptr && !(*defsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM, 1))){
-    pout("Out of memory in parse_attribute_def\n");
-    EXIT(1);
-  }
-
-  defs=*defsptr;
-
-  // look along list and see if we find the pair
-  for (i=0; vendorattributeargs[i] && strcmp(pair, vendorattributeargs[i]); i++);
-
-  switch (i) {
-  case 0:
-    // attribute 9 is power on time in minutes
-    defs[9]=1;
-    return 0;
-  case 1:
-    // attribute 9 is power-on-time in seconds
-    defs[9]=3;
-    return 0;
-  case 2:
-    // attribute 9 is temperature in celsius
-    defs[9]=2;
-    return 0;
-  case 3:
-    // attribute 220 is temperature in celsius
-    defs[220]=1;
-    return 0;
-  case 4:
-    // print all attributes in raw 8-bit form
-    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)
-      defs[j]=253;
-    return 0;
-  case 5:
-    // print all attributes in raw 16-bit form
-    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)
-      defs[j]=254;
-    return 0;
-  case 6:
-    // print all attributes in raw 48-bit form
-    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)
-      defs[j]=255;
-    return 0;
-  case 7:
-    // attribute 200 is write error count
-    defs[200]=1;
-    return 0;
-  case 8:
-    // attribute 9 increments once every 30 seconds (power on time
-    // measure)
-    defs[9]=4;
-    return 0;
-  case 9:
-    // attribute 194 is ten times disk temp in Celsius
-    defs[194]=1;
-    return 0;
-  case 10:
-    // attribute 194 is unknown
-    defs[194]=2;
-    return 0;
-  case 11:
-    // Hitachi : Attributes 193 has 2 values : 1 load, 1 normal unload
-    defs[193]=1;
-    return 0;
-  case 12:
-    // Fujitsu
-    defs[201]=1;
-    return 0;
-  case 13:
-    // Fujitsu
-    defs[192]=1;
-    return 0;
-  case 14:
-    // Fujitsu
-    defs[198]=1;
-    return 0;
-  default:
-    // pair not found
-    break;
-  }
-  // At this point, either the pair was not found, or it is of the
-  // form N,uninterpreted, in which case we need to parse N
-  j=sscanf(pair,"%d,%14s", &i, temp);
- 
-  // if no match to pattern, unrecognized
-  if (j!=2 || i<0 || i >255)
-    return 1;
-
-  // check for recognized strings
-  if (!strcmp(temp, "raw8")) {
-    defs[i]=253;
-    return 0;
-  }
-  
-  // check for recognized strings
-  if (!strcmp(temp, "raw16")) {
-    defs[i]=254;
-    return 0;
-  }
-  
-  // check for recognized strings
-  if (!strcmp(temp, "raw48")) {
-    defs[i]=255;
-    return 0;
-  }
- 
-  // didn't recognize the string
-  return 1;
-}
-
-// Structure used in sorting the array vendorattributeargs[].
-typedef struct vaa_pair_s {
-  const char *vaa;
-  const char *padded_vaa;
-} vaa_pair;
-
-// Returns a copy of s with all numbers of less than three digits padded with
-// leading zeros.  Returns NULL if there isn't enough memory available.  The
-// memory for the string is dynamically allocated and should be freed by the
-// caller.
-char *pad_numbers(const char *s)
-{
-  char c, *t, *u;
-  const char *r;
-  int i, len, ndigits = 0;
-
-  // Allocate the maximum possible amount of memory needed.
-  if (!(t = (char *)malloc(strlen(s)*2+2)))
-    return NULL;
-
-  // Copy the string s to t, padding any numbers of less than three digits
-  // with leading zeros.  The string is copied backwards to simplify the code.
-  r = s + strlen(s);
-  u = t;
-  while (( r-- >= s)) {
-    if (isdigit((int)*r))
-      ndigits++;
-    else if (ndigits > 0) {
-      while (ndigits++ < 3)
-        *u++ = '0';
-      ndigits = 0;
-    }
-    *u++ = *r;
-  }
-  *u = '\0';
-
-  // Reverse the string in t.
-  len = strlen(t);
-  for (i = 0; i < len/2; i++) {
-    c          = t[i];
-    t[i]       = t[len-1-i];
-    t[len-1-i] = c;
-  }
-
-  return t;
-}
-
-// Comparison function for qsort().  Used by sort_vendorattributeargs().
-int compare_vaa_pairs(const void *a, const void *b)
-{
-  vaa_pair *p = (vaa_pair *)a;
-  vaa_pair *q = (vaa_pair *)b;
-
-  return strcmp(p->padded_vaa, q->padded_vaa);
-}
-
-// Returns a sorted list of vendorattributeargs or NULL if there is not enough
-// memory available.  The memory for the list is allocated dynamically and
-// should be freed by the caller.
-// To perform the sort, any numbers in the strings are padded out to three
-// digits by adding leading zeros.  For example,
-//
-//    "9,minutes"  becomes  "009,minutes"
-//    "N,raw16"    becomes  "N,raw016"
-//
-// and the original strings are paired with the padded strings.  The list of
-// pairs is then sorted by comparing the padded strings (using strcmp) and the
-// result is then the list of unpadded strings.
-//
-const char **sort_vendorattributeargs(void) {
-  const char **ps, **sorted_list = NULL;
-  vaa_pair *pairs, *pp;
-  int count, i;
-
-  // Figure out how many strings are in vendorattributeargs[] (not including
-  // the terminating NULL).
-  count = (sizeof vendorattributeargs) / sizeof(char *) - 1;
-
-  // Construct a list of pairs of strings from vendorattributeargs[] and their
-  // padded equivalents.
-  if (!(pairs = (vaa_pair *)malloc(sizeof(vaa_pair) * count)))
-    goto END;
-  for (ps = vendorattributeargs, pp = pairs; *ps; ps++, pp++) {
-    pp->vaa = *ps;
-    if (!(pp->padded_vaa = pad_numbers(*ps)))
-      goto END;
-  }
-
-  // Sort the array of vaa_pair structures by comparing the padded strings
-  // using strcmp().
-  qsort(pairs, count, sizeof(vaa_pair), compare_vaa_pairs);
-
-  // Construct the sorted list of strings.
-  if (!(sorted_list = (const char **)malloc(sizeof vendorattributeargs)))
-    goto END;
-  for (ps = sorted_list, pp = pairs, i = 0; i < count; ps++, pp++, i++)
-    *ps = pp->vaa;
-  *ps = NULL;
-
-END:
-  if (pairs) {
-    for (i = 0; i < count; i++)
-      if (pairs[i].padded_vaa)
-        free((void *)pairs[i].padded_vaa);
-    free((void *)pairs);
-  }
-
-  // If there was a problem creating the list then sorted_list should now
-  // contain NULL.
-  return sorted_list;
-}
-
-// Function to return a multiline string containing a list of the arguments in 
-// vendorattributeargs[].  The strings are preceeded by tabs and followed
-// (except for the last) by newlines.
-// This function allocates the required memory for the string and the caller
-// must use free() to free it.  It returns NULL if the required memory can't
-// be allocated.
-char *create_vendor_attribute_arg_list(void){
-  const char **ps, **sorted;
-  char *s;
-  int len;
-
-  // Get a sorted list of vendor attribute arguments.  If the sort fails
-  // (which should only happen if the system is really low on memory) then just
-  // use the unordered list.
-  if (!(sorted = (const char **) sort_vendorattributeargs()))
-    sorted = vendorattributeargs;
-
-  // Calculate the required number of characters
-  len = 1;                // At least one char ('\0')
-  for (ps = sorted; *ps != NULL; ps++) {
-    len += 1;             // For the tab
-    len += strlen(*ps);   // For the actual argument string
-    if (*(ps+1))
-      len++;              // For the newline if required
-  }
-
-  // Attempt to allocate memory for the string
-  if (!(s = (char *)malloc(len)))
-    return NULL;
-
-  // Construct the string
-  *s = '\0';
-  for (ps = sorted; *ps != NULL; ps++) {
-    strcat(s, "\t");
-    strcat(s, *ps);
-    if (*(ps+1))
-      strcat(s, "\n");
-  }
-
-  free(sorted);
-
-  // Return a pointer to the string
-  return s;
-}
-
-// swap two bytes.  Point to low address
-void swap2(char *location){
-  char tmp=*location;
-  *location=*(location+1);
-  *(location+1)=tmp;
-  return;
-}
-
-// swap four bytes.  Point to low address
-void swap4(char *location){
-  char tmp=*location;
-  *location=*(location+3);
-  *(location+3)=tmp;
-  swap2(location+1);
-  return;
-}
-
-// swap eight bytes.  Points to low address
-void swap8(char *location){
-  char tmp=*location;
-  *location=*(location+7);
-  *(location+7)=tmp;
-  tmp=*(location+1);
-  *(location+1)=*(location+6);
-  *(location+6)=tmp;
-  swap4(location+2);
-  return;
-}
-
-static char *commandstrings[]={
-  "SMART ENABLE",
-  "SMART DISABLE",
-  "SMART AUTOMATIC ATTRIBUTE SAVE",
-  "SMART IMMEDIATE OFFLINE",
-  "SMART AUTO OFFLINE",
-  "SMART STATUS",
-  "SMART STATUS CHECK",
-  "SMART READ ATTRIBUTE VALUES",
-  "SMART READ ATTRIBUTE THRESHOLDS",
-  "SMART READ LOG",
-  "IDENTIFY DEVICE",
-  "IDENTIFY PACKET DEVICE"
-};
-
-void prettyprint(unsigned char *stuff, char *name){
-  int i,j;
-  pout("\n===== [%s] DATA START (BASE-16) =====\n", name);
-  for (i=0; i<32; i++){
-    pout("%03d-%03d: ", 16*i, 16*(i+1)-1);
-    for (j=0; j<15; j++)
-      pout("%02x ",*stuff++);
-    pout("%02x\n",*stuff++);
-  }
-  pout("===== [%s] DATA END (512 Bytes) =====\n\n", name);
-}
-
-// This function provides the pretty-print reporting for SMART
-// commands: it implements the various -r "reporting" options for ATA
-// ioctls.
-int smartcommandhandler(int device, smart_command_set command, int select, char *data){
-  int retval;
-
-  // This conditional is true for commands that return data
-  int getsdata=(command==PIDENTIFY || 
-	        command==IDENTIFY || 
-	        command==READ_LOG || 
-	        command==READ_THRESHOLDS || 
-	        command==READ_VALUES);
-  
-  // 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){
-    pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
-    return -1;
-  }
-  
-  // The reporting is cleaner, and we will find coding bugs faster, if
-  // the commands that failed clearly return empty (zeroed) data
-  // structures
-  if (getsdata)
-    memset(data, '\0', 512);
-
-  // In case the command produces an error, we'll want to know what it is:
-  errno=0;
-  
-  // now execute the command
-  if (con->escalade)
-    retval=escalade_command_interface(device, con->escalade-1, command, select, data);
-  else
-    retval=ata_command_interface(device, command, select, data);
-  
-  // If reporting is enabled, say what output was produced by the command
-  if (con->reportataioctl){
-    if (errno)
-      pout("REPORT-IOCTL: DeviceFD=%d Command=%s returned %d errno=%d [%s]\n", 
-	   device, commandstrings[command], retval, errno, strerror(errno));
-    else
-      pout("REPORT-IOCTL: DeviceFD=%d Command=%s returned %d\n",
-	   device, commandstrings[command], retval);
-    
-    // if requested, pretty-print the output data structure
-    if (con->reportataioctl>1 && getsdata)
-      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.  Returns 0
-// if all OK.  Returns -1 if no ATA Device identity can be
-// established.  Returns >0 if Device is ATA Packet Device (not SMART
-// capable).  The value of the integer helps identify the type of
-// Packet device, which is useful so that the user can connect the
-// formal device number with whatever object is inside their computer.
-int ataReadHDIdentity (int device, struct ata_identify_device *buf){
-  unsigned short *rawstructure=(unsigned short *)buf;
-  unsigned char *rawbyte=(unsigned char *)buf;
-
-  // See if device responds either to IDENTIFY DEVICE or IDENTIFY
-  // PACKET DEVICE
-  if ((smartcommandhandler(device, IDENTIFY, 0, (char *)buf))){
-    if (smartcommandhandler(device, PIDENTIFY, 0, (char *)buf)){
-      return -1; 
-    }
-  }
-
-  if (isbigendian()){
-    unsigned short *alias=(unsigned short*)buf;
-    int i;
-    
-    // swap various capability words that are needed
-    swap2((char *)(alias+255)); 
-    for (i=80; i<=87; i++)
-      swap2((char *)(alias+i));
-  }
-  
-  // If there is a checksum there, validate it
-  if ((rawstructure[255] & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
-    checksumwarning("Drive Identity Structure");
-  
-  // If this is a PACKET DEVICE
-  if (rawbyte[1]>>7) {
-    if (
-	(rawbyte[160] || rawbyte[161])                  &&    // word 80 valid
-	(rawbyte[160]!=0xff || rawbyte[161]!=0xff)      &&    // word 80 valid
-        ((rawbyte[160] & 0xf0) || (rawbyte[161] & 0x8f))      // is ATA-4 through 14
-	)
-      // ATAPI-4 and on indicates device type in bits 8-12 of word 0:
-      return 1+(rawbyte[1] & 0x1f);
-    else
-      //  ATAPI 1-3 device -- let's guess a CDROM
-      return 6;
-  }
-
-  // Not a PACKET DEVICE
-  return 0;
-}
-
-// Returns ATA version as an integer, and a pointer to a string
-// describing which revision.  Note that Revision 0 of ATA-3 does NOT
-// support SMART.  For this one case we return -3 rather than +3 as
-// the version number.  See notes above.
-int ataVersionInfo (const char** description, struct ata_identify_device *drive, unsigned short *minor){
-  unsigned short major;
-  int i;
-
-  // check that arrays at the top of this file are defined
-  // consistently
-  if (sizeof(minor_str) != sizeof(char *)*(1+MINOR_MAX)){
-    pout("Internal error in ataVersionInfo().  minor_str[] size %d\n"
-	 "is not consistent with value of MINOR_MAX+1 = %d\n", 
-	 (int)(sizeof(minor_str)/sizeof(char *)), MINOR_MAX+1);
-    fflush(NULL);
-    abort();
-  }
-  if (sizeof(actual_ver) != sizeof(int)*(1+MINOR_MAX)){
-    pout("Internal error in ataVersionInfo().  actual_ver[] size %d\n"
-	 "is not consistent with value of MINOR_MAX = %d\n",
-	 (int)(sizeof(actual_ver)/sizeof(int)), MINOR_MAX+1);
-    fflush(NULL);
-    abort();
-  }
-
-  // get major and minor ATA revision numbers
-  major=drive->major_rev_num;
-  *minor=drive->minor_rev_num;
-  
-  // First check if device has ANY ATA version information in it
-  if (major==NOVAL_0 || major==NOVAL_1) {
-    *description=NULL;
-    return -1;
-  }
-  
-  // The minor revision number has more information - try there first
-  if (*minor && (*minor<=MINOR_MAX)){
-    int std = actual_ver[*minor];
-    if (std) {
-      *description=minor_str[*minor];
-      return std;
-    }
-  }
-  
-  // HDPARM has a very complicated algorithm from here on. Since SMART only
-  // exists on ATA-3 and later standards, let's punt on this.  If you don't
-  // like it, please fix it.  The code's in CVS.
-  for (i=15; i>0; i--)
-    if (major & (0x1<<i))
-      break;
-  
-  *description=NULL; 
-  if (i==0)
-    return 1;
-  else
-    return i;;
-}
-
-// returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
-int ataSmartSupport(struct ata_identify_device *drive){
-  unsigned short word82=drive->command_set_1;
-  unsigned short word83=drive->command_set_2;
-  
-  // check if words 82/83 contain valid info
-  if ((word83>>14) == 0x01)
-    // return value of SMART support bit 
-    return word82 & 0x0001;
-  
-  // since we can're rely on word 82, we don't know if SMART supported
-  return -1;
-}
-
-// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
-int ataIsSmartEnabled(struct ata_identify_device *drive){
-  unsigned short word85=drive->cfs_enable_1;
-  unsigned short word87=drive->csf_default;
-  
-  // check if words 85/86/87 contain valid info
-  if ((word87>>14) == 0x01)
-    // return value of SMART enabled bit
-    return word85 & 0x0001;
-  
-  // Since we can't rely word85, we don't know if SMART is enabled.
-  return -1;
-}
-
-
-// Reads SMART attributes into *data
-int ataReadSmartValues(int device, struct ata_smart_values *data){	
-  
-  if (smartcommandhandler(device, READ_VALUES, 0, (char *)data)){
-    syserror("Error SMART Values Read failed");
-    return -1;
-  }
-
-  // compute checksum
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART Attribute Data Structure");
-  
-  // byte swap if needed
-  if (isbigendian()){
-    int i;
-    swap2((char *)&(data->revnumber));
-    swap2((char *)&(data->total_time_to_complete_off_line));
-    swap2((char *)&(data->smart_capability));
-    for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-      struct ata_smart_attribute *x=data->vendor_attributes+i;
-      swap2((char *)&(x->flags));
-    }
-  }
-
-  return 0;
-}
-
-
-// This corrects some quantities that are byte reversed in the SMART
-// SELF TEST LOG
-void fixsamsungselftestlog(struct ata_smart_selftestlog *data){
-  int i;
-  
-  // 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);
-
-  // fix endian order, if needed
-  if (isbigendian()){
-    int i;
-    swap2((char*)&(data->revnumber));
-    for (i=0; i<21; i++){
-      struct ata_smart_selftestlog_struct *x=data->selftest_struct+i;
-      swap2((char *)&(x->timestamp));
-      swap4((char *)&(x->lbafirstfailure));
-    }
-  }
-
-  return 0;
-}
-
-
-// Reads the Log Directory (log #0).  Note: NO CHECKSUM!!
-int ataReadLogDirectory (int device, struct ata_smart_log_directory *data){	
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x00, (char *)data)){
-    return -1;
-  }
-
-  // swap endian order if needed
-  if (isbigendian()){
-    swap2((char *)&(data->logversion));
-  }
-  
-  return 0;
-}
-
-
-// Reads the selective self-test log (log #9)
-int ataReadSelectiveSelfTestLog(int device, struct ata_selective_self_test_log *data){	
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){
-    return -1;
-  }
-
-  // swap endian order if needed
-  if (isbigendian()){
-    int i;
-    swap2((char *)&(data->logversion));
-    for (i=0;i<5;i++){
-      swap8((char *)&(data->span[i].start));
-      swap8((char *)&(data->span[i].end));
-    }
-    swap8((char *)&(data->currentlba));
-    swap2((char *)&(data->currentspan));
-    swap2((char *)&(data->flags));
-    swap2((char *)&(data->pendingtime));
-  }
-  return 0;
-}
-
-#if DEVELOP_SELECTIVE_SELF_TEST
-// Writes the selective self-test log (log #9)
-int ataWriteSelectiveSelfTestLog(int device){	
-  int i;
-  struct ata_selective_self_test_log sstlog, *data=&sstlog;
-  unsigned char cksum=0;
-  unsigned char *ptr=(unsigned char *)data;
-
-  // Read log
-  ataReadSelectiveSelfTestLog(device, data);
-
-  // Clear spans
-  for (i=0; i<5; i++)
-    memset(data->span+i, 0, sizeof(struct test_span));
-
-  // Set spans for testing 
-  for (i=0; i<con->smartselectivenumspans; i++){
-    data->span[i].start = con->smartselectivespan[i][0];
-    data->span[i].end   = con->smartselectivespan[i][1];
-  }
-
-  // Do NOT perform off-line scan after selective 
-  data->flags=0;
-  data->undefined=data->checksum=0;
-
-  // Put in correct checksum
-  for (i=0; i<512; i++)
-    cksum+=ptr[i];
-  cksum=~cksum;
-  cksum+=1;
-  data->checksum=cksum;
-
-    // swap endian order if needed
-  if (isbigendian()){
-    int i;
-    swap2((char *)&(data->logversion));
-    for (i=0;i<5;i++){
-      swap8((char *)&(data->span[i].start));
-      swap8((char *)&(data->span[i].end));
-    }
-    swap8((char *)&(data->currentlba));
-    swap2((char *)&(data->currentspan));
-    swap2((char *)&(data->flags));
-    swap2((char *)&(data->pendingtime));
-  }
-
-  // send data to device -- ioctl NOT implemented yet!
-  if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){
-    return -1;
-  }
-
-  return 0;
-}
-#endif
-
-
-// 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));
-  }
-  return;
-}
-
-void fixsamsungerrorlog2(struct ata_smart_errorlog *data){
-  // Device error count in bytes 452-3
-  swap2((char *)&(data->ata_error_count));
-  return;
-}
-
-// Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
-// Error Log is #2, and the Extended Comprehensive SMART Error log is
-// #3
-int ataReadErrorLog (int device, struct ata_smart_errorlog *data){	
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){
-    syserror("Error SMART Error Log Read failed");
-    return -1;
-  }
-  
-  // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART ATA Error Log Structure");
-  
-  // Some disks have the byte order reversed in some SMART Summary
-  // Error log entries
-  if (con->fixfirmwarebug == FIX_SAMSUNG)
-    fixsamsungerrorlog(data);
-  else if (con->fixfirmwarebug == FIX_SAMSUNG2)
-    fixsamsungerrorlog2(data);
-
-  // Correct endian order if necessary
-  if (isbigendian()){
-    int i,j;
-    
-    // Device error count in bytes 452-3
-    swap2((char *)&(data->ata_error_count));
-    
-    // step through 5 error log data structures
-    for (i=0; i<5; i++){
-      // step through 5 command data structures
-      for (j=0; j<5; j++)
-	// Command data structure 4-byte millisec timestamp
-	swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
-      // Error data structure life timestamp
-      swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
-    }
-  }
-  
-  return 0;
-}
-
-int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
-  
-  // get data from device
-  if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
-    syserror("Error SMART Thresholds Read failed");
-    return -1;
-  }
-  
-  // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
-    checksumwarning("SMART Attribute Thresholds Structure");
-  
-  // byte swap if needed
-  if (isbigendian())
-    swap2((char *)&(data->revnumber));
-
-  return 0;
-}
-
-int ataEnableSmart (int device ){	
-  if (smartcommandhandler(device, ENABLE, 0, NULL)){
-    syserror("Error SMART Enable failed");
-    return -1;
-  }
-  return 0;
-}
-
-int ataDisableSmart (int device ){	
-  
-  if (smartcommandhandler(device, DISABLE, 0, NULL)){
-    syserror("Error SMART Disable failed");
-    return -1;
-  }  
-  return 0;
-}
-
-int ataEnableAutoSave(int device){  
-  if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
-    syserror("Error SMART Enable Auto-save failed");
-    return -1;
-  }
-  return 0;
-}
-
-int ataDisableAutoSave(int device){
-  
-  if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
-    syserror("Error SMART Disable Auto-save failed");
-    return -1;
-  }
-  return 0;
-}
-
-// In *ALL* ATA standards the Enable/Disable AutoOffline command is
-// marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
-// vendors still support it for backwards compatibility. IBM documents
-// it for some drives.
-int ataEnableAutoOffline (int device ){	
-  
-  /* timer hard coded to 4 hours */  
-  if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
-    syserror("Error SMART Enable Automatic Offline failed");
-    return -1;
-  }
-  return 0;
-}
-
-// Another Obsolete Command.  See comments directly above, associated
-// with the corresponding Enable command.
-int ataDisableAutoOffline (int device ){	
-  
-  if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
-    syserror("Error SMART Disable Automatic Offline failed");
-    return -1;
-  }
-  return 0;
-}
-
-// If SMART is enabled, supported, and working, then this call is
-// guaranteed to return 1, else zero.  Silent inverse of
-// ataSmartStatus()
-int ataDoesSmartWork(int device){	
-  return !smartcommandhandler(device, STATUS, 0, NULL);
-}
-
-// This function uses a different interface (DRIVE_TASK) than the
-// other commands in this file.
-int ataSmartStatus2(int device){
-
-  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;
-}
-
-// 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,select=0;
-
-  // Boolean, if set, says test is captive
-  cap=testtype & CAPTIVE_MASK;
-  
-  // Boolean, if set, then test is selective
-  select=(testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST);
-
-  // 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";
-#if DEVELOP_SELECTIVE_SELF_TEST
-  else if (select){
-    int i;
-    type="Selective self-test";
-    pout("Using test spans:\n");
-    for (i = 0; i < con->smartselectivenumspans; i++)
-      pout("%lld - %lld\n",
-	   con->smartselectivespan[i][0],
-	   con->smartselectivespan[i][1]);
-  }
-#endif
-  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);
-
-#if DEVELOP_SELECTIVE_SELF_TEST
-  // If doing a selective self-test, issue WRITE_LOG command
-  if (select && ataWriteSelectiveSelfTestLog(device)){
-    char errormsg[256];
-    sprintf(errormsg,"Command \"%s\" failed to WRITE Selective Self-Test Log ",cmdmsg); 
-    syserror(errormsg);
-    pout("\n");
-    return -1;
-  }
-#endif
-
-  // Now send the command to test
-  errornum=smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL);
-
-  if (errornum && !(cap && errno==EIO)){
-    char errormsg[128];
-    sprintf(errormsg,"Command \"%s\" failed",cmdmsg); 
-    syserror(errormsg);
-    pout("\n");
-    return -1;
-  }
-  
-  // Since the command succeeded, tell user
-  if (testtype==ABORT_SELF_TEST)
-    pout("Self-testing aborted!\n");
-  else
-    pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg);
-  return 0;
-}
-
-/* Test Time Functions */
-int TestTime(struct ata_smart_values *data,int testtype){
-  switch (testtype){
-  case OFFLINE_FULL_SCAN:
-    return (int) data->total_time_to_complete_off_line;
-  case SHORT_SELF_TEST:
-  case SHORT_CAPTIVE_SELF_TEST:
-    return (int) data->short_test_completion_time;
-  case EXTEND_SELF_TEST:
-  case EXTEND_CAPTIVE_SELF_TEST:
-    return (int) data->extend_test_completion_time;
-  case CONVEYANCE_SELF_TEST:
-  case CONVEYANCE_CAPTIVE_SELF_TEST:
-    return (int) data->conveyance_test_completion_time;
-  default:
-    return 0;
-  }
-}
-
-// This function tells you both about the ATA error log and the
-// self-test error log capability.  The bit is poorly documented in
-// the ATA/ATAPI standard.  SMART error logging is also indicated in
-// bit 0 of DEVICE IDENTIFY word 87 (if top two bits of word 87 match
-// pattern 01).  However this was only introduced in ATA-6 (but error
-// logging was in ATA-5).
-int isSmartErrorLogCapable ( struct ata_smart_values *data){
-   return data->errorlog_capability & 0x01;
-}
-
-int isGeneralPurposeLoggingCapable(struct ata_identify_device *identity){
-  unsigned short word84=identity->command_set_extension;
-  unsigned short word87=identity->csf_default;
-
-  // If bit 14 of word 84 is set to one and bit 15 of word 84 is
-  // cleared to zero, the contents of word 84 contains valid support
-  // information. If not, support information is not valid in this
-  // word.
-  if ((word84>>14) == 0x01)
-    // If bit 5 of word 84 is set to one, the device supports the
-    // General Purpose Logging feature set.
-    return (word84 & (0x01 << 5));
-  
-  // If bit 14 of word 87 is set to one and bit 15 of word 87 is
-  // cleared to zero, the contents of words (87:85) contain valid
-  // information. If not, information is not valid in these words.  
-  if ((word87>>14) == 0x01)
-    // If bit 5 of word 87 is set to one, the device supports
-    // the General Purpose Logging feature set.
-    return (word87 & (0x01 << 5));
-
-  // not capable
-  return 0;
-}
-
-
-// SMART self-test capability is also indicated in bit 1 of DEVICE
-// IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
-// However this was only introduced in ATA-6 (but self-test log was in
-// ATA-5).
-int isSupportExecuteOfflineImmediate(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x01;
-}
-// Note in the ATA-5 standard, the following bit is listed as "Vendor
-// Specific".  So it may not be reliable. The only use of this that I
-// have found is in IBM drives, where it is well-documented.  See for
-// example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
-// hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
-int isSupportAutomaticTimer(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x02;
-}
-int isSupportOfflineAbort(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x04;
-}
-int isSupportOfflineSurfaceScan(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x08;
-}
-int isSupportSelfTest (struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x10;
-}
-int isSupportConveyanceSelfTest(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x20;
-}
-int isSupportSelectiveSelfTest(struct ata_smart_values *data){
-   return data->offline_data_collection_capability & 0x40;
-}
-
-
-
-// Loop over all valid attributes.  If they are prefailure attributes
-// and are at or below the threshold value, then return the ID of the
-// first failing attribute found.  Return 0 if all prefailure
-// attributes are in bounds.  The spec says "Bit 0
-// -Pre-failure/advisory - If the value of this bit equals zero, an
-// attribute value less than or equal to its corresponding attribute
-// threshold indicates an advisory condition where the usage or age of
-// the device has exceeded its intended design life period. If the
-// value of this bit equals one, an atribute value less than or equal
-// to its corresponding attribute threshold indicates a pre-failure
-// condition where imminent loss of data is being predicted."
-
-
-// onlyfailed=0 : are or were any age or prefailure attributes <= threshold
-// onlyfailed=1:  are any prefailure attributes <= threshold now
-int ataCheckSmart(struct ata_smart_values *data,
-		  struct ata_smart_thresholds *thresholds,
-		  int onlyfailed){
-  int i;
-  
-  // loop over all attributes
-  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-
-    // pointers to disk's values and vendor's thresholds
-    struct ata_smart_attribute *disk=data->vendor_attributes+i;
-    struct ata_smart_threshold_entry *thre=thresholds->thres_entries+i;
- 
-    // consider only valid attributes
-    if (disk->id && thre->id){
-      int failednow,failedever;
-      
-      failednow =disk->current <= thre->threshold;
-      failedever=disk->worst   <= thre->threshold;
-      
-      if (!onlyfailed && failedever)
-	return disk->id;
-      
-      if (onlyfailed && failednow && ATTRIBUTE_FLAGS_PREFAILURE(disk->flags))
-	return disk->id;      
-    }
-  }
-  return 0;
-}
-
-
-
-// This checks the n'th attribute in the attribute list, NOT the
-// attribute with id==n.  If the attribute does not exist, or the
-// attribute is > threshold, then returns zero.  If the attribute is
-// <= threshold (failing) then we the attribute number if it is a
-// prefail attribute.  Else we return minus the attribute number if it
-// is a usage attribute.
-int ataCheckAttribute(struct ata_smart_values *data,
-		      struct ata_smart_thresholds *thresholds,
-		      int n){
-  struct ata_smart_attribute *disk;
-  struct ata_smart_threshold_entry *thre;
-  
-  if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !data || !thresholds)
-    return 0;
-  
-  // pointers to disk's values and vendor's thresholds
-  disk=data->vendor_attributes+n;
-  thre=thresholds->thres_entries+n;
-
-  if (!disk || !thre)
-    return 0;
-  
-  // consider only valid attributes, check for failure
-  if (!disk->id || !thre->id || (disk->id != thre->id) || disk->current> thre->threshold)
-    return 0;
-  
-  // We have found a failed attribute.  Return positive or negative? 
-  if (ATTRIBUTE_FLAGS_PREFAILURE(disk->flags))
-    return disk->id;
-  else
-    return -1*(disk->id);
-}
-
-
-// This routine prints the raw value of an attribute as a text string
-// into out. It also returns this 48-bit number as a long long.  The
-// array defs[] contains non-zero values if particular attributes have
-// non-default interpretations.
-
-long long ataPrintSmartAttribRawValue(char *out, 
-				      struct ata_smart_attribute *attribute,
-				      unsigned char *defs){
-  long long rawvalue;
-  unsigned word[3];
-  int j;
-  unsigned char select;
-  
-  // convert the six individual bytes to a long long (8 byte) integer.
-  // This is the value that we'll eventually return.
-  rawvalue = 0;
-  for (j=0; j<6; j++) {
-    // This looks a bit roundabout, but is necessary.  Don't
-    // succumb to the temptation to use raw[j]<<(8*j) since under
-    // the normal rules this will be promoted to the native type.
-    // On a 32 bit machine this might then overflow.
-    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];
-  }
-  
-  // if no data array, Attributes have default interpretations
-  if (defs)
-    select=defs[attribute->id];
-  else
-    select=0;
-
-  // Print six one-byte quantities.
-  if (select==253){
-    for (j=0; j<5; j++)
-      out+=sprintf(out, "%d ", attribute->raw[5-j]);
-    out+=sprintf(out, "%d ", attribute->raw[0]);
-    return rawvalue;
-  } 
-  
-  // Print three two-byte quantities
-  if (select==254){
-    out+=sprintf(out, "%d %d %d", word[2], word[1], word[0]); 
-    return rawvalue;
-  } 
-  
-  // Print one six-byte quantity
-  if (select==255){
-    out+=sprintf(out, "%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 (select==1){
-      // minutes
-      long long tmp1=rawvalue/60;
-      long long tmp2=rawvalue%60;
-      out+=sprintf(out, "%lluh+%02llum", tmp1, tmp2);
-    }
-    else if (select==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 (select==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;
-   // Load unload cycles
-  case 193:
-    if (select==1){
-      // loadunload
-      long load  =attribute->raw[0] + (attribute->raw[1]<<8) + (attribute->raw[2]<<16);
-      long unload=attribute->raw[3] + (attribute->raw[4]<<8) + (attribute->raw[5]<<16);
-      out+=sprintf(out, "%lu/%lu", load, unload);
-    }
-    else
-      // associated
-      out+=sprintf(out, "%llu", rawvalue);
-    break;
-    // Temperature
-  case 194:
-    if (select==1){
-      // ten times temperature in Celsius
-      int deg=word[0]/10;
-      int tenths=word[0]%10;
-      out+=sprintf(out, "%d.%d", deg, tenths);
-    }
-    else if (select==2)
-      // unknown attribute
-      out+=sprintf(out, "%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 *definitions){
-  char *name;
-  unsigned char val;
-
-  // If no data array, use default interpretations
-  if (definitions)
-    val=definitions[id];
-  else
-    val=0;
-
-  switch (id){
-    
-  case 1:
-    name="Raw_Read_Error_Rate";
-    break;
-  case 2:
-    name="Throughput_Performance";
-    break;
-  case 3:
-    name="Spin_Up_Time";
-    break;
-  case 4:
-    name="Start_Stop_Count";
-    break;
-  case 5:
-    name="Reallocated_Sector_Ct";
-    break;
-  case 6:
-    name="Read_Channel_Margin";
-    break;
-  case 7:
-    name="Seek_Error_Rate";
-    break;
-  case 8:
-    name="Seek_Time_Performance";
-    break;
-  case 9:
-    switch (val) {
-    case 1:
-      name="Power_On_Minutes";
-      break;
-    case 2:
-      name="Temperature_Celsius";
-      break;
-    case 3:
-      name="Power_On_Seconds";
-      break;
-    case 4:
-      name="Power_On_Half_Minutes";
-      break;
-    default:
-      name="Power_On_Hours";
-      break;
-    }
-    break;
-  case 10:
-    name="Spin_Retry_Count";
-    break;
-  case 11:
-    name="Calibration_Retry_Count";
-    break;
-  case 12:
-    name="Power_Cycle_Count";
-    break;
-  case 13:
-    name="Read_Soft_Error_Rate";
-    break;
-  case 191:
-    name="G-Sense_Error_Rate";
-    break;
-  case 192:
-    switch (val) {
-    case 1:
-      // Fujitsu
-      name="Emergency_Retract_Cycle_Ct";
-      break;
-    default:
-      name="Power-Off_Retract_Count";
-      break;
-    }
-    break;
-  case 193:
-    name="Load_Cycle_Count";
-    break;
-  case 194:
-    switch (val){
-    case 1:
-      // Samsung SV1204H with RK100-13 firmware
-      name="Temperature_Celsius_x10";
-      break;
-    case 2:
-      // for disks with no temperature Attribute
-      name="Unknown_Attribute";
-      break;
-    default:
-      name="Temperature_Celsius";
-      break;
-    }
-    break;
-  case 195:
-    // Fujitsu name="ECC_On_The_Fly_Count";
-    name="Hardware_ECC_Recovered";
-    break;
-  case 196:
-    name="Reallocated_Event_Count";
-    break;
-  case 197:
-    name="Current_Pending_Sector";
-    break;
-  case 198:
-    switch (val){
-    case 1:
-      // Fujitsu
-      name="Off-line_Scan_UNC_Sector_Ct";
-      break;
-    default:
-      name="Offline_Uncorrectable";
-      break;
-    }
-    break;
-  case 199:
-    name="UDMA_CRC_Error_Count";
-    break;
-  case 200:
-    switch (val) {
-    case 1:
-      // Fujitsu MHS2020AT
-      name="Write_Error_Count";
-      break;
-    default:
-      // Western Digital
-      name="Multi_Zone_Error_Rate";
-      break;
-    }
-    break;
-  case 201:
-    switch (val) {
-    case 1:
-      // Fujitsu
-      name="Detected_TA_Count";
-      break;
-    default:
-      name="Soft_Read_Error_Rate";
-      break;
-    }
-    break;
-  case 202:
-    // Fujitsu
-    name="TA_Increase_Count";
-    // Maxtor: Data Address Mark Errors
-    break;
-  case 203:
-    // Fujitsu
-    name="Run_Out_Cancel";
-    // Maxtor: ECC Errors
-    break;
-  case 204:
-    // Fujitsu
-    name="Shock_Count_Write_Opern";
-    // Maxtor: Soft ECC Correction
-    break;
-  case 205:
-    // Fujitsu
-    name="Shock_Rate_Write_Opern";
-    // Maxtor: Thermal Aspirates
-    break;
-  case 206:
-    // Fujitsu
-    name="Flying_Height_Measurement";
-    break;
-  case 207:
-    // Maxtor
-    name="Spin_High_Current";
-    break;
-  case 208:
-    // Maxtor
-    name="Spin_Buzz";
-    break;
-  case 209:
-    // Maxtor
-    name="Offline_Seek_Performnce";
-    break;
-  case 220:
-    switch (val) {
-    case 1:
-      name="Temperature_Celsius";
-      break;
-    default:
-      name="Disk_Shift";
-      break;
-    }
-    break;
-  case 221:
-    name="G-Sense_Error_Rate";
-    break;
-  case 222:
-    name="Loaded_Hours";
-    break;
-  case 223:
-    name="Load_Retry_Count";
-    break;
-  case 224:
-    name="Load_Friction";
-    break;
-  case 225:
-    name="Load_Cycle_Count";
-    break;
-  case 226:
-    name="Load-in_Time";
-    break;
-  case 227:
-    name="Torq-amp_Count";
-    break;
-  case 228:
-    name="Power-off_Retract_Count";
-    break;
-  case 230:
-    // seen in IBM DTPA-353750
-    name="Head_Amplitude";
-    break;
-  case 231:
-    name="Temperature_Celsius";
-    break;
-  case 240:
-    name="Head_Flying_Hours";
-    break;
-  case 250:
-    name="Read_Error_Retry_Rate";
-    break;
-  default:
-    name="Unknown_Attribute";
-    break;
-  }
-  sprintf(out,"%3hu %s",(short int)id,name);
-  return;
-}
diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp
deleted file mode 100644
index 9d93aee890881f3d1cf2bab620c737bef87212ac..0000000000000000000000000000000000000000
--- a/sm5/ataprint.cpp
+++ /dev/null
@@ -1,1442 +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 "atacmdnames.h"
-#include "atacmds.h"
-#include "ataprint.h"
-#include "smartctl.h"
-#include "extern.h"
-#include "utility.h"
-#include "knowndrives.h"
-#include "config.h"
-
-const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.112 2003/10/27 20:59:04 ballen4705 Exp $"
-ATACMDNAMES_H_CVSID ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
-
-// for passing global control variables
-extern smartmonctrl *con;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
-// bytes.
-void swapbytes(char *out, const char *in, size_t n)
-{
-  size_t i;
-
-  for (i = 0; i < n; i += 2) {
-    out[i]   = in[i+1];
-    out[i+1] = in[i];
-  }
-}
-
-// Copies in to out, but removes leading and trailing whitespace.
-void trim(char *out, const char *in)
-{
-  int i, first, last;
-
-  // Find the first non-space character (maybe none).
-  first = -1;
-  for (i = 0; in[i]; i++)
-    if (!isspace((int)in[i])) {
-      first = i;
-      break;
-    }
-
-  if (first == -1) {
-    // There are no non-space characters.
-    out[0] = '\0';
-    return;
-  }
-
-  // Find the last non-space character.
-  for (i = strlen(in)-1; i >= first && isspace((int)in[i]); i--)
-    ;
-  last = i;
-
-  strncpy(out, in+first, last-first+1);
-  out[last-first+1] = '\0';
-}
-
-// Convenience function for formatting strings from ata_identify_device
-void formatdriveidstring(char *out, const char *in, int n)
-{
-  char tmp[65];
-
-  n = n > 64 ? 64 : n;
-  swapbytes(tmp, in, n);
-  tmp[n] = '\0';
-  trim(out, tmp);
-}
-
-// Function for printing ASCII byte-swapped strings, skipping white
-// space. Please note that this is needed on both big- and
-// little-endian hardware.
-void printswap(char *output, char *in, unsigned int n){
-  formatdriveidstring(output, in, n);
-  if (*output)
-    pout("%s\n", output);
-  else
-    pout("[No Information Found]\n");
-}
-
-/* For the given Command Register (CR) and Features Register (FR), attempts
- * to construct a string that describes the contents of the Status
- * Register (ST) and Error Register (ER).  The string is dynamically allocated
- * memory and the return value is a pointer to this string.  It is up to the
- * caller to free this memory.  If there is insufficient memory or if the
- * meanings of the flags of the error register are not known for the given
- * command then it returns NULL.
- *
- * The meanings of the flags of the error register for all commands are
- * described in the ATA spec and could all be supported here in theory.
- * Currently, only a few commands are supported (those that have been seen
- * to produce errors).  If many more are to be added then this function
- * should probably be redesigned.
- */
-char *construct_st_er_desc(unsigned char CR, unsigned char FR,
-                                 unsigned char ST, unsigned char ER)
-{
-  char *s;
-  char *error_flag[8];
-  int i;
-  /* If for any command the Device Fault flag of the status register is
-   * not used then used_device_fault should be set to 0 (in the CR switch
-   * below)
-   */
-  int uses_device_fault = 1;
-
-  /* A value of NULL means that the error flag isn't used */
-  for (i = 0; i < 8; i++)
-    error_flag[i] = NULL;
-
-  switch (CR) {
-  case 0x20:  /* READ SECTOR(S) */
-    error_flag[6] = "UNC";
-    error_flag[5] = "MC";
-    error_flag[4] = "IDNF";
-    error_flag[3] = "MCR";
-    error_flag[2] = "ABRT";
-    error_flag[1] = "NM";
-    error_flag[0] = "obs";
-    break;
-  case 0x25:  /* READ DMA EXT */
-  case 0xC8:  /* READ DMA */
-    error_flag[7] = "ICRC";
-    error_flag[6] = "UNC";
-    error_flag[5] = "MC";
-    error_flag[4] = "IDNF";
-    error_flag[3] = "MCR";
-    error_flag[2] = "ABRT";
-    error_flag[1] = "NM";
-    error_flag[0] = "obs";
-    break;
-  case 0x30:  /* WRITE SECTOR(S) */
-    error_flag[6] = "WP";
-    error_flag[5] = "MC";
-    error_flag[4] = "IDNF";
-    error_flag[3] = "MCR";
-    error_flag[2] = "ABRT";
-    error_flag[1] = "NM";
-    break;
-  case 0xA1:  /* IDENTIFY PACKET DEVICE */
-  case 0xEF:  /* SET FEATURES */
-  case 0x00:  /* NOP */
-    error_flag[2] = "ABRT";
-    break;
-  case 0xB0:  /* SMART */
-    switch(FR) {
-    case 0xD6:  /* SMART WRITE LOG */
-      error_flag[4] = "IDNF";
-      error_flag[2] = "ABRT";
-      break;
-    case 0xD9:  /* SMART DISABLE OPERATIONS */
-    case 0xDA:  /* SMART RETURN STATUS */
-      error_flag[2] = "ABRT";
-      break;
-    default:
-      return NULL;
-      break;
-    }
-    break;
-  case 0xCA:  /* WRITE DMA */
-    error_flag[7] = "ICRC";
-    error_flag[6] = "WP";
-    error_flag[5] = "MC";
-    error_flag[4] = "IDNF";
-    error_flag[3] = "MCR";
-    error_flag[2] = "ABRT";
-    error_flag[1] = "NM";
-    error_flag[0] = "obs";
-    break;
-  default:
-    return NULL;
-  }
-
-  /* 100 bytes -- that'll be plenty (OK, this is lazy!) */
-  if (!(s = (char *)malloc(100)))
-    return s;
-
-  s[0] = '\0';
-
-  /* We ignore any status flags other than Device Fault and Error */
-
-  if (uses_device_fault && (ST & (1 << 5))) {
-    strcat(s, "Device Fault");
-    if (ST & 1)  // Error flag
-      strcat(s, "; ");
-  }
-  if (ST & 1) {  // Error flag
-    int count = 0;
-
-    strcat(s, "Error: ");
-    for (i = 7; i >= 0; i--)
-      if ((ER & (1 << i)) && (error_flag[i])) {
-        if (count++ > 0)
-          strcat(s, ", ");
-        strcat(s, error_flag[i]);
-      }
-  }
-
-  return s;
-}
-
-void ataPrintDriveInfo (struct ata_identify_device *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, (char *)drive->model,40);
-
-  pout("Serial Number:    ");
-  printswap(serial, (char *)drive->serial_no,20);
-
-  pout("Firmware Version: ");
-  printswap(firm, (char *)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){
-  char *message=NULL;
-
-  // the final 7 bits
-  unsigned char stat=data->offline_data_collection_status & 0x7f;
-  
-  pout("Offline data collection status:  (0x%02x)\t",
-       (int)data->offline_data_collection_status);
-    
-  switch(stat){
-  case 0x00:
-    message="never started";
-    break;
-  case 0x02:
-    message="completed without error";
-    break;
-  case 0x04:
-    message="suspended by an interrupting command from host";
-    break;
-  case 0x05:
-    message="aborted by an interrupting command from host";
-    break;
-  case 0x06:
-    message="aborted by the device with a fatal error";
-    break;
-  default:
-    if (stat >= 0x40)
-      pout("Vendor Specific.\n");
-    else
-      pout("Reserved.\n");
-  }
-  
-  if (message)
-    // Off-line data collection status byte is not a reserved
-    // or vendor specific value
-    pout("Offline data collection activity was\n"
-	 "\t\t\t\t\t%s.\n", message);
-  
-  // Report on Automatic Data Collection Status.  Only IBM documents
-  // this bit.  See SFF 8035i Revision 2 for details.
-  if (data->offline_data_collection_status & 0x80)
-    pout("\t\t\t\t\tAuto Offline Data Collection: Enabled.\n");
-  else
-    pout("\t\t\t\t\tAuto Offline Data Collection: Disabled.\n");
-  
-  return;
-}
-
-void PrintSmartSelfExecStatus(struct ata_smart_values *data)
-{
-   pout("Self-test execution status:      ");
-   
-   switch (data->self_test_exec_status >> 4)
-   {
-      case 0:
-        pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t",
-                (int)data->self_test_exec_status);
-        pout("without error or no self-test has ever \n\t\t\t\t\tbeen run.\n");
-        break;
-       case 1:
-         pout("(%4d)\tThe self-test routine was aborted by\n\t\t\t\t\t",
-                 (int)data->self_test_exec_status);
-         pout("the host.\n");
-         break;
-       case 2:
-         pout("(%4d)\tThe self-test routine was interrupted\n\t\t\t\t\t",
-                 (int)data->self_test_exec_status);
-         pout("by the host with a hard or soft reset.\n");
-         break;
-       case 3:
-          pout("(%4d)\tA fatal error or unknown test error\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("occurred while the device was executing\n\t\t\t\t\t");
-          pout("its self-test routine and the device \n\t\t\t\t\t");
-          pout("was unable to complete the self-test \n\t\t\t\t\t");
-          pout("routine.\n");
-          break;
-       case 4:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("a test element that failed and the test\n\t\t\t\t\t");
-          pout("element that failed is not known.\n");
-          break;
-       case 5:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the electrical element of the test\n\t\t\t\t\t");
-          pout("failed.\n");
-          break;
-       case 6:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the servo (and/or seek) element of the \n\t\t\t\t\t");
-          pout("test failed.\n");
-          break;
-       case 7:
-          pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("the read element of the test failed.\n");
-          break;
-       case 15:
-          pout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t",
-                  (int)data->self_test_exec_status);
-          pout("%1d0%% of test remaining.\n", 
-                  (int)(data->self_test_exec_status & 0x0f));
-          break;
-       default:
-          pout("(%4d)\tReserved.\n",
-                  (int)data->self_test_exec_status);
-          break;
-   }
-	
-}
-
-
-
-void PrintSmartTotalTimeCompleteOffline ( struct ata_smart_values *data){
-  pout("Total time to complete Offline \n");
-  pout("data collection: \t\t (%4d) seconds.\n", 
-       (int)data->total_time_to_complete_off_line);
-}
-
-
-
-void PrintSmartOfflineCollectCap(struct ata_smart_values *data){
-  pout("Offline data collection\n");
-  pout("capabilities: \t\t\t (0x%02x) ",
-       (int)data->offline_data_collection_capability);
-  
-  if (data->offline_data_collection_capability == 0x00){
-    pout("\tOffline data collection not supported.\n");
-  } 
-  else {
-    pout( "%s\n", isSupportExecuteOfflineImmediate(data)?
-	  "SMART execute Offline immediate." :
-	  "No SMART execute Offline immediate.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportAutomaticTimer(data)? 
-	  "Auto Offline data collection on/off support.":
-	  "No Auto Offline data collection support.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportOfflineAbort(data)? 
-	  "Abort Offline collection upon new\n\t\t\t\t\tcommand.":
-	  "Suspend Offline collection upon new\n\t\t\t\t\tcommand.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportOfflineSurfaceScan(data)? 
-	  "Offline surface scan supported.":
-	  "No Offline surface scan supported.");
-    
-    pout( "\t\t\t\t\t%s\n", isSupportSelfTest(data)? 
-	  "Self-test supported.":
-	  "No Self-test supported.");
-
-    pout( "\t\t\t\t\t%s\n", isSupportConveyanceSelfTest(data)? 
-	  "Conveyance Self-test supported.":
-	  "No Conveyance Self-test supported.");
-
-    pout( "\t\t\t\t\t%s\n", isSupportSelectiveSelfTest(data)? 
-	  "Selective Self-test supported.":
-	  "No Selective Self-test supported.");
-  }
-}
-
-
-
-void PrintSmartCapability ( struct ata_smart_values *data)
-{
-   pout("SMART capabilities:            ");
-   pout("(0x%04x)\t", (int)data->smart_capability);
-   
-   if (data->smart_capability == 0x00)
-   {
-       pout("Automatic saving of SMART data\t\t\t\t\tis not implemented.\n");
-   } 
-   else 
-   {
-	
-      pout( "%s\n", (data->smart_capability & 0x01)? 
-              "Saves SMART data before entering\n\t\t\t\t\tpower-saving mode.":
-              "Does not save SMART data before\n\t\t\t\t\tentering power-saving mode.");
-		
-      if ( data->smart_capability & 0x02 )
-      {
-          pout("\t\t\t\t\tSupports SMART auto save timer.\n");
-      }
-   }
-}
-
-
-
-void PrintSmartErrorLogCapability ( struct ata_smart_values *data)
-{
-
-   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){
-  pout("Short self-test routine \n");
-  if (isSupportSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->short_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-void PrintSmartExtendedSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Extended self-test routine\n");
-  if (isSupportSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->extend_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-void PrintSmartConveyanceSelfTestPollingTime(struct ata_smart_values *data){
-  pout("Conveyance self-test routine\n");
-  if (isSupportConveyanceSelfTest(data))
-    pout("recommended polling time: \t (%4d) minutes.\n", 
-	 (int)data->conveyance_test_completion_time);
-  else
-    pout("recommended polling time: \t        Not Supported.\n");
-}
-
-// onlyfailed=0 : print all attribute values
-// onlyfailed=1:  just ones that are currently failed and have prefailure bit set
-// onlyfailed=2:  ones that are failed, or have failed with or without prefailure bit set
-void PrintSmartAttribWithThres (struct ata_smart_values *data, 
-				struct ata_smart_thresholds *thresholds,
-				int onlyfailed){
-  int i;
-  int needheader=1;
-  char rawstring[64];
-    
-  // step through all vendor attributes
-  for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
-    char *status;
-    struct ata_smart_attribute *disk=data->vendor_attributes+i;
-    struct ata_smart_threshold_entry *thre=thresholds->thres_entries+i;
-    
-    // consider only valid attributes
-    if (disk->id && thre->id){
-      char *type, *update;
-      int failednow,failedever;
-      char attributename[64];
-
-      failednow = (disk->current <= thre->threshold);
-      failedever= (disk->worst   <= thre->threshold);
-      
-      // These break out of the loop if we are only printing certain entries...
-      if (onlyfailed==1 && (!ATTRIBUTE_FLAGS_PREFAILURE(disk->flags) || !failednow))
-	continue;
-      
-      if (onlyfailed==2 && !failedever)
-	continue;
-      
-      // print header only if needed
-      if (needheader){
-	if (!onlyfailed){
-	  pout("SMART Attributes Data Structure revision number: %d\n",(int)data->revnumber);
-	  pout("Vendor Specific SMART Attributes with Thresholds:\n");
-	}
-	pout("ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE\n");
-	needheader=0;
-      }
-      
-      // is this Attribute currently failed, or has it ever failed?
-      if (failednow)
-	status="FAILING_NOW";
-      else if (failedever)
-	status="In_the_past";
-      else
-	status="    -";
-
-      // Print name of attribute
-      ataPrintSmartAttribName(attributename,disk->id, con->attributedefs);
-      pout("%-28s",attributename);
-
-      // printing line for each valid attribute
-      type=ATTRIBUTE_FLAGS_PREFAILURE(disk->flags)?"Pre-fail":"Old_age";
-      update=ATTRIBUTE_FLAGS_ONLINE(disk->flags)?"Always":"Offline";
-
-      pout("0x%04x   %.3d   %.3d   %.3d    %-10s%-9s%-12s", 
-	     (int)disk->flags, (int)disk->current, (int)disk->worst,
-	     (int)thre->threshold, type, update, status);
-
-      // print raw value of attribute
-      ataPrintSmartAttribRawValue(rawstring, disk, con->attributedefs);
-      pout("%s\n", rawstring);
-      
-      // print a warning if there is inconsistency here!
-      if (disk->id != thre->id){
-	char atdat[64],atthr[64];
-	ataPrintSmartAttribName(atdat, disk->id, con->attributedefs);
-	ataPrintSmartAttribName(atthr, thre->id, con->attributedefs);
-	pout("%-28s<== Data Page      |  WARNING: PREVIOUS ATTRIBUTE HAS TWO\n",atdat);
-	pout("%-28s<== Threshold Page |  INCONSISTENT IDENTITIES IN THE DATA\n",atthr);
-      }
-    }
-  }
-  if (!needheader) pout("\n");
-}
-
-void ataPrintGeneralSmartValues(struct ata_smart_values *data, struct ata_identify_device *drive){
-  pout("General SMART Values:\n");
-  
-  PrintSmartOfflineStatus(data); 
-  
-  if (isSupportSelfTest(data)){
-    PrintSmartSelfExecStatus (data);
-  }
-  
-  PrintSmartTotalTimeCompleteOffline(data);
-  PrintSmartOfflineCollectCap(data);
-  PrintSmartCapability(data);
-  
-  PrintSmartErrorLogCapability(data);
-
-  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 && con->fixfirmwarebug != FIX_SAMSUNG2) {
-    pout("Warning: ATA error count %d inconsistent with error log pointer %d\n\n",
-	 data->ata_error_count,data->error_log_pointer);
-  }
-  
-  // starting printing error log info
-  if (data->ata_error_count<=5)
-    pout( "ATA Error Count: %d\n", (int)data->ata_error_count);
-  else
-    pout( "ATA Error Count: %d (device log contains only the most recent five errors)\n",
-	   (int)data->ata_error_count);
-  QUIETOFF(con);
-  pout("\tCR = Command Register [HEX]\n"
-       "\tFR = Features Register [HEX]\n"
-       "\tSC = Sector Count Register [HEX]\n"
-       "\tSN = Sector Number Register [HEX]\n"
-       "\tCL = Cylinder Low Register [HEX]\n"
-       "\tCH = Cylinder High Register [HEX]\n"
-       "\tDH = Device/Head Register [HEX]\n"
-       "\tDC = Device Command Register [HEX]\n"
-       "\tER = Error register [HEX]\n"
-       "\tST = Status register [HEX]\n"
-       "Timestamp = decimal seconds since the previous disk power-on.\n"
-       "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-- ) {
-    char *st_er_desc;
-
-    // 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]))){
-      // Table 57 of T13/1532D Volume 1 Revision 3
-      char *msgstate;
-      int bits=data->errorlog_struct[i].error_struct.state & 0x0f;
-      switch (bits){
-      case 0x00: msgstate="in an unknown state";break;
-      case 0x01: msgstate="sleeping"; break;
-      case 0x02: msgstate="in standby mode"; break;
-      case 0x03: msgstate="active or idle"; break;
-      case 0x04: msgstate="doing SMART Offline or Self-test"; break;
-      default:   
-	if (bits<0x0b)
-	  msgstate="in a reserved state";
-	else
-	  msgstate="in a vendor specific state";
-      }
-
-      // See table 42 of ATA5 spec
-      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\n",msgstate);
-      pout("  After command completion occurred, registers were:\n"
-	   "  ER ST SC SN CL CH DH\n"
-	   "  -- -- -- -- -- -- --\n"
-	   "  %02x %02x %02x %02x %02x %02x %02x",
-	   (int)data->errorlog_struct[i].error_struct.error_register,
-	   (int)data->errorlog_struct[i].error_struct.status,
-	   (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);
-      // Add a description of the contents of the status and error registers
-      // if possible
-      st_er_desc = construct_st_er_desc(
-        data->errorlog_struct[i].commands[4].commandreg,
-        data->errorlog_struct[i].commands[4].featuresreg,
-        data->errorlog_struct[i].error_struct.status,
-        data->errorlog_struct[i].error_struct.error_register
-      );
-      if (st_er_desc) {
-        pout("  %s", st_er_desc);
-        free(st_er_desc);
-      }
-      pout("\n\n");
-      pout("  Commands leading to the command that caused the error were:\n"
-	   "  CR FR SC SN CL CH DH DC   Timestamp  Command/Feature_Name\n"
-	   "  -- -- -- -- -- -- -- --   ---------  --------------------\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 %7d.%03d  %s\n",
-	       (int)thiscommand->commandreg,
-	       (int)thiscommand->featuresreg,
-	       (int)thiscommand->sector_count,
-	       (int)thiscommand->sector_number,
-	       (int)thiscommand->cylinder_low,
-	       (int)thiscommand->cylinder_high,
-	       (int)thiscommand->drive_head,
-	       (int)thiscommand->devicecontrolreg,
-	       (unsigned int)(thiscommand->timestamp / 1000U),
-	       (unsigned int)(thiscommand->timestamp % 1000U),
-	       look_up_ata_command(thiscommand->commandreg, thiscommand->featuresreg));
-      }
-      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 structure revision number %d\n",(int)data->revnumber);
-  if ((data->revnumber!=0x0001) && allentries && con->fixfirmwarebug != FIX_SAMSUNG)
-    pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
-  if (data->mostrecenttest==0){
-    if (allentries)
-      pout("No self-tests have been logged.  [Use the smartctl -t option to run these.]\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="Offline            "; break;
-      case   1: msgtest="Short offline      "; break;
-      case   2: msgtest="Extended offline   "; break;
-      case   3: msgtest="Conveyance offline "; break;
-      case   4: msgtest="Selective offline  "; break;
-      case 127: msgtest="Abort offline test "; break;
-      case 129: msgtest="Short captive      "; break;
-      case 130: msgtest="Extended captive   "; break;
-      case 131: msgtest="Conveyance captive "; break;
-      case 132: msgtest="Selective captive  "; break;
-      default:  
-	if ( log->selftestnumber>=192 ||
-	    (log->selftestnumber>= 64 && log->selftestnumber<=126))
-	  msgtest="Vendor offline     ";
-	else
-	  msgtest="Reserved offline   ";
-      }
-      
-      // test status
-      switch((log->selfteststatus)>>4){
-      case  0:msgstat="Completed without error      "; break;
-      case  1:msgstat="Aborted by host              "; break;
-      case  2:msgstat="Interrupted (host reset)     "; break;
-      case  3:msgstat="Fatal or unknown error       "; errorfound=1; break;
-      case  4:msgstat="Completed: unknown failure   "; errorfound=1; break;
-      case  5:msgstat="Completed: electrical failure"; errorfound=1; break;
-      case  6:msgstat="Completed: servo/seek failure"; errorfound=1; break;
-      case  7:msgstat="Completed: read failure      "; errorfound=1; break;
-      case  8:msgstat="Completed: handling damage?? "; errorfound=1; break;
-      case 15:msgstat="Self-test routine in progress"; break;
-      default:msgstat="Unknown/reserved test status ";
-      }
-
-      retval+=errorfound;
-      sprintf(percent,"%1d0%%",(log->selfteststatus)&0xf);
-
-      // T13/1321D revision 1c: (Data structure Rev #1)
-
-      //The failing LBA shall be the LBA of the uncorrectable sector
-      //that caused the test to fail. If the device encountered more
-      //than one uncorrectable sector during the test, this field
-      //shall indicate the LBA of the first uncorrectable sector
-      //encountered. If the test passed or the test failed for some
-      //reason other than an uncorrectable sector, the value of this
-      //field is undefined.
-
-      // This is true in ALL ATA-5 specs
-      
-      if (!errorfound || log->lbafirstfailure==0xffffffff || log->lbafirstfailure==0x00000000)
-	sprintf(firstlba,"%s","-");
-      else	
-	sprintf(firstlba,"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 &&
-	ATTRIBUTE_FLAGS_PREFAILURE(data->vendor_attributes[i].flags) &&
-	(data->vendor_attributes[i].current <= thresholds->thres_entries[i].threshold) &&
-	(thresholds->thres_entries[i].threshold != 0xFE)){
-      pout("Attribute ID %d Failed\n",(int)data->vendor_attributes[i].id);
-      failed = 1;
-    } 
-  }   
-  pout("%s\n", ( failed )?
-	 "SMART overall-health self-assessment test result: FAILED!\n"
-	 "Drive failure expected in less than 24 hours. SAVE ALL DATA":
-	 "SMART overall-health self-assessment test result: PASSED");
-}
-
-
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-void failuretest(int type, int returnvalue){
-
-  // If this is an error in an "optional" SMART command
-  if (type==OPTIONAL_CMD){
-    if (con->conservative){
-      pout("An optional SMART command failed: exiting.  Remove '-T conservative' option to continue.\n");
-      EXIT(returnvalue);
-    }
-    return;
-  }
-
-  // If this is an error in a "mandatory" SMART command
-  if (type==MANDATORY_CMD){
-    if (con->permissive--)
-      return;
-    pout("A mandatory SMART command failed: exiting. To continue, add one or more '-T permissive' options.\n");
-    EXIT(returnvalue);
-  }
-
-  pout("Smartctl internal error in failuretest(type=%d). Please contact developers at %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 ata_identify_device 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, retid=0, supported=0, needupdate=0;
-
-  // Start by getting Drive ID information.  We need this, to know if SMART is supported.
-  if ((retid=ataReadHDIdentity(fd,&drive))<0){
-    pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n");
-    failuretest(MANDATORY_CMD, returnval|=FAILID);
-  }
-
-  // If requested, show which presets would be used for this drive and exit.
-  if (con->showpresets) {
-    showpresets(&drive);
-    EXIT(0);
-  }
-
-  // Use preset vendor attribute options unless user has requested otherwise.
-  if (!con->ignorepresets){
-    unsigned char *charptr;
-    if ((charptr=con->attributedefs))
-      applypresets(&drive, &charptr, con);
-    else {
-      pout("Fatal internal error in ataPrintMain()\n");
-      EXIT(returnval|=FAILCMD);
-    }
-  }
-
-  // Print most drive identity information if requested
-  if (con->driveinfo){
-    pout("=== START OF INFORMATION SECTION ===\n");
-    ataPrintDriveInfo(&drive);
-  }
-
-  // Was this a packet device?
-  if (retid>0){
-    pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n", packetdevicetype(retid-1));
-    failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-  }
-  
-  // if drive does not supports SMART it's time to exit
-  supported=ataSmartSupport(&drive);
-  if (supported != 1){
-    if (supported==0) {
-      pout("SMART support is: Unavailable - device lacks SMART capability.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      pout("                  Checking to be sure by trying SMART ENABLE command.\n");
-    }
-    else {
-      pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      pout("                  Checking for SMART support by trying SMART ENABLE command.\n");
-    }
-
-    if (ataEnableSmart(fd)){
-      pout("                  SMART ENABLE failed - this establishes that this device lacks SMART functionality.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      supported=0;
-    }
-    else {
-      pout("                  SMART ENABLE appeared to work!  Continuing.\n");
-      supported=1;
-    }
-    if (!con->driveinfo) pout("\n");
-  }
-  
-  // Now print remaining drive info: is SMART enabled?    
-  if (con->driveinfo){
-    int ison=ataIsSmartEnabled(&drive),isenabled=ison;
-    
-    if (ison==-1) {
-      pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-      // check SMART support by trying a command
-      pout("                  Checking to be sure by trying SMART RETURN STATUS command.\n");
-      isenabled=ataDoesSmartWork(fd);
-    }
-    else
-      pout("SMART support is: Available - device has SMART capability.\n");
-    
-    if (isenabled)
-      pout("SMART support is: Enabled\n");
-    else {
-      if (ison==-1)
-	pout("SMART support is: Unavailable\n");
-      else
-	pout("SMART support is: Disabled\n");
-    }
-    pout("\n");
-  }
-  
-  // START OF THE ENABLE/DISABLE SECTION OF THE CODE
-  if (con->smartenable || con->smartdisable || 
-      con->smartautosaveenable || con->smartautosavedisable || 
-      con->smartautoofflineenable || con->smartautoofflinedisable)
-    pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
-  
-  // Enable/Disable SMART commands
-  if (con->smartenable){
-    if (ataEnableSmart(fd)) {
-      pout("Smartctl: SMART Enable Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Enabled.\n");
-  }
-  
-  // From here on, every command requires that SMART be enabled...
-  if (!ataDoesSmartWork(fd)) {
-    pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
-    return returnval;
-  }
-  
-  // Turn off SMART on device
-  if (con->smartdisable){    
-    if (ataDisableSmart(fd)) {
-      pout( "Smartctl: SMART Disable Failed.\n\n");
-      failuretest(MANDATORY_CMD,returnval|=FAILSMART);
-    }
-    pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
-    return returnval;		
-  }
-  
-  // Let's ALWAYS issue this command to get the SMART status
-  code=ataSmartStatus2(fd);
-  if (code==-1)
-    failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-
-  // Enable/Disable Auto-save attributes
-  if (con->smartautosaveenable){
-    if (ataEnableAutoSave(fd)){
-      pout( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Attribute Autosave Enabled.\n");
-  }
-  if (con->smartautosavedisable){
-    if (ataDisableAutoSave(fd)){
-      pout( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n");
-      failuretest(MANDATORY_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Attribute Autosave Disabled.\n");
-  }
-  
-  // for everything else read values and thresholds are needed
-  if (ataReadSmartValues(fd, &smartval)){
-    pout("Smartctl: SMART Read Values failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-  if (ataReadSmartThresholds(fd, &smartthres)){
-    pout("Smartctl: SMART Read Thresholds failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-
-  // Enable/Disable Off-line testing
-  if (con->smartautoofflineenable){
-    if (!isSupportAutomaticTimer(&smartval)){
-      pout("Warning: device does not support SMART Automatic Timers.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    needupdate=1;
-    if (ataEnableAutoOffline(fd)){
-      pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Automatic Offline Testing Enabled every four hours.\n");
-  }
-  if (con->smartautoofflinedisable){
-    if (!isSupportAutomaticTimer(&smartval)){
-      pout("Warning: device does not support SMART Automatic Timers.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    needupdate=1;
-    if (ataDisableAutoOffline(fd)){
-      pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else
-      pout("SMART Automatic Offline Testing Disabled.\n");
-  }
-
-  if (needupdate && ataReadSmartValues(fd, &smartval)){
-    pout("Smartctl: SMART Read Values failed.\n\n");
-    failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-  }
-
-  // all this for a newline!
-  if (con->smartenable || con->smartdisable || 
-      con->smartautosaveenable || con->smartautosavedisable || 
-      con->smartautoofflineenable || con->smartautoofflinedisable)
-    pout("\n");
-
-  // START OF READ-ONLY OPTIONS APART FROM -V and -i
-  if (con->checksmart || con->generalsmartvalues || con->smartvendorattrib || con->smarterrorlog || con->smartselftestlog)
-    pout("=== START OF READ SMART DATA SECTION ===\n");
-  
-  // Check SMART status (use previously returned value)
-  if (con->checksmart){
-    switch (code) {
-
-    case 0:
-      // The case where the disk health is OK
-      pout("SMART overall-health self-assessment test result: PASSED\n");
-      if (ataCheckSmart(&smartval, &smartthres,0)){
-	if (con->smartvendorattrib)
-	  pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
-	else {
-	  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
-  if (con->smartlogdirectory){
-    struct ata_smart_log_directory smartlogdirectory;
-    if (!isGeneralPurposeLoggingCapable(&drive)){
-      pout("Warning: device does not support General Purpose Logging\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    else {
-      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
-  switch (con->testcase){
-  case OFFLINE_FULL_SCAN:
-    if (!isSupportExecuteOfflineImmediate(&smartval)){
-      pout("Warning: device does not support Execute Offline Immediate function.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case ABORT_SELF_TEST:
-  case SHORT_SELF_TEST:
-  case EXTEND_SELF_TEST:
-  case SHORT_CAPTIVE_SELF_TEST:
-  case EXTEND_CAPTIVE_SELF_TEST:
-    if (!isSupportSelfTest(&smartval)){
-      pout("Warning: device does not support Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-  case CONVEYANCE_SELF_TEST:
-  case CONVEYANCE_CAPTIVE_SELF_TEST:
-    if (!isSupportConveyanceSelfTest(&smartval)){
-      pout("Warning: device does not support Conveyance Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-#if DEVELOP_SELECTIVE_SELF_TEST
-  case SELECTIVE_SELF_TEST:
-  case SELECTIVE_CAPTIVE_SELF_TEST:
-    if (!isSupportSelectiveSelfTest(&smartval)){
-      pout("Warning: device does not support Selective Self-Test functions.\n\n");
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    break;
-#endif
-  default:
-    pout("Internal error in smartctl: con->testcase==%d not recognized\n", (int)con->testcase);
-    pout("Please contact smartmontools developers at %s.\n", PACKAGE_BUGREPORT);
-    EXIT(returnval|=FAILCMD);
-  }
-
-  // Now do the test.  Note ataSmartTest prints its own error/success
-  // messages
-  if (ataSmartTest(fd, con->testcase))
-    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))){ 
-    time_t t=time(NULL);
-    if (con->testcase==OFFLINE_FULL_SCAN) {
-      t+=timewait;
-      pout("Please wait %d seconds for test to complete.\n", (int)timewait);
-    } else {
-      t+=timewait*60;
-      pout("Please wait %d minutes for test to complete.\n", (int)timewait);
-    }
-    pout("Test will complete after %s\n", ctime(&t));
-    
-    if (con->testcase!=SHORT_CAPTIVE_SELF_TEST && 
-	con->testcase!=EXTEND_CAPTIVE_SELF_TEST && 
-	con->testcase!=CONVEYANCE_CAPTIVE_SELF_TEST && 
-	con->testcase!=SELECTIVE_CAPTIVE_SELF_TEST)
-      pout("Use smartctl -X to abort test.\n");	
-  }    
-  return returnval;
-}
diff --git a/sm5/knowndrives.cpp b/sm5/knowndrives.cpp
deleted file mode 100644
index 7fa10e5249a3046d15234f480a02615e2623304f..0000000000000000000000000000000000000000
--- a/sm5/knowndrives.cpp
+++ /dev/null
@@ -1,541 +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 "extern.h"
-#include "knowndrives.h"
-#include "utility.h"
-#include "config.h"
-
-const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.51 2003/10/27 18:57:24 pjwilliams Exp $"
-                                ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
-
-#define MODEL_STRING_LENGTH                         40
-#define FIRMWARE_STRING_LENGTH                       8
-#define TABLEPRINTWIDTH                             19
-
-// See vendorattributeargs[] array in atacmds.c for definitions.
-#define PRESET_9_MINUTES                   {   9,  1 }
-#define PRESET_9_TEMP                      {   9,  2 }
-#define PRESET_9_SECONDS                   {   9,  3 }
-#define PRESET_9_HALFMINUTES               {   9,  4 }
-#define PRESET_192_EMERGENCYRETRACTCYCLECT { 192,  1 }
-#define PRESET_193_LOADUNLOAD              { 193,  1 }
-#define PRESET_194_10XCELSIUS              { 194,  1 }
-#define PRESET_194_UNKNOWN                 { 194,  2 }
-#define PRESET_198_OFFLINESCANUNCSECTORCT  { 198,  1 }
-#define PRESET_200_WRITEERRORCOUNT         { 200,  1 }
-#define PRESET_201_DETECTEDTACOUNT         { 201,  1 }         
-#define PRESET_220_TEMP                    { 220,  1 }
-
-/* Arrays of preset vendor-specific attribute options for use in
- * knowndrives[]. */
-
-extern long long bytes;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// These two are common to several models.
-const unsigned char vendoropts_9_minutes[][2] = {
-  PRESET_9_MINUTES,
-  {0,0}
-};
-const unsigned char vendoropts_9_seconds[][2] = {
-  PRESET_9_SECONDS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_194_UNKNOWN,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
-  PRESET_9_SECONDS,
-  PRESET_192_EMERGENCYRETRACTCYCLECT,
-  PRESET_198_OFFLINESCANUNCSECTORCT,
-  PRESET_200_WRITEERRORCOUNT,
-  PRESET_201_DETECTEDTACOUNT,
-  {0,0}
-};
-
-const unsigned char vendoropts_Fujitsu_MHR2040AT[][2] = {
-  PRESET_9_SECONDS,
-  PRESET_192_EMERGENCYRETRACTCYCLECT,
-  PRESET_198_OFFLINESCANUNCSECTORCT,
-  PRESET_200_WRITEERRORCOUNT,
-  {0,0}
-};
-
-const unsigned char vendoropts_Samsung_SV4012H[][2] = {
-  PRESET_9_HALFMINUTES,
-  {0,0}
-};
-
-const unsigned char vendoropts_Samsung_SV1204H[][2] = {
-  PRESET_9_HALFMINUTES,
-  PRESET_194_10XCELSIUS,
-  {0,0}
-};
-
-const unsigned char vendoropts_Hitachi_DK23EA[][2] = {
-  PRESET_9_MINUTES,
-  PRESET_193_LOADUNLOAD,
-  {0,0}
-};
-
-const char same_as_minus_F[]="Fixes byte order in some SMART data (same as -F samsung)";
-const char same_as_minus_F2[]="Fixes byte order in some SMART data (same as -F samsung2)";
-
-const char may_need_minus_F_disabled[]="Contact developers at " PACKAGE_BUGREPORT "; may need -F samsung disabled";
-const char may_need_minus_F2_disabled[]="Contact developers at " PACKAGE_BUGREPORT "; may need -F samsung2 disabled";
-
-/* Special-purpose functions for use in knowndrives[]. */
-void specialpurpose_reverse_samsung(smartmonctrl *con)
-{
-  con->fixfirmwarebug = FIX_SAMSUNG;
-}
-void specialpurpose_reverse_samsung2(smartmonctrl *con)
-{
-  con->fixfirmwarebug = FIX_SAMSUNG2;
-}
-
-/* Table of settings for known drives terminated by an element containing all
- * zeros.  The drivesettings structure is described in knowndrives.h.  Note
- * that lookupdrive() will search knowndrives[] from the start to end or
- * until it finds the first match, so the order in knowndrives[] is important
- * for distinct entries that could match the same drive. */
-
-// Note that the table just below uses EXTENDED REGULAR EXPRESSIONS.
-// A good on-line reference for these is:
-// http://www.zeus.com/extra/docsystem/docroot/apps/web/docs/modules/access/regex.html
-
-const drivesettings knowndrives[] = {
-  { // IBM Deskstar 60GXP series
-    "IC35L0[12346]0AVER07",
-    ".*",
-    "IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
-      "Please see http://www.geocities.com/dtla_update/index.html#rel",
-    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 MPD and MPE series
-    "^FUJITSU MP[DE]....A[HT]$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHN2300AT
-    "^FUJITSU MHN2300AT$",
-    ".*",
-    NULL,
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Fujitsu MHR2040AT
-    "^FUJITSU MHR2040AT$",
-    ".*",    // Tested on 40BA
-    NULL,
-    vendoropts_Fujitsu_MHR2040AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHS2020AT
-    "^FUJITSU MHS2020AT$",
-    ".*",    // Tested on 8004
-    NULL,
-    vendoropts_Fujitsu_MHS2020AT,
-    NULL, NULL
-  },
-  { // Fujitsu MHM2200AT
-    "^FUJITSU MHM2200AT$",
-    ".*",  // Tested with firmware version 3822
-    "The FUJITSU MHM2200AT firmware has a harmless Drive Identity\n"
-      "Structure checksum error bug.",
-    vendoropts_9_seconds,
-    NULL, NULL
-  },
-  { // Samsung SV4012H (known firmware)
-    "^SAMSUNG SV4012H$",
-    "^RM100-08$",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV4012H (match revision *-23 firmware)
-    "^SAMSUNG .*$",
-    ".*-23$",
-    may_need_minus_F2_disabled,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung2,
-    same_as_minus_F2
-  },
-  { // Samsung SV4012H (all other firmware)
-    "^SAMSUNG SV4012H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV4012H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV1204H (known firmware)
-    "^SAMSUNG SV1204H$",
-    "^RK100-1[3-5]$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { //Samsung SV1204H (all other firmware)
-    "^SAMSUNG SV1204H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV0412H (known firmware)
-    "^SAMSUNG SV0412H$",
-    "^SK100-01$",
-    NULL,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { // Samsung SV0412H (all other firmware)
-    "^SAMSUNG SV0412H$",
-    ".*",
-    may_need_minus_F_disabled,
-    vendoropts_Samsung_SV1204H,
-    specialpurpose_reverse_samsung,
-    same_as_minus_F
-  },
-  { //Samsung SP1604N, tested with FW TM100-23
-    "^SAMSUNG SP1604N$",
-    ".*",
-    NULL,
-    vendoropts_Samsung_SV4012H,
-    NULL,NULL
-  },
-  { //SAMSUNG SV0322A with FW JK200-35
-    "^SAMSUNG SV0322A$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL
-  },
-  { // Samsung ALL OTHER DRIVES
-    "^SAMSUNG.*",
-    ".*",
-    "Contact developers at " PACKAGE_BUGREPORT "; may need -F samsung[2] enabled.\n",
-    NULL, NULL, NULL
-  },
-  { // Maxtor 6L080J4 and 4K080H4
-    "^MAXTOR (6L080J4|4K080H4)$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  { // Maxtor 4D080H4
-    "^Maxtor (4D080H4|4G120J6)$",
-    ".*",
-    NULL,
-    vendoropts_Maxtor_4D080H4,
-    NULL, NULL
-  },
-  { // Maxtor 4R080J0
-    "^Maxtor (4R080J0|4R080L0|6Y0[6|8]0L0|6Y1[2|6]0P0)$",
-    ".*",
-    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 at " PACKAGE_BUGREPORT "; may need -v 9,minutes enabled.\n",
-    NULL,
-    NULL, NULL
-  },
-  { // HITACHI_DK23BA-20
-    "^HITACHI_DK23BA-20$",
-    ".*",
-    NULL,
-    vendoropts_9_minutes,
-    NULL, NULL
-  },
-  { // HITACHI_DK23EA-30
-    "^HITACHI_DK23EA-30$",
-    ".*",
-    NULL,
-    vendoropts_Hitachi_DK23EA,
-    NULL, NULL
-  },
-  { // IBM GXP-180
-    "^IC35L120AVV207-[01]$",
-    ".*", 
-    NULL, NULL, NULL, NULL 
-  },
-  {
-    //  IBM Deskstar 120GXP  [Phil -- use for testing]
-    "^IC35L060AVVA07-[01]$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-  },
-  { // TOSHIBA MK4025GAS
-    "^TOSHIBA MK4025GAS$",
-    ".*",
-    NULL, NULL, NULL, NULL
-  },
-  {
-    // TOSHIBA MK6021GAS [Bruce -- use for testing on laptop]
-    "^TOSHIBA MK6021GAS$",
-    ".*",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-  },
-  /*------------------------------------------------------------
-   *  End of table.  Do not add entries below this marker.
-   *------------------------------------------------------------ */
-  {NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
-// Searches knowndrives[] for a drive with the given model number and firmware
-// string.  If either the drive's model or firmware strings are not set by the
-// manufacturer then values of NULL may be used.  Returns the index of the
-// first match in knowndrives[] or -1 if no match if found.
-int lookupdrive(const char *model, const char *firmware)
-{
-  regex_t regex;
-  int i, index;
-  const char *empty = "";
-
-  model = model ? model : empty;
-  firmware = firmware ? firmware : empty;
-
-  for (i = 0, index = -1; index == -1 && knowndrives[i].modelregexp; i++) {
-    // Attempt to compile regular expression.
-    if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
-      goto CONTINUE;
-
-    // Check whether model matches the regular expression in knowndrives[i].
-    if (!regexec(&regex, model, 0, NULL, 0)) {
-      // model matches, now check firmware.
-      if (!knowndrives[i].firmwareregexp)
-        // The firmware regular expression in knowndrives[i] is NULL, which is
-        // considered a match.
-        index = i;
-      else {
-        // Compare firmware against the regular expression in knowndrives[i].
-        regfree(&regex);  // Recycle regex.
-        if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
-          goto CONTINUE;
-        if (!regexec(&regex, firmware, 0, NULL, 0))
-          index = i;
-      }
-    }
-  CONTINUE:
-    regfree(&regex);
-  }
-
-  return index;
-}
-
-
-// Shows all presets for drives in knowndrives[].
-void showonepreset(const drivesettings *drivetable){
-  
-  const unsigned char (* presets)[2] = drivetable->vendoropts;
-  int first_preset = 1;
-  
-  // Basic error check
-  if (!drivetable || !drivetable->modelregexp){
-    pout("Null known drive table pointer. Please report\n"
-	 "this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
-    return;
-  }
-  
-  // print model and firmware regular expressions
-  pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", drivetable->modelregexp);
-  pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", drivetable->firmwareregexp ?
-       drivetable->firmwareregexp : "");
-  
-  // if there are any presets, then show them
-  if (presets && (*presets)[0]) while (1) {
-    char out[256];
-    const int attr = (*presets)[0], val  = (*presets)[1];
-    unsigned char fakearray[MAX_ATTRIBUTE_NUM];
-
-    // if we are at the end of the attribute list, break out
-    if (!attr)  
-      break;
-    
-    // This is a hack. ataPrintSmartAttribName() needs a pointer to an
-    // "array" to dereference, so we provide such a pointer.
-    fakearray[attr]=val;
-    ataPrintSmartAttribName(out, attr, fakearray);
-
-    // Use leading zeros instead of spaces so that everything lines up.
-    out[0] = (out[0] == ' ') ? '0' : out[0];
-    out[1] = (out[1] == ' ') ? '0' : out[1];
-    pout("%-*s %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "", out);
-    first_preset = 0;
-    presets++;
-  }
-  else
-    pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
-
-  
-  // Is a special purpose function defined?  If so, describe it
-  if (drivetable->specialpurpose){
-    pout("%-*s ", TABLEPRINTWIDTH, "OTHER PRESETS:");
-    pout("%s\n", drivetable->functiondesc ?
-	 drivetable->functiondesc : "A special purpose function "
-	 "is defined for this drive"); 
-  }
-  
-  // Print any special warnings
-  if (drivetable->warningmsg){
-    pout("%-*s ", TABLEPRINTWIDTH, "WARNINGS:");
-    pout("%s\n", drivetable->warningmsg);
-  }
-  
-  return;
-}
-
-void showallpresets(void){
-  int i;
-
-  // loop over all entries in the knowndrives[] table, printing them
-  // out in a nice format
-  for (i=0; knowndrives[i].modelregexp; i++){
-    showonepreset(&knowndrives[i]);
-    pout("\n");
-  }
-  return;
-}
-
-// Shows the presets (if any) that are available for the given drive.
-void showpresets(const struct ata_identify_device *drive){
-  int i;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
-  
-  // and search to see if they match values in the table
-  if ((i = lookupdrive(model, firmware)) < 0) {
-    // no matches found
-    pout("No presets are defined for this drive.  Its identity strings:\n"
-	 "MODEL:    %s\n"
-	 "FIRMWARE: %s\n"
-	 "do not match any of the known regular expressions.\n"
-	 "Use -P showall to list all known regular expressions.\n",
-	 model, firmware);
-    return;
-  }
-  
-  // We found a matching drive.  Print out all information about it.
-  pout("Drive found in smartmontools Database.  Drive identity strings:\n"
-       "%-*s %s\n"
-       "%-*s %s\n"
-       "match smartmontools Drive Database entry:\n",
-       TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmware);
-  showonepreset(&knowndrives[i]);
-  return;
-}
-
-// Sets preset vendor attribute options in opts by finding the entry
-// (if any) for the given drive in knowndrives[].  Values that have
-// already been set in opts will not be changed.  Returns <0 if drive
-// not recognized else index >=0 into drive database.
-int applypresets(const struct ata_identify_device *drive, unsigned char **optsptr,
-                  smartmonctrl *con) {
-  int i;
-  unsigned char *opts;
-  char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
-  
-  if (*optsptr==NULL)
-    bytes+=MAX_ATTRIBUTE_NUM;
-  
-  if (*optsptr==NULL && !(*optsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM,1))){
-    pout("Unable to allocate memory in applypresets()");
-    bytes-=MAX_ATTRIBUTE_NUM;
-    EXIT(1);
-  }
-  
-  opts=*optsptr;
-
-  // get the drive's model/firmware strings
-  formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
-  formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
-
-  // Look up the drive in knowndrives[] 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/os_freebsd.cpp b/sm5/os_freebsd.cpp
deleted file mode 100644
index 290b8f6aef0bec1c8b5b914cca867c05ce031dfe..0000000000000000000000000000000000000000
--- a/sm5/os_freebsd.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * os_freebsd.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <err.h>
-#include <camlib.h>
-#include <cam/scsi/scsi_message.h>
-#include <sys/ata.h>
-
-
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-#include "os_freebsd.h"
-
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.20 2003/10/28 00:44:29 arvoreen Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Private table of open devices: guaranteed zero on startup since
-// part of static data.
-struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
-
-// forward declaration
-static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *ch);
-
-// Like open().  Return positive integer handle, used by functions below only.  mode=="ATA" or "SCSI".
-int deviceopen (const char* dev, char* mode) {
-  struct freebsd_dev_channel *fdchan;
-  int parse_ok, i;
-
-  // Search table for a free entry
-  for (i=0; i<FREEBSD_MAXDEV; i++)
-    if (!devicetable[i])
-      break;
-  
-  // If no free entry found, return error.  We have max allowed number
-  // of "file descriptors" already allocated.
-  if (i==FREEBSD_MAXDEV) {
-    errno=EMFILE;
-    return -1;
-  }
-
-  fdchan = calloc(1,sizeof(struct freebsd_dev_channel));
-  if (fdchan == NULL) {
-    // errno already set by call to malloc()
-    return -1;
-  }
-
-  parse_ok = parse_ata_chan_dev (dev,fdchan);
-  if (parse_ok == GUESS_DEVTYPE_DONT_KNOW) {
-    free(fdchan);
-    errno = ENOTTY;
-    return -1; // can't handle what we don't know
-  }
-
-  if (parse_ok == GUESS_DEVTYPE_ATA) {
-    if ((fdchan->atacommand = open("/dev/ata",O_RDWR))<0) {
-      int myerror = errno;	//preserve across free call
-      free (fdchan);
-      errno = myerror;
-      return -1;
-    }
-  }
-
-  if (parse_ok == GUESS_DEVTYPE_SCSI) {
-    // this is really a NO-OP, as the parse takes care
-    // of filling in correct details
-  }
-  
-  // return pointer to "file descriptor" table entry, properly offset.
-  devicetable[i]=fdchan;
-  return i+FREEBSD_FDOFFSET;
-}
-
-// Returns 1 if device not available/open/found else 0.  Also shifts fd into valid range.
-static int isnotopen(int *fd, struct freebsd_dev_channel** fdchan) {
-  // put valid "file descriptor" into range 0...FREEBSD_MAXDEV-1
-  *fd -= FREEBSD_FDOFFSET;
-  
-  // check for validity of "file descriptor".
-  if (*fd<0 || *fd>=FREEBSD_MAXDEV || !((*fdchan)=devicetable[*fd])) {
-    errno = ENODEV;
-    return 1;
-  }
-  
-  return 0;
-}
-
-// Like close().  Acts on handles returned by above function.
-int deviceclose (int fd) {
-  struct freebsd_dev_channel *fdchan;
-  int failed = 0;
-
-  // check for valid file descriptor
-  if (isnotopen(&fd, &fdchan))
-    return -1;
-  
-
-  // did we allocate a SCSI device name?
-  if (fdchan->devname)
-    free(fdchan->devname);
-  
-  // close device, if open
-  if (fdchan->atacommand)
-    failed=close(fdchan->atacommand);
-
-  if (fdchan->scsicontrol)
-    failed=close(fdchan->scsicontrol);
-  
-  // if close succeeded, then remove from device list
-  // Eduard, should we also remove it from list if close() fails?  I'm
-  // not sure. Here I only remove it from list if close() worked.
-  if (!failed) {
-    free(fdchan);
-    devicetable[fd]=NULL;
-  }
-  
-  return failed;
-}
-
-#define NO_RETURN 0
-#define BAD_SMART 1
-#define NO_3WARE 2
-#define BAD_KERNEL 3
-#define MAX_MSG 3
-
-// Utility function for printing warnings
-void printwarning(int msgNo, const char* extra) {
-  static int printed[] = {0,0,0,0};
-  static const char* message[]={
-    "The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n can not be retrieved with this version of ATAng, please do not rely on this value\n",
-    
-    "Error SMART Status command failed\nPlease get assistance from \n" PROJECTHOME "\nRegister values returned from SMART Status command are:\n",
-    
-    PACKAGE_STRING " does not currentlly support TWE devices (3ware Escalade)\n",
-    
-    "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
-  };
-
-  if (msgNo >= 0 && msgNo <= MAX_MSG) {
-    if (!printed[msgNo]) {
-      printed[msgNo] = 1;
-      pout("%s", message[msgNo]);
-      if (extra)
-	pout("%s",extra);
-    }
-  }
-  return;
-}
-
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
-  struct freebsd_dev_channel* con;
-  int retval, copydata=0;
-  struct ata_cmd iocmd;
-  unsigned char buff[512];
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -1;
-
-#ifndef ATAREQUEST
-  // sorry, but without ATAng, we can't do anything here
-  printwarning(BAD_KERNEL,NULL);
-  errno = ENOSYS;
-  return -1;
-#else
-  bzero(buff,512);
-
-  bzero(&iocmd,sizeof(struct ata_cmd));
-  bzero(buff,512);
-  iocmd.cmd=ATAREQUEST;
-  iocmd.channel=con->channel;
-  iocmd.device=con->device;
-
-  iocmd.u.request.u.ata.command=WIN_SMART;
-  iocmd.u.request.timeout=600;
-  switch (command){
-  case READ_VALUES:
-    iocmd.u.request.u.ata.feature=SMART_READ_VALUES;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case READ_THRESHOLDS:
-    iocmd.u.request.u.ata.feature=SMART_READ_THRESHOLDS;
-    iocmd.u.request.u.ata.count=1;
-    iocmd.u.request.u.ata.lba=1|(0xc24f<<8);
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case READ_LOG:
-    iocmd.u.request.u.ata.feature=SMART_READ_LOG_SECTOR;
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
-    iocmd.u.request.u.ata.count=1;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case IDENTIFY:
-    iocmd.u.request.u.ata.command=WIN_IDENTIFY;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case PIDENTIFY:
-    iocmd.u.request.u.ata.command=WIN_PIDENTIFY;
-    iocmd.u.request.flags=ATA_CMD_READ;
-    iocmd.u.request.data=buff;
-    iocmd.u.request.count=512;
-    copydata=1;
-    break;
-  case ENABLE:
-    iocmd.u.request.u.ata.feature=SMART_ENABLE;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case DISABLE:
-    iocmd.u.request.u.ata.feature=SMART_DISABLE;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case AUTO_OFFLINE:
-    // NOTE: According to ATAPI 4 and UP, this command is obsolete
-    iocmd.u.request.u.ata.feature=SMART_AUTO_OFFLINE;
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case AUTOSAVE:
-    iocmd.u.request.u.ata.feature=SMART_AUTOSAVE;
-    iocmd.u.request.u.ata.count=0xf1;  // to enable autosave
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case IMMEDIATE_OFFLINE:
-    iocmd.u.request.u.ata.feature=SMART_IMMEDIATE_OFFLINE;
-    iocmd.u.request.u.ata.lba = select|(0xc24f<<8); // put test in sector
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-    break;
-  case STATUS_CHECK: // same command, no HDIO in FreeBSD
-  case STATUS:
-    // this command only says if SMART is working.  It could be
-    // replaced with STATUS_CHECK below.
-    iocmd.u.request.u.ata.feature=SMART_STATUS;
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
-#ifdef ATA_CMD_READ_REG
-    // this is not offical ATAng code.  Patch submitted, will remove
-    // once accepted and committed.
-    iocmd.u.request.flags |= ATA_CMD_READ_REG;
-#endif
-    break;
-  default:
-    pout("Unrecognized command %d in ata_command_interface()\n"
-	 "Please contact " PACKAGE_BUGREPORT "\n", command);
-    errno=ENOSYS;
-    return -1;
-  }
-  
-  if (command==STATUS_CHECK){
-    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
-    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
-    unsigned char low,high;
-    
-    if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)))
-      return -1;
-
-#ifndef ATA_CMD_READ_REG
-    printwarning(NO_RETURN,NULL);
-#endif
-
-    high = (iocmd.u.request.u.ata.lba >> 16) & 0xff;
-    low = (iocmd.u.request.u.ata.lba >> 8) & 0xff;
-    
-    // Cyl low and Cyl high unchanged means "Good SMART status"
-    if (low==normal_lo && high==normal_hi)
-      return 0;
-    
-    // These values mean "Bad SMART status"
-    if (low==failed_lo && high==failed_hi)
-      return 1;
-    
-    // We haven't gotten output that makes sense; print out some debugging info
-    char buf[512];
-    sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
-	    (int)iocmd.u.request.u.ata.command,
-	    (int)iocmd.u.request.u.ata.feature,
-	    (int)iocmd.u.request.u.ata.count,
-	    (int)((iocmd.u.request.u.ata.lba) & 0xff),
-	    (int)((iocmd.u.request.u.ata.lba>>8) & 0xff),
-	    (int)((iocmd.u.request.u.ata.lba>>16) & 0xff),
-	    (int)iocmd.u.request.error);
-    printwarning(BAD_SMART,buf);
-    return 0;   
-  }
-
-  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) {
-    perror("Failed command: ");
-    return -1;
-  }
-  // 
-  if (copydata)
-    memcpy(data, buff, 512);
-  
-  return 0;
-#endif
-}
-
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
-{
-  struct freebsd_dev_channel* con = NULL;
-  struct cam_device* cam_dev = NULL;
-  union ccb *ccb;
-  
-  
-    if (report > 0) {
-        int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-
-  // check that "file descriptor" is valid
-  if (isnotopen(&fd,&con))
-      return -ENOTTY;
-
-
-  if (!(cam_dev = cam_open_spec_device(con->devname,con->unitnum,O_RDWR,NULL))) {
-    warnx("%s",cam_errbuf);
-    return -1;
-  }
-
-  if (!(ccb = cam_getccb(cam_dev))) {
-    warnx("error allocating ccb");
-    return -ENOMEM;
-  }
-
-  // clear out structure, except for header that was filled in for us
-  bzero(&(&ccb->ccb_h)[1],
-	sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
-
-  cam_fill_csio(&ccb->csio,
-		/*retrires*/ 1,
-		/*cbfcnp*/ NULL,
-		/* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
-		/* tagaction */ MSG_SIMPLE_Q_TAG,
-		/* dataptr */ iop->dxferp,
-		/* datalen */ iop->dxfer_len,
-		/* senselen */ iop->max_sense_len,
-		/* cdblen */ iop->cmnd_len,
-		/* timout */ iop->timeout);
-  memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
-
-  if (cam_send_ccb(cam_dev,ccb) < 0) {
-    warn("error sending SCSI ccb");
-    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
-    cam_freeccb(ccb);
-    return -1;
-  }
-
-  if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
-    cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
-    cam_freeccb(ccb);
-    return -1;
-  }
-
-  if (iop->sensep) {
-    memcpy(&(ccb->csio.sense_data),iop->sensep,sizeof(struct scsi_sense_data));
-    iop->resp_sense_len = sizeof(struct scsi_sense_data);
-  }
-
-  iop->scsi_status = ccb->csio.scsi_status;
-
-  cam_freeccb(ccb);
-  
-  if (cam_dev)
-    cam_close_device(cam_dev);
-
-  if (report > 0) {
-    pout("  status=0\n");
-    int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-	 (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-  return 0;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, smart_command_set command, int select, char *data) {
-  printwarning(NO_3WARE,NULL);
-  return -1;
-}
-
-
-static int get_ata_channel_unit ( const char* name, int* unit, int* dev) {
-  // there is no direct correlation between name 'ad0, ad1, ...' and
-  // channel/unit number.  So we need to iterate through the possible
-  // channels and check each unit to see if we match names
-  struct ata_cmd iocmd;
-  int fd,maxunit;
-  
-  bzero(&iocmd, sizeof(struct ata_cmd));
-
-  if ((fd = open("/dev/ata", O_RDWR)) < 0)
-    return -errno;
-  
-  iocmd.cmd = ATAGMAXCHANNEL;
-  if (ioctl(fd, IOCATA, &iocmd) < 0) {
-    return -errno;
-    close(fd);
-  }
-  maxunit = iocmd.u.maxchan;
-  for (*unit = 0; *unit < maxunit; (*unit)++) {
-    iocmd.channel = *unit;
-    iocmd.device = -1;
-    iocmd.cmd = ATAGPARM;
-    if (ioctl(fd, IOCATA, &iocmd) < 0) {
-      close(fd);
-      return -errno;
-    }
-    if (iocmd.u.param.type[0] && !strcmp(name,iocmd.u.param.name[0])) {
-      *dev = 0;
-      break;
-    }
-    if (iocmd.u.param.type[1] && !strcmp(name,iocmd.u.param.name[1])) {
-      *dev = 1;
-      break;
-    }
-  }
-  close(fd);
-  if (*unit == maxunit)
-    return -1;
-  else
-    return 0;
-}
-
-
-// Guess device type (ata or scsi) based on device name (FreeBSD
-// specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
-// osst, nosst and sg.
-static const char * fbsd_dev_prefix = "/dev/";
-static const char * fbsd_dev_ata_disk_prefix = "ad";
-static const char * fbsd_dev_scsi_disk_plus = "da";
-static const char * fbsd_dev_scsi_tape1 = "sa";
-static const char * fbsd_dev_scsi_tape2 = "nsa";
-static const char * fbsd_dev_scsi_tape3 = "esa";
-
-static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
-  int len;
-  int dev_prefix_len = strlen(fbsd_dev_prefix);
-  
-  // if dev_name null, or string length zero
-  if (!dev_name || !(len = strlen(dev_name)))
-    return GUESS_DEVTYPE_DONT_KNOW;
-  
-  // Remove the leading /dev/... if it's there
-  if (!strncmp(fbsd_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len) 
-      // if nothing else in the string, unrecognized
-      return GUESS_DEVTYPE_DONT_KNOW;
-    // else advance pointer to following characters
-    dev_name += dev_prefix_len;
-  }
-  // form /dev/ad* or ad*
-  if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
-	       strlen(fbsd_dev_ata_disk_prefix))) {
-    if (chan != NULL) {
-      if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
-	return GUESS_DEVTYPE_DONT_KNOW;
-      }
-    }
-    return GUESS_DEVTYPE_ATA;
-  }
-  
-  // form /dev/da* or da*
-  if (!strncmp(fbsd_dev_scsi_disk_plus, dev_name,
-	       strlen(fbsd_dev_scsi_disk_plus)))
-    goto handlescsi;
-
-  // form /dev/sa* or sa*
-  if (!strncmp(fbsd_dev_scsi_tape1, dev_name,
-	      strlen(fbsd_dev_scsi_tape1)))
-    goto handlescsi;
-
-  // form /dev/nsa* or nsa*
-  if (!strncmp(fbsd_dev_scsi_tape2, dev_name,
-	      strlen(fbsd_dev_scsi_tape2)))
-    goto handlescsi;
-
-  // form /dev/esa* or esa*
-  if (!strncmp(fbsd_dev_scsi_tape3, dev_name,
-	      strlen(fbsd_dev_scsi_tape3)))
-    goto handlescsi;
-  
-  // we failed to recognize any of the forms
-  return GUESS_DEVTYPE_DONT_KNOW;
-
- handlescsi:
-  if (chan != NULL) {
-    if (!(chan->devname = calloc(1,DEV_IDLEN+1)))
-      return GUESS_DEVTYPE_DONT_KNOW;
-    
-    if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)
-      return GUESS_DEVTYPE_DONT_KNOW;
-  }
-  return GUESS_DEVTYPE_SCSI;
-  
-}
-
-int guess_device_type (const char* dev_name) {
-  return parse_ata_chan_dev(dev_name,NULL);
-}
-
-// global variable holding byte count of allocated memory
-extern long long bytes;
-
-void *FreeNonZero(void* address, int size,int whatline,char* file);
-
-// we are going to take advantage of the fact that FreeBSD's devfs will only
-// have device entries for devices that exist.  So if we get the equivilent of
-// ls /dev/ad?, we have all the ATA devices on the system
-int get_dev_names(char*** names, const char* prefix) {
-  DIR* dir;
-  struct dirent* dirent;
-  int n = 0;
-  char** mp;
-
-  // first, preallocate space for upto max number of ATA devices
-  if (!(mp =  (char **)calloc(MAX_NUM_DEV,sizeof(char*))))
-    return -1;
-  
-  bytes += (sizeof(char*)*MAX_NUM_DEV);
-
-  dir = opendir("/dev");
-  if (dir == NULL) {
-    int myerr = errno;
-    mp= FreeNonZero(mp,(sizeof (char*) * MAX_NUM_DEV),__LINE__,__FILE__);
-    errno = myerr;
-    return -1;
-  }
-  
-  // now step through names
-  while ((dirent = readdir(dir)) && (n < MAX_NUM_DEV)) {
-    if (dirent->d_type == DT_CHR &&
-	(strstr(dirent->d_name,prefix) != NULL) &&
-	(dirent->d_namlen == 3)) {
-      mp[n++] = CustomStrDup(dirent->d_name,1,__LINE__,__FILE__);
-    }
-  }
-  closedir(dir);
-  mp = realloc(mp,n*(sizeof(char*))); // shrink to correct size
-  bytes -= (MAX_NUM_DEV-n)*(sizeof(char*)); // and correct allocated bytes
-  *names=mp;
-  return n;
-}
-
-int make_device_names (char*** devlist, const char* name) {
-  if (!strcmp(name,"SCSI"))
-    return get_dev_names(devlist,"da");
-  else if (!strcmp(name,"ATA"))
-    return get_dev_names(devlist,"ad");
-  else
-    return 0;
-}
diff --git a/sm5/os_generic.cpp b/sm5/os_generic.cpp
deleted file mode 100644
index 90fb367010b576c1fecadf36a93ee40142158c98..0000000000000000000000000000000000000000
--- a/sm5/os_generic.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * os_generic.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003 NAME HERE <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/
- *
- */
-
-/*  PORTING NOTES AND COMMENTS
-
-To port smartmontools to the OS of your choice, you need to:
-
-[0] Contact smartmontools-support@lists.sourceforge.net to check that
-it's not already been done.
-
-[1] Make copies of os_generic.[hc] called os_myOS.[hc]
-
-[2] Modify configure.in so that case "${host}" include myOS
-
-[3] Verify that ./autogen.sh && ./configure && make compiles the code.
-If not, fix any compilation problems.
-
-[4] Provide the functions defined in this file: flesh out the
-skeletons below. Note that for Darwin much of this already
-exists. See some partially developed but incomplete code at:
-http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5_Darwin/
-
-[5] Contact smartmontools-support@lists.sourceforge.net to see about
-checking your code into the smartmontools CVS archive.
-
-*/
-
-// These are needed to define prototypes for the functions defined below
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-// This is to include whatever prototypes you define in os_generic.h
-#include "os_generic.h"
-
-// Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_generic.cpp,v 1.3 2003/10/17 05:14:33 ballen4705 Exp $" \
-ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char* dev_name) {
-    return GUESS_DEVTYPE_DONT_KNOW;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist), the
-// others each contain null-terminated character strings.
-int make_device_names (char*** devlist, const char* name) {
-  return 0;
-}
-
-// Like open().  Return positive integer handle, only used by
-// functions below.  type="ATA" or "SCSI".  If you need to store extra
-// information about your devices, create a private internal array
-// within this file (see os_freebsd.c for an example).
-int deviceopen(const char *pathname, char *type){
-  return -1;
-}
-
-// Like close().  Acts only on handles returned by above function.
-int deviceclose(int fd){
-  return 0;
-}
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data){
-  return -1;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, smart_command_set command, int select, char *data){
-  return -1;
-}
-
-#include <errno.h>
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  return -ENOSYS;
-}
diff --git a/sm5/os_linux.cpp b/sm5/os_linux.cpp
deleted file mode 100644
index bad45fe6a30c89f02a4d977bcc94e95e2cf58bbc..0000000000000000000000000000000000000000
--- a/sm5/os_linux.cpp
+++ /dev/null
@@ -1,799 +0,0 @@
-/* 
- *  os_linux.c
- * 
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003 Doug Gilbert <dougg@torque.net>
- *
- *  Parts of this file are derived from code that was
- *
- *  Written By: Adam Radford <linux@3ware.com>
- *  Modifications By: Joel Jacobson <linux@3ware.com>
- *  		     Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *                    Brad Strand <linux@3ware.com>
- *
- *  Copyright (C) 1999-2003 3ware Inc.
- *
- *  Kernel compatablity By:	Andre Hedrick <andre@suse.com>
- *  Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
- *
- * Other ars of this file are derived from code that was
- * 
- * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
- * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- * 
- */
-
-// This file contains the linux-specific IOCTL parts of
-// smartmontools. It includes one interface routine for ATA devices,
-// one for SCSI devices, and one for ATA devices behind escalade
-// controllers.
-
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <scsi/scsi_ioctl.h>
-#include <dirent.h>
-#include <sys/stat.h>
-
-#include "atacmds.h"
-#include "config.h"
-#include "os_linux.h"
-#include "scsicmds.h"
-#include "smartd.h"
-#include "utility.h"
-
-const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.14 2003/10/27 09:26:20 ballen4705 Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// global variable holding byte count of allocated memory
-extern long long bytes;
-
-void *FreeNonZero(void* address, int size,int whatline,char* file);
-
-// equivalent to open(path, flags)
-int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) 
-    return open(pathname, O_RDWR | O_NONBLOCK);
-  else if (!strcmp(type,"ATA")) 
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  else
-    return -1;
-}
-
-// equivalent to close(file descriptor)
-int deviceclose(int fd){
-  return close(fd);
-}
-
-
-// we are going to take advantage of the fact that Linux's devfs will only
-// have device entries for devices that exist.  So if we get the equivalent of
-// ls /dev/hd[a-t], we have all the ATA devices on the system
-int get_dev_names(char*** names, const char* prefix, int max) {
-  DIR* dir;
-  struct dirent* dirent;
-  int n = 0;
-  int len;
-  char** mp;
-  char buf[20]; // temp holding space to create full /dev/* pathname
-  char linkbuf[1024]; // see what link is pointing to...
-  struct stat statbuf;
-
-  // first, preallocate space for upto max number of ATA devices
-  if (!(mp =  (char **)calloc(max,sizeof(char*))))
-    return -1;
-  
-  bytes += (sizeof(char*)*max);
-
-  dir = opendir("/dev");
-  if (dir == NULL) {
-    int myerr = errno;
-    mp= FreeNonZero(mp,(sizeof (char*) * max),__LINE__,__FILE__);
-    errno = myerr;
-    return -1;
-  }
-  
-  // now step through names
-  // NOTE: We look for block special OR links, as Linux DEVFS will
-  // actually have these as softlinks to real device entry
-  while ((dirent = readdir(dir)) && (n < max)) {
-    if ((dirent->d_type == DT_LNK || dirent->d_type == DT_BLK ) &&
-	(strstr(dirent->d_name,prefix) != NULL) &&
-	(_D_EXACT_NAMLEN(dirent) == 3)) {
-      sprintf(buf,"/dev/%s",dirent->d_name);
-      // if it is a link, then let's check what the link points to
-      if (dirent->d_type == DT_LNK) {
-	memset(linkbuf,0,1024); // fill with nulls
-	sprintf(linkbuf,"/dev/"); // add path prefix
-	len = readlink(buf,linkbuf+5,1018); // append actual link value
-	if (len > -1) {
-	  if (!stat(linkbuf,&statbuf) && S_ISBLK(statbuf.st_mode)) {
-	    // so this is a block device...is it a disc?
-	    char * p = strrchr(linkbuf,'/');
-	    if (p != NULL && !strcmp(p+1,"disc"))
-	      mp[n++] = CustomStrDup(buf,1,__LINE__,__FILE__);
-	  }
-	}
-      } else
-	  mp[n++] = CustomStrDup(buf,1,__LINE__,__FILE__);
-    }
-  }
-  closedir(dir);
-  mp = realloc(mp,n*(sizeof(char*))); // shrink to correct size
-  bytes -= (max-n)*(sizeof(char*)); // and correct allocated bytes
-  *names=mp;
-  return n;
-}
-
-// makes a list of device names to scan, for either ATA or SCSI
-// devices.  Return -1 if no memory remaining, else the number of
-// devices on the list, which can be >=0.
-int make_device_names (char*** devlist, const char* name) {
-  if (!strcmp(name,"SCSI"))
-    //     /dev/sda-sdz
-    return get_dev_names(devlist,"sd", MAXSCSIDEVICES);
-  else if (!strcmp(name,"ATA"))
-    //     /dev/hda-hdt
-    return get_dev_names(devlist,"hd", MAXATADEVICES);
-  else
-    return 0;
-}
-
-
-// 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 ata_command_interface(int device, smart_command_set command, int select, char *data){
-  unsigned char buff[STRANGE_BUFFER_LENGTH];
-  int retval, copydata=0;
-
-  // The two linux IOCTL's that we use.  These MUST be consistent with
-  // the same quantities in the kernel include file linux/hdreg.h
-  const int HDIO_DRIVE_TASK = 0x031e;
-  const int HDIO_DRIVE_CMD  = 0x031f;
-  const int HDIO_DRIVE_CMD_OFFSET = 4;
-
-  // See struct hd_drive_cmd_hdr in hdreg.h
-  // buff[0]: ATA COMMAND CODE REGISTER
-  // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
-  // buff[2]: ATA FEATURES REGISTER
-  // buff[3]: ATA SECTOR COUNT REGISTER
-  
-  // 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;
-  case STATUS_CHECK:
-    // This command uses HDIO_DRIVE_TASK and has different syntax than
-    // the other commands.
-    buff[1]=SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in linux_ata_command_interface()\n"
-	 "Please contact " PACKAGE_BUGREPORT "\n", command);
-    errno=ENOSYS;
-    return -1;
-  }
-  
-  // There are two different types of ioctls().  The HDIO_DRIVE_TASK
-  // one is this:
-  if (command==STATUS_CHECK){
-
-    // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
-    // have to read the IDE driver source code.  Sigh.
-    // buff[0]: ATA COMMAND CODE REGISTER
-    // buff[1]: ATA FEATURES REGISTER
-    // buff[2]: ATA SECTOR_COUNT
-    // buff[3]: ATA SECTOR NUMBER
-    // buff[4]: ATA CYL LO REGISTER
-    // buff[5]: ATA CYL HI REGISTER
-    // buff[6]: ATA DEVICE HEAD
-
-    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
-    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
-    buff[4]=normal_lo;
-    buff[5]=normal_hi;
-    
-    if ((retval=ioctl(device, HDIO_DRIVE_TASK, buff)))
-      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;   
-  }
-  
-#if (1)
-  // Note to people doing ports to other OSes -- don't worry about
-  // this block -- you can ignore it.  I have put it here because
-  // under linux when you do IDENTIFY DEVICE to a packet device, it
-  // generates an ugly kernel syslog error message.  This is harmless
-  // but frightens users.  So this block is an attempt to detect
-  // packet devices and make IDENTIFY DEVICE fail "nicely" without a
-  // syslog error message.
-
-  // This doesn't always work, since ATA-3 did not have a separate
-  // IDENTIFY PACKET DEVICE command.  In fact while ATAPI was
-  // introduced in ATA-3, IDENTIFY PACKET DEVICE only appeared in ATA
-  // 4 revision 2.  Anyway, this doesn't matter, since packet devices
-  // don't support SMART anyway.
-
-  // for IDENTIFY command, check if device is a packet device, and if
-  // it is, then we simulate a 'clean' error without calling the
-  // lower-level ioctl that will generate a kernel error log message.
-  //
-  // To add some extra complexity, note that IDENTIFY PACKET DEVICE
-  // was only introduced in ATA-4 revision 1.  Before that, a packet
-  // device responds to IDENTIFY DEVICE.
-  //
-  // Byte 160: low order bits of IDENTIFY DEVICE word 80
-  if (command==IDENTIFY || command==PIDENTIFY){
-    unsigned char deviceid[512];
-    const int HDIO_GET_IDENTITY=0x030d;
-
-    // we first get the device identity, as seen when the system was
-    // booted or the device was FIRST registered.  This will not be
-    // current if the user has subsequently changed some of the
-    // parameters.
-    int getid=ioctl(device, HDIO_GET_IDENTITY, deviceid);
-
-    // If the IOCTL succeeded, and the device is ATAPI and not ATAPI 1-3...
-    if (
-	!getid                                            &&     // ioctl succeeded
-	deviceid[1]>>7                                    &&     // is Packet device
-	(deviceid[160] || deviceid[161])                  &&     // word 80 valid
-	(deviceid[160]!=0xff || deviceid[161]!=0xff)      &&     // word 80 valid
-        ((deviceid[160] & 0xf0) || (deviceid[161] & 0x8f))       // is ATA-4 through 14
-      ) {
-      // then swap the IDENTIFY and PIDENTIFY commands
-      if (command==IDENTIFY)
-	buff[0]=WIN_PIDENTIFY;
-      
-      if (command==PIDENTIFY)
-	buff[0]=WIN_IDENTIFY;      
-    }
-  }
-#endif
-  
-  // We are now doing the HDIO_DRIVE_CMD type ioctl.
-  if ((retval=ioctl(device, HDIO_DRIVE_CMD, buff)))
-    return -1;
-
-  // if the command returns data, copy it back
-  if (copydata)
-    memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, 512);
-  
-  return 0; 
-}
-
-/* SCSI command transmission interface function, implementation is OS
- * specific. Returns 0 if SCSI command successfully launched and response
- * received, else returns a negative errno value */
-
-/* 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 in Linux 2.4.21 and 2.5.70 to extend SEND DIAGNOSTIC timeout
- * to 2 hours in order to allow long foreground extended self tests. */
-int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
-{
-    struct linux_ioctl_send_command wrk;
-    int status, buff_offset;
-    size_t len;
-
-    memcpy(wrk.buff, iop->cmnd, iop->cmnd_len);
-    buff_offset = iop->cmnd_len;
-    if (report > 0) {
-        int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-    switch (iop->dxfer_dir) {
-        case DXFER_NONE:
-            wrk.inbufsize = 0;
-            wrk.outbufsize = 0;
-            break;
-        case DXFER_FROM_DEVICE:
-            wrk.inbufsize = 0;
-            if (iop->dxfer_len > MAX_DXFER_LEN)
-                return -EINVAL;
-            wrk.outbufsize = iop->dxfer_len;
-            break;
-        case DXFER_TO_DEVICE:
-            if (iop->dxfer_len > MAX_DXFER_LEN)
-                return -EINVAL;
-            memcpy(wrk.buff + buff_offset, iop->dxferp, iop->dxfer_len);
-            wrk.inbufsize = iop->dxfer_len;
-            wrk.outbufsize = 0;
-            break;
-        default:
-            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
-            return -EINVAL;
-    }
-    iop->resp_sense_len = 0;
-    iop->scsi_status = 0;
-    iop->resid = 0;
-    status = ioctl(dev_fd, SCSI_IOCTL_SEND_COMMAND , &wrk);
-    if (-1 == status) {
-        if (report)
-            pout("  status=-1, errno=%d [%s]\n", errno, strerror(errno));
-        return -errno;
-    }
-    if (0 == status) {
-        if (report > 0)
-            pout("  status=0\n");
-        if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
-            memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
-            if (report > 1) {
-                int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-                pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-                     (trunc ? " [only first 256 bytes shown]" : ""));
-                dStrHex(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) & 0xf))
-        iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
-    len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
-                SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
-    if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && 
-        iop->sensep && (len > 0)) {
-        memcpy(iop->sensep, wrk.buff, len);
-        iop->resp_sense_len = len;
-        if (report > 1) {
-            pout("  >>> Sense buffer, len=%d:\n", (int)len);
-            dStrHex(wrk.buff, len , 1);
-        }
-    }
-    if (report) {
-        if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
-            pout("  status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
-                 wrk.buff[2] & 0xf, wrk.buff[12], wrk.buff[13]);
-        }
-        else
-            pout("  status=0x%x\n", status);
-    }
-    if (iop->scsi_status > 0)
-        return 0;
-    else {
-        if (report > 0)
-            pout("  ioctl status=0x%x but scsi status=0, fail with EIO\n", 
-                 status);
-        return -EIO;      /* give up, assume no device there */
-    }
-}
-
-void printwarning(smart_command_set command);
-
-// PURPOSE
-//   This is an interface routine meant to isolate the OS dependent
-//   parts of the code, and to provide a debugging interface.  Each
-//   different port and OS needs to provide it's own interface.  This
-//   is the linux interface to the 3ware 3w-xxxx driver.  It allows ATA
-//   commands to be passed through the SCSI driver.
-// DETAILED DESCRIPTION OF ARGUMENTS
-//   fd: is the file descriptor provided by open()
-//   disknum is the disk number (0 to 15) in the RAID array
-//   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"
-
-int escalade_command_interface(int fd, int disknum, smart_command_set command, int select, char *data){
-
-  // Structures for passing commands through 3Ware Escalade Linux Driver
-  TW_Ioctl ioctlbuf;
-  TW_Passthru passthru;
-
-  // If command returns 512 bytes, set to 1, else 0
-  int readdata=0;
-
-  // Clear out the data structures
-  memset (&ioctlbuf, 0, sizeof(TW_Ioctl));
-  memset (&passthru, 0, sizeof(TW_Passthru));
-
-  // Same for (almost) all commands - but some reset below
-  passthru.byte0.opcode  = 0x11;
-  passthru.request_id    = 0xFF;
-  passthru.byte3.aport   = disknum;
-  passthru.byte3.host_id = 0;
-  passthru.status        = 0;           
-  passthru.flags         = 0x1;
-  passthru.drive_head    = 0x0;
-  passthru.sector_num    = 0;
-
-  // All SMART commands use this CL/CH signature.  These are magic
-  // values from the ATA specifications.
-  passthru.cylinder_lo = 0x4F;
-  passthru.cylinder_hi = 0xC2;
-  
-  // SMART ATA COMMAND REGISTER value
-  passthru.command = WIN_SMART;
-  
-  // Is this a command that returns 512 bytes?
-  if (command == READ_VALUES ||
-      command == READ_THRESHOLDS ||
-      command == READ_LOG ||
-      command == IDENTIFY) {
-    readdata=1;
-    passthru.byte0.sgloff = 0x5;
-    passthru.size         = 0x7;
-    passthru.param        = 0xD;
-    passthru.sector_count = 0x1;
-  }
-  else {
-    // Non data command -- but doesn't use large sector 
-    // count register values.  passthru.param values are:
-    // 0x00 - non data command without TFR write check,
-    // 0x08 - non data command with TFR write check,
-    passthru.byte0.sgloff = 0x0;
-    passthru.size         = 0x5;
-    passthru.param        = 0x8;
-    passthru.sector_count = 0x0;
-  }
-  
-  // Now set ATA registers depending upon command
-  switch (command){
-  case READ_VALUES:
-    passthru.features = SMART_READ_VALUES;
-    break;
-  case READ_THRESHOLDS:
-    passthru.features = SMART_READ_THRESHOLDS;
-    break;
-  case READ_LOG:
-    passthru.features = SMART_READ_LOG_SECTOR;
-    // log number to return
-    passthru.sector_num  = select;
-    break;
-  case IDENTIFY:
-    // ATA IDENTIFY DEVICE
-    passthru.command     = 0xEc;
-    passthru.features    = 0;
-    passthru.cylinder_lo = 0;
-    passthru.cylinder_hi = 0;
-    break;
-  case PIDENTIFY:
-    // 3WARE controller can NOT have packet device internally
-    pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
-    errno=ENODEV;
-    return -1;
-  case ENABLE:
-    passthru.features = SMART_ENABLE;
-    break;
-  case DISABLE:
-    passthru.features = SMART_DISABLE;
-    break;
-  case AUTO_OFFLINE:
-    passthru.features = SMART_AUTO_OFFLINE;
-    // Enable or disable?
-    passthru.sector_count = select;
-    break;
-  case AUTOSAVE:
-    passthru.features = SMART_AUTOSAVE;
-    // Enable or disable?
-    passthru.sector_count = select;
-    break;
-  case IMMEDIATE_OFFLINE:
-    passthru.features = SMART_IMMEDIATE_OFFLINE;
-    // What test type to run?
-    passthru.sector_num  = select;
-    break;
-  case STATUS_CHECK:
-    passthru.features = SMART_STATUS;
-    break;
-  case STATUS:
-    // This is JUST to see if SMART is enabled, by giving SMART status
-    // command. But it doesn't say if status was good, or failing.
-    // See below for the difference.
-    passthru.features = SMART_STATUS;
-    break;
-  default:
-    pout("Unrecognized command %d in linux_3ware_command_interface(disk %d)\n"
-	 "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
-    errno=ENOSYS;
-    return -1;
-  }
-
-  /* Copy the passthru command into the ioctl input buffer */
-  memcpy(&ioctlbuf.input_data, &passthru, sizeof(TW_Passthru));
-  ioctlbuf.cdb[0] = TW_IOCTL;
-  ioctlbuf.opcode = TW_ATA_PASSTHRU;
-
-  // CHECKME -- IS THIS RIGHT?? Even for non data I/O commands?
-  ioctlbuf.input_length = 512;
-  ioctlbuf.output_length = 512;
-  
-  /* Now send the command down through an ioctl() */
-  if (ioctl(fd, SCSI_IOCTL_SEND_COMMAND, &ioctlbuf)) {
-    // If error was provoked by driver, tell user how to fix it
-    if ((command==AUTO_OFFLINE || command==AUTOSAVE) && select){
-      printwarning(command);
-      errno=ENOTSUP;
-    }
-    return -1;
-  }
-
-  // If this is a read data command, copy data to output buffer
-  if (readdata){
-    TW_Output *tw_output=(TW_Output *)&ioctlbuf;
-    memcpy(data, tw_output->output_data, 512);
-  }
-  
-  // We are finished with all commands except for STATUS_CHECK
-  if (command!=STATUS_CHECK) {
-    return 0;
-  }
-  else {
-
-    // To find out if the SMART RETURN STATUS is good or failing, we
-    // need to examine the values of the Cylinder Low and Cylinder
-    // High Registers.
-    
-    TW_Output *tw_output=(TW_Output *)&ioctlbuf;
-    TW_Passthru *tw_passthru_returned=(TW_Passthru *)&(tw_output->output_data);
-    unsigned short cyl_lo=tw_passthru_returned->cylinder_lo;
-    unsigned short cyl_hi=tw_passthru_returned->cylinder_hi;
-    
-    // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
-    if (cyl_lo==0x4F && cyl_hi==0xC2)
-      return 0;
-    
-    // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
-    if (cyl_lo==0xF4 && cyl_hi==0x2C)
-      return 1;
-    
-    // Any other values mean that something has gone wrong with the command
-    printwarning(command);
-    errno=ENOSYS;
-    return 0;
-  }
-}
-
-// Utility function for printing warnings
-void printwarning(smart_command_set command){
-  static int printed1=0,printed2=0,printed3=0;
-  const char* message=
-    "can not be passed through the 3ware 3w-xxxx driver.  This can be fixed by\n"
-    "applying a simple 3w-xxxx driver patch that can be found here:\n"
-    PROJECTHOME "\n"
-    "Alternatively, upgrade your 3w-xxxx driver to version 1.02.00.037 or greater.\n\n";
-
-  if (command==AUTO_OFFLINE && !printed1) {
-    printed1=1;
-    pout("The SMART AUTO-OFFLINE ENABLE command (smartmontools -o on option/Directive)\n%s", message);
-  } 
-  else if (command==AUTOSAVE && !printed2) {
-    printed2=1;
-    pout("The SMART AUTOSAVE ENABLE command (smartmontools -S on option/Directive)\n%s", message);
-  }
-  else if (command==STATUS_CHECK && !printed3) {
-    printed3=1;
-    pout("The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n%s", message);
-  }
-  
-  return;
-}
-
-// Guess device type (ata or scsi) based on device name (Linux
-// specific) SCSI device name in linux can be sd, sr, scd, st, nst,
-// osst, nosst and sg.
-static const char * lin_dev_prefix = "/dev/";
-static const char * lin_dev_ata_disk_plus = "h";
-static const char * lin_dev_ata_devfs_disk_plus = "ide/";
-static const char * lin_dev_scsi_devfs_disk_plus = "scsi/";
-static const char * lin_dev_scsi_disk_plus = "s";
-static const char * lin_dev_scsi_tape1 = "ns";
-static const char * lin_dev_scsi_tape2 = "os";
-static const char * lin_dev_scsi_tape3 = "nos";
-
-int guess_device_type(const char * dev_name) {
-  int len;
-  int dev_prefix_len = strlen(lin_dev_prefix);
-  
-  // if dev_name null, or string length zero
-  if (!dev_name || !(len = strlen(dev_name)))
-    return GUESS_DEVTYPE_DONT_KNOW;
-  
-  // Remove the leading /dev/... if it's there
-  if (!strncmp(lin_dev_prefix, dev_name, dev_prefix_len)) {
-    if (len <= dev_prefix_len)
-      // if nothing else in the string, unrecognized
-      return GUESS_DEVTYPE_DONT_KNOW;
-    // else advance pointer to following characters
-    dev_name += dev_prefix_len;
-  }
-  
-  // form /dev/h* or h*
-  if (!strncmp(lin_dev_ata_disk_plus, dev_name,
-	       strlen(lin_dev_ata_disk_plus)))
-    return GUESS_DEVTYPE_ATA;
-  
-  // form /dev/ide/* or ide/*
-  if (!strncmp(lin_dev_ata_devfs_disk_plus, dev_name,
-	       strlen(lin_dev_ata_devfs_disk_plus)))
-    return GUESS_DEVTYPE_ATA;
-
-  // form /dev/s* or s*
-  if (!strncmp(lin_dev_scsi_disk_plus, dev_name,
-	       strlen(lin_dev_scsi_disk_plus)))
-    return GUESS_DEVTYPE_SCSI;
-
-  // form /dev/scsi/* or scsi/*
-  if (!strncmp(lin_dev_scsi_devfs_disk_plus, dev_name,
-	       strlen(lin_dev_scsi_devfs_disk_plus)))
-    return GUESS_DEVTYPE_SCSI;
-  
-  // form /dev/ns* or ns*
-  if (!strncmp(lin_dev_scsi_tape1, dev_name,
-	       strlen(lin_dev_scsi_tape1)))
-    return GUESS_DEVTYPE_SCSI;
-  
-  // form /dev/os* or os*
-  if (!strncmp(lin_dev_scsi_tape2, dev_name,
-	       strlen(lin_dev_scsi_tape2)))
-    return GUESS_DEVTYPE_SCSI;
-  
-  // form /dev/nos* or nos*
-  if (!strncmp(lin_dev_scsi_tape3, dev_name,
-	       strlen(lin_dev_scsi_tape3)))
-    return GUESS_DEVTYPE_SCSI;
-  
-  // we failed to recognize any of the forms
-  return GUESS_DEVTYPE_DONT_KNOW;
-}
diff --git a/sm5/os_solaris.cpp b/sm5/os_solaris.cpp
deleted file mode 100644
index f22bbfc98a2162351bb88af28cc669e7c773977d..0000000000000000000000000000000000000000
--- a/sm5/os_solaris.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * os_solaris.c
- *
- * Home page of code is: http://smartmontools.sourceforge.net
- *
- * Copyright (C) 2003 Casper Dik <smartmontools-support@lists.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This code was originally developed as a Senior Thesis by Michael Cornwell
- * at the Concurrent Systems Laboratory (now part of the Storage Systems
- * Research Center), Jack Baskin School of Engineering, University of
- * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
- *
- */
-
-/*
-  If you want to do a solaris port, some sample code, showing how to
-  access SCSI data under solaris, can be found here:
-  http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=2003721.204932.21807%40cable.prodigy.com
-  Please contact the smartmontools developers at:
-  smartmontools-support@lists.sourceforge.net
-*/
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-
-// These are needed to define prototypes for the functions defined below
-#include "config.h"
-#include "atacmds.h"
-#include "scsicmds.h"
-#include "utility.h"
-
-// This is to include whatever prototypes you define in os_solaris.h
-#include "os_solaris.h"
-
-extern long long bytes;
-
-const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.8 2003/10/26 02:20:40 ballen4705 Exp $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
-
-// The printwarning() function warns about unimplemented functions
-int printedout[2];
-char *unimplemented[2]={
-  "ATA command routine ata_command_interface()",
-  "3ware Escalade Controller command routine escalade_command_interface()",
-};
-
-int printwarning(int which){
-  if (!unimplemented[which])
-    return 0;
-
-  if (printedout[which])
-    return 1;
-  
-  printedout[which]=1;
-  
-  pout("\n"
-       "#######################################################################\n"
-       "%s NOT IMPLEMENTED under Solaris.\n"
-       "Please contact " PACKAGE_BUGREPORT " if\n"
-       "you want to help in porting smartmontools to Solaris.\n"
-       "#######################################################################\n"
-       "\n",
-       unimplemented[which]);
-
-  return 1;
-}
-
-static const char *uscsidrvrs[] = {
-	"sd",
-	"ssd",
-	"st"
-};
-
-static const char *atadrvrs[] = {
-	"cmdk",
-	"dad",
-};
-
-static int
-isdevtype(const char *dev_name, const char *table[], int tsize)
-{
-  char devpath[MAXPATHLEN];
-  int i;
-  char *basename;
-
-  if (realpath(dev_name, devpath) == NULL)
-    return 0;
- 
-  if ((basename = strrchr(devpath, '/')) == NULL)
-    return 0;
-
-  basename++;
-
-  for (i = 0; i < tsize; i++) {
-    int l = strlen(table[i]);
-    if (strncmp(basename, table[i], l) == 0 && basename[l] == '@')
-      return 1;
-  }
-  return 0;
-}
-
-static int
-isscsidev(const char *path)
-{
-  return isdevtype(path, uscsidrvrs, sizeof (uscsidrvrs) / sizeof (char *));
-}
-
-static int
-isatadev(const char *path)
-{
-  return isdevtype(path, atadrvrs, sizeof (atadrvrs) / sizeof (char *));
-}
-
-// tries to guess device type given the name (a path)
-int guess_device_type (const char* dev_name) {
-  if (isscsidev(dev_name))
-    return GUESS_DEVTYPE_SCSI;
-  else if (isatadev(dev_name))
-    return GUESS_DEVTYPE_ATA;
-  else
-    return GUESS_DEVTYPE_DONT_KNOW;
-}
-
-struct pathlist {
-	char **names;
-	int  nnames;
-	int  maxnames;
-};
-
-static int
-addpath(const char *path, struct pathlist *res)
-{
-	if (++res->nnames > res->maxnames) {
-		res->maxnames += 16;
-		res->names = realloc(res->names, res->maxnames * sizeof (char *));
-		if (res->names == NULL)
-			return -1;
-		bytes += 16*sizeof(char *);
-	}
-	if (!(res->names[res->nnames-1] = CustomStrDup((char *)path, 1, __LINE__, __FILE__)))
-		return -1;
-	return 0;
-}
-
-static int 
-grokdir(const char *dir, struct pathlist *res, int testfun(const char *))
-{
-	char pathbuf[MAXPATHLEN];
-	size_t len;
-	DIR *dp;
-	struct dirent *de;
-	int isdisk = strstr(dir, "dsk") != NULL;
-	char *p;
-
-	len = snprintf(pathbuf, sizeof (pathbuf), "%s/", dir);
-	if (len >= sizeof (pathbuf))
-		return -1;
-
-	dp = opendir(dir);
-	if (dp == NULL)
-		return 0;
-
-	while ((de = readdir(dp)) != NULL) {
-		if (de->d_name[0] == '.')
-			continue;
-
-		if (strlen(de->d_name) + len >= sizeof (pathbuf))
-			continue;
-
-		if (isdisk) {
-			/* Disk represented by slice 0 */
-			p = strstr(de->d_name, "s0");
-			/* String doesn't end in "s0\0" */
-			if (p == NULL || p[2] != '\0')
-				continue;
-		} else {
-			/* Tape drive represented by the all-digit device */
-			for (p = de->d_name; *p; p++)
-                                if (!isdigit((int)(*p)))
-					break;
-			if (*p != '\0')
-				continue;
-		}
-		strcpy(&pathbuf[len], de->d_name);
-		if (testfun(pathbuf)) {
-			if (addpath(pathbuf, res) == -1) {
-				closedir(dp);
-				return -1;
-			}
-		}
-	}
-	closedir(dp);
-
-	return 0;
-}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number of devices, or -1 if out of memory.
-int make_device_names (char*** devlist, const char* name) {
-	struct pathlist res;
-
-	res.nnames = res.maxnames = 0;
-	res.names = NULL;
-	if (strcmp(name, "SCSI") == 0) {
-		if (grokdir("/dev/rdsk", &res, isscsidev) == -1)
-			return -1;
-		if (grokdir("/dev/rmt", &res, isscsidev) == -1)
-			return -1;
-
-		// shrink array to min possible size
-		res.names = realloc(res.names, res.nnames * sizeof (char *));
-		bytes -= sizeof(char *)*(res.maxnames-res.nnames);
-
-		// pass list back
-		*devlist = res.names;
-		return res.nnames;
-	}
-	
-	// ATA case not implemented
-	*devlist=NULL;
-	return 0;
-}
-
-// Like open().  Return integer handle, used by functions below only.
-// type="ATA" or "SCSI".
-int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) 
-    return open(pathname, O_RDWR | O_NONBLOCK);
-  else if (!strcmp(type,"ATA")) 
-    return open(pathname, O_RDONLY | O_NONBLOCK);
-  else
-    return -1;
-}
-
-// Like close().  Acts on handles returned by above function.
-int deviceclose(int fd){
-    return close(fd);
-}
-
-
-// Interface to ATA devices.  See os_linux.c
-int ata_command_interface(int fd, smart_command_set command, int select, char *data){
-  if (printwarning(0))
-    return -1;
-  return -1;
-}
-
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, smart_command_set command, int select, char *data){
-  if (printwarning(1))
-    return -1;
-  return -1;
-}
-
-#include <errno.h>
-#include <sys/scsi/generic/commands.h>
-#include <sys/scsi/generic/status.h>
-#include <sys/scsi/impl/types.h>
-#include <sys/scsi/impl/uscsi.h>
-
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
-  struct uscsi_cmd uscsi;
-
-    if (report > 0) {
-        int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
-    }
-
-
-  memset(&uscsi, 0, sizeof (uscsi));
-
-  uscsi.uscsi_cdb = (void *)iop->cmnd;
-  uscsi.uscsi_cdblen = iop->cmnd_len;
-  if (iop->timeout == 0)
-    uscsi.uscsi_timeout = 60; /* XXX */
-  else
-    uscsi.uscsi_timeout = iop->timeout;
-  uscsi.uscsi_bufaddr = (void *)iop->dxferp;
-  uscsi.uscsi_buflen = iop->dxfer_len;
-  uscsi.uscsi_rqbuf = (void *)iop->sensep;
-  uscsi.uscsi_rqlen = iop->max_sense_len;
-
-  switch (iop->dxfer_dir) {
-  case DXFER_NONE:
-  case DXFER_FROM_DEVICE:
-    uscsi.uscsi_flags = USCSI_READ;
-    break;
-  case DXFER_TO_DEVICE:
-    uscsi.uscsi_flags = USCSI_WRITE;
-    break;
-  default:
-    return -EINVAL;
-  }
-  uscsi.uscsi_flags |= USCSI_ISOLATE;
-
-  if (ioctl(fd, USCSICMD, &uscsi))
-    return -errno;
-
-  iop->scsi_status = uscsi.uscsi_status;
-  iop->resid = uscsi.uscsi_resid;
-  iop->resp_sense_len = iop->max_sense_len - uscsi.uscsi_rqresid;
-
-  if (report > 0) {
-    int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    pout("  status=0\n");
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-         (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-
-  return (0);
-}
diff --git a/sm5/scsicmds.cpp b/sm5/scsicmds.cpp
deleted file mode 100644
index 92a742e76bb52ab8bd2c7415c1cceb052aa861bf..0000000000000000000000000000000000000000
--- a/sm5/scsicmds.cpp
+++ /dev/null
@@ -1,1671 +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 <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.54 2003/10/13 12:43:22 ballen4705 Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID;
-
-/* for passing global control variables */
-extern smartmonctrl *con;
-
-/* output binary in hex and optionally ascii */
-void dStrHex(const char* str, int len, int no_ascii)
-{
-    const char* p = str;
-    unsigned char c;
-    char buff[82];
-    int a = 0;
-    const int bpstart = 5;
-    const int cpstart = 60;
-    int cpos = cpstart;
-    int bpos = bpstart;
-    int i, k;
-    
-    if (len <= 0) return;
-    memset(buff,' ',80);
-    buff[80]='\0';
-    k = sprintf(buff + 1, "%.2x", a);
-    buff[k + 1] = ' ';
-    if (bpos >= ((bpstart + (9 * 3))))
-        bpos++;
-
-    for(i = 0; i < len; i++)
-    {
-        c = *p++;
-        bpos += 3;
-        if (bpos == (bpstart + (9 * 3)))
-            bpos++;
-        sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c);
-        buff[bpos + 2] = ' ';
-        if (no_ascii)
-            buff[cpos++] = ' ';
-        else {
-            if ((c < ' ') || (c >= 0x7f))
-                c='.';
-            buff[cpos++] = c;
-        }
-        if (cpos > (cpstart+15))
-        {
-            pout("%s\n", buff);
-            bpos = bpstart;
-            cpos = cpstart;
-            a += 16;
-            memset(buff,' ',80);
-            k = sprintf(buff + 1, "%.2x", a);
-            buff[k + 1] = ' ';
-        }
-    }
-    if (cpos > cpstart)
-    {
-        pout("%s\n", buff);
-    }
-}
-
-struct scsi_opcode_name {
-    UINT8 opcode;
-    const char * name;
-};
-
-static struct scsi_opcode_name opcode_name_arr[] = {
-    /* in ascending opcode order */
-    {TEST_UNIT_READY, "test unit ready"},       /* 0x00 */
-    {REQUEST_SENSE, "request sense"},           /* 0x03 */
-    {INQUIRY, "inquiry"},                       /* 0x12 */
-    {MODE_SELECT, "mode select"},               /* 0x15 */
-    {MODE_SENSE, "mode sense"},                 /* 0x1a */
-    {RECEIVE_DIAGNOSTIC, "receive diagnostic"}, /* 0x1c */
-    {SEND_DIAGNOSTIC, "send diagnostic"},       /* 0x1d */
-    {LOG_SENSE, "log sense"},                   /* 0x4d */
-    {MODE_SELECT_10, "mode select(10)"},        /* 0x55 */
-    {MODE_SENSE_10, "mode sense(10)"},          /* 0x5a */
-};
-
-const char * scsi_get_opcode_name(UINT8 opcode)
-{
-    int k;
-    int len = sizeof(opcode_name_arr) / sizeof(opcode_name_arr[0]);
-    struct scsi_opcode_name * onp;
-
-    for (k = 0; k < len; ++k) {
-        onp = &opcode_name_arr[k];
-        if (opcode == onp->opcode)
-            return onp->name;
-        else if (opcode < onp->opcode)
-            return NULL;
-    }
-    return NULL;
-}
-
-
-void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
-                          struct scsi_sense_disect * out)
-{
-    memset(out, 0, sizeof(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 SIMPLE_ERR_NOT_READY;
-    else if (SCSI_SK_ILLEGAL_REQUEST == sinfo->sense_key) {
-        if (SCSI_ASC_UNKNOWN_OPCODE == sinfo->asc)
-            return SIMPLE_ERR_BAD_OPCODE;
-        else if (SCSI_ASC_UNKNOWN_FIELD == sinfo->asc)
-            return SIMPLE_ERR_BAD_FIELD;
-        else if (SCSI_ASC_UNKNOWN_PARAM == sinfo->asc)
-            return SIMPLE_ERR_BAD_PARAM;
-    }
-    return SIMPLE_NO_ERROR;
-}
-
-const char * scsiErrString(int scsiErr)
-{
-    if (scsiErr < 0)
-        return strerror(-scsiErr);
-    switch (scsiErr) {
-        case SIMPLE_NO_ERROR: 
-            return "no error";
-        case SIMPLE_ERR_NOT_READY: 
-            return "device not ready";
-        case SIMPLE_ERR_BAD_OPCODE: 
-            return "unsupported scsi opcode";
-        case SIMPLE_ERR_BAD_FIELD: 
-            return "unsupported field in scsi command";
-        case SIMPLE_ERR_BAD_PARAM: 
-            return "badly formed scsi parameters";
-        case SIMPLE_ERR_BAD_RESP: 
-            return "scsi response fails sanity test";
-        default:
-            return "unknown error";
-    }
-}
-
-/* Sends LOG SENSE command. Returns 0 if ok, 1 if device NOT READY, 2 if
-   command not supported, 3 if field (within command) not supported or
-   returns negated errno.  SPC sections 7.6 and 8.2 N.B. Sets PC==1
-   to fetch "current cumulative" log pages.
-   If known_resp_len > 0 then a single fetch is done for this response
-   length. If known_resp_len == 0 then twin fetches are performed, the
-   first to deduce the response length, then send the same command again
-   requesting the deduced response length. This protects certain fragile 
-   HBAs. The twin fetch technique should not be used with the TapeAlert
-   log page since it clears its state flags after each fetch. */
-int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
-                 int known_resp_len)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int pageLen;
-    int status, res;
-
-    if (known_resp_len > bufLen)
-        return -EIO;
-    if (known_resp_len > 0)
-        pageLen = known_resp_len;
-    else {
-        /* Starting twin fetch strategy: first fetch to find respone length */
-        pageLen = 4;
-        if (pageLen > bufLen)
-            return -EIO;
-
-        memset(&io_hdr, 0, sizeof(io_hdr));
-        memset(cdb, 0, sizeof(cdb));
-        io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-        io_hdr.dxfer_len = pageLen;
-        io_hdr.dxferp = pBuf;
-        cdb[0] = LOG_SENSE;
-        cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-        cdb[7] = (pageLen >> 8) & 0xff;
-        cdb[8] = pageLen & 0xff;
-        io_hdr.cmnd = cdb;
-        io_hdr.cmnd_len = sizeof(cdb);
-        io_hdr.sensep = sense;
-        io_hdr.max_sense_len = sizeof(sense);
-    
-        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-        if (0 != status)
-            return status;
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        if ((res = scsiSimpleSenseFilter(&sinfo)))
-            return res;
-        pageLen = (pBuf[2] << 8) + pBuf[3] + 4;
-        if (pageLen > bufLen)
-            pageLen = bufLen;
-    }
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = pageLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = LOG_SENSE;
-    cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
-    cdb[7] = (pageLen >> 8) & 0xff;
-    cdb[8] = pageLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* 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;
-
-    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, con->reportscsiioctl);
-    if (0 == status) {
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        status = scsiSimpleSenseFilter(&sinfo);
-        if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {
-            int offset;
-
-            offset = scsiModePageOffset(pBuf, bufLen, 0);
-            if (offset < 0)
-                return SIMPLE_ERR_BAD_RESP;
-            else if (pagenum != (pBuf[offset] & 0x3f))
-                return SIMPLE_ERR_BAD_RESP;
-        }
-    }
-    return status;
-}
-
-/* Sends a 6 byte MODE SELECT command. Assumes given pBuf is the response
- * from a corresponding 6 byte MODE SENSE command. Such a response should
- * have a 4 byte header followed by 0 or more 8 byte block descriptors
- * (normally 1) and then 1 mode page. Returns 0 if ok, 1 if NOT READY,
- * 2 if command not supported (then MODE SELECT(10) may be supported), 
- * 3 if field in command not supported, 4 if bad parameter to command
- * or returns negated errno. SPC sections 7.7 and 8.4 */
-int scsiModeSelect(int device, int 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;
-
-    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, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* MODE SENSE (10 byte). Returns 0 if ok, 1 if NOT READY, 2 if command 
- * not supported (then MODE SENSE(6) might be supported), 3 if field in
- * command not supported or returns negated errno.  
- * SPC sections 7.10 and 8.4 */
-int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[10];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = MODE_SENSE_10;
-    cdb[2] = (pc << 6) | (pagenum & 0x3f);
-    cdb[7] = (bufLen >> 8) & 0xff;
-    cdb[8] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 == status) {
-        scsi_do_sense_disect(&io_hdr, &sinfo);
-        status = scsiSimpleSenseFilter(&sinfo);
-        if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {
-            int offset;
-
-            offset = scsiModePageOffset(pBuf, bufLen, 1);
-            if (offset < 0)
-                return SIMPLE_ERR_BAD_RESP;
-            else if (pagenum != (pBuf[offset] & 0x3f))
-                return SIMPLE_ERR_BAD_RESP;
-        }
-    }
-    return status;
-}
-
-/* Sends a 10 byte MODE SELECT command. Assumes given pBuf is the response
- * from a corresponding 10 byte MODE SENSE command. Such a response should
- * have a 8 byte header followed by 0 or more 8 byte block descriptors
- * (normally 1) and then 1 mode page. Returns 0 if ok, 1 NOT REAFY, 2 if 
- * command not supported (then MODE SELECT(6) may be supported), 3 if field
- * in command not supported, 4 if bad parameter to command or returns
- * negated errno. SAM sections 7.8 and 8.4 */
-int scsiModeSelect10(int device, int 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;
-
-    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, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* Standard INQUIRY returns 0 for ok, anything else is a major problem.
- * bufLen should be 36 for unsafe devices (like USB mass storage stuff)
- * otherwise they can lock up! SPC sections 7.4 and 8.6 */
-int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_sense_disect sinfo;
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    int status;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = INQUIRY;
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* INQUIRY to fetch Vital Page Data.  Returns 0 if ok, 1 if NOT READY
- * (unlikely), 2 if command not supported, 3 if field in command not 
- * supported, 5 if response indicates that EVPD bit ignored or returns
- * negated errno. SPC section 7.4 and 8.6 */
-int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status, res;
-
-    if ((bufLen < 0) || (bufLen > 255))
-        return -EINVAL;
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    if (bufLen > 1)
-        pBuf[1] = 0x0;
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = INQUIRY;
-    cdb[1] = 0x1;       /* set EVPD bit (enable Vital Product Data) */
-    cdb[2] = vpd_page;
-    cdb[4] = bufLen;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    if ((res = scsiSimpleSenseFilter(&sinfo)))
-        return res;
-    /* Guard against devices that ignore EVPD bit and do standard INQUIRY */
-    if (bufLen > 1) {
-        if (vpd_page == pBuf[1]) {
-            if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))
-                return SIMPLE_ERR_BAD_RESP;
-        } else
-            return SIMPLE_ERR_BAD_RESP;
-    }
-    return 0;
-}
-
-/* REQUEST SENSE command. Returns 0 if ok, anything else major problem.
- * SPC section 7.24 */
-int scsiRequestSense(int device, struct scsi_sense_disect * sense_info)
-{
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    UINT8 buff[18];
-    int status, len;
-    UINT8 ecode;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = sizeof(buff);
-    io_hdr.dxferp = buff;
-    cdb[0] = REQUEST_SENSE;
-    cdb[4] = sizeof(buff);
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if ((0 == status) && (sense_info)) {
-        ecode = buff[0] & 0x7f;
-        sense_info->error_code = ecode;
-        sense_info->sense_key = buff[2] & 0xf;
-        sense_info->asc = 0;
-        sense_info->ascq = 0;
-        if ((0x70 == ecode) || (0x71 == ecode)) {
-            len = buff[7] + 8;
-            if (len > 13) {
-                sense_info->asc = buff[12];
-                sense_info->ascq = buff[13];
-            }
-        }
-    }
-    return status;
-}
-
-/* SEND DIAGNOSTIC command.  Returns 0 if ok, 1 if NOT READY, 2 if command
- * not supported, 3 if field in command not supported or returns negated
- * errno. SPC section 7.25 */
-int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = bufLen ? DXFER_TO_DEVICE: DXFER_NONE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = SEND_DIAGNOSTIC;
-    if (SCSI_DIAG_DEF_SELF_TEST == functioncode)
-        cdb[1] = 0x4;  /* SelfTest bit */
-    else if (SCSI_DIAG_NO_SELF_TEST != functioncode)
-        cdb[1] = (functioncode & 0x7) << 5; /* SelfTest _code_ */
-    else   /* SCSI_DIAG_NO_SELF_TEST == functioncode */
-        cdb[1] = 0x10;  /* PF bit */
-    cdb[3] = (bufLen >> 8) & 0xff;
-    cdb[4] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-    io_hdr.timeout = 5 * 60 * 60;   /* five hours because a foreground 
-                    extended self tests can take 1 hour plus */
-    
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* RECEIVE DIAGNOSTIC command. Returns 0 if ok, 1 if NOT READY, 2 if
- * command not supported, 3 if field in command not supported or returns
- * negated errno. SPC section 7.17 */
-int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf, 
-                      int bufLen)
-{
-    struct scsi_cmnd_io io_hdr;
-    struct scsi_sense_disect sinfo;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
-    io_hdr.dxfer_len = bufLen;
-    io_hdr.dxferp = pBuf;
-    cdb[0] = RECEIVE_DIAGNOSTIC;
-    cdb[1] = pcv;
-    cdb[2] = pagenum;
-    cdb[3] = (bufLen >> 8) & 0xff;
-    cdb[4] = bufLen & 0xff;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, &sinfo);
-    return scsiSimpleSenseFilter(&sinfo);
-}
-
-/* TEST UNIT READY command. SPC section 7.28 (probably in SBC as well) */
-static int _testunitready(int device, struct scsi_sense_disect * sinfo)
-{
-    struct scsi_cmnd_io io_hdr;
-    UINT8 cdb[6];
-    UINT8 sense[32];
-    int status;
-
-    memset(&io_hdr, 0, sizeof(io_hdr));
-    memset(cdb, 0, sizeof(cdb));
-    io_hdr.dxfer_dir = DXFER_NONE;
-    io_hdr.dxfer_len = 0;
-    io_hdr.dxferp = NULL;
-    cdb[0] = TEST_UNIT_READY;
-    io_hdr.cmnd = cdb;
-    io_hdr.cmnd_len = sizeof(cdb);
-    io_hdr.sensep = sense;
-    io_hdr.max_sense_len = sizeof(sense);
-
-    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
-    if (0 != status)
-        return status;
-    scsi_do_sense_disect(&io_hdr, sinfo);
-    return 0;
-}
-
-/* Returns 0 for device responds and media ready, 1 for device responds and
-   media not ready, or returns a negated errno value */
-int scsiTestUnitReady(int device)
-{
-    struct scsi_sense_disect sinfo;
-    int status;
-
-    status = _testunitready(device, &sinfo);
-    if (0 != status)
-        return status;
-    if (SCSI_SK_NOT_READY == sinfo.sense_key)
-        return SIMPLE_ERR_NOT_READY;
-    else if (SCSI_SK_UNIT_ATTENTION == sinfo.sense_key) {
-        /* power on reset, media changed, ok ... try again */
-        status = _testunitready(device, &sinfo);        
-        if (0 != status)
-            return status;
-        if (SCSI_SK_NOT_READY == sinfo.sense_key)
-            return SIMPLE_ERR_BAD_FIELD;
-    }
-    return 0;
-}
-
-/* Offset into mode sense (6 or 10 byte) response that actual mode page
- * starts at (relative to resp[0]). Returns -1 if problem */
-int scsiModePageOffset(const UINT8 * resp, int len, int modese_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: response length too short, resp_len=%d"
-                 " offset=%d bd_len=%d\n", resp_len, offset, bd_len);
-            offset = -1;
-        }
-    }
-    return offset;
-}
-
-/* IEC mode page byte 2 bit masks */
-#define DEXCPT_ENABLE   0x08
-#define EWASC_ENABLE    0x10
-#define DEXCPT_DISABLE  0xf7
-#define EWASC_DISABLE   0xef
-#define TEST_DISABLE    0xfb
-
-/* Fetches the Informational Exceptions Control mode page. First tries
- * the 6 byte MODE SENSE command and if that fails with an illegal opcode
- * tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive
- * number if a known error (see  SIMPLE_ERR_ ...) or a negative errno
- * value. */
-int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp)
-{
-    int 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 (SIMPLE_ERR_BAD_OPCODE == err) { /* 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), 0))) {
-        *currenttemp = 0;
-        *triptemp = 0;
-        pout("Log Sense for temperature failed [%s]\n", scsiErrString(err));
-        return err;
-    }
-    *currenttemp = tBuf[9];
-    *triptemp = tBuf[15];
-    return 0;
-}
-
-/* Read informational exception log page or Request Sense response.
- * Fetching asc/ascq code potentially flagging an exception or warning.
- * Returns 0 if ok, else error number. A current temperature of 255
- * (Celsius) implies that the temperature not available. */
-int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
-                UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp)
-{
-    UINT8 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(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk
-    memset(&sense_info, 0, sizeof(sense_info));
-    if (hasIELogPage) {
-        if ((err = scsiLogSense(device, IE_LOG_PAGE, tBuf, 
-                                sizeof(tBuf), 0))) {
-            pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
-            return err;
-        }
-	// pull out page size from response, don't forget to add 4
-        pagesize = (unsigned short) ((tBuf[2] << 8) | tBuf[3]) + 4; 
-        if ((pagesize < 4) || tBuf[4] || tBuf[5]) {
-            pout("Log Sense failed, IE page, bad parameter code or length\n");
-            return SIMPLE_ERR_BAD_PARAM;
-        }
-        if (tBuf[7] > 1) {
-            sense_info.asc = tBuf[8]; 
-            sense_info.ascq = tBuf[9];
-            if (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 err;
-        }
-    }
-    *asc = sense_info.asc;
-    *ascq = sense_info.ascq;
-    if ((! temperatureSet) && hasTempLogPage) {
-        if (0 == scsiGetTemp(device, &currTemp, &tripTemp))
-            *currenttemp = currTemp;
-    }
-    return 0;
-}
-
-// The first character (W, C, I) tells the severity
-static const char * TapeAlertsMessageTable[]= {  
-    " ",
-    /* 0x01 */
-   "W: The tape drive is having problems reading data. No data has been lost,\n"
-       "  but there has been a reduction in the performance of the tape.",
-    /* 0x02 */
-   "W: The tape drive is having problems writing data. No data has been lost,\n"
-       "  but there has been a reduction in the capacity of the tape.",
-    /* 0x03 */
-   "W: The operation has stopped because an error has occurred while reading\n"
-       "  or writing data that the drive cannot correct.",
-    /* 0x04 */
-   "C: Your data is at risk:\n"
-       "  1. Copy any data you require from this tape. \n"
-       "  2. Do not use this tape again.\n"
-       "  3. Restart the operation with a different tape.",
-    /* 0x05 */
-   "C: The tape is damaged or the drive is faulty. Call the tape drive\n"
-       "  supplier helpline.",
-    /* 0x06 */
-   "C: The tape is from a faulty batch or the tape drive is faulty:\n"
-       "  1. Use a good tape to test the drive.\n"
-       "  2. If problem persists, call the tape drive supplier helpline.",
-    /* 0x07 */
-   "W: The tape cartridge has reached the end of its calculated useful life:\n"
-       "  1. Copy data you need to another tape.\n"
-       "  2. Discard the old tape.",
-    /* 0x08 */
-   "W: The tape cartridge is not data-grade. Any data you back up to the tape\n"
-       "  is at risk. Replace the cartridge with a data-grade tape.",
-    /* 0x09 */
-   "C: You are trying to write to a write-protected cartridge. Remove the\n"
-       "  write-protection or use another tape.",
-    /* 0x0a */
-   "I: You cannot eject the cartridge because the tape drive is in use. Wait\n"
-       "  until the operation is complete before ejecting the cartridge.",
-    /* 0x0b */
-   "I: The tape in the drive is a cleaning cartridge.",
-    /* 0x0c */
-   "I: You have tried to load a cartridge of a type which is not supported\n"
-       "  by this drive.",
-    /* 0x0d */
-   "C: The operation has failed because the tape in the drive has experienced\n"
-       "  a mechanical failure:\n"
-       "  1. Discard the old tape.\n"
-       "  2. Restart the operation with a different tape.",
-    /* 0x0e */
-   "C: The operation has failed because the tape in the drive has experienced\n"
-       "  a mechanical failure:\n"
-       "  1. Do not attempt to extract the tape cartridge\n"
-       "  2. Call the tape drive supplier helpline.",
-    /* 0x0f */
-   "W: The memory in the tape cartridge has failed, which reduces\n"
-       "  performance. Do not use the cartridge for further write operations.",
-    /* 0x10 */
-   "C: The operation has failed because the tape cartridge was manually\n"
-       "  de-mounted while the tape drive was actively writing or reading.",
-    /* 0x11 */
-   "W: You have loaded a cartridge of a type that is read-only in this drive.\n"
-       "  The cartridge will appear as write-protected.",
-    /* 0x12 */
-   "W: The tape directory on the tape cartridge has been corrupted. File\n"
-       "  search performance will be degraded. The tape directory can be rebuilt\n"
-       "  by reading all the data on the cartridge.",
-    /* 0x13 */
-   "I: The tape cartridge is nearing the end of its calculated life. It is\n"
-       "  recommended that you:\n"
-       "  1. Use another tape cartridge for your next backup.\n"
-       "  2. Store this tape in a safe place in case you need to restore "
-       "  data from it.",
-    /* 0x14 */
-   "C: The tape drive needs cleaning:\n"
-       "  1. If the operation has stopped, eject the tape and clean the drive.\n"
-       "  2. If the operation has not stopped, wait for it to finish and then\n"
-       "  clean the drive.\n"
-       "  Check the tape drive users manual for device specific cleaning instructions.",
-    /* 0x15 */
-   "W: The tape drive is due for routine cleaning:\n"
-       "  1. Wait for the current operation to finish.\n"
-       "  2. The use a cleaning cartridge.\n"
-       "  Check the tape drive users manual for device specific cleaning instructions.",
-    /* 0x16 */
-   "C: The last cleaning cartridge used in the tape drive has worn out:\n"
-       "  1. Discard the worn out cleaning cartridge.\n"
-       "  2. Wait for the current operation to finish.\n"
-       "  3. Then use a new cleaning cartridge.",
-    /* 0x17 */
-   "C: The last cleaning cartridge used in the tape drive was an invalid\n"
-       "  type:\n"
-       "  1. Do not use this cleaning cartridge in this drive.\n"
-       "  2. Wait for the current operation to finish.\n"
-       "  3. Then use a new cleaning cartridge.",
-    /* 0x18 */
-   "W: The tape drive has requested a retention operation",
-    /* 0x19 */
-   "W: A redundant interface port on the tape drive has failed",
-    /* 0x1a */
-   "W: A tape drive cooling fan has failed",
-    /* 0x1b */
-   "W: A redundant power supply has failed inside the tape drive enclosure.\n"
-       "  Check the enclosure users manual for instructions on replacing the\n"
-       "  failed power supply.",
-    /* 0x1c */
-   "W: The tape drive power consumption is outside the specified range.",
-    /* 0x1d */
-   "W: Preventive maintenance of the tape drive is required. Check the tape\n"
-       "  drive users manual for device specific preventive maintenance\n"
-       "  tasks or call the tape drive supplier helpline.",
-    /* 0x1e */
-   "C: The tape drive has a hardware fault:\n"
-       "  1. Eject the tape or magazine.\n"
-       "  2. Reset the drive.\n"
-       "  3. Restart the operation.",
-    /* 0x1f */
-   "C: The tape drive has a hardware fault:\n"
-       "  1. Turn the tape drive off and then on again.\n"
-       "  2. Restart the operation.\n"
-    "  3. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x20 */
-   "W: The tape drive has a problem with the application client interface:\n"
-       "  1. Check the cables and cable connections.\n"
-       "  2. Restart the operation.",
-    /* 0x21 */
-   "C: The operation has failed:\n"
-       "  1. Eject the tape or magazine.\n"
-       "  2. Insert the tape or magazine again.\n"
-       "  3. Restart the operation.",
-    /* 0x22 */
-   "W: The firmware download has failed because you have tried to use the\n"
-       "  incorrect firmware for this tape drive. Obtain the correct\n"
-       "  firmware and try again.",
-    /* 0x23 */
-   "W: Environmental conditions inside the tape drive are outside the\n"
-       "  specified humidity range.",
-    /* 0x24 */
-   "W: Environmental conditions inside the tape drive are outside the\n"
-       "  specified temperature range.",
-    /* 0x25 */
-   "W: The voltage supply to the tape drive is outside the specified range.",
-    /* 0x26 */
-   "C: A hardware failure of the tape drive is predicted. Call the tape\n"
-       "  drive supplier helpline.",
-    /* 0x27 */
-   "W: The tape drive may have a hardware fault. Run extended diagnostics to\n"
-       "  verify and diagnose the problem. Check the tape drive users manual for\n"
-       "  device specific instructions on running extended diagnostic tests.",
-    /* 0x28 */
-   "C: The changer mechanism is having difficulty communicating with the tape\n"
-       "  drive:\n"
-       "  1. Turn the autoloader off then on.\n"
-       "  2. Restart the operation.\n"
-       "  3. If problem persists, call the tape drive supplier helpline.",
-    /* 0x29 */
-   "C: A tape has been left in the autoloader by a previous hardware fault:\n"
-       "  1. Insert an empty magazine to clear the fault.\n"
-       "  2. If the fault does not clear, turn the autoloader off and then\n"
-       "  on again.\n"
-       "  3. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x2a */
-   "W: There is a problem with the autoloader mechanism.",
-    /* 0x2b */
-   "C: The operation has failed because the autoloader door is open:\n"
-       "  1. Clear any obstructions from the autoloader door.\n"
-       "  2. Eject the magazine and then insert it again.\n"
-       "  3. If the fault does not clear, turn the autoloader off and then\n"
-       "  on again.\n"
-       "  4. If the problem persists, call the tape drive supplier helpline.",
-    /* 0x2c */
-   "C: The autoloader has a hardware fault:\n"
-       "  1. Turn the autoloader off and then on again.\n"
-       "  2. Restart the operation.\n"
-       "  3. If the problem persists, call the tape drive supplier helpline.\n"
-       "  Check the autoloader users manual for device specific instructions\n"
-       "  on turning the device power on and off.",
-    /* 0x2d */
-   "C: The autoloader cannot operate without the magazine,\n"
-       "  1. Insert the magazine into the autoloader.\n"
-       "  2. Restart the operation.",
-    /* 0x2e */
-   "W: A hardware failure of the changer mechanism is predicted. Call the\n"
-       "  tape drive supplier helpline.",
-    /* 0x2f */
-   "I: Reserved.",
-    /* 0x30 */
-   "I: Reserved.",
-    /* 0x31 */
-   "I: Reserved.",
-    /* 0x32 */
-   "W: Media statistics have been lost at some time in the past",
-    /* 0x33 */
-   "W: The tape directory on the tape cartridge just unloaded has been\n"
-       "  corrupted. File search performance will be degraded. The tape\n"
-       "  directory can be rebuilt by reading all the data.",
-    /* 0x34 */
-   "C: The tape just unloaded could not write its system area successfully:\n"
-       "  1. Copy data to another tape cartridge.\n"
-       "  2. Discard the old cartridge.",
-    /* 0x35 */
-   "C: The tape system are could not be read successfully at load time:\n"
-    "  1. Copy data to another tape cartridge.\n",
-    /* 0x36 */
-   "C: The start or data could not be found on the tape:\n"
-       "  1. Check you are using the correct format tape.\n"
-       "  2. Discard the tape or return the tape to your supplier",
-    /* 0x37 */
-    "C: The operation has failed because the media cannot be loaded\n"
-        "  and threaded.\n"
-        "  1. Remove the cartridge, inspect it as specified in the product\n"
-        "  manual, and retry the operation.\n"
-        "  2. If the problem persists, call the tape drive supplier help line.",
-    /* 0x38 */
-    "C: The operation has failed because the medium cannot be unloaded:\n"
-        "  1. Do not attempt to extract the tape cartridge.\n"
-        "  2. Call the tape driver supplier help line.",
-    /* 0x39 */
-    "C: The tape drive has a problem with the automation interface:\n"
-        "  1. Check the power to the automation system.\n"
-        "  2. Check the cables and cable connections.\n"
-        "  3. Call the supplier help line if problem persists.",
-    /* 0x3a */
-    "W: The tape drive has reset itself due to a detected firmware\n"
-        "  fault. If problem persists, call the supplier help line.",
-    };
-
-const char * scsiTapeAlertsTapeDevice(unsigned short code)
-{
-    const int num = sizeof(TapeAlertsMessageTable) /
-                        sizeof(TapeAlertsMessageTable[0]);
-
-    return (code < num) ?  TapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-// The first character (W, C, I) tells the severity
-static const char * ChangerTapeAlertsMessageTable[]= {  
-    " ",
-    /* 0x01 */
-    "C: The library mechanism is having difficulty communicating with the\n"
-        "  drive:\n"
-        "  1. Turn the library off then on.\n"
-        "  2. Restart the operation.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x02 */
-    "W: There is a problem with the library mechanism. If problem persists,\n"
-        "  call the library supplier help line.",
-    /* 0x03 */
-    "C: The library has a hardware fault:\n"
-        "  1. Reset the library.\n"
-        "  2. Restart the operation.\n"
-        "  Check the library users manual for device specific instructions on resetting\n"
-        "  the device.",
-    /* 0x04 */
-    "C: The library has a hardware fault:\n"
-        "  1. Turn the library off then on again.\n"
-        "  2. Restart the operation.\n"
-        "  3. If the problem persists, call the library supplier help line.\n"
-        "  Check the library users manual for device specific instructions on turning the\n"
-        "  device power on and off.",
-    /* 0x05 */
-    "W: The library mechanism may have a hardware fault.\n"
-        "  Run extended diagnostics to verify and diagnose the problem. Check the library\n"
-        "  users manual for device specific instructions on running extended diagnostic\n"
-        "  tests.",
-    /* 0x06 */
-    "C: The library has a problem with the host interface:\n"
-        "  1. Check the cables and connections.\n"
-        "  2. Restart the operation.",
-    /* 0x07 */
-    "W: A hardware failure of the library is predicted. Call the library\n"
-        "  supplier help line.",
-    /* 0x08 */
-    "W: Preventive maintenance of the library is required.\n"
-        "  Check the library users manual for device specific preventative maintenance\n"
-        "  tasks, or call your library supplier help line.",
-    /* 0x09 */
-    "C: General environmental conditions inside the library are outside the\n"
-        "  specified humidity range.",
-    /* 0x0a */
-    "C: General environmental conditions inside the library are outside the\n"
-        "  specified temperature range.",
-    /* 0x0b */
-    "C: The voltage supply to the library is outside the specified range.\n"
-        "  There is a potential problem with the power supply or failure of\n"
-        "  a redundant power supply.",
-    /* 0x0c */
-    "C: A cartridge has been left inside the library by a previous hardware\n"
-        "  fault:\n"
-        "  1. Insert an empty magazine to clear the fault.\n"
-        "  2. If the fault does not clear, turn the library off and then on again.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x0d */
-    "W: There is a potential problem with the drive ejecting cartridges or\n"
-        "  with the library mechanism picking a cartridge from a slot.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x0e */
-    "W: There is a potential problem with the library mechanism placing a\n"
-        "  cartridge into a slot.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x0f */
-    "W: There is a potential problem with the drive or the library mechanism\n"
-        "  loading cartridges, or an incompatible cartridge.",
-    /* 0x10 */
-    "C: The library has failed because the door is open:\n"
-        "  1. Clear any obstructions from the library door.\n"
-        "  2. Close the library door.\n"
-        "  3. If the problem persists, call the library supplier help line.",
-    /* 0x11 */
-    "C: There is a mechanical problem with the library media import/export\n"
-        "  mailslot.",
-    /* 0x12 */
-    "C: The library cannot operate without the magazine.\n"
-        "  1. Insert the magazine into the library.\n"
-        "  2. Restart the operation.",
-    /* 0x13 */
-    "W: Library security has been compromised.",
-    /* 0x14 */
-    "I: The library security mode has been changed.\n"
-        "  The library has either been put into secure mode, or the library has exited\n"
-        "  the secure mode.\n"
-        "  This is for information purposes only. No action is required.",
-    /* 0x15 */
-    "I: The library has been manually turned offline and is unavailable for use.",
-    /* 0x16 */
-    "I: A drive inside the library has been taken offline.\n"
-        "  This is for information purposes only. No action is required.",
-    /* 0x17 */
-    "W: There is a potential problem with the bar code label or the scanner\n"
-        "  hardware in the library mechanism.\n"
-        "  1. No action needs to be taken at this time.\n"
-        "  2. If the problem persists, call the library supplier help line.",
-    /* 0x18 */
-    "C: The library has detected an inconsistency in its inventory.\n"
-        "  1. Redo the library inventory to correct inconsistency.\n"
-        "  2. Restart the operation.\n"
-        "  Check the applications users manual or the hardware users manual for\n"
-        "  specific instructions on redoing the library inventory.",
-    /* 0x19 */
-    "W: A library operation has been attempted that is invalid at this time.",
-    /* 0x1a */
-    "W: A redundant interface port on the library has failed.",
-    /* 0x1b */
-    "W: A library cooling fan has failed.",
-    /* 0x1c */
-    "W: A redundant power supply has failed inside the library. Check the\n"
-        "  library users manual for instructions on replacing the failed power supply.",
-    /* 0x1d */
-    "W: The library power consumption is outside the specified range.",
-    /* 0x1e */
-    "C: A failure has occurred in the cartridge pass-through mechanism between\n"
-        "  two library modules.",
-    /* 0x1f */
-    "C: A cartridge has been left in the pass-through mechanism from a\n"
-        "  previous hardware fault. Check the library users guide for instructions on\n"
-        "  clearing this fault.",
-    /* 0x20 */
-    "I: The library was unable to read the bar code on a cartridge.",
-};
-
-const char * scsiTapeAlertsChangerDevice(unsigned short code)
-{
-    const int num = sizeof(ChangerTapeAlertsMessageTable) /
-                        sizeof(ChangerTapeAlertsMessageTable[0]);
-
-    return (code < num) ?  ChangerTapeAlertsMessageTable[code] : "Unknown Alert"; 
-}
-
-
-/* this is a subset of the SCSI additional sense code strings indexed
- * by "ascq" for the case when asc==SCSI_ASC_IMPENDING_FAILURE (0x5d)
- */
-static const char * strs_for_asc_5d[] = {
-   /* 0x00 */   "FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED",
-        "SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-        "",
-   /* 0x10 */   "HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "HARDWARE IMPENDING FAILURE CONTROLLER DETECTED",
-        "HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x20 */   "CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED",
-        "CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x30 */   "DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED",
-        "DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x40 */   "SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "SERVO IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "SERVO IMPENDING FAILURE CONTROLLER DETECTED",
-        "SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x50 */   "SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "SPINDLE IMPENDING FAILURE CONTROLLER DETECTED",
-        "SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-        "SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT",
-        "",
-        "",
-        "",
-   /* 0x60 */   "FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE",
-        "FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS",
-        "FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH",
-        "FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS",
-        "FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED",
-        "FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE",
-        "FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE",
-        "FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT",
-   /* 0x6c */   "FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT"};
-
-
-/* this is a subset of the SCSI additional sense code strings indexed
- *  * by "ascq" for the case when asc==SCSI_ASC_WARNING (0xb)
- *   */
-static const char * strs_for_asc_b[] = {
-       /* 0x00 */   "WARNING",
-               "WARNING - SPECIFIED TEMPERATURE EXCEEDED",
-               "WARNING - ENCLOSURE DEGRADED"};
-
-static char spare_buff[128];
-
-const char * scsiGetIEString(UINT8 asc, UINT8 ascq)
-{
-    const char * rp;
-
-    if (SCSI_ASC_IMPENDING_FAILURE == asc) {
-        if (ascq == 0xff)
-            return "FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)";
-        else if (ascq < 
-                 (sizeof(strs_for_asc_5d) / sizeof(strs_for_asc_5d[0]))) {
-            rp = strs_for_asc_5d[ascq];
-            if (strlen(rp) > 0)
-                return rp;
-        }
-        snprintf(spare_buff, sizeof(spare_buff),
-                 "FAILURE PREDICTION THRESHOLD EXCEEDED: ascq=0x%x", ascq);
-        return spare_buff;
-    } else if (SCSI_ASC_WARNING == asc) {
-        if (ascq < (sizeof(strs_for_asc_b) / sizeof(strs_for_asc_b[0]))) {
-            rp = strs_for_asc_b[ascq];
-            if (strlen(rp) > 0)
-                return rp;
-        }
-        snprintf(spare_buff, sizeof(spare_buff), "WARNING: ascq=0x%x", ascq);
-        return spare_buff;
-    }
-    return NULL;        /* not a IE additional sense code */
-}
-
-
-/* This is not documented in t10.org, page 0x80 is vendor specific */
-/* Some IBM disks do an offline read-scan when they get this command. */
-int scsiSmartIBMOfflineTest(int device)
-{       
-    UINT8 tBuf[256];
-        
-    memset(tBuf, 0, sizeof(tBuf));
-    /* Build SMART Off-line Immediate Diag Header */
-    tBuf[0] = 0x80; /* Page Code */
-    tBuf[1] = 0x00; /* Reserved */
-    tBuf[2] = 0x00; /* Page Length MSB */
-    tBuf[3] = 0x04; /* Page Length LSB */
-    tBuf[4] = 0x03; /* SMART Revision */
-    tBuf[5] = 0x00; /* Reserved */
-    tBuf[6] = 0x00; /* Off-line Immediate Time MSB */
-    tBuf[7] = 0x00; /* Off-line Immediate Time LSB */
-    return scsiSendDiagnostic(device, SCSI_DIAG_NO_SELF_TEST, tBuf, 8);
-}
-
-int scsiSmartDefaultSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_DEF_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartShortSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_BG_SHORT_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartExtendSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_BG_EXTENDED_SELF_TEST, 
-                              NULL, 0);
-}
-
-int scsiSmartShortCapSelfTest(int device)
-{       
-    return scsiSendDiagnostic(device, SCSI_DIAG_FG_SHORT_SELF_TEST, NULL, 0);
-}
-
-int scsiSmartExtendCapSelfTest(int device)
-{
-    return scsiSendDiagnostic(device, SCSI_DIAG_FG_EXTENDED_SELF_TEST, 
-                              NULL, 0);
-}
-
-int scsiSmartSelfTestAbort(int device)
-{
-    return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0);
-}
-
-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/scsiprint.cpp b/sm5/scsiprint.cpp
deleted file mode 100644
index 33cf68e2a3f46097569673aab63bd9561f9f9345..0000000000000000000000000000000000000000
--- a/sm5/scsiprint.cpp
+++ /dev/null
@@ -1,787 +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.53 2003/10/19 08:05:55 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;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-UINT8 gBuf[GBUF_SIZE];
-#define LOG_RESP_LEN 252
-#define LOG_RESP_TAPE_ALERT_LEN 0x144
-#define LOG_RESP_SELF_TEST_LEN 0x194
-
-/* Log pages supported */
-static int gSmartLPage = 0;     /* Informational Exceptions log page */
-static int gTempLPage = 0;
-static int gSelfTestLPage = 0;
-static int gStartStopLPage = 0;
-static int gTapeAlertsLPage = 0;
-
-/* Mode pages supported */
-static int gIecMPage = 1;     /* N.B. assume it until we know otherwise */
-
-
-static void scsiGetSupportedLogPages(int device)
-{
-    int i, err;
-
-    if ((err = scsiLogSense(device, SUPPORTED_LOG_PAGES, gBuf, 
-                            LOG_RESP_LEN, 0))) {
-        if (con->reportscsiioctl > 0)
-            pout("Log Sense for supported pages failed [%s]\n", 
-                 scsiErrString(err)); 
-        return;
-    } 
-
-    for (i = 4; i < gBuf[3] + LOGPAGEHDRSIZE; i++) {
-        switch (gBuf[i])
-        {
-            case TEMPERATURE_PAGE:
-                gTempLPage = 1;
-                break;
-            case STARTSTOP_CYCLE_COUNTER_PAGE:
-                gStartStopLPage = 1;
-                break;
-            case SELFTEST_RESULTS_PAGE:
-                gSelfTestLPage = 1;
-                break;
-            case IE_LOG_PAGE:
-                gSmartLPage = 1;
-                break;
-            case TAPE_ALERTS_PAGE:
-                gTapeAlertsLPage = 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, gSmartLPage, gTempLPage,
-                           &asc, &ascq, &currenttemp))) {
-        /* error message already announced */
-        QUIETOFF(con);
-        return;
-    }
-    QUIETOFF(con);
-    cp = scsiGetIEString(asc, ascq);
-    if (cp) {
-        QUIETON(con);
-        pout("SMART Health Status: %s [asc=%x,ascq=%x]\n", cp, asc, ascq); 
-        QUIETOFF(con);
-    } else if (gIecMPage)
-        pout("SMART Health Status: OK\n");
-
-    if (currenttemp && !gTempLPage) {
-        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 char *severities = "CWI";
-
-static int scsiGetTapeAlertsData(int device, int peripheral_type)
-{
-    unsigned short pagelength;
-    unsigned short parametercode;
-    int i, err;
-    char *s;
-    const char *ts;
-    int failures = 0;
-
-    QUIETON(con);
-    if ((err = scsiLogSense(device, TAPE_ALERTS_PAGE, gBuf, 
-                        LOG_RESP_TAPE_ALERT_LEN, LOG_RESP_TAPE_ALERT_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 (s=severities; *s; s++) {
-	for (i = 4; i < pagelength; i += 5) {
-	    parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1];
-
-	    if (gBuf[i + 4]) {
-		ts = SCSI_PT_MEDIUM_CHANGER == peripheral_type ?
-		    scsiTapeAlertsChangerDevice(parametercode) :
-		    scsiTapeAlertsTapeDevice(parametercode);
-		if (*ts == *s) {
-		    if (!failures)
-			pout("TapeAlert Errors (C=Critical, W=Warning, I=Informational):\n");
-		    pout("[0x%02x] %s\n", parametercode, ts);
-		    failures += 1; 
-		}
-	    }
-	}
-    }
-    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, 0))) {
-        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 maximum 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, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[0]);
-        found[0] = 1;
-    }
-    if (0 == scsiLogSense(device, WRITE_ERROR_COUNTER_PAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[1]);
-        found[1] = 1;
-    }
-    if (0 == scsiLogSense(device, VERIFY_ERROR_COUNTER_PAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        scsiDecodeErrCounterPage(gBuf, &errCounterArr[2]);
-        ecp = &errCounterArr[2];
-        for (k = 0; k < 7; ++k) {
-            if (ecp->gotPC[k] && ecp->counter[k]) {
-                found[2] = 1;
-                break;
-            }
-        }
-    }
-    if (found[0] || found[1] || found[2]) {
-        pout("\nError counter log:\n");
-        pout("          Errors Corrected    Total      Total   "
-             "Correction     Gigabytes    Total\n");
-        pout("              delay:       [rereads/    errors   "
-             "algorithm      processed    uncorrected\n");
-        pout("            minor | major  rewrites]  corrected  "
-             "invocations   [10^9 bytes]  errors\n");
-        for (k = 0; k < 3; ++k) {
-            if (! found[k])
-                continue;
-            ecp = &errCounterArr[k];
-            pout("%s%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("\nDevice does not support Error Counter logging\n");
-    if (0 == scsiLogSense(device, NON_MEDIUM_ERROR_PAGE, gBuf, 
-                          LOG_RESP_LEN, 0)) {
-        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_SELF_TEST_LEN, 0))) {
-        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;
-}
-
-static const char * peripheral_dt_arr[] = {
-        "disk",
-        "tape",
-        "printer",
-        "processor",
-        "optical disk(4)",
-        "CD/DVD",
-        "scanner",
-        "optical disk(7)",
-        "medium changer",
-        "communications",
-        "graphics(10)",
-        "graphics(11)",
-        "storage array",
-        "enclosure",
-        "simplified disk",
-        "optical card reader"
-};
- 
-/* 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;
-    int peri_dt = 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;
-    peri_dt = gBuf[0] & 0x1f;
-    if (peripheral_type)
-        *peripheral_type = peri_dt;
-    if (! all)
-	return 0;
-
-    if (len >= 36) {
-        memset(manufacturer, 0, sizeof(manufacturer));
-        strncpy(manufacturer, (char *)&gBuf[8], 8);
-     
-        memset(product, 0, sizeof(product));
-        strncpy(product, (char *)&gBuf[16], 16);
-            
-        memset(revision, 0, sizeof(revision));
-        strncpy(revision, (char *)&gBuf[32], 4);
-        pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
-        if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
-            /* should use VPD page 0x83 and fall back to this page (0x80)
-             * if 0x83 not supported. NAA requires a lot of decoding code */
-            len = gBuf[3];
-            gBuf[4 + len] = '\0';
-            pout("Serial number: %s\n", &gBuf[4]);
-        }
-        else if (con->reportscsiioctl > 0) {
-            QUIETON(con);
-            if (SIMPLE_ERR_BAD_RESP == err)
-                pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
-            else
-                pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
-            QUIETOFF(con);
-        }
-    } else {
-        QUIETON(con);
-        pout("Short INQUIRY response, skip product id\n");
-        QUIETOFF(con);
-    }
-    // print SCSI peripheral device type
-    if (peri_dt < (sizeof(peripheral_dt_arr) / sizeof(peripheral_dt_arr[0])))
-        pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
-    else
-        pout("Device type: <%d>\n", peri_dt);
-
-    // print current time and date and timezone
-    dateandtimezone(timedatetz);
-    pout("Local Time is: %s\n", timedatetz);
-
-    if ((SCSI_PT_SEQUENTIAL_ACCESS == *peripheral_type) ||
-        (SCSI_PT_MEDIUM_CHANGER == *peripheral_type))
-        is_tape = 1;
-    // See if unit accepts SCSI commmands from us
-    if ((err = scsiTestUnitReady(device))) {
-        if (SIMPLE_ERR_NOT_READY == err) {
-            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");
-            if (con->reportscsiioctl > 0)
-	        pout(" [%s]\n", scsiErrString(err));
-            else
-	        pout("\n");
-            if (SIMPLE_ERR_BAD_RESP == err) {
-                pout(">> Terminate command early due to bad response to IEC "
-                     "mode page\n");
-                QUIETOFF(con);
-                gIecMPage = 0;
-                return 1;
-            }
-            QUIETOFF(con);
-        }
-        gIecMPage = 0;
-        return 0;
-    }
-    if (!is_tape)
-        pout("Device supports SMART and is %s\n",
-             (scsi_IsExceptionControlEnabled(&iec)) ? "Enabled" : "Disabled");
-    pout("%s\n", (scsi_IsWarningEnabled(&iec)) ? 
-                  "Temperature Warning Enabled" :
-                  "Temperature Warning Disabled or Not Supported");
-    return 0;
-}
-
-static int scsiSmartEnable(int device)
-{
-    struct scsi_iec_mode_page iec;
-    int err;
-
-    if ((err = scsiFetchIECmpage(device, &iec))) {
-        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;
-    }
-    // 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);
-}
-
-/* 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, durationSec;
-
-    if (scsiGetDriveInfo(fd, &peripheral_type, con->driveinfo)) {
-        failuretest(MANDATORY_CMD, returnval |= FAILID);
-    }
-
-    if (con->smartenable) {
-        if (scsiSmartEnable(fd))
-            failuretest(MANDATORY_CMD, returnval |= FAILSMART);
-    }
-
-    if (con->smartdisable) {
-        if (scsiSmartDisable(fd))
-            failuretest(MANDATORY_CMD,returnval |= FAILSMART);
-    }
-
-    if (con->checksmart) {
-        scsiGetSupportedLogPages(fd);
-        checkedSupportedLogPages = 1;
-        if ((SCSI_PT_SEQUENTIAL_ACCESS == peripheral_type) ||
-            (SCSI_PT_MEDIUM_CHANGER == peripheral_type)) { /* tape device */
-            if (gTapeAlertsLPage) {
-		if (con->driveinfo)
-		    pout("TapeAlert Supported\n");
-                if (-1 == scsiGetTapeAlertsData(fd, peripheral_type))
-                    failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
-	    }
-	    else
-		pout("TapeAlert Not Supported\n");
-            if (gTempLPage)
-                scsiPrintTemp(fd);         
-            if (gStartStopLPage)
-                scsiGetStartStopData(fd);
-        } else { /* disk, cd/dvd, enclosure, etc */
-            scsiGetSmartData(fd);
-            if (gTempLPage)
-                scsiPrintTemp(fd);         
-            if (gStartStopLPage)
-                scsiGetStartStopData(fd);
-        }
-    }   
-    if (con->smarterrorlog)
-        scsiPrintErrorCounterLog(fd);
-    if (con->smartselftestlog) {
-        if (! checkedSupportedLogPages)
-            scsiGetSupportedLogPages(fd);
-        res = 0;
-        if (gSelfTestLPage)
-            res = scsiPrintSelfTest(fd);
-        else {
-            pout("Device does not support Self Test logging\n");
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-        }
-        if (0 != res)
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-    }
-    if (con->smartexeoffimmediate) {
-        if (scsiSmartDefaultSelfTest(fd)) {
-            pout( "Default Self Test Failed\n");
-            return returnval;
-        }
-        pout("Default Self Test Successful\n");
-    }
-    if (con->smartshortcapselftest) {
-        if (scsiSmartShortCapSelfTest(fd)) {
-            pout("Short Foreground Self Test Failed\n");
-            return returnval;
-        }
-        pout("Short Foreground Self Test Successful\n");
-    }
-    if (con->smartshortselftest ) { 
-        if ( scsiSmartShortSelfTest(fd)) {
-            pout("Short Background Self Test Failed\n");
-            return returnval;
-        }
-        pout("Short Background Self Test has begun\n");
-        pout("Use smartctl -X to abort test\n");
-    }
-    if (con->smartextendselftest) {
-        if (scsiSmartExtendSelfTest(fd)) {
-            pout("Extended Background Self Test Failed\n");
-            return returnval;
-        }
-        pout("Extended Background Self Test has begun\n");
-        if ((0 == scsiFetchExtendedSelfTestTime(fd, &durationSec)) &&
-            (durationSec > 0)) {
-            time_t t = time(NULL);
-
-            t += durationSec;
-            pout("Please wait %d minutes for test to complete.\n", 
-                 durationSec / 60);
-            pout("Estimated completion time: %s\n", ctime(&t));
-        }
-        pout("Use smartctl -X to abort test\n");        
-    }
-    if (con->smartextendcapselftest) {
-        if (scsiSmartExtendCapSelfTest(fd)) {
-            pout("Extended Foreground Self Test Failed\n");
-            return returnval;
-        }
-        pout("Extended Foreground Self Test Successful\n");
-    }
-    if (con->smartselftestabort) {
-        if (scsiSmartSelfTestAbort(fd)) {
-            pout("Self Test Abort Failed\n");
-            return returnval;
-        }
-        pout("Self Test returned without error\n");
-    }           
-    return returnval;
-}
diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp
deleted file mode 100644
index 8aa04a72d8294fd2d6fc2aefe019a29855c61c11..0000000000000000000000000000000000000000
--- a/sm5/smartctl.cpp
+++ /dev/null
@@ -1,847 +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 "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef HAVE_GETOPT_LONG
-#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 *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid; 
-const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.104 2003/10/27 11:23:32 ballen4705 Exp $"
-ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_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;
-
-// to hold onto exit code for atexit routine
-extern int exitstatus;
-
-// Track memory use
-extern long long bytes;
-
-void printslogan(){
-  pout("smartctl version %s Copyright (C) 2002-3 Bruce Allen\n", PACKAGE_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,atacmdnames_c_cvsid);
-  pout("%s",out);
-  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,os_XXXX_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);
-  pout("\nsmartctl build configured on " SMARTMONTOOLS_CONFIGURE_DATE "\n");
-  pout("smartctl configure arguments: " SMARTMONTOOLS_CONFIGURE_ARGS "\n");
-
-
-  return;
-}
-
-void UsageSummary(){
-  pout("\nUse smartctl -h to get a usage summary\n\n");
-  return;
-}
-
-/*  void prints help information for command syntax */
-void Usage (void){
-  printf("Usage: smartctl [options] device\n\n");
-  printf("============================================ SHOW INFORMATION OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -h, --help, --usage\n"
-"         Display this help and exit\n\n"
-"  -V, --version, --copyright, --license\n"
-"         Print license, copyright, and version information and exit\n\n"
-"  -i, --info                                                       \n"
-"         Show identity information for device\n\n"
-"  -a, --all                                                        \n"
-"         Show all SMART information for device\n\n"
-  );
-#else
-  printf(
-"  -h        Display this help and exit\n"
-"  -V        Print license, copyright, and version information\n"
-"  -i        Show identity information for device\n"
-"  -a        Show all SMART information for device\n\n"
-  );
-#endif
-  printf("================================== SMARTCTL RUN-TIME BEHAVIOR OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -q TYPE, --quietmode=TYPE                                           (ATA)\n"
-"         Set smartctl quiet mode to one of: errorsonly, silent\n\n"
-"  -d TYPE, --device=TYPE\n"
-"         Specify device type to one of: ata, scsi, 3ware,N\n\n"
-"  -T TYPE, --tolerance=TYPE                                           (ATA)\n"
-"         Tolerance: normal, conservative, permissive, verypermissive\n\n"
-"  -b TYPE, --badsum=TYPE                                              (ATA)\n"
-"         Set action on bad checksum to one of: warn, exit, ignore\n\n"
-"  -r TYPE, --report=TYPE\n"
-"         Report transactions (see man page)\n\n"
-  );
-#else
-  printf(
-"  -q TYPE   Set smartctl quiet mode to one of: errorsonly, silent     (ATA)\n"
-"  -d TYPE   Specify device type to one of: ata, scsi, 3ware,N\n"
-"  -T TYPE   Tolerance: normal, conservative,permissive,verypermissive (ATA\n"
-"  -b TYPE   Set action on bad checksum to one of: warn, exit, ignore  (ATA)\n"
-"  -r TYPE   Report transactions (see man page)\n\n"
-  );
-#endif
-  printf("============================== DEVICE FEATURE ENABLE/DISABLE COMMANDS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -s VALUE, --smart=VALUE\n"
-"        Enable/disable SMART on device (on/off)\n\n"
-"  -o VALUE, --offlineauto=VALUE                                       (ATA)\n"
-"        Enable/disable automatic offline testing on device (on/off)\n\n"
-"  -S VALUE, --saveauto=VALUE                                          (ATA)\n"
-"        Enable/disable Attribute autosave on device (on/off)\n\n"
-  );
-#else
-  printf(
-"  -s VALUE  Enable/disable SMART on device (on/off)\n"
-"  -o VALUE  Enable/disable device automatic offline testing (on/off)  (ATA)\n"
-"  -S VALUE  Enable/disable device Attribute autosave (on/off)         (ATA)\n\n"
-  );
-#endif
-  printf("======================================= READ AND DISPLAY DATA OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -H, --health\n"
-"        Show device SMART health status\n\n"
-"  -c, --capabilities                                                  (ATA)\n"
-"        Show device SMART capabilities\n\n"
-"  -A, --attributes                                                    (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, directory\n\n"
-"  -v N,OPTION , --vendorattribute=N,OPTION                            (ATA)\n"
-"        Set display OPTION for vendor Attribute N (see man page)\n\n"
-"  -F TYPE, --firmwarebug=TYPE                                         (ATA)\n"
-"        Use firmware bug workaround: none, samsung, samsung2\n\n"
-"  -P TYPE, --presets=TYPE                                             (ATA)\n"
-"        Drive-specific presets: use, ignore, show, showall\n\n"
-  );
-#else
-  printf(
-"  -H        Show device SMART health status\n"
-"  -c        Show device SMART capabilities                             (ATA)\n"
-"  -A        Show device SMART vendor-specific Attributes and values    (ATA)\n"
-"  -l TYPE   Show device log. Type is one of: error, selftest, directory\n"
-"  -v N,OPT  Set display OPTion for vendor Attribute N (see man page)   (ATA)\n"
-"  -F TYPE   Use firmware bug workaround: none, samsung, samsung2       (ATA)\n"
-"  -P TYPE   Drive-specific presets: use, ignore, show, showall         (ATA)\n\n"
-  );
-#endif
-  printf("============================================ DEVICE SELF-TEST OPTIONS =====\n\n");
-#ifdef HAVE_GETOPT_LONG
-  printf(
-"  -t TEST, --test=TEST\n"
-#if DEVELOP_SELECTIVE_SELF_TEST
-"        Run test.  TEST is: offline, short, long, conveyance, selective,M-N\n\n"
-#else
-"        Run test.  TEST is: offline, short, long, conveyance\n\n"
-#endif
-
-"  -C, --captive\n"
-#if DEVELOP_SELECTIVE_SELF_TEST
-"        With -t, do test in captive mode (short/long/conveyance/selective)\n\n"
-#else
-"        With -t, do test in captive mode (short/long/conveyance)\n\n"
-#endif
-
-"  -X, --abort\n"
-"        Abort any non-captive test on device\n\n"
-);
-#else
-  printf(
-#if DEVELOP_SELECTIVE_SELF_TEST
-"  -t TEST   Run test.  TEST is: offline, short, long, conveyance, selective,M-N\n"
-"  -C        With -t, do test in captive mode (short/long/conveyance/selective)\n"
-#else
-"  -t TEST   Run test.  TEST is: offline, short, long, conveyance\n"
-"  -C        With -t, do test in captive mode (short/long/conveyance)\n"
-#endif
-"  -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"
-"  smartctl -a -device=3ware,2 /dev/sda\n"
-"          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-  );
-#else
-  printf(
-"  smartctl -a /dev/hda                       (Prints all SMART information)\n"
-"  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
-"  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
-"  smartctl -A -l selftest -q errorsonly /dev/hda\n"
-"                                      (Prints Self-Test & Attribute errors)\n"
-"  smartctl -a -d 3ware,2 /dev/sda\n"
-"          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
-  );
-#endif
-}
-
-/* Returns a pointer to a static string containing a formatted list of the valid
-   arguments to the option opt or NULL on failure. Note 'v' case different */
-const char *getvalidarglist(char opt) {
-  switch (opt) {
-  case 'q':
-    return "errorsonly, silent";
-  case 'd':
-    return "ata, scsi, 3ware,N";
-  case 'T':
-    return "normal, conservative, permissive, verypermissive";
-  case 'b':
-    return "warn, exit, ignore";
-  case 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 's':
-  case 'o':
-  case 'S':
-    return "on, off";
-  case 'l':
-    return "error, selftest, directory";
-  case 'P':
-    return "use, ignore, show, showall";
-  case 't':
-#if DEVELOP_SELECTIVE_SELF_TEST
-    return "offline, short, long, conveyance, selective,M-N";
-#else
-    return "offline, short, long, conveyance";
-#endif
-  case 'F':
-    return "none, samsung, samsung2";
-  case 'v':
-  default:
-    return NULL;
-  }
-}
-
-/* Prints the message "=======> VALID ARGUMENTS ARE: <LIST>  <=======\n", where
-   <LIST> is the list of valid arguments for option opt. */
-void printvalidarglistmessage(char opt) {
-  char *s;
-  
-  if (opt=='v')
-    s=create_vendor_attribute_arg_list();
-  else
-    s=(char *)getvalidarglist(opt);
-  
-  if (!s) {
-    pout("Error whilst constructing argument list for option %c", opt);
-    return;
-  }
- 
-  if (opt=='v'){
-    pout("=======> VALID ARGUMENTS ARE:\n\thelp\n%s\n<=======\n", s);
-    free(s);
-  }
-  else {
-  // getvalidarglist() might produce a multiline or single line string.  We
-  // need to figure out which to get the formatting right.
-    char separator = strchr(s, '\n') ? '\n' : ' ';
-    pout("=======> VALID ARGUMENTS ARE:%c%s%c<=======\n", separator, (char *)s, separator);
-  }
-
-  return;
-}
-
-
-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;
-  unsigned char *charp;
-  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;
-	con->escalade = 0;
-      } else if (!strcmp(optarg,"scsi")) {
-	tryata  = FALSE;
-	tryscsi = TRUE;
-	con->escalade = 0;
-      } else {
-	// look for RAID-type device
-	int i;
-        char *s;
-	
-	// make a copy of the string to mess with
-	if (!(s = strdup(optarg))) {
-          con->veryquietmode = FALSE;
-          pout("No memory for argument of -d. Exiting...\n");
-          exit(FAILCMD);
-        } else if (strncmp(s,"3ware,",6)) {
-	  badarg = TRUE;
-	} else if (split_report_arg2(s, &i)) {
-	  pout("Option -d 3ware,N requires N to be a non-negative integer\n");
-	  badarg = TRUE;
-        } else if (i<0 || i>15) {
-	  pout("Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i);
-	  badarg = TRUE;
-	} else {
-	  // NOTE: escalade = disk number + 1
-          con->escalade = i+1;
-	  tryata  = TRUE;
-	  tryscsi = FALSE;
-	}
-        free(s);
-      } 	
-      break;
-    case 'T':
-      if (!strcmp(optarg,"normal")) {
-        con->conservative = FALSE;
-        con->permissive   = 0;
-      } else if (!strcmp(optarg,"conservative")) {
-        con->conservative = TRUE;
-      } else if (!strcmp(optarg,"permissive")) {
-        if (con->permissive<0xff)
-	  con->permissive++;
-      } else if (!strcmp(optarg,"verypermissive")) {
-        con->permissive=0xff;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'b':
-      if (!strcmp(optarg,"warn")) {
-        con->checksumfail   = FALSE;
-        con->checksumignore = FALSE;
-      } else if (!strcmp(optarg,"exit")) {
-        con->checksumfail   = TRUE;
-        con->checksumignore = FALSE;
-      } else if (!strcmp(optarg,"ignore")) {
-        con->checksumignore = TRUE;
-        con->checksumfail   = FALSE;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'r':
-      {
-        int i;
-        char *s;
-
-        // split_report_arg() may modify its first argument string, so use a
-        // copy of optarg in case we want optarg for an error message.
-        if (!(s = strdup(optarg))) {
-          con->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 if (!strcmp(optarg,"samsung2")) {
-        con->fixfirmwarebug = FIX_SAMSUNG2;
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'c':
-      con->generalsmartvalues = TRUE;
-      break;
-    case 'A':
-      con->smartvendorattrib = TRUE;
-      break;
-    case 'l':
-      if (!strcmp(optarg,"error")) {
-        con->smarterrorlog = TRUE;
-      } else if (!strcmp(optarg,"selftest")) {
-        con->smartselftestlog = TRUE;
-      } else if (!strcmp(optarg,"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);
-      }
-      charp=con->attributedefs;
-      if (!charp){
-	pout("Fatal internal error in ParseOpts()\n");
-	EXIT(FAILCMD);
-      }
-      if (parse_attribute_def(optarg, &charp))
-	badarg = TRUE;
-      break;    
-    case 'P':
-      if (!strcmp(optarg, "use")) {
-        con->ignorepresets = FALSE;
-      } else if (!strcmp(optarg, "ignore")) {
-        con->ignorepresets = TRUE;
-      } else if (!strcmp(optarg, "show")) {
-        con->showpresets = TRUE;
-      } else if (!strcmp(optarg, "showall")) {
-        showallpresets();
-        EXIT(0);
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 't':
-      if (!strcmp(optarg,"offline")) {
-        con->smartexeoffimmediate = TRUE;
-        con->testcase             = OFFLINE_FULL_SCAN;
-      } else if (!strcmp(optarg,"short")) {
-        con->smartshortselftest = TRUE;
-        con->testcase           = SHORT_SELF_TEST;
-      } else if (!strcmp(optarg,"long")) {
-        con->smartextendselftest = TRUE;
-        con->testcase            = EXTEND_SELF_TEST;
-      } else if (!strcmp(optarg,"conveyance")) {
-        con->smartconveyanceselftest = TRUE;
-        con->testcase            = CONVEYANCE_SELF_TEST;
-#if DEVELOP_SELECTIVE_SELF_TEST
-      } else if (!strncmp(optarg,"selective",strlen("selective"))) {
-        unsigned long long start, stop;
-
-        if (split_selective_arg(optarg, &start, &stop)) {
-          badarg = TRUE;
-        } else {
-          if (con->smartselectivenumspans >= 5 || start > stop) {
-            con->veryquietmode=FALSE;
-            printslogan();
-            if (start > stop) {
-              pout("ERROR: Start LBA > ending LBA in argument \"%s\"\n",
-                optarg);
-            } else {
-              pout("ERROR: No more than five selective self-test spans may be"
-                " defined\n");
-            }
-	    UsageSummary();
-            EXIT(FAILCMD);
-          }
-          con->smartselectivespan[con->smartselectivenumspans][0] = start;
-          con->smartselectivespan[con->smartselectivenumspans][1] = stop;
-          con->smartselectivenumspans++;
-          con->testcase            = SELECTIVE_SELF_TEST;
-        }
-#endif
-      } else {
-        badarg = TRUE;
-      }
-      break;
-    case 'C':
-      captive = TRUE;
-      break;
-    case 'X':
-      con->smartselftestabort = TRUE;
-      con->testcase           = ABORT_SELF_TEST;
-      break;
-    case 'h':
-      con->veryquietmode=FALSE;
-      printslogan();
-      Usage();
-      EXIT(0);	
-      break;
-    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);
-	UsageSummary();
-	EXIT(FAILCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be
-        // missing.  Note (BA) this logic seems to fail using Solaris
-        // getopt!
-        if (strchr(shortopts, optopt) != NULL) {
-          pout("=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n", optopt);
-          printvalidarglistmessage(optopt);
-        } else
-	  pout("=======> UNRECOGNIZED OPTION: %c <=======\n",optopt);
-	UsageSummary();
-	EXIT(FAILCMD);
-      }
-      Usage();
-      EXIT(0);	
-    } // closes switch statement to process command-line options
-    
-    // Check to see if option had an unrecognized or incorrect argument.
-    if (badarg) {
-      printslogan();
-      // It would be nice to print the actual option name given by the user
-      // here, but we just print the short form.  Please fix this if you know
-      // a clean way to do it.
-      pout("=======> INVALID ARGUMENT TO -%c: %s <======= \n", optchar, optarg);
-      printvalidarglistmessage(optchar);
-      UsageSummary();
-      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");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-
-  // If captive option was used, change test type if appropriate.
-  if (captive && con->smartshortselftest) {
-    con->smartshortselftest    = FALSE;
-    con->smartshortcapselftest = TRUE;
-    con->testcase              = SHORT_CAPTIVE_SELF_TEST;
-  } else if (captive && con->smartextendselftest) {
-    con->smartextendselftest    = FALSE;
-    con->smartextendcapselftest = TRUE;
-    con->testcase               = EXTEND_CAPTIVE_SELF_TEST;
-  }
-  else if (captive && con->smartconveyanceselftest) {
-    con->smartconveyanceselftest    = FALSE;
-    con->smartconveyancecapselftest = TRUE;
-    con->testcase                   = CONVEYANCE_CAPTIVE_SELF_TEST;
-  }
-#if DEVELOP_SELECTIVE_SELF_TEST
-  else if (captive && con->smartselectiveselftest) {
-    con->smartselectiveselftest    = FALSE;
-    con->smartselectivecapselftest = TRUE;
-    con->testcase                  = SELECTIVE_CAPTIVE_SELF_TEST;
-  }
-#endif 
- 
-  // From here on, normal operations...
-  printslogan();
-  
-  // Warn if the user has provided no device name
-  if (argc-optind<1){
-    pout("ERROR: smartctl requires a device name as the final command-line argument.\n\n");
-    UsageSummary();
-    EXIT(FAILCMD);
-  }
-  
-  // Warn if the user has provided more than one device name
-  if (argc-optind>1){
-    int i;
-    pout("ERROR: smartctl takes ONE device name as the final command-line argument.\n");
-    pout("You have provided %d device names:\n",argc-optind);
-    for (i=0; i<argc-optind; i++)
-      pout("%s\n",argv[optind+i]);
-    UsageSummary();
-    EXIT(FAILCMD);
-  }  
-}
-
-// Printing function (controlled by global con->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;
-  char *mode=NULL;
-
-  // define control block for external functions
-  con=&control;
-
-  // Part input arguments
-  ParseOpts(argc,argv);
-
-  device = argv[argc-1];
-
-  if (!tryata && !tryscsi) {
-    // user has not specified device type, so guess
-    dev_type = guess_device_type(device);
-    if (GUESS_DEVTYPE_SCSI == dev_type) {
-      tryscsi = 1;
-    } else if (GUESS_DEVTYPE_ATA == dev_type)
-      tryata = 1;
-    else {
-      pout("Smartctl: please specify if this is an ATA or SCSI device with the -d option.\n");
-      UsageSummary();
-      return FAILCMD;
-    }    
-  }
-  
-  // set up mode for open() call.  SCSI case is:
-  mode="SCSI";
-
-  if (tryata)
-    mode="ATA";
-    
-  // 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 = deviceopen(device, mode);
-  if (fd<0) {
-    char errmsg[256];
-    snprintf(errmsg,256,"Smartctl open device: %s failed",argv[argc-1]);
-    errmsg[255]='\0';
-    syserror(errmsg);
-    return FAILDEV;
-  }
-
-  // now call appropriate ATA or SCSI routine
-  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");
-    UsageSummary();
-    return FAILCMD;
-  }
-  
-  return retval;
-}
diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp
deleted file mode 100644
index 67af7583ca301282650920e0d6c7b1dd019e3740..0000000000000000000000000000000000000000
--- a/sm5/smartd.cpp
+++ /dev/null
@@ -1,2762 +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/
- *
- */
-
-// unconditionally included files
-#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 <syslog.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#include <setjmp.h>
-
-// see which system files to conditionally include
-#include "config.h"
-
-// conditionally included files
-#ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
-#endif
-#ifdef HAVE_STRINGS_H
-// needed for index(3) in solaris
-#include <strings.h>
-#endif
-
-// locally included files
-#include "atacmds.h"
-#include "ataprint.h"
-#include "extern.h"
-#include "knowndrives.h"
-#include "scsicmds.h"
-#include "smartd.h"
-#include "utility.h"
-
-// These are CVS identification information for *.c and *.h files
-extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, 
-                  *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
-
-const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.226 2003/10/27 11:23:32 ballen4705 Exp $" 
-                            ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID
-                            SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID; 
-
-extern const char *reportbug;
-
-// GNU copyleft statement.  Needed for GPL purposes.
-const char *copyleftstring="smartd comes with ABSOLUTELY NO WARRANTY. This is\n"
-                           "free software, and you are welcome to redistribute it\n"
-                           "under the terms of the GNU General Public License\n"
-                           "Version 2. See http://www.gnu.org for further details.\n\n";
-
-extern unsigned char debugmode;
-
-// command-line: how long to sleep between checks
-static int checktime=CHECKTIME;
-
-// command-line: name of PID file (NULL for no pid file)
-static char* pid_file=NULL;
-
-// configuration file name
-static char* configfile=SYSCONFDIR "/" CONFIGFILENAME ;
-
-// command-line: when should we exit?
-static int quit=0;
-
-// used for control of printing, passing arguments to atacmds.c
-smartmonctrl *con=NULL;
-
-// pointers to (real or simulated) entries in configuration file
-cfgfile *cfgentries[MAXENTRIES];
-
-// pointers to ATA and SCSI devices being monitored 
-cfgfile *atadevlist[MAXATADEVICES],*scsidevlist[MAXSCSIDEVICES];
-
-// number of ATA and SCSI devices being monitored
-int numdevata=0,numdevscsi=0;
-
-// track memory usage
-extern long long bytes;
-
-// exit status
-extern int exitstatus;
-
-
-// set to one if we catch a USR1 (check devices now)
-volatile int caughtsigUSR1=0;
-
-// set to one if we catch a HUP (reload config file). In debug mode,
-// set to two, if we catch INT (also reload config file).
-volatile int caughtsigHUP=0;
-
-#if SCSITIMEOUT
-// stack environment if we time out during SCSI access (USB devices)
-jmp_buf registerscsienv;
-#endif
-
-// prints CVS identity information for the executable
-void PrintCVS(void){
-  char out[CVSMAXLEN];
-  
-  PrintOut(LOG_INFO,(char *)copyleftstring);
-  PrintOut(LOG_INFO,"CVS version IDs of files used to build this code are:\n");
-  printone(out,atacmdnames_c_cvsid);
-  PrintOut(LOG_INFO,"%s",out);
-  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,os_XXXX_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);
-  PrintOut(LOG_INFO,"\nsmartd build configured on " SMARTMONTOOLS_CONFIGURE_DATE "\n");
-  PrintOut(LOG_INFO,"smartd configure arguments: " SMARTMONTOOLS_CONFIGURE_ARGS "\n");
-  return;
-}
-
-// Removes config file entry, freeing all memory
-void RmConfigEntry(cfgfile **anentry, int whatline){
-  
-  cfgfile *cfg;
-
-  // pointer should never be null!
-  if (!anentry){
-    PrintOut(LOG_CRIT,"Internal error in RmConfigEntry() at line %d of file %s\n%s",
-	     whatline, __FILE__, reportbug);    
-    EXIT(EXIT_BADCODE);
-  }
-  
-  // only remove entries that exist!
-  if (!(cfg=*anentry))
-    return;
-
-  // entry exists -- free all of its memory
-  cfg->name            = FreeNonZero(cfg->name,           -1,__LINE__,__FILE__);
-  cfg->address         = FreeNonZero(cfg->address,        -1,__LINE__,__FILE__);
-  cfg->emailcmdline    = FreeNonZero(cfg->emailcmdline,   -1,__LINE__,__FILE__);
-  cfg->smartthres      = FreeNonZero(cfg->smartthres,      sizeof(struct ata_smart_thresholds),__LINE__,__FILE__);
-  cfg->smartval        = FreeNonZero(cfg->smartval,        sizeof(struct ata_smart_values),__LINE__,__FILE__);
-  cfg->monitorattflags = FreeNonZero(cfg->monitorattflags, NMONITOR*32,__LINE__,__FILE__);
-  cfg->attributedefs   = FreeNonZero(cfg->attributedefs,   MAX_ATTRIBUTE_NUM,__LINE__,__FILE__);
-  *anentry             = FreeNonZero(cfg,                  sizeof(cfgfile),__LINE__,__FILE__);
-
-  return;
-}
-
-// deallocates all memory associated with cfgentries list
-void RmAllConfigEntries(){
-  int i;
-
-  for (i=0; i<MAXENTRIES; i++)
-    RmConfigEntry(cfgentries+i, __LINE__);
-  return;
-}
-
-// deallocates all memory associated with ATA/SCSI device lists
-void RmAllDevEntries(){
-  int i;
-  
-  for (i=0; i<MAXATADEVICES; i++)
-    RmConfigEntry(atadevlist+i, __LINE__);
-  
-  for (i=0; i<MAXSCSIDEVICES; i++)
-    RmConfigEntry(scsidevlist+i, __LINE__);
-  
-  return;
-}
-
-// remove the PID file
-void RemovePidFile(){
-  if (pid_file) {
-    if ( -1==unlink(pid_file) )
-      PrintOut(LOG_CRIT,"Can't unlink PID file %s (%s).\n", 
-	       pid_file, strerror(errno));
-    pid_file=FreeNonZero(pid_file, -1,__LINE__,__FILE__);
-  }
-  return;
-}
-
-//  Note if we catch a SIGUSR1
-void USR1handler(int sig){
-  caughtsigUSR1=1;
-  return;
-}
-
-// Note if we catch a HUP (or INT in debug mode)
-void HUPhandler(int sig){
-  if (sig==SIGHUP)
-    caughtsigHUP=1;
-  else
-    caughtsigHUP=2;
-  return;
-}
-
-// signal handler for TERM, QUIT, and INT (if not in debug mode)
-void sighandler(int sig){
-
-  // are we exiting with SIGTERM?
-  int isterm=(sig==SIGTERM);
-  int isquit=(sig==SIGQUIT);
-  int isok=debugmode?isterm || isquit:isterm;
-
-  PrintOut(isok?LOG_INFO:LOG_CRIT, "smartd received signal %d: %s\n",
-	   sig, strsignal(sig));
-  
-  EXIT(isok?0:EXIT_SIGNAL);
-}
-
-// signal handler that prints Goodbye message and removes pidfile
-void Goodbye(){  
-  
-  // clean up memory -- useful for debugging
-  RmAllConfigEntries();
-  RmAllDevEntries();
-
-  // delete PID file, if one was created
-  RemovePidFile();
-
-  // useful for debugging -- have we managed memory correctly?
-  if (debugmode || bytes!=0)
-    PrintOut(LOG_INFO, "Memory still allocated for devices at exit is %lld bytes.\n", bytes);
-
-  // if we are exiting because of a code bug, print CVS info
-  if (exitstatus==EXIT_BADCODE || bytes)
-    PrintCVS();
-
-  // and this should be the final output from smartd before it exits
-  PrintOut(exitstatus?LOG_CRIT:LOG_INFO, "smartd is exiting (exit status %d)\n", exitstatus);
-
-  return;
-}
-
-#define ENVLENGTH 512
-
-// a replacement for setenv() which is not available on all platforms.
-// Note that the string passed to putenv must not be freed or made
-// invalid, since a pointer to it is kept by putenv(). This means that
-// it must either be a static buffer or allocated off the heap. The
-// string can be freed if the environment variable is redefined or
-// deleted via another call to putenv(). So we keep these on the stack
-// as long as the system() call is underway.
-int exportenv(char* stackspace, const char *name, const char *value){
-  snprintf(stackspace,ENVLENGTH, "%s=%s", name, value);
-  return putenv(stackspace);
-}
-
-// 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];
-  char environ_strings[10][ENVLENGTH];
-  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_CRIT,"internal error in PrintAndMail(): cfg->emailfreq=%d\n",cfg->emailfreq);
-    return;
-  }
-  if (which<0 || which>9) {
-    PrintOut(LOG_CRIT,"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;
-
-  // Return if this is an email test and one has already been sent.
-  if (which == 0 && mail->logged)
-    return;
-  
-  // To decide if to send mail, we need to know what time it is.
-  epoch=time(NULL);
-
-  // Return if less than one day has gone by
-  if (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';
-
-#ifdef HAVE_GETDOMAINNAME
-  if (getdomainname(domainname, 256))
-    sprintf(domainname,"Unknown");
-  else
-    domainname[255]='\0';
-#else
-  sprintf(domainname,"Unknown");
-#endif
-  
-  // print warning string into message
-  va_start(ap, fmt);
-  vsnprintf(message, 256, fmt, ap);
-  va_end(ap);
-
-  // appropriate message about further information
-  additional[0]=original[0]=further[0]='\0';
-  if (which) {
-    sprintf(further,"You can also use the smartctl utility for further investigation.\n");
-
-    switch (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
-  exportenv(environ_strings[0], "SMARTD_MAILER", executable);
-  exportenv(environ_strings[1], "SMARTD_MESSAGE", message);
-  exportenv(environ_strings[2], "SMARTD_SUBJECT", subject);
-  dateandtimezoneepoch(dates, mail->firstsent);
-  exportenv(environ_strings[3], "SMARTD_TFIRST", dates);
-  snprintf(dates, 64,"%d", (int)mail->firstsent);
-  exportenv(environ_strings[4], "SMARTD_TFIRSTEPOCH", dates);
-  exportenv(environ_strings[5], "SMARTD_FAILTYPE", whichfail[which]);
-  if (address)
-    exportenv(environ_strings[6], "SMARTD_ADDRESS", address);
-  exportenv(environ_strings[7], "SMARTD_DEVICESTRING", cfg->name);
-
-  if (cfg->escalade){
-    char *s,devicetype[16];
-    sprintf(devicetype, "3ware,%d", cfg->escalade-1);
-    exportenv(environ_strings[8], "SMARTD_DEVICETYPE", devicetype);
-    if ((s=strchr(cfg->name, ' ')))
-      *s='\0';
-    exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-    if (s)
-      *s=' ';
-  }
-  else {
-    exportenv(environ_strings[8], "SMARTD_DEVICETYPE", cfg->tryata?"ata":"scsi");
-    exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
-  }
-
-  // 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 || con->escalade) {
-    openlog("smartd", LOG_PID, LOG_DAEMON);
-    vsyslog(LOG_INFO, fmt, ap);
-    closelog();
-  }
-  va_end(ap);
-  fflush(NULL);
-  return;
-}
-
-// Forks new process, closes ALL file descriptors, redirects stdin,
-// stdout, and stderr.  Not quite daemon().  See
-// http://www.iar.unlp.edu.ar/~fede/revistas/lj/Magazines/LJ47/2335.html
-// for a good description of why we do things this way.
-void DaemonInit(){
-  pid_t pid;
-  int i;  
-
-  // flush all buffered streams.  Else we might get two copies of open
-  // streams since both parent and child get copies of the buffers.
-  fflush(NULL);
-  
-  if ((pid=fork()) < 0) {
-    // unable to fork!
-    PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  else if (pid)
-    // we are the parent process -- exit cleanly
-    EXIT(0);
-  
-  // from here on, we are the child process.
-  setsid();
-
-  // Fork one more time to avoid any possibility of having terminals
-  if ((pid=fork()) < 0) {
-    // unable to fork!
-    PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
-    EXIT(EXIT_STARTUP);
-  }
-  else if (pid)
-    // we are the parent process -- exit cleanly
-    EXIT(0);
-
-  // Now we are the child's child...
-
-  // close any open file descriptors
-  for (i=getdtablesize();i>=0;--i)
-    close(i);
-  
-  // redirect any IO attempts to /dev/null for stdin
-  i=open("/dev/null",O_RDWR);
-  // stdout
-  dup(i);
-  // stderr
-  dup(i);
-  umask(0);
-  chdir("/");
-  
-  PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid());
-
-  return;
-}
-
-// create a PID file containing the current process id
-void WritePidFile() {
-  if (pid_file) {
-    int error = 0;
-    pid_t pid = getpid();
-    mode_t old_umask;
-    FILE* fp; 
-    
-    old_umask = umask(0077);
-    fp = fopen(pid_file, "w");
-    umask(old_umask);
-    if (fp == NULL) {
-      error = 1;
-    } else if (fprintf(fp, "%d\n", (int)pid) <= 0) {
-      error = 1;
-    } else if (fclose(fp) != 0) {
-      error = 1;
-    }
-    if (error) {
-      PrintOut(LOG_CRIT, "unable to write PID file %s - exiting.\n", pid_file);
-      EXIT(EXIT_PID);
-    }
-    PrintOut(LOG_INFO, "file %s written containing PID %d\n", pid_file, (int)pid);
-  }
-  return;
-}
-
-// Prints header identifying version of code and home
-void PrintHead(){
-  PrintOut(LOG_INFO,"smartd version %s Copyright (C) 2002-3 Bruce Allen\n", PACKAGE_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 (%s) Directives (after device name):\n", configfile);
-  PrintOut(LOG_INFO,"  -d TYPE Set the device type: ata, scsi, removable, 3ware,N\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 Firmware bug workaround: none, samsung, samsung2\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;
-}
-
-/* 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 'q':
-    return "nodev, errors, nodevstartup, never, onecheck";
-  case 'r':
-    return "ioctl[,N], ataioctl[,N], scsiioctl[,N]";
-  case 'p':
-    return "<FILE_NAME>";
-  case 'i':
-    return "<INTEGER_SECONDS>";
-  default:
-    return NULL;
-  }
-}
-
-/* prints help information for command syntax */
-void Usage (void){
-  PrintOut(LOG_INFO,"Usage: smartd [options]\n\n");
-#ifdef HAVE_GETOPT_LONG
-  PrintOut(LOG_INFO,"  -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,"  -q WHEN, --quit=WHEN\n");
-  PrintOut(LOG_INFO,"        Quit on one of: %s\n\n", GetValidArgList('q'));
-  PrintOut(LOG_INFO,"  -r, --report=TYPE\n");
-  PrintOut(LOG_INFO,"        Report transactions for one of: %s\n\n", GetValidArgList('r'));
-  PrintOut(LOG_INFO,"  -V, --version, --license, --copyright\n");
-  PrintOut(LOG_INFO,"        Print License, Copyright, and version information\n");
-#else
-  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,"  -q WHEN Quit on one of: %s\n", GetValidArgList('q'));
-  PrintOut(LOG_INFO,"  -r TYPE Report transactions for one of: %s\n", GetValidArgList('r'));
-  PrintOut(LOG_INFO,"  -V      Print License, Copyright, and version information\n");
-#endif
-}
-
-// returns negative if problem, else fd>=0
-static int OpenDevice(char *device, char *mode) {
-  int fd;
-  char *s=device;
-  
-  // If there is an ASCII "space" character in the device name,
-  // terminate string there.  This is for 3ware devices only.
-  if ((s=strchr(device,' ')))
-    *s='\0';
-
-  // open the device
-  fd = deviceopen(device, mode);
-
-  // if we removed a space, put it back in please
-  if (s)
-    *s=' ';
-
-  // if we failed to open the device, complain!
-  if (fd < 0) {
-    PrintOut(LOG_INFO,"Device: %s, %s, open() failed\n",
-             device, strerror(errno));
-    return -1;
-  }
-  // device opened sucessfully
-  return fd;
-}
-
-int CloseDevice(int fd, char *name){
-  if (deviceclose(fd)){
-    PrintOut(LOG_INFO,"Device: %s, %s, close(%d) failed\n", name, strerror(errno), fd);
-    return 1;
-  }
-  // device sucessfully closed
-  return 0;
-}
-
-// returns <0 on failure
-int ATAErrorCount(int fd, char *name){
-  struct ata_smart_errorlog log;
-  
-  if (-1==ataReadErrorLog(fd,&log)){
-    PrintOut(LOG_INFO,"Device: %s, Read SMART Error Log Failed\n",name);
-    return -1;
-  }
-  
-  // return current number of ATA errors
-  return log.error_log_pointer?log.ata_error_count:0;
-}
-
-// returns <0 if problem
-int SelfTestErrorCount(int fd, char *name){
-  struct ata_smart_selftestlog log;
-
-  if (-1==ataReadSelfTestLog(fd,&log)){
-    PrintOut(LOG_INFO,"Device: %s, Read SMART Self Test Log Failed\n",name);
-    return -1;
-  }
-  
-  // return current number of self-test errors
-  return ataPrintSmartSelfTestlog(&log,0);
-}
-
-// scan to see what ata devices there are, and if they support SMART
-int ATADeviceScan(cfgfile *cfg){
-  int fd, supported=0;
-  struct ata_identify_device drive;
-  char *name=cfg->name;
-  int retainsmartdata=0;
-  int retid;
-
-  // should we try to register this as an ATA device?
-  if (!(cfg->tryata))
-    return 1;
-  
-  // open the device
-  if ((fd=OpenDevice(name, "ATA"))<0)
-    // device open failed
-    return 1;
-  PrintOut(LOG_INFO,"Device: %s, opened\n", name);
-  
-  // pass user settings on to low-level ATA commands
-  con->escalade=cfg->escalade;
-  con->fixfirmwarebug = cfg->fixfirmwarebug;
-
-  // Get drive identity structure
-  if ((retid=ataReadHDIdentity (fd,&drive))<0){
-    // Unable to read Identity structure
-    PrintOut(LOG_INFO,"Device: %s, unable to read Device Identity Structure\n",name);
-    deviceclose(fd);
-    return 2; 
-  }
-
-  if (retid){
-    PrintOut(LOG_INFO,"Device: %s, packet devices [this device %s] not SMART capable\n",
-	     name, packetdevicetype(retid-1));
-    return 2;
-  }
-
-  // Show if device in database, and use preset vendor attribute
-  // options unless user has requested otherwise.
-  if (cfg->ignorepresets)
-    PrintOut(LOG_INFO, "Device: %s, smartd database not searched (Directive: -P ignore).\n", name);
-  else {
-    // do whatever applypresets decides to do. Will allocate memory if
-    // cfg->attributedefs is needed.
-    if (applypresets(&drive, &cfg->attributedefs, con)<0)
-      PrintOut(LOG_INFO, "Device: %s, not found in smartd database.\n", name);
-    else
-      PrintOut(LOG_INFO, "Device: %s, found in smartd database.\n", name);
-    
-    // then save the correct state of the flag (applypresets may have changed it)
-    cfg->fixfirmwarebug = con->fixfirmwarebug;
-  }
-  
-  // If requested, show which presets would be used for this drive
-  if (cfg->showpresets) {
-    int savedebugmode=debugmode;
-    PrintOut(LOG_INFO, "Device %s: presets are:\n", name);
-    if (!debugmode)
-      debugmode=2;
-    showpresets(&drive);
-    debugmode=savedebugmode;
-  }
-
-  // see if drive supports SMART
-  supported=ataSmartSupport(&drive);
-  if (supported!=1) {
-    if (supported==0)
-      // drive does NOT support SMART
-      PrintOut(LOG_INFO,"Device: %s, lacks SMART capability\n",name);
-    else
-      // can't tell if drive supports SMART
-      PrintOut(LOG_INFO,"Device: %s, ATA IDENTIFY DEVICE words 82-83 don't specify if SMART capable.\n",name);
-  
-    // should we proceed anyway?
-    if (cfg->permissive){
-      PrintOut(LOG_INFO,"Device: %s, proceeding since '-T permissive' Directive given.\n",name);
-    }
-    else {
-      PrintOut(LOG_INFO,"Device: %s, to proceed anyway, use '-T permissive' Directive.\n",name);
-      deviceclose(fd);
-      return 2;
-    }
-  }
-  
-  if (ataEnableSmart(fd)){
-    // Enable SMART command has failed
-    PrintOut(LOG_INFO,"Device: %s, could not enable SMART capability\n",name);
-    deviceclose(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",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, disabled SMART Attribute Autosave.\n",name);
-  }
-
-  // or enable device attribute autosave
-  if (cfg->autosave==2){
-    if (ataEnableAutoSave(fd))
-      PrintOut(LOG_INFO,"Device: %s, could not enable SMART Attribute Autosave.\n",name);
-    else
-      PrintOut(LOG_INFO,"Device: %s, enabled SMART Attribute Autosave.\n",name);
-  }
-
-  // capability check: SMART status
-  if (cfg->smartcheck && ataSmartStatus2(fd)==-1){
-    PrintOut(LOG_INFO,"Device: %s, not capable of SMART Health Status check\n",name);
-    cfg->smartcheck=0;
-  }
-  
-  // capability check: Read smart values and thresholds.  Note that
-  // smart values are ALSO needed even if we ONLY want to know if the
-  // device is self-test log or error-log capable!  After ATA-5, this
-  // information was ALSO reproduced in the IDENTIFY DEVICE response,
-  // but sadly not for ATA-5.  Sigh.
-
-  // do we need to retain SMART data after returning from this routine?
-  retainsmartdata=cfg->usagefailed || cfg->prefail || cfg->usage;
-  
-  // do we need to get SMART data?
-  if (retainsmartdata || cfg->autoofflinetest || cfg->selftest || cfg->errorlog) {
-    cfg->smartval=(struct ata_smart_values *)calloc(1,sizeof(struct ata_smart_values));
-    cfg->smartthres=(struct ata_smart_thresholds *)calloc(1,sizeof(struct ata_smart_thresholds));
-    
-    if (cfg->smartval)
-      bytes+=sizeof(struct ata_smart_values);
-    
-    if (cfg->smartthres)
-      bytes+=sizeof(struct ata_smart_thresholds);
-
-    if (!cfg->smartval || !cfg->smartthres){
-      PrintOut(LOG_CRIT,"Not enough memory to obtain SMART data\n");
-      EXIT(EXIT_NOMEM);
-    }
-    
-    if (ataReadSmartValues(fd,cfg->smartval) ||
-	ataReadSmartThresholds (fd,cfg->smartthres)){
-      PrintOut(LOG_INFO,"Device: %s, Read SMART Values and/or Thresholds Failed\n",name);
-      retainsmartdata=cfg->usagefailed=cfg->prefail=cfg->usage=0;
-    }
-  }
-  
-  // enable/disable automatic on-line testing
-  if (cfg->autoofflinetest){
-    // is this an enable or disable request?
-    char *what=(cfg->autoofflinetest==1)?"disable":"enable";
-    if (!cfg->smartval)
-      PrintOut(LOG_INFO,"Device: %s, could not %s SMART Automatic Offline Testing.\n",name, what);
-    else {
-      // if command appears unsupported, issue a warning...
-      if (!isSupportAutomaticTimer(cfg->smartval))
-	PrintOut(LOG_INFO,"Device: %s, SMART Automatic Offline Testing unsupported...\n",name);
-      // ... but then try anyway
-      if ((cfg->autoofflinetest==1)?ataDisableAutoOffline(fd):ataEnableAutoOffline(fd))
-	PrintOut(LOG_INFO,"Device: %s, %s SMART Automatic Offline Testing failed.\n", name, what);
-      else
-	PrintOut(LOG_INFO,"Device: %s, %sd SMART Automatic Offline Testing.\n", name, what);
-    }
-  }
-  
-  // capability check: self-test-log
-  if (cfg->selftest){
-    int 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 (!cfg->smartval || !isSmartErrorLogCapable(cfg->smartval)){
-      PrintOut(LOG_INFO, "Device: %s, does not support SMART Self-test Log.\n", name);
-      cfg->selftest=0;
-      cfg->selflogcount=0;
-    }
-    else {
-      // get number of Self-test errors logged
-      val=SelfTestErrorCount(fd, name);
-      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 (!cfg->smartval || !isSmartErrorLogCapable(cfg->smartval)){
-      PrintOut(LOG_INFO, "Device: %s, does not support SMART Error Log.\n", name);
-      cfg->errorlog=0;
-      cfg->ataerrorcount=0;
-    }
-    else {
-      // get number of ATA errors logged
-      val=ATAErrorCount(fd, name);
-      if (val>=0)
-	cfg->ataerrorcount=val;
-      else
-	cfg->errorlog=0;
-    }
-  }
-  
-  // If we don't need to save SMART data, get rid of it now
-  if (!retainsmartdata) {
-    if (cfg->smartval) {
-      cfg->smartval=CheckFree(cfg->smartval, __LINE__,__FILE__);
-      bytes-=sizeof(struct ata_smart_values);
-    }
-    if (cfg->smartthres) {
-      cfg->smartthres=CheckFree(cfg->smartthres, __LINE__,__FILE__);
-      bytes-=sizeof(struct ata_smart_thresholds);
-    }
-  }
-
-  // If no tests available or selected, return
-  if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck || 
-        cfg->usagefailed || cfg->prefail || cfg->usage)) {
-    deviceclose(fd);
-    return 3;
-  }
-  
-  // Do we still have entries available?
-  if (numdevata>=MAXATADEVICES){
-    PrintOut(LOG_CRIT,"smartd has found more than MAXATADEVICES=%d ATA devices.\n"
-             "Recompile code from " PROJECTHOME " with larger MAXATADEVICES\n",(int)numdevata);
-    EXIT(EXIT_CCONST);
-  }
-  
-  // register device
-  PrintOut(LOG_INFO,"Device: %s, is SMART capable. Adding to \"monitor\" list.\n",name);
-  
-    // record number of device, type of device, increment device count
-  cfg->tryscsi=0;
-  cfg->tryata=1;
-
-  // close file descriptor
-  CloseDevice(fd, name);
-  return 0;
-}
-
-// on success, return 0. On failure, return >0.  Never return <0,
-// please.
-static int SCSIDeviceScan(cfgfile *cfg)
-{
-    int 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, "SCSI")) < 0) {
-#ifdef SCSIDEVELOPMENT
-        PrintOut(LOG_WARNING, "Device: %s, skip\n", device);
-        return 0;
-#else
-        return 1;
-#endif
-    }
-    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);
-      else
-	PrintOut(LOG_ERR, "Device: %s, failed Test Unit Ready [err=%d]\n", 
-		 device, err);
-      deviceclose(fd);
-#ifdef SCSIDEVELOPMENT
-      return 0;
-#else
-      return 2; 
-#endif
-    }
-  
-    if ((err = scsiFetchIECmpage(fd, &iec))) {
-      PrintOut(LOG_WARNING, "Device: %s, Fetch of IEC (SMART) mode page "
-	       "failed, err=%d, skip device\n", device, err);
-      deviceclose(fd);
-#ifdef SCSIDEVELOPMENT
-      return 0;
-#else
-      return 3;
-#endif
-    }
-    if (! scsi_IsExceptionControlEnabled(&iec)) {
-      PrintOut(LOG_WARNING, "Device: %s, IE (SMART) not enabled, "
-	       "skip device\n", device);
-      deviceclose(fd);
-#ifdef SCSIDEVELOPMENT
-      return 0;
-#else
-      return 3;
-#endif
-    }
-    
-    // Device exists, and does SMART.  Add to list
-    if (numdevscsi >= MAXSCSIDEVICES) {
-      PrintOut(LOG_ERR, "smartd has found more than MAXSCSIDEVICES=%d "
-	       "SCSI devices.\n" "Recompile code from " PROJECTHOME 
-	       " with larger MAXSCSIDEVICES\n", (int)numdevscsi);
-#ifdef SCSIDEVELOPMENT
-      deviceclose(fd);
-      return 0;
-#else
-      EXIT(EXIT_CCONST);
-#endif
-    }
-    
-    // now we can proceed to register the device
-    PrintOut(LOG_INFO, "Device: %s, is SMART capable. Adding "
-             "to \"monitor\" list.\n",device);
- 
-    // Flag that certain log pages are supported (information may be
-    // available from other sources).
-    if (0 == scsiLogSense(fd, SUPPORTED_LOG_PAGES, tBuf, sizeof(tBuf), 0)) {
-        for (k = 4; k < tBuf[3] + LOGPAGEHDRSIZE; ++k) {
-            switch (tBuf[k]) { 
-                case TEMPERATURE_PAGE:
-                    cfg->TempPageSupported = 1;
-                    break;
-                case IE_LOG_PAGE:
-                    cfg->SmartPageSupported = 1;
-                    break;
-                default:
-                    break;
-            }
-        }   
-    }
-
-    // record number of device, type of device, increment device count
-    cfg->tryata = 0;
-    cfg->tryscsi = 1;
-
-    // get rid of allocated memory only needed for ATA devices
-    cfg->monitorattflags = FreeNonZero(cfg->monitorattflags, NMONITOR*32,__LINE__,__FILE__);
-    cfg->attributedefs   = FreeNonZero(cfg->attributedefs,   MAX_ATTRIBUTE_NUM,__LINE__,__FILE__);
-    cfg->smartval        = FreeNonZero(cfg->smartval,        sizeof(struct ata_smart_values),__LINE__,__FILE__);
-    cfg->smartthres      = FreeNonZero(cfg->smartthres,      sizeof(struct ata_smart_thresholds),__LINE__,__FILE__);
-
-    // Check if scsiCheckIE() is going to work
-    {
-        UINT8 asc = 0;
-        UINT8 ascq = 0;
-        UINT8 currenttemp = 0;
-
-        if (scsiCheckIE(fd, cfg->SmartPageSupported, cfg->TempPageSupported,
-                        &asc, &ascq, &currenttemp)) {
-            PrintOut(LOG_INFO, "Device: %s, unexpectedly failed to read SMART"
-                     " values\n", device);
-            cfg->SuppressReport = 1;
-        }
-    }
-    // close file descriptor
-    CloseDevice(fd, device);
-    return 0;
-}
-
-// We compare old and new values of the n'th attribute.  Note that n
-// is NOT the attribute ID number.. If (Normalized & Raw) equal,
-// then return 0, else nonzero.
-int  ATACompareValues(changedattribute_t *delta,
-                            struct ata_smart_values *new,
-                            struct ata_smart_values *old,
-                            struct ata_smart_thresholds *thresholds,
-                            int n, char *name){
-  struct ata_smart_attribute *now,*was;
-  struct ata_smart_threshold_entry *thre;
-  unsigned char oldval,newval;
-  int sameraw;
-
-  // check that attribute number in range, and no null pointers
-  if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !new || !old || !thresholds)
-    return 0;
-  
-  // pointers to disk's values and vendor's thresholds
-  now=new->vendor_attributes+n;
-  was=old->vendor_attributes+n;
-  thre=thresholds->thres_entries+n;
-
-  // consider only valid attributes
-  if (!now->id || !was->id || !thre->id)
-    return 0;
-  
-  
-  // issue warning if they don't have the same ID in all structures:
-  if ( (now->id != was->id) || (now->id != thre->id) ){
-    PrintOut(LOG_INFO,"Device: %s, same Attribute has different ID numbers: %d = %d = %d\n",
-             name, (int)now->id, (int)was->id, (int)thre->id);
-    return 0;
-  }
-
-  // new and old values of Normalized Attributes
-  newval=now->current;
-  oldval=was->current;
-
-  // See if the RAW values are unchanged (ie, the same)
-  if (memcmp(now->raw, was->raw, 6))
-    sameraw=0;
-  else
-    sameraw=1;
-  
-  // if any values out of the allowed range, or if the values haven't
-  // changed, return 0
-  if (!newval || !oldval || newval>0xfe || oldval>0xfe || (oldval==newval && sameraw))
-    return 0;
-  
-  // values have changed.  Construct output and return
-  delta->newval=newval;
-  delta->oldval=oldval;
-  delta->id=now->id;
-  delta->prefail=ATTRIBUTE_FLAGS_PREFAILURE(now->flags);
-  delta->sameraw=sameraw;
-
-  return 1;
-}
-
-// This looks to see if the corresponding bit of the 32 bytes is set.
-// This wastes a few bytes of storage but eliminates all searching and
-// sorting functions! Entry is ZERO <==> the attribute ON. Calling
-// with set=0 tells you if the attribute is being tracked or not.
-// Calling with set=1 turns the attribute OFF.
-int IsAttributeOff(unsigned char attr, unsigned char **datap, int set, int which, int whatline){
-  unsigned char *data;
-  int loc=attr>>3;
-  int bit=attr & 0x07;
-  unsigned char mask=0x01<<bit;
-
-  if (which>=NMONITOR || which < 0){
-    PrintOut(LOG_CRIT, "Internal error in IsAttributeOff() at line %d of file %s (which=%d)\n%s",
-	     whatline, __FILE__, which, reportbug);
-    EXIT(EXIT_BADCODE);
-  }
-
-  if (*datap == NULL){
-    // NULL data implies Attributes are ON...
-    if (!set)
-      return 0;
-    
-    // we are writing
-    if (!(*datap=calloc(NMONITOR*32, 1))){
-      PrintOut(LOG_CRIT,"No memory to create monattflags\n");
-      EXIT(EXIT_NOMEM);
-    }
-
-    bytes+=NMONITOR*32;
-  }
-  
-  // pointer to the 256 bits that we need
-  data=*datap+which*32;
-
-  // attribute zero is always OFF
-  if (!attr)
-    return 1;
-
-  if (!set)
-    return (data[loc] & mask);
-  
-  data[loc]|=mask;
-
-  // return value when setting has no sense
-  return 0;
-}
-
-
-int ATACheckDevice(cfgfile *cfg){
-  int fd,i;
-  char *name=cfg->name;
-  
-  // fix firmware bug if requested
-  con->fixfirmwarebug=cfg->fixfirmwarebug;
-  con->escalade=cfg->escalade;
-
-  // If user has asked, 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.  ATAPI
-  // cd/dvd devices will hang awaiting media if O_NONBLOCK is not
-  // given (see linux cdrom driver).
-  if ((fd=OpenDevice(name, "ATA"))<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=cfg->smartthres;
-    
-    // Read current attribute values. *drive contains old values and thresholds
-    if (ataReadSmartValues(fd,&curval)){
-      PrintOut(LOG_CRIT, "Device: %s, failed to read SMART Attribute Data\n", name);
-      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 (!IsAttributeOff(att, &cfg->monitorattflags, 0, MONITOR_FAILUSE, __LINE__)){
-            char attname[64], *loc=attname;
-            
-            // get attribute name & skip white space
-            ataPrintSmartAttribName(loc, att, cfg->attributedefs);
-            while (*loc && *loc==' ') loc++;
-            
-            // warning message
-            PrintOut(LOG_CRIT, "Device: %s, Failed SMART usage Attribute: %s.\n", name, loc);
-            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) && ATACompareValues(&delta, &curval, cfg->smartval, thresh, i, name)){
-          unsigned char id=delta.id;
-
-          // if the only change is the raw value, and we're not
-          // tracking raw value, then continue loop over attributes
-          if (!delta.sameraw && delta.newval==delta.oldval && !IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_RAW, __LINE__))
-            continue;
-
-          // are we tracking this attribute?
-          if (!IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_IGNORE, __LINE__)){
-            char newrawstring[64], oldrawstring[64], attname[64], *loc=attname;
-
-            // get attribute name, skip spaces
-            ataPrintSmartAttribName(loc, id, cfg->attributedefs);
-            while (*loc && *loc==' ') loc++;
-            
-            // has the user asked for us to print raw values?
-            if (IsAttributeOff(id, &cfg->monitorattflags, 0, MONITOR_RAWPRINT, __LINE__)) {
-              // get raw values (as a string) and add to printout
-              char rawstring[64];
-              ataPrintSmartAttribRawValue(rawstring, curval.vendor_attributes+i, cfg->attributedefs);
-              sprintf(newrawstring, " [Raw %s]", rawstring);
-              ataPrintSmartAttribRawValue(rawstring, cfg->smartval->vendor_attributes+i, cfg->attributedefs);
-              sprintf(oldrawstring, " [Raw %s]", rawstring);
-            }
-            else
-              newrawstring[0]=oldrawstring[0]='\0';
-
-            // prefailure attribute
-            if (cfg->prefail && delta.prefail)
-              PrintOut(LOG_INFO, "Device: %s, SMART Prefailure Attribute: %s changed from %d%s to %d%s\n",
-                       name, loc, delta.oldval, oldrawstring, delta.newval, newrawstring);
-
-            // usage attribute
-            if (cfg->usage && !delta.prefail)
-              PrintOut(LOG_INFO, "Device: %s, SMART Usage Attribute: %s changed from %d%s to %d%s\n",
-                       name, loc, delta.oldval, oldrawstring, delta.newval, newrawstring);
-          }
-        } // endof block tracking usage or prefailure
-      } // end of loop over attributes
-     
-      // Save the new values into *drive for the next time around
-      *(cfg->smartval)=curval;
-    } 
-  }
-  
-  // check if number of selftest errors has increased (note: may also DECREASE)
-  if (cfg->selftest){
-    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;
-}
-
-#define DEF_SCSI_REPORT_TEMPERATURE_DELTA 2
-static int scsi_report_temperature_delta = DEF_SCSI_REPORT_TEMPERATURE_DELTA;
-
-int SCSICheckDevice(cfgfile *cfg)
-{
-    UINT8 asc, ascq;
-    UINT8 currenttemp;
-    int fd;
-    char *name=cfg->name;
-    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, "SCSI"))<0) {
-        PrintAndMail(cfg, 9, LOG_CRIT, "Device: %s, unable to open device",
-                      name);
-        return 1;
-    }
-    currenttemp = 0;
-    asc = 0;
-    ascq = 0;
-    if (! cfg->SuppressReport) {
-        if (scsiCheckIE(fd, cfg->SmartPageSupported, cfg->TempPageSupported,
-                        &asc, &ascq, &currenttemp)) {
-            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);
-            cfg->SuppressReport = 1;
-        }
-    }
-    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);  
-  
-    if (currenttemp && currenttemp!=255) {
-        if (cfg->Temperature) {
-            if (abs(((int)currenttemp - (int)cfg->Temperature)) >= 
-                scsi_report_temperature_delta) {
-                PrintOut(LOG_INFO, "Device: %s, Temperature changed %d degrees "
-                         "to %d degrees since last report\n", name, 
-                         (int)(currenttemp - cfg->Temperature), 
-                         (int)currenttemp);
-                cfg->Temperature = currenttemp;
-            }
-        }
-        else {
-            PrintOut(LOG_INFO, "Device: %s, initial Temperature is %d "
-                     "degrees\n", name, (int)currenttemp);
-            cfg->Temperature = currenttemp;
-        }
-    }
-
-    CloseDevice(fd, name);
-    return 0;
-}
-
-// Checks the SMART status of all ATA and SCSI devices
-void CheckDevicesOnce(cfgfile **atadevices, cfgfile **scsidevices){
-  int i;
-  
-  for (i=0; i<numdevata; i++) 
-    ATACheckDevice(atadevices[i]);
-  
-  for (i=0; i<numdevscsi; i++)
-    SCSICheckDevice(scsidevices[i]);
-
-  return;
-}
-
-#if SCSITIMEOUT
-// This alarm means that a SCSI USB device was hanging
-void AlarmHandler(int signal) {
-  longjmp(registerscsienv, 1);
-}
-#endif
-
-// Does initialization right after fork to daemon mode
-void Initialize(time_t *wakeuptime){
-
-  // install goobye message and remove pidfile handler
-  atexit(Goodbye);
-  
-  // write PID file only after installing exit handler
-  if (!debugmode)
-    WritePidFile();
-  
-  // install signal handlers.  On Solaris, can't use signal() because
-  // it resets the handler to SIG_DFL after each call.  So use sigset()
-  // instead.  So SIGNALFN()==signal() or SIGNALFN()==sigset().
-  
-  // normal and abnormal exit
-  if (SIGNALFN(SIGTERM, sighandler)==SIG_IGN)
-    SIGNALFN(SIGTERM, SIG_IGN);
-  if (SIGNALFN(SIGQUIT, sighandler)==SIG_IGN)
-    SIGNALFN(SIGQUIT, SIG_IGN);
-  
-  // in debug mode, <CONTROL-C> ==> HUP
-  if (SIGNALFN(SIGINT, debugmode?HUPhandler:sighandler)==SIG_IGN)
-    SIGNALFN(SIGINT, SIG_IGN);
-  
-  // Catch HUP and USR1
-  if (SIGNALFN(SIGHUP, HUPhandler)==SIG_IGN)
-    SIGNALFN(SIGHUP, SIG_IGN);
-  if (SIGNALFN(SIGUSR1, USR1handler)==SIG_IGN)
-    SIGNALFN(SIGUSR1, SIG_IGN);
-
-  // initialize wakeup time to CURRENT time
-  *wakeuptime=time(NULL);
-  
-  return;
-}
-
-time_t dosleep(time_t wakeuptime){
-  time_t timenow=0;
-  
-  // If past wake-up-time, compute next wake-up-time
-  timenow=time(NULL);
-  while (wakeuptime<=timenow){
-    int intervals=1+(timenow-wakeuptime)/checktime;
-    wakeuptime+=intervals*checktime;
-  }
-  
-  // sleep until we catch SIGUSR1 or have completed sleeping
-  while (timenow<wakeuptime && !caughtsigUSR1 && !caughtsigHUP){
-    
-    // protect user again system clock being adjusted backwards
-    if (wakeuptime>timenow+checktime){
-      PrintOut(LOG_CRIT, "System clock time adjusted to the past. Resetting next wakeup time.\n");
-      wakeuptime=timenow+checktime;
-    }
-    
-    // Exit sleep when time interval has expired or a signal is received
-    sleep(wakeuptime-timenow);
-    
-    timenow=time(NULL);
-  }
-  
-  // if we caught a SIGUSR1 then print message and clear signal
-  if (caughtsigUSR1){
-    PrintOut(LOG_INFO,"Signal USR1 - checking devices now rather than in %d seconds.\n",
-	     wakeuptime-timenow>0?(int)(wakeuptime-timenow):0);
-    caughtsigUSR1=0;
-  }
-  
-  // return adjusted wakeuptime
-  return wakeuptime;
-}
-
-// Print out a list of valid arguments for the Directive d
-void printoutvaliddirectiveargs(int priority, char d) {
-  char *s=NULL;
-
-  switch (d) {
-  case 'd':
-    PrintOut(priority, "ata, scsi, removable, 3ware,N");
-    break;
-  case 'T':
-    PrintOut(priority, "normal, permissive");
-    break;
-  case 'o':
-  case 'S':
-    PrintOut(priority, "on, off");
-    break;
-  case 'l':
-    PrintOut(priority, "error, selftest");
-    break;
-  case 'M':
-    PrintOut(priority, "\"once\", \"daily\", \"diminishing\", \"test\", \"exec\"");
-    break;
-  case 'v':
-    if (!(s = create_vendor_attribute_arg_list())) {
-      PrintOut(LOG_CRIT,"Insufficient memory to construct argument list\n");
-      EXIT(EXIT_NOMEM);
-    }
-    PrintOut(priority, "\n%s\n", s);
-    s=CheckFree(s, __LINE__,__FILE__);
-    break;
-  case 'P':
-    PrintOut(priority, "use, ignore, show, showall");
-    break;
-  case 'F':
-    PrintOut(priority, "none, samsung, samsung2");
-    break;
-  }
-}
-
-// exits with an error message, or returns integer value of token
-int GetInteger(char *arg, char *name, char *token, int lineno, char *configfile, int min, int max){
-  char *endptr;
-  int val;
-  
-  // check input range
-  if (min<0){
-    PrintOut(LOG_CRIT, "min =%d passed to GetInteger() must be >=0\n", min);
-    return -1;
-  }
-
-  // make sure argument is there
-  if (!arg) {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s takes integer argument from %d to %d.\n",
-             configfile, lineno, name, token, min, max);
-    return -1;
-  }
-  
-  // get argument value (base 10), check that it's integer, and in-range
-  val=strtol(arg,&endptr,10);
-  if (*endptr!='\0' || val<min || val>max )  {
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s has argument: %s; needs integer from %d to %d.\n",
-             configfile, lineno, name, token, arg, min, max);
-    return -1;
-  }
-
-  // all is well; return value
-  return val;
-}
-
-// This function returns 1 if it has correctly parsed one token (and
-// any arguments), else zero if no tokens remain.  It returns -1 if an
-// error was encountered.
-int ParseToken(char *token,cfgfile *cfg){
-  char sym;
-  char *name=cfg->name;
-  int lineno=cfg->lineno;
-  char *delim = " \n\t";
-  int badarg = 0;
-  int missingarg = 0;
-  char *arg = NULL;
-
-  // 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();
-    return -1;
-  }
-  
-  // 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.
-      cfg->permissive=0;
-    } else if (!strcmp(arg, "permissive")) {
-      // Permissive mode; ignore errors from Mandatory SMART commands
-      cfg->permissive=1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'd':
-    // specify the device type
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "ata")) {
-      cfg->tryata  = 1;
-      cfg->tryscsi = 0;
-      cfg->escalade =0;
-    } else if (!strcmp(arg, "scsi")) {
-      cfg->tryscsi = 1;
-      cfg->tryata  = 0;
-      cfg->escalade =0;
-    } else if (!strcmp(arg, "removable")) {
-      cfg->removable = 1;
-    } else {
-      // look 3ware,N RAID device
-      int i;
-      char *s;
-      
-      // make a copy of the string to mess with
-      if (!(s = strdup(arg))) {
-	PrintOut(LOG_CRIT,
-		 "No memory to copy argument to -d option - exiting\n");
-	EXIT(EXIT_NOMEM);
-      } else if (strncmp(s,"3ware,",6)) {
-	badarg=1;
-      } else if (split_report_arg2(s, &i)){
-	PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n",
-		 configfile, lineno, name);
-	badarg=1;
-      } else if ( i<0 || i>15) {
-	PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n",
-		 configfile, lineno, name, i);
-	badarg=1;
-      } else {
-	// NOTE: escalade = disk number + 1
-	cfg->escalade = i+1;
-	cfg->tryata  = TRUE;
-	cfg->tryscsi = FALSE;
-      }
-      s=CheckFree(s, __LINE__,__FILE__); 
-    }
-    break;
-  case 'F':
-    // fix firmware bug
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "none")) {
-      cfg->fixfirmwarebug = FIX_NONE;
-    } else if (!strcmp(arg, "samsung")) {
-      cfg->fixfirmwarebug = FIX_SAMSUNG;
-    } else if (!strcmp(arg, "samsung2")) {
-      cfg->fixfirmwarebug = FIX_SAMSUNG2;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'H':
-    // check SMART status
-    cfg->smartcheck=1;
-    break;
-  case 'f':
-    // check for failure of usage attributes
-    cfg->usagefailed=1;
-    break;
-  case 't':
-    // track changes in all vendor attributes
-    cfg->prefail=1;
-    cfg->usage=1;
-    break;
-  case 'p':
-    // track changes in prefail vendor attributes
-    cfg->prefail=1;
-    break;
-  case 'u':
-    //  track changes in usage vendor attributes
-    cfg->usage=1;
-    break;
-  case 'l':
-    // track changes in SMART logs
-    if ((arg = strtok(NULL, delim)) == NULL) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "selftest")) {
-      // track changes in self-test log
-      cfg->selftest=1;
-    } else if (!strcmp(arg, "error")) {
-      // track changes in ATA error log
-      cfg->errorlog=1;
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'a':
-    // monitor everything
-    cfg->smartcheck=1;
-    cfg->prefail=1;
-    cfg->usagefailed=1;
-    cfg->usage=1;
-    cfg->selftest=1;
-    cfg->errorlog=1;
-    break;
-  case 'o':
-    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))) {
-        PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive %s 'exec' argument must be followed by executable path.\n",
-                 configfile, lineno, name, token);
-	return -1;
-      }
-      // Free the last cmd line given if any
-      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);
-        cfg->emailcmdline=FreeNonZero(cfg->emailcmdline, -1,__LINE__,__FILE__);
-      }
-      // Attempt to copy the argument
-      cfg->emailcmdline=CustomStrDup(arg, 1, __LINE__,__FILE__);
-    } else {
-      badarg = 1;
-    }
-    break;
-  case 'i':
-    // ignore failure of usage attribute
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_FAILUSE, __LINE__);
-    break;
-  case 'I':
-    // ignore attribute for tracking purposes
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_IGNORE, __LINE__);
-    break;
-  case 'r':
-    // print raw value when tracking
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
-    break;
-  case 'R':
-    // track changes in raw value (forces printing of raw value)
-    if ((val=GetInteger(arg=strtok(NULL,delim), name, token, lineno, configfile, 1, 255))<0)
-      return -1;
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
-    IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAW, __LINE__);
-    break;
-  case '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);
-      return -1;
-    }
-    cfg->address=CustomStrDup(arg, 1, __LINE__,__FILE__);
-    break;
-  case 'v':
-    // non-default vendor-specific attribute meaning
-    if (!(arg=strtok(NULL,delim))) {
-      missingarg = 1;
-    } else if (parse_attribute_def(arg, &cfg->attributedefs)){   
-      badarg = 1;
-    }
-    break;
-  case 'P':
-    // Define use of drive-specific presets.
-    if (!(arg = strtok(NULL, delim))) {
-      missingarg = 1;
-    } else if (!strcmp(arg, "use")) {
-      cfg->ignorepresets = FALSE;
-    } else if (!strcmp(arg, "ignore")) {
-      cfg->ignorepresets = TRUE;
-    } else if (!strcmp(arg, "show")) {
-      cfg->showpresets = TRUE;
-    } else if (!strcmp(arg, "showall")) {
-      showallpresets();
-    } else {
-      badarg = 1;
-    }
-    break;
-  default:
-    // Directive not recognized
-    PrintOut(LOG_CRIT,"File %s line %d (drive %s): unknown Directive: %s\n",
-             configfile, lineno, name, token);
-    Directives();
-    return -1;
-  }
-  if (missingarg) {
-    PrintOut(LOG_CRIT, "File %s line %d (drive %s): Missing argument to %s Directive\n",
-	     configfile, lineno, name, token);
-  }
-  if (badarg) {
-    PrintOut(LOG_CRIT, "File %s line %d (drive %s): Invalid argument to %s Directive: %s\n",
-	     configfile, lineno, name, token, arg);
-  }
-  if (missingarg || badarg) {
-    PrintOut(LOG_CRIT, "Valid arguments to %s Directive are: ", token);
-    printoutvaliddirectiveargs(LOG_CRIT, sym);
-    PrintOut(LOG_CRIT, "\n");
-    return -1;
-  }
-
-  return 1;
-}
-
-// Allocate storage for a new cfgfile entry.  If original!=NULL, it's
-// a copy of the original, but with private data storage.  Else all is
-// zeroed.  Returns address, and fails if non memory available.
-
-cfgfile *CreateConfigEntry(cfgfile *original){
-  cfgfile *add;
-  
-  // allocate memory for new structure
-  if (!(add=(cfgfile *)calloc(1,sizeof(cfgfile))))
-    goto badexit;
-
-  bytes+=sizeof(cfgfile);
-  
-  // if old structure was pointed to, copy it
-  if (original)
-    memcpy(add, original, sizeof(cfgfile));
-  
-  // make private copies of data items ONLY if they are in use (non
-  // NULL)
-  add->name         = CustomStrDup(add->name,         0, __LINE__,__FILE__);
-  add->emailcmdline = CustomStrDup(add->emailcmdline, 0, __LINE__,__FILE__);
-  add->address      = CustomStrDup(add->address,      0, __LINE__,__FILE__);
-
-  if (add->attributedefs) {
-    if (!(add->attributedefs=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM,1)))
-      goto badexit;
-    bytes+=MAX_ATTRIBUTE_NUM;
-    memcpy(add->attributedefs, original->attributedefs, MAX_ATTRIBUTE_NUM);
-  }
-  
-  if (add->monitorattflags) {
-    if (!(add->monitorattflags=(unsigned char *)calloc(NMONITOR*32, 1)))
-      goto badexit;
-    bytes+=NMONITOR*32;
-    memcpy(add->monitorattflags, original->monitorattflags, NMONITOR*32);
-  }
-  
-  if (add->smartval) {
-    if (!(add->smartval=(struct ata_smart_values *)calloc(1,sizeof(struct ata_smart_values))))
-      goto badexit;
-    else
-      bytes+=sizeof(struct ata_smart_values);
-  }
-  
-  if (add->smartthres) {
-    if (!(add->smartthres=(struct ata_smart_thresholds *)calloc(1,sizeof(struct ata_smart_thresholds))))
-      goto badexit;
-    else
-      bytes+=sizeof(struct ata_smart_thresholds);
-  }
-
-  return add;
-
- badexit:
-  PrintOut(LOG_CRIT, "No memory to create entry from configuration file\n");
-  EXIT(EXIT_NOMEM);
-}
-
-
-// This is the routine that adds things to the cfgentries list. To
-// prevent memory leaks when re-reading the configuration file many
-// times, this routine MUST deallocate any memory other than that
-// pointed to within cfg-> before it returns.
-//
-// Return values are:
-//  1: parsed a normal line
-//  0: found comment or blank line
-// -1: found SCANDIRECTIVE line
-// -2: found an error
-//
-// Note: this routine modifies *line from the caller!
-int ParseConfigLine(int entry, int lineno,char *line){
-  char *token=NULL;
-  char *name=NULL;
-  char *delim = " \n\t";
-  cfgfile *cfg=NULL;
-  int devscan=0;
-
-  // get first token: device name. If a comment, skip line
-  if (!(name=strtok(line,delim)) || *name=='#') {
-    return 0;
-  }
-
-  // Have we detected the SCANDIRECTIVE directive?
-  if (!strcmp(SCANDIRECTIVE,name)){
-    devscan=1;
-    if (entry) {
-      PrintOut(LOG_INFO,"Scan Directive %s (line %d) must be the first entry in %s\n",name, lineno, configfile);
-      return -2;
-    }
-  }
-
-  // Is there space for another entry?
-  if (entry>=MAXENTRIES){
-    PrintOut(LOG_CRIT,"Error: configuration file %s can have no more than MAXENTRIES=%d entries\n",
-             configfile,MAXENTRIES);
-    return -2;
-  }
-  
-  // We've got a legit entry, make space to store it
-  cfg=cfgentries[entry]=CreateConfigEntry(NULL);
-  cfg->name = CustomStrDup(name, 1, __LINE__,__FILE__);
-
-  // 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_device_type(cfg->name))
-    cfg->tryscsi=0;
-  else if (GUESS_DEVTYPE_SCSI == guess_device_type(cfg->name))
-    cfg->tryata=0;
-  /* in "don't know" case leave both tryata and tryscsi set */
-  
-  // parse tokens one at a time from the file.
-  while ((token=strtok(NULL,delim))){
-    int retval=ParseToken(token,cfg);
-    
-    if (retval==0)
-      // No tokens left:
-      break;
-    
-    if (retval>0) {
-      // Parsed token  
-#if (0)
-      PrintOut(LOG_INFO,"Parsed token %s\n",token);
-#endif
-      continue;
-    }
-    
-    if (retval<0) {
-      // error found on the line
-      return -2;
-    }
-  }
-  
-  // If we found 3ware controller, then modify device name by adding a SPACE
-  if (cfg->escalade){
-    int len=17+strlen(cfg->name);
-    char *newname;
-    
-    if (devscan){
-      PrintOut(LOG_CRIT, "smartd: can not scan for 3ware devices (line %d of file %s)\n",
-	       lineno, configfile);
-      return -2;
-    }
-    
-    if (!(newname=(char *)calloc(len,1))) {
-      PrintOut(LOG_INFO,"No memory to parse file: %s line %d, %s\n", configfile, lineno, strerror(errno));
-      EXIT(EXIT_NOMEM);
-    }
-    
-    // Make new device name by adding a space then RAID disk number
-    snprintf(newname, len, "%s [3ware_disk_%02d]", cfg->name, cfg->escalade-1);
-    cfg->name=CheckFree(cfg->name, __LINE__,__FILE__);
-    cfg->name=newname;
-    bytes+=16;
-  }
-
-  // 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);
-    return -2;
-  }
-  
-  // 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);
-      return -2;
-    }
-    // now free memory.  From here on the sign of <nomailer> is
-    // address==NULL and cfg->emailcmdline!=NULL
-    cfg->address=FreeNonZero(cfg->address, -1,__LINE__,__FILE__);
-  }
-
-  // set cfg->emailfreq to 1 (once) if user hasn't set it
-  if (!cfg->emailfreq)
-    cfg->emailfreq = 1;
-
-  entry++;
-
-  if (devscan)
-    return -1;
-  else
-    return 1;
-}
-
-// clean up utility for ParseConfigFile()
-void cleanup(FILE **fpp){
-  if (*fpp){
-    fclose(*fpp);
-    *fpp=NULL;
-  }
-
-  return;
-}
-
-
-// Parses a configuration file.  Return values are:
-// -1:    could not open config file, or syntax error
-//  N=>0: found N entries
-// 
-// In the case where the return value is 0, there are three
-// possiblities:
-// Empty configuration file ==> cfgentries[0]==NULL
-// No configuration file    ==> cfgentries[0]->lineno == 0
-// SCANDIRECTIVE found      ==> cfgentries[0]->lineno != 0
-int ParseConfigFile(){
-  FILE *fp=NULL;
-  int entry=0,lineno=1,cont=0,contlineno=0;
-  char line[MAXLINELEN+2];
-  char fullline[MAXCONTLINE+1];
-
-  // 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);
-    return -1;
-  }
-  
-  // No configuration file found -- use fake one
-  if (fp==NULL) {
-    int len=strlen(SCANDIRECTIVE)+4;
-    char *fakeconfig=(char *)calloc(len,1);
-  
-    if (!fakeconfig || 
-	(len-1) != snprintf(fakeconfig, len, "%s -a", SCANDIRECTIVE) ||
-	-1 != ParseConfigLine(entry, 0, fakeconfig)
-	) {
-      PrintOut(LOG_CRIT,"Internal error in ParseConfigFile() at line %d of file %s\n%s", 
-	       __LINE__, __FILE__, reportbug);
-      EXIT(EXIT_BADCODE);
-    }
-    fakeconfig=CheckFree(fakeconfig, __LINE__,__FILE__);
-    return 0;
-  }
-    
-  // configuration file exists
-  PrintOut(LOG_INFO,"Opened configuration file %s\n",configfile);
-
-  // parse config file line by line
-  while (1) {
-    int len=0,scandevice;
-    char *lastslash;
-    char *comment;
-    char *code;
-
-    // make debugging simpler
-    memset(line,0,sizeof(line));
-
-    // get a line
-    code=fgets(line,MAXLINELEN+2,fp);
-    
-    // are we at the end of the file?
-    if (!code){
-      if (cont) {
-        scandevice=ParseConfigLine(entry,contlineno,fullline);
-        // See if we found a SCANDIRECTIVE directive
-        if (scandevice==-1) {
-	  cleanup(&fp);
-          return 0;
-	}
-	// did we find a syntax error
-	if (scandevice==-2) {
-	  cleanup(&fp);
-	  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);
-      cleanup(&fp);
-      return -1;
-    }
-
-    // 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);
-      cleanup(&fp);
-      return -1;
-    }
-    
-    // copy string so far into fullline, and increment length
-    strcpy(fullline+cont,line);
-    cont+=len;
-
-    // is this a continuation line.  If so, replace \ by space and look at next line
-    if ( (lastslash=rindex(line,'\\')) && !strtok(lastslash+1," \n\t")){
-      *(fullline+(cont-len)+(lastslash-line))=' ';
-      continue;
-    }
-
-    // Not a continuation line. Parse it
-    scandevice=ParseConfigLine(entry,contlineno,fullline);
-
-    // did we find a scandevice directive?
-    if (scandevice==-1) {
-      cleanup(&fp);
-      return 0;
-    }
-    // did we find a syntax error
-    if (scandevice==-2) {
-      cleanup(&fp);
-      return -1;
-    }
-
-    entry+=scandevice;
-    lineno++;
-    cont=0;
-  }
-  cleanup(&fp);
-  
-  // note -- may be zero if syntax of file OK, but no valid entries!
-  return entry;
-}
-
-
-// Prints copyright, license and version information
-void PrintCopyleft(void){
-  debugmode=1;
-  PrintHead();
-  PrintCVS();
-  return;
-}
-
-/* Prints the message "=======> VALID ARGUMENTS ARE: <LIST>  <=======\n", where
-   <LIST> is the list of valid arguments for option opt. */
-void PrintValidArgs(char opt) {
-  const char *s;
-
-  PrintOut(LOG_CRIT, "=======> VALID ARGUMENTS ARE: ");
-  if (!(s = GetValidArgList(opt)))
-    PrintOut(LOG_CRIT, "Error constructing argument list for option %c", opt);
-  else
-    PrintOut(LOG_CRIT, (char *)s);
-  PrintOut(LOG_CRIT, " <=======\n");
-}
-
-// Parses input line, prints usage message and
-// version/license/copyright messages
-void ParseOpts(int argc, char **argv){
-  extern char *optarg;
-  extern int  optopt, optind, opterr;
-  int optchar;
-  int badarg;
-  char *tailptr;
-  long lchecktime;
-  // Please update GetValidArgList() if you edit shortopts
-  const char *shortopts = "q:dDi:p:r:Vh?";
-#ifdef HAVE_GETOPT_LONG
-  char *arg;
-  // Please update GetValidArgList() if you edit longopts
-  struct option longopts[] = {
-    { "quit",           required_argument, 0, 'q' },
-    { "debug",          no_argument,       0, 'd' },
-    { "showdirectives", no_argument,       0, 'D' },
-    { "interval",       required_argument, 0, 'i' },
-    { "pidfile",	required_argument, 0, 'p' },
-    { "report",         required_argument, 0, 'r' },
-    { "version",        no_argument,       0, 'V' },
-    { "license",        no_argument,       0, 'V' },
-    { "copyright",      no_argument,       0, 'V' },
-    { "help",           no_argument,       0, 'h' },
-    { "usage",          no_argument,       0, 'h' },
-    { 0,                0,                 0, 0   }
-  };
-#endif
-  
-  opterr=optopt=0;
-  badarg=FALSE;
-  
-  // Parse input options.  This horrible construction is so that emacs
-  // indents properly.  Sorry.
-  while (-1 != (optchar = 
-#ifdef HAVE_GETOPT_LONG
-		getopt_long(argc, argv, shortopts, longopts, NULL)
-#else
-		getopt(argc, argv, shortopts)
-#endif
-		)) {
-    
-    switch(optchar) {
-    case 'q':
-      if (!(strcmp(optarg,"nodev"))) {
-	quit=0;
-      } else if (!(strcmp(optarg,"nodevstartup"))) {
-	quit=1;
-      } else if (!(strcmp(optarg,"never"))) {
-	quit=2;
-      } else if (!(strcmp(optarg,"onecheck"))) {
-	quit=3;
-	debugmode=1;
-      } else if (!(strcmp(optarg,"errors"))) {
-	quit=4;
-      } else {
-	badarg = TRUE;
-      }
-      break;
-    case '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, "No memory to process -r option - exiting\n");
-          EXIT(EXIT_NOMEM);
-        }
-        if (split_report_arg(s, &i)) {
-	  badarg = TRUE;
-	} else if (i<1 || i>3) {
-	  debugmode=1;
-	  PrintHead();
-	  PrintOut(LOG_CRIT, "======> INVALID REPORT LEVEL: %s <=======\n", optarg);
-	  PrintOut(LOG_CRIT, "======> LEVEL MUST BE INTEGER BETWEEN 1 AND 3<=======\n");
-	  EXIT(EXIT_BADCMD);
-        } else if (!strcmp(s,"ioctl")) {
-          con->reportataioctl  = con->reportscsiioctl = i;
-        } else if (!strcmp(s,"ataioctl")) {
-          con->reportataioctl = i;
-        } else if (!strcmp(s,"scsiioctl")) {
-          con->reportscsiioctl = i;
-        } else {
-          badarg = TRUE;
-        }
-        s=CheckFree(s, __LINE__,__FILE__);
-      }
-      break;
-    case 'p':
-      pid_file=CustomStrDup(optarg, 1, __LINE__,__FILE__);
-      break;
-    case 'V':
-      PrintCopyleft();
-      EXIT(0);
-      break;
-    case 'h':
-      debugmode=1;
-      PrintHead();
-      Usage();
-      EXIT(0);
-      break;
-    case '?':
-    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);
-          PrintValidArgs(optopt);
-        } else {
-          PrintOut(LOG_CRIT, "=======> UNRECOGNIZED OPTION: %s <=======\n\n",arg+2);
-        }
-        PrintOut(LOG_CRIT, "\nUse smartd --help to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-#endif
-      if (optopt) {
-        // Iff optopt holds a valid option then argument must be missing.
-        if (strchr(shortopts, optopt) != NULL){
-          PrintOut(LOG_CRIT, "=======> ARGUMENT REQUIRED FOR OPTION: %c <=======\n",optopt);
-          PrintValidArgs(optopt);
-        } else {
-          PrintOut(LOG_CRIT, "=======> UNRECOGNIZED OPTION: %c <=======\n\n",optopt);
-        }
-        PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-        EXIT(EXIT_BADCMD);
-      }
-      Usage();
-      EXIT(0);
-    }
-
-    // Check to see if option had an unrecognized or incorrect argument.
-    if (badarg) {
-      debugmode=1;
-      PrintHead();
-      // It would be nice to print the actual option name given by the user
-      // here, but we just print the short form.  Please fix this if you know
-      // a clean way to do it.
-      PrintOut(LOG_CRIT, "=======> INVALID ARGUMENT TO -%c: %s <======= \n", optchar, optarg);
-      PrintValidArgs(optchar);
-      PrintOut(LOG_CRIT, "\nUse smartd -h to get a usage summary\n\n");
-      EXIT(EXIT_BADCMD);
-    }
-  }
-
-  // no pidfile in debug mode
-  if (debugmode && pid_file) {
-    debugmode=1;
-    PrintHead();
-    PrintOut(LOG_CRIT, "=======> INVALID CHOICE OF OPTIONS: -d and -p <======= \n\n");
-    PrintOut(LOG_CRIT, "Error: pid file %s not written in debug (-d) mode\n\n", pid_file);
-    pid_file=FreeNonZero(pid_file, -1,__LINE__,__FILE__);
-    EXIT(EXIT_BADCMD);
-  }
-  
-  // print header
-  PrintHead();
-  
-  return;
-}
-
-// Function we call if no configuration file was found or if the
-// SCANDIRECTIVE Directive was found.  It makes entries for /dev/hd[a-t]
-// and /dev/sd[a-z].
-int MakeConfigEntries(const char *type, int start){
-  int i;
-  int num;
-  char** devlist = NULL;
-  cfgfile *first=cfgentries[0],*cfg=first;
-
-  // make list of devices
-  if ((num=make_device_names(&devlist,type))<0){
-    PrintOut(LOG_CRIT,"No memory to create device name scan list\n");
-    EXIT(EXIT_NOMEM);
-  }
-  
-  // if nothing on list, we are finished!
-  if (!num)
-    return num;
-
-  // check that we still have space for entries
-  if (MAXENTRIES<(start+num)){
-    PrintOut(LOG_CRIT,"Error: simulated config file can have no more than MAXENTRIES=%d entries\n",(int)MAXENTRIES);
-    // need to clean up memory allocated by make_device_names
-    for (i=0; i < num; i++) {
-      devlist[i] = FreeNonZero(devlist[i],strlen((char*)devlist[i]),__LINE__,__FILE__);
-    }
-    devlist = FreeNonZero(devlist,(sizeof (char*) * num),__LINE__,__FILE__);
-    EXIT(EXIT_CCONST);
-  }
-  
-  // loop over entries to create
-  for(i=0; i<num; i++){
-    
-    // make storage and copy for all but first entry
-    if ((start+i))
-      cfg=cfgentries[start+i]=CreateConfigEntry(first);
-    
-    // ATA or SCSI?
-    cfg->tryata = !strcmp(type,"ATA");
-    cfg->tryscsi= !strcmp(type,"SCSI");
-    
-    // remove device name, if it's there, and put in correct one
-    cfg->name=FreeNonZero(cfg->name, -1,__LINE__,__FILE__);
-    // save pointer to the device name created within
-    // make_device_names
-    cfg->name=devlist[i];
-  }
-  
-  // If needed, free memory used for devlist: pointers now in
-  // cfgentries[]->names
-  devlist = FreeNonZero(devlist,(sizeof (char*) * num),__LINE__,__FILE__);
-  
-  return num;
-}
- 
-void CanNotRegister(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;
-}
-
-// returns -1 if config file had syntax errors, else number of entries
-// which may be zero or positive.  If we found no configuration file,
-// or it contained SCANDIRECTIVE, then *scanning is set to 1, else 0.
-int ReadOrMakeConfigEntries(int *scanning){
-  int entries;
-  
-  // deallocate any cfgfile data structures in memory
-  RmAllConfigEntries();
-  
-  // parse configuration file configfile (normally /etc/smartd.conf)  
-  if ((entries=ParseConfigFile())<0) {
- 
-    // There was an error reading the configuration file.
-    RmAllConfigEntries();
-    PrintOut(LOG_CRIT, "Configuration file %s has fatal syntax errors.\n", configfile);
-    return -1;
-  }
-
-  // did we find entries or scan?
-  *scanning=0;
-  
-  // no error parsing config file.
-  if (entries) {
-    // we did not find a SCANDIRECTIVE and did find valid entries
-    PrintOut(LOG_CRIT, "Configuration file %s parsed.\n", configfile);
-  }
-  else if (cfgentries[0]) {
-    // we found a SCANDIRECTIVE or there was no configuration file so
-    // scan.  Configuration file's first entry contains all options
-    // that were set
-    cfgfile *first=cfgentries[0];
-    int doata = first->tryata;
-    int doscsi= first->tryscsi;
-    
-    *scanning=1;
-    
-    if (first->lineno)
-      PrintOut(LOG_INFO,"Configuration file %s was parsed, found %s, scanning devices\n", configfile, SCANDIRECTIVE);
-    else
-      PrintOut(LOG_INFO,"No configuration file %s found, scanning devices\n", configfile);
-    
-    // make config list of ATA devices to search for
-    if (doata)
-      entries+=MakeConfigEntries("ATA", entries);
-    // make config list of SCSI devices to search for
-    if (doscsi)
-      entries+=MakeConfigEntries("SCSI", entries);
-  } 
-  else
-    PrintOut(LOG_CRIT,"Configuration file %s parsed but has no entries (like /dev/hda)\n",configfile);
-  
-  return entries;
-}
-
-
-// This function tries devices from cfgentries.  Each one that can be
-// registered is moved onto the [ata|scsi]devices lists and removed
-// from the cfgentries list, else it's memory is deallocated.
-void RegisterDevices(int scanning){
-  int i;
-  
-  // start by clearing lists/memory of ALL existing devices
-  RmAllDevEntries();
-  numdevata=numdevscsi=0;
-  
-  // Register entries
-  for (i=0; cfgentries[i] && i<MAXENTRIES ; i++){
-    
-    cfgfile *ent=cfgentries[i];
-    
-    // register ATA devices
-    if (ent->tryata){
-      if (ATADeviceScan(ent))
-	CanNotRegister(ent->name, "ATA", ent->lineno, scanning);
-      else {
-	// move onto the list of ata devices
-	cfgentries[i]=NULL;
-	atadevlist[numdevata++]=ent;
-      }
-    }
-    
-    // then register SCSI devices
-    if (ent->tryscsi){
-      int retscsi=0;
-
-#if SCSITIMEOUT
-      struct sigaction alarmAction, defaultaction;
-
-      // Set up an alarm handler to catch USB devices that hang on
-      // SCSI scanning...
-      alarmAction.sa_handler= AlarmHandler;
-      alarmAction.sa_flags  = SA_RESTART;
-      if (sigaction(SIGALRM, &alarmAction, &defaultaction)) {
-	// if we can't set timeout, just scan device
-	PrintOut(LOG_CRIT, "Unable to initialize SCSI timeout mechanism.\n");
-	retscsi=SCSIDeviceScan(ent);
-      }
-      else {
-	// prepare return point in case of bad SCSI device
-	if (setjmp(registerscsienv))
-	  // SCSI device timed out!
-	  retscsi=-1;
-	else {
-	// Set alarm, make SCSI call, reset alarm
-	  alarm(SCSITIMEOUT);
-	  retscsi=SCSIDeviceScan(ent);
-	  alarm(0);
-	}
-	if (sigaction(SIGALRM, &defaultaction, NULL)){
-	  PrintOut(LOG_CRIT, "Unable to clear SCSI timeout mechanism.\n");
-	}
-      }
-#else
-      retscsi=SCSIDeviceScan(ent);
-#endif   
-
-      // Now scan SCSI device...
-      if (retscsi){
-	if (retscsi<0)
-	  PrintOut(LOG_CRIT, "Device %s timed out (poorly-implemented USB device?)\n", ent->name);
-	CanNotRegister(ent->name, "SCSI", ent->lineno, scanning);
-      }
-      else {
-	// move onto the list of scsi devices
-	cfgentries[i]=NULL;
-	scsidevlist[numdevscsi++]=ent;
-      }
-    }
-    
-    // if device is explictly listed and we can't register it, then
-    // exit unless the user has specified that the device is removable
-    if (cfgentries[i]  && !scanning){
-      if (ent->removable || quit==2)
-	PrintOut(LOG_INFO, "Device %s not available\n", ent->name);
-      else {
-	PrintOut(LOG_CRIT, "Unable to register device %s (no Directive -d removable). Exiting.\n", ent->name);
-	EXIT(EXIT_BADDEV);
-      }
-    }
-    
-    // free up memory if device could not be registered
-    RmConfigEntry(cfgentries+i, __LINE__);
-  }
-  
-  return;
-}
-
-int main(int argc, char **argv){
-
-  // external control variables for ATA disks
-  smartmonctrl control;
-
-  // is it our first pass through?
-  int firstpass=1;
-
-  // next time to wake up
-  time_t wakeuptime;
-
-  // for simplicity, null all global communications variables/lists
-  con=&control;
-  memset(con,        0,sizeof(control));
-  memset(atadevlist, 0,sizeof(cfgfile *)*MAXATADEVICES);
-  memset(scsidevlist,0,sizeof(cfgfile *)*MAXSCSIDEVICES);
-  memset(cfgentries, 0,sizeof(cfgfile *)*MAXENTRIES);
-
-  // 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;
-  
-  // don't exit on bad checksums
-  con->checksumfail=0;
-  
-  // the main loop of the code
-  while (1){
-
-    // Should we (re)read the config file?
-    if (firstpass || caughtsigHUP){
-      int entries, scanning=0;
-
-      if (!firstpass)
-	PrintOut(LOG_INFO,
-		 caughtsigHUP==1?
-		 "Signal HUP - rereading configuration file %s\n":
-		 "\a\nSignal INT - rereading configuration file %s (CONTROL-\\ quits)\n\n",
-		 configfile);
-      
-      // clears cfgentries, (re)reads config file, makes >=0 entries
-      entries=ReadOrMakeConfigEntries(&scanning);
-
-      // checks devices, then moves onto ata/scsi list or deallocates.
-      if (entries>=0 || quit==4)
-	RegisterDevices(scanning);
-      
-      if (entries<0 && quit==4)
-	EXIT(EXIT_BADCONF);
-
-      // Log number of devices we are monitoring...
-      if (numdevata+numdevscsi || quit==2 || (quit==1 && !firstpass))
-	PrintOut(LOG_INFO,"Monitoring %d ATA and %d SCSI devices\n",
-		 numdevata, numdevscsi);
-      else {
-	PrintOut(LOG_INFO,"Unable to monitor any SMART enabled devices. Exiting...\n");
-	EXIT(EXIT_NODEV);
-      }	  
-      
-      // reset signal
-      caughtsigHUP=0;
-    }
-
-    // check all devices once
-    CheckDevicesOnce(atadevlist, scsidevlist); 
-    
-    // user has asked us to exit after first check
-    if (quit==3) {
-      PrintOut(LOG_INFO,"Started with '-q onecheck' option. All devices sucessfully checked once.\n"
-	       "smartd is exiting (exit status 0)\n");
-      EXIT(0);
-    }
-    
-    // fork into background if needed
-    if (firstpass && !debugmode)
-      DaemonInit();
-    
-    // set exit and signal handlers, write PID file, set wake-up time
-    if (firstpass){
-      Initialize(&wakeuptime);
-      firstpass=0;
-    }
-    
-    // sleep until next check time, or a signal arrives
-    wakeuptime=dosleep(wakeuptime);
-  }
-}
diff --git a/sm5/utility.cpp b/sm5/utility.cpp
deleted file mode 100644
index 5ad61d4f82192d42c198108397c0948d144ece83..0000000000000000000000000000000000000000
--- a/sm5/utility.cpp
+++ /dev/null
@@ -1,416 +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 <syslog.h>
-#include <stdarg.h>
-#include "utility.h"
-#include "config.h"
-
-// Any local header files should be represented by a CVSIDX just below.
-const char* utility_c_cvsid="$Id: utility.cpp,v 1.27 2003/10/21 01:45:50 arvoreen Exp $" CONFIG_H_CVSID UTILITY_H_CVSID;
-
-const char * packet_types[] = {
-        "Direct-access (disk)",
-        "Sequential-access (tape)",
-        "Printer",
-        "Processor",
-        "Write-once (optical disk)",
-        "CD/DVD",
-        "Scanner",
-        "Optical memory (optical disk)",
-        "Medium changer",
-        "Communications",
-        "Graphic arts pre-press (10)",
-        "Graphic arts pre-press (11)",
-        "Array controller",
-        "Enclosure services",
-        "Reduced block command (simplified disk)",
-        "Optical card reader/writer"
-};
-
-// Whenever exit() status is EXIT_BADCODE, please print this message
-const char *reportbug="Please report this bug to the Smartmontools developers at " PACKAGE_BUGREPORT ".\n";
-
-
-// hang on to exit code, so we can make use of more generic 'atexit()'
-// functionality and still check our exit code
-int exitstatus = 0;
-
-// command-line argument: are we running in debug mode?.
-unsigned char debugmode = 0;
-
-
-// This value follows the peripheral device type value as defined in
-// SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in
-// the ATA standard for packet devices to define the device type.
-const char *packetdevicetype(int type){
-  if (type<0x10)
-    return packet_types[type];
-  
-  if (type<0x20)
-    return "Reserved";
-  
-  return "Unknown";
-}
-
-
-// Returns 1 if machine is big endian, else zero.  This is a run-time
-// rather than a compile-time function.  We could do it at
-// compile-time but in principle there are architectures that can run
-// with either byte-ordering.
-int isbigendian(){
-  short i=0x0100;
-  char *tmp=(char *)&i;
-  return *tmp;
-}
-
-#define DBLEN 64
-
-// 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[DBLEN];
-  
-  // Get the time structure.  We need this to determine if we are in
-  // daylight savings time or not.
-  tmval=localtime(&tval);
-  
-  // Convert to an ASCII string, put in datebuffer
-  // same as: asctime_r(tmval, datebuffer);
-  strncpy(datebuffer, asctime(tmval), DBLEN);
-  datebuffer[DBLEN-1]='\0';
-  
-  // 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, DBLEN, "%s %s", datebuffer, timezonename);
-  
-  return;
-}
-
-// Date and timezone gets printed into string pointed to by buffer
-void dateandtimezone(char *buffer){
-  
-  // Get the epoch (time in seconds since Jan 1 1970)
-  time_t tval=time(NULL);
-  
-  dateandtimezoneepoch(buffer, tval);
-  return;
-}
-
-// These are two utility functions for printing CVS IDs. Massagecvs()
-// returns distance that it has moved ahead in the input string
-int massagecvs(char *out, const char *cvsid){
-  char *copy,*filename,*date,*version;
-  int retVal=0;
-  const char delimiters[] = " ,$";
-
-  // make a copy on the heap, go to first token,
-  if (!(copy=strdup(cvsid)))
-    return 0;
-
-  if (!(filename=strtok(copy, delimiters))){
-    free(copy);
-    return 0;
-  }
-
-  // move to first instance of "Id:"
-  while (strcmp(filename,"Id:"))
-    if (!(filename=strtok(NULL, delimiters))){
-      free(copy);
-      return 0;
-    }
-  
-  // get filename, skip "v", get version and date
-  if (!(  filename=strtok(NULL, delimiters)  ) ||
-      !(           strtok(NULL, delimiters)  ) ||
-      !(   version=strtok(NULL, delimiters)  ) ||
-      !(      date=strtok(NULL, delimiters)  ) ) {
-    free(copy);
-    return 0;
-  }
-  
-  sprintf(out,"%-13s revision: %-6s date: %-15s", filename, version, date);
-  retVal = (date-copy)+strlen(date);
-  free(copy);
-  return  retVal;
-}
-
-// prints a single set of CVS ids
-void printone(char *block, const char *cvsid){
-  char strings[CVSMAXLEN];
-  const char *here=cvsid;
-  int line=1,len=strlen(cvsid)+1;
-
-  // check that the size of the output block is sufficient
-  if (len>=CVSMAXLEN) {
-    pout("CVSMAXLEN=%d must be at least %d\n",CVSMAXLEN,len+1);
-    EXIT(1);
-  }
-
-  // loop through the different strings
-  while ((len=massagecvs(strings,here))){
-    switch (line++){
-    case 1:
-      block+=snprintf(block,CVSMAXLEN,"Module:");
-      break;
-    default:
-      block+=snprintf(block,CVSMAXLEN,"  uses:");
-    } 
-    block+=snprintf(block,CVSMAXLEN," %s\n",strings);
-    here+=len;
-  }
-  return;
-}
-
-
-// A replacement for perror() that sends output to our choice of
-// printing.
-void syserror(const char *message){
-  const char *errormessage;
-  
-  // Get the correct system error message:
-  errormessage=strerror(errno);
-
-  // Check that caller has handed a sensible string, and provide
-  // appropriate output. See perrror(3) man page to understand better.
-    if (message && *message)
-      pout("%s: %s\n",message, errormessage);
-    else
-      pout("%s\n",errormessage);
-	
-    return;
-}
-
-// Prints a warning message for a failed regular expression compilation from
-// regcomp().
-void printregexwarning(int errcode, regex_t *compiled){
-  size_t length = regerror(errcode, compiled, NULL, 0);
-  char *buffer = malloc(length);
-  if (!buffer){
-    pout("Out of memory in printregexwarning()\n");
-    return;
-  }
-  regerror(errcode, compiled, buffer, length);
-  pout("%s\n", buffer);
-  free(buffer);
-  return;
-}
-
-// A wrapper for regcomp().  Returns zero for success, non-zero otherwise.
-int compileregex(regex_t *compiled, const char *pattern, int cflags)
-{ 
-  int errorcode;
-
-  if ((errorcode = regcomp(compiled, pattern, cflags))) {
-    pout("Internal error: unable to compile regular expression %s", pattern);
-    printregexwarning(errorcode, compiled);
-    pout("Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n");
-    return 1;
-  }
-  return 0;
-}
-
-// Splits an argument to the -r option into a name part and an (optional) 
-// positive integer part.  s is a pointer to a string containing the
-// argument.  After the call, s will point to the name part and *i the
-// integer part if there is one or 1 otherwise.  Note that the string s may
-// be changed by this function.  Returns zero if successful and non-zero
-// otherwise.
-int split_report_arg(char *s, int *i)
-{
-  if ((s = strchr(s, ','))) {
-    // Looks like there's a name part and an integer part.
-    char *tailptr;
-
-    *s++ = '\0';
-    if (*s == '0' || !isdigit((int)*s))  // The integer part must be positive
-      return 1;
-    errno = 0;
-    *i = (int) strtol(s, &tailptr, 10);
-    if (errno || *tailptr != '\0')
-      return 1;
-  } else {
-    // There's no integer part.
-    *i = 1;
-  }
-
-  return 0;
-}
-
-// same as above but sets *i to -1 if missing , argument
-int split_report_arg2(char *s, int *i){
-  char *tailptr;
-  s+=6;
-
-  if (*s=='\0' || !isdigit((int)*s)) { 
-    // What's left must be integer
-    *i=-1;
-    return 1;
-  }
-
-  errno = 0;
-  *i = (int) strtol(s, &tailptr, 10);
-  if (errno || *tailptr != '\0') {
-    *i=-1;
-    return 1;
-  }
-
-  return 0;
-}
-
-// Splits an argument to the -t option that is assumed to be of the form
-// "selective,%lld-%lld" (prefixes of "0" (for octal) and "0x"/"0X" (for hex)
-// are allowed).  The first long long int is assigned to *start and the second
-// to *stop.  Returns zero if successful and non-zero otherwise.
-int split_selective_arg(char *s, unsigned long long *start,
-                        unsigned long long *stop)
-{
-  char *tailptr;
-
-  if (!(s = strchr(s, ',')))
-    return 1;
-  if (!isdigit((int)(*++s)))
-    return 1;
-  errno = 0;
-  // Last argument to strtoull (the base) is 0 meaning that decimal is assumed
-  // unless prefixes of "0" (for octal) or "0x"/"0X" (for hex) are used.
-  *start = strtoull(s, &tailptr, 0);
-  s = tailptr;
-  if (errno || *s++ != '-')
-    return 1;
-  *stop = strtoull(s, &tailptr, 0);
-  if (errno || *tailptr != '\0')
-    return 1;
-  return 0;
-}
-
-long long bytes = 0;
-// Helps debugging.  If the second argument is non-negative, then
-// decrement bytes by that amount.  Else decrement bytes by (one plus)
-// length of null terminated string.
-void *FreeNonZero(void *address, int size, int line, char* file){
-  if (address) {
-    if (size<0)
-      bytes-=1+strlen(address);
-    else
-      bytes-=size;
-    return CheckFree(address, line,file);
-  }
-  return NULL;
-}
-
-// To help with memory checking.  Use when it is known that address is
-// NOT null.
-void *CheckFree(void *address, int whatline,char* file){
-  if (address){
-    free(address);
-    return NULL;
-  }
-  
-  PrintOut(LOG_CRIT, "Internal error in CheckFree() at line %d of file %s\n%s", 
-	   whatline, file, reportbug);
-  EXIT(EXIT_BADCODE);
-}
-
-
-// A custom version of strdup() that keeps track of how much memory is
-// being allocated. If mustexist is set, it also throws an error if we
-// try to duplicate a NULL string.
-char *CustomStrDup(char *ptr, int mustexist, int whatline, char* file){
-  char *tmp;
-
-  // report error if ptr is NULL and mustexist is set
-  if (ptr==NULL){
-    if (mustexist) {
-      PrintOut(LOG_CRIT, "Internal error in CustomStrDup() at line %d of file %s\n%s", 
-	       whatline, file, reportbug);
-      EXIT(EXIT_BADCODE);
-    }
-    else
-      return NULL;
-  }
-
-  // make a copy of the string...
-  tmp=strdup(ptr);
-  
-  if (!tmp) {
-    PrintOut(LOG_CRIT, "No memory to duplicate string %s\n", ptr);
-    EXIT(EXIT_NOMEM);
-  }
-  
-  // and track memory usage
-  bytes+=1+strlen(ptr);
-  
-  return tmp;
-}
-
-// 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;
-}
diff --git a/www/3w-xxxx.txt b/www/3w-xxxx.txt
deleted file mode 100644
index 773d62930b7e4b7d95d083a05313aec85e8d38d9..0000000000000000000000000000000000000000
--- a/www/3w-xxxx.txt
+++ /dev/null
@@ -1,110 +0,0 @@
----------------------------------------------------------------------------
-# August 14, 2003
-#
-# Adam Radford has incorporated a change that now allows the 3w-xxxx
-# driver to return the Cylinder Low/High values.  These are needed to
-# get the SMART health status.  This patch incorporates those changes
-# as well.
-#
-# August 12, 2003
-#
-# 3ware has incorporated a more general version of this fix into their latest
-# 3w-xxxx driver release. Rather than using this patch, you can upgrade your 
-# 3w-xxxx driver to version 1.02.00.037 or greater.  Or you can use this patch.
-#
-# August 8, 2003
-# PATCH FOR 3WARE 3w-xxxx DRIVER
-# Bruce Allen ballen at gravity.phys.uwm.edu
-# CVS ID of this file: $Id: 3w-xxxx.txt,v 1.3 2003/08/14 14:56:07 ballen4705 Exp $
-# 
-# To apply this patch, save this entire file to 3w-xxxx.txt in a
-# directory containing the original unpatched 3w-xxxx.c file. Then
-# given the command:
-#                     patch < 3w-xxxx.txt
-# That's it!
-#
-# TECHNICAL EXPLANATION OF THE PATCH FOLLOWS.  SKIP IT IF YOU DON'T CARE.
-#
-# The 3w-xxxx SCSI RAID driver for 3ware Escalade controller cards has a bug
-# in the "passthru" ioctl() which prevents two SMART commands from being
-# passed to the ATA devices behind the controller. The commands are:
-# 
-#  SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE 
-#  (Command Register=0xB0/Feature Register=0xD2)
-# 
-#  SMART ENABLE/DISABLE AUTOMATIC OFF-LINE
-#  (Command Register=0xB0/Feature Register=0xDB)
-# 
-# [Note: the second of these commands is listed as "Obsolete" in the ATA
-# specifications.  It was originally defined in SFF-8035i.  Most vendors
-# (IBM/Hitachi, Maxtor, Samsung, WD, among others) still implement it for
-# backwards compatibility.]
-# 
-# The problem arises because in both cases (stupidly!) the ENABLE subcommand
-# is indicated with a nonzero value of the Sector Count Register.  For the
-# AUTOSAVE command one uses Sector Count Register=0xF1 and for the AUTOMATIC
-# OFF-LINE command one uses Sector Count Register=0xF8.
-# 
-# This provokes the following error messages from the 3w-xxxx driver:
-#   3w-xxxx: tw_ioctl(): Passthru size (123392) too big.
-#   3w-xxxx: tw_ioctl(): Passthru size (126976) too big.
-# and the driver doesn't pass the ATA command on.  This is because the
-# passthru part of the 3w-xxxx driver assumes that the value in the Sector
-# Count Register is the number of 512-byte blocks to transfer, and these
-# values exceed the internal buffer sizes.
-# 
-# In fact both of these are non-data commands, and so this is trivial to
-# fix.  I am attaching an 8-line patch for this purpose.  It looks for these
-# particular commands and then treats them as non-data commands. It has been
-# tested on both a 6800 and a 7500 controller, and should be endian-order
-# and 32/64-bit clean.
-# 
-# [Note: the normal linux ide drivers also assume that the Sector Count
-# Register is the number of 512-byte sectors to transfer to user space.  
-# But in that case the user can simply allocate a userland buffer large
-# enough to hold the 0xf1*0x200 or 0xf8*0x200 bytes, and then ignore the
-# contents.]
-#
-# -----------------------------------------------------------------------
-
---- 3w-xxxx.c.save	Thu Aug 14 16:28:35 2003
-+++ 3w-xxxx.c	Thu Aug 14 16:44:04 2003
-@@ -1915,12 +1915,15 @@
- 			}
- 
- 			passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
--			passthru->sg_list[0].length = passthru->sector_count*512;
--			if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
--				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
--				return 1;
-+			/* Don't load sg_list for non-data ATA cmds */
-+			if ((passthru->param != 0) && (passthru->param != 0x8)) {
-+				passthru->sg_list[0].length = passthru->sector_count*512;
-+				if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
-+					printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
-+					return 1;
-+				}
-+				passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
- 			}
--			passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
- 			tw_post_command_packet(tw_dev, request_id);
- 			return 0;
- 		case TW_CMD_PACKET:
-@@ -2170,8 +2173,15 @@
- 	ioctl = (TW_Ioctl *)buff;
- 	switch (ioctl->opcode) {
- 		case TW_ATA_PASSTHRU:
--			passthru = (TW_Passthru *)ioctl->data;
--			memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
-+		        passthru = (TW_Passthru *)ioctl->data;
-+			/* Don't return data for non-data ATA cmds */
-+			if ((passthru->param != 0) && (passthru->param != 0x8))
-+				memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
-+			else {
-+			/* For non-data cmds, return cmd pkt */
-+				if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command))
-+					memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
-+			}
- 			break;
- 		case TW_CMD_PACKET_WITH_DATA:
- 			dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
diff --git a/www/FAQ.xml b/www/FAQ.xml
deleted file mode 100644
index 51fd9fbbd56e1bc1cdc6e5504cfa9dfe6b6e8923..0000000000000000000000000000000000000000
--- a/www/FAQ.xml
+++ /dev/null
@@ -1,543 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" >
-
-<!--
-Layout borrowed from Doug's smartmontools_scsi.xml.  The following text
-is also from his file.
-
-This is DocBook XML that can be rendered into a single HTML page with a
-command like 'xmlto html-nochunks <this_file_name>'.  It can also be
-rendered into multi-page HTML (drop the "-nochunks") or pdf, ps, txt,
-etc.
--->
-
-<article id="index">
- <articleinfo>
-   <title>FAQ - Frequently Asked Questions</title>
-   <author>
-    <firstname>smartmontools</firstname>
-    <surname>developers</surname>
-    <affiliation>
-     <address>
-      <email>smartmontools-support@lists.sourceforge.net</email>
-     </address>
-    </affiliation>
-   </author>
-  <authorinitials>sd</authorinitials>
-  <pubdate>2003-09-24</pubdate>
-
-  <revhistory>
-     <revision>
-       <revnumber>1.0</revnumber>
-       <date>2003-10-22</date>
-       <authorinitials>sd</authorinitials>
-       <revremark>
-             Moved from index.html to XML
-       </revremark>
-     </revision>
-  </revhistory>
-
-  <copyright>
-   <year>2003</year>
-   <holder>Bruce Allen</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-      Permission is granted to copy, distribute and/or modify this
-      document under the terms of the GNU Free Documentation License,
-      Version 1.1 or any later version published by the Free Software
-      Foundation; with no Invariant Sections, with no Front-Cover Texts,
-      and with no Back-Cover Texts.
-   </para>
-   <para>
-    For an online copy of the license see
-    <ulink url="http://www.fsf.org/copyleft/fdl.html">
-    <literal>http://www.fsf.org/copyleft/fdl.html</literal></ulink> .
-   </para>
-
-  </legalnotice>
-
-  <abstract>
-  <para>
-   FAQ - Frequently Asked Questions
-  </para>
-  </abstract>
- </articleinfo>
-
-<!--
-<toc></toc>
--->
-
-
-<sect1 id="a">
-
-<title>What do I do if I have problems, or need support?  Suppose I want
-to become a developer, or suggest some new extensions?</title>
-
-<para>First, search the support mailing list archives to see if your
-question has been answered.  Instructions are in the following
-paragraph.  If you don't find an answer there, then please send an
-e-mail to the smartmontools-support mailing list.  Instructions are
-available at <ulink url="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">
-<literal>http://lists.sourceforge.net/mailman/listinfo/smartmontools-support</literal></ulink>
-. The list is moderated but you're not required to subscribe to it in
-order to post your question.</para>
-
-<para>To search the archives, first go to <ulink url="http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support">
-<literal>http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support</literal></ulink>
-. In the top left corner you will see a search box: use <emphasis
-role="bold">Mailing List</emphasis> as the type of search.  This tool
-works very well.</para>
-
-<para>Note that from time to time SourceForge has mailing problems and
-you'll get a message telling you that <emphasis role="italic">Either
-your mailing list name was misspelled or your mailing list has not been
-archived yet.  If this list has just been created, please retry in 2-4
-hours</emphasis>.  If this happens, you'll have to try again
-later.</para>
-
-</sect1>
-
-<sect1 id="b">
-
-<title>What are the future plans for smartmontools?</title>
-
-<para>My plan is that smartmontools-5.x will support ATA/ATAPI-5 disks. 
-Eventually, we'll do smartmontools-6.x to support ATA/ATAPI-6 disks,
-smartmontools-7.x for the ATA/ATAPI-7 standard, and so on.  The "x" will
-denote revision level, as bugs get found and fixed, and as enhancements
-get added.  If it's possible to maintain backwards compatibility, that
-would be nice, but I don't know if it will be possible or
-practical.</para>
-
-</sect1>
-
-<sect1 id="c">
-
-<title>Why are you doing this?</title>
-
-<para>My research group at U. Wisconsin - Milwaukee runs a beowulf
-cluster -  <ulink url="http://www.lsc-group.phys.uwm.edu/beowulf/medusa/">
-<literal>http://www.lsc-group.phys.uwm.edu/beowulf/medusa/</literal></ulink>
--  with 600 ATA-5 and -6 disks (300 IBM and 300 Maxtor).  We have more
-than 50 TB of data stored on the system.  I also help out with a cluster
--  <ulink url="http://pandora.aei.mpg.de/merlin/">
-<literal>http://pandora.aei.mpg.de/merlin/</literal></ulink> -  at the
-Albert Einstein Institute that has another 300 IBM ATA-6 disks (36 TB
-total).  It's nice to have advanced warning when a disk is going to
-fail.</para>
-
-</sect1>
-
-<sect1 id="d">
-
-<title>I see some strange output from smartctl.  What does it
-mean?</title>
-
-<para>The raw S.M.A.R.T. attributes (temperature, power-on lifetime, and
-so on) are stored in vendor-specific structures.  Sometime these are
-strange.  Hitachi disks (at least some of them) store power-on lifetime
-in minutes, rather than hours (see next question below).  IBM disks (at
-least some of them) have three temperatures stored in the raw structure,
-not just one.  And so on.  If you find strange output, or unknown
-attributes, please send an e-mail to the mailing list and we'll help you
-try and figure it out.</para>
-
-</sect1>
-
-<sect1 id="e">
-
-<title>What Kernel Version is needed? (Linux)</title>
-
-<para>Kernel versions 2.4.0 or later should work.  We recommend the
-latest 2.4 kernel.</para>
-
-<para>Vanilla kernel.org 2.2.X kernels do not support the
-HDIO_DRIVE_TASK ioctl(), which is needed for the ATA drive to execute
-the ATA SMART RETURN STATUS command.  So these kernels will not
-work.</para>
-
-<para>Vendor-supplied 2.2.X kernels, and vanilla 2.2.X kernels patched
-with Andre Hedrick's IDE patches -  <ulink url="http://www.funet.fi/pub/linux/kernel/people/hedrick/ide-2.2.20/">
-<literal>http://www.funet.fi/pub/linux/kernel/people/hedrick/ide-2.2.20/</literal></ulink>
-(also available from your local kernel.org mirror, not updated for
-2.2.21 or later, and probably still containing a few bugs) may support
-the needed ioctl().</para>
-
-<para>If the configuration option CONFIG_IDE_TASK_IOCTL exists in your
-2.2.X kernel source code tree, then your 2.2.X kernel will probably
-support smartmontools.  Note that this kernel configuration option does
-<emphasis role="italic">not</emphasis> need to be enabled.  Its presence
-merely indicates that the required HDIO_DRIVE_TASK ioctl() is
-supported.</para>
-
-</sect1>
-
-<sect1 id="f">
-
-<title>What attributes does smartmontools not yet recognize?</title>
-
-<para>From Maxtor disks (99), (100), (101)</para>
-
-<para>If you can attach names/meanings to these attributes, please send
-a note to the mailing list.  If you have access to other SMART utilities
-(especially manufacturer-specific ones, see below) and can send us
-comparison output from smartctl and the other utility, that's especially
-useful.</para>
-
-</sect1>
-
-<sect1 id="g">
-
-<title>My Maxtor/Hitachi/Fujitsu disk is only a few days old, yet
-smartctl reports its age (Attribute 9) as thousands of hours!</title>
-
-<para>On some recent disks, Maxtor has started to use Attribute 9 to
-store the lifetime in minutes rather than hours.  In this case, use the
--m option (smartctl versions 5.0.X) or the --vendorattribute=9,minutes
-(smartctl 5.1.X) option to correctly display hours and minutes.</para>
-
-<para>Some models of Fujitsu disks are known to use Attribute 9 for
-lifetime in seconds.  In that case, use the --vendorattribute=9,seconds
-option to correctly display hours, minutes and seconds.</para>
-
-</sect1>
-
-<sect1 id="h">
-
-<title>The power-on timer (Attribute 9 raw value) on my Maxtor disk acts
-strange.</title>
-
-<para>There are three related problems with Maxtor's SMART
-firmware:</para>
-
-<para><emphasis role="bold">1 - </emphasis>On some disks from 2001/2002,
-the raw value of Attribute 9 (Power On Time) is <emphasis
-role="italic">supposed</emphasis> to be minutes. But it advances at an
-unpredictable rate, always more slowly than one count per minute.  One
-(unconfirmed) theory is that when the disk is in idle mode, the counter
-stops advancing.  This is only supposed to happen in standby
-mode.</para>
-
-<para><emphasis role="bold">2 - </emphasis> In Maxtor disks that use the
-raw value of Attribute 9 as a minutes counter, only two bytes (of the
-six available) are used to store the raw value.  So it resets to zero
-once every 65536=2^16 minutes, or about once every 1092 hours.  This is
-fixed in all Maxtor disks manufactured after July 2003, where the raw
-value was extended to four bytes.</para>
-
-<para><emphasis role="bold">3 - </emphasis> In Maxtor disks that use the
-raw value of Attribute 9 as a minutes counter, the hour time-stamps in
-the self-test and ATA error logs are calculated by right shifting 6
-bits.  This is equivalent to dividing by 64 rather than by 60.  As a
-result, the hour time-stamps in these logs advance 7% more slowly than
-they should.  Thus, if you do self-tests once per week at the same time,
-instead of the time-stamps being 168 hours apart, they are 157 hours
-apart.  This is also fixed in all Maxtor disks manufactured after July
-2003.</para>
-
-</sect1>
-
-<sect1 id="i">
-
-<title>Where can I find manufacturer-specific disk-testing
-utilities?</title>
-
-<para>A good listing of such utilities can be found at <ulink url="http://www.benchmarkhq.ru/english.html?/be_hdd2.html">
-<literal>http://www.benchmarkhq.ru/english.html?/be_hdd2.html</literal></ulink>
-. Unfortunately most of these are for MS operating systems, but most can
-be run from an MS-DOS boot disk.  Note: if you do run one of these
-utilities, and it identifies the meanings of any SMART Attributes that
-are not known to smartmontools, please report them to the mailing
-list.</para>
-
-<para>These utilities have an important role to fill.  If your disk has
-bad sectors (for example, as revealed by running self-tests with
-smartmontools) and the disk is not able to recover the data from those
-sectors, then the disk will <emphasis role="italic">not</emphasis>
-automatically reallocate those damaged sectors from its set of spare
-sectors, because forcing the reallocation to take place may entail some
-loss of data.  Because the commands that force such reallocation are
-<emphasis role="italic">Vendor Specific</emphasis>, most manufactuers
-provide a utility for this purpose.  It may cause data loss but can
-repair damaged sectors (at least, until it runs out of replacement
-sectors).</para>
-
-</sect1>
-
-<sect1 id="j">
-
-<title>When I run <emphasis role="tt">smartd</emphasis>,
-the SYSLOG <emphasis role="tt">/var/log/messages</emphasis> contains
-messages like this:</title>
-
-<programlisting>
-smartd: Reading Device /dev/sdv
-modprobe: modprobe: Can't locate module block-major-65
-</programlisting>
-
-<para>This is because when <emphasis role="tt">smartd</emphasis> starts,
-it looks for all ATA and SCSI devices to monitor (matching the pattern
-<emphasis role="tt">/dev/hd[a-z]</emphasis> or <emphasis
-role="tt">/dev/sd[a-z]</emphasis>).  The log messages appear because
-your system doesn't have most of these devices.</para>
-
-<para>Recent releases of smartd can use a configuration file <emphasis
-role="tt">smartd.conf</emphasis> to specify which devices to include or
-exclude from start-up search.</para>
-
-</sect1>
-
-<sect1 id="k">
-
-<title>What's the story on IBM SMART disks?</title>
-
-<para>Apparently some of the older SMART firmware on IBM disks can
-interfere with the regular operation of the disk.   If you have this
-problem, a firmware upgrade that fixes the problem is avaialable at
-<ulink url="http://www.geocities.com/dtla_update/">
-<literal>http://www.geocities.com/dtla_update/</literal></ulink>
-.</para>
-
-</sect1>
-
-<sect1 id="l">
-
-<title>How can I check that the package hasn't been tampered
-with?</title>
-
-<para>Since the <emphasis role="tt">smartmontools</emphasis> utilities
-run as root, you might be concerned about something harmful being
-embedded within them. Starting with release 5.19 of <emphasis
-role="tt">smartmontools</emphasis>, the .rpm files and tarball have been
-GPG signed.  (The tarball's fingerprint is given in the SoureForge
-Release Notes.) Please verify these using the GPG Signing Key available
-at <ulink url="http://smartmontools.sourceforge.net/SmartmontoolsSigningKey.txt">
-<literal>http://smartmontools.sourceforge.net/SmartmontoolsSigningKey.txt</literal></ulink>
-.</para>
-
-</sect1>
-
-<sect1 id="m">
-
-<title>Is there a bootable standalone CD or floppy that contains
-smartmontools?</title>
-
-<para>If you have a system that is showing signs of disk trouble (for
-example, it's unbootable and the console is full of disk error messages)
-it can be handy to have a version of smartmontools that can be run off
-of a bootable CD or floppy to examine the disk's SMART data and run
-self-tests.  This is also useful if you want to run Captive Self-Tests
-(the <emphasis role="bold"><emphasis role="tt">-C</emphasis></emphasis>
-option of <emphasis role="bold"><emphasis
-role="tt">smartctl</emphasis></emphasis> ) on disks that can not easily
-be unmounted, such as those hosting the Operating System files.  Or you
-can use this to run <emphasis role="tt">smartctl</emphasis> on computers
-that don't use Linux as the day-to-day Operating System.</para>
-
-<para>At present I am only aware of three such bootable disks:</para>
-
-<itemizedlist>
-<listitem>
-<para>LNX-BBC Bootable CD - <ulink url="http://www.lnx-bbc.org/">
-<literal>http://www.lnx-bbc.org/</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>Stresslinux Bootable CD - <ulink url="http://www.stresslinux.org/">
-<literal>http://www.stresslinux.org/</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>RIP (Recovery Is Possible) Bootable CD/Floppy - <ulink url="http://www.tux.org/pub/people/kent-robotti/looplinux/rip/">
-<literal>http://www.tux.org/pub/people/kent-robotti/looplinux/rip/</literal></ulink></para>
-</listitem>
-</itemizedlist>
-
-<para> Please let us know if there are others, and we'll add them to
-this list.</para>
-
-</sect1>
-
-<sect1 id="n">
-
-<title>Can I monitor ATA disks behind SCSI RAID controllers?</title>
-
-<para>From release 5.1-16, smartmontools supports 3ware SCSI RAID
-controllers that use ATA disks internally.  To pass commands through the
-3ware controller, use the smartmontools <emphasis role="bold">-d
-3ware,N</emphasis> option or Directive.</para>
-
-<para>In smartmontools release 5.1-16, the SMART HEALTH STATUS
-(smartmontools <emphasis role="bold">-H</emphasis>) is not returned
-correctly for 3ware devices.  In this release, the ENABLE AUTOMATIC
-OFFLINE and ENABLE ATTRIBUTE AUTOSAVE commands (smartmontools <emphasis
-role="bold">-o on</emphasis> and <emphasis role="bold">-S on</emphasis>)
-are <emphasis role="italic">disabled</emphasis> for 3ware devices,
-because at the time 5.1-16 was released, the 3w-xxxx driver could not
-pass these commands through to the ATA disks.</para>
-
-<para>Later smartmontools CVS code and releases <emphasis
-role="italic">do</emphasis> correctly support <emphasis
-role="italic">all</emphasis> of these commands.  You may:</para>
-
-<itemizedlist>
-<listitem>
-<para>Use version <emphasis role="bold">1.02.00.037</emphasis> or
-greater of the 3w-xxxx driver, or</para>
-</listitem>
-
-<listitem>
-<para>Patch earlier 3ware 3w-xxxx drivers with <ulink url="http://smartmontools.sourceforge.net/3w-xxxx.txt">
-<literal>http://smartmontools.sourceforge.net/3w-xxxx.txt</literal></ulink>
-so that these commands reach the disks, or</para>
-</listitem>
-
-<listitem>
-<para>Use an <emphasis role="bold">unpatched</emphasis> earlier 3w-xxxx
-driver (which won't pass these commands to the disks but will instead
-print harmless warning messages to SYSLOG).</para>
-</listitem>
-</itemizedlist>
-
-<para>Since smartmontools 3ware support is new, please report positive
-or negative experiences to the mailing list, particularly for 64-bit
-and/or big-endian architectures.</para></sect1>
-
-<sect1 id="o">
-
-<title>SCSI disks and tapes (TapeAlert)</title>
-
-<para>smartmontools for SCSI disks and tapes (including medium changers)
-is discussed at <ulink url="http://smartmontools.sourceforge.net/smartmontools_scsi.html">
-<literal>http://smartmontools.sourceforge.net/smartmontools_scsi.html</literal></ulink>
-.</para>
-
-</sect1>
-
-<sect1 id="p">
-
-<title>FireWire, USB, and SATA disks/systems</title>
-
-<para>As for USB and FireWire (ieee1394) disks and tape drives, the news
-isn't good.  They appear to Linux as SCSI devices but their
-implementations do not usually support those SCSI commands needed by
-smartmontools.  The ieee1394 consortium recently certified the first
-external enclosure (containing a ATA disk and a protocol bridge) as
-being compliant to the relevant standards.  Such devices have already
-been on the market for about 3  years and they tend to only support the
-bare minimum of commands needed for device operation (i.e. S.M.A.R.T.
-support is an unsupported extra).</para>
-
-<para>I'd be very grateful to find someone who could help me test the
-smartmontools code on serial ATA (SATA) disks.  They should appear as
-normal ATA disks in Linux.</para>
-
-</sect1>
-
-<sect1 id="q">
-
-<title>How does smartmontools differ from smartsuite?</title>
-
-<para>The smartsuite code was originally developed as a Senior Thesis by
-Michael Cornwell at the Concurrent Systems Laboratory (now part of the
-Storage Systems Research Center - <ulink url="http://ssrc.soe.ucsc.edu/">
-<literal>http://ssrc.soe.ucsc.edu/</literal></ulink>), Jack Baskin
-School of Engineering, University of California, Santa Cruz.  You can
-find some information about the original smartsuite project here:</para>
-
-<itemizedlist>
-<listitem>
-<para>Press Release 1 - <ulink url="http://www.ucsc.edu/news_events/press_releases/archive/99-00/09-99/smart_software.htm">
-<literal>http://www.ucsc.edu/news_events/press_releases/archive/99-00/09-99/smart_software.htm</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>Press Release 2 - <ulink url="http://www.santa-cruz.com/archive/1999/September/22/local/stories/5local.htm">
-<literal>http://www.santa-cruz.com/archive/1999/September/22/local/stories/5local.htm</literal></ulink></para>
-</listitem>
-
-<listitem>
-<para>Press Release 3 - <ulink url="http://www.ucsc.edu/currents/99-00/09-27/smart.html">
-<literal>http://www.ucsc.edu/currents/99-00/09-27/smart.html</literal></ulink></para>
-</listitem>
-</itemizedlist>
-
-<para>smartmontools was derived directly from smartsuite.  It differs
-from smartsuite in that it supports the ATA/ATAPI-5 standard.  So for
-example <emphasis role="tt">smartctl</emphasis> from smartsuite has no
-facility for printing the SMART self-test logs, and doesn't print
-timestamp information in the most usable way.</para>
-
-<para>The <emphasis role="tt">smartctl</emphasis> utility in
-smartmontools has added functionality for this (<emphasis role="tt">-q,
--l selftest,-S, -T, -v and -m</emphasis> options), updated
-documentation, and also fixes small technical bugs in smartsuite.  [One
-example: smartsuite does not actually use the ATA SMART RETURN STATUS
-command to find out the health status of a disk.  It instead tries to
-infer this from the SMART Attribute values.]  See <ulink url="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?rev=HEAD&amp;content-type=text/plain">
-<literal>http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?rev=HEAD&amp;content-type=text/plain</literal></ulink> for a summary of what's been done.</para>
-
-<para>The <emphasis role="tt">smartd</emphasis> utility differs from the
-smartsuite <emphasis role="tt">smartd</emphasis> in major ways.  First,
-it prints somewhat more informative error messages to the syslog. 
-Second, on startup it looks for a configuration file <emphasis
-role="tt">smartd.conf</emphasis>, and if <emphasis
-role="tt">smartd</emphasis> finds this file, it monitors the list of
-devices therein, rather than querying all IDE and SCSI devices on your
-system.  (If the configuration file does not exist, then it does query
-all IDE and SCSI devices.)  Also, it's a well-behaved daemon and doesn't
-leave open file descriptors and other detrius behind.</para>
-
-<para>In addition, the <emphasis role="tt">smartmontools</emphasis>
-version of <emphasis role="tt">smartd</emphasis> can be instructed (via
-Directives in the configuration file) to monitor for changes in a number
-of different disk properties: the SMART status, failure or prefailure
-attributes going below threshold, new errors appearing in the ATA Error
-Log or the SMART Self-Test Log, and so on. <emphasis
-role="tt">smartd</emphasis> can also send an e-mail warning or run a
-user-specified executable if it detects a problem with the disk.</para>
-
-<para>The other principle difference is that smartmontools is an
-OpenSource development project, meaning that we keep the files in CVS,
-and that  other developers who wish to contribute can commit changes to
-the archive.  If you would like to contribute, please write to the
-mailing-list.</para>
-
-<para>But the bottom line is that the code in smartmontools is derived
-directly from smartsuite and is similar.  The smartsuite package can be
-found at <ulink url="http://sourceforge.net/projects/smartsuite/">
-<literal>http://sourceforge.net/projects/smartsuite/</literal></ulink>
-.</para></sect1>
-
-<sect1 id="r">
-
-<title>Does it work on Windows?</title>
-
-<para>Currently not, but we consider Cygwin - <ulink url="http://www.cygwin.com/">
-<literal>http://www.cygwin.com/</literal></ulink> -  the way to go,
-where CVS compiles almost out of the box but still lacks any specific
-code to make it work.  Write to the mailing list if you're interested in
-porting it.  Someone already sent some S.M.A.R.T. code for Windows,
-which may be of use.  Porting to other platforms may be easier as well
-now that any Linux specific code (like linux/hdreg.h) has been removed,
-and more will be done soon in that direction.</para>
-
-<para>A Cygwin port would probably only require and additional DLL,
-cygwin1.dll, to run on plain Windows.</para></sect1>
-
-<sect1 id="s">
-
-<title>Why has the versioning scheme changed?</title>
-
-<para>With the move to GNU Autoconf and GNU Automake it changed from
-5.X-Y (where X and Y are one or more numbers) to 5.Y.  This had to be
-done because the -Y extension is used by distributions to almost always
-denote a new build of the same version. So, the first version with that
-change will be 5.19 and not 5.1-19.</para>
-
-</sect1>
-
-</article>
diff --git a/www/Makefile b/www/Makefile
deleted file mode 100644
index 999759089c3e386cbbc1965808b9ffe262a66b1a..0000000000000000000000000000000000000000
--- a/www/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Manufactures HTML file from XML file. Note: do NOT edit the HTML
-# file, only the XML file.
-
-all: smartmontools_scsi.html
-
-smartmontools_scsi.html: smartmontools_scsi.xml 
-	xmlto html-nochunks smartmontools_scsi.xml
-
-upload: smartmontools_scsi.html index.html
-	scp smartmontools_scsi.html ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
-	scp 3w-xxxx.txt ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
-	scp index.html ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs
-	scp examples/*.html ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs/examples
-	scp examples/*.txt ballen4705@smartmontools.sourceforge.net:/home/groups/s/sm/smartmontools/htdocs/examples
diff --git a/www/SmartmontoolsSigningKey.txt b/www/SmartmontoolsSigningKey.txt
deleted file mode 100644
index 0ac19356f748d2b5f81b33962e588e8af28fb16d..0000000000000000000000000000000000000000
--- a/www/SmartmontoolsSigningKey.txt
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.0.7 (GNU/Linux)
-
-mQGiBD9XAXIRBACgLEphBmhUKWE1mRKzjkq/8vZHtJsVUiFivcbxaSLa9jBbJoZV
-sQk5fdcleVE6CcuodMetVE6Gl8uM4W4iymp0i35lwefdgmUzJYmza1ZD7Uk0x4zv
-tKi9xZ9Hc+yrf4SHRwLTZxuUyLf9TURwGXfLd2bxP1USYJVL4vOYoiBwBwCgq/w3
-EyO5PhlGp5rfE+WIoyy9GHcEAIYP3ctigHu6tnSobIGA77BFOv+v7DbXRjbKhEz1
-s4lPGQQP5h2t4VFRiy9RlD4GlEXD51cRFMmtFk4cBbOuONQbNOJFQQ/9JpVBU6/O
-CZrVMUqDnQMd2mdUU8pxM7cguaw5cPFxqqX5dkW1JikGrlG1QsH5UxuYhdadO+al
-1fTnA/9RMRscXd6aAdN66pZ9mGoqIxVUO6N+icXO7DP+ArIt7gu4GLgvvARlgMiS
-neRV4g7mvLm41kBDEv5gug+h2ha5ZI+P51oSRYs8yA5fVtl0GA2YRA2QercALv6C
-CtAvnFXWFqSeyW1ESdd2zFKBjhXlBVkmujOyKDS6LXRpZjwJXrRWU21hcnRtb250
-b29scyBTaWduaW5nIEtleSAodGhyb3VnaCAyMDA0KSA8c21hcnRtb250b29scy1z
-dXBwb3J0QGxpc3RzLnNvdXJjZWZvcmdlLm5ldD6IZAQTEQIAJAUCP1cBcgIbAwUJ
-AnjQAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAjPh86m7GaIlTQAJ9IsqaxHbqX
-BSd+xfJwUAZyKWqyLwCgoa2rMvHAHa/Pvpt4E0i0xF9NW3yITAQTEQIADAUCP1cB
-+QWDAnjPeQAKCRARGZEEN/UVgWa7AJ95rEDeEw9G3uqAZO7L9u650QPX6wCgoHJ9
-Hq/akQJZhOgSKyrgVEyAc8S5AQ0EP1cBeBAEAMLXV8RwVFDs5EvfkQNwasoKNS+N
-PvvhO/weED188XklZ3QTiToEp2b4JFaoUkTk1l2f9JxagDPaVHR6XU8H740x25LZ
-gC6XObKMBxqJ9CrBLGcMt/bCugquDu18KFlL3Y1rq9uBxq9JS6CJthUzeaaFdFQS
-V7tF2+3hBz/Okqo7AAMFA/9l0YcKnTKDy8jdOtNjky1NEbaF1LjyRc4laT6N4O6q
-Xg2oGD6MgS7zSK/ORcT3B0T5kpTo6gnKLTYDxEAvpNjrOjlwn08Jtm3xrQZLId/W
-RAo+Qqn5Or+sugZZpQPHrGGB9TTc0AL3MfCbK4mlssVhS0SAq35E/osCLQcor7Sx
-sohPBBgRAgAPBQI/VwF4AhsMBQkCeNAAAAoJECM+HzqbsZoi4WUAn2IQhEtHY/48
-4rljbro8yUwYlrXzAJ44VfTwmjLlI9aoYdRW/cTtZ0tPgw==
-=f2kQ
------END PGP PUBLIC KEY BLOCK-----
diff --git a/www/cvs-script b/www/cvs-script
deleted file mode 100755
index 6974e72e239dd9bb9e8220f35c9237c7252d1f34..0000000000000000000000000000000000000000
--- a/www/cvs-script
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# execute this script in the current shell, using for example
-# . cvs_script
-unset CVS_SERVER
-export CVS_RSH=ssh
-export CVSROOT=:ext:ballen4705@cvs.smartmontools.sourceforge.net:/cvsroot/smartmontools
diff --git a/www/examples/FUJITSU1.txt b/www/examples/FUJITSU1.txt
deleted file mode 100644
index b10abf7a3b232514e1133510003645544d3ad932..0000000000000000000000000000000000000000
--- a/www/examples/FUJITSU1.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-[root/]# smartctl -v 9,seconds -v 200,writeerrorcount /dev/hda
-
-smartctl version 5.1-18 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     FUJITSU MHR2040AT
-Serial Number:    NJ41T291391J
-Firmware Version: 40BA
-Device is:        Not in smartctl database [for details use: -P showall]
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 1
-Local Time is:    Thu Sep  4 22:18:48 2003 CEST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-					Auto Off-line Data Collection: Disabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 ( 468) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine
-recommended polling time: 	 (  60) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000f   100   100   046    Pre-fail  Always       -       52685626284
-  2 Throughput_Performance  0x0005   100   100   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0003   093   093   025    Pre-fail  Always       -       24065
-  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       160
-  5 Reallocated_Sector_Ct   0x0033   099   099   024    Pre-fail  Always       -       31
-  7 Seek_Error_Rate         0x000f   100   100   047    Pre-fail  Always       -       131071
-  8 Seek_Time_Performance   0x0005   100   100   019    Pre-fail  Offline      -       0
-  9 Power_On_Seconds        0x0032   092   092   000    Old_age   Always       -       1335h+10m+34s
- 10 Spin_Retry_Count        0x0013   100   100   020    Pre-fail  Always       -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       150
-192 Power-Off_Retract_Count 0x0032   099   099   000    Old_age   Always       -       7
-193 Load_Cycle_Count        0x0032   074   074   000    Old_age   Always       -       95890
-194 Temperature_Celsius     0x0022   090   100   000    Old_age   Always       -       57
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       10141348
-196 Reallocated_Event_Count 0x0032   099   099   000    Old_age   Always       -       30
-197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
-200 Write_Error_Count       0x000f   036   033   060    Pre-fail  Always   FAILING_NOW 2883583
-203 Run_Out_Cancel          0x0002   091   091   000    Old_age   Always       -       2589872160305
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log structure revision number 1
-No self-tests have been logged
-
-
diff --git a/www/examples/HITACHI_DK23BA-20-0.txt b/www/examples/HITACHI_DK23BA-20-0.txt
deleted file mode 100644
index 13e9cb0122e0c6e4e072ddfc91efba9d9a4a3d19..0000000000000000000000000000000000000000
--- a/www/examples/HITACHI_DK23BA-20-0.txt
+++ /dev/null
@@ -1,163 +0,0 @@
-[root@ballen www]# /usr/sbin/smartctl -am /dev/hda
-
-smartctl version 5.0-25 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     HITACHI_DK23BA-20                       
-Serial Number:    12H7M8
-Firmware Version: 00E0A0D2
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-See vendor-specific Attribute list for marginal Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (1530) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  26) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000d   100   083   050    Pre-fail     -       677
-  3 Spin_Up_Time            0x0007   100   100   050    Pre-fail     -       0
-  4 Start_Stop_Count        0x0032   100   100   050    Old_age      -       249
-  5 Reallocated_Sector_Ct   0x0033   099   099   010    Pre-fail     -       30
-  7 Seek_Error_Rate         0x000f   100   100   050    Pre-fail     -       319
-  9 Power_On_Hours          0x0032   099   099   060    Old_age      -       701 h + 42 m
- 10 Spin_Retry_Count        0x0013   100   100   050    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   050    Old_age      -       249
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       15
-195 Hardware_ECC_Recovered  0x001a   100   001   050    Old_age  In_the_past 559
-196 Reallocated_Event_Count 0x0032   097   097   001    Old_age      -       30
-197 Current_Pending_Sector  0x0032   095   095   001    Old_age      -       5
-198 Offline_Uncorrectable   0x0010   095   095   001    Old_age      -       31
-199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age      -       0
-221 G-Sense_Error_Rate      0x000a   100   100   050    Old_age      -       0
-223 Load_Retry_Count        0x0012   100   100   050    Old_age      -       0
-225 Load_Cycle_Count        0x0032   095   095   050    Old_age      -       18446744072753281791
-230 Unknown_Attribute       0x0032   100   100   060    Old_age      -       18484
-250 Unknown_Attribute       0x000a   100   070   050    Old_age      -       601
-
-SMART Error Log Version: 1
-ATA Error Count: 9 (device log contains only the most recent five errors)
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:01 SN:15 CL:be CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   01   15   be   2e    e0   c8     831.599
- 00   00   01   14   be   2e    e0   c8     831.594
- 00   00   01   13   be   2e    e0   c8     831.594
- 00   00   01   12   be   2e    e0   c8     831.594
- 00   00   01   11   be   2e    e0   c8     831.594
-
-Error 2 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:45 SN:15 CL:be CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   80   da   bd   2e    e0   c8     829.680
- 00   00   80   5a   bd   2e    e0   c8     829.677
- 00   00   80   da   bc   2e    e0   c8     829.673
- 00   00   80   5a   bc   2e    e0   c8     829.671
- 00   00   01   58   bc   2e    e0   c8     829.671
-
-Error 3 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:01 SN:47 CL:bc CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   01   47   bc   2e    e0   c8     826.962
- 00   00   01   46   bc   2e    e0   c8     826.961
- 00   00   01   45   bc   2e    e0   c8     826.961
- 00   00   01   44   bc   2e    e0   c8     826.961
- 00   00   01   43   bc   2e    e0   c8     826.961
-
-Error 4 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:13 SN:47 CL:bc CH:2e D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   80   da   bb   2e    e0   c8     825.038
- 00   00   80   5a   bb   2e    e0   c8     825.033
- 00   00   80   da   ba   2e    e0   c8     825.030
- 00   00   80   5a   ba   2e    e0   c8     824.940
- 00   00   80   da   b9   2e    e0   c8     824.937
-
-Error 5 occurred at disk power-on lifetime: 458 hours
-When the command that caused the error occurred, the device was active or idle.
-After command completion occurred, registers were:
-ER:40 SC:01 SN:85 CL:19 CH:2c D/H:e0 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   00   01   85   19   2c    e0   c8     816.487
- 00   00   01   84   19   2c    e0   c8     816.487
- 00   00   01   83   19   2c    e0   c8     816.486
- 00   00   01   82   19   2c    e0   c8     816.486
- 00   00   01   81   19   2c    e0   c8     816.486
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed                     00%       691         
-# 2  Extended off-line   Completed: read failure       40%       661         0x002c1985
-# 3  Extended off-line   Completed: read failure       40%       661         0x002c1985
-# 4  Short off-line      Completed                     00%       660         
-# 5  Extended off-line   Completed: read failure       40%       658         0x002c1985
-# 6  Short off-line      Completed                     00%       658         
-# 7  Short off-line      Completed                     00%       658         
-# 8  Extended off-line   Completed: read failure       40%       658         0x002c1985
-# 9  Extended off-line   Completed: read failure       40%       657         0x002c1985
-#10  Short off-line      Completed                     00%       647         
-#11  Short off-line      Completed                     00%       587         
-#12  Short off-line      Completed                     00%       583         
-#13  Short off-line      Completed                     00%       551         
-#14  Short captive       Interrupted (host reset)      40%       551         
-#15  Short off-line      Completed                     00%       551         
-#16  Extended off-line   Completed: read failure       40%       550         0x002c1985
-#17  Extended off-line   Aborted by host               50%       550         
-#18  Short off-line      Completed                     00%       550         
-#19  Short off-line      Completed                     00%       537         
-#20  Extended off-line   Completed: read failure       40%       536         0x002c1985
-#21  Short off-line      Completed                     00%       536         
diff --git a/www/examples/IC35L120AVV207-0.txt b/www/examples/IC35L120AVV207-0.txt
deleted file mode 100644
index 4e43e8c2d0976622c07e0e0cddc4507716f5cca6..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVV207-0.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-# smartctl -a /dev/hda
-smartctl version 5.0-45 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVV207-0                        
-Serial Number:    VNVD02G4G4BDEG
-Firmware Version: V24OA63A
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 3a
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (2855) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  48) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   060    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0007   102   102   024    Pre-fail     -       16974103
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age      -       14
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   020    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   100   100   000    Old_age      -       242
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       14
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       24
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age      -       24
-194 Temperature_Celsius     0x0002   203   203   000    Old_age      -       27 (Lifetime Min/Max 20/37)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%        54         
diff --git a/www/examples/IC35L120AVVA07-0-0.txt b/www/examples/IC35L120AVVA07-0-0.txt
deleted file mode 100644
index 57926ccfba480e32daeec54bd0011e23ffdfc5e3..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVVA07-0-0.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVVA07-0                        
-Serial Number:    VNC605A6GG8W8A
-Firmware Version: VA6OA52A
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (3399) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  57) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   060    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   147   147   050    Pre-fail     -       266
-  3 Spin_Up_Time            0x0007   093   093   024    Pre-fail     -       23593335
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age      -       13
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   138   138   020    Pre-fail     -       30
-  9 Power_On_Hours          0x0012   100   100   000    Old_age      -       554
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       13
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       36
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age      -       36
-194 Temperature_Centigrade  0x0002   183   183   000    Old_age      -       30 (Lifetime Min/Max 23/39)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%       492         
-# 2  Short off-line      Completed                     00%       296         
-# 3  Extended off-line   Completed                     00%       169         
-# 4  Short off-line      Completed                     00%       168         
diff --git a/www/examples/IC35L120AVVA07-0-1.txt b/www/examples/IC35L120AVVA07-0-1.txt
deleted file mode 100644
index 992a620cec64e49651e672bbf8da46d9f6a57e77..0000000000000000000000000000000000000000
--- a/www/examples/IC35L120AVVA07-0-1.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     IC35L120AVVA07-0                        
-Serial Number:    VNC605A6GEWZDA
-Firmware Version: VA6OA52A
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (3399) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   1) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  57) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   060    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0007   098   098   024    Pre-fail     -       22348126
-  4 Start_Stop_Count        0x0012   100   100   000    Old_age      -       13
-  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   020    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   100   100   000    Old_age      -       554
- 10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       13
-192 Power-Off_Retract_Count 0x0032   100   100   050    Old_age      -       36
-193 Load_Cycle_Count        0x0012   100   100   050    Old_age      -       36
-194 Temperature_Centigrade  0x0002   189   189   000    Old_age      -       29 (Lifetime Min/Max 23/36)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0022   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%       492         
-# 2  Extended off-line   Completed                     00%       169         
diff --git a/www/examples/MAXTOR-0.txt b/www/examples/MAXTOR-0.txt
deleted file mode 100644
index 13e0eb28e95d5c7d703ac975814277c44d1c525c..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-0.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674205306226        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x02)	Offline data collection activity 
-					completed without error.
-Self-test execution status:      ( 112)	The previous self-test completed having
-					the read element of the test failed.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   077   077   020    Pre-fail     -       2909
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       29
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       1
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   097   097   001    Old_age      -       1992
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       29
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   093   090   042    Old_age      -       19
-195 Hardware_ECC_Recovered  0x001a   100   006   000    Old_age      -       7683906
-196 Reallocated_Event_Count 0x0010   099   099   020    Old_age      -       1
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       1
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   198   198   000    Old_age      -       2
-
-SMART Error Log Version: 1
-ATA Error Count: 11 (device log contains only the most recent five errors)
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:02 SN:41 CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   02   41   2d   70    e8   c4     90.713
- 70   08   04   3f   2d   70    e8   c4     86.648
- 70   08   06   3d   2d   70    e8   c4     82.584
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
-
-Error 2 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:04 SN:3f CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   04   3f   2d   70    e8   c4     86.648
- 70   08   06   3d   2d   70    e8   c4     82.584
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
- 28   08   08   4b   2c   28    e8   c5     78.339
-
-Error 3 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:06 SN:3d CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   06   3d   2d   70    e8   c4     82.584
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
- 28   08   08   4b   2c   28    e8   c5     78.339
- 28   08   08   0b   2c   28    e8   c5     78.338
-
-Error 4 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:08 SN:3b CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   08   3b   2d   70    e8   c4     78.342
- 28   08   04   8b   2c   28    e8   c5     78.341
- 28   08   08   4b   2c   28    e8   c5     78.339
- 28   08   08   0b   2c   28    e8   c5     78.338
- 28   08   08   cb   2b   28    e8   c5     78.337
-
-Error 5 occurred at disk power-on lifetime: 1029 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:66 SN:41 CL:2d CH:70 D/H:e8 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 70   08   66   41   2d   70    e8   c4     69.020
- 70   08   68   3f   2d   70    e8   c4     64.956
- 70   08   6a   3d   2d   70    e8   c4     60.891
- 70   08   6c   3b   2d   70    e8   c4     56.826
- 70   08   fe   a9   2c   70    e8   c4     52.713
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed: read failure       90%      1965         0x08702f11
-# 2  Short off-line      Completed                     00%      1800         
-# 3  Short off-line      Completed                     00%      1778         
-# 4  Short off-line      Completed                     00%      1777         
diff --git a/www/examples/MAXTOR-1.txt b/www/examples/MAXTOR-1.txt
deleted file mode 100644
index b1ed8ace35f6f00813087682bb8b1d9177b3ad2f..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-1.txt
+++ /dev/null
@@ -1,143 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674119123435        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x04)	Offline data collection activity was 
-					suspended by an interrupting command from host.
-Self-test execution status:      (  89)	The previous self-test completed having
-					the electrical element of the test
-					failed.
-Total time to complete off-line 
-data collection: 		 (2536) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   074   074   020    Pre-fail     -       3294
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       32
-  5 Reallocated_Sector_Ct   0x0033   001   001   020    Pre-fail FAILING_NOW 499
-  7 Seek_Error_Rate         0x000b   100   001   023    Pre-fail In_the_past 0
-  9 Power_On_Hours          0x0012   086   086   001    Old_age      -       9812
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       32
- 13 Read_Soft_Error_Rate    0x000b   100   001   023    Pre-fail In_the_past 0
-194 Temperature_Centigrade  0x0022   091   086   042    Old_age      -       24
-195 Hardware_ECC_Recovered  0x001a   006   004   000    Old_age      -       417912090
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   033   032   020    Old_age      -       338
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 20255 (device log contains only the most recent five errors)
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:60 SN:b8 CL:c6 CH:02 D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 02   05   60   b8   c6   02    e5   c4     474.857
- 02   05   f8   20   c6   02    e5   c4     470.748
- 02   05   08   18   c6   02    e5   c4     470.746
- 00   00   f8   20   c5   02    e5   c4     470.732
- 00   00   08   18   c5   02    e5   c4     470.730
-
-Error 2 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:68 SN:b0 CL:c6 CH:02 D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 02   05   f8   20   c6   02    e5   c4     470.748
- 02   05   08   18   c6   02    e5   c4     470.746
- 00   00   f8   20   c5   02    e5   c4     470.732
- 00   00   08   18   c5   02    e5   c4     470.730
- 02   05   f8   20   c4   02    e5   c4     470.717
-
-Error 3 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:08 SN:c0 CL:3e CH:0e D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   05   08   c0   3e   0e    e5   c4     181.677
- d0   04   08   b0   67   d0    e4   c5     181.651
- 0e   05   08   a0   45   0e    e5   c4     181.646
- 0e   05   80   20   43   0e    e5   c4     181.635
- 0e   05   80   20   41   0e    e5   c4     181.622
-
-Error 4 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:60 SN:c0 CL:3e CH:0e D/H:e5 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   05   80   a0   3e   0e    e5   c4     172.530
- 0e   05   80   20   3d   0e    e5   c4     172.335
- 0e   05   80   20   3c   0e    e5   c4     164.744
- 0e   05   10   10   3b   0e    e5   c4     164.736
- 0e   05   f8   18   3a   0e    e5   c4     157.202
-
-Error 5 occurred at disk power-on lifetime: 9574 hours
-When the command that caused the error occurred, the device was in a vendor specific or reserved state.
-After command completion occurred, registers were:
-ER:40 SC:c0 SN:18 CL:04 CH:d3 D/H:e4 ST:d1
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- d3   04   c0   18   04   d3    e4   c4     502.837
- d3   04   f8   e0   03   d3    e4   c4     498.739
- d3   04   f8   e8   02   d3    e4   c4     498.716
- 55   01   c8   90   70   55    e1   c4     498.705
- 55   01   38   48   70   55    e1   c4     498.680
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed: electrical failure 90%      9786         
-# 2  Extended captive    Completed: servo/seek failure 90%      9676         0x04b7ed3d
-# 3  Extended captive    Completed                     00%      9575         
-# 4  Extended off-line   Completed                     00%      9432         
-# 5  Extended off-line   Completed                     00%      9415         
diff --git a/www/examples/MAXTOR-2.txt b/www/examples/MAXTOR-2.txt
deleted file mode 100644
index 9ff60ffcb3927d55bfa1c40ff5b803b9cc9ced87..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-2.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674119113862        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-See vendor-specific Attribute list for marginal Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x05)	Offline data collection activity was 
-					aborted by an interrupting command from host.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   075   075   020    Pre-fail     -       3249
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       31
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   001   023    Pre-fail In_the_past 0
-  9 Power_On_Hours          0x0012   086   086   001    Old_age      -       9754
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       31
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   035   032   042    Old_age  FAILING_NOW 168
-195 Hardware_ECC_Recovered  0x001a   100   002   000    Old_age      -       880099716
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed                     00%      9691         
-# 2  Short captive       Completed                     00%      9691         
-# 3  Extended captive    Completed                     00%      9618         
-# 4  Extended captive    Interrupted (host reset)      90%      9563         
-# 5  Short captive       Completed                     00%      9563         
-# 6  Short off-line      Completed                     00%      9563         
-# 7  Short captive       Completed                     00%      9545         
-# 8  Extended off-line   Completed                     00%      9541         
-# 9  Short captive       Completed                     00%      9541         
-#10  Extended off-line   Completed                     00%      9537         
-#11  Extended off-line   Completed                     00%      9536         
-#12  Extended off-line   Interrupted (host reset)      90%      9534         
-#13  Extended off-line   Completed                     00%      9517         
-#14  Extended off-line   Completed                     00%      9484         
diff --git a/www/examples/MAXTOR-3.txt b/www/examples/MAXTOR-3.txt
deleted file mode 100644
index 26df69e5977a8b4e46958290ac79b663d7246e4e..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-3.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 6L080J4                          
-Serial Number:    664201100034        
-Firmware Version: A93.0500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  35) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  40) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   069   066   020    Pre-fail     -       3984
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       110
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   099   099   001    Old_age      -       1294
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       110
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   092   087   042    Old_age      -       22
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age      -       1163
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%      1038         
-# 2  Extended off-line   Aborted by host               00%       786         
-# 3  Extended off-line   Aborted by host               00%       786         
diff --git a/www/examples/MAXTOR-4.txt b/www/examples/MAXTOR-4.txt
deleted file mode 100644
index 65ae2850d953448898079f827870b697f26dc07d..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-4.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-smartctl version 5.0-24 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 6L080J4                          
-Serial Number:    664205757172        
-Firmware Version: A93.0500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x04)	Offline data collection activity was 
-					suspended by an interrupting command from host.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  35) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  40) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   065   064   020    Pre-fail     -       4481
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       81
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail     -       0
-  9 Power_On_Hours          0x0012   098   098   001    Old_age      -       1767
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   100   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       81
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail     -       0
-194 Temperature_Centigrade  0x0022   091   084   042    Old_age      -       24
-195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age      -       52795
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age      -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%      1283         
diff --git a/www/examples/MAXTOR-6.txt b/www/examples/MAXTOR-6.txt
deleted file mode 100644
index fe37f6541cc9b0f487578982b94f6a4931f984fd..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-6.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-# /usr/sbin/smartctl -a -m /dev/hda
-smartctl version 5.0-49 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     Maxtor 4R080J0                          
-Serial Number:    R20BZ3LE            
-Firmware Version: RAMB1TU0
-ATA Version is:   7
-ATA Standard is:  Unrecognized. Minor revision code: 0x1e
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x82)	Offline data collection activity 
-					completed without error.
-Self-test execution status:      (  33)	The self-test routine was interrupted
-					by the host with a hard or soft reset.
-Total time to complete off-line 
-data collection: 		 ( 241) seconds.
-Offline data collection
-capabilities: 			 (0x5b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  41) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  3 Spin_Up_Time            0x0027   252   252   063    Pre-fail     -       1621
-  4 Start_Stop_Count        0x0032   253   253   000    Old_age      -       18
-  5 Reallocated_Sector_Ct   0x0033   253   253   063    Pre-fail     -       0
-  6 Read_Channel_Margin     0x0001   253   253   100    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000a   253   252   000    Old_age      -       0
-  8 Seek_Time_Performance   0x0027   252   244   187    Pre-fail     -       41642
-  9 Power_On_Hours          0x0032   253   253   000    Old_age      -       27 h + 13 m
- 10 Spin_Retry_Count        0x002b   252   252   157    Pre-fail     -       0
- 11 Calibration_Retry_Count 0x002b   253   252   223    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   253   253   000    Old_age      -       24
-192 Power-Off_Retract_Count 0x0032   253   253   000    Old_age      -       0
-193 Load_Cycle_Count        0x0032   253   253   000    Old_age      -       0
-194 Temperature_Celsius     0x0032   253   253   000    Old_age      -       29
-195 Hardware_ECC_Recovered  0x000a   253   252   000    Old_age      -       31004
-196 Reallocated_Event_Count 0x0008   253   253   000    Old_age      -       0
-197 Current_Pending_Sector  0x0008   253   253   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   253   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0008   199   199   000    Old_age      -       0
-200 Multi_Zone_Error_Rate   0x000a   253   252   000    Old_age      -       0
-201 Unknown_Attribute       0x000a   253   252   000    Old_age      -       3
-202 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-203 Unknown_Attribute       0x000b   253   252   180    Pre-fail     -       2
-204 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-205 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-207 Unknown_Attribute       0x002a   252   252   000    Old_age      -       0
-208 Unknown_Attribute       0x002a   252   252   000    Old_age      -       0
-209 Unknown_Attribute       0x0024   079   063   000    Old_age      -       0
- 99 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-100 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-101 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 5
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 5 occurred at disk power-on lifetime: 4 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:01
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   d4   00   82   4f   c2    f0   b0     8907.296
- 08   d4   00   82   4f   c2    f0   b0     6260.832
- 08   d1   01   01   4f   c2    f0   b0     6260.800
- 08   d0   01   00   4f   c2    f0   b0     6260.768
- 08   da   00   00   4f   c2    10   b0     6260.736
-
-Error 4 occurred at disk power-on lifetime: 1 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:01
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   d4   00   82   4f   c2    f0   b0     1944.192
- 08   d4   00   82   4f   c2    f0   b0     1824.240
- 08   d1   01   01   4f   c2    f0   b0     1824.224
- 08   d0   01   00   4f   c2    f0   b0     1824.160
- 08   00   08   3f   00   00    f0   ca     1810.400
-
-Error 3 occurred at disk power-on lifetime: 1 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:01
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0e   d4   00   82   4f   c2    f0   b0     1456.432
- 08   d4   00   82   4f   c2    f0   b0     1379.456
- 08   d1   01   01   4f   c2    f0   b0     1379.440
- 08   d0   01   00   4f   c2    f0   b0     1379.376
- 08   00   08   f7   01   54    f0   ca     1378.544
-
-Error 2 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:00 SN:00 CL:f4 CH:2c D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 08   d4   00   82   4f   c2    f0   b0     908.320
- 08   d1   01   01   4f   c2    f0   b0     908.320
- 08   d0   01   00   4f   c2    f0   b0     908.272
- 08   d4   00   7f   4f   c2    f0   b0     905.696
- 08   d1   01   01   4f   c2    f0   b0     905.664
-
-Error 1 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:50 SN:40 CL:97 CH:03 D/H:10 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    10   ef     137.184
- 00   3d   00   00   00   00    10   c3     137.136
- 00   e4   00   00   00   00    10   c3     137.088
- 00   3d   00   00   00   00    10   c3     137.088
- 00   00   00   00   5e   20    10   70     137.040
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended captive    Interrupted (host reset)      10%         4         
-# 2  Short off-line      Completed                     00%         2         
-# 3  Short captive       Completed                     00%         2         
-# 4  Extended captive    Interrupted (host reset)      40%         1         
-# 5  Extended captive    Interrupted (host reset)      70%         1         
-# 6  Extended captive    Interrupted (host reset)      40%         0         
diff --git a/www/examples/MAXTOR-7.txt b/www/examples/MAXTOR-7.txt
deleted file mode 100644
index 1d3fa00491946ea74388b37962bdac003ee8c829..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-7.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-smartctl version 5.1-4 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4                          
-Serial Number:    674119114160        
-Firmware Version: A08.1500
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Tue May 13 08:59:49 2003 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x82) Offline data collection activity 
-                                        completed without error.
-Self-test execution status:      ( 112) The previous self-test completed having
-                                        the read element of the test failed.
-Total time to complete off-line 
-data collection:                 (  44) seconds.
-Offline data collection
-capabilities:                    (0x1b) SMART execute Offline immediate.
-                                        Automatic timer ON/OFF support.
-                                        Suspend Offline collection upon new
-                                        command.
-                                        Offline surface scan supported.
-                                        Self-test supported.
-SMART capabilities:            (0x0003) Saves SMART data before entering
-                                        power-saving mode.
-                                        Supports SMART auto save timer.
-Error logging capability:        (0x01) Error logging supported.
-Short self-test routine 
-recommended polling time:        (   2) minutes.
-Extended self-test routine 
-recommended polling time:        (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   075   075   020    Pre-fail     -       3214
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age      -       58
-  5 Reallocated_Sector_Ct   0x0033   098   098   020    Pre-fail     -       12
-  7 Seek_Error_Rate         0x000b   001   001   023    Pre-fail FAILING_NOW 13
-  9 Power_On_Hours          0x0012   078   078   001    Old_age      -       14851
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age      -       0
- 11 Calibration_Retry_Count 0x0013   100   090   020    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age      -       58
- 13 Read_Soft_Error_Rate    0x000b   100   085   023    Pre-fail     -       0
-194 Temperature_Celsius     0x0022   091   087   042    Old_age      -       24
-195 Hardware_ECC_Recovered  0x001a   004   003   000    Old_age      -       513691822
-196 Reallocated_Event_Count 0x0010   099   099   020    Old_age      -       1
-197 Current_Pending_Sector  0x0032   098   098   020    Old_age      -       12
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 25 (device log contains only the most recent five errors)
-        DCR = Device Control Register
-        FR  = Features Register
-        SC  = Sector Count Register
-        SN  = Sector Number Register
-        CL  = Cylinder Low Register
-        CH  = Cylinder High Register
-        D/H = Device/Head Register
-        CR  = Content written to Command Register
-        ER  = Error register
-        STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 25 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:04 SN:53 CL:1d CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   4f   1d   0c    e0   c8     0.523
- 0c   00   08   47   1d   0c    e0   c8     510.677
- 04   00   08   6f   04   04    e0   ca     510.675
- 04   00   08   4f   1c   04    e0   ca     510.674
- 04   00   08   6f   04   04    e0   ca     510.674
-
-Error 24 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:03 SN:44 CL:1d CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   3f   1d   0c    e0   c8     495.294
- 0c   00   08   37   1d   0c    e0   c8     491.239
- 0c   00   08   2f   1d   0c    e0   c8     488.433
- 14   00   08   17   04   14    e0   ca     488.432
- 0c   00   08   b7   00   0c    e0   ca     488.432
-
-Error 23 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:06 SN:21 CL:18 CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   1f   18   0c    e0   c8     392.659
- 00   00   08   17   18   0c    e0   c8     392.654
- 0c   00   08   0f   18   0c    e0   c8     392.624
- 00   00   08   07   18   0c    e0   c8     392.620
- 00   00   08   ff   17   0c    e0   c8     392.615
-
-Error 22 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:05 SN:b2 CL:16 CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   af   16   0c    e0   c8     385.889
- 04   00   08   6f   04   04    e0   ca     385.886
- 04   00   08   4f   1c   04    e0   ca     385.886
- 04   00   08   6f   04   04    e0   ca     385.886
- 04   00   08   4f   1c   04    e0   ca     385.885
-
-Error 21 occurred at disk power-on lifetime: 14799 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:40 SC:06 SN:a9 CL:16 CH:0c D/H:e0 ST:59
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 0c   00   08   a7   16   0c    e0   c8     381.795
- 04   00   08   6f   04   04    e0   ca     381.793
- 04   00   08   4f   1c   04    e0   ca     381.793
- 04   00   08   6f   04   04    e0   ca     381.792
- 04   00   08   4f   1c   04    e0   ca     381.792
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed: read failure       90%     14757         0x000409bb
-# 2  Extended off-line   Completed: read failure       90%     14755         0x000bf956
-# 3  Extended off-line   Completed                     00%     14305         -
-# 4  Extended off-line   Completed                     00%     14100         -
-# 5  Extended off-line   Completed                     00%     13721         -
-# 6  Extended off-line   Completed                     00%     13636         -
-# 7  Extended off-line   Completed                     00%     13233         -
-# 8  Extended off-line   Completed                     00%     13078         -
-# 9  Extended off-line   Completed                     00%     12093         -
-#10  Extended off-line   Completed                     00%     11926         -
-#11  Extended off-line   Completed                     00%     11428         -
-#12  Extended off-line   Completed                     00%     11030         -
-#13  Extended off-line   Completed                     00%     10888         -
-#14  Extended off-line   Completed                     00%     10728         -
-#15  Extended off-line   Completed                     00%     10435         -
-#16  Extended off-line   Completed                     00%     10267         -
-#17  Extended off-line   Completed                     00%     10098         -
-#18  Extended off-line   Completed                     00%      9930         -
-#19  Extended off-line   Completed                     00%      9599         -
diff --git a/www/examples/MAXTOR-8.txt b/www/examples/MAXTOR-8.txt
deleted file mode 100644
index 3ae4d87735563a46d403293ec5ce00b26d6bb3d0..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-8.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-smartctl version 5.1-14 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4
-Serial Number:    674119116076
-Firmware Version: A08.1500
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Tue Jun 17 14:46:37 2003 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x82)	Offline data collection activity was
-					completed without error.
-					Auto Off-line Data Collection: Enabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0027   075   075   020    Pre-fail  Always       -       3249
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age   Always       -       45
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail  Always       -       0
-  7 Seek_Error_Rate         0x000b   100   001   023    Pre-fail  Always   In_the_past 0
-  9 Power_On_Hours          0x0012   082   082   001    Old_age   Always       -       12223
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age   Always       -       0
- 11 Calibration_Retry_Count 0x0013   020   020   020    Pre-fail  Always   FAILING_NOW 8
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age   Always       -       45
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail  Always       -       0
-194 Temperature_Celsius     0x0022   094   088   042    Old_age   Always       -       17
-195 Hardware_ECC_Recovered  0x001a   100   007   000    Old_age   Always       -       494134044
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age   Offline      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age   Always       -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%     11610         -
-# 2  Extended off-line   Completed                     00%     11213         -
-# 3  Extended off-line   Completed                     00%     11072         -
-# 4  Extended off-line   Completed                     00%     10911         -
-# 5  Extended off-line   Completed                     00%     10618         -
-# 6  Extended off-line   Completed                     00%     10450         -
-# 7  Extended off-line   Completed                     00%     10282         -
-# 8  Extended off-line   Completed                     00%     10114         -
-# 9  Extended off-line   Completed                     00%      9783         -
-
diff --git a/www/examples/MAXTOR-9.txt b/www/examples/MAXTOR-9.txt
deleted file mode 100644
index 6a692423d766812c05a4c6f298bda322d780a655..0000000000000000000000000000000000000000
--- a/www/examples/MAXTOR-9.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-smartctl version 5.1-14 Copyright (C) 2002-3 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     MAXTOR 4K080H4
-Serial Number:    674119123112
-Firmware Version: A08.1500
-Device is:        In smartctl database [for details use: -P show]
-ATA Version is:   5
-ATA Standard is:  ATA/ATAPI-5 T13 1321D revision 1
-Local Time is:    Tue Aug 19 02:06:11 2003 CDT
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: FAILED!
-Drive failure expected in less than 24 hours. SAVE ALL DATA.
-See vendor-specific Attribute list for failed Attributes.
-
-General SMART Values:
-Off-line data collection status: (0x80)	Offline data collection activity was
-					never started.
-					Auto Off-line Data Collection: Enabled.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  44) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-					No Conveyance Self-test supported.
-					No Selective Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-					No General Purpose Logging support.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  50) minutes.
-
-SMART Attributes Data Structure revision number: 11
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x0029   100   253   020    Pre-fail  Offline      -       0
-  3 Spin_Up_Time            0x0027   075   074   020    Pre-fail  Always       -       3186
-  4 Start_Stop_Count        0x0032   100   100   008    Old_age   Always       -       68
-  5 Reallocated_Sector_Ct   0x0033   100   100   020    Pre-fail  Always       -       0
-  7 Seek_Error_Rate         0x000b   100   100   023    Pre-fail  Always       -       0
-  9 Power_On_Hours          0x0012   074   074   001    Old_age   Always       -       17202
- 10 Spin_Retry_Count        0x0026   100   100   000    Old_age   Always       -       0
- 11 Calibration_Retry_Count 0x0013   010   010   020    Pre-fail  Always   FAILING_NOW 9
- 12 Power_Cycle_Count       0x0032   100   100   008    Old_age   Always       -       68
- 13 Read_Soft_Error_Rate    0x000b   100   100   023    Pre-fail  Always       -       0
-194 Temperature_Celsius     0x0022   092   087   042    Old_age   Always       -       22
-195 Hardware_ECC_Recovered  0x001a   018   003   000    Old_age   Always       -       1082933060
-196 Reallocated_Event_Count 0x0010   100   100   020    Old_age   Offline      -       0
-197 Current_Pending_Sector  0x0032   100   100   020    Old_age   Always       -       0
-198 Offline_Uncorrectable   0x0010   100   253   000    Old_age   Offline      -       0
-199 UDMA_CRC_Error_Count    0x001a   200   200   000    Old_age   Always       -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%     17157         -
-# 2  Extended off-line   Completed                     00%     16990         -
-# 3  Extended off-line   Completed                     00%     16823         -
-# 4  Extended off-line   Completed                     00%     16657         -
-# 5  Extended off-line   Completed                     00%     16598         -
-# 6  Extended off-line   Completed                     00%     16490         -
-# 7  Extended off-line   Completed                     00%     16323         -
-# 8  Extended off-line   Completed                     00%     16157         -
-# 9  Extended off-line   Completed                     00%     15991         -
-#10  Extended off-line   Completed                     00%     15696         -
-#11  Extended off-line   Completed                     00%     15614         -
-#12  Extended off-line   Completed                     00%     15241         -
-#13  Extended off-line   Completed                     00%     15026         -
-#14  Extended off-line   Completed                     00%     14785         -
-#15  Extended off-line   Completed                     00%     14334         -
-#16  Extended off-line   Completed                     00%     14129         -
-#17  Extended off-line   Completed                     00%     13750         -
-#18  Extended off-line   Completed                     00%     13665         -
-#19  Extended off-line   Completed                     00%     13262         -
-#20  Extended off-line   Completed                     00%     13108         -
-#21  Extended off-line   Completed                     00%     12125         -
-
diff --git a/www/examples/Maxtor-5.txt b/www/examples/Maxtor-5.txt
deleted file mode 100644
index 3bb171eb6fd032d5ad56dea9925c85bec295c545..0000000000000000000000000000000000000000
--- a/www/examples/Maxtor-5.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-smartctl version 5.0-36 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     Maxtor 98196H8                          
-Serial Number:    V80HV6NC            
-Firmware Version: ZAH814Y0
-ATA Version is:   6
-ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 0
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 (  30) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  60) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000a   253   252   000    Old_age      -       26
-  3 Spin_Up_Time            0x0027   208   206   063    Pre-fail     -       11285
-  4 Start_Stop_Count        0x0032   253   253   000    Old_age      -       62
-  5 Reallocated_Sector_Ct   0x0033   253   253   063    Pre-fail     -       0
-  6 Read_Channel_Margin     0x0001   253   253   100    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000a   253   252   000    Old_age      -       0
-  8 Seek_Time_Performance   0x0027   249   244   187    Pre-fail     -       50271
-  9 Power_On_Hours          0x0032   236   236   000    Old_age      -       32671
- 10 Spin_Retry_Count        0x002b   253   252   223    Pre-fail     -       0
- 11 Calibration_Retry_Count 0x002b   253   252   223    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   253   253   000    Old_age      -       67
-196 Reallocated_Event_Count 0x0008   253   253   000    Old_age      -       0
-197 Current_Pending_Sector  0x0008   253   253   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0008   253   253   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0008   199   199   000    Old_age      -       0
-200 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-201 Unknown_Attribute       0x000a   253   252   000    Old_age      -       1
-202 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-203 Unknown_Attribute       0x000b   253   252   180    Pre-fail     -       2
-204 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-205 Unknown_Attribute       0x000a   253   252   000    Old_age      -       0
-207 Unknown_Attribute       0x002a   253   252   000    Old_age      -       0
-208 Unknown_Attribute       0x002a   253   252   000    Old_age      -       0
-209 Unknown_Attribute       0x0024   253   253   000    Old_age      -       0
- 96 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
- 97 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
- 98 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
- 99 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-100 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-101 Unknown_Attribute       0x0004   253   253   000    Old_age      -       0
-
-SMART Error Log Version: 1
-ATA Error Count: 3
-	DCR = Device Control Register
-	FR  = Features Register
-	SC  = Sector Count Register
-	SN  = Sector Number Register
-	CL  = Cylinder Low Register
-	CH  = Cylinder High Register
-	D/H = Device/Head Register
-	CR  = Content written to Command Register
-	ER  = Error register
-	STA = Status register
-Timestamp is seconds since the previous disk power-on.
-Note: timestamp "wraps" after 2^32 msec = 49.710 days.
-
-Error 1 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:40 SN:42 CL:97 CH:23 D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    00   ef     137.440
- 00   d9   00   00   4f   c2    00   b0     137.328
- 00   da   00   00   4f   c2    00   b0     137.232
- 00   d8   00   00   4f   c2    00   b0     137.152
- 00   db   00   00   4f   c2    00   b0     136.976
-
-Error 2 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:40 SN:40 CL:97 CH:23 D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    00   ef     342.432
- 00   e4   00   00   00   00    00   c3     342.368
- 00   d0   00   00   0a   00    00   c3     342.368
- 00   fe   00   00   00   00    00   ef     342.304
- 00   3d   00   00   00   00    00   c3     342.256
-
-Error 3 occurred at disk power-on lifetime: 0 hours
-When the command that caused the error occurred, the device was in an unknown state.
-After command completion occurred, registers were:
-ER:04 SC:40 SN:40 CL:97 CH:03 D/H:00 ST:51
-Sequence of commands leading to the command that caused the error were:
-DCR   FR   SC   SN   CL   CH   D/H   CR   Timestamp
- 00   fe   00   00   00   00    00   ef     342.304
- 00   3d   00   00   00   00    00   c3     342.256
- 00   e4   00   00   00   00    00   c3     342.192
- 00   3d   00   00   00   00    00   c3     342.192
- 00   00   01   01   00   00    00   ec     342.144
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Short off-line      Completed                     00%      5255         
diff --git a/www/examples/TOSHIBA-0.txt b/www/examples/TOSHIBA-0.txt
deleted file mode 100644
index 965e55d99af8af42a5d6592c3159dd9fbb70312a..0000000000000000000000000000000000000000
--- a/www/examples/TOSHIBA-0.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-smartctl version 5.0-31 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     TOSHIBA MK2018GAS                       
-Serial Number:    X22F7553T           
-Firmware Version: Q2.03 D 
-ATA Version is:   5
-ATA Standard is:  Unrecognized. Minor revision code: 0x00
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 ( 212) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  23) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   050    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   100   100   001    Pre-fail     -       910
-  4 Start_Stop_Count        0x0032   100   100   000    Old_age      -       18
-  5 Reallocated_Sector_Ct   0x0033   100   100   050    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   050    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   050    Pre-fail     -       0
-  9 Power_On_Hours          0x0032   100   100   000    Old_age      -       9
- 10 Spin_Retry_Count        0x0033   100   100   030    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       18
-192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age      -       6
-193 Load_Cycle_Count        0x0032   100   100   000    Old_age      -       437
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0030   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age      -       0
-220 Disk_Shift              0x0002   100   100   000    Old_age      -       4250
-222 Loaded_Hours            0x0032   100   100   000    Old_age      -       4
-223 Load_Retry_Count        0x0032   100   100   000    Old_age      -       0
-224 Load_Friction           0x0022   100   100   000    Old_age      -       0
-226 Load-in_Time            0x0026   100   100   000    Old_age      -       590
-240 Unknown_Attribute       0x0001   100   100   001    Pre-fail     -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%         4         
-# 2  Short captive       Completed                     00%         0         
-# 3  Short off-line      Completed                     00%         0         
diff --git a/www/examples/TOSHIBA-MK6021GAS.txt b/www/examples/TOSHIBA-MK6021GAS.txt
deleted file mode 100644
index 776cb3dcee4f794a875c763556a27b001893c597..0000000000000000000000000000000000000000
--- a/www/examples/TOSHIBA-MK6021GAS.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-smartctl version 5.1-7 Copyright (C) 2002 Bruce Allen
-Home page is http://smartmontools.sourceforge.net/
-
-=== START OF INFORMATION SECTION ===
-Device Model:     TOSHIBA MK6021GAS                       
-Serial Number:    Y2MJ1530T           
-Firmware Version: GA023A  
-ATA Version is:   5
-ATA Standard is:  Unrecognized. Minor revision code: 0x00
-Local Time is:    Mon Feb 17 09:37:27 2003 CST
-SMART support is: Available - device has SMART capability.
-SMART support is: Enabled
-
-=== START OF READ SMART DATA SECTION ===
-SMART overall-health self-assessment test result: PASSED
-
-General SMART Values:
-Off-line data collection status: (0x00)	Offline data collection activity was
-					never started.
-Self-test execution status:      (   0)	The previous self-test routine completed
-					without error or no self-test has ever 
-					been run.
-Total time to complete off-line 
-data collection: 		 ( 587) seconds.
-Offline data collection
-capabilities: 			 (0x1b) SMART execute Offline immediate.
-					Automatic timer ON/OFF support.
-					Suspend Offline collection upon new
-					command.
-					Offline surface scan supported.
-					Self-test supported.
-SMART capabilities:            (0x0003)	Saves SMART data before entering
-					power-saving mode.
-					Supports SMART auto save timer.
-Error logging capability:        (0x01)	Error logging supported.
-Short self-test routine 
-recommended polling time: 	 (   2) minutes.
-Extended self-test routine 
-recommended polling time: 	 (  65) minutes.
-
-SMART Attributes Data Structure revision number: 16
-Vendor Specific SMART Attributes with Thresholds:
-ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE     WHEN_FAILED RAW_VALUE
-  1 Raw_Read_Error_Rate     0x000b   100   100   050    Pre-fail     -       0
-  2 Throughput_Performance  0x0005   100   100   050    Pre-fail     -       0
-  3 Spin_Up_Time            0x0027   100   100   001    Pre-fail     -       1267
-  4 Start_Stop_Count        0x0032   100   100   000    Old_age      -       18
-  5 Reallocated_Sector_Ct   0x0033   100   100   050    Pre-fail     -       0
-  7 Seek_Error_Rate         0x000b   100   100   050    Pre-fail     -       0
-  8 Seek_Time_Performance   0x0005   100   100   050    Pre-fail     -       0
-  9 Power_On_Hours          0x0032   100   100   000    Old_age      -       39
- 10 Spin_Retry_Count        0x0033   100   100   030    Pre-fail     -       0
- 12 Power_Cycle_Count       0x0032   100   100   000    Old_age      -       16
-192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age      -       1
-193 Load_Cycle_Count        0x0032   100   100   000    Old_age      -       460
-194 Temperature_Celsius     0x0022   100   100   000    Old_age      -       40 (Lifetime Min/Max 17/51)
-196 Reallocated_Event_Count 0x0032   100   100   000    Old_age      -       0
-197 Current_Pending_Sector  0x0032   100   100   000    Old_age      -       0
-198 Offline_Uncorrectable   0x0030   100   100   000    Old_age      -       0
-199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age      -       0
-220 Disk_Shift              0x0002   100   100   000    Old_age      -       8332
-222 Loaded_Hours            0x0032   100   100   000    Old_age      -       30
-223 Load_Retry_Count        0x0032   100   100   000    Old_age      -       0
-224 Load_Friction           0x0022   100   100   000    Old_age      -       0
-226 Load-in_Time            0x0026   100   100   000    Old_age      -       159
-240 Head flying hours       0x0001   100   100   001    Pre-fail     -       0
-
-SMART Error Log Version: 1
-No Errors Logged
-
-SMART Self-test log, version number 1
-Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
-# 1  Extended off-line   Completed                     00%         4         -
-
diff --git a/www/examples/atapi_cdrw_smt_a.html b/www/examples/atapi_cdrw_smt_a.html
deleted file mode 100644
index 3e6cea3184ec067f6462097c24d5d00c78abf359..0000000000000000000000000000000000000000
--- a/www/examples/atapi_cdrw_smt_a.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>atapi_cdrw_smt_a</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device: ATAPI&nbsp;&nbsp;&nbsp;
-CD-RW 48X16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: A.RZ</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: CD/DVD</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-17:24:44 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support SMART</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support Error
-Counter logging</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support Self Test
-logging</span>
-</body>
-</html>
diff --git a/www/examples/ativ_36_smt_a.html b/www/examples/ativ_36_smt_a.html
deleted file mode 100644
index c5dc6b2b326e1020fdd4e59f7aac524fb2b4c796..0000000000000000000000000000000000000000
--- a/www/examples/ativ_36_smt_a.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>Atlas IV 36 WLS smartmontools output</title>
-</head>
-<body>
-<span style="font-family: monospace;">Device: QUANTUM&nbsp; ATLAS IV 36
-WLS&nbsp; Version: 0A0A </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: 363930037828 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sat May&nbsp; 3
-21:20:08 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Disabled </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Enabled </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Sense: Ok! </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 35 C </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log: </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-65535&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13</span>
-</body>
-</html>
diff --git a/www/examples/bnch_DLT1.html b/www/examples/bnch_DLT1.html
deleted file mode 100644
index efa6a371318df3b037a982309b3805b82d334752..0000000000000000000000000000000000000000
--- a/www/examples/bnch_DLT1.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>benchmark tape systems DLT1</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-11 Copyright
-(C) 2002-3 Bruce Allen </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is </span><a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/"
- style="font-family: monospace;">http://smartmontools.sourceforge.net/</a><span
- style="font-family: monospace;"> </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Device: BNCHMARK
-DLT1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Version: 391B </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: 0000052369<br>
-Device type: tape</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sun May&nbsp; 4
-11:53:27 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">device is NOT READY (media
-absent, spun down, etc) </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert Supported </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert: Ok! </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log: </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-5.920&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Warning: device does not support
-Self Test Logging</span>
-</body>
-</html>
diff --git a/www/examples/bnch_robot.html b/www/examples/bnch_robot.html
deleted file mode 100644
index 5069b96191292ddc95c1c81cc18c20c685b3d7d5..0000000000000000000000000000000000000000
--- a/www/examples/bnch_robot.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>Benchmark tape systems robot</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-11 Copyright
-(C) 2002-3 Bruce Allen </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is </span><a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/"
- style="font-family: monospace;">http://smartmontools.sourceforge.net/</a><span
- style="font-family: monospace;"> </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Device:
-STK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-L20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Version: 0207 </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: LLC02207812<br>
-Device type: medium changer</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sun May&nbsp; 4
-11:54:39 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Disabled or
-Not Supported </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert Supported </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">TapeAlert Errors (C=Critical,
-W=Warning, I=Informational): </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">[0x02] W: There is a problem with
-the library mechanism. If problem persists, </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;call the library supplier
-help line. </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">[0x0d] W: There is a potential
-problem with the drive ejecting cartridges or </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;with the library mechanism
-picking a cartridge from a slot. </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;1. No action needs to be
-taken at this time. </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;2. If the problem persists,
-call the library supplier help line. </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">[0x0e] W: There is a potential
-problem with the library mechanism placing a </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;cartridge into a slot. </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;1. No action needs to be
-taken at this time. </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;2. If the problem persists,
-call the library supplier help line. </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">No Error counter log to report </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Warning: device does not support
-Self Test Logging</span>
-</body>
-</html>
diff --git a/www/examples/ddrs_39130_smt_a.html b/www/examples/ddrs_39130_smt_a.html
deleted file mode 100644
index e920d71a1f8def59fe8d5930e2431dcfb3109511..0000000000000000000000000000000000000000
--- a/www/examples/ddrs_39130_smt_a.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>ddrs_39130_smt_a.html</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device:
-IBM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-DDRS-39130D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: DC1B</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: QE702689</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: disk</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-16:51:27 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Enabled</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Disabled or
-Not Supported</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: OK</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log:</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-4.295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">verify:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device does not support Self Test
-logging</span>
-</body>
-</html>
diff --git a/www/examples/hp_c5713a_smt_a.html b/www/examples/hp_c5713a_smt_a.html
deleted file mode 100644
index 4c4beea98338e0e74f5eb441caec307f1bb102e2..0000000000000000000000000000000000000000
--- a/www/examples/hp_c5713a_smt_a.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>HP DDS-4 drive smartmontools output</title>
-</head>
-<body>
-<pre wrap="">smartctl version 5.1-11 Copyright (C) 2002-3 Bruce Allen<br>Home page is <a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/">http://smartmontools.sourceforge.net/</a><br><br>Device: HP       C5713A           Version: H910<br>Local Time is: Thu May  1 23:26:38 2003 EEST<br>Temperature Warning Disabled or Not Supported<br>TapeAlert Supported<br>TapeAlert: Ok!<br><br>Error counter log:<br>          Errors Corrected    Total      Total   Correction     Gigabytes    Total<br>              delay:       [rereads/    errors   algorithm      processed    uncorrected<br>            minor | major  rewrites]  corrected  invocations   [10^9 bytes]  errors<br>read:          0        0         0         2          0          0.000           0<br>write:         0        0         0         0          0          0.000           0<br>Warning: device does not support Self Test Logging</pre>
-</body>
-</html>
diff --git a/www/examples/mam3184_smt_a.html b/www/examples/mam3184_smt_a.html
deleted file mode 100644
index b2896462e43f6c797e65f83180f7db7b6debc1d4..0000000000000000000000000000000000000000
--- a/www/examples/mam3184_smt_a.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title>mam3184_smt_a.html</title>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device: FUJITSU&nbsp;
-MAM3184MP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 0106</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: UKS0P2300CK0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: disk</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-15:35:10 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Enabled</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Enabled</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: OK</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 42 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Manufactured in week 10 of year
-2002</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Current start stop
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 280 times</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Recommended start stop
-count:&nbsp; 10000 times</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log:</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-510.626&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-769.950&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 855</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Self-test log</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Num&nbsp;
-Test&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-segment&nbsp; LifeTime&nbsp; LBA_first_err [SK ASC ASQ]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;
-Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-number&nbsp;&nbsp; (hours)</span><br style="font-family: monospace;">
-<span style="font-family: monospace;"># 1&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-980&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 2&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-788&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 3&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-768&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 4&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-665&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 5&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-635&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 6&nbsp; Foreground
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;
-635&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 7&nbsp; Foreground
-long&nbsp;&nbsp; Interrupted (bus reset ?)&nbsp;&nbsp; -&nbsp;&nbsp;
-634&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 8&nbsp; Foreground
-long&nbsp;&nbsp; Interrupted (bus reset ?)&nbsp;&nbsp; -&nbsp;&nbsp;
-634&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 9&nbsp; Foreground
-long&nbsp;&nbsp; Interrupted (bus reset ?)&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#10&nbsp; Foreground short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#11&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Long (extended) Self Test
-duration: 837 seconds [13.9 minutes]</span><br>
-<tt><br>
-</tt>
-</body>
-</html>
diff --git a/www/examples/mam3184_smt_health.html b/www/examples/mam3184_smt_health.html
deleted file mode 100644
index 37a41fb18685bd2b8a5c35ece46f9b56664d442a..0000000000000000000000000000000000000000
--- a/www/examples/mam3184_smt_health.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title>mam3184_smt_health.html</title>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: FAILURE
-PREDICTION THRESHOLD EXCEEDED (FALSE) [asc=5d,ascq=ff]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 42 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Manufactured in week 10 of year
-2002</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Current start stop
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 280 times</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Recommended start stop
-count:&nbsp; 10000 times</span><br>
-<tt><br>
-</tt>
-</body>
-</html>
diff --git a/www/examples/map3735_smt_a.html b/www/examples/map3735_smt_a.html
deleted file mode 100644
index 928904f1bd0e06b1a78b85815f93ae34c24bff38..0000000000000000000000000000000000000000
--- a/www/examples/map3735_smt_a.html
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-  <title>Fujitsu MAP 3735 smartmontools output</title>
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-10 Copyright
-(C) 2002-3 Bruce Allen </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is </span><a
- class="moz-txt-link-freetext"
- href="http://smartmontools.sourceforge.net/"
- style="font-family: monospace;">http://smartmontools.sourceforge.net/</a><span
- style="font-family: monospace;"> </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Device: FUJITSU&nbsp;
-MAP3735NP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 0105 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number: UPG0P2A00491 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Sat May&nbsp; 3
-21:22:09 2003 EST </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Disabled </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Disabled or
-Not Supported </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Sense: Ok! </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 39 C </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Manufactured in week 40 of year
-2002 </span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Current start stop
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14 times </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Recommended start stop
-count:&nbsp; 10000 times </span><br style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log: </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-810.959&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-72.300&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 </span><br
- style="font-family: monospace;">
-<br style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 27 </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">No self-tests have been logged </span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Long (extended) Self Test
-duration: 2872 seconds [47.9 minutes]</span>
-</body>
-</html>
diff --git a/www/examples/st318451_smt_a.html b/www/examples/st318451_smt_a.html
deleted file mode 100644
index fcbadaa880c2b67ad2e9431b3080bd83bb194176..0000000000000000000000000000000000000000
--- a/www/examples/st318451_smt_a.html
+++ /dev/null
@@ -1,185 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-  <title>st318451_smt_a</title>
-  <meta http-equiv="content-type"
- content="text/html; charset=ISO-8859-1">
-</head>
-<body>
-<span style="font-family: monospace;">smartctl version 5.1-12 Copyright
-(C) 2002-3 Bruce Allen</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Home page is
-http://smartmontools.sourceforge.net/</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Device: SEAGATE&nbsp;
-ST318451LW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 0003</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Serial number:
-3CC01TTG000071033QEA</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device type: disk</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Local Time is: Thu May 15
-17:12:14 2003 EST</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Device supports SMART and is
-Enabled</span><br style="font-family: monospace;">
-<span style="font-family: monospace;">Temperature Warning Enabled</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Health Status: OK</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Current Drive
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp; 34 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Drive Trip
-Temperature:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 65 C</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Error counter log:</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Errors Corrected&nbsp;&nbsp;&nbsp; Total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Total&nbsp;&nbsp; Correction&nbsp;&nbsp;&nbsp;&nbsp;
-Gigabytes&nbsp;&nbsp;&nbsp; Total</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delay:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [rereads/&nbsp;&nbsp;&nbsp;
-errors&nbsp;&nbsp; algorithm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-processed&nbsp;&nbsp;&nbsp; uncorrected</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-minor | major&nbsp; rewrites]&nbsp; corrected&nbsp;
-invocations&nbsp;&nbsp; [10^9 bytes]&nbsp; errors</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">read:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-100.431&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">write:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">verify:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-0.010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Non-medium error
-count:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">SMART Self-test log</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Num&nbsp;
-Test&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-segment&nbsp; LifeTime&nbsp; LBA_first_err [SK ASC ASQ]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;
-Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-number&nbsp;&nbsp; (hours)</span><br style="font-family: monospace;">
-<span style="font-family: monospace;"># 1&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 2&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 3&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 4&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;
-10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 5&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 6&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 7&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 8&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;"># 9&nbsp; Background
-long&nbsp;&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#10&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#11&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#12&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">#13&nbsp; Background short&nbsp;
-Completed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--&nbsp;&nbsp;&nbsp;&nbsp;
-0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- [-&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; -]</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br
- style="font-family: monospace;">
-<span style="font-family: monospace;">Long (extended) Self Test
-duration: 587 seconds [9.8 minutes]</span><br>
-<tt><br>
-</tt>
-</body>
-</html>
diff --git a/www/index.html b/www/index.html
deleted file mode 100644
index f7fc4cc5a3ae96b0f550fb9785af0945332afa2f..0000000000000000000000000000000000000000
--- a/www/index.html
+++ /dev/null
@@ -1,754 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
- <title>smartmontools Home Page (last updated $Date: 2003/10/22 16:39:17 $)</title>
- <link rev="made" href="mailto:smartmontools-support&#64;sourceforge.net" />
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
- <meta name="description" content="smartmontools Home Page" />
- <meta name="keywords" content="S.M.A.R.T., SMART, Linux, disk, monitoring, monitor" />
-</head>
-<body>
-
-<!-- $Id: index.html,v 1.98 2003/10/22 16:39:17 ballen4705 Exp $ -->
-<div align="center"><h1><font color="#3333ff">smartmontools Home Page</font></h1></div>
-
-<p>Welcome! This is the home page for the smartmontools package.</p> 
-
-<p>The smartmontools package contains two utility programs
-(<font color="#3333ff"><b>smartctl</b></font> and
-<font color="#3333ff"><b>smartd</b></font>) to control and monitor storage
-systems using the Self-Monitoring, Analysis and Reporting Technology
-System (SMART) built into most modern ATA and SCSI hard
-disks.&#160; In many cases, these utilities will provide advanced warning
-of disk degradation and failure.</p> 
-
-<p>Smartmontools is derived from the <a
-href="http://sourceforge.net/projects/smartsuite/">smartsuite
-package</a>, and includes support for ATA/ATAPI-5 disks.&#160; It
-should run on any modern Linux system, and is being ported to BSD
-variants.</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="#scsi">SCSI disks and tapes (TapeAlert)</a></li>
-<li><a href="#testinghelp">FireWire, USB, and SATA disks/tapes</a></li>
-<li><a href="#differfromsmartsuite">How does smartmontools differ from
-smartsuite?</a></li>
-<li><a href="#references">Useful references on SMART and ATA/ATAPI-5,
--6, and -7</a></li>
-<li><a href="#sampleoutput">Example output from smartmontools</a>
-<b>smartctl</b> utility</li>
-<li><a href="http://cvs.sourceforge.net/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> (Archive has <b>Search Box</b> in top left corner).</li>
-<li>Current <a href="man/smartctl.8.html">smartctl</a>, <a href="man/smartd.8.html">smartd</a>, and <a href="man/smartd.conf.5.html">smartd.conf</a> HTML man pages generated from CVS.</li>
-</ul>
-
-<hr size="2" />
-
-<b><a name="howtodownload"></a>How to download and install
-smartmontools</b>
-
-<p>There are 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.1-18.i386.rpm</pre>
-For most users, this is all that is needed.</li>
-<li>If you receive an error message, you have probably previously
-installed the <tt>smartsuite</tt> package, or RedHat's
-<tt>kernel-utils</tt> package, which provide older versions of the
-<tt>smartd</tt> and <tt>smartctl</tt> utilities.&#160; In this case you
-should use the <tt>--nodeps</tt> or <tt>--force</tt> arguments of rpm to
-replace these two utilities:
-<pre>rpm -ivh --nodeps --force smartmontools-5.1-18.i386.rpm</pre></li>
-<li>If you want to remove the package (<tt>rpm -e smartmontools</tt>)
-and your system does not have <tt>chkconfig</tt> installed, you may need
-to use:
-<pre>rpm -e --noscripts smartmontools</pre></li>
-</ul>
-
-<b>Second Method - Install from the source tarball</b>
-<ul>
-<li>Download the latest source tarball from <a href="http://sourceforge.net/project/showfiles.php?group_id=64297">here</a>.
-Note: you probably want the most recent release.</li>
-<li>Uncompress the tarball:
-<pre>tar zxvf smartmontools-5.20.tar.gz</pre></li>
-<li>The previous step created a directory called <tt>smartmontools-5.20</tt>
-containing the code.&#160; Go to that directory, build, and install:
-<pre>cd smartmontools-5.20
-./configure
-make
-make install
-</pre></li>
-<li> Note that the <tt>./configure</tt> step above is not needed for releases &lt;=5.1-18.  For releases &gt;=5.19, <tt>./configure</tt>
-can take optional arguments.  These optional arguments are fully explained in the
-<a href="http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/INSTALL?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">INSTALL</a>
-file.  Some common choices are:
-<ul>
-<li> Red Hat (install in <tt>/usr</tt> and <tt>/etc</tt>): <tt>./configure</tt></li>
-<li> Slackware (install in <tt>/usr</tt> and <tt>/etc</tt>): <tt>./configure</tt></li>
-<li> Filesystem Hierarchy Standard (installs in <tt>/usr/local</tt>): <tt>./configure --prefix=/usr/local</tt></li>
-<li> Debian (installs in <tt>/usr/local</tt>): <tt>./configure --prefix=/usr/local</tt></li>
-</ul>
-</li>
-<li>To compile from another directory (avoids overwriting virgin files from the smartmontools package)
-replace <tt>./configure [options]</tt> by:
-<pre>
-mkdir objdir
-cd objdir
-../configure [options]
-</pre></li>
-<li>To install to another destination (useful for testing and to avoid overwriting an existing smartmontools installation)
-replace <tt>make install</tt> by:
-<pre>
-make DESTDIR=/home/myself/smartmontools-test install
-</pre>
-Use a full path: <tt>~/smartmontools-test</tt> won't work.
-</li>
-<li>Unless the destination directory is your home directory (or a location that you have write permission)
-only root can do <tt>make install</tt></li>
-</ul>
-
-<b>Third Method - Install from the CVS repository</b>
-<ul>
-<li><p>One of the really cool things about CVS is that you can get
-<i>any</i> version of the code you want, from the first release up the
-the most current development version.&#160; And it's trivial, because
-each release is <u>tagged</u> with a name like
-<tt>RELEASE_5_1_18</tt>.&#160; You can see what the different names are
-by looking at the <a href="http://cvs.sourceforge.net/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.1-16 release:
-
-<pre>cvs -d:pserver:anonymous@cvs.smartmontools.sourceforge.net:/cvsroot/smartmontools co -r RELEASE_5_1_16 sm5</pre></li>
-
-<li><p>This will create a subdirectory called <tt>sm5/</tt> containing the
-code.&#160; Go to that directory, build, and install:</p>
-<pre>cd sm5
-./autogen.sh
-./configure
-make
-make install
-</pre>
-
-<ul>
-<li>See notes under <b>Second method - install from source tarball</b> for different options to <tt>./configure</tt>
-and other useful remarks.</li>
-<li>Skip <tt>./autogen.sh</tt> and <tt>./configure</tt> for tagged releases
-&lt;= 5.1-18 (RELEASE_5_X_Y, where X = 0 or 1 and Y = 0 to 18).</li>
-<li>If you get the current sources (<tt>cvs co</tt> with no arguments or do <tt>cvs up
--A</tt>) then you <i>will</i>  need those two additional steps.</li>
-</ul></li>
-
-<li>To update your sources to the 5.1-18 release:
-<pre>cd sm5
-cvs up -r RELEASE_5_1_18</pre></li>
-
-<li>To update any tagged release to the latest development code:
-
-<pre>cd sm5
-cvs up -A</pre></li>
-</ul>
-
-<b>Fourth Method - Install the Debian package (for machines using the
-Debian GNU/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.18-1.agx0_i386.deb
-</pre>
-But the preferred method is to add the following line to your
-<tt>/etc/apt/sources.list</tt>:
-<pre>deb http://honk.physik.uni-konstanz.de/~agx/linux-i386/debian smartmontools/
-</pre>
-and type <pre>
-apt-get update &amp;&amp; apt-get install smartmontools
-</pre> this will automatically download and install the package.
-</li>
-</ul>
-
-<b>After installing it using Method 1, 2, 3 or 4 above, you can read the
-man pages, and try out the commands:</b>
-
-<pre>
-man smartd.conf
-man smartctl
-man smartd
-/usr/sbin/smartctl -s on -o on -S on /dev/hda (only root can do this)
-/usr/sbin/smartctl -a /dev/hda (only root can do this)</pre>
-
-<p>Note that the default location for the manual pages are
-<tt>/usr/share/man/man5</tt> and <tt>/usr/share/man/man8</tt>.&#160; If
-"<tt>man</tt>" doesn't find them, then you may need to add
-<tt>/usr/share/man</tt> to your <tt>MANPATH</tt> environment
-variable.</p>
-
-<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>
-
-<hr size="2" />
-
-<a name="FAQ"></a><b>Frequently Asked Questions</b>
-
-<p>If your question is not here, please <a href="mailto:smartmontools-support&#64;lists.sourceforge.net">email
-me</a>.</p>
-
-<ul>
-<li><b>What do I do if I have problems, or need support?&#160; Suppose
-I want to become a developer, or suggest some new extensions?</b>
-
-<p>First, search the support mailing list archives to see if your
-question has been answered. Instructions are in the following
-paragraph.  If you don't find an answer there, then please send an
-email to the <a
-href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">smartmontools-support
-mailing list</a>.  This is a moderated forum: you are not
-required to subscribe to the list in order to post your question.
-</p>
-
-<p>To search the email archives, first go to the <a
-href="http://sourceforge.net/mailarchive/forum.php?forum=smartmontools-support">
-mailing list archive</a>.  In the top left corner you will see a
-search box: use <b>Mailing List</b> as the type of search. This tool
-works very well.</p>
-
-<p>Note that from time to time SourceForge has mailing list problems
-and you'll get a message telling you that <i>Either your mailing list
-name was misspelled or your mailing list has not been archived yet. If
-this list has just been created, please retry in 2-4 hours</i>.  If
-this happens, you'll have to try again later.
-</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 SMART attributes (temperature, power-on lifetime, and so
-on) are stored in vendor-specific structures.&#160; Sometime these are
-strange.&#160; Hitachi disks (at least some of them) store power-on
-lifetime in minutes, rather than hours (see next question below).&#160; IBM disks (at least some
-of them) have three temperatures stored in the raw structure, not just
-one.&#160; And so on.&#160; If you find strange output, or unknown
-attributes, please send an email to <a href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support"> 
-smartmontools-support</a> and we'll help you try and figure it
-out.</p></li>
-
-<li><b>What Kernel Version is needed? (Linux)</b>
-
-<p>
-Kernel versions 2.4.0 or later should work. We recommend the latest
-2.4 kernel.<br /><br />
-
-Vanilla kernel.org 2.2.X kernels do not support the HDIO_DRIVE_TASK
-ioctl(), which is needed for the ATA drive to execute the ATA SMART
-RETURN STATUS command. So these kernels will not work.<br /><br />
-
-Vendor-supplied 2.2.X kernels, and vanilla 2.2.X kernels patched with
-<a href="http://www.funet.fi/pub/linux/kernel/people/hedrick/ide-2.2.20/">Andre
-Hedrick's IDE patches</a> (available from your local kernel.org
-mirror, not updated for 2.2.21 or later, and probably still containing
-a few bugs) may support the needed ioctl().<br /><br />
-
-If the configuration option CONFIG_IDE_TASK_IOCTL exists in your 2.2.X
-kernel source code tree, then your 2.2.X kernel will probably support
-smartmontools.  Note that this kernel configuration option does
-<i>not</i> need to be enabled. Its presence merely indicates that the
-required HDIO_DRIVE_TASK ioctl() is supported.
-</p></li>
-
-<li><b>What attributes does smartmontools not yet recognize?</b>
-
-<p>From Maxtor disks (99), (100), (101)
-</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
-SMART 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>My Maxtor/Hitachi/Fujitsu disk is only a few days old, yet smartctl reports its age (Attribute 9) as thousands of hours!</b>
-
-<p>On 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>
-<p>Some models of Fujitsu disks are known to use Attribute 9
-for lifetime in seconds. In that case, use the --vendorattribute=9,seconds
-option to correctly display hours, minutes and seconds.</p>
-</li>
-
-<li><b>The power-on timer (Attribute 9 raw value) on my Maxtor disk acts strange.</b>
-
-<p>There are three related problems with Maxtor's SMART firmware:
-</p>
-
-<p>
-<b>1 - </b>
-On some disks from 2001/2002, the raw value of Attribute 9 (Power On
-Time) is <i>supposed</i> to be minutes. But it advances at an
-unpredictable rate, always more slowly than one count per minute.  One
-(unconfirmed) theory is that when the disk is in idle mode, the
-counter stops advancing.  This is only supposed to happen in standby
-mode.
-</p>
-
-<p>
-<b>2 - </b> In Maxtor disks that use the raw value of Attribute 9 as a
-minutes counter, only two bytes (of the six available) are used to
-store the raw value.  So it resets to zero once every 65536=2^16
-minutes, or about once every 1092 hours. This is fixed in all Maxtor
-disks manufactured after July 2003, where the raw value was extended
-to four bytes.
-</p>
-
-<p>
-<b>3 - </b> In Maxtor disks that use the raw value of Attribute 9 as a
-minutes counter, the hour time-stamps in the self-test and ATA error
-logs are calculated by right shifting 6 bits.  This is equivalent to
-dividing by 64 rather than by 60.  As a result, the hour time stamps
-in these logs advance 7% more slowly than they should.  Thus, if you
-do self-tests once per week at the same time, instead of the
-time-stamps being 168 hours apart, they are 157 hours apart.  This is
-also fixed in all Maxtor disks manufactured after July 2003.
-</p>
-</li>
-
-<li><b>Where can I find manufacturer-specific disk-testing utilities?</b>
-
-<p>A good listing of such utilities can be found <a
-href="http://www.benchmarkhq.ru/english.html?/be_hdd2.html">here</a>.
-Unfortunately most of these are for MS operating systems, but most can
-be run from an MS-DOS boot disk. Note: if you do run one of these
-utilities, and it identifies the meanings of any SMART Attributes that
-are not known to smartmontools, please report them to the mailing list
-above.</p>
-
-<p>These utilities have an important role to fill.  If your disk has
-bad sectors (for example, as revealed by running self-tests with
-smartmontools) and the disk is not able to recover the data from those
-sectors, then the disk will <i>not</i> automatically reallocate those
-damaged sectors from its set of spare sectors, because
-forcing the reallocation to take place may entail some loss of data.
-Because the commands that force such reallocation are
-<i>Vendor Specific</i>, most manufactuers provide a utility for this
-purpose. It may cause data loss but can repair damaged sectors (at
-least, until it runs out of replacement sectors).
-</p>
-</li>
-
-<li><b>When I run <tt>smartd</tt>, the SYSLOG <tt>/var/log/messages</tt>
-contains messages like this:</b>
-<pre>smartd: Reading Device /dev/sdv
-modprobe: modprobe: Can't locate module block-major-65</pre>
-
-<p>This is because when <tt>smartd</tt> starts, 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 SMART disks?</b>
-
-<p>Apparently some of the older SMART firmware on IBM disks can 
-interfere with the regular operation of the disk.&#160; If you have this
-problem, here is an <a href="http://www.geocities.com/dtla_update/">IBM
-DISK FIRMWARE UPGRADE</a> that fixes the problem.
-</p></li>
-
-<li><b>How can I check that the package hasn't been tampered with?</b>
-
-<p>Since the <tt>smartmontools</tt> utilities run as root, you might
-be concerned about something harmful being embedded within
-them. Starting with release 5.19 of <tt>smartmontools</tt>, the .rpm
-files and tarball have been GPG signed. The tarball's fingerprint is
-given in a file on the release page with a name like
-<tt>smartmontools-5.20.tar.gz.asc</tt>.  Please verify these using
-the <a href="SmartmontoolsSigningKey.txt">Smartmontools GPG Signing
-Key</a>
-</p></li>
-
-<li><b>Is there a bootable standalone CD or floppy that contains smartmontools?</b>
-
-<p>If you have a system that is showing signs of disk trouble (for
-example, it's unbootable and the console is full of disk error
-messages) it can be handy to have a version of smartmontools that can
-be run off of a bootable CD or floppy to examine the disk's SMART data and run
-self-tests.  This is also useful if you want to run Captive Self-Tests
-(the <b><tt>-<font size="+2">C</font></tt></b> option of
-<b><tt>smartctl</tt></b> ) on disks that can not easily be unmounted,
-such as those hosting the Operating System files. Or you can use
-this to run <tt>smartctl</tt> on computers that don't use linux as the
-day-to-day operating system.</p>
-
-<p>At present I am only aware of three such bootable disks:</p>
-<ul>
-<li><a href="http://www.lnx-bbc.org/">LNX-BBC Bootable CD</a> </li>
-<li><a href="http://www.stresslinux.org/">Stresslinux Bootable CD</a></li>
-<li><a href="http://www.tux.org/pub/people/kent-robotti/looplinux/rip/">RIP (Recovery Is Possible) Bootable CD/Floppy</a></li>
-</ul>
-<p>
-Please let me know if there are others, and I will add them to this
-list.
-</p>
-</li>
-
-<li><b>Can I monitor ATA disks behind SCSI RAID controllers?</b>
-
-<p>
-From release 5.1-16, smartmontools supports 3ware SCSI RAID
-controllers that use ATA disks internally. To pass commands through
-the 3ware controller, use the smartmontools <b>-d 3ware,N</b> option
-or Directive.
-</p>
-
-<p>
-In smartmontools release 5.1-16, the SMART HEALTH STATUS
-(smartmontools <b>-H</b>) is not returned correctly for 3ware devices.
-In this release, the ENABLE AUTOMATIC OFFLINE and ENABLE ATTRIBUTE
-AUTOSAVE commands (smartmontools <b>-o on</b> and <b>-S on</b>) are
-<i>disabled</i> for 3ware devices, because at the time 5.1-16 was
-released, the 3w-xxxx driver could not pass these commands through to
-the ATA disks.
-</p>
-
-<p>
-Later smartmontools CVS code and releases
-<i>do</i> correctly support <i>all</i> of these commands.  You may:
-</p>
-<ul>
-<li>use version <b>1.02.00.037</b> or greater of the 3w-xxxx driver, or</li>
-<li><a href="3w-xxxx.txt">patch</a> earlier 3ware 3w-xxxx drivers so that
-these commands reach the disks, or</li>
-<li> use an <b>unpatched</b> earlier 3w-xxxx driver (which won't pass these
-commands to the disks but will instead print
-harmless warning messages to SYSLOG).</li>
-</ul>
-<p>
-Since smartmontools 3ware support is new, please report positive or negative experiences to the <a
-href="http://lists.sourceforge.net/lists/listinfo/smartmontools-support">support
-mailing list</a>, particularly for 64-bit and/or big-endian
-architectures.
-</p>
-</li>
-
-<li><b>Does it work on Windows?</b>
-
-<p>Currently not (but you can run it from a bootable CD - see above).
-We would welcome a <a href="http://www.cygwin.com/">Cygwin</a> port.
-<a
-href="mailto:smartmontools-support&#64;lists.sourceforge.net">Contact
-us</a> if you're interested in porting it. Some code showing how to
-access SMART data under Windows 98, NT 4, Windows 2000, and Windows XP
-can be found <a
-href="ftp://ftp.heise.de/pub/ct/listings/0207-218.zip">here</a>.
-Additional information from Microsoft can be found <a
-href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q208048">here</a>.
-A related newsgroup thread (with pointers to additional documentation,
-etc.) is <a
-href="http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&th=18cdac9d90f6bda1&rnum=1">here</a>.
-</p> </li>
-
-<li><b>Why has the versioning scheme changed?</b>
-
-<p>It was non-standard.  So with the move to GNU Autoconf and GNU
-Automake it changed from 5.X-Y (where X and Y are one or more numbers)
-to 5.Y.  So the releases are numbered (starting with the oldest and
-moving forward in time):
-5.0-1,...,5.0-45,5.1-1,...,5.1-18,5.19,5.20,...
-</p>
-</li>
-
-<li><b>My ATA drive is not in the smartctl/smartd database.  How do I get it added?</b>
-
-<p>
- First use the command:<br/>
- <tt>smartctl -t short /dev/hd?</tt><br/>
- to run a short self-test on the drive,
- and wait a few minutes for the test to complete.
- The timestamp in the self-test log will help us to determine
- whether Attribute 9 is being used to store the lifetime in hours,
- minutes, or seconds.  Then email the output from:<br/>
- <tt>smartctl -a /dev/hd?</tt><br/> 
-to <a href="http://lists.sourceforge.net/mailman/listinfo/smartmontools-support">smartmontools-support</a>
- as an email attachment.  If you need to use any of the
- vendor-specific display options (<b>-v</b> options) with this drive
- or if any of the Attributes are behaving strangely please include
- that information as well.
-</p>
-</li>
-</ul>
-
-<hr size="2" /><a name="scsi"></a><b>SCSI disks and tapes
-(TapeAlert)</b>
-<p>Smartmontools for SCSI disks and tapes (including medium changers) is
-discussed on a separate <a href="smartmontools_scsi.html">page</a>.
-</p>
-
-<hr size="2" /><a name="testinghelp"></a><b>FireWire, USB, and SATA 
-disks/systems</b>
-<p>As for USB and FireWire (ieee1394) disks and tape drives, the news
-is not good. They appear to Linux as SCSI devices but their
-implementations do not usually support those SCSI commands needed by
-smartmontools. The ieee1394 consortium recently certified the <span
- style="font-style: italic;">first</span> external enclosure (containing
-a ATA disk and a protocol bridge) as being compliant to the relevant
-standards. Such devices have already been on the market for about 3 
-years and they tend to only support the bare minimum of commands
-needed for device operation (i.e. SMART support is an unsupported
-extra).<br />
-</p>
-<p>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 SMART self-test logs, and doesn't print timestamp
-information in the most usable way.&#160; The <tt>smartctl</tt> utility
-in smartmontools has added functionality for this (<tt>-q, -l selftest,-S,
--T, -v and -m</tt> options), updated documentation, and also fixes small
-technical bugs in smartsuite. [One example: smartsuite does not actually use the
-ATA SMART RETURN STATUS command to find out the health status of a disk.  It instead tries to infer this from the
-SMART Attribute values.]&#160; See the 
-<a href="http://cvs.sourceforge.net/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
-SMART and the  ATA/ATAPI standards</big></b>
-
-<p><big>If you are having trouble understanding the output of smartctl
-or smartd, please first read the manual pages:</big></p>
-
-<pre>
-man 5 smartd.conf
-man 8 smartctl
-man 8 smartd
-</pre>
-
-<p><big>If you'd like to know more about SMART, 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 SMART specification is SFF-8035i from the <a href="http://www.sffcommittee.com/ns/">
-  Small Form Factors (SFF) Committee</a>.&#160; 
-  <ul>
-    <li>
-      Here is the SFF <a href="ftp://ftp.seagate.com/sff/INF-8035.TXT"> "link"</a>
-     (they have "expired" the document).
-    </li>
-    <li>
-      Version 1.0 of <a href="ftp://ftp.ds2.pg.gda.pl/pub/macro/S.M.A.R.T./SFF-8035i.pdf">
-      SFF-8035i "Self-Monitoring, Analysis and Reporting Technology (S.M.A.R.T.)". </a>
-    </li>
-    <li>
-      Revision 2.0 of <a href="ftp://ftp.ds2.pg.gda.pl/pub/macro/S.M.A.R.T./8035R2_0.PDF">
-      SFF-8035i "Self-Monitoring, Analysis and Reporting Technology (S.M.A.R.T.)". </a>
-    </li>
-    <li>
-      Revision 1.4 of <a href="ftp://ftp.ds2.pg.gda.pl/pub/macro/S.M.A.R.T./8055.PDF">
-      SFF-8055i "S.M.A.R.T. Applications Guide for the ATA and SCSI Interfaces" </a>
-    </li>
-  </ul>
-</li>
-<li>From the <a href="http://cmrr.ucsd.edu/smart/">UCSD SMART Project</a>:
-<ul> 
- <li><a href="http://cmrr.ucsd.edu/smart/tech_papr/HamerlySmartPaper.pdf">Bayesian
-Approaches to Failure Prediction for Disk Drives</a></li>
-  <li><a href="http://cmrr.ucsd.edu/smart/tech_papr/SmtPapTransReliFinalWeb.pdf">Improved
-Disk-Drive Failure Warnings</a></li>
- </ul>
- </li>
- <li>From the Seagate Corporation:
- <ul>
-  <li><a href="http://www.seagate.com/newsinfo/docs/disc/drive_reliability.pdf" target="_blank">Estimating Drive Reliability in Desktop Computers and
-Consumer Electronics Systems</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/enhanced_smart.pdf" target="_blank">Enhanced SMART - Get SMART For Reliability</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/smart_u8.pdf" target="_blank">Playing it SMART</a></li>
-  <li><a href="http://www.seagate.com/docs/pdf/whitepaper/Enhanced_DST_Tech_Paper.pdf" target="_blank">Enhanced Drive Self-Test</a></li>
- </ul>
- </li>
- <li><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 - reallocated sector count)</li>
- <li><a href="examples/MAXTOR-2.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has had failing SMART test in the past.  Look at the Seek Error Rate)</li>
- <li><a href="examples/MAXTOR-7.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status, some failed self-tests)</li>
- <li><a href="examples/MAXTOR-8.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status - calibration retry count)</li>
- <li><a href="examples/MAXTOR-9.txt">MAXTOR 4K080H4</a> 80 GB 5400 RPM (has failing SMART status - calibration retry count)</li>
- <li><a href="examples/MAXTOR-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>
- <li><a href="examples/FUJITSU1.txt">Fujitsu MHR2040AT</a> Fujitsu Laptop Disk (has failing SMART status - write error count)</li>
-</ul>
-
-<hr size="2" />
-
-Maintained by: <a href="mailto:smartmontools-support&#64;lists.sourceforge.net">Bruce Allen</a><br />
-Last updated: <tt>$Date: 2003/10/22 16:39:17 $</tt><br />
-CVS tag: <tt>$Id: index.html,v 1.98 2003/10/22 16:39:17 ballen4705 Exp $</tt>
-
-<hr size="2" />
-
-<div align="center">Hosted by</div>
-
-<div align="center"><a href="http://sourceforge.net/"><img style="border:0;width=:88px;height:31px"
-   src="http://sourceforge.net/sflogo.php?group_id=64297&amp;type=5" alt="SourceForge.net" /></a></div>
-
-<br />
-
-<div align="center"><a href="http://validator.w3.org/check/referer"><img style="border:0;width=:88px;height:31px"
-   src="http://www.w3.org/Icons/valid-xhtml10.png" alt="Valid XHTML 1.0!" /></a></div>
-
-<br />
-
-<div align="center"><a href="http://validator.w3.org/check?uri=http%3A%2F%2Fsmartmontools.sourceforge.net">
-Validate XHTML 1.0 Transitional.</a></div>
-
-</body>
-</html>
diff --git a/www/script b/www/script
deleted file mode 100755
index fa7cd8c224367b6aba467f81fc960da4efc80375..0000000000000000000000000000000000000000
--- a/www/script
+++ /dev/null
@@ -1,24 +0,0 @@
-#! /bin/bash
-
-# This is a script to wrap smartctl output into http:// displayable form
-# It requires a filename as input, and produces an file with a .html extension as output
-
-if [ $# -ne 1 ] ; then
-	echo This script requires one a file as input
-	exit 1
-fi
-
-model=`grep "Device Model"  $1  | awk '{print $3}' `
-
-# see if file name in use
-let i=0
-while [ -f $model-$i.html ] ; do
-	let i+=1
-done
-
-filename=$model-$i
-echo -e "<pre><tt>\n"    > $filename.html
-cat $1                  >> $filename.html
-echo -e "</tt></pre>\n" >> $filename.html
-
-echo created file $filename.html
diff --git a/www/smartmontools_scsi.xml b/www/smartmontools_scsi.xml
deleted file mode 100644
index ea008da4154a2066dba28991435e1e0c9c2e913f..0000000000000000000000000000000000000000
--- a/www/smartmontools_scsi.xml
+++ /dev/null
@@ -1,755 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" >
-
-<!--
-This is DocBook XML that can be rendered into a single HTML page with a
-command like 'xmlto html-nochunks <this_file_name>'. It can
-also be rendered into multi-page HTML (drop the "-nochunks") or pdf,
-ps, txt, etc.
--->
-
-<article id="index">
- <articleinfo>
-   <title>Smartmontools for SCSI devices</title>
-   <author>
-    <firstname>Douglas</firstname>
-    <surname>Gilbert</surname>
-    <affiliation>
-     <address>
-      <email>dgilbert@interlog.com</email>
-     </address>
-    </affiliation>
-   </author>
-  <authorinitials>dpg</authorinitials>
-  <pubdate>2003-10-13</pubdate>
-
-  <revhistory>
-     <revision>
-       <revnumber>1.1</revnumber>
-       <date>2003-10-13</date>
-       <authorinitials>dpg</authorinitials>
-       <revremark>
-             freebsd, timestamp
-       </revremark>
-     </revision>
-     <revision>
-       <revnumber>1.0</revnumber>
-       <date>2003-05-26</date>
-       <authorinitials>dpg</authorinitials>
-       <revremark>
-             first cut
-       </revremark>
-     </revision>
-  </revhistory>
-
-  <copyright>
-   <year>2003</year>
-   <holder>Douglas Gilbert</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-      Permission is granted to copy, distribute and/or modify this document
-      under the terms of the GNU Free Documentation License, Version 1.1
-      or any later version published by the Free Software Foundation;
-      with no Invariant Sections, with no Front-Cover Texts, and with
-      no Back-Cover Texts.
-   </para>
-   <para>
-    For an online copy of the license see
-    <ulink url="http://www.fsf.org/copyleft/fdl.html">
-    <literal>www.fsf.org/copyleft/fdl.html</literal></ulink>.
-   </para>
-
-  </legalnotice>
-
-  <abstract>
-  <para>
-    This article describes how smartmontools interacts with SCSI 
-    storage devices (including tapes). Smartmontools is a SMART
-    utility toolset for the Unix based operating system (including 
-    Linux and FreeBSD). <acronym>SMART</acronym> is an acronym for
-    Self-Monitoring, Analysis and Reporting Technology.
-  </para>
-  </abstract>
- </articleinfo>
-
-<!--
-<toc></toc>
--->
-
-  <sect1 id="intro">
-      <title>Introduction</title>
-<para>
-Smartmontools controls and monitors storage devices using the
-Self-Monitoring, Analysis and Reporting Technology System 
-(<acronym>SMART</acronym>). This toolset was originally built
-for Linux but recently has been ported to FreeBSD and another
-port for Solaris is taking shape.
-This article describes how smartmontools interacts with SCSI devices.
-Passing reference is also made to devices that use the SCSI command
-set such as USB mass storage devices and IEEE1394 devices that use
-the "sbp2" protocol.
-</para>
-<para>
-The primary web site for smartmontools is at
-<ulink url="index.html">
-<literal>smartmontools.sourceforge.net</literal></ulink> from which the
-latest versions (both source and binaries) can be obtained. Smartmontools
-grew out of the now dormant <emphasis>smartsuite</emphasis> project which
-is still available on the sourceforge site. The smartmontools main page
-concentrates on ATA devices (whose draft standards can be found at
-<ulink url="http://www.t13.org"><literal>www.t13.org</literal></ulink>).
-This article attempts to supply some SCSI specific information for
-those users of smartmontools that wish to monitor SCSI storage devices.
-</para>
-<para>
-This document was last altered on 13th October 2003.
-</para>
-</sect1>
-
- <sect1 id="doco">
-      <title>Documentation</title>
-<para>
-One of the first surprises working with SCSI devices and smartmontools
-is that the SCSI standards (found at <ulink url="http://www.t10.org">
-<literal>www.t10.org</literal></ulink>)
-do <emphasis>not</emphasis> use
-the term <acronym>SMART</acronym>. Instead the awkward term "Informational
-Exceptions" (IE) is used. <acronym>SMART</acronym> never attained the status
-of "standard" and its original documents have been withdrawn. Its catchy
-name lives on, especially on vendors' web sites and obviously in the
-name of this toolset. Luckily the good ideas in <acronym>SMART</acronym>
-have been incorporated into the ATA and SCSI standards albeit in
-slightly different forms.
-</para>
-<para>
-The SCSI standards themselves have been sub-divided and three categories
-are of interest:
-<itemizedlist>
-<listitem><para>architectural model [SAM-3]</para></listitem>
-<listitem><para>command sets [SPC-3, SBC-2, SSC-2, SMC-2, etc]
-</para></listitem>
-<listitem><para>transports [SPI-4, SBP-2, FCP-3, etc]</para></listitem>
-</itemizedlist>
-The architectural model while interesting says nothing specific about
-Informational Exceptions or related topics. With respect to the transports
-the term <emphasis>SCSI</emphasis> has often been synonomous with one
-of the SCSI Parallel Interface transports (e.g. SPI-4 which is often know
-as "Ultra320") however this is unhelpful. For the purpose of smartmontools
-the SCSI command sets are more interesting. The main reference is the
-SCSI Primary Commands (SPC-3) document, specifically these sections:
-<itemizedlist>
-<listitem><para>self test operations; SEND DIAGNOSTIC command (which is
-the mechanism for requesting self tests)
-</para></listitem>
-<listitem><para>MODE SENSE and MODE SELECT commands (both 6 and 10 byte
-variants); Mode parameters [these mode pages:
-Informational Exceptions Control (IEC) and the Control]
-</para></listitem>
-<listitem><para>LOG SENSE and LOG SELECT commands;
-Log parameters [these log pages: Informational exceptions,
-read/write/verify error counters, non medium error count, temperature, 
-start-stop cycle counter and the self test results]
-</para></listitem>
-</itemizedlist>
-The SCSI Block Commands (SBC-2) document covers random access storage
-devices such as disks (but excluding CD/DVD readers and writers which are
-covered by MMC-3) while the SCSI Streaming Commands (SSC-2) document covers 
-tape systems.  The SBC-2 standard does not contain any additional 
-information (over SPC-3) about Informational Exceptions. 
-The SSC-2 standard covers TapeAlert (section 4.2.15), some extra facilities in
-the IEC mode page (see the mode parameters section) and some additional
-log pages. Medium changers which are often the "robots" in jukebox
-tape systems often support the TapeAlert mechanism and are described in
-the SMC-2 standard. 
-</para>
-<para>
-Initially <acronym>SMART</acronym> began on SCSI disks as vendor
-specific extensions. Gradually the <acronym>SMART</acronym> functionality has
-moved into the standard (often by other names) and vendors are improving
-their standards' compliance. [In the vendors' defence some of the
-"standards" such as SPC-3 are drafts and are yet to be ratified.]
-Some SCSI disk vendors have product manuals (available on the net)
-that cover the parts of the command set, defined in SPC-3 and SBC-2,
-that their disk supports. Some of these manuals fill in details that are
-left deliberately vague in the the standards. In some cases vendor specific
-mode and log pages are also outlined. 
-<footnote><para>
-Seagate's "Cheetah 15K.3 Product Manual, Rev F" contains sections on SMART,
-thermal monitor, and drive self test (section 5.2.7 to 5.2.9). It also
-lists the supported mode pages, the default and changeable values.
-</para></footnote>
-</para>
-</sect1>
-
-<sect1 id="infoexc">
-      <title>Informational Exceptions</title>
-<para>
-So what are Informational Exceptions in the SCSI context? They are a
-set of vendor specific parameters that the device monitors and if a
-"failure prediction threshhold" is exceeded then an exception is
-reported. A user is also able to set threshholds on error counters and
-have an exception reported if a condition is met. Additionally most
-modern disks monitor their temperature and will issue a warning if
-a temperature threshhold is exceeded.
-</para>
-<para>
-The "failure prediction threshhold" exception reporting and the temperature
-warning are separately controlled (in byte 2 of the Informational Exceptions
-Control (IEC) mode page).
-<footnote><para>
-Henceforth the term <emphasis>Informational Exceptions</emphasis>
-(or IE) will include both Informational Exceptions and the
-temperature (or "enclosure degraded") warnings.
-</para></footnote>
-In smartmontools the
-<command>smartctl -s on &lt;device&gt;</command> command turns on IE.
-There are various reasons why this may not (fully) work (e.g. IEC mode
-page not available or not changeable) so this command queries the device
-again after it has attempted the change and reports the state.
-The <command>smartctl -s off &lt;device&gt;</command> command turns off
-IE reporting.
-<footnote><para>
-IE have a (minor) performance impact on a disk. There are various other
-settings in the IEC mode page (e.g. PERF, EBF and LOGERR) that address
-this. The standard gives a lot of latitude to the vendor in implementing
-these additional flags. This finer level of control may be added to 
-smartmontools if the need arises.
-</para></footnote>
-</para>
-<sect2 id="iereport">
-      <title>IE reporting</title>
-<para>
-Informational Exceptions are reported via the standard SCSI mechanism of 
-an additional sense code (asc) and an additional sense code qualifier (ascq)
-pair. A selection of these pairs and the associated message (full list in
-SPC-3 document) is listed here:
-<programlisting>
-asc    ascq   message
--------------------------------------------------------
-0xb    0x1    Warning - specified temperature exceeded
-0x5d   0x0    Failure prediction threshold exceeded
-0x5d   0x2    Media failure prediction threshold exceeded
-0x5d   0x10   Hardware impending failure general hard drive failure
-0x5d   0x11   Hardware impending failure drive error rate too high
-0x5d   0x56   Spindle impending failure start unit times too high
-0x5d   0xff   Failure prediction threshold exceeded (false)
-</programlisting>
-The last entry in the above table results from setting the TEST bit and
-is for exercising the reporting mechanism rather than the indication
-of an actual error.
-See this <link linkend="testbit">footnote</link> for more information.
-</para>
-<para>
-The difficult part is that the device may detect these conditions
-independently of any command executing. Even if it detects an informational
-exception during a command it needs to be careful sending IE error
-notifications back with a command especially if that command succeeded
-(Linux will not handle this too well in the 2.4 kernel series). 
-There is aynchronous event notification (AEN) in SCSI but it is not
-reliably supported across all transports. So smartmontools relies
-on a poll from the <command>smartd</command> daemon (the default
-is every 30 minutes) to detect informational exceptions.
-</para>
-<para>
-The additional sense code and its qualifier are part of what is termed as
-the <emphasis>sense buffer</emphasis> which is the response to a 
-REQUEST SENSE command. The sense key is also found in the sense buffer.
-Synchronous SCSI commands that fail return a single byte status code of
-CHECK CONDITION. An OS kernel would see this error/warning status and
-then check the sense buffer (by doing a REQUEST SENSE or by other means)
-and decide how to continue. From smartmontools's point of view, its
-<command>smartd</command> daemon would like to process Informational 
-Exceptions without interference from the OS. This is done by setting up
-the IEC mode page's MRIE field set to 6. This instructs the SCSI 
-device to hold a pending exception until an unsolicited REQUEST SENSE is 
-sent. If an exception is pending then the sense key will be "NO SENSE"
-and the asc, ascq pair will be set accordingly. In the case of no pending
-exception the asc,ascq pair will both be zero. The pending exception is 
-also visible in the IE log page, if that is supported. So 
-<command>smartd</command> can check the device during its normal polling 
-cycle. By default this polling cycle is set to 30 minutes.
-</para>
-<para>
-Pending informational exceptions can also be checked by running
-<command>smartctl -H &lt;device&gt;</command>. A message of
-"SMART Health Status: OK" indicates that there is no pending IE.
-<footnote><para>
-<anchor id="testbit"/>
-One might worry whether the <command>smartd</command> daemon is properly set
-up or if the device really will issue IE when the need arises. The mechanism
-can be tested by setting the TEST bit in the IEC mode page. That is
-done by this command: <command>smartctl -r ioctl,3 -s on &lt;device&gt;
-</command> [ignore the extra debugging output that "-r ioctl,3" causes]. A
-special asc/ascq pair is reserved for testing (0x5d,0xff)
-and the standard associates with it this awkward message: "Failure prediction 
-threshold exceeded (false)". A call to 
-<command>smartctl -H &lt;device&gt;</command> or waiting until the next 
-<command>smartd</command> poll should produce that message if the mechanism 
-is working. The IEC mode page TEST bit can be turned off (i.e. back to normal
-IE) with <command>smartctl -s on &lt;device&gt;</command>. The output
-after the TEST bit has been activated is shown in the 
-Examples section for the Fujitsu MAM3184 disk.
-</para></footnote>
-</para>
-</sect2>
-</sect1>
-
-<sect1 id="selftest">
-      <title>Self Tests</title>
-<para>
-Rather than wait for IE tresholds to be triggered, an administrator can
-request a self test or program one to happen periodically (e.g. at 3 a.m.
-every night or perhaps weekly). All SCSI disks should support a
-<emphasis>default</emphasis> self test since it is mandatory. This can
-be invoked with the <command>smartctl -t offline &lt;device&gt;</command>
-command. Despite the term "offline" this is actually a foreground test
-of less than 2 minutes. On completion the default self test yields any 
-errors detected and makes no entry into the self test log.
-</para>
-<para>
-The other self test that are optional supported by the device are list here
-with the <command>smartctl</command> invocation in brackets:
-<itemizedlist>
-<listitem><para>
-background short [<command>smartctl -t short &lt;device&gt;</command>]
-</para></listitem>
-<listitem><para>
-background extended [<command>smartctl -t long &lt;device&gt;</command>]
-</para></listitem>
-<listitem><para>
-foreground short [<command>smartctl -C -t short &lt;device&gt;</command>]
-</para></listitem>
-<listitem><para>
-foreground extended [<command>smartctl -C -t long &lt;device&gt;</command>]
-</para></listitem>
-</itemizedlist>
-Short self tests should take less than two minutes to complete. The extended
-self tests have been known to take more than one hour for disks that are over 
-100 GBytes in size. Care should be taken with foreground tests on disks
-with mounted file systems as the OS may not take kindly to an hour delay
-on a simple READ command.
-<footnote><para>
-Linux has an additional problem with the foreground extended self tests:
-it will attempt to time out the command after 10 seconds. This will appear
-in the self test log page as an aborted self test. This problem is fixed
-in lk 2.4.22 and the soon to be released lk 2.6 series (by extending the
-timeout to 2 hours). To be on the safe side use the background extended
-test instead. Also some disks silently ignored foreground self 
-tests (e.g. Seagate Cheetah 15K.1).
-</para></footnote>
-</para>
-<para>
-Background self tests can be aborted with the <command>smartctl -X 
-&lt;device&gt; </command> command. The self test log will note that an
-abort was requested.
-</para>
-<para>
-Self tests other than the default self test cause an entry to be placed
-in the self test results log page. The 20 most recent self tests are
-listed there. The table can be listed with the
-<command>smartctl -l selftest &lt;device&gt;</command> command. All tests
-output the accumulated power on hours when the test was performed and
-the success or otherwise (e.g. the self test was aborted by the user's
-request) of the test. Unsuccesful self tests output a self test segment 
-number (vendor specific), the logical block address of the first failure
-(if appropriate) and a sense_key,asc,ascq triple. Following the self test 
-result table is the expected duration of an uninterrupted extended self test
-if that figure is provided by the device. See <xref linkend="examples"/>. 
-</para>
-</sect1>
-
-<sect1 id="errorlog">
-      <title>Error Logs</title>
-<para>
-The <command>smartctl -l error &lt;device&gt;</command> command displays
-the error counters maintained in the device's log pages. The displayed
-log pages (if available) are:
-<itemizedlist>
-<listitem><para>
-write error counters
-</para></listitem>
-<listitem><para>
-read error counters
-</para></listitem>
-<listitem><para>
-verify error counters (only displayed if non-zero)
-</para></listitem>
-<listitem><para>
-non-medium error counter (only a single number displayed)
-</para></listitem>
-</itemizedlist>
-Each of the write, read and verify error counter pages has various
-parameters codes. They are itemized below with the smartctl column
-name followed, in brackets, with SPC-3's description:
-<itemizedlist>
-<listitem><para>
-Error Corrected delay: minor [Errors corrected without substantial delay]
-</para></listitem>
-<listitem><para>
-Error Corrected delay: major [Errors corrected with possible delays]
-</para></listitem>
-<listitem><para>
-Total rereads/rewrites [Total (e.g. rewrites and rereads)]
-</para></listitem>
-<listitem><para>
-Total errors corrected [Total errors corrected]
-</para></listitem>
-<listitem><para>
-Correction algorithm invocations [Total times correction algorithm processed]
-</para></listitem>
-<listitem><para>
-Gigabytes processed {10^9} [Total bytes processed]
-</para></listitem>
-<listitem><para>
-Total uncorrected errors [Total uncorrected errors]
-</para></listitem>
-</itemizedlist>
-</para>
-<para>
-The SPC-3 draft standard then goes on to caution that the
-<emphasis>exact</emphasis> definitions of the error counters is not
-part of the standard (i.e. they are vendor specific). Unfortunately
-the current batch of SCSI disk manufacturers' product manuals has
-little or no additional information concerning log pages.
-The disk product manuals do imply that the disk firmware collects
-these counter values and periodically commits them to persistent
-storage (disk or non-volatile RAM).
-<footnote><para>
-This is why some models spring to life after minutes of inactivity and
-perform some operation even though there are no external commands
-pending.
-</para></footnote>
-They also imply that their firmware is monitoring these error counters
-and if they exceed some threshhold (e.g. in a certain time interval)
-then the firmware will report an Informational Exception.
-</para>
-</sect1>
-
-<sect1 id="smartctl">
-      <title>smartctl command line utility</title>
-<para>
-<command>smartctl</command> is a command line utility supplied
-by the smartmontools package. It has a man page (in section 8, the system
-administration tools). It has many options, only some of which apply
-to SCSI devices. Those options that don't apply to SCSI devices have "[ATA]"
-next to them. The <command>smartctl</command> command has both traditional
-single letter options (e.g. "-h") and the corresponding "--" variants
-(e.g. "--help"). Command line options that <command>smartctl</command>
-cannot interpret cause a short help message. Calling 
-<command>smartctl --help</command> will cause a voluminous usage message 
-to appear.
-</para>
-<para>
-In Linux the appropriate SCSI devices that <command>smartctl</command> can
-operate on are /dev/sd&lt;letter&gt; for disks (partition number are not
-required) and any of the various device names for a tape (e.g. /dev/st0,
-/dev/nst0a, or /dev/osst2l). It is possible that cd/dvd devices support SMART
-but the author is not aware of an examples. SCSI generic (sg) devices in 
-linux may also be used.
-</para>
-<para>
-Debug information is output when the '-r ioctl' or the '-r scsiioctl' option
-is used. More debug is output when the '-r ioctl,&lt;n&gt;' form is used
-(where "n" is a number greater or equal to 1). Both '-r ioctl' and
-'r scsiioctl,1' select the same amount of SCSI debug informations. The debug
-level currently defined are:
-<itemizedlist>
-<listitem><para>
-1 - output SCSI commands sent to the device and the status received from
-the device
-</para></listitem>
-<listitem><para>
-2 - additionally, output the first 64 bytes of data sent to or received from
-the device
-</para></listitem>
-<listitem><para>
-3 - additionally, set the IEC mode page TEST bit if accompanying the '-s on'
-option
-</para></listitem>
-</itemizedlist>
-See this <link linkend="testbit">footnote</link> for more information about the
-use of the IEC mode page TEST bit.
-</para>
-<para>
-One shortcoming of the Informational Exception data provided by
-SCSI devices (at least as defined in the current standard) is that
-no LOG SENSE page tells the user how many hours the device has been
-in use for. The device needs to track its "age" for applying timestamps
-to self test results (seen in the "Lifetime (hours)" column of the
-<command>smartctl -l selftest</command> command) if they are supported.
-So one way to circumvent this shortcoming is to do dummy self 
-tests. Hence do a <command>smartctl -t short</command> command and then
-wait 2 minutes to see the result in the self test log in which the most
-recent self test row (i.e. the first) will have the current lifetime of
-the device.
-</para>
-</sect1>
-
-<sect1 id="smartd">
-      <title>smartd daemon</title>
-<para>
-Smartd is a daemon for monitoring disks (both ATA and SCSI). It is
-recommended that tape drives and medium changers are monitored in
-a more manual fashion with the <command>smartctl</command> command
-as discussed in <xref linkend="tapes"/>.
-</para>
-<para>
-The configuration file for <command>smartd</command>
-is called <filename>/etc/smartd.conf</filename> and has a man page (as does
-the <command>smartd</command> command). The controlling daemon script
-is placed in the normal place for a distribution, typically
-<filename>/etc/rc.d/init.d/smartd</filename>.
-</para>
-<para>
-<command>smartd</command> polls the devices it has recognized when it
-was started. By default it polls every 30 minutes. It reports any adverse
-finding and noteworthy occurrences (e.g. disk drive temperature changes)
-to a log file (<filename>/var/log/messages</filename>). <command>smartd
-</command> can be configured to take other actions, for example send
-email to a system administrator.
-</para>
-<para>
-SCSI disks can be discovered by <command>smartd</command> via a scan of 
-device nodes <filename>/dev/sda</filename> through to 
-<filename>/dev/sdz</filename> by placing the word "DEVICESCAN" in
-<filename>/etc/smartd.conf</filename> file. Alternatively the
-"DEVICESCAN" word can be removed (or commented out) and SCSI devices
-named explicity:
-<programlisting>
-/dev/sda -d scsi
-/dev/sdb -d scsi
-</programlisting>
-The "-d scsi" argument tells <command>smartd</command> that it is a
-SCSI device which it would guess with these names but not names
-generated by devfs or other coherent naming tools for SCSI devices.
-</para>
-</sect1>
-
-<sect1 id="tapes">
-      <title>TapeAlert</title>
-<para>
-TapeAlert (or "tape alerts") is closely related to Informational Exceptions.
-TapeAlert is specialized for tape and medium changer devices.
-An example of a TapeAlert is an indication that the heads need to be cleaned.
-</para>
-<para>
-TapeAlert uses the Informational Exception mechanism in a special
-way. The pending TapeAlert errors are be always read from the
-TapeAlert log page. The Informational Exceptions can be used to tell
-the system that one of more of the TapeAlert flags has been set but
-the flags can be polled even when Informational Exceptions are
-disabled. In fact, the most natural way to use TapeAlert is to poll
-the flags (with smartctl) at certain points when using the tape, for
-example:
-<itemizedlist>
-<listitem><para>
-when starting a new job using the tape drive
-</para></listitem>
-<listitem><para>
-after an unrecoverable error
-</para></listitem>
-<listitem><para>
-at the end of using each tape (before it is unloaded)
-</para></listitem>
-</itemizedlist>
-</para>
-<para>
-The TapeAlert information is divided into three severity classes:
-Critical, Warning, and Information. The critical messages require
-urgent user intervention. Both critical and warning errors may lead to
-loss of data. Some of the errors are related to the medium and others
-to the hardware. This is why the TapeAlert information should be
-checked according to the tape use and not polled using fixed time
-interval.
-</para>
-<para>
-Different set of flags are defined for tape drives and media
-changers. Most of the flags are optional and the set of flags
-supported depends on the device. TapeAlert is being included into the
-SCSI-3 standards. Many SCSI-2 drives support TapeAlert but the
-implementation may not fully conform to the SCSI-3 draft definition
-used by smartctl.
-</para>
-<para>
-It is important that only one application
-(or OS driver) is monitoring tape alerts since reading the TapeAlert log 
-page deactivates all flags after they are read. 
-<footnote><para>
-In a multi initiator environment (e.g. several computers sharing the same
-tape jukebox) there can be one application monitoring tape alerts
-per initiator.
-</para></footnote>
-Currently the Linux SCSI tape drivers (st and osst) do not check the 
-TapeAlert log page. [The osst driver is specifically designed for OnStream
-drives that use the SCSI command set.]
-</para>
-<para>
-In Linux, a medium changer device (i.e. the robot in a tape jukebox) is
-accessed via a SCSI generic (sg) device name. These device names have the
-form <filename>/dev/sg&lt;n&gt;</filename> where "&lt;n&gt;" is a number
-starting at zero. To find the mapping of the device names to sg numbers
-see the output of this command: <command>cat /proc/scsi/sg/device_strs
-</command>. The first row corresponds to <filename>/dev/sg0</filename>,
-the second row to <filename>/dev/sg1</filename>, etc.
-</para>
-<para>
-Code and information on the TapeAlert mechanism have been provided by 
-Kai M&auml;kisara <email>Kai.Makisara@kolumbus.fi</email>.
-</para>
-</sect1>
-
-<sect1 id="usb1394">
-      <title>USB and IEEE1394 Disks</title>
-<para>
-USB mass storage devices and IEEE1394 devices that use the sbp2 protocol
-(which is an official SCSI transport) appear to the OS as SCSI
-devices. However in almost all cases the "device" is actually an
-ATA disk (or an ATAPI CD/DVD reader/writer) that goes through a bridge
-in the external enclosure. The first generation of these bridges had
-very poor SCSI semantics and supported virtually none of the commands
-required by smartmontools. Evidently a second generation of those
-bridges are now appearing in external enclosures. Please test your devices
-in this category (preferably with no file systems mounted); the author would
-like to be proved wrong.
-</para>
-</sect1>
-
-<sect1 id="raid">
-      <title>RAID</title>
-<para>
-It is unlikely that a hardware RAID controller will directly support 
-smartmontools. A SCSI RAID controller is a virtual target device that 
-essentially remaps the SCSI commands it receives to the physical disks on its 
-internal buses. The physical disks in a "SCSI" RAID could be ATA or sATA
-disks, in this case a SCSI bus is used between the host computer and an
-external RAID controller since LVD SCSI buses (SPI-2,3 and 4) can run 
-up to 25 metres (plus other protocol related issues).
-</para>
-<para>
-Some SCSI RAIDs equipped internally with SCSI disks allow access to the 
-physical disks via logical unit numbers (LUNs) greater than 0. The SCSI RAID
-controller itself takes LUN equal to 0. In this case smartmontools could
-be applied to the LUNs greater than 0 that refer to physical disks.
-</para>
-<para>
-Some SCSI RAIDs equipped internally ATA disks have a mechanism that
-allows ATA commands to be tunnelled to the ATA disks. The 3ware 6000
-and 7000 series Escalade controllers are examples. In this case,
-special provision has been made in smartmontools (starting with
-release 5.1-16) to tunnel the ATA command required through to the
-physical disks.  This is done by using the smartctl/smartd -d 3ware,N
-option/Directive. Please see the smartctl and smartd man pages for
-details.
-</para>
-</sect1>
-
-<sect1 id="examples">
-      <title>Examples</title>
-<para>
-Here is some output from the <command>smartctl</command>
-command. Mostly it is for the '--all' option.
-<itemizedlist>
-<listitem><para>
-StorageTek LT20 tape 'jukebox': the
-<ulink url="examples/bnch_DLT1.html">
-<literal>tape reading mechanism</literal></ulink>
-and the
-<ulink url="examples/bnch_robot.html">
-<literal>medium changer</literal></ulink> (robot).
-Note the TapeAlert warnings in the medium changer output.
-</para></listitem>
-<listitem><para>
-HP DDS-4 
-<ulink url="examples/hp_c5713a_smt_a.html">
-<literal>tape</literal></ulink>
-drive.
-</para></listitem>
-<listitem><para>
-Generic ATAPI CD-RW
-<ulink url="examples/atapi_cdrw_smt_a.html">
-<literal>cd writer</literal></ulink> is an example of a device that
-does not support SMART.
-</para></listitem>
-<listitem><para>
-IBM DDRS 39130
-<ulink url="examples/ddrs_39130_smt_a.html">
-<literal>disk</literal></ulink>
- manufactured in 1998. 
-</para></listitem>
-<listitem><para>
-Fujitsu MAM3184MP 18 GigaByte 
-<ulink url="examples/mam3184_smt_a.html">
-<literal>disk</literal></ulink> when all is well. Here is the output from
-the <command>smartctl -H</command> command after the IEC Test bit has been 
-set (with the <command>smartctl -s on -r ioctl,3</command> command) on the
-same Fujitsu <ulink url="examples/mam3184_smt_health.html">
-<literal>disk</literal></ulink> .
-</para></listitem>
-<listitem><para>
-Fujitsu MAP3735NP 73 GigaByte 
-<ulink url="examples/map3735_smt_a.html">
-<literal>disk</literal></ulink>
-</para></listitem>
-<listitem><para>
-Quantum ATLAS IV 36 WLS, 36 GigaByte 
-<ulink url="examples/ativ_36_smt_a.html">
-<literal>disk</literal></ulink>
-</para></listitem>
-<listitem><para>
-Seagate Cheetah ST318451LW 18 GigaByte 
-<ulink url="examples/st318451_smt_a.html">
-<literal>disk</literal></ulink>. It would seem that the total count of bytes
-written is reset every time the disk is power cycled. However the total
-count of bytes read seems to accumulate over power cycles.
-</para></listitem>
-</itemizedlist>
-
-</para>
-</sect1>
-
-<sect1 id="links">
-      <title>Links</title>
-<para>
-Here are some links to related projects and packages:
-<itemizedlist>
-<listitem><para>
-<anchor id="t10"/>
-primary reference site for SCSI architecture, command sets and transports
-<ulink url="http://www.t10.org">
-<literal>www.t10.org</literal></ulink>.
-<footnote><para>
-The documents found on the t10 site are actually <emphasis>draft</emphasis>
-standards. Once they are ratified they become available from ANSI for
-a fee. The t10 site maintains the last draft prior to ratification and
-the most recent draft of yet to be ratified standards.
-</para></footnote>
-</para></listitem>
-<listitem><para>
-<anchor id="scsirastools"/>
-SCSI raid monitoring tools plus a firmware update utility and other low level
-tools <ulink url="http://scsirastools.sourceforge.net">
-<literal>scsirastools.sourceforge.net</literal></ulink> .
-</para></listitem>
-<listitem><para>
-<anchor id="sg3utils"/>
-A package of SCSI low level tools for Linux called sg3_utils can be found
-on this page <ulink url="http://www.torque.net/sg">
-<literal>www.torque.net/sg</literal></ulink> (the most recent version
-is sg3_utils-1.04). Allows command level access to SCSI devices.
-</para></listitem>
-<listitem><para>
-<anchor id="howto"/>
-There is a HOWTO on the Linux SCSI subsystem in the 2.4 series here:
-<ulink url="http://www.tldp.org/HOWTO/SCSI-2.4-HOWTO">
-<literal>www.tldp.org/HOWTO/SCSI-2.4-HOWTO</literal></ulink>.
-</para></listitem>
-
-</itemizedlist>
-</para>
-</sect1>
-
-</article>
-