#!/bin/sh

# Shell script to collect data concerning installed software.
# 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.74 $
 
. ${SCC_BIN}/scc_modules/scc_utils

# Apache can be installed in many different places and can be used with
# or without the -d and -f option. When the config-file cannot be determined
# this way, check the contents of the binary executable for the compiled
# location of the root and the name of the config-file.
# As an additional bonus it can run as httpd or apache2.
# The catch of apache2 should precede httpd to properly catch process: /opt/apache2/bin/httpd.
rm -f ${TMP2_FILE}
awk	'		{ catch = ""; }
	/apache2/	{ catch = "apache2"; }
	/httpd/		{ catch = "httpd"; }
			{
				if ( length( catch ) > 0 )
				{
					# show apache daemons with init as their parent.
					if ( $3 == 1 )
					{
						# remove all data in front of the command.
						for ( i = 1; $i !~ catch; i++ )
						{
							$i = ""
						}
						print;
					}
				}
			}' ${PROC_FILE}			|
sed	-e 's/^ *//'	\
	-e 's/-d/-d /g'	\
	-e 's/-f/-f /g'		|
awk '{
	# complete all lines to format:
	# <path>:<executable>:<config-directory>:<config-file>:<settings>
	if ( $1 ~ "^/" )
	{
		path = $1;
		sub( "/[^/]*$", "", path );
		sub( ".*/", "", $1 );
		exe = $1;
	}
	else
	{
		path = "_";
		exe = $1;
	}
	c_dir = "_";
	c_file = "_";
	settings = "_";
	for ( i = 2; i <= NF; i++ )
	{
		if ( $i ~ "^-d$" )
		{
			i++;
			c_dir = $i;
		}
		if ( $i ~ "^-f$" )
		{
			i++;
			c_file = $i;
		}
		if ( $i ~ "^-D" )
		{
			setting = sprintf( "%s %s", settings, $i );
		}
	}
	print path ":" exe ":" c_dir ":" c_file ":" settings;
}'				|
sort -u >${TMP1_FILE}

scc_keep_apache_config="software:Apache:config"
scc_keep_apache_count="software:Apache:count"
if [ -s ${TMP1_FILE} ]
then
	# We collected data from running httpd(s).

	echo "${scc_keep_apache_count}:1" >>${SCC_KEEP_NEW}

	cat ${TMP1_FILE}
else
	# Use the data in the keep-file. Use it for max. 5 runs of SCC.
	cnt=$(sed -n -e "s/^${scc_keep_apache_count}://p" ${SCC_KEEP_CONFIG})
	cnt=$(( ${cnt:-0} + 1 ))
	if [ ${cnt} -le 5 -a ${cnt} -gt 1 ]
	then
		echo "${scc_keep_apache_count}:${cnt}" >>${SCC_KEEP_NEW}

		# Use the config-file from a previous run of SCC.
		sed -n -e "s/^${scc_keep_apache_config}://p" ${SCC_KEEP_CONFIG}
	fi
fi				|
sed -e 's/:/ /g'		|
while read path exe c_dir c_file settings
do
	parms="${path}:${exe}:${c_dir}:${c_file}:${settings}"

	if [ ! -d ${path} ]
	then
		path="";
	fi
	if [ ! -f ${path}/${exe} ]
	then
		exe=$(which ${exe} 2>/dev/null)
		exe=${exe##no *}	# erase the message: no httpd in . . 
		exe=${exe:="httpd"}
	else
		exe=${path}/${exe}
	fi

	# Record the settings for all servers.
	if [ -x ${exe} ]
	then
		# Record the compiled settings only once for each server.
		# Same server as one of the previous processes?
		grep -l "${scc_keep_apache_config}:${httpd}:" ${SCC_KEEP_NEW} >/dev/null 2>/dev/null
		if [ $? -ne 0 ]
		then
			# Do not use: ${exe} -V as an ordinary user might craft his own httpd.
			# Register the compiled settings in de the executable.
			strings ${exe} 2>/dev/null		|
			sed -n -e "s@^ -D@fix:software:Apache:${exe}::-D@p"
		fi

		# Record the command-line settings for each instance.
		if [ "${settings}" != "_" ]
		then
			echo "${settings}"		|
			tr "," "\012"			|
			sed -e "s@^@fix:software:Apache:${exe}::@"
		fi

	fi
	echo "${scc_keep_apache_config}:${parms}" >>${SCC_KEEP_NEW}

	# Runtime options override compiled settings:
	if [ "${c_file}" != "_" ]			# -f option used?
	then
		if [ -f "${c_file}" ]			# absolute path?
		then
			conf="${c_file}"
		elif [ -f "${c_dir}/${c_file}" ]
		then
			conf="${c_dir}/${c_file}"	# combine arguments of -d and -f options
		else
			strings ${exe} 2>/dev/null       |
			sed -n	-e 's/"//g'	\
				-e 's/^ -D //p' >${TMP2_FILE}

			# Check the following directories:
			# - compiled setting HTTPD_ROOT
			# - "base" path of apache-installation
			for dir in "$(sed -n -e 's/HTTPD_ROOT=//p' ${TMP2_FILE})" "${path%%/bin}"
			do
				if [ -f "${dir}/${c_file}" ]
				then
					conf="${dir}/${c_file}"
					break
				fi
			done
		fi
	fi

	if [ -z "${conf}" ]             # nothing yet from -f option?
	then
		if [ ! -s ${TMP2_FILE} ]
		then
			strings ${exe} 2>/dev/null       |
			sed -n	-e 's/"//g'	\
				-e 's/^ -D //p' >${TMP2_FILE}
		fi

		# Try the compiled setting
		file="$(sed -n -e 's/SERVER_CONFIG_FILE=//p' ${TMP2_FILE})"
		root_dir="$(sed -n -e 's/HTTPD_ROOT=//p' ${TMP2_FILE})"

		# Check the following directories:
		# - supplied with -d option
		# - compiled setting HTTPD_ROOT
		# - "base" path of apache-installation
		# - empty, in case SERVER_CONFIG_FILE contains an absolute path
		# For each directory check:
		# - compiled setting for SERVER_CONFIG_FILE
		# - conf/httpd.conf
		for dir in "${c_dir}" "${root_dir}" ${path%%/bin} ""
		do
			if [ -f "${file}" ]
			then
				conf="${file}"
				break
			elif [ -f "${dir}/${file}" ]
			then
				conf="${dir}/${file}"
				break
			elif [ -f "${dir}/conf/httpd.conf" ]
			then
				conf="${dir}/conf/httpd.conf"
				break
			fi
		done
	fi

	if [ -f "${conf}" ]
	then
		scc_check_file "${conf}" "fix:software:Apache:${conf}::" "#"

		srm_conf="${conf%/*}/srm.conf"
		scc_check_file "${srm_conf}" "fix:software:Apache:${srm_conf}::" "#"

		# Wildcards can be used. Remove characters that can start a subshell.
		sed -n -e 's/^[ 	]*[Ii]nclude[ 	]*//p' "${conf}"	|
		tr -d -c "a-z A-Z/.*#^\-_0-9[\]\012"				|
		sort -u								|
		while read file
		do
			conf_base="${conf%/conf/*}"
			if [ -f "${file}" ]
			then
				echo "${file}"
			elif [ -f "${conf%/*}/${file}" ]
			then
				echo "${conf%/*}/${file}"
			elif [ -d "${file}" ]
			then
				for f in ${file}/*
				do
					echo "${f}"
				done
			else
				# Let the shell resolve the pattern,
				# the above "tr -d" avoids a subshell from being started.
				for f in ${file} ${conf_base}/${file}
				do
					echo "${f}"
				done
			fi
		done								|
		while read subconf
		do
			scc_check_file "${subconf}" "fix:software:Apache:${conf} include:${subconf}::" "#"
		done
	fi
done
rm -f ${TMP1_FILE} ${TMP2_FILE}

scc_check_file /etc/Bastille/config "fix:software:Bastille:/etc/Bastille/config::" "#"

case "${OS_NAME}" in
HP-UX)		if [ -x /bin/cc ]
		then
			echo "fix:software:C-compiler::$(what /bin/cc 2>/dev/null | grep HP)"
		fi
		;;
SunOS)		if [ -d /opt/SUNWspro ]
		then
			echo "fix:software:C-compiler::$(what /opt/SUNWspro/bin/cc 2>/dev/null | grep RELEASE)"
		else
			echo "fix:software:C-compiler::$(what /usr/ucb/cc 2>/dev/null | grep SMI)"
		fi
		;;
esac

scc_check_file /etc/opt/cifsclient/cifsclient.cfg "fix:software:cifs:cifsclient.cfg::" "#"

dir_list="/var/adm/cron /etc/cron.d /etc"
if [ "${OS_NAME}" = "OSF1" ]
then
	# OSF1 has many .proto files in /etc. They are not related to cron.
	dir_list="/var/adm/cron /etc/cron.d"
fi
for d in ${dir_list}
do
	for file in ${d}/queuedefs ${d}/.proto ${d}/.proto.*
	do
		scc_check_file "${file}" "fix:software:cron:configuration::${file}:	" "#"
	done

	# Sort the following files to make comparing systems easier.
	for file in ${d}/at.allow ${d}/at.deny ${d}/cron.allow ${d}/cron.deny
	do
		scc_check_file "${file}" "fix:software:cron:configuration::${file}:	" "#"		|
		sort
	done
done

# Collect the cron-jobs.
for f in	/var/spool/cron/crontabs/*	\
		/etc/cron.*/*			\
		/etc/crontab			\
		/var/cron/tabs/*		\
		/etc/anacrontab			\
		/var/spool/cron/*		\
		/etc/daily			\
		/etc/daily.conf			\
		/etc/weekly			\
		/etc/weekly.conf		\
		/etc/monthly			\
		/etc/monthly.conf		
do
	if [ ! -f "${f}" ]
	then
		continue
	fi

	job=$(basename ${f})

	# NOTE: /etc/cron.d can contain cron configuration-files.
	# Ignore these files, as we are collecting cron-jobs in this loop.
	case ${job} in
		*.allow)	continue;;
		*.deny)		continue;;
		queuedefs)	continue;;
		.proto*)	continue;;
	esac

	# Ordinary users are allowed to change their cron-jobs.
	# Register their jobs as variable parts in the snapshot.
	# We need the uid of a user to determine whether it is a ordinary or system user. 
	# When id fails, we have a job like: cron.daily which should be "fix"
	prefix="fix"
	uid=$(id -u ${job} 2>/dev/null)
	if [ $? -eq 0 ]
	then
		if [ ${uid} -ge ${MAX_SYS_ACCOUNT_ID} ]
		then
			prefix="var"
		fi
	fi

	scc_check_file "${f}" "${prefix}:software:cron:${f}::" "#"
done

if [ -x /opt/resmon/bin/resls ]
then
	/opt/resmon/bin/resls /					|
	sed	-e '/^$/d'	\
		-e 's/^/fix:software:EMS-resls::/'
fi

if [ -x /etc/opt/resmon/lbin/moncheck ]
then
	/etc/opt/resmon/lbin/moncheck				|
	sed	-e '/^$/d'			\
		-e 's/port=[0-9][0-9]*$/port=/'	\
		-e 's/^/fix:software:EMS-monitors::/'
fi
[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of EMS-monitors"

scc_check_file /etc/evmdaemon.conf	"fix:software:evmd:/etc/evmdaemon.conf::"	"#"
scc_check_file /etc/evmchannel.conf	"fix:software:evmd:/etc/evmchannel.conf::"	"#"
scc_check_file /etc/evmlogger.conf	"fix:software:evmd:/etc/evmlogger.conf::"	"#"
scc_check_file /etc/evmd.auth		"fix:software:evmd:/etc/evm.auth::"		"#"
for filter in /usr/share/evm/filters/*evf
do
	scc_check_file "${filter}"  "fix:software:evmd:${filter}::" "#"
done

# Contributed by Harry van Wiggen.
if [ -f /etc/ha.d/ha.cf ]
then
	scc_check_file /etc/ha.d/ha.cf		"fix:software:heartbeat:ha.cf::"	"#"
	scc_check_file /etc/ha.d/haresources	"fix:software:heartbeat:haresources::"	"#"
	for file in /etc/ha.d/authkeys /etc/ha.d/resource.d/*
	do
		if [ -f "${file}" ]
		then
			echo "fix:software:heartbeat:md5sum ${file}::$(md5sum ${file} 2>/dev/null)"
		fi
	done
fi

# Contributed by Harry van Wiggen.
if [ -d /etc/htdig ]
then
	for file in /etc/htdig/*
	do
		scc_check_file "${file}"  "fix:software:htdig:${file}::" "#"
	done
fi

if [ -d /opt/ignite/bin ]
then
	if [ -h /var/opt/ignite/recovery/latest ]
	then
		echo "fix:software:Ignite-UX:latest::$(ls -ld /var/opt/ignite/recovery/latest | scc_ls )"
	elif [ -f  /var/opt/ignite/recovery/makrec.last ]
	then
		echo "fix:software:Ignite-UX:makrec.last::$(ls -l /var/opt/ignite/recovery/makrec.last | scc_ls )"
	fi

	# The output of print_manifest is not easy to process for comparing.
	# Generate a new manifest-file and process that.
	/opt/ignite/bin/print_manifest >/dev/null 2>&1
	sort -u /var/opt/ignite/local/manifest/manifest.info	|
	sed	-e '/^ *$/d'		\
		-e '/^PERIPHERAL/d'	\
		-e '/^LVM_DISK/d'	\
		-e '/^UFS_DISK/d'	\
		-e '/^UFS_LAYOUT/d'	\
		-e 's/^/fix:software:Ignite-UX:manifest.info::/'

	INDEX=/var/opt/ignite/INDEX
	scc_check_file "${INDEX}" "fix:software:Ignite-UX:${INDEX}::" "#"

	if [ -f ${INDEX} ]
	then
		sed	-e 's/^[ 	][ 	]*"//'	\
			-e 's/"$//' ${INDEX}			|
		grep "^/"					|
		sort -u						|
		while read file
		do
			scc_check_file "${file}" "fix:software:Ignite-UX:${file}::" "#"
		done
	fi

	for f in /var/opt/ignite/scripts/*
	do
		scc_check_file "${f}" "fix:software:Ignite-UX:scripts:$(basename ${f})::" "#"
	done

	scc_check_file /var/opt/ignite/server/ignite.defs "fix:software:Ignite-UX:/var/opt/ignite/server/ignite.defs::" "#"

	for f in /var/opt/ignite/clients/*
	do
		if [ -h ${f} ]
		then
			echo "fix:software:Ignite-UX:clients:$(basename ${f})::$(ls -ld ${f} | awk '{ print $NF }')"
		fi
	done

	scc_check_file /etc/opt/ignite/instl_boottab "fix:software:Ignite-UX:/etc/opt/ignite/instl_boottab::" "#"

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of Ignite-UX"
fi

if [ "${OS_NAME}" = "SunOS" ]
then
	# For non-Solaris systems, this file has nothing to do with JunpStart.
	scc_check_file /etc/bootparams "fix:software:jumpstart:/etc/bootparams::" "#"
fi

if [ -f /etc/bootparams ]
then
	# This code works when one system functions as boot_server, install_server and conf_server

	> ${TMP1_FILE}

	sed -e '/^[ 	]*#/d' -e '/^[ 	]*$/d' /etc/bootparams		|
	awk	'{
			sysid="?"
			for ( i = 2; i <= NF; i++ )
			{
				if ( $i ~ "^sysid_config=" )
				{
					cnt = split( $i, parts, ":" );
					if ( cnt == 2 )
					{
						sysid = parts[ 2 ];
					}
					break;
				}
			}
			print sysid;
		}'							|
	sort -u								|
	while read sysid_cfg
	do
		if [ -f "${sysid_cfg}/sysidcfg" ]
		then
			sed	-e 's/root_password=.*/root_password=ERASED/'				\
				-e "s@^@fix:software:jumpstart:sysidcfg:${sysid_cfg}/sysidcfg::@"	\
					<"${sysid_cfg}/sysidcfg"
		fi
	done

	# Use the install_config item to retrieve all begin, class and finish files.
	sed -e '/^[ 	]*#/d' -e '/^[ 	]*$/d' /etc/bootparams		|
	awk	'{
			inst="?"
			for ( i = 2; i <= NF; i++ )
			{
				if ( $i ~ "^install_config=" )
				{
					cnt = split( $i, parts, ":" );
					if ( cnt == 2 )
					{
						inst = parts[ 2 ];
					}
					break;
				}
			}
			print inst;
		}'							|
	sort -u								|
	while read inst
	do
		if [ -f "${inst}/rules.ok" ]
		then
			sed	-e '/^#/d'								\
				-e "s@^@fix:software:jumpstart:install-config:${inst}/rules.ok::@"	\
					<"${inst}/rules.ok"

			sed	-e '/^[ 	]*#/d'		\
				-e '/^[ 	]*$/d'		\
					<"${inst}/rules.ok"				|
			awk	'{
					if ( NF > 2 )
					{
						printf( "begin %s/%s\n", d, $(NF-2) );
						printf( "class %s/%s\n", d, $(NF-1) );
						printf( "finish %s/%s\n", d, $NF );
					}
				}' d="${inst}"						|
			sed -e '/-$/d'							|
			sort -u								|
			while read c file
			do
				grep -l "^${c} ${file}" ${TMP1_FILE} 2>/dev/null >/dev/null 2>/dev/null
				if [ $? -ne 0 ]
				then
					echo "${c} ${file}" >>${TMP1_FILE}

					if [ -f "${file}" ]
					then
						sed	-e '/^#/d'					\
							-e "s@^@fix:software:jumpstart:${c}:${file}::@"	\
								<"${file}"
					fi
				fi
			done

		fi

		# The rules and the rules.ok files should be identical (except for the checksum line).
		if [ -f "{inst}/rules" -a -f "${inst}/rules.ok" ]
		then
			diff rules rules.ok	|
			sed -n -e '/^[<>] /p' >${TMP2_FILE}

			differences="$(sed -e '/> # version=.*checksum=/d' <${TMP2_FILE})"
			if [ -n "${differences}" ]
			then
				class="fix:software:jumpstart:${inst}:rules-rules.ok"
				sed	-e "s/^</${class}::rules   /"	\
					-e "s/^>/${class}::rules.ok/" ${TMP2_FILE}
			fi
			rm -f ${TMP2_FILE}
		fi
	done

	rm -f ${TMP1_FILE}
fi

if [ -x /usr/sbin/swlist ]
then
	# Record the bundles and the products not contained in a bundle.
	# Products are also recorded through their filesets, record them here as var data.
	/usr/sbin/swlist 2>/dev/null							|
	awk	'/^# Bundle/	{ p = "fix"; show = 1 }
		/^# Product/	{ p = "var" }
		/^#$/		{ next }
		/^$/		{ next }
				{
					if ( show )
					{
						print p ":software:installed software::" $0; 
					}
				}'

	# Show the fileset, ignore the header.
	/usr/sbin/swlist -l fileset -x one_liner="name revision title" 2>/dev/null	|
	sed -e '1,/^$/d'								|
	sed -e 's/^/fix:software:installed-filesets::/'

	swlist -l fileset -a state 2>/dev/null		|
	sed	-e '/configured[ 	]*$/d'	\
		-e '/transient[ 	]*$/d'	\
		-e '/^#/d'			\
		-e '/^[ 	]*$/d'		\
		-e 's/^/fix:software:patches:unconfigured::/'

fi

# Registrate the version of scc installed from source.
# This will only work with a release from scc-srv more recent than 1.3.25 
if [ "${SCC_INSTALL_PHASE}" = "postinstall" ]
then
	# The following variable is only set to "source" when scc is installed from source.
	if [ "${SCC_INSTALL_METHOD}" = "source" ]
	then
		# add to snapshot and new-keep
		echo "fix:software:installed-source::scc:1.6.26"	|
		tee -a ${SCC_KEEP_NEW}
	else
		# nothing to do, installed version of scc is reported by swlist, pkginfo, rpm, ...
		:
	fi
else
	# Copy from keep-file to snapshot and to new-keep.
	# When scc is not installed from source, this will not produce any data.
	grep "^fix:software:installed-source::scc:" ${SCC_KEEP_CONFIG}	|
	tee -a ${SCC_KEEP_NEW}
fi


if [ -x /usr/bin/lslpp ]
then
	/usr/bin/lslpp -a -c -L			|
	sed -e 's/^/fix:software:installed-aix-filesets::/'
fi

if [ -x /usr/bin/pkginfo ]
then
	# Wes Brown pointed out:
	# - NAME and VERSION can contain ":" and spaces.
	# - some patches do not update the version of a product, only the PSTAMP.
	/usr/bin/pkginfo -l				|
	awk	'/PKGINST:/	{ pkg = $2; next; }
		/NAME:/		{ $1 = ""; gsub( ":", ";" ); name = $0; next; }
		/CATEGORY:/	{ $1 = ""; gsub( ":", ";" ); cat = $0; next; }
		/VERSION:/	{ $1 = ""; gsub( ":", ";" ); ver = $0; next; }
		/PSTAMP:/	{
					$1 = "";
					gsub( ":", ";" );
					printf( "fix:software:installed-packages:%s::%s:%s:%s:%s\n",\
						cat, pkg, name, ver, $0 );
					pkg = "";
					name = "";
					cat = "";
					ver = "";
					next;
				}'			|
	sed -e 's/:[ 	][ 	]*/:/g'			|
	sort -f -t":" -k 1,8
fi

if [ -x /usr/sbin/setld ]
then
	# Installed software for TRU64
	/usr/sbin/setld -i 2>/dev/null			|
	sed -e 's/^/fix:software:installed-subsets::/'
fi

if [ -x /usr/bin/dpkg ]
then
	/usr/bin/dpkg -l 2>/dev/null			|
	sed -e 's/^/fix:software:installed Debian packages::/'
fi
scc_check_file /etc/apt/sources.list "fix:software:/etc/apt/sources.list::" "#"

if [ -x /usr/sbin/qpkg ]
then
	/usr/sbin/qpkg -I -v 2>/dev/null		|
	sort						|
	sed -e 's/^/fix:software:installed Gentoo packages::/'
fi

if [ -x /usr/sbin/pkg_version ]
then
	# Check whether packages are uptodate compared with ports. FreeBSD only.
	/usr/sbin/pkg_version -v 2>/dev/null		|
	sed -e 's/^/var:software:ports::/'
fi

if [ -x /usr/sbin/pkg_info ]
then
	/usr/sbin/pkg_info 2>/dev/null		|
	sed -e 's/^/fix:software:installed-BSD-packages::/'

	scc_check_file /usr/local/etc/pkgtools.conf "fix:software:BSD:/usr/local/etc/pkgtools.conf::" "#"
fi

if [ -x /bin/rpm ]
then
	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: start of rpm"

	scc_keep_rpm_config="fix:software:installed-rpms"

	# When this program is called during the pre- and post-install
	# of SCC, the rpm-database is locked and cannot be queried.
	# On Mandrake, rpm "hangs" during install. Ignore rpm during installs of SCC.
	if [ ! "${SCC_INSTALL_PHASE}" ]
	then
		/bin/rpm -qa --queryformat "${scc_keep_rpm_config}:%{GROUP}::%{NAME}:%{VERSION}-%{RELEASE}\n" 2>/dev/null |
		sort -t: -k 1,7
	fi >${TMP1_FILE}

	# During installs, rpm is able to reply to the --showrc option
	/bin/rpm --showrc 2>/dev/null		|
	sed	-e '/^=====/,$d'	\
		-e "s/^/fix:software:rpm showrc::/"

	if [ -s ${TMP1_FILE} ]
	then
		# Use the output from RPM.
		cat ${TMP1_FILE}
	else
		# Use the output from a previous run of SCC. 
		grep "${scc_keep_rpm_config}:" ${SCC_KEEP_CONFIG}
	fi					|
	tee -a ${SCC_KEEP_NEW}		# keep the results for a next run.
	# The use of rpm is a permanent attribute of a system. Do not count the
	# use of this data in the keep-file.

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

if [ -x /sbin/ipchains-save ]
then
	/sbin/ipchains-save 2>&1		|
	sed -e 's/^/fix:software:ipchains:rules::/'

	scc_check_file /etc/iptoip.xml "fix:software:ipchains:/etc/iptoip.xml::" "#"
fi

if [ -x /sbin/iptables-save ]
then
	# Ignore variable data:
	# - comment lines contain timestamps
	# - traffic counters are surrounded by '[' and ']'
	/sbin/iptables-save 2>&1				|
	sed	-e 's/\[.*\]//'		\
		-e '/^#/d'		\
		-e 's/^/fix:software:iptables:rules::/'

fi

scc_check_file /opt/hpservices/etc/motprefs "fix:software:ISEE:motprefs::" "#"
scc_check_file /opt/hpservices/etc/hpservices.conf "fix:software:ISEE:hpservices.conf::" "#"

scc_check_file /etc/ksysguarddrc "fix:software:/etc/ksysguarddrc::" "#"

scc_check_file /etc/kbr5.conf "fix:software:kerberos:/etc/kbr5.conf::" "#"
scc_check_file /etc/kbr5.keytab "fix:software:kerberos:/etc/kbr5.keytab::" "#"

scc_check_file /etc/ldap.conf "fix:software:ldap:/etc/ldap.conf::" "#"
scc_check_file /usr/pkg/etc/openldap/ldap.conf "fix:software:ldap:/usr/pkg/etc/openldap/ldap.conf::" "#"
if [ -f /etc/ldap.secret ]
then
	scc_crypt </etc/ldap.secret		|
	sed -e 's@^@fix:software:ldap:/etc/ldap.secret::@'
fi

for dir in /etc/openldap /usr/pkg/etc/openldap
do
	SLAPD=${dir}/slapd.conf
	if [ -f ${SLAPD} ]
	then
		# Encrypt the plaintext rootpw.
		rootpw="$(grep "^rootpw" ${SLAPD} | scc_crypt )"
		scc_check_file "${SLAPD}" "fix:software:ldap:${SLAPD}::" "#"		|
		sed -e "s/::rootpw.*/::rootpw ${rootpw}/"

		# Get all the files that are included in the main config file for OpenLdap.
		sed -n -e 's/^include[ 	]*//p' ${SLAPD}		|
		while read file remainder
		do
			scc_check_file "${file}" "fix:software:ldap:${file}::" "#"
		done
	fi
done

scc_check_file /etc/locate.rc "fix:software:/etc/locate.rc::" "#"

if [ -f /etc/logrotate.conf ]
then
	scc_check_file /etc/logrotate.conf "fix:software:/etc/logrotate.conf::" "#"

	rot_include="$(sed -n -e 's/^include[ 	]*//p' /etc/logrotate.conf 2>/dev/null )"
	for entry in "${rot_include}"
	do
		if [ -d "${entry}" ]
		then
			for rot_f in ${entry}/*
			do
				scc_check_file "${rot_f}" "fix:software:/etc/logrotate.conf include:${rot_f}::" "#"
			done
		elif [ -f "${entry}" ]
		then
			scc_check_file "${entry}" "fix:software:/etc/logrotate.conf include:${entry}::" "#"
		fi
	done
fi

if [ -x /usr/bin/lpstat ]
then
	/usr/bin/lpstat -d 2>/dev/null			|
	sed -e 's/^/fix:software:lp:default::/'

	if [ -h /usr/bin/lpstat ]
	then
		# Justprint installed and active
		scc_check_file /opt/pms/setup/jpsetup.ini "fix:software:lp:justprint::" "#"
	else
		lpstat -v 2>/dev/null			|
		sed -e 's/^/fix:software:lp:destinations::/'
	fi

	lpstat -r 2>/dev/null			|
	sed -e 's/^/fix:software:lp:scheduler::/'
elif [ -x /usr/sbin/lpc ]
then
	lpc status all				|
	sed	-e '/^[ 	]/d'	\
		-e 's/^/fix:software:lp:destinations::/'
fi

scc_check_file /etc/hosts.lpd "fix:software:lp:/etc/hosts.lpd::" "#"
scc_check_file /etc/rlpd.conf "fix:software:lp:/etc/rlpd.conf::" "#"

scc_keep_mail_count="software:mail-server:count"
scc_keep_mail_config="software:mail-server:config"
version=$( ( echo quit; sleep 1 ) | telnet localhost 25 2>&1 | grep "^220")
if [ "${version}" ]
then
	version=$(echo ${version}	|
		sed	-e 's/220 //'			\
			-e 's/ [A-Z][a-z][a-z],.*//'	\
			-e 's/;.*//'			\
			-e 's/ready at.*//')
	cnt=1
else
	cnt=$(sed -n -e "s/^${scc_keep_mail_count}://p" ${SCC_KEEP_CONFIG})
	cnt=$(( ${cnt:-0} + 1 ))
	version=""
	if [ ${cnt} -lt 5 -a ${cnt} -gt 1 ]
	then
		version=$(sed -n -e "s/^${scc_keep_mail_config}://p" ${SCC_KEEP_CONFIG})
	fi
fi
if [ "${version}" ]
then
	echo "fix:software:mail-server::version:	${version}"

	echo "${scc_keep_mail_count}:${cnt}" >>${SCC_KEEP_NEW}
	echo "${scc_keep_mail_config}:${version}" >>${SCC_KEEP_NEW}
fi

sed	-n -e 's/^.*:include:\(.*majordomo.*\)/\1/p'	\
		/etc/aliases /etc/mail/aliases /etc/postfix/aliases 2>/dev/null		|
while read file
do
	scc_check_file "${file}" "var:software:majordomo:${file}::" "#"
done

scc_check_file /etc/my.conf "fix:software:MySQL::" "#"

# Netscape Fasttrack server
awk '/ns-httpd.*-d/	{
				sub( ".*ns-httpd.*-d[ 	]", "" );
				sub( "[ 	].*", "" );
				print;
			}' ${PROC_FILE}					|
sort -u									|
while read dir
do
	if [ -f "${dir}"/magnus.conf ]
	then
		server="$(awk '/^[ 	]*ServerID/ { print $NF; exit 0 }' "${dir}/magnus.conf")"
		if [ "${server}" ]
		then
			class="fix:software:Netscape Fasttrack:${server}"
		else
			class="fix:software:Netscape Fasttrack:${dir}"
		fi
		scc_check_file "${dir}"/admin.conf "${class}:admin.conf::" "#"
		scc_check_file "${dir}"/magnus.conf "${class}:magnus.conf::" "#"
		scc_check_file "${dir}"/obj.conf "${class}:obj.conf::" "#"

		acl="$(awk '/^[ 	]*ACLFile/ { print $NF; exit 0 }' "${dir}/magnus.conf")"
		if [ -f "${acl}" ]
		then
			echo "${class}:ACL::${acl}"
			scc_check_file "${acl}" "${class}:ACL::" "#"
		fi
	fi
done

# Edit scc-localize to change the default setting of this variable.
if [ -z "${SCC_PERL}" ]
then
	# No specific PATH, use the default list of directories of SCC).
	SCC_PERL="$(which perl 2>/dev/null)"
fi
if [ -x "${SCC_PERL}" ]
then
	echo "#!${SCC_PERL}" >${TMP1_FILE}
	cat >>${TMP1_FILE} <<\_X_
		use ExtUtils::Installed;

		my ($inst) = ExtUtils::Installed->new();
		my (@modules) = $inst->modules();

		foreach $module(@modules)
		{
			$version = $inst->version($module) || "unknown version";
			@mod_dirs = $inst->directories($module,"prog");
			print "fix:software:perl-modules:" . $module . "::" . "version	: " . $version . "\n";
			foreach $dir(@mod_dirs)
			{
				print "fix:software:perl-modules:" . $module . "::" . $dir . "\n";
			}
		}
_X_

	chmod u+x ${TMP1_FILE}
	${TMP1_FILE} 2>/dev/null

	rm -f ${TMP1_FILE}
fi

scc_check_file ${SCC_CONF}/scc-localize "fix:software:scc:${SCC_CONF}/scc-localize::" "#"
scc_check_file ${SCC_CONF}/scc-split.conf "fix:software:scc:${SCC_CONF}/scc-split.conf::" "#"
for module in ${SCC_BIN}/scc_modules/scc_[0-9][0-9][0-9][0-9]_[su]_*
do
	if [ -x "${module}" ]
	then
		# We detect changes in the modules. This checksum is also recorded in
		# the output of a user-module. scc-log ignores changes when the checksum
		# in the output of the user-module changes (when the user-module has run).
		# Remove comments and empty lines to avoid extra changes in the checksum.
		checksum="$(sed -e 's/[ 	]*#.*//' -e '/^[ 	]*$/d' <"${module}" | cksum)"
		echo "fix:software:scc:modules::${module##*/}	${checksum}"
	fi
done

ORG_PATH=${PATH}
PATH=${PATH}:/usr/local/bin
php_exe="$(which php 2>/dev/null)"
if [ -x "${php_exe}" ]
then
	php -v 2>/dev/null		|
	sed -e 's/^/fix:software:php:version::/'

	php -m 2>/dev/null		|
	sed -e 's/^/fix:software:php:modules::/'

	php -i 2>/dev/null >${TMP1_FILE}
	html="$(grep -li "^<!DOCTYPYE HTML" ${TMP1_FILE})"
	if [ -z "${html}" ]
	then
		# Querying php also results in the environment being dumped.
		# The variables of scc are part of this environment and they have 
		# variable values, remove them.
		tr -d "
" <${TMP1_FILE}					|
		sed	-e '/^This program /,/^Configuration$/d'	\
			-e '/\/scc\/tmp\//d'				\
			-e '/SCC_/d'					\
			-e '/tick_prev/d'				\
			-e '/^[ 	]*$/d'					|
		awk	'/\=>/	{
					print "fix:software:php:" cat "::" $0;
					next
				}
				{
					if ( length( $0 ) < 2 )
					{
						print "fix:software:php:" cat "::" $0;
					}
					else
					{
						cat=$0;
					}
				}'
	fi
	rm -f ${TMP1_FILE}
fi
PATH=${ORG_PATH};	export PATH

scc_check_file /etc/php.ini "fix:software:php:/etc/php.ini::" ";"
scc_check_file /usr/local/lib/php.ini "fix:software:php:/usr/local/lib/php.ini::" ";"

# To collect scc-srv config data we look under the default directory /var/opt/scc-srv.
# When scc-srv has been relocated, we assume that scc has been relocated in the same way as scc-srv.
# We reach the relocated scc-srv by appending "-srv" to "our" variable ${SCC_TOP}.
dir_list="/var/opt/scc-srv"
if [ "${SCC_TOP}-srv" != "${dir_list}" ]
then
	dir_list="${dir_list} ${SCC_TOP}-srv"
fi
for d in ${dir_list}
do
	dir=${d}/conf
	if [ ! -d "${dir}" ]
	then
		continue
	fi

	# The general configs.
	scc_check_file ${dir}/scc.conf "fix:software:scc-srv:${dir}/scc.conf::" "#"
	scc_check_file ${dir}/scc-smt-select "fix:software:scc-srv:${dir}/scc-smt-select::" "#"

	# The configs per realm.
	for dir in ${d}/data/www/*/custom
	do
		if [ ! -d "${dir}" ]
		then
			continue
		fi
		realm="$(basename $(dirname "${dir}"))"
		perm="$(ls -ld "${dir}"/.. | awk '{ print $1, $3, $4 }')"
		echo "fix:software:scc-srv:realm ${realm}::permissions:	${perm}"

		scc_check_file "${dir}/scc-realm.conf" "fix:software:scc-srv:realm ${realm}::scc-realm.conf:	" "#"
		scc_check_file "${dir}/scc-smt-select" "fix:software:scc-srv:realm ${realm}::scc-smt-select:	" "#"
		scc_check_file "${dir}/scc-rules.conf" "fix:software:scc-srv:realm ${realm}::scc-rules.conf:	" "#"
	done

	# Permissions of all transfer directories.
	for dir in ${d}/data/transfer/*
	do
		if [ ! -d "${dir}" ]
		then
			continue
		fi

		perm="$(ls -ld "${dir}" | awk '{ print $1, $3, $4 }')"
		echo "fix:software:scc-srv:${dir}::permissions:	${perm}"
	done

	# We do not "break" here, as systems might contain the scc-srv in the "original" AND the
	# relocated location. This undesirable situation now appears in the snapshot.
done


for dir in /etc/ssh /opt/openssh2/etc /usr/local/etc/ssh
do
	if [ ! -d ${dir} ]
	then
		continue
	fi

	scc_check_file "${dir}/sshd_config" "fix:software:openssh2:sshd_config::" "#"
	scc_check_file "${dir}/ssh_config" "fix:software:openssh2:ssh_config::" "#"

	if [ -f ${dir}/ssh_host_key ]
	then
		scc_crypt <${dir}/ssh_host_key			|
		sed -e 's/^/fix:software:openssh2:ssh_host_key::/'
	fi

	scc_check_file "${dir}/ssh_host_key.pub" "fix:software:openssh2:ssh_host_key.pub::" "#"

	scc_check_file "${dir}/ssh_known_hosts" "fix:software:openssh2:ssh_known_hosts::" "#"
	scc_check_file "${dir}/shosts.equiv" "fix:software:openssh2:shosts.equiv::" "#"
	scc_check_file "${dir}/sshrc" "fix:software:openssh2:sshrc::" "#"

	break			# Do not check other directories
done
scc_check_file /etc/ssh_known_hosts "fix:software:openssh2:/etc/ssh_known_hosts::" "#"

scc_check_file /etc/pam.conf "fix:software:pam:/etc/pam.conf::" "#"
scc_check_file /etc/pam_user.conf "fix:software:pam:/etc/pam_user.conf::" "#"

for f in /etc/pam.d/*
do
	scc_check_file "${f}" "fix:software:pam:${f}::" "#"
done

if [ -x /usr/bin/showrev ]
then
	/usr/bin/showrev -p				|
	sort -nr					|
	sed -e 's/^/fix:software:patches:showrev::/'
fi

if [ -x /usr/contrib/bin/show_patches ]
then
	/usr/contrib/bin/show_patches -s		|
	sed -e 's/^/fix:software:patches:superseded::/'

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

if [ -x /usr/contrib/bin/check_patches ]
then
	/usr/contrib/bin/check_patches -i >/dev/null 2>&1
	sed	-e '1,/^$/d'	\
		-e 's/^/fix:software:patches:invalid::/' </tmp/check_patches.report

	/usr/contrib/bin/check_patches -s >/dev/null 2>&1
	sed	-e '1,/^$/d'	\
		-e 's/^/fix:software:patches:non-configured::/' </tmp/check_patches.report

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

if [ -x /usr/sbin/dupatch ]
then
	/usr/sbin/dupatch -track -nolog -type kit 2>/dev/null	|
	sed	-e '1,/-------/d'		\
		-e '/^[ 	]*NOTE/,$d'	\
		-e '/^[ 	]*$/d'		\
		-e 's/^/fix:software:patch-kit::/'

	# Ignore up to the header and then the next 3 lines.
	/usr/sbin/dupatch -track -nolog -type patch 2>/dev/null	|
	sed	-e '1,/Patches installed on the system:/d'	|
	sed	-e '1,3d'		\
		-e '/^[ 	]*$/d'	\
		-e 's/^ - //'		\
		-e 's/^/fix:software:installed-patches::/'
fi

# OpenBSD packet filter
scc_check_file /etc/pf.conf "fix:software:packet filter:/etc/pf.conf::" "#"
scc_check_file /etc/pf.os "fix:software:packet filter:/etc/pf.os::" "#"
scc_check_file /etc/authpf/authpf.conf "fix:software:packet filter:/etc/authpf/authpf.conf::" "#"
scc_check_file /etc/authpf/authpf.allow "fix:software:packet filter:/etc/authpf/authpf.allow::" "#"
scc_check_file /etc/authpf/authpf.rules "fix:software:packet filter:/etc/authpf/authpf.rules::" "#"
scc_check_file /etc/authpf/authpf.message "fix:software:packet filter:/etc/authpf/authpf.message::" "#"
scc_check_file /etc/authpf/authpf.problem "fix:software:packet filter:/etc/authpf/authpf.problem::" "#"
for f in /etc/authpf/users/*/authpf.conf /etc/authpf/banned/*
do
	scc_check_file "${f}" "fix:software:packet filter:${f}::" "#"
done

postconf_exe="$(which postconf 2>/dev/null)"
if [ -x "${postconf_exe}" ]
then
	postconf 2>/dev/null		|
	sed -e 's/^/fix:software:postfix::/'
fi

prefix="fix:software:Predictive"
if [ -x /opt/pred/bin/psconfig ]
then
	/opt/pred/bin/psconfig print configuration 2>&1		|
	sed -e '1,/^---/d'					|
	sed -e "s/^/${prefix}:psconfig::config:		/"

	/opt/pred/bin/psconfig print versions 2>&1		|
	sed -e '1,/^---/d'					|
	sed -e "s/^/${prefix}:psconfig::ruleset:	/"

	scc_check_file /etc/uucp/Devices "${prefix}:/etc/uucp/Devices::" "#"
	scc_check_file /etc/uucp/Dialers "${prefix}:/etc/uucp/Dialers::" "#"

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of Predictive"
fi
prefix=""

scc_check_file /etc/prmconf "fix:software:PRM /etc/prmconf::" "#"

scc_check_file /var/sam/.acl "fix:software:SAM:.acl::" "#"
scc_check_file /var/sam/preferences/app_preference "fix:software:SAM:app_preference::" "#"

for f in /etc/sam/custom/*.tp
do
	scc_check_file ${f} "fix:software:SAM:template:$(basename ${f})::" "#"
done
for f in /etc/sam/custom/*.cf
do
	scc_check_file ${f} "fix:software:SAM:restricted users:$(basename ${f})::" "#"
done
for f in /etc/sam/custom/*.gp
do
	scc_check_file ${f} "fix:software:SAM:restricted groups:$(basename ${f})::" "#"
done

scc_check_file /etc/sam/reg_dirs.db "fix:software:SAM:reg_dirs.db::" "#"
scc_check_file /etc/sam/reg_files.db "fix:software:SAM:reg_files.db::" "#"

for f in /etc/sam/*excl
do
	scc_check_file ${f} "fix:software:SAM:exclude lists:$(basename ${f})::" "#"
done

# Edit scc-localize to change the default setting of this variable.
if [ -z "${SCC_TESTPARM}" ]
then
	# No specific PATH, use the default list of directories of SCC).
	SCC_TESTPARM="$(which testparm 2>/dev/null)"
	SCC_TESTPARM="${SCC_TESTPARM-:testparm}"
fi
if [ ! -x "${SCC_TESTPARM}" ]
then
	# testparm is not accessible through our PATH.
	# When smbd is running, we signal via a message that we cannot 
	# capture the configuration of the running Samba server.
	grep -l "[ 	/]smbd" ${PROC_FILE} >/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
		echo "fix:messages::to access testparm (samba), copy and edit scc-localize: SCC_TESTPARM"
	fi
fi
if [ -x "${SCC_TESTPARM}" ]
then
	"${SCC_TESTPARM}" -s 2>/dev/null				|
	awk '/^\[.*\]$/ { prefix=$1; next; }
		{
			if ( NR == 1 )
			{
				prefix="general";
			}

			if ( NF > 0 )
			{
				print prefix "::" $0;
			}
		}'					|
	sed	-e 's/^\[//'	\
		-e 's/]::/::/'	\
		-e 's/^/fix:software:samba:/'
fi

# Service Control Manager
# Only report SCM when this is a management system, otherwise ignore
SCM_LABEL="fix:software:Service Control Manager"
scc_check_file /var/opt/mx/data/mx.properties "${SCM_LABEL}:mx.properties::" "#"
if [ -x /etc/rc.config.d/ServCtlMgr ]
then
	. /etc/rc.config.d/ServCtlMgr
	if [ ${SCM_START_CMS} = 1 ]
	then
		if [ -x /opt/mx/bin/mxnode ]
		then
			/opt/mx/bin/mxauth -lt 2>&1		|
			sed -e "s/^/${SCM_LABEL}:autorisation::/"

			/opt/mx/bin/mxnode -lt 2>&1		|
			sed -e "s/^/${SCM_LABEL}:nodes::/"

			/opt/mx/bin/mxngroup -lt 2>&1		|
			sed -e "s/^/${SCM_LABEL}:nodegroup::/"

			/opt/mx/bin/mxrole -lt 2>&1		|
			sed -e "s/^/${SCM_LABEL}:role::/"

			/opt/mx/bin/mxuser -lt 2>&1		|
			sed -e "s/^/${SCM_LABEL}:users::/"
		fi
		if [ -x /opt/mx/bin/mxtool ]
		then
			/opt/mx/bin/mxtool -ld 2>/dev/null	|
			grep "/Category:"			|
			cut -c25-				|
			sort -u					|
			while read cat
			do
				/opt/mx/bin/mxtool -ld -c "${cat}" 2>/dev/null	|
				grep "^Tool name:"				|
				cut -c25-					|
				sort -u						|
				while read tool
				do
					/opt/mx/bin/mxtool -ld -t "${tool}" 2>&1		|
					sed -e "s/^/${SCM_LABEL}:category ${cat}::${tool}:	/"
				done
			done
		fi
	fi
fi

if [ -x /opt/scr/bin/scrconfig ]
then
	# System Configuration Repository
	/opt/scr/bin/scrconfig 2>/dev/null				|
	sed -e 's@[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9] ......@MM/DD/YYYY HH:MM ???   @' \
		-e 's/^/fix:software:SCR:config::/'

	# By using scc, you don't need SCR-details. Ignore it by default as it produces MUCH output.
	# Edit scc-localize to change the default setting of this variable.
	if [ "${SCC_SCR_DETAILS}" ]
	then
		/opt/scr/bin/scrfilter 2>/dev/null				|
		while read filter
		do
			/opt/scr/bin/scrfilter -l "${filter}" 2>/dev/null			|
			sed	-e "s/^/fix:software:SCR:filter ${filter}::/"	\
				-e 's/  *on$/	on/'				\
				-e 's/  *off$/	off/'
		done
	fi
fi

[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: start of SD-UX"

if [ -x /usr/sbin/swlist ]
then
	swacl -l host 2>/dev/null			|
	sed	-e '1,/^$/d'		\
		-e "s@^@fix:software:SD-UX:swacl-host::@"

	swacl -l root 2>/dev/null			|
	sed	-e '1,/^$/d'		\
		-e "s@^@fix:software:SD-UX:swacl-root::@"

	swacl -l global_soc_template 2>/dev/null			|
	sed	-e '1,/^$/d'		\
		-e "s@^@fix:software:SD-UX:swacl-global_soc_template::@"

	swlist -l depot 2>/dev/null	|
	sort				|
	sed	-e '/^#/d'	\
		-e 's/^ *//'	\
		-e '/^ *$/d'		|
	while read depot
	do
		if [ -d "${depot}" -o -f "${depot}" ]
		then
			[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: start of depot ${depot}"

			# File depots do not have ACL's
			if [ ! -f "${depot}" ]
			then
				swacl -l depot @ "${depot}" 2>&1		|
				sed	-e '1,/^$/d'		\
					-e "s@^@fix:software:SD-UX:${depot}:swacl::@"
			fi

			# Get attributes of depots, we are not interested in all attributes.
			# Those containing '_' seem interesting enough.
			swlist -d -v -l depot @ "${depot}" 2>/dev/null  |
			awk     '				{ prefix="fix" }
				/_date/				{ prefix="var" }
				/_time/				{ next }
				/^[^    ]*_[^ 	]*[ 	]/	{ print prefix ":" c "::" $0; next }'	\
					c="software:SD-UX:${depot}:attributes"

			# Get some attributes of bundles and products.
			for level in bundle product
			do
				swlist -d -v -l ${level} @ "${depot}" 2>/dev/null	|
				awk	'/^software_spec/	{
									split( $2, parts, "," );
									l = sprintf( "%s:%s,%s",\
										p, parts[ 1 ], parts[ 2 ] );
									if ( NF > 1 )
									{
										print l "::" $0;
									}
									next;
								}
					/^control_directory/	{ if ( NF > 1 ) print l "::" $0; next; }
					/^machine_type/		{ if ( NF > 1 ) print l "::" $0; next; }
					/^os_/			{ if ( NF > 1 ) print l "::" $0; next; }
					/^is_/			{ if ( NF > 1 ) print l "::" $0; next; }' \
						p="fix:software:SD-UX:${depot}:${level}"
			done
		else
			# swlist -l depot reports this depot, but there is no directory or file.
			# When the depot is removed, it should be unregisterd by: swreg -l depot -u <depot>
			echo "fix:messages::SD-UX:depot ${depot} not found"
		fi
	done

	swmodify -V 2>/dev/null				|
	sed	-e '/^[ 	]*$/d'	\
		-e 's/^/fix:software:SD-UX:data model revisions::/'
fi

[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of SD-UX"

# Assign "var" to Real and RunAS UG to avoid differences between interactive runs and cron-jobs.
echo ""							|
sendmail -bt -d 2>/dev/null				|
sed	-e '/^[ 	]*$/d'			\
	-e '/getla/d'				\
	-e '/assign_queueid/d'				|
awk	'				{ prefix="fix"; }
	/Real.UG.id=[^:]*:[^:]*,/	{ prefix="var"; }
	/RunAs[UG]id=[^:]*:[^:]*,/	{ prefix="var"; }
					{ print prefix ":software:sendmail:options::" $0 }'

for f in	access			\
		aliases			\
		domaintable		\
		mail.rc			\
		mailertable		\
		mailer.conf		\
		sendmail.cf		\
		sendmail.mc		\
		service.switch		\
		spamd.conf		\
		local-host-names	\
		trusted-users		\
		virtusertable
do
	for d in /etc/postfix /etc /etc/mail
	do
		# Stop when the file is found.
		scc_check_file "${d}/${f}" "fix:software:sendmail:${d}/${f}::" "#" && break
	done
done

ls -l /etc/smrsh/* 2>/dev/null		|
scc_ls					|
sed -e 's@^@fix:software:sendmail:/etc/smrsh::@'

scc_check_file /etc/sensorsd.conf "fix:software:/etc/sensorsd.conf::" "#"

#### HP ServiceGuard: both Linux and HP-UX versions
# Read cluster paths on linux cluster
if [ -f /etc/cmcluster.conf ]
then
	scc_check_file /etc/cmcluster.conf "fix:software:ServiceGuard:/etc/cmcluster.conf::" "#"
	. /etc/cmcluster.conf
fi

# Set path for HP-UX cluster if linux cluster paths not set
SGSBIN=${SGSBIN:-/usr/sbin}
SGCONF=${SGCONF:-/etc/cmcluster}

if [ -x ${SGSBIN}/cmquerycl ]
then
	grep -l -e "${SGLBIN}/c[m]cld" -e " c[m]cld" ${PROC_FILE} >/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
		echo "fix:software:ServiceGuard:general::status:	active"

		${SGSBIN}/cmquerycl -v		|
		sed -e 's/^/var:software:ServiceGuard:sw-status::/'

		${SGSBIN}/cmgetconf 2>/dev/null					|
		sed	-e '/^#/d'					\
			-e '/does not have an ID, or a disk label/d'	\
			-e '/cannot be included in the topology/d'	\
			-e '/^[Uu]se /d'				\
			-e 's/^/fix:software:ServiceGuard:cluster::/'		|
		uniq

		scc_check_file ${SGCONF}/cmclnodelist "fix:software:ServiceGuard:cmclnodelist::" "#"
		scc_check_file ${SGCONF}/cmcluster.rc "fix:software:ServiceGuard:cmcluster.rc::" "#"

		${SGSBIN}/cmviewcl -v 2>${TMP1_FILE}		|
		sed -e "s/^/var:software:ServiceGuard:status::/"

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

		# Get the status of the package.
		${SGSBIN}/cmviewcl -l package 2>/dev/null	|
		sed	-e '/^[ 	]*$/d'	\
			-e '/PACKAGE/d'		\
			-e 's/^[ 	]*//'	\
			-e 's/[ 	].*//'			|
		sort						|
		while read pkg remainder
		do
			${SGSBIN}/cmgetconf -v -p ${pkg}		|
			sed	-e '/^#/d'		\
				-e '/^[ 	]*$/d'	\
				-e "s/^/fix:software:ServiceGuard:${pkg}::/"

			${SGSBIN}/cmgetconf -p ${pkg}							|
			awk	'/^RUN_SCRIPT[ 	]/	{ run = $2; print $2, $1 }
				/^HALT_SCRIPT[ 	]/	{ if ( $2 != run ) print $2, $1 }'	|
			while read file category
			do
				scc_check_file "${file}" "fix:software:ServiceGuard:${pkg}::${category}:	" "#"
			done

		done
	else
		echo "fix:software:ServiceGuard:general::status:	inactive"
	fi
fi

# Sun Cluster.
if [ -x /usr/cluster/bin/scconf ]
then
	/usr/cluster/bin/scinstall -p 2>/dev/null	|
	sed -e 's/^/fix:software:Sun Cluster:scinstall::/'

	/usr/cluster/bin/scconf -p 2>/dev/null		|
	sed -e 's/^/fix:software:Sun Cluster:scconf::/'

	/usr/cluster/bin/scrgadm -p 2>/dev/null		|
	sed -e 's/^/fix:software:Sun Cluster:scrgadm::/'

	/usr/cluster/bin/scstat -p 2>/dev/null		|
	sed -e 's/^/var:software:Sun Cluster:scstat::/'
fi

# TRU64 Cluster
if [ -x /usr/sbin/clu_get_info ]
then
	/usr/sbin/clu_get_info 2>/dev/null		|
	tee ${TMP1_FILE}				|
	sed -e 's/^/fix:software:TRU64 Cluster:clu_get_info::/'

	myid="$(awk '/memberid for this member =/ { print $NF }' ${TMP1_FILE})"
	if [ "${myid}" ]
	then
		/usr/sbin/clu_get_info -full -m "${myid}" 2>/dev/null		|
		sed -e 's/^/fix:software:TRU64 Cluster:full info::/'
	fi

	rm -f ${TMP1_FILE}
fi

if [ -x /usr/bin/caa_stat ]
then
	/usr/bin/caa_stat -v 2>/dev/null		|
	awk	'				{ prefix="fix"; }
		/^RESTART|^FAILURE_COUNT/	{ prefix="var"; }
						{ print prefix ":software:TRU64 Cluster:applications::" $0 }'
fi

scc_check_file /etc/rc.config.common "fix:software:TRU64 Cluster:/etc/rc.config.common::" "#"
if [ "${OS_NAME}" = "OSF1" ]
then
	scc_check_file /etc/rc.config "fix:software:TRU64 Cluster:/etc/rc.config::" "#"
fi

grep -l "squid.*-f" ${PROC_FILE} >/dev/null 2>/dev/null
if [ $? -eq 0 ]
then
	grep "squid.*-f" ${PROC_FILE}		|
	sed	-e 's/.*squid.*-f *//'	\
		-e 's/ .*//'
else
	# In order to let the following code work, squid should be located in 
	# one of the directories of PATH. Or a symbolic link to the executable
	# should be placed in directory ${SCC_BIN}.
	squid_exe="$(which squid 2>/dev/null)"
	if [ -x "${squid_exe}" ]
	then
		squid -h 2>&1		|
		awk '/  *-f file/	{ 
						if ( NF > 7 )
						{
							print $8;
						}
						else
						{
							getline;
							print $1;
						}
					}'
	fi
fi >${TMP1_FILE}

scc_keep_squid_count="software:squid:count"
scc_keep_squid_config="software:squid:config"
if [ -s ${TMP1_FILE} ]
then
	# We collected a config-file from a running squid.
	squid_cfg=$(cat ${TMP1_FILE})
	squid_cnt=1
else
	# Use the config-file from a previous run of SCC.
	# Use this data for max. 5 runs of SCC.
	squid_cnt=$(sed -n -e "s/^${scc_keep_squid_count}://p" ${SCC_KEEP_CONFIG})
	squid_cnt=$(( ${squid_cnt:-0} + 1 ))
	squid_cfg=""
	if [ ${squid_cnt} -lt 5 -a ${squid_cnt} -gt 1 ]
	then
		squid_cfg=$(sed -n -e "s/^${scc_keep_squid_config}://p" ${SCC_KEEP_CONFIG})
	fi
fi

if [ -n "${squid_cfg}" ]
then
	scc_check_file "${squid_cfg}" "fix:software:squid:${squid_cfg}::" "#"

	if [ -f "${squid_cfg}" ]
	then
		# Keep the name of the config-file in the case that squid
		# is not running during the next run of SCC.
		echo "${scc_keep_squid_config}:${squid_cfg}" >>${SCC_KEEP_NEW}
		echo "${scc_keep_squid_count}:${squid_cnt}" >>${SCC_KEEP_NEW}
	fi
fi
rm -f ${TMP1_FILE}

sram_dir=/etc/opt/sram
sram_cfg=${sram_dir}/user.ini

if [ -f ${sram_cfg} ]
then

	include_path=$(sed -n -e 's/^include=//p' ${sram_cfg})
	specs=$(sed -n -e 's/^configfile=//p' ${sram_cfg})

	# Select the existing directories to speed-up finding the included files.
	touch ${TMP1_FILE}
	dir_list=$(for d in $(echo ${sram_dir} ${include_path} | sed -e 's/:/ /g')
		do
			if [ -d "${d}" ]
			then
				echo "${d}"

				# Check all include directories in case configfile is a relative path.
				if [ -f "${d}/${specs}" ]
				then
					echo "${d}/${specs}" >${TMP1_FILE}
				fi
			fi
		done)

	if [ ! -f "${specs}" ]
	then
		specs=$(<${TMP1_FILE})
	fi
	rm -f ${TMP1_FILE}

	scc_check_file ${sram_cfg} "fix:software:SRAM:${sram_cfg}::" "#"

	# ${TMP1_FILE} holds the hierarchy.
	# We process the hierarchy to find new includes.
	# ${TMP2_FILE}  holds the hierarchy and its includes.
	# We loop until there are no new includes.
	level=0
	todo="${specs}"
	echo "${specs}" >${TMP1_FILE}
	while [ -n "${todo}" ]
	do
		level=$(( ${level} + 1 ))
		if [ ${level} -gt 20 ]
		then
			echo "fix:messages::nesting too deep for SRAM: ${level}"
		fi

		todo=""
		>${TMP2_FILE}

		while read l f
		do
			if [ -n "${f}" ]
			then
				# level and file are determined: ready
				echo "${l} ${f}" >>${TMP2_FILE}
				continue;
			fi
			f="${l}"

			if [ ! -f "${f}" ]
			then
				echo "fix:messages::missing include file for SRAM: ${f}"
				continue
			fi

			echo "${level} ${f}" >>${TMP2_FILE}

			# Now we are adding the includes of ${f} without a level indicator.
			# Process these files at the next level (run of the outer loop).
			sed -n -e 's/^[ 	]*include[ 	]*"//p' "${f}"	|
			sed -e 's/";.*//'					|
			while read inc remainder
			do
				if [ -f "${inc}" ]
				then
					todo="${inc}"
					echo "${inc}" >>${TMP2_FILE}
				else
					for d in ${dir_list}
					do
						if [ -f "${d}/${inc}" ]
						then
							todo="${d}/${inc}"
							echo "${d}/${inc}" >>${TMP2_FILE}
							break
						fi
					done
				fi
			done
		done <${TMP1_FILE}

		mv ${TMP2_FILE} ${TMP1_FILE}
	done

	# Add the hierarchy to the snapshot
	awk '{
		# Syntax is: <level> <file>
		printf( "fix:software:SRAM:hierarchy::" );
		# Replace the level by indentation.
		for ( i = 1; i < $1; i++ )
		{
			printf( "   " );
		}
		$1 = "";
		print;
	}' ${TMP1_FILE}

	# Add the config and all included files to the snapshot.
	sed -e 's/^[0-9][0-9]*.//' ${TMP1_FILE}		|
	sort -u						|
	while read file remainder
	do
		sed -e "s@^@fix:software:SRAM:${file}::@" ${file}
	done

	rm -f ${TMP1_FILE} ${TMP2_FILE}
fi

scc_check_file /etc/sudoers "fix:software:sudo::/etc/sudoers	" "#"

if [ -d ~sybase ]
then
	(
	cd ~sybase

	if [ -h interfaces ]
	then
		link=$(ls -l interfaces	| awk '{ print $NF }')
		cd $(dirname ${link})
	fi

	if [ -f interfaces ]
	then
		awk '/#/		{ next }
			/^[ 	]*$/	{ next }
			/^[^ 	]/	{ prefix = $1 }
					{ printf( "fix:software:sybase:%s::interface:	%s\n", prefix, $0 ) }' interfaces
	fi

	for f in init/*/version
	do
		scc_check_file "${f}" "fix:software:sybase:version:$(basename ${f})::" "#"
	done

	sed -n "s/.*-s//p" install/RUN_* 2>/dev/null	|
	sed -e 's/ .*//'				|
	sort -u						|
	while read dbms
	do
		grep -l "${dbms}" ${PROC_FILE} >/dev/null 2>/dev/null
		if [ $? -eq 0 ]
		then
			scc_check_file "${dbms}.cfg" "fix:software:sybase:${dbms}.cfg::" "#"	|
			grep -v "DEFAULT$"
		fi
	done
	)
fi

# Switch-over is replaced after HP-UX 10.20 by MC/ServiceGuard
scc_check_file /etc/switch/Switchinfo "fix:software:switchover:/etc/switch/Switchinfo::" "#"
scc_check_file /etc/switch/become "fix:software:switchover:/etc/switch/become::" "#"

scc_check_file /var/adm/sw/.codewords "fix:software:swinstall /var/adm/sw/.codewords::" "#"

syslog_cfg=$(sed -n -e 's/.*[s]yslogd.*-f *//p' ${PROC_FILE} | sed -e 's/ .*//')
if [ ! -f "${syslog_cfg}" ]
then
	syslog_cfg=/etc/syslog.conf
fi
scc_check_file "${syslog_cfg}" "fix:software:syslogd ${syslog_cfg}::" "#"
scc_check_file /etc/newsyslog.conf "fix:software:syslogd /etc/newsyslog.conf::" "#"

scc_check_file /etc/ucf.conf "fix:software:/etc/ucf.conf::" "#"

scc_check_file /etc/updatedb.conf "fix:software:/etc/updatedb.conf::" "#"

VCS_BIN=/opt/VRTSvcs/bin
export VCS_BIN

if [ -d "${VCS_BIN}" ]
then
	VCS_CLASS="software:Veritas Cluster Server"

	grep -l "${VCS_BIN}/[h]ad" ${PROC_FILE} >/dev/null
	if [ $? -eq 1 ]
	then
		# VCS not active, check the keep-file for VCS-data.
		sed -n	-e "/^fix:${VCS_CLASS}:/p"	\
			-e "/^var:${VCS_CLASS}:/p"	\
				${SCC_KEEP_CONFIG}		|
		tee -a ${SCC_KEEP_NEW}
	else
		{
			class="${VCS_CLASS}:dependencies"
			${VCS_BIN}/hagrp -dep			|
			sed -e "s/^/fix:${class}::/"

			class="${VCS_CLASS}:group"
			${VCS_BIN}/hagrp -display -localclus				|
			sed	-e '/^[ 	]$/d'				\
				-e '/^#/d'					\
				-e 's/[ 	][ 	]*/::/'			\
				-e "s/^/fix:${class}:/"					|
			sed	-e "s/^fix:\(${class}:.*::Enabled\)/var:\1/"	\
				-e "s/^fix:\(${class}:.*::State\)/var:\1/"

			class="${VCS_CLASS}:attributes"
			${VCS_BIN}/haclus -display -localclus		|
			sed -e "s/^/fix:${class}::/"			|
			sed	-e "s/^fix:\(${class}::ClusterTime\)/var:\1/"	\
				-e "s/^fix:\(${class}::GlobalCounter\)/var:\1/"

			class="${VCS_CLASS}:status"
			${VCS_BIN}/hastatus -summary		|
			sed -e "s/^/var:${class}::/"

			class="${VCS_CLASS}:resource"
			${VCS_BIN}/hares -display -localclus					|
			sed	-e '/^[ 	]$/d'					\
				-e '/^#/d'						\
				-e 's/[ 	][ 	]*/::/'				\
				-e "s/^/fix:${class}:/"						|
			sed	-e "s/^fix:\(${class}:.*::ConfidenceLevel\)/var:\1/"	\
				-e "s/^fix:\(${class}:.*::LastOnline\)/var:\1/"		\
				-e "s/^fix:\(${class}:.*::ResourceInfo\)/var:\1/"	\
				-e "s/^fix:\(${class}:.*::Start\)/var:\1/"		\
				-e "s/^fix:\(${class}:.*::State\)/var:\1/"

			class="${VCS_CLASS}:resource:dependencies"
			${VCS_BIN}/hares -dep			|
			sed -e "s/^/fix:${class}::/"

			class="${VCS_CLASS}:system"
			${VCS_BIN}/hasys -display -localclus					|
			sed	-e '/^[ 	]$/d'					\
				-e '/^#/d'						\
				-e 's/[ 	][ 	]*/::/'				\
				-e "s/^/fix:${class}:/"						|
			sed	-e "s/^fix:\(${class}:.*::ConfigCheckSum\)/var:\1/"     \
				-e "s/^fix:\(${class}:.*::ConfigModDate\)/var:\1/"

			class="${VCS_CLASS}:system:status"
			${VCS_BIN}/hasys -state -localclus		|
			sed -e "s/^/var:${class}::/"

			class="${VCS_CLASS}:resource type"
			${VCS_BIN}/hatype -display			|
			sed	-e '/^[ 	]$/d'		\
				-e '/^#/d'			\
				-e 's/[ 	][ 	]*/::/'	\
				-e "s/^/var:${class}:/"

			class="${VCS_CLASS}:users"
			${VCS_BIN}/hauser -display			|
			sed -e "s/^/fix:${class}::/"

			class="${VCS_CLASS}:log"
			${VCS_BIN}/halog -info				|
			sed -e "s/^/fix:${class}::/"

			class="${VCS_CLASS}:heartbeat"
			${VCS_BIN}/hahb -display 2>/dev/null		|
			sed -e "s/^/var:${class}::/"

			class="${VCS_CLASS}:defaults"
			for type in cluster group system heartbeat
			do
				${VCS_BIN}/haattr -display ${type} 2>/dev/null		|
				sed -e "s/^/fix:${class}:${type}::/"
			done

			class="${VCS_CLASS}:agents"
			${VCS_BIN}/haagent -display 2>/dev/null		|
			sed -e "s/^/var:${class}::/"

			scc_check_file /etc/llttab "fix:${VCS_CLASS}:connections::" "#"
		}	|
		tee -a ${SCC_KEEP_NEW}

	fi	# if process "had" active
fi	# if [ -d "${VCS_BIN}" ]

exit 0
