#!/bin/bash
#
# prtdiag is a solaris command that offers a wealth of system data.
# this script attempts to emulate that.
#
# Author: tom "spot" callaway <tcallawa@redhat.com>
#
# Todo: add more arch checking (ia64?)
# Todo: use cardctl to do PCMCIA checking

VERSION=1.2

USAGE="usage:  prtdiag [-AacCdefhis] [-o <filename>]"

# assume Celsius
CELSIUS=true

# assume we don't want alerts
ALERTS=false

if [ -z "$1" ]; then
   #assume -a
   #echo "$USAGE"
   SHOWALL=true
fi

while getopts ":aAcCdefhio:sv" opt; do
   case $opt in
      A  ) ALERTS=true ;;
      a  ) SHOWALL=true ;;
      c  ) SHOWCPU=true ;;
      C  ) CELSIUS=true ;;
      d  ) SHOWIDE=true ;;
      e  ) SHOWENV=true ;;
      f  ) CELSIUS=false ;;
      h  ) printf "$USAGE\n"
           printf "\nAvailable command line options:\n"
           printf "%b\t-a\t\tShow all (default)\n"
           printf "%b\t-c\t\tShow CPU Info\n"
	   printf "%b\t-C\t\tTemperatures in Celsius (default)\n"
           printf "%b\t-d\t\tShow IDE Device Info\n"
           printf "%b\t-e\t\tShow Environmental Info\n"
           printf "%b\t-f\t\tTemperatures in Fahrenheit\n"
           printf "%b\t-h\t\tthis help\n"
           printf "%b\t-i\t\tShow IO Device Info\n"
           printf "%b\t-o filename\tOutput to file\n"
           printf "%b\t-s\t\tShow SCSI Device Info\n"
           printf "%b\t-v\t\tOutput version information and exit\n\n"
           exit 1 ;;
      i  ) SHOWIO=true ;;
      o  ) SAVETOFILE="true"
           MYFILENAME="$OPTARG" ;;
      s  ) SHOWSCSI=true;;
      v  ) printf "%bprtdiag : version $VERSION\n"
           exit 1 ;;
      \? ) printf "$USAGE\n"
           exit 1 ;;
   esac
done

shift $(($OPTIND -1))

if [ "$SAVETOFILE" = "true" ]; then
   if [ -f "$MYFILENAME" ]; then
      printf "%bOutput file \"$MYFILENAME\" already exists! Aborting!\n"
      exit 1
   else
      if [ -d "$MYFILENAME" ]; then
         printf "%bOutput file \"$MYFILENAME\" is a directory!?! You must be kidding. Aborting!\n"
         exit 1
      fi
   fi
else
   MYFILENAME="/dev/stdout"
fi

# we need to assume SHOWALL if not set
if [ "$SHOWALL" != "true" ] && [ "$SHOWCPU" != "true" ] && [ "$SHOWIDE" != "true" ] && [ "$SHOWENV" != "true" ] && [ "$SHOWIO" != "true" ] && [ "$SHOWSCSI" != "true" ]; then
   SHOWALL=true
fi

# Alerts
# The sanest way to do alerts is via a config file. We'll look two places for it.
# First, lets look for /etc/prtdiag.cfg. If we don't find it, we'll look in the user's dir.
if [ "$ALERTS" = "true" ]; then
   if [ -f /etc/prtdiag.cfg ]; then
      CONFIGFILE="/etc/prtdiag.cfg"
      . /etc/prtdiag.cfg
   else
      if [ -f ~/prtdiag.cfg ]; then
         CONFIGFILE="~/prtdiag.cfg"
         . ~/prtdiag.cfg
      else
         # Uhoh. We didn't find it. I could implement command line parsing, but that makes things uglier.
         # Lets just tell the user that they need to make a prtdiag.cfg and disable alerts.
         printf "*** Can't find prtdiag.cfg! Please add it to /etc or ~. ***\n"
         printf "*** Disabling Alerts ***\n"
         ALERTS=false
      fi
   fi
fi

# Now, we can go ahead and use the config file data.
# I'm going to assume all entries are in the format "ATTRIBUTE=VALUE"
# If they don't have EMAIL=address, I'm going to disable ALERTS
# In theory, alerts could be sent to a pager, but then we'll be depping on a custom app. 
# Most modern pagers accept email anyways.
if [ "$ALERTS" = "true" ]; then
   if [ ! "$EMAIL" ]; then
      printf "*** Didn't find email address value in prtdiag.cfg! Disabling Alerts. ***\n"
      ALERTS=false
   fi
fi	

# *** Universal Checks 
# *** If they fail, we don't run. No ifs ands or buts.
# *** As a result, all of these checks always write to stdout

# Define archtype first. No sense wasting time checking for intel specific apps on non intel hw.
ARCHTYPE=`/bin/uname -m`

# Make sure /proc is mounted.

if [ ! -f /proc/cpuinfo ]; then
   printf "*** Can't find /proc/cpuinfo! This means that /proc isn't mounted. ***\n"
   printf "*** Mount /proc and try again. ***\n"
   printf "*** Aborting! ***\n"
   exit 0
fi

# If we're a sparc, make sure /proc/openprom is mounted.

if [ "$ARCHTYPE" = "sparc" ] || [ "$ARCHTYPE" = "sparc64" ]; then
   if [ ! -f /proc/openprom/name ]; then
      printf "*** Can't find /proc/openprom/name! This means that /proc/openprom isn't mounted. ***\n"
      printf "*** Mount /proc/openprom and try again. ***\n"
      printf "*** Aborting! ***\n"
      exit 0
   fi
fi

# Make sure lspci is installed.
# Well, if the user doesn't care about IO, then, this check isn't terribly vital.

if [ "$SHOWALL" = "true" ] || [ "$SHOWIO" = "true" ]; then
   if [ ! -f /sbin/lspci ]; then
      printf "*** Can't find /sbin/lspci! This means that pciutils isn't installed. ***\n"
      printf "*** Get pciutils from http://atrey.karlin.mff.cuni.cz/~mj/pciutils.shtml or your Linux vendor. ***\n"
      printf "*** Aborting! ***\n"
      exit 0
   fi
fi

# Make sure textutils is installed.

if [ ! -f /usr/bin/wc ]; then
   printf "*** Can't find /usr/bin/wc! This means that textutils isn't installed. ***\n"
   printf "*** Get textutils from http://www.gnu.org/software/textutils/textutils.html or your Linux vendor. ***\n"
   printf "*** Aborting! ***\n"
   exit 0
fi

# Then, make sure its not old as hell.
# textutils needs to be greater than 2.0.8

#GOODWCVER=`wc --version | head -n1 | cut -d ")" -f 2 |perl -pe 's/^\s+//' | sed 's/\(^[0-9]\)\.\([0-9]*\)\.\([0-9]*\).*/\3/' | cut -d "." -f 2- | sed 's/[a-z]//'`
#BADWCVER=8
#
# Josh Glover (2002/10/22): wc version check is now fair to versions greater
#                           than 2.0.8, but having a final digit less than 8
#                           (e.g. 2.1, 2.1.1, etc)
GOODWCVER=`wc --version | head -n1 | cut -d ")" -f 2 |perl -pe 's/^\s+//;s/\.//;s/\s+$//' |perl -pe 'if(length()<3){s/$/0/}'` 
# Well, we also should account for the old funky gnu use of "[a-z]" for numbering. 
# Lets just make those letters and remnant periods disappear. ~spot
GOODWCVER=`echo $GOODWCVER | sed 's/[a-z.]//g'`
BADWCVER=208
TRUEWCVER=`wc --version | head -n1 | cut -d ")" -f 2 |perl -pe 's/^\s+//'`

if [ "$GOODWCVER" -lt "$BADWCVER" ]; then
   printf "*** Found /usr/bin/wc, but its too old. ***\n"
   printf "*** prtdiag needs at least version 2.0.8 of textutils, you have version $TRUEWCVER. ***\n"
   printf "*** Get a newer textutils from http://www.gnu.org/software/textutils/textutils.html or your Linux vendor. ***\n"
   printf "*** Aborting! ***\n"
   exit 0
fi

# *** Non-vital checks
# *** These checks are non-vital, aka, we'll run if they fail, but we won't like it.
# *** These checks will be written to file if user specifies.

# Try to acquire hardware vendor from DMI
# If we're x86 based, that is.

if [ "$ARCHTYPE" = "sparc" ] || [ "$ARCHTYPE" = "sparc64" ] || [ "$ARCHTYPE" = "alpha" ] || [ "$ARCHTYPE" = "s390" ]; 
then
   NODMIDECODE=true
else
   if [ ! -f /usr/sbin/dmidecode ]; then
      NODMIDECODE=true
      printf "*** dmidecode was NOT found in /usr/sbin. ***\n" >> "$MYFILENAME"
      printf "*** Install the kernel-utils package! ***\n" >> "$MYFILENAME"
      printf "*** System information will be limited. ***\n\n" >> "$MYFILENAME"
   else
      if [ `whoami` != "root" ]; then
         NODMIDECODE=true
         printf "*** dmidecode found, but prtdiag is not being run as root ***\n" >> "$MYFILENAME"
         printf "*** user = `whoami` ***\n" >> "$MYFILENAME"
         printf "*** For optimal output, run this script as root. ***\n" >> "$MYFILENAME"
         printf "*** System information will be limited. ***\n\n" >> "$MYFILENAME"
      fi
   fi	
fi

# We only care about this check if we're looking at environmental data

if [ "$SHOWALL" = "true" ] || [ "$SHOWENV" = "true" ]; then

# See if lm_sensors is installed/configured
# lm_sensors is x86 only.

   if [ "$ARCHTYPE" = "sparc" ] || [ "$ARCHTYPE" = "sparc64" ] || [ "$ARCHTYPE" = "alpha" ] || [ "$ARCHTYPE" = "s390" ]; then
      NOLMSENSORS=true
   else
      if [ ! -f /usr/sbin/sensors-detect ]; then
         NOLMSENSORS=true
         printf "*** lm_sensors was NOT found. ***\n" >> "$MYFILENAME"
         printf "*** Get lm_sensors from http://www2.lm-sensors.nu/~lm78/ or your Linux vendor. ***\n" >> "$MYFILENAME"
         printf "*** System information will be limited. ***\n\n" >> "$MYFILENAME"
      else
#         LMSCHECK=`grep "alias char-major-89 i2c-dev" /etc/modules.conf`
#
# Josh Glover (2002/10/22): What if the alias is tab-separated instead?
#
         LMSCHECK=`grep "alias char-major-89[[:blank:]]\+i2c-dev" /etc/modules.conf`
         if [ -z "$LMSCHECK" ]; then
            NOLMSENSORS=true
            printf "*** lm_sensors was found, but it doesn't look configured. ***\n" >> "$MYFILENAME"
            printf "*** Please run /usr/sbin/sensors-detect and edit /etc/modules.conf ***\n" >> "$MYFILENAME"
            printf "*** System information will be limited. ***\n\n" >> "$MYFILENAME"
         fi
      fi
   fi
fi

# *** System Summary
# *** We always provide this. Always.

# Add system hostname, and put a time/date stamp
SYSTEMHOSTNAME=`hostname`
TIMEOFREPORT=`date`

printf "System Hostname: $SYSTEMHOSTNAME\n"
printf "Time of Report: $TIMEOFREPORT\n"

# Special case (aka, not intel)
# First one, sparc/sparc64

if [ "$ARCHTYPE" = "sparc" ] || [ "$ARCHTYPE" = "sparc64" ]; then

# Can the system vendor be anything but Sun?

   SYSTEMVENDOR="Sun"
   MODELTYPE=`cut -d "'" -f 2 /proc/openprom/banner-name`
   NUMOFCPUS=`grep "ncpus probed" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'`
   TYPEOFCPUS=`grep -w "cpu" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'`
   SPEEDOFCPUSINMHZ=
   CPUCOUNTVAR=1
   CPUSEARCHSTRING=`cat /proc/openprom/banner-name`
   CPUCHECKSTRING=`echo "$CPUSEARCHSTRING" | grep "MHz"`
   if [ "$CPUCHECKSTRING" ]; then
	 CPUMOVEVAR=`cut -d " " -f $CPUCOUNTVAR /proc/openprom/banner-name`
	 while [ "$CPUMOVEVAR" ]; do
	    if [ `cut -d " " -f $CPUCOUNTVAR /proc/openprom/banner-name | grep "MHz"` ]; then
               SPEEDOFCPUSINMHZ=`cut -d " " -f $CPUCOUNTVAR /proc/openprom/banner-name | cut -d "M" -f 1`
               CPUMOVEVAR=
            else
               CPUCOUNTVAR=`expr $CPUCOUNTVAR + 1`
	       CPUMOVEVAR=`cut -d " " -f $CPUCOUNTVAR /proc/openprom/banner-name`
            fi
         done
   else
         SPEEDOFCPUSINMHZ="????"
   fi
else

# Special case #2: Alpha

   if [ "$ARCHTYPE" = "alpha" ]; then
      MODELTYPE=`grep "platform string" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//' | sed 's/[0-9][0-9][0-9] MHz//' | sed 's/[0-9][0-9] MHz//' | sed 's/[0-9][0-9][0-9][0-9] MHz//' | perl -pe 's/\s+$//'`
      NUMOFCPUS=`grep "cpus detected" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'| perl -pe 's/\s+$//'`
      TYPEOFCPUS=`grep "cpu model" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'| perl -pe 's/\s+$//'`
      RAWCPUSPEED=`grep "cycle frequency" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
      SPEEDOFCPUSINMHZ=`expr $RAWCPUSPEED / 1000000`
   else

# Special case #3: S390

      if [ "$ARCHTYPE" = "s390" ]; then
	 SYSTEMVENDOR=`grep "vendor_id" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'`
         MODELTYPE=`grep "machine =" /proc/cpuinfo | tail -n1 | cut -d "=" -f 4 | perl -pe 's/^\s+//'`
         NUMOFCPUS=`grep "# processors" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'`
         TYPEOFCPUS=`grep "version =" /proc/cpuinfo | tail -n 1 | cut -d "," -f 1 | cut -d "=" -f 2- | perl -pe 's/^\s+//'`
#         RAWCPUSPEED=
         SPEEDOFCPUSINMHZ="VARIABLE"
      else

# If not caught by a special case, you must be x86!

      if [ "$NODMIDECODE" = "true" ]; then
         SYSTEMVENDOR="Unknown Vendor"
      else
         SYSTEMVENDOR=`/usr/sbin/dmidecode |grep -A 1 "System Information Block" |grep "Vendor"| head -n1 |cut -d " " -f 2-`
      fi

# deal with the blank case

      UNSPACEDSYSTEMVENDOR=`echo "$SYSTEMVENDOR" | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
      if [ -z "$UNSPACEDSYSTEMVENDOR" ]; then
         SYSTEMVENDOR="Unknown Vendor"
      fi

# deal with the unset case (mrhat)

      if [ "$SYSTEMVENDOR" = "System Manufacturer" ]; then
         SYSTEMVENDOR="Unknown Vendor"
      fi

      if [ "$NODMIDECODE" = "true" ]; then
         MODELTYPE="Unknown Model"
      else
         MODELTYPE=`/usr/sbin/dmidecode |grep -A 2 "System Information Block" |grep "Product" | head -n1 |cut -d " " -f 2-| perl -pe 's/\s+$//'`
      fi

# deal with the blank case

      UNSPACEDMODELTYPE=`echo "$MODELTYPE" | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
      if [ -z "$UNSPACEDMODELTYPE" ]; then
         MODELTYPE="Unknown Model"
      fi



# deal with the unset case (mrhat)

      if [ "$MODELTYPE" = "System Name" ]; then
         MODELTYPE="Unknown Model"
      fi

      NUMOFCPUS=`grep processor /proc/cpuinfo | grep -v "ID" | wc -l |  perl -pe 's/^\s+//'`
      TYPEOFCPUS=`grep "model name" /proc/cpuinfo |head -n 1 | cut -d " " -f 3-`
      SPEEDOFCPUSINMHZ=`grep "cpu MHz" /proc/cpuinfo |head -n 1 | cut -d " " -f 3-`
     fi
   fi
fi

if [ "$ARCHTYPE" = "sparc" ] || [ "$ARCHTYPE" = "sparc64" ]; then
   printf "%bSystem Configuration: [$ARCHTYPE] $SYSTEMVENDOR $MODELTYPE\n" >> $MYFILENAME
else
   if [ "$ARCHTYPE" = "alpha" ]; then
      printf "%bSystem Configuration: [$ARCHTYPE] $MODELTYPE ($NUMOFCPUS X $TYPEOFCPUS $SPEEDOFCPUSINMHZ MHz)\n" >> "$MYFILENAME"
   else
      printf "%bSystem Configuration: [$ARCHTYPE] $SYSTEMVENDOR $MODELTYPE ($NUMOFCPUS X $TYPEOFCPUS $SPEEDOFCPUSINMHZ MHz)\n" >> "$MYFILENAME"
   fi
fi

HOSTBUSCLOCKSPEED=`dmesg |grep "host bus clock speed" | cut -d " " -f 7`
 
if [ -z "$HOSTBUSCLOCKSPEED" ]; then
   HOSTBUSCLOCKSPEED="UNKNOWN"
fi

if [ "$HOSTBUSCLOCKSPEED" = "UNKNOWN" ]; then
   printf "%bSystem clock frequency: UNKNOWN (no APIC in kernel?)\n" >> "$MYFILENAME"
else
   printf "System clock frequency: $HOSTBUSCLOCKSPEED MHz\n" >> "$MYFILENAME"
fi

# Well, the problem with defaulting to dmesg instead of /var/log/dmesg, is
# that dmesg only holds a small amount of information (and can lose 
# bootdata)
# New heuristic checks to see if its there, and uses it if it is.
# ~spot
#

if [ -f /var/log/dmesg ]; then
	AMTOFMEMINKB=`grep "Memory:" /var/log/dmesg | head -n1 | cut -d ":" -f 2 | cut -d "/" -f 2 | cut -d "k" -f1 | perl -pe 's/\s+$//'`
else
	AMTOFMEMINKB=`dmesg |grep "Memory:" | head -n1 | cut -d ":" -f 2 | cut -d "/" -f 2 | cut -d "k" -f1 | perl -pe 's/\s+$//'`
fi

# If we still have nothing, then get it from /proc/meminfo (even though 
# thats a bit off. ~spot
if [ -z $AMTOFMEMINKB ]; then
	AMTOFMEMINKB=`cat /proc/meminfo | grep MemTotal | cut -d ":" -f 2- | perl -pe 's/^\s+//' | cut -d " " -f 1`
	AMTOFMEMINMB=`expr $AMTOFMEMINKB / 1024`
else
	AMTOFMEMINMB=`expr $AMTOFMEMINKB / 1024`
fi

printf "%bMemory size (approximate): $AMTOFMEMINMB Megabytes\n" >> "$MYFILENAME"

# *** CPU section

if [ "$SHOWALL" = "true" ] || [ "$SHOWCPU" = "true" ]; then
   printf "%b\n========================= CPUs ========================\n\n" >> "$MYFILENAME"
   printf " CPU #\t    CPU MHz     CACHE (KB)     Bogomips\n"  >> "$MYFILENAME"
   printf "%b-------\t   ---------   ------------   ----------\n" >> "$MYFILENAME"
   if [ "$ARCHTYPE" = "sparc" ] || [ "$ARCHTYPE" = "sparc64" ]; then 
      CPUSPEED="$SPEEDOFCPUSINMHZ"
      CPUCACHE="UNKNOWN"
      i=1
         while [ "$NUMOFCPUS" -ge "$i" ]; do
            CPULINE=`expr $i - 1`
# I don't know of a way to find CPU cache size on Linux/SPARC
            BOGOMIPS=`grep "Cpu$CPULINE" /proc/cpuinfo | grep Bogo | cut -d ":" -f 2 | perl -pe 's/^\s+//'`
            printf "   $i\t      $CPUSPEED\t $CPUCACHE\t$BOGOMIPS\n" >> "$MYFILENAME"
            i=`expr $i + 1`
         done
   else
      if [ "$ARCHTYPE" = "alpha" ]; then
         CPUSPEED="$SPEEDOFCPUSINMHZ"
         CPUCACHE="UNKNOWN"
         i=1
         while [ "$NUMOFCPUS" -ge "$i" ]; do
            CPULINE=`expr $i - 1`
            BOGOMIPS=`grep BogoMIPS /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
            printf "   $CPULINE\t      $CPUSPEED\t $CPUCACHE\t$BOGOMIPS\n" >> "$MYFILENAME"
            i=`expr $i + 1`
         done
      else
         if [ "$ARCHTYPE" = "s390" ]; then
            CPUCACHE="UNKNOWN"
	    CPUSPEED="VARIABLE"
	    BOGOMIPS=`grep "bogomips per cpu" /proc/cpuinfo | cut -d ":" -f 2 | perl -pe 's/^\s+//'`
            i=1
	    while [ "$NUMOFCPUS" -ge "$i" ]; do
               CPULINE=`expr $i - 1`
               printf "   $CPULINE\t    $CPUSPEED\t $CPUCACHE\t$BOGOMIPS\n" >> "$MYFILENAME"
               i=`expr $i + 1`
            done
         else
            for i in `grep "^[^*]*processor" /proc/cpuinfo | grep -v "ID" |cut -d ":" -f 2| perl -pe 's/^\s+//'`; do
               CPULINE=`grep processor /proc/cpuinfo |grep -w $i`
               CPUSPEED=`grep -A18 -w "$CPULINE" /proc/cpuinfo |grep "cpu MHz" | cut -d " " -f 3-`
               CPUCACHE=`grep -A18 -w "$CPULINE" /proc/cpuinfo |grep "cache size" | cut -d " " -f 3-`
               BOGOMIPS=`grep -A18 -w "$CPULINE" /proc/cpuinfo |grep "bogomips" | cut -d " " -f 2`
               printf "   $i\t    $CPUSPEED\t  $CPUCACHE\t$BOGOMIPS\n" >> "$MYFILENAME"
            done
         fi
      fi
   fi
fi

# *** IO device section

if [ "$SHOWALL" = "true" ] || [ "$SHOWIO" = "true" ]; then
   printf "\n====================== IO Devices =====================\n" >> "$MYFILENAME"
   if [ ! -f /proc/pci ] && [ ! -f /proc/isapnp ]; then
      printf "\n***** No PCI or ISA buses found! *****\n" >> "$MYFILENAME"
   else
      printf "\n  BUS	\t  TYPE   \t   DESCRIPTION\n" >> "$MYFILENAME"
      printf "%b-------\t\t---------\t ---------------\n" >> "$MYFILENAME"
# Now, lets scan for valid PCI devices.
# First, lets see if we have a bus to scan:
      if [ -f /proc/pci ]; then
         ALLDONE=0
         COUNTERVAR=1
         PREVIOUSDEVICE="none"
         while [ $ALLDONE != 1 ]; do
            CURRENTDEVICE=`/sbin/lspci |grep -vi "bridge:"| grep -vi "SMBus" |head -n$COUNTERVAR |tail -1`
# check to see if we've displayed this one already
            if [ "$PREVIOUSDEVICE" = "$CURRENTDEVICE" ]; then
               ALLDONE=1
            else
               DEVICETYPE=`echo "$CURRENTDEVICE" | cut -d " " -f 2- | cut -d ":" -f 1 | cut -d " " -f 1`
               if [ "$DEVICETYPE" = "IDE" ]; then
                  IDECHANFOUND=true
               fi
               if [ "$DEVICETYPE" = "SCSI" ]; then
                  SCSICHANFOUND=true
               fi
               DEVICEDESCRIPTION=`echo "$CURRENTDEVICE" | cut -d " " -f 2- | cut -d ":" -f 2`
               LENGTHOFDEVICETYPE=`echo "$DEVICETYPE" | wc -m | perl -pe 's/^\s+//'`
               if [ "$DEVICETYPE" = "VGA" ]; then
                  AGPCHECK=`/sbin/lspci -v |grep -A10 "VGA" | grep "Capabilities" | grep "AGP"`
                  if [ "$AGPCHECK" ]; then
                     TYPEOFPCI="AGP"
                  else
                     TYPEOFPCI="PCI"
                  fi
               else
                  TYPEOFPCI="PCI"
               fi
               if [ $LENGTHOFDEVICETYPE -gt 6 ]; then
                  printf "  $TYPEOFPCI\t\t$DEVICETYPE\t$DEVICEDESCRIPTION\n" >> "$MYFILENAME"
               else
                  printf "  $TYPEOFPCI\t\t$DEVICETYPE\t\t$DEVICEDESCRIPTION\n" >> "$MYFILENAME"
               fi
               COUNTERVAR=`expr $COUNTERVAR + 1`
               PREVIOUSDEVICE="$CURRENTDEVICE"
            fi
         done
      fi
# Next, lets scan for valid ISA devices.
# This assumes a recent 2.4 kernel.
      if [ -f /proc/isapnp ]; then
         for i in `grep "^[^*]*Card" /proc/isapnp | cut -d " " -f 2 | perl -pe 's/^\s+//'`; do
            ISATYPE=`grep "Card $i" /proc/isapnp | cut -d "'" -f 2 | cut -d ":" -f 2`
            printf "  ISA\t\t\t\t $ISATYPE\n" >> "$MYFILENAME"
         done
      fi
   fi
fi

# *** IDE devices section

if [ "$SHOWALL" = true ] || [ "$SHOWIDE" = "true" ]; then
   printf "%b\n====================== IDE Devices ======================\n\n" >> "$MYFILENAME"
   if [ "$IDECHANFOUND" = "true" ]; then
      printf "Host / Channel\t  Vendor\t  Model  \t\tType\n" >> "$MYFILENAME"
      printf "%b---------------\t----------\t---------\t\t--------\n" >> "$MYFILENAME"
      for IDEHOST in 0 1 ; do {
         for IDECHAN in a b c d ; do {
            [ -r /proc/ide/ide${IDEHOST}/hd${IDECHAN}/model ] && {
            [ ${do_hdr} ] && {
            echo; do_hdr= 
            }
            read IDEMEDIA </proc/ide/ide${IDEHOST}/hd${IDECHAN}/media
            IDEVENDOR=`cut -d " " -f 1 /proc/ide/ide${IDEHOST}/hd${IDECHAN}/model`
            IDEMODEL=`cut -d " " -f 2- /proc/ide/ide${IDEHOST}/hd${IDECHAN}/model`
# If the model is blank, assume the model is the vendor
            if [ -z "$IDEMODEL" ]; then
               IDEMODEL="$IDEVENDOR"
               IDEVENDOR=" "
            fi
# If the model is the same as the vendor, assume the model is the vendor
            if [ "$IDEMODEL" = "$IDEVENDOR" ]; then
               IDEMODEL="$IDEVENDOR"
               IDEVENDOR=" "
            fi
            LENGTHOFIDEVENDOR=`echo "$IDEVENDOR" | perl -pe 's/\s+$//' | wc -m | perl -pe 's/^\s+//'`
            LENGTHOFIDEMODEL=`echo "$IDEMODEL" | perl -pe 's/\s+$//' | wc -m | perl -pe 's/^\s+//'`
            if [ $LENGTHOFIDEVENDOR -ge 8 ]; then
               printf "ide$IDEHOST / hd$IDECHAN\t$IDEVENDOR\t$IDEMODEL" >> "$MYFILENAME"
            else
               printf "ide$IDEHOST / hd$IDECHAN\t$IDEVENDOR\t\t$IDEMODEL" >> "$MYFILENAME"
            fi
            if [ $LENGTHOFIDEMODEL -ge 16 ]; then
               printf "\t$IDEMEDIA\n"  >> "$MYFILENAME"
            else
               if [ $LENGTHOFIDEMODEL -ge 8 ]; then
                  printf "\t\t$IDEMEDIA\n" >> "$MYFILENAME"
               else
                  printf "\t\t\t$IDEMEDIA\n" >> "$MYFILENAME"
               fi
            fi
            }
      } done
   } done
   else
      printf "*** No IDE channels present, hence no devices! ***\n" >> "$MYFILENAME"
   fi
fi

# *** SCSI Device section

if [ "$SHOWALL" = "true" ] || [ "$SHOWSCSI" = "true" ]; then
if [ "$ARCHTYPE" = "s390" ]; then
   printf "%b\n===================== DASD Devices ======================\n\n" >> "$MYFILENAME"
   if [ ! -f /proc/dasd/devices ]; then
      DASDCHANFOUND=false
   else
      cat /proc/dasd/devices
   fi
else
   printf "%b\n===================== SCSI Devices ======================\n\n" >> "$MYFILENAME"
   if [ ! -f /proc/scsi/scsi ]; then
      SCSICHANFOUND=false
   else
      SCSIPROCCHECK=`head -n1 /proc/scsi/scsi | cut -d ":" -f 2- | perl -pe 's/^\s+//'`
      if [ "$SCSIPROCCHECK" != "none" ]; then
         SCSICHANFOUND=true
      fi
   fi
   if [ "$SCSICHANFOUND" = "true" ]; then
      printf "Host/Channel/ID/LUN\t Vendor\t\t  Model\t\t  Type\n" >> "$MYFILENAME"
      printf "%b-------------------\t--------\t---------\t--------\n" >> "$MYFILENAME"
      for shost in 0 1 2 3 4 5 6 7 8 9; do
         for schan in 0 1 2 3 4 5 6 7 8 9; do
            for sid in `egrep "Host: scsi${shost} Channel: 0${schan}" /proc/scsi/scsi | cut -d ":" -f 4 | cut -d " " -f 2`; do
               SCSILUN=`egrep -A 2 "Host: scsi${shost} Channel: 0${schan} Id: ${sid}" /proc/scsi/scsi | cut -d ":" -f 5- | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
               SCSIVEND=`egrep -A 2 "Host: scsi${shost} Channel: 0${schan} Id: ${sid}" /proc/scsi/scsi | grep "Vendor" | cut -d ":" -f 2 | cut -d " " -f 2 | perl -pe 's/\s+$//'`
               SCSIMODEL=`egrep -A 2 "Host: scsi${shost} Channel: 0${schan} Id: ${sid}" /proc/scsi/scsi | grep "Model" | cut -d ":" -f 3 | cut -d " " -f 2| perl -pe 's/\s+$//'`
               SCSITYPE=`egrep -A 2 "Host: scsi${shost} Channel: 0${schan} Id: ${sid}" /proc/scsi/scsi | grep "Type" | cut -d ":" -f 2 | perl -pe 's/^\s+//' | cut -d " " -f 1 | perl -pe 's/\s+$//'`
               LENGTHOFSCSIVENDOR=`echo "$SCSIVEND" | perl -pe 's/\s+$//' | wc -m | perl -pe 's/^\s+//'`
               LENGTHOFSCSIMODEL=`echo "$SCSIMODEL" | perl -pe 's/\s+$//' | wc -m | perl -pe 's/^\s+//'`
               if [ $LENGTHOFSCSIVENDOR -ge 8 ]; then
                  printf "scsi${shost} / ${schan} / ${sid} / $SCSILUN\t$SCSIVEND\t" >> "$MYFILENAME"
               else
                  printf "scsi${shost} / ${schan} / ${sid} / $SCSILUN\t$SCSIVEND\t\t" >> "$MYFILENAME"
               fi
               if [ $LENGTHOFSCSIMODEL -ge 8 ]; then
                  printf "$SCSIMODEL\t$SCSITYPE\n" >> "$MYFILENAME"
               else
                  printf "$SCSIMODEL\t\t$SCSITYPE\n" >> "$MYFILENAME"
               fi
            done
         done
      done
   else
      printf "*** No SCSI channels present, hence no devices! ***\n" >> "$MYFILENAME"
   fi
fi
fi

# *** Environmental Section

if [ "$SHOWALL" = "true" ] || [ "$SHOWENV" = "true" ]; then
# Now, lets do the lm_sensors stuff.
   printf "%b\n================== Environmental Status =================\n\n" >> "$MYFILENAME"
   if [ "$NOLMSENSORS" = "true" ]; then
      printf "*** Unable to provide Environmental Status Data. ***\n\n" >> "$MYFILENAME"
   else
# First, lets see if we have any data on the fans.
      printf "%b========================== Fans =========================\n\n" >> "$MYFILENAME"
# No fans found by lm_sensors! (likely)
      FANSTRING=`sensors |grep "fan*"`
      if [ -z "$FANSTRING" ]; then
         printf "%b*** Fan data is not available for this system. ***\n" >> "$MYFILENAME"
      else
         printf "  NUM\t\t  SPEED  \n" >> "$MYFILENAME"
         printf "%b-------\t\t---------\n" >> "$MYFILENAME"
# *** OLD HEURISTICS: This doesn't work.
#        for i in `sensors |grep "fan*"| cut -d ":" -f 1 | sed 's/fan//'`; do
#
         NUMFANS=`sensors |grep "[Ff]an*" | cut -d ":" -f 1 | wc -l | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
         k=1
         while [ $k -le $NUMFANS ]; do
            l=`expr $k - 1`
            FANTAILNUMVAR=`expr $NUMFANS - $l` 
            FANSPEED=`sensors |grep "[Ff]an" | tail -n$FANTAILNUMVAR | head -n1 | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
# 0 fanspeed?
            if [ "$FANSPEED" = "0 RPM" ]; then
               FANSPEED="0 RPM (disconnected?)"
            fi
# negative fanspeed?
            FANSPEEDSIGN=`echo "$FANSPEED" | grep "-"`
            if [ ! -z "$FANSPEEDSIGN" ]; then
               FANSPEED="$FANSPEED (bad/disconnected fan?)"
            fi
            if [ "$ALERTS" = "true" ]; then
               if [ "$FANMIN" ]; then
# Assumption: There are no more than 5 fans in any single machine.
# There's gotta be a better way to do this, this methodology is bad and wrong.
# And yes, we could make the checking case insensitive, but... nah.
                  if [ $k = 1 ]; then
                     if [ "$IGNOREFAN1" != "true" ]; then
                        RUNFANALERTS=true
                     else
                        RUNFANALERTS=false
                     fi
                  else
                     if [ $k = 2 ]; then
                        if [ "$IGNOREFAN2" != "true" ]; then
                           RUNFANALERTS=true
                        else
                           RUNFANALERTS=false
                        fi
                     else
                        if [ $k = 3 ]; then
                           if [ "$IGNOREFAN3" != "true" ]; then
                              RUNFANALERTS=true
                           else
                              RUNFANALERTS=false
                           fi
                        else
                           if [ $k = 4 ]; then
                              if [ "$IGNOREFAN4" != "true" ]; then
                                 RUNFANALERTS=true
                              else
                                 RUNFANALERTS=false
                              fi
                           else
                              if [ $k = 5 ]; then
                                 if [ "$IGNOREFAN5" != "true" ]; then
                                    RUNFANALERTS=true
                                 else
                                    RUNFANALERTS=false
                                 fi
                              else
                                 if [ $k -ge 6 ]; then
                                    RUNFANALERTS=false
                                 fi
                              fi
                           fi
                        fi
                     fi
                  fi
                  if [ "$RUNFANALERTS" = "true" ]; then
                     FANDISCONNECTCHECK=`echo "$FANSPEED" | grep "disconnected"`
                     if [ "$FANDISCONNECTCHECK" ]; then
                        printf "PRTDIAG ALERT: Fan $k is in bad/disconnect condition on $SYSTEMHOSTNAME\nTime of Alert: $TIMEOFREPORT" | 
mail -s "PRTDIAG ALERT: Fan alert on $SYSTEMHOSTNAME" $EMAIL
                     else
                        if [ $FANSPEED -lt $FANMIN ]; then
                           printf "PRTDIAG ALERT: Fan $k is running at $FANSPEED on $SYSTEMHOSTNAME, which is less than $FANMIN.\nTime of Alert: $TIMEOFREPORT" | mail -s "PRTDIAG ALERT: Fan alert on $SYSTEMHOSTNAME" $EMAIL
                        fi
                     fi
                  fi
               fi
            fi
            printf "   $k\t\t$FANSPEED\n" >> "$MYFILENAME"
# increment our counter var
            k=`expr $k + 1`
         done
      fi
# Next, lets see if we have Temperature Data from sensors.
      if [ "$CELSIUS" = "true" ]; then
         printf "%b\n============= System Temperatures (Celsius) =============\n\n" >> "$MYFILENAME"
      else
         printf "%b\n============ System Temperatures (Fahrenheit) ===========\n\n" >> "$MYFILENAME"
      fi
      TEMPSTRING=`sensors | grep "[Tt]emp*"`
      if [ -z "$TEMPSTRING" ]; then
         printf "%b*** Temperature data is not available for this system. ***\n" >> "$MYFILENAME"
      else
         printf "  SENSOR  \t  TEMP  \t  TYPE\n" >> "$MYFILENAME"
         printf "%b----------\t--------\t--------\n" >> "$MYFILENAME"
# *** OLD HEURISTICS HERE : This doesn't really work right in all cases.
#
#         TEMPSENSORMULTICHECK=`sensors |grep "temp*" | cut -d ":" -f 1 | sed 's/temp//' |head -n1 | cat -A`
#
#         if [ "$TEMPSENSORMULTICHECK" = "$" ]; then
#
          NUMSENSORS=`sensors |grep "[Tt]emp*" | cut -d ":" -f 1 | sed 's/[tT]emp//' | wc -l |  perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
          if [ $NUMSENSORS = 1 ]; then
# we found one, but only one sensor
            if [ "$CELSIUS" = "true" ]; then
               SENSORTEMP=`sensors |grep "[Tt]emp:" | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
            else
               SENSORTEMP=`sensors -f |grep "[Tt]emp:" | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
            fi
            if [ "$CELSIUS" = "true" ]; then
               STRIPPEDSENSORTEMP=`echo "$SENSORTEMP" | sed 's/C//' | sed 's/+//' | cut -d "." -f 1`
               if [ $STRIPPEDSENSORTEMP -ge 100 ]; then
                  SENSORTEMP="$SENSORTEMP (bad/disconnected sensor?)"
               fi
            else
               STRIPPEDSENSORTEMP=`echo "$SENSORTEMP" | sed 's/F//' | sed 's/+//' | cut -d "." -f 1`
               if [ $STRIPPEDSENSORTEMP -ge 212 ]; then
                  SENSORTEMP="$SENSORTEMP (bad/disconnected sensor?)"
               fi
            fi
            TEMPSENSORTYPE=`sensors | grep "[Tt]emp" | cut -d ":" -f 1 | sed 's/[Tt]emp$i//' | sed 's/[Tt]emp//'`
# Explanation:
# If we're enabling alerts, and we've got a tempmax setting, and we don't want to ignore the #1 sensor, check for alerts.
# If any of the above conditions aren't met, don't check for alerts, keep flying.
            if [ "$ALERTS" = "true" ]; then
               if [ "$TEMPMAX" ]; then
                  if [ "$IGNORESENSOR1" != "true" ]; then
                     DISCONNECTCHECK=`echo "$SENSORTEMP" | grep "disconnected sensor"`
                     if [ "$DISCONNECTCHECK" ]; then
                        printf "PRTDIAG ALERT: Temperature sensor $i is in bad/disconnect condition on $SYSTEMHOSTNAME\nTime of Alert: $TIMEOFREPORT" | mail -s "PRTDIAG ALERT: Temperature alert on $SYSTEMHOSTNAME" $EMAIL
                     else
                        if [ $STRIPPEDSENSORTEMP -ge $TEMPMAX ]; then
                           printf "PRTDIAG ALERT: Temperature sensor $i is reporting $STRIPPEDSENSORTEMP which is greater than $TEMPMAX on $SYSTEMHOSTNAME\nTime of Alert: $TIMEOFREPORT" |mail -s "PRTDIAG ALERT: Temperature alert on $SYSTEMHOSTNAME" $EMAIL
                        fi
                     fi
                  fi
               fi                  
            fi
            printf "    1\t\t   $STRIPPEDSENSORTEMP\t\t  $TEMPSENSORTYPE\n" >> "$MYFILENAME"
         else
# *** OLD HEURISTICS: Again, not quite what we want.
#
#            for i in `sensors |grep "temp*" | cut -d ":" -f 1 | sed 's/temp//'`; do
#
            i=1
            while [ $i -le $NUMSENSORS ]; do 
               j=`expr $i - 1`
               TAILNUMVAR=`expr $NUMSENSORS - $j`
#               echo "TAILNUMVAR = $TAILNUMVAR"
               if [ "$CELSIUS" = "true" ]; then
                  SENSORTEMP=`sensors | grep "[Tt]emp" | tail -n$TAILNUMVAR | head -n1 | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
#                 SENSORTEMP=`sensors |grep [Tt]emp | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
               else
                  SENSORTEMP=`sensors -f | grep "[Tt]emp" | tail -n$TAILNUMVAR | head -n1 | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
#                 SENSORTEMP=`sensors -f |grep temp$i | cut -d ":" -f 2 | cut -d "(" -f 1 | perl -pe 's/^\s+//' | perl -pe 's/\s+$//'`
               fi
# If the reading is > 100 Celsius or > 212 Fahrenheit, perhaps this reading is bogus?
               if [ "$CELSIUS" = "true" ]; then
                  STRIPPEDSENSORTEMP=`echo "$SENSORTEMP" | sed 's/C//' | sed 's/+//' | cut -d "." -f 1`
                  if [ $STRIPPEDSENSORTEMP -ge 100 ]; then
                     SENSORTEMP="$SENSORTEMP (bad/disconnected sensor?)"
                  fi
               else
                  STRIPPEDSENSORTEMP=`echo "$SENSORTEMP" | sed 's/F//' | sed 's/+//' | cut -d "." -f 1`
                  if [ $STRIPPEDSENSORTEMP -ge 212 ]; then
                     SENSORTEMP="$SENSORTEMP (bad/disconnected sensor?)"
                  fi
               fi
               TEMPSENSORTYPE=`sensors | grep "[Tt]emp" | tail -n$TAILNUMVAR | head -n1 | cut -d ":" -f 1 | sed 's/[Tt]emp$i//' | sed 's/[Tt]emp//'`
               if [ "$ALERTS" = "true" ]; then
                  if [ "$TEMPMAX" ]; then
# Assumption: There are no more than 5 temperature sensors in any single machine.                     
# There's gotta be a better way to do this, this methodology is bad and wrong.
# And yes, we could make the checking case insensitive, but... nah.
                     if [ $i = 1 ]; then
                        if [ "$IGNORESENSOR1" != "true" ]; then
                           RUNTEMPALERTS=true
                        else
                           RUNTEMPALERTS=false
                        fi
                     else
                        if [ $i = 2 ]; then
                           if [ "$IGNORESENSOR2" != "true" ]; then
                              RUNTEMPALERTS=true
                           else
                              RUNTEMPALERTS=false
                           fi
                        else
                           if [ $i = 3 ]; then
                              if [ "$IGNORESENSOR3" != "true" ]; then
                                 RUNTEMPALERTS=true
                              else
                                 RUNTEMPALERTS=false
                              fi
                           else
                              if [ $i = 4 ]; then
                                 if [ "$IGNORESENSOR4" != "true" ]; then
                                    RUNTEMPALERTS=true
                                 else
                                    RUNTEMPALERTS=false
                                 fi
                              else
                                 if [ $i = 5 ]; then
                                    if [ "$IGNORESENSOR5" != "true" ]; then
                                       RUNTEMPALERTS=true
                                    else
                                       RUNTEMPALERTS=false
                                    fi
                                 else
                                    if [ $i -ge 6 ]; then
                                       RUNTEMPALERTS=false
                                    fi
                                 fi
                              fi
                           fi
                        fi
                     fi
                     if [ "$RUNTEMPALERTS" = "true" ]; then
                        DISCONNECTCHECK=`echo "$SENSORTEMP" | grep "disconnected sensor"`
                        if [ "$DISCONNECTCHECK" ]; then
                           printf "PRTDIAG ALERT: Temperature sensor $i is in bad/disconnect condition on $SYSTEMHOSTNAME\nTime of Alert: $TIMEOFREPORT" | mail -s "PRTDIAG ALERT: Temperature alert on $SYSTEMHOSTNAME" $EMAIL
                        else
                           if [ $STRIPPEDSENSORTEMP -ge $TEMPMAX ]; then
                              printf "PRTDIAG ALERT: Temperature sensor $i is reporting $STRIPPEDSENSORTEMP which is greater than $TEMPMAX on $SYSTEMHOSTNAME\nTime of Alert: $TIMEOFREPORT" | mail -s "PRTDIAG ALERT: Temperature alert on $SYSTEMHOSTNAME" $EMAIL
                           fi
                        fi
                     fi
                  fi
               fi
               printf "    $i\t\t   $STRIPPEDSENSORTEMP\t\t  $TEMPSENSORTYPE\n" >> "$MYFILENAME"
# increment our counter var
               i=`expr $i + 1`
            done
         fi
      fi
   fi
fi
printf "\n" >> "$MYFILENAME"
