#!/bin/sh

# Shell script to collect hardware data.
# Copyright (C) 2001-2004 Open Challenge B.V.
# Copyright (C) 2004 OpenEyeT Professional Services.
#
# 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING.
# If not, write to the Free Software Foundation,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Contact information: www.OpenEyeT.nl/scc/index.html 

# This is a system module of scc, to call it separately in the
# proper environment, use: scc-collect -i -e <module_name>

# SCC-release:	1.6.26
# file-version:	$Revision: 1.62 $
 
. ${SCC_BIN}/scc_modules/scc_utils

if [ -x /sbin/atacontrol ]
then
	/sbin/atacontrol list 2>/dev/null	|
	sed -e 's/^/fix:hardware:atacontrol::/'
fi

if [ -x /opt/hparray/bin/arraydsp ]
then
	/opt/hparray/bin/arraydsp -i -S 2>/dev/null	|
	awk -F: '{
		# Format of input is: I:<id1>:<id2>:..:<idN>
		# No array: I:
		for ( i = 2; i <= NF; i++ )
		{
			if ( length( $i ) > 1 )
			{
				print $i;
			}
		}
	}'						|
	while read id remainder
	do
		touch ${TMP1_FILE}

		/opt/hparray/bin/arraydsp -l -S ${id}		|
		sed	-e "s/:${id}[:0]*$//"	\
			-e "s/^/fix:hardware:AutoRAID:${id}:lun::/"

		/opt/hparray/bin/arraydsp -d -S ${id}		|
		sed	-e "s/:${id}[:0]*$//"	\
			-e "s/^/fix:hardware:AutoRAID:${id}:disk::/"

		/opt/hparray/bin/arraydsp -c ${id}		|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:AutoRAID:${id}:controller::/"

		/opt/hparray/bin/arraydsp -s ${id}		|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:AutoRAID:${id}:general::/"

		/opt/hparray/bin/arraydsp -v ${id}		|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/var:hardware:AutoRAID:${id}:capacity::/"

		/opt/hparray/bin/arraydsp -h ${id}		|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:AutoRAID:${id}:hardware-status::/"
	done

	if [ ! -f ${TMP1_FILE} ]
	then
		echo "fix:hardware:AutoRAID:hardware::absent"
	fi
	rm -f ${TMP1_FILE}

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of AutoRAID"
fi

if [ -x /usr/sbin/cfgadm ]
then
	# Replace the value in the "busy" column to avoid differences.
	# Erase the dates to avoid differences.
	# Tape info is variable.
	cfgadm -lav 2>/dev/null									|
	sed	-e 's/  [ny]  /  -  /'			\
		-e 's/^[A-Z][a-z][a-z] [0-9 ][0-9]  [0-9][0-9][0-9][0-9]/            /'		|
	awk	'/^[^:][^:]*::rmt\//	{ print "var:hardware:cfgadm::" $0; next }
					{ print "fix:hardware:cfgadm::" $0; next }'
fi

if [ -x /usr/sbin/consadm ]
then
	/usr/sbin/consadm -p 2>/dev/null	|
	sed -e 's/^/fix:hardware:consadm::/'
fi

if [ -x /usr/sbin/psrinfo ]
then
	/usr/sbin/psrinfo -v			|
	sed	-e '/^Status/d'	\
		-e '/since/d'	\
		-e 's/^/fix:hardware:cpu psrinfo::/'
fi

scc_check_file /proc/cpuinfo "fix:hardware:cpu /proc/cpuinfo::" "#"	|
sed	-e 's/fix:\(.*:cpu MHz\)/var:\1/'		\
	-e 's/fix:\(.*user unaligned acc\)/var:\1/'	\
	-e 's/fix:\(.*:bogomips\)/var:\1/'

if [ -x /usr/sbin/sizer ]
then
	echo "fix:hardware:cpu type::$(/usr/sbin/sizer -c 2>/dev/null)"
	echo "fix:hardware:cpu family::$(/usr/sbin/sizer -implver 2>/dev/null)"
fi

scc_check_file /proc/dma "fix:hardware:DMA /proc/dma::" "#"

scc_check_file /etc/ddr.dbase "fix:hardware:/etc/ddr.dbase::" "#"

scc_check_file /etc/discover.conf "fix:hardware:/etc/discover.conf::" "#"

if [ -x /opt/hparray/bin/amdsp ]
then
	/opt/hparray/bin/amdsp -i -S 2>/dev/null	|
	awk -F: '{
		# Format of input is: I:<id1>:<alias1>:<id2>:<alias2>:..<aliasN>
		# Skip the aliases
		for ( i = 2; i <= NF; i += 2 )
		{
			if ( length( $i ) > 1 )
			{
				print $i;
			}
		}
	}'						|
	while read id remainder
	do
		touch ${TMP1_FILE}

		/opt/hparray/bin/amdsp -l -S ${id}	|
		sed	-e "s/:${id}[:0]*$//"	\
			-e "s/^/fix:hardware:FC60-array:${id}:lun::/"

		/opt/hparray/bin/amdsp -d -S ${id}	|
		sed	-e "s/:${id}[:0]*$//"	\
			-e "s/^/fix:hardware:FC60-array:${id}:disk::/"

		/opt/hparray/bin/amdsp -c ${id}		|
		sed	-e '/^ *$/d'		\
			-e 's/^   //'		\
			-e '/Controller Date/d'	\
			-e '/Controller Time/d'	\
			-e "s/^/fix:hardware:FC60-array:${id}:controller::/"

		/opt/hparray/bin/amdsp -g ${id}	|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:FC60-array:${id}:diskgroup::/"

		/opt/hparray/bin/amdsp -r ${id}	|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:FC60-array:${id}:rebuild::/"

		/opt/hparray/bin/amdsp -s ${id}		|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:FC60-array:${id}:general::/"

		/opt/hparray/bin/amdsp -h ${id}		|
		sed	-e '/^ *$/d'	\
			-e 's/^   //'	\
			-e "s/^/fix:hardware:FC60-array:${id}:hardware-status::/"
	done

	if [ ! -f ${TMP1_FILE} ]
	then
		echo "fix:hardware:FC60-array:hardware::absent"
	fi
	rm -f ${TMP1_FILE}

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of FC60-array"
fi

if [ -x /usr/bin/graphinfo -a -c /dev/crt ]
then
	graphinfo /dev/crt 2>/dev/null		|
	sed	-e '/^$/d'				\
		-e '/^OS\/SOFTWARE VERSIONS/,$d'	\
		-e 's/^/fix:hardware:graphics::/'
fi

scc_check_file /etc/opt/sicl/hwconfig.cf "fix:hardware:HP IO libraries hwconfig.cf::" "#"

if [ -x /usr/contrib/bin/machinfo -a "${OS_NAME}" = "HP-UX" ]
then
	/usr/contrib/bin/machinfo		|
	sed -e 's/^/fix:hardware:machinfo::/'
fi

if [ -x /usr/sbin/parstatus ]
then
	parstatus 2>/dev/null		|
	sed -e 's/^/fix:hardware:partitions::/'
fi

if [ -x /usr/sbin/vparstatus ]
then
	# TODO: I have not yet tested the output, so all output is var.
	vparstatus -w 2>/dev/null		|
	sed -e 's/^/var:hardware:Vpartitions::/'

	# TODO: I have not yet tested the output, so all output is var.
	vparstatus -v 2>/dev/null		|
	sed -e 's/^/var:hardware:Vpartitions::/'
fi

if [ -x /usr/sbin/sizer ]
then
	/usr/sbin/sizer -P 2>/dev/null			|
	sed -e 's/^/fix:hardware:partitions::/'
fi

if [ -x /usr/sbin/prtfru ]
then
	/usr/sbin/prtfru -c 2>/dev/null			|
	sed -e 's/^/fix:hardware:prtfru:data::/'

	/usr/sbin/prtfru -l 2>/dev/null			|
	sed -e 's/^/fix:hardware:prtfru:hierarchy::/'
fi

ARMDSP=/opt/sanmgr/commandview/client/sbin/armdsp
if [ -x ${ARMDSP} ]
then
	rm -f ${TMP1_FILE} ${TMP2_FILE}

	${ARMDSP} -i				|
	tee ${TMP1_FILE}			|
	sed	-e '/^#/d'		\
		-e '/^[ 	]*$/d'	\
		-e 's/^/fix:hardware:SAN:devices::/'

	awk '/Serial Number:/	{ print $NF }' ${TMP1_FILE}	|
	sort							|
	while read SN
	do
		${ARMDSP} "${SN}" > ${TMP2_FILE}
		SNalias="$(awk -F_ '/^Alias:/ { print $NF}' ${TMP2_FILE})"
		[ -n "${SNalias}" ] && SN="${SNalias}"

		awk '/Last Event Log/	{
						printf( "var:hardware:SAN:%s::%s\n", l, $0 );
						next
					}
			{
				printf( "fix:hardware:SAN:%s::%s\n", l, $0 );
				next
			}' l="${SN} overview" ${TMP2_FILE}

		${ARMDSP} -a "${SN}"			|
		awk 'BEGIN		{ var = 0 }
			/Scrub State:/	{ var = 1 }
			/Last Event Log/ || /Voltage/ || /mAh$/ || /Remaining Capacity/ || var == 1 {
					printf( "var:hardware:SAN:%s::%s\n", l, $0 );
					next
				}
				{
					printf( "fix:hardware:SAN:%s::%s\n", l, $0 );
					next
				}' l="${SN} details"
	done
fi
rm -f ${TMP1_FILE} ${TMP2_FILE} 2> /dev/null

## Added by Paul te Vaanholt for HP Storage Works Secure Path
if [ -x /sbin/spmgr ]
then
	/sbin/spmgr display			|
	grep -v -i -e "report created:"		|
	sed "s/^/fix:hardware:hp secure path::/"
fi

## Added by Paul te Vaanholt for EMC Symmetrix machines
# Edit scc-localize to change the default setting of this variable.
SYMCLI=${SYMCLI:-/usr/symcli/bin}
EMC="hardware:EMC symmetrix"

if [ -x ${SYMCLI}/symdev ]
then
	${SYMCLI}/symdev list 2>&1				|
	sed -e "s/^/fix:${EMC}:devices::/"
fi

if [ -x ${SYMCLI}/symdg ]
then
	${SYMCLI}/symdg list 2>/dev/null			|
	sed -e "s/^/fix:${EMC}:symdg list::/"

	${SYMCLI}/symdg list 2>/dev/null			|
	grep -v -e "D E V I C E" -e "Num.* of" -e "Symmetrix"	|
	awk 'NF > 5 { print $1 }'				|
	while read DG
	do
		# The structure of the output of this command is general data followed by several categories.
		#Group Name: <group>
		#   general data ...
		#   category
		#   {
		#   category-data
		#   }
		${SYMCLI}/symdg show "${DG}" 2>/dev/null			|
		awk	'/^Group Name/	{
						category = "general";
						next;
					}
			/^[ 	]*$/	{	next; }
			/^[ 	]*{/	{
						category = prev_line;
						sub( "^[ 	]*", "", category );
						gsub( "[\(][^\)]*[\)]", "", category );	# no text in brackets
						sub( "[ 	]*:*$", "", category );
						gsub( "  ", " ", category );
					}
					{
						if ( length( prev_line ) > 0 )
						{
							print prefix category "::" prev_line;
						}
						prev_line = $0;
					}
			END		{
						print prefix category "::" prev_line;
					}' prefix="fix:${EMC}:${DG}:"

		${SYMCLI}/symdg -f ${TMP1_FILE} export "${DG}" 2>/dev/null
		sed -e "s/^/fix:${EMC}:${DG}:export::/" <${TMP1_FILE}
		rm -f ${TMP1_FILE}

		if [ -x ${SYMCLI}/symrdf ]
		then
			${SYMCLI}/symrdf -g "${DG}" query 2>/dev/null			|
			sed -e "s/^/fix:${EMC}:${DG}:query::/"
		fi

		if [ -x ${SYMCLI}/symmir ]
		then
			${SYMCLI}/symmir -g "${DG}" -rdf query 2>/dev/null		|
			sed -e "s/^/fix:${EMC}:${DG}:mirror state::/"
		fi
	done
fi

if [ -x ${SYMCLI}/syminq ]
then
	${SYMCLI}/syminq 2>/dev/null			|
	sed -e "s/^/fix:${EMC}:syminq::/"
fi

# Sun Storedge
if [ -x /usr/sbin/sccli ]
then
	/usr/sbin/sccli -l 2>/dev/null			|
	awk '/^\/dev\//	{ print $1, $NF }'		|
	while read device id
	do
		/usr/sbin/sccli "${device}" show configuration ${TMP1_FILE} 2>/dev/null

		# The contents of the output file are:
		# <empty line>
		# * <category> 
		# <empty line>
		# <data>
		awk	'/^[ 	]*$/	{ if ( class_cnt < 1 ) next }
			/^\* /		{
						class = $2;
						prefix = "var";
						if ( class != "enclosure-status" )
						{
							prefix = "fix";
						}
						class_cnt = 0;
						next;
					}
					{
						print prefix ":hardware:Sun Storedge:" i ":" class "::" $0;
						class_cnt += 1;
					}' i="${id}" ${TMP1_FILE}			|
		sed	-e 's@^fix:\(.*:inquiry-data:: Page D.* Fibre Channel Address\)@var:\1@'	\
			-e 's@^fix:\(.*:inquiry-data:: Page D.* Port Name\)@var:\1@'
		# Some data appears to "change" for each run of scc. Tag this data variable.
		# inquiry-data:: Page D0 Fibre Channel Address: A7 (id 40)
		# inquiry-data:: Page D0 Port Name: 216000C0FF884D85

		rm -f ${TMP1_FILE}
	done
fi

if [ -x /sbin/sysctl ]
then
	case "${OS_NAME}" in
	*BSD)	LABEL="hw"
		;;
	*)	LABEL="dev"
		;;
	esac

	/sbin/sysctl -a 2>/dev/null								|
	sed	-n									\
		-e "s/^${LABEL}\.usermem/var:hardware:sysctl::${LABEL}.usermem/p"	\
		-e "s/^${LABEL}\./fix:hardware:sysctl::${LABEL}./p"				|
	sort
fi

if [ -x /opt/fcms/bin/fcmsutil ]
then
	for dev in /dev/fcms* /dev/td*
	do
		if [ -c "${dev}" ]
		then
			class="hardware:TACHYON-interface:${dev}"

			/opt/fcms/bin/tdutil "${dev}" read 0x008 pci 2>/dev/null	|
			sed -e "s@^@fix:${class}::tdutil	@"

			/opt/fcms/bin/fcmsutil "${dev}" 2>/dev/null			|
			awk	'/^[ 	]*$/			{ next }
								{ prefix="fix"; }
				/Number of Assisted IOs/	{ prefix="var" }
				/Number of Active Login/	{ prefix="var" }
								{ print prefix ":" l $0 }' l="${class}::fcmsutil	"

			# The following data (control register) changes frequently: var.
			/opt/fcms/bin/fcmsutil "${dev}" read_cr 2>/dev/null		|
			sed	-e '/^[ 	]*$/d'		\
				-e "s@^@var:${class}::registers	@"

			/opt/fcms/bin/fcmsutil "${dev}" stat 2>/dev/null		|
			sed	-e '/^[ 	]*$/d'		\
				-e "s@^@var:${class}::status	@"
		fi
	done
fi

if [ -x /usr/sbin/icod_stat ]
then
	/usr/sbin/icod_stat 2>/dev/null		|
	sed -e 's/^/fix:hardware:Instant Capacity on Demand::/'
fi

scc_check_file /proc/scsi/scsi "fix:hardware:scsi:/proc/scsi/scsi::" "#"
scc_check_file /proc/scsi/sg/host_strs "fix:hardware:scsi:/proc/scsi/sg/host_strs::" "#"

if [ -x /usr/sbin/luxadm ]
then
	# Sun Enterprise Network Array
	/usr/sbin/luxadm probe 2>/dev/null		|
	sed -e 's/^/fix:hardware:SENA:probe::/'

	/usr/sbin/luxadm -e port 2>/dev/null		|
	sed -e 's/^/fix:hardware:SENA:port::/'

	for d in $(ls /dev/es/* 2>/dev/null )
	do
		/usr/sbin/luxadm inq "${d}" 2>/dev/null	|
		sed -e "s@^@fix:hardware:SENA:${d}::@"
	done

	/usr/sbin/luxadm probe 2>/dev/null		|
	sed -n -e 's/^S.*Name:\([^ ]*\) .*/\1/p'	|
	sort						|
	while read enclosure remainder
	do
		/usr/sbin/luxadm display ${enclosure}		|
		sed	-e "/Temperature [sS]ensors/,/ temperatures /d"	\
			-e "/Interconnect assembly/,/Language/d"	\
			-e "s/^/fix:hardware:SENA:${enclosure}:display::/"
	done
fi

scc_check_file /etc/path_to_inst "fix:hardware:devices:/etc/path_to_inst::" "#"
scc_check_file /etc/name_to_major "fix:hardware:devices:/etc/name_to_major::" "#"
scc_check_file /etc/minor_perm "fix:hardware:devices:/etc/minor_perm::" "#"
scc_check_file /etc/driver_classes "fix:hardware:devices:/etc/driver_classes::" "#"
scc_check_file /etc/driver_aliases "fix:hardware:devices:/etc/driver_aliases::" "#"
scc_check_file /etc/devlink.tab "fix:hardware:devices:/etc/devlink.tab::" "#"
scc_check_file /etc/dacf.conf "fix:hardware:devices:/etc/dacf.conf::" "#"
scc_check_file /etc/dgroup.tab "fix:hardware:devices:/etc/dgroup.tab::" "#"

# On RedHat and *BSD systems, there are too many device files.
if [ "${OS_NAME}" = "HP-UX" -o "${OS_NAME}" = "SunOS"  -o "${OS_NAME}" = "OSF1" ]
then
	{
		if [ -x /usr/sbin/lsdev -a "${OS_NAME}" = "HP-UX" ]
		then
			# Get the major device numbers for the "variable" ownership devices.
			/usr/sbin/lsdev					|
			sed -n	-e 's/^[ 	]*//'	\
				-e 's/ .*pt[ms]$//p'	\
				-e 's/ .*pty[ms]$//p'	\
				-e 's/ .*tel[ms]$//p'	\
				-e 's/ .*tty$//p'
		fi

		{
			# Ignore the file-descriptor devices on SunOS.
			find /dev -type b -o -type c		|
			fgrep -v "/dev/fd/"

			if [ -d /devices ]		# SunOS
			then
				# There ware way too many pseudo devices, ignore them.
				find /devices -type b -o -type c	|
				fgrep -v "/pseudo/"
			fi
		}				|
		sort				|
		xargs ls -ld			|
		sed -e 's/,/ /'
	}							|
	awk '{
		if ( NF == 1 )
		{
			# Here we process the list of major device numbers with
			# "variable" ownership of the device-files.
			variable[ $1 ] = 1;
			cnt_variable++;
			next;
		}

		cnt=split( $NF, parts, "/" );
		dir="/dev"
		if ( cnt > 3 )
		{
			dir=sprintf( "/%s/%s", parts[ 2 ], parts[ 3 ] );
		}

		if ( cnt_variable > 0 )
		{
			if ( variable[ $5 ] == 0 )
			{
				# This is fixed.
				printf( "fix:hardware:device-files:%s::%s:	%s %2s %8.8s %8.8s %4s %s\n",\
					dir, $NF, $1, $2, $3, $4, $5, $6 );
				next;
			}
		}
		# Treat permission, owner and group as variable.
		# For tty-device files these properties depend on the
		# current user that is logged in on the device.

		# Name, link-count, major and minor number are fixed.
		printf( "fix:hardware:device-files:%s::%s:	%2s %4s %s\n",\
			dir, $NF, $2, $5, $6 );
		# permissions, owner and group are variable.
		printf( "var:hardware:device-files:%s::%s:	%s %8.8s %8.8s\n",\
			dir, $NF, $1, $3, $4 );
	}'
fi

if [ -x /sbin/dsfmgr ]
then
	# Erase all dates from the output.
	/sbin/dsfmgr -s -x 2>/dev/null					|
	sed	-e 's/ [A-Z][a-z][a-z] [0-9][0-9]  [0-9][0-9][0-9][0-9] / /'	\
		-e 's/ [A-Z][a-z][a-z]  [0-9]  [0-9][0-9][0-9][0-9] / /'	\
		-e 's/ [A-Z][a-z][a-z] [0-9][0-9] [0-9][0-9]:[0-9][0-9] / /'	\
		-e 's/ [A-Z][a-z][a-z] [0-9][0-9]  [0-9]:[0-9][0-9] / /'	\
		-e 's/^/fix:hardware:dsfmgr::/'
fi

if [ -x /usr/bin/raw ]
then
	/usr/bin/raw -qa 2>/dev/null		|
	sed -e 's/^/fix:hardware:raw device::/'
fi

scc_check_file /etc/device.tab "fix:hardware:devices:/etc/device.tab::" "#"

scc_check_file /var/adm/sbtab "fix:hardware:disk:/var/adm/sbtab::" "#"

ls /dev/rdsk 2>/dev/null	|
if [ "${OS_NAME}" = "SunOS" ]
then
	# Slice 0 (s0) indicates the entire disk,
	# other slices are used to address parts of the disk.
	sed -e "/s[1-9]$/d"
else
	cat -
fi				|
sort				|
while read disk remainder
do
	if [ -x /usr/sbin/diskinfo ]
	then
		/usr/sbin/diskinfo -v /dev/rdsk/${disk} 2>/dev/null	|
		sed	-e '/Additional inquiry/d'	\
			-e "s/^/fix:hardware:disk:${disk}::diskinfo:	/"
	fi

	if [ -x /usr/sbin/lssf ]
	then
		/usr/sbin/lssf /dev/rdsk/${disk} 2>/dev/null	|
		sed -e "s/^/fix:hardware:disk:${disk}::lssf:	/"
	fi

	if [ -x /usr/sbin/prtvtoc ]
	then
		/usr/sbin/prtvtoc /dev/rdsk/${disk} 2>/dev/null		|
		sed -e "s/^/fix:hardware:disk:${disk}::prtvtoc:	/"
	fi

	if [ -x /usr/sbin/format -a "${OS_NAME}" = "SunOS" ]
	then
		# Remove the slice-ID from the device-name
		dsk=$(echo ${disk} | sed -e 's/s0$//')

		printf "inquiry\npartition\nprint\nquit\nquit\n"	|
		/usr/sbin/format -d ${dsk} 2>&1				|
		awk	'/^Warning/		{ next }
			/^[ 	]*$/		{ next }
			/^format>/		{ show = 1; prefix="format:	" }
			/^format> $/		{ show = 0 }
			/^partition> Current /	{ show = 1; prefix="partition:	"; partition = 1 }
			/^partition> $/		{ show = 0 }
			/^  2 /			{ if ( partition ) size=$7 }
						{ if ( show) print "fix:hardware:disk:" d "::" prefix $0 }
			END	{ if ( length( size ) > 0 ) print "fix:hardware:disk:" d "::size:	" size }' d=${dsk}
	fi

	if [ -x /usr/sbin/scsictl ]
	then
		/usr/sbin/scsictl -a /dev/rdsk/${disk} 2>${TMP1_FILE}	|
		sed -e "s/^/fix:hardware:disk:${disk}::scsictl:	/"

		if [ -s ${TMP1_FILE} ]
		then
			# SAN's can use pseudo LUNs, where scsictl fails. Do not collect more info.
			continue
		fi
	fi

	if [ -x /usr/sbin/pvdisplay -o -x /sbin/pvdisplay ]
	then
		pvdisplay /dev/dsk/${disk} >/dev/null 2>${TMP1_FILE}
		if [ -s ${TMP1_FILE} ]
		then
			grep -l "find the volume group" ${TMP1_FILE} >/dev/null 2>/dev/null
			if [ $? -eq 0 ]
			then
				echo "fix:hardware:disk:${disk}::LVM:	absent"
			else
				echo "fix:hardware:disk:${disk}::LVM:	messages:present"
			fi
		else
			echo "fix:hardware:disk:${disk}::LVM:	present"

			dd bs=8200 skip=1 count=1 if=/dev/dsk/${disk} 2>/dev/null	|
			od -x								|
			awk	'{
					if ( NR == 1 )
					{
						pvid = sprintf( "%s%s%s%s", $2, $3, $4, $5 );
						vgid = sprintf( "%s%s%s%s", $6, $7, $8, $9 );
						printf( "fix:hardware:disk:%s::PVID:%s\n", d, toupper( pvid ) );
						printf( "fix:hardware:disk:%s::VGID:%s\n", d, toupper( vgid ) );
						exit( 0 );
					}
				}' d="${disk}"
		fi
		rm -f ${TMP1_FILE}
	fi
done
rm -f ${TMP1_FILE}

if [ -x /sbin/fdisk -a "${OS_NAME}" = "Linux" ]
then
	# Determine the disks of our local filesystems.
	df -l							|
	sed -n -e 's@^/dev/\([ehs]d.\).*@/dev/\1@p'		|
	sort -u							|
	while read dsk remainder
	do
		/sbin/fdisk -l -u ${dsk} 2>/dev/null					|
		sed     -e '/^[ 	]*$/d'				\
			-e "s@^@fix:hardware:disk:${dsk##*/}::fdisk:	@"

		case "${dsk##*/}" in
		hd*)	/sbin/hdparm -i ${dsk} 2>/dev/null	|
			sed -e "s@^@fix:hardware:disk:${dsk##*/}::hdparm:	@"
			;;
		esac
	done
fi

if [ -x /sbin/fdisk  -a "${OS_NAME}" = "FreeBSD" ]
then
	ls /dev/ad[0-9] /dev/da[0-9] 2>/dev/null	|
	while read disk
	do
		fdisk ${disk} 2>/dev/null		|
		sed -e "s@^@fix:hardware:disk:${disk##*/}::fdisk:	@"
	done
fi

if [ -x /sbin/sysctl -a -x /sbin/disklabel ]
then
	# Retrieve all the disknames, ignore floppy and CD-rom.
        /sbin/sysctl -n hw.disknames 2>/dev/null			|
	tr " ," "\012"							|
	sort								|
	sed	-e '/^fd/d'	\
		-e '/^cd/d'						|
	while read disk
	do
		/sbin/disklabel ${disk} </dev/null 2>/dev/null	|
		sed -e "s/^/fix:hardware:disklabels:${disk}::/"
	done
fi

if [ -x /sbin/hwmgr -a -x /sbin/disklabel ]
then
	/sbin/hwmgr show scsi					|
	awk '{ if ( $4 == "disk" ) print $8 }'			|
	while read disk
	do
		# Disks can be added to an EMC box without the device files being created.
		device="/devices/disk/${disk}a"
		if [ -b "${device}" ]
		then
			/sbin/disklabel -r ${device} 2>/dev/null			|
			sed -e "s/^/fix:hardware:disk:${disk}::disklabel:	/"
		fi
	done
fi

for d in /proc/ide/hd*
do
	if [ -d "${d}" ]
	then
		disk=$(basename "${d}")
		if [ -x /sbin/ide_info ]
		then
			/sbin/ide_info /dev/${disk} 2>/dev/null	|
			sed -e "s/^/fix:hardware:disk:${disk}::ide_info:	/"
		else
			scc_check_file "${d}/model" "fix:hardware:disk:${disk}::model:	" "#"
			scc_check_file "${d}/driver" "fix:hardware:disk:${disk}::driver:	" "#"
		fi
		scc_check_file "${d}/geometry" "fix:hardware:disk:${disk}::geometry:	" "#"
		scc_check_file "${d}/settings" "fix:hardware:disk:${disk}::settings:	" "#"
	fi
done
scc_check_file "/proc/ide/drivers" "fix:hardware:disk:/proc/ide/drivers::" "#"

if [ -x /usr/sbin/emxmgr ]
then
	for adapter in $(/usr/sbin/emxmgr -d 2>/dev/null | grep emx)
	do
		/usr/sbin/emxmgr -t ${adapter} 2>/dev/null		|
		sed -e "s/^/fix:hardware:EMX:${adapter}::/"
	done
fi

if [ -x /sbin/irdiag ]
then
	# I20 internal raid
	# TODO: I have not yet tested the output, so all output is var.
	/sbin/irdiag -v 2>&1		|
	sed -e 's/^/var:hardware:I20 internal raid::/'
fi

if [ -x /usr/lib/osa/bin/lad -a -x /usr/lib/osa/bin/drivutil ]
then
	/usr/lib/osa/bin/lad 2>/dev/null		|
	sed -e 's/^/fix:hardware:RaidManager:lad::/'

	/usr/lib/osa/bin/lad 2>/dev/null		|
	sort						|
	while read dev remainder
	do
		if [ -z "${dev}" ]
		then
			continue;
		fi

		/usr/lib/osa/bin/raidutil -c ${dev} -i 2>/dev/null		|
		sed	-e '/^[ 	]*$/d'	\
			-e '/succeeded/d'	\
			-e "s/^/fix:hardware:RaidManager:${dev}:raidutil::/"

		/usr/lib/osa/bin/drivutil -I ${dev} 2>/dev/null		|
		sed	-e '/^[ 	]*$/d'	\
			-e '/succeeded/d'	\
			-e "s/^/fix:hardware:RaidManager:${dev}:drive group::/"

		/usr/lib/osa/bin/drivutil -d ${dev} 2>/dev/null		|
		sed	-e '/^[ 	]*$/d'	\
			-e '/succeeded/d'	\
			-e "s/^/fix:hardware:RaidManager:${dev}:drives per group::/"

		/usr/lib/osa/bin/drivutil -i ${dev} 2>/dev/null		|
		sed	-e '/^[ 	]*$/d'	\
			-e '/succeeded/d'	\
			-e "s/^/fix:hardware:RaidManager:${dev}:drive::/"

		/usr/lib/osa/bin/drivutil -l ${dev} 2>/dev/null		|
		sed	-e '/^[ 	]*$/d'	\
			-e '/succeeded/d'	\
			-e "s/^/fix:hardware:RaidManager:${dev}:LUN::/"
	done
fi

for f in /etc/osa/rmparams /etc/osa/mnf /usr/lib/osa/rdac_address
do
	scc_check_file ${f} "fix:hardware:RaidManager:${f}::" "#"
done

if [ -x /usr/lib/osa/bin/healthck ]
then
	/usr/lib/osa/bin/healthck -a 2>/dev/null	|
	sed	-e '/^[ 	]*$/d'	\
		-e '/succeeded/d'	\
		-e 's/^/var:hardware:RaidManager:healthck::/'
fi

scc_check_file "/etc/raid/rmparams" "fix:hardware:RaidManager:/etc/raid/rmparams::" "#"

for f in /etc/raidtab /etc/raid?.conf
do
	scc_check_file "${f}" "fix:hardware:software RAID:${f}::" "#"
done
scc_check_file "/proc/mdstat" "var:hardware:software RAID:/proc/mdstat::" "#"	# Status is var data.

[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of disk"

# Data Terminal Connectors
for dtc in /opt/dtcmgr/sbin/dtclist /opt/rdtcmgr/sbin/rdtclist
do
	if [ ! -x ${dtc} ]
	then
		continue
	fi

	${dtc} -c 2>/dev/null			|
	sed -e '/^Error/d' -e '/^[ 	]/d'	|
	while read dtc_dev other
	do
		${dtc} -c ${dtc_dev}			|
		tr "\f" " "				|
		sed	-e '/^[ 	]*$/d'	\
			-e "s/^/fix:hardware:dtc:${dtc_dev}::/"
	done
done

scc_check_file /etc/ddfa/dp "fix:hardware:dtc:/etc/ddfa/dp::" "#"	|
tee ${TMP1_FILE}
if [ -s ${TMP1_FILE} ]
then
	# This file can also contain a message from scc_check_file, select only the contents of the file.
	# The last field of each line contains the name of a configuration file.
	sed -n	-e 's/[ 	]*$//'	\
		-e 's/^fix:hardware:dtc:.*[ 	]//p' ${TMP1_FILE}	|
	while read file
	do
		scc_check_file "${file}" "fix:hardware:dtc:${file}::" "#"
	done
fi
rm -f ${TMP1_FILE}

if [ -f /proc/interrupts ]
then
	awk '{
		if ( NR == 1 )
		{
			num_cpu=NF;
			next;
		}
		print $1, $(2+num_cpu), $(3+num_cpu) }' /proc/interrupts		|
	sed	-e '/^$/d'	\
		-e 's@^@fix:hardware:/proc/interrupts::@'
fi

scc_check_file /proc/ioports "fix:hardware:/proc/ioports::" "#"

scc_check_file /etc/kbdlang "fix:hardware:/etc/kbdlang::" "#"

if [ -x /usr/bin/getdev ]
then
	/usr/bin/getdev		|
	while read device remainder
	do
		devattr -v ${device}		|
		sed -e "s/^/fix:hardware:devattr:${device}::devattr:	/"
	done
fi

if [ -x /usr/bin/getconf ]
then
	if [ "$OS_NAME" = "AIX" ]
	then
		# Contributed by Doug Probst.
		getconf_opts="CLK_TCK HARDWARE_BITMODE KERNEL_BITMODE MACHINE_ARCHITECTURE" 
	else
		getconf_opts="CS_MACHINE_SERIAL CLK_TCK CPU_CHIP_TYPE HW_CPU_SUPP_BITS HW_32_64_CAPABLE KERNEL_BITS"
	fi
	for c in ${getconf_opts}
	do
		echo "fix:hardware:getconf::${c}:	$(/usr/bin/getconf ${c} 2>/dev/null)"
	done
fi

if [ -x /usr/bin/isalist ]
then
	/usr/bin/isalist				|
	sed -e 's/^/fix:hardware:instruction set:isalist::/'
fi

if [ -x /usr/bin/isainfo ]
then
	/usr/bin/isainfo -bv 2>/dev/null		|
	sed -e 's/^/fix:hardware:instruction set bits:isainfo::/'
fi

if [ -x /usr/sbin/lscfg ]
then
	/usr/sbin/lscfg -v				|
	sed	-e '/^[ 	]*$/d'	\
		-e 's/^/fix:hardware:lscfg::/'
fi

if [ -x /usr/sbin/prtconf ]
then
	/usr/sbin/prtconf -v 2>/dev/null		|
	sed	-e 's/^/fix:hardware:prtconf:device-tree::/'	\
		-e 's/^fix:\(.*::[ 	][ 	]*dev=\)/var:\1/'

	/usr/sbin/prtconf -vp 2>/dev/null		|
	sed -n -e 's/^  *idprom:/fix:hardware:prtconf:PROM::idprom:/p' 2>/dev/null
fi

if [ -f /proc/meminfo ]
then
	grep Total /proc/meminfo		|
	sed -e 's@^@fix:hardware:memory /proc/meminfo::@'
fi
scc_check_file /proc/iomem "fix:hardware:memory /proc/iomem::" "#"

file=/etc/X11/XF86Config
if [ /etc/XF86Config -nt ${file} ]
then
	file=/etc/XF86Config
fi
scc_check_file "${file}" "fix:hardware:monitor:${file}::" "#"

if [ -x /sbin/hwmgr ]
then
	for cat in name scsi component
	do
		/sbin/hwmgr show "${cat}" 2>&1			|
		awk	'{
				prefix = "fix";
				if ( c == "scsi" && $4 == "tape" )
				{
					# The driver owner seems to change for tapes.
					prefix = "var";
				}
				printf( "%s:hardware:hwmgr:%s::%s\n", prefix, c, $0 );
			}' c="${cat}"
	done

	/sbin/hwmgr view devices -category fibre 2>&1		|
	sed -e "s/^/fix:hardware:hwmgr:fibre::/"

	for cat in cluster devices hierarchy env
	do
		/sbin/hwmgr view "${cat}" 2>&1			|
		sed -e "s/^/fix:hardware:hwmgr:${cat}::/"
	done
fi

if [ -x /sbin/scu ]
then
	/sbin/scu show edt 2>&1					|
	sed -e 's/^/fix:hardware:scu::/'
fi

if [ -x /usr/sbin/ioscan ]
then
	# On some systems you may want to ignore NO_HW, for example on backup servers in SAN
	# environments. Depending on IGNORE_NO_HW, the sed params are changed
	# Edit scc-localize to change the default setting of this variable.
	IGNORE_NO_HW=${IGNORE_NO_HW:-0}

	/usr/sbin/ioscan -fn 2>${TMP1_FILE}		|
	if [ ${IGNORE_NO_HW} -eq 1 ]
	then
		sed -e 's/^/fix:hardware:ioscan::/' -e 's/NO_HW  /CLAIMED/'
	else
		sed -e 's/^/fix:hardware:ioscan::/'
	fi

	sed -e 's/^/fix:hardware:ioscan::messages:	/' ${TMP1_FILE}
	rm -f ${TMP1_FILE}

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of ioscan"
elif [ -f /etc/sysconfig/hwconf ]
then
	scc_check_file /etc/sysconfig/hwconf "fix:hardware:/etc/sysconfig/hwconf::" "-"
fi

if [ -x /usr/bin/rad ]
then
	# Online adding and replacement (HP-UX).
	/usr/bin/rad -q 2>/dev/null					|
	sed	-e '/^[ 	]*$/d'		\
		-e 's/^/fix:hardware:OLA:overview::/'

	ls -l /usr/sbin/olrad.d 2>/dev/null				|
	scc_ls								|
	sed	-e '/^total/d'			\
		-e 's@^@fix:hardware:OLA:/usr/sbin/olrad.d::@'

	/usr/bin/rad -q 2>/dev/null					|
	grep "^[0-9].*Yes"						|
	while read slot remainder
	do
		/usr/bin/rad -c ${slot} 2>/dev/null		|
		sed	-e '/^[ 	]*$/d'		\
			-e "s/^/fix:hardware:OLA:${slot}::/"
	done
fi

scc_check_file /etc/olar.config "fix:hardware:/etc/olar.config::" "-"
scc_check_file /etc/olar.config.common "fix:hardware:/etc/olar.config.common::" "-"

if [ -x /sbin/lspci ]
then
	/sbin/lspci -vv		|
	sed -e 's/^/fix:hardware:pci-devices lspci::/'
else
	scc_check_file /proc/pci "fix:hardware:pci-devices /proc/pci::" "#"
fi

if [ -x /usr/sbin/pciconf ]
then
	/usr/sbin/pciconf -v -l 2>/dev/null 		|
	sed -e 's/^/fix:hardware:pciconf::/'
fi

if [ -x /sbin/lspnp ]
then
	/sbin/lspnp -vv 2>/dev/null		|
	sed -e 's/^/fix:hardware:pnp-devices lspnp::/'
else
	scc_check_file /proc/bus/pnp "fix:hardware:pnp-devices /proc/bus/pnp::" "#"
fi

scc_check_file /etc/power.conf "fix:hardware:power management::/etc/power.conf:	" "#"

if [ -x "/usr/platform/$(uname -m 2>/dev/null)/sbin/prtdiag" ]
then
	/usr/platform/$(uname -m 2>/dev/null)/sbin/prtdiag -v		|
	sed -e 's/^/var:hardware:prtdiag::/'
fi

# Remove receive and transmit statistics.
scc_check_file /proc/tty/driver/serial "fix:hardware:serial hardware::" "#"	|
sed	-e 's/ [rt]x:[0-9][0-9]*//g'

if [ -x /usr/sbin/cstm ]
then
	# When diagmond is not running, cstm will loop. 
	grep -l diagmond ${PROC_FILE} >/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
		# stm often hangs during install. As the stm-data is variable in the snapshot,
		# it does not matter for the logboook. Skipping stm during installation, will also
		# speed up the installation. The install-scripts set the variable SCC_IGNORE_STM.
		# To remove stm permanently from the collection process,
		# edit scc-localize and change the default setting of this variable.
		if [ -z "${SCC_IGNORE_STM}" ]
		then
			if [ -x /usr/contrib/bin/machinfo ]
			then
				machinfo="yes";
			fi

			(
				echo "selall"
				echo "info"
				echo "wait"
				echo "infolog"
				echo "Done"
				echo "quit"
				echo "OK"
			)						|
			/usr/sbin/cstm 2>/dev/null			|
			awk 'BEGIN	{ path="intro"	}
				/^-- Information Tool Log for .* on path .*/	{
						path=$(NF-1);
					}
				/^-- Information Tool Log for each selected device --/	{
						path="trailer";
					}
				/^ *$/	{ next }
				/System Serial/	{
						# The System Serial can be retrieved fast by
						# means of machinfo. When this program is absent, it
						# is obtained via stm. It should be present under 
						# class "general".
						if ( length( m ) == 0 )
						{
							printf( "fix:general::System Serial Number:%s\n",\
								$NF ) >>k;
							# The "general" module retrieves this data from
							# the keep-file. It is available in the next run.
						}
					}
					{
						print "var:hardware:stm:" path "::" $0;
					}' k="${SCC_KEEP_NEW}" m="${machinfo}"

			[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of stm"
		fi
	else
		echo "fix:hardware:stm:general::messages:stm skipped, diagmond is not running"
	fi
else
	if [ -f /var/tombstones/ts99 ]
	then
		tr -d "
" </var/tomstones/ts99		|
		sed -e 's/^/var:hardware:last pdcinfo Tombstone::/'
	fi
fi

sc_adm="/usr/platform/$(uname -i 2>/dev/null)/sbin/scadm"
if [ -x ${sc_adm} ]
then
	class="hardware:System Controller"

	${sc_adm} version 2>/dev/null			|
	sed -e "s/^/fix:${class}::version	: /"

	${sc_adm} show 2>/dev/null			|
	sed -e "s/^/fix:${class}::parameters	: /"

	${sc_adm} shownetwork 2>/dev/null		|
	tr -d "\015"					|
	sed -e "s/^/fix:${class}::network	: /"

	${sc_adm} usershow 2>/dev/null			|
	sed -e "s/^/fix:${class}::users	: /"

	${sc_adm} loghistory 2>/dev/null		|
	tr -d "\015"					|
	sed -e "s/^/var:${class}::loghistory	: /"
fi

if [ -x /sbin/lsusb ]
then
	/sbin/lsusb -vv 2>/dev/null 		|
	sed -e "s/^/fix:hardware:usb::/"
fi

if [ -x /usr/sbin/usbdevs ]
then
	/usr/sbin/usbdevs -v 2>/dev/null 		|
	sed -e "s/^/fix:hardware:usb::/"
fi

if [ -x /usr/sbin/zoneadm ]
then
	/usr/sbin/zoneadm list -cv 2>/dev/null		|
	sed -e 's/^/var:hardware:zoneadm:status::/'

	/usr/sbin/zoneadm list -c 2>/dev/null		|
	grep -v "^global$"				|
	sort						|
	while read zone
	do
		/usr/sbin/zonecfg -z "${zone}" export 2>/dev/null	|
		sed -e "s/^/fix:hardware:zonecfg:${zone}::/"
	done
fi

exit 0
