#!/bin/sh

### Parameters ###
logfile="/tmp/smart_report.tmp"
email="me@example.com"
subject="Full Detail SMART Status Report for `hostname -s`"
drives="da0 da1 da2 da3 da4 da5 da6 da7 ada0 ada1"
tempWarn=35
tempCrit=40
sectorsCrit=0
reSectorsCrit=10
testAgeWarn=2
warnSymbol="?"
critSymbol="!"
### Set email headers ###
(
  echo "To: ${email}"
  echo "Subject: ${subject}"
  echo 'Content-Type: multipart/alternative; boundary="boundary-string"'
  echo "Content-Type: text/html"
  echo "MIME-Version: 1.0"
  echo -e "\r\n"
) > "$logfile"
### Set email body ###

(
  echo "--boundary-string"
  echo 'Content-Type: text/plain; charset="utf-8"'
  echo 'Content-Transfer-Encoding: quoted-printable'
  echo 'Content-Disposition: inline'
  echo 
  echo 'Please see the HTML content.'
  echo
  echo "--boundary-string"
  echo 'Content-Type: text/html; charset="utf-8"'
  echo 'Content-Transfer-Encoding: quoted-printable'
  echo 'Content-Disposition: inline'
  echo
) >> "$logfile"

echo "<html>" >> "$logfile"

### CSS Stylesheet ###
(
echo "<head>"
echo "<style type "text/css">"
echo "<!--"
echo "/* @group Blink */"
echo ".blink {"
echo "   -webkit-animation: blink .75s linear infinite;"
echo "   -moz-animation: blink .75s linear infinite;"
echo "   -ms-animation: blink .75s linear infinite;"
echo "   -o-animation: blink .75s linear infinite;"
echo "	animation: blink .75s linear infinite;"
echo "}"
echo "@-webkit-keyframes blink {"
echo "   0% { opacity: 1; }"
echo "   50% { opacity: 1; }"
echo "   50.01% { opacity: 0; }"
echo "   100% { opacity: 0; }"
echo "}"
echo "@-moz-keyframes blink {"
echo "   0% { opacity: 1; }"
echo "   50% { opacity: 1; }"
echo "   50.01% { opacity: 0; }"
echo "   100% { opacity: 0; }"
echo "}"
echo "@-ms-keyframes blink {"
echo "   0% { opacity: 1; }"
echo "   50% { opacity: 1; }"
echo "   50.01% { opacity: 0; }"
echo "   100% { opacity: 0; }"
echo "}"
echo "@-o-keyframes blink {"
echo "   0% { opacity: 1; }"
echo "   50% { opacity: 1; }"
echo "   50.01% { opacity: 0; }"
echo "   100% { opacity: 0; }"
echo "}"
echo "@keyframes blink {"
echo "   0% { opacity: 1; }"
echo "   50% { opacity: 1; }"
echo "   50.01% { opacity: 0; }"
echo "   100% { opacity: 0; }"
echo "}"
echo "/* @end */"
echo "-->"
echo "</style>"
echo "</head>"
echo "<body>"
echo "<pre style=\"font-size:12px\">"
) >> "$logfile"
###### summary ######
(
  echo "<b>SMART status report summary for all drives</b>"
  echo "+------+---------------+----+-----+-----+-----+-------+-------+--------+------+------+------+-------+----+"
  echo "|Device|Serial         |Temp|Power|Start|Spin |ReAlloc|Current|Offline |UDMA  |Seek  |High  |Command|Last|"
  echo "|      |               |    |On   |Stop |Retry|Sectors|Pending|Uncorrec|CRC   |Errors|Fly   |Timeout|Test|"
  echo "|      |               |    |Hours|Count|Count|       |Sectors|Sectors |Errors|      |Writes|Count  |Age |"
  echo "+------+---------------+----+-----+-----+-----+-------+-------+--------+------+------+------+-------+----+"
) >> "$logfile"
for drive in $drives
do
  (
  smartctl -A -i -v 7,hex48 /dev/"$drive" | \
  awk -v device="$drive" -v tempWarn="$tempWarn" -v tempCrit="$tempCrit" -v reSectorsCrit="$reSectorsCrit" -v sectorsCrit="$sectorsCrit" \
  -v testAgeWarn="$testAgeWarn" -v warnSymbol="$warnSymbol" -v critSymbol="$critSymbol" \
  -v lastTestHours="$(smartctl -l selftest /dev/"$drive" | grep "# 1" | awk '{print $9}')" '\
  /Serial Number:/{serial=$3} \
  /Temperature_Celsius/{temp=$10} \
  /Power_On_Hours/{onHours=$10} \
  /Start_Stop_Count/{startStop=$10} \
  /Spin_Retry_Count/{spinRetry=$10} \
  /Reallocated_Sector/{reAlloc=$10} \
  /Current_Pending_Sector/{pending=$10} \
  /Offline_Uncorrectable/{offlineUnc=$10} \
  /UDMA_CRC_Error_Count/{crcErrors=$10} \
  /Seek_Error_Rate/{seekErrors=("0x" substr($10,3,4));totalSeeks=("0x" substr($10,7))} \
  /High_Fly_Writes/{hiFlyWr=$10} \
  /Command_Timeout/{cmdTimeout=$10} \
  END {
  testAge=sprintf("%.0f", (onHours - lastTestHours) / 24);
  bcolor="";
  ecolor="";
  if (temp > tempCrit || reAlloc > reSectorsCrit || pending > sectorsCrit || offlineUnc > sectorsCrit) {
    bcolor = "<font color='red'>";
    ecolor = "</font>";
  }
  else if (temp > tempWarn || reAlloc > 0 || pending > 0 || offlineUnc > 0 || testAge > testAgeWarn) {
    bcolor = "<font color='orange'>";
    ecolor = "</font>";
  }
  seekErrors=sprintf("%d", seekErrors);
  totalSeeks=sprintf("%d", totalSeeks);
  if (totalSeeks == "0") {
  seekErrors="N/A";
  totalSeeks="N/A";
  }
  if (hiFlyWr == "") hiFlyWr="N/A";
  if (cmdTimeout == "") cmdTimeout="N/A";
  printf "|%s%-6s%s|%-15.15s|%4s|%5.5s|%5s|%5s|%7s|%7s|%8s|%6s|%6s|%6s|%7s|%4.4s|\n",
  bcolor, device, ecolor, serial, temp, onHours, startStop, spinRetry, reAlloc, pending, offlineUnc, \
  crcErrors, seekErrors, hiFlyWr, cmdTimeout, testAge;
  }'
  ) >> "$logfile"
done
(
  echo "+------+---------------+----+-----+-----+-----+-------+-------+--------+------+------+------+-------+----+"
  echo ""
  echo ""
) >> "$logfile"
###### for each drive ######
for drive in $drives
do
  brand="$(smartctl -i /dev/"$drive" | grep "Model Family" | awk '{print $3, $4, $5}')"
  serial="$(smartctl -i /dev/"$drive" | grep "Serial Number" | awk '{print $3}')"
  (
  echo ""
  echo "========== <b>SMART status report for ${drive} drive (${brand}: ${serial})</b> =========="
  smartctl -H -A -l error /dev/"$drive"
  smartctl -l selftest /dev/"$drive" | grep "# 1 \|Num" | cut -c6-
  echo ""
  echo ""
  ) >> "$logfile"
done
sed -i '' -e '/smartctl 6.3/d' "$logfile"
sed -i '' -e '/Copyright/d' "$logfile"
sed -i '' -e '/=== START OF READ/d' "$logfile"
sed -i '' -e '/SMART Attributes Data/d' "$logfile"
sed -i '' -e '/Vendor Specific SMART/d' "$logfile"
sed -i '' -e '/SMART Error Log Version/d' "$logfile"
echo "</pre></body></html>" >> "$logfile"
echo '--boundary-string--' >> "$logfile"

### Send report ###
sendmail -t < "$logfile"

rm "$logfile"
