#!/bin/sh

# Shell script to collect data concerning installed software.
# Copyright (C) 2001-2004 Open Challenge B.V.
# Copyright (C) 2004-2005 OpenEyeT Professional Services.
# Copyright (C) 2005-2009 QNH.
#
# 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: http://scc.qnh-infrastructure.nl/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.9.28
# file-version:	$Revision: 1.175 $
 
set -u

. ${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.
# Ignore processes like (indicated by Harry van Wiggen):
# root  2636  1  0  Mar 12 ?  1:03 /opt/apache/ssl/stunnel/sbin/stunnel -c -d 127.0.0.1:390 -r lda
# hub   3471  1  0  Mar 31 ?  0:35 /appl/local/jdk/1.6.0_03/bin/java -Djava.util.logging.manager=org.apache.abc
rm -f ${TMP2_FILE}
awk	'		{ catch = ""; }
	/\/stunnel /	{ next }
	/\/java /	{ next }
	/apache/	{ catch = "apache"; }
	/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 50 -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}:${exe}:" ${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:
	conf=""
	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

	server="Apache"
	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} ${path} ""
		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
			elif [ -f "${dir}/httpd.cfg" ]
			then
				conf="${dir}/httpd.cfg"
				server="Gaztek webserver"
				break
			fi
		done
	fi

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

		srm_conf="${conf%/*}/srm.conf"
		scc_check_file "${srm_conf}" "fix:software:${server}:${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:${server}:${conf} include:${subconf}::" "#"
		done
	fi
done
rm -f ${TMP1_FILE} ${TMP2_FILE}

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

# Check bbd to determine whether Big Brother/Sister is used.
sed -n -e 's/.*[ 	]\(.*\)\/[b]in\/bbd$/\1/p' ${PROC_FILE} | head -n 1 >${TMP1_FILE}

scc_keep_BB_dir="software:BB:config"
scc_keep_BB_count="software:BB:count"
if [ -s ${TMP1_FILE} ]
then
	# We collected data from a running bbd.

	echo "${scc_keep_BB_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_BB_count}://p" ${SCC_KEEP_CONFIG})
	cnt=$(( ${cnt:-0} + 1 ))
	if [ ${cnt} -le 5 -a ${cnt} -gt 1 ]
	then
		echo "${scc_keep_BB_count}:${cnt}" >>${SCC_KEEP_NEW}

		# Use the base-directory from a previous run of SCC.
		sed -n -e "s/^${scc_keep_BB_dir}://p" ${SCC_KEEP_CONFIG}
	fi
fi				|
while read dir
do
	echo "${scc_keep_BB_dir}:${dir}" >>${SCC_KEEP_NEW}

	label="Big Brother"
	if [ -d "${dir}/adm" ]
	then
		label="Big Sister"
	fi

	for file in "${dir}"/etc/* "${dir}"/adm/*
	do
		scc_check_file "${file}" "fix:software:${label}:${file}::" "#"
	done
done

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/*	\
		/var/spool/cron/tabs/*		\
		/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

# Dag Wiers configuration collector.
for file in /etc/dconf.conf /etc/dconf-custom.conf /etc/dconf.d/*.conf
do
	scc_check_file "${file}" "fix:software:dconf:${file}::" "#"
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::/'

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of EMS-monitors"
fi

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

scc_check_file /etc/exim/configure "fix:software:exim::" "#"

for file in /etc/gmetad.conf /etc/gmond.conf /etc/ganglia/gmond.conf /etc/ganglia/conf.php /etc/ganglia/conf.d/*.conf
do
	scc_check_file "${file}"  "fix:software:ganglia:${file}::" "#"
done

if [ -x /usr/bin/gpgconf ]
then
	/usr/bin/gpgconf --list-components 2>/dev/null		|
	sort -f							|
	sed -e 's/^/fix:software:gpgconf:components::/'

	/usr/bin/gpgconf --list-components 2>/dev/null		|
	sed -e 's/:.*//'					|
	sort -f							|
	while read component
	do
		/usr/bin/gpgconf --list-option  ${component} 2>/dev/null		|
		sort -f									|
		sed -e "s/^/fix:software:gpgconf:component ${component}::/"
	done
fi

# 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 [ -d /etc/java ]
then
	for file in /etc/java/*.conf /etc/java/jpackage-release
	do
		scc_check_file "${file}" "fix:software:java:${file}::" "#"
	done
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

for file in /etc/nagios/*.cfg
do
	scc_check_file "${file}" "fix:software:nagios:${file}::" "#"
done

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

scc_check_file /etc/niminfo "fix:software:nim:/etc/niminfo::" "#"

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

if [ -x /usr/sbin/instfix ]
then
	# AIX
	instfix -i -c		|
	awk -F: '{
			#IY58143:devices.pci.00100f00.rte:5.3.0.1:5.3.0.10:+:Required fixes for AIX 5.3
			if ( $5 == "+" )
			{
				if ( ignore[ $1 ] == 0 )
				{
					printf( "fix:software:instfix:superseded::%s	%s\n", $1, $NF );
					ignore[ $1 ] = 1;
				}
				next;
			}
			if ( $5 == "!" )
			{
				if ( ignore[ $1 ] == 0 )
				{
					printf( "fix:software:instfix:not installed::%s	%s\n", $1, $NF );
					ignore[ $1 ] = 1;
				}
				next;
			}
			if ( $5 == "-" )
			{
				printf( "fix:software:instfix:down level::%s	%-30s	%-12s	%-12s	%s\n",\
					$1, $2, $3, $4, $NF );
				next;
			}
			if ( $5 == "=" )
			{
				printf( "fix:software:instfix:correct level::%s	%-30s	%-12s	%s\n",\
					$1, $2, $3, $NF );
				next;
			}
		}'			|
	sort
fi

if [ -x /usr/sbin/emgr ]
then
	/usr/sbin/emgr -l 2>&1		|
	sed -e 's/^/fix:software:interim fixes::/'
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.9.28"	|
		tee -a ${SCC_KEEP_NEW}
	else
		# remove possible source-install from keep-data
		cat <<-_X_ | ed -s ${SCC_KEEP_CONFIG} >/dev/null 2>/dev/null
			g/fix:software:installed-source::scc:/d
			w
			q
_X_
	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 2>/dev/null			|
	sed -e 's/^/fix:software:installed-aix-filesets::/'
fi

if [ -d /var/log/packages -a -f /etc/slackware-version ]
then
	(
		cd /var/log/packages

		ls                                      |
		xargs awk '/PACKAGE NAME/       {
							if ( show )
							{
								printf( "\n" );
								show = 0;
							}
							printf( "fix:software:installed Slackware packages::%s:", $3 );
							next
						}
			/PACKAGE DESCRIPTION/   { show = 1; next }      # Description is on next line
						{
							if ( show )
							{
								sub( "[^:]*:[ ]*", "" );
								print;
								show = 0;
							}
						}
			END	{
					if ( show )
					{
						printf( "\n" );
					}
				}'
	)
fi

(
	# Define this variable in a sub-shell to avoid influencing the environment of php later in this script.
	export MOONBASE=/var/lib/lunar/moonbase
	if [ ! -d "${MOONBASE}" -a -f /etc/lunar/config ]
	then
		MOONBASE="$( sed -n 's/.*MOONBASE=//p' /etc/lunar/config)"
	fi
	if [ -d "${MOONBASE}" ]
	then
		cd "${MOONBASE}"
		for group in *
		do
			if [ -d "${group}" ]
			then
				# Directory hierarchy: $MOONBASE/group/module/DETAILS
				# Modules can be combined in a directory of a subgroup.
				find "${group}" -type f 2>/dev/null			|
				grep "/DETAILS$"					|
				sort							|
				xargs grep "^[ 	]*VERSION=" /dev/null			|
				sed	-e "s@/DETAILS:.*VERSION=@:@"		\
					-e "s@^@fix:software:lunar modules:@"	\
					-e "s@/@::@"
			fi
		done
	fi

	for file in	"${MOONBASE}/aliases"	\
			/etc/lunar/config	\
			/etc/lunar/local/*	\
			/etc/lunar/mirrors/*
	do
		scc_check_file "${file}" "fix:software:lunar:${file}::" "#"
	done
)


if [ -d /Programs -a "${SCC_LINUX_DISTRO}" = "GoboLinux" ]
then
	(
		cd /Programs
		for program in *
		do
			if [ -h "${program}/Current" ]                  
			then
				ls -ld "${program}/Current"	|
				sed -e "s@.*Current[ 	]*->[ 	]*@${program}:@"
			else
				for version in "${program}"/[0-9]*
				do
					echo "${version}"	|
					sed -e 's@/@:@'
				done
			fi
		done				|
		sed -e 's/^/fix:software:installed GoboLinux packages::/'
	)
fi

if [ -x /usr/bin/pkginfo ]
then
	if [ "${SCC_LINUX_DISTRO}" = "CRUX" ]
	then
		# This distro uses the -i option to list its own type of packages.
		# Output consists of name and version pairs, separated by a space.
		/usr/bin/pkginfo -i		|
		sed	-e 's/ /:/'	\
			-e 's/^/fix:software:installed CRUX packages::/'

		scc_check_file /etc/pkgmk.conf "fix:software:CRUX packages:/etc/pkgmk.conf::" "#"
		scc_check_file /etc/pkgadd.conf "fix:software:CRUX packages:/etc/pkgadd.conf::" "#"

		for file in /etc/prt-get.conf /etc/ports/*
		do
			scc_check_file "${file}" "fix:softare:CRUX ports:${file}::" "#"
		done

		ports -d			|
		sed -e 's/^/var:software:CRUX pots:differences::/'
	elif [ "${SCC_LINUX_DISTRO}" != "vector" ] 
	then
		# VectorLinux contains /usr/bin/pkginfo, but uses Slackware packages.

		# 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( ":", ";" ); stamp = $0; next; }
			/STATUS:/	{
						printf( "fix:software:installed-packages:%s::%s:%s:%s:%s\n",\
							cat, pkg, name, ver, stamp );
						pkg = "";
						name = "";
						cat = "";
						ver = "";
						stamp = "";
						next;
					}'			|
		sed -e 's/:[ 	][ 	]*/:/g'			|
		sort -f -t":" -k 1,8
	fi
fi

scc_check_file /etc/slapt-get/slapt-getrc "fix:software:Slackware:/etc/slapt-get/slapt-getrc::" "#"

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::" "#"
scc_check_file /etc/apt/apt.conf "fix:software:/etc/apt/apt.conf::" "#"
for file in /etc/dpkg/*.cfg
do
	scc_check_file "${file}" "fix:software:${file}::" "#"
done

if [ -x /usr/bin/apt-config ]
then
	/usr/bin/apt-config dump 2>/dev/null		|
	sed -e 's/^/fix:software:apt-config dump::/'
fi 

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/bin/emerge ]
then
	/usr/bin/emerge --pretend --emptytree --nocolor --tree world 2>/dev/null	|
	sed	-e '/Calculating world dependencies/d'		\
		-e "s/^/fix:software:Gentoo portage:software::/"
fi

scc_check_file /etc/dispatch-conf.conf 	"fix:software:Gentoo portage:/etc/dispatch-conf.conf::"	"#"
scc_check_file /etc/etc-update.conf	"fix:software:Gentoo portage:/etc/etc-update.conf::"	"#"
scc_check_file /etc/make.conf		"fix:software:Gentoo portage:/etc/make.conf::"		"#"
scc_check_file /etc/make.globals	"fix:software:Gentoo portage:/etc/make.globals::"	"#"

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 -o -x /usr/pkg/sbin/pkg_info ]
then
	scc_keep_pkginfo_config="fix:software:installed-BSD-packages::"

	# When this program is called during the pre- and post-install
	# of SCC, the pkg-database is locked and cannot be queried.
	# On OpenBSD, pkg_info "hangs" during install. Ignore pkg_info during installs of SCC.
	if [ ! "${SCC_INSTALL_PHASE}" ]
	then
		if [ -x /usr/sbin/pkg_info ]
		then
			/usr/sbin/pkg_info 2>/dev/null
		else
			/usr/pkg/sbin/pkg_info 2>/dev/null
		fi						|
		sed -e "s/^/${scc_keep_pkginfo_config}/"
	fi >${TMP1_FILE}

	if [ -s ${TMP1_FILE} ]
	then
		# Use the output from pkg_info.
		cat ${TMP1_FILE}
	else
		# Use the output from a previous run of SCC. 
		grep "${scc_keep_pkginfo_config}" ${SCC_KEEP_CONFIG}
		if [ $? -ne 0 ]
		then
			# No output from pkg_info and nothing found in the data we kept.
			echo "var:software:installed-BSD-packages:message::No packages are shown for first run of scc during install."
		fi
	fi					|
	tee -a ${SCC_KEEP_NEW}		# keep the results for a next run.
	rm -f ${TMP1_FILE}
	# The use of pkg_info is a permanent attribute of a system. Do not count the
	# use of this data in the keep-file.

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

if [ "${OS_NAME}" = "OpenBSD" ]
then
	# Recording the software versions of the base system of OpenBSD can be done
	# by recording the RCS idents of all seperate files. Suggested by Marco Hyman.
	for dir in /sbin /bin /usr/sbin /usr/bin
	do
		if [ -d "${dir}" ]
		then
			ident "${dir}"/* 2>/dev/null            |
			awk '/^  /	{
						print "fix:software:OpenBSD software:" d "::" label "   " $0;
						next;
					}
					{
						label=$1;
						sub( ".*/", "", label );
						next;
					}' d="${dir}"
		fi
	done
fi

if [ -x /usr/bin/pisi ]
then
	# When listing installed software, the version of a package is not displayed (only the name).
	# To obtain the version, we have to use the info command for the supplied name.
	# To know what data to catch from the info option, we look for a line 
	# with 4 (comma separated) fields: name, version, edition and build
	# Use the first package to determine the label of this line with 4 fields.
	# pisi does not handle head in a pipe well, use a temporary file.
	# Keep the data as pisi li takes quite some time.
	/usr/bin/pisi li				|
	sed	-e 's/^[ 	]*//'	\
		-e 's/ - .*//' >${TMP1_FILE}
	first_package="$(head -n 1 ${TMP1_FILE})"

	# Determine name label, example data:
	#Name: scc, version: 1, release: 8, build 9
	#Naam: scc, versie: 1, uitgave: 8, bouw 9
	label="$(/usr/bin/pisi info ${first_package}	|
		awk -F, '{ if ( NF == 4 ) print $1 }'	|
		sed -e 's/ .*//'			|
		head -n 1)"

	# Get the info of all packages.
	xargs pisi info <${TMP1_FILE}		|
	awk '/^'"${label} "'/	{
					# Example data:
					#Name: knazar, version: 0.2, release: 6, build 2
					#Summary: An application to protect your computer from evil eyes (harmful looks)
					sub( ",", "", $2 ) 		# Get the package name
					if ( ! visited[ $2 ] )
					{
						sub( ",", "", $4 ) 
						sub( ",", "", $6 ) 
						printf( "%s::%s:%s.%s.%s:",	\
							"fix:software:installed pisi packages", $2, $4, $6, $8 );
						visited[ $2 ] = 1;	# avoid double entry in snapshot
						getline;		# goto summary on next line
						$1="";			# erase label
						sub( "^ ", "" );
						print;
						next;
					}
				}'		|
	sort -f

	rm -f ${TMP1_FILE}

	/usr/bin/pisi list-repo 2>/dev/null			|
	sed -e 's/^/fix:software:pisi repositories::/'
fi

if [ "${SCC_LINUX_DISTRO}" = "PuppyLinux" ]
then
	# Remove the continuation character at the end of each line.
	scc_check_file /root/.packages/packages.txt "fix:software:installed Puppy::" "#"	|
	sed -e 's/\\$//'

	scc_check_file /root/.packages/alienpackages.txt "fix:software:installed Puppy alien::" "#"	|
	sed -e 's/\\$//'

	scc_check_file /root/.packages/buildvariables "fix:software:installed Puppy buildvariables::" "#"
fi

if [ -x /usr/bin/pacman ]
then
	scc_check_file /etc/pacman.conf "fix:software:pacman:/etc/pacman.conf::" "#"
	scc_check_file /etc/makepkg.conf "fix:software:pacman:/etc/makepkg.conf::" "#"
	for config in /etc/pacman.d/*
	do
		scc_check_file "${config}" "fix:software:pacman:${config}::" "#"
	done

	if [ "${SCC_LINUX_DISTRO}" = "archlinux" ]
	then
		/usr/bin/pacman -Q 2>/dev/null		|
		sed -e 's/^/fix:software:pacman packages::/'
	else
		/usr/bin/pacman -qa 2>/dev/null		|
		sed -e 's/^/fix:software:pacman packages::/'
	fi
fi

busybox_check rpm
busybox_rpm=$?
if [ ${busybox_rpm} -eq 0 -a -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.
	# When specific output from rpm is added to the snapshot, scc-log has to be extended
	# to avoid changes on the second run of scc on a system.
	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}
		if [ $? -ne 0 ]
		then
			# No output from rpm and nothing found in the data we kept.
			echo "var:software:installed-rpms:message::No rpms are shown for first run of scc during install."
		fi
	fi					|
	tee -a ${SCC_KEEP_NEW}		# keep the results for a next run.
	rm -f ${TMP1_FILE}
	# The use of rpm is a permanent attribute of a system. Do not count the
	# use of this data in the keep-file.

	for file in /etc/pki/rpm-gpg/*
	do
		scc_check_file "${file}" "fix:software:rpm - gpg:${file}::" "#"
	done

	if [ ! "${SCC_INSTALL_PHASE}" ]
	then
		rpm -qa gpg-pubkey			|
		while read key
		do
			rpm -qi "${key}" 2>/dev/null					|
			sed	-e 's/Build Date:.*//'				\
				-e 's/Install Data:.*Build/Build/'		\
				-e "s/^/fix:software:rpm - imported keys:${key}::/"
		done
	fi >${TMP1_FILE}

	if [ -s ${TMP1_FILE} ]
	then
		# Use the output from RPM.
		cat ${TMP1_FILE}
	else
		# Use the output from a previous run of SCC. 
		grep "fix:software:rpm - imported keys:" ${SCC_KEEP_CONFIG}
	fi					|
	tee -a ${SCC_KEEP_NEW}		# keep the results for a next run.
	rm -f ${TMP1_FILE}

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

if [ -x /usr/bin/smart ]
then
	# Smart package manager: config includes channels.
	/usr/bin/smart config --show 2>/dev/null		|
	sed -e 's/^/fix:software:smart:config::/'
fi

scc_check_file /etc/imapd "fix:software:imap:/etc/imapd::" "#"

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

	iptables -nL 2>/dev/null			|
	sed -e 's/^/fix:software:iptables:list::/'
fi

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

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 /etc/openldap/ldap.conf "fix:software:ldap:/etc/openldap/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

if [ -x /usr/sbin/inulag ]
then
	/usr/sbin/inulag -lc				|
	sed -e 's/^/fix:software:license:inulag::/'
fi

if [ -x /usr/bin/lslicense ]
then
	/usr/bin/lslicense				|
	sed -e 's/^/fix:software:license:lslicense::/'
fi

scc_check_file /var/ifor/i4ls.ini "fix:software:license:i4ls.ini::" "#"
scc_check_file /var/ifor/i4ls.rc "fix:software:license:i4ls.rc::" "#"

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

# Contributed by Antoine Davous:
# The file /etc/logadm.conf is altered by the logadm command.
# Lines contain the date of the next processing of that line.
# Example date: Sat Aug 25 01:10:01 2007
# To avoid changes in the logbook, we change all date's to: DDD MMM dd hh:mm:ss YYYYY
scc_check_file /etc/logadm.conf "fix:software:logadm:/etc/logadm.conf::" "#"	|
sed	-e 's/[A-Z][a-z][a-z] [A-Z][a-z][a-z] [0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]/DDD MMM dd hh:mm:ss YYYY/g'

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

	rm -f ${TMP1_FILE}

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

	grep /etc/logrotate.d ${TMP1_FILE} >/dev/null 2>/dev/null
	if [ $? -ne 0 ]
	then
		# /etc/logrotate.d has not been included in the main-config.
		for file in /etc/logrotate.d/*
		do
			scc_check_file "${file}" "fix:software:logrotate:${file}::" "#"
		done
	fi
	rm -f ${TMP1_FILE}
fi

if [ -d /etc/log.d/conf ]
then
	for file in /etc/log.d/conf/logwatch.conf /etc/logwatch/conf/*.conf
	do
		scc_check_file "${file}" "fix:software:logwatch:${file}::" "#" 
	done

	for cat in logfiles services
	do
		# These files appear to be small. Do not give each file its own class.
		# File contents are properties of class ${cat} (category).
		for file in /etc/log.d/conf/${cat}/*
		do
			scc_check_file "${file}" "fix:software:logwatch:${cat}::${file##*/}	: " "#"
		done
	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

export HP_MC3_BIN=/opt/hpsmc/common/bin
export HP_MC3_TMP=${SCC_TMP}/hp_mc3
if [ -x ${HP_MC3_BIN}/hpssidgen ]
then
	mkdir -p ${HP_MC3_TMP}

	# These programs are normally quiet and produce their output in files.
	${HP_MC3_BIN}/hpssidgen -outdir ${HP_MC3_TMP} -V >/dev/null 2>&1
	${HP_MC3_BIN}/hpsconfig -outdir ${HP_MC3_TMP} >/dev/null 2>&1

	(
		cd ${HP_MC3_TMP}
		for file in *
		do
			scc_check_file "${file}" "fix:software:HP Mission Critical Common Component:${file}::" "#" |
			sed -e '/TimestampGenerated/d'
		done
	)
	rm -rf ${HP_MC3_TMP}
fi

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

cfg_file="$(sed -n -e 's/[p]ostgres.* -c config_file=//p' ${PROC_FILE} | sed -e 's/[" ].*//')"
dir="${cfg_file%/*}"
if [ -d "${dir}" ]
then
	for file in "${dir}/"*
	do
		scc_check_file "${file}" "fix:software:postgresql:${file}::" "#"
	done
fi
extra_dir="/etc/postgresql-common" 
if [ "${dir}" != "${extra_dir}" ]
then
	scc_check_file "${extra_dir}/autovacuum.conf" "fix:software:postgreql:${extra_dir}/autovacuum.conf::" "#" 
	scc_check_file "${extra_dir}/users_clusters" "fix:software:postgreql:${extra_dir}/users_clusters::" "#" 
fi

# 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 /etc/Pegasus/access.conf "fix:software:Pegasus:/etc/Pegasus/access.conf::" "#"

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]_* ${SCC_BIN}/scc_modules/scc_utils
do
	case "${module}" in
	*scc_*~)	continue;;		# Ignore (vim) copies.
	esac

	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
	# No longer php as executable.
	php_exe="$(which php5 2>/dev/null)"
fi
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 '/REQUEST_TIME/d'				\
			-e '/tick_prev/d'				\
			-e '/sed_sep/d'					\
			-e '/total_time/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

for file in /etc/phph.ini /usr/local/lib/php.ini /etc/php.d/*.ini /etc/php5/*/php.ini
do
	scc_check_file "${file}" "fix:software:php:${file}::" ";"
done

# The collection of SAP config data has been moved to a separate module: scc_0610_s_oracle_sapr3.

# 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/ssl/openssl.cnf "fix:software:openssl:/etc/ssl/openssl.cnf::" "#"

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

scc_check_file /etc/sysconfig/rhn/rhn-applet	"fix:software:RHN:/etc/sysconfig/rhn/rhn-applet::"	"#"
scc_check_file /etc/sysconfig/rhn/rhnsd		"fix:software:RHN:/etc/sysconfig/rhn/rhnsd::"		"#"
scc_check_file /etc/sysconfig/rhn/sources	"fix:software:RHN:/etc/sysconfig/rhn/sources::"		"#"
scc_check_file /etc/sysconfig/rhn/systemid	"fix:software:RHN:/etc/sysconfig/rhn/systemid::"	"#"
scc_check_file /etc/sysconfig/rhn/up2date	"fix:software:RHN:/etc/sysconfig/rhn/up2date::"		"#"
scc_check_file /etc/sysconfig/rhn/up2date-uuid	"fix:software:RHN:/etc/sysconfig/rhn/up2date-uuid::"	"#"

# 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 /etc/pythonstart "fix:software:python:/etc/pythonstart::" "#"

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"
	else
		# Samba is not running and we cannot access testparm, try some config files on default locations.
		for dir in /etc /etc/samba
		do
			for file in lmhosts smb.conf smbusers
			do
				scc_check_file "${dir}/${file}" "fix:software:samba:${dir}/${file}::" "#"
			done
		done
	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:-no}" ]
	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

# Several small files contain the elements of the user interface. Filename is not part of the classification.
for file in /etc/setuptool.d/*
do
	scc_check_file "${file}" "fix:software:setuptool::${file}	: " "#"
done

if [ -x /usr/sbin/swlist ]
then
	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: start of SD-UX"

	scc_check_file /var/adm/sw/defaults "fix:software:SD-UX:defaults::" "#"

	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	# for level in bundle product
		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	# if [ -d "${depot}" -o -f "${depot}" ]
	done	# while read depot

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

	[ ${SCC_PROFILING} ] && scc_timing "		${SCC_MODULE}: end of SD-UX"
fi	# if [ -x /usr/sbin/swlist ]

# Do not run on Engarde and NetBSD as the -bt option is not supported and produces log-messages.
if [ "${SCC_LINUX_DISTRO}" != "engarde" -a "${OS_NAME}" != "NetBSD" ]
then
	# 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 }'
fi

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::" "#"

scc_check_file "/etc/cluster.conf"		"fix:software:RedHat /etc/cluster.conf::" "#"
scc_check_file "/etc/cluster.xml"		"fix:software:RedHat /etc/cluster.xml::" "#"
scc_check_file "/etc/cluster/cluster.conf"	"fix:software:RedHat /etc/cluster/cluster.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

for file in /etc/snort/*.config
do
	scc_check_file "${file}" "fix:software:snort:${file}::" "#"
done

for file in /etc/spamassassin/*
do
	scc_check_file "${file}" "fix:software:spamassassin:${file}::" "#"
done

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

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

scc_check_file /opt/qs/conf/qs_authfile "fix:software:ServiceGuard:/opt/qs/conf/qs_authfile::" "#"

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

if [ -x /usr/sbin/suma ]
then
	/usr/sbin/suma -c	|
	sed -e 's/^/fix:software:SUMA configuration::/'
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}::" "#"

	(
		# Attempt to collect all config files in the same directory as the squid config file.
		squid_dir="${squid_cfg%/*}"
		if [ -d "${squid_dir}" ]
		then
			ls ${squid_dir}/*.conf		|
			grep -v ${squid_cfg}
		fi

		# Harry van Wiggen indicated the include statement for squid. Example line:
		#acl PROX_ALLOW_DST  url_regex   "/usr/local/squid/etc/prox_allow_dest.txt"
		# These files can reside in another directory than the squid config file.
		awk	'/^acl/	{
					gsub( "\"", "", $(NF) );
					print $NF;
				}' "${squid_cfg}" 2>/dev/null
	)					|
	sort -u					|
	while read file
	do
		scc_check_file "${file}" "fix:software:squid:${file}::" "#"
	done

	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

# SOS: Son Of Sysreport
if [ -x /usr/sbin/sosreport ]
then
	/usr/sbin/sosreport -l 2>/dev/null		|
	sed -e 's/^/fix:software:sosreport::/'
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/syslog-ng/syslog-ng.conf "fix:software:syslogd /etc/syslog-ng/syslog-ng.conf::" "#"

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

if [ -d /etc/tomcat6 ]
then
	for file in /etc/tomcat6/policy.d/*
	do
		scc_check_file "${file}" "fix:software:tomcat6:${file}::" "//"
	done
fi

if [ -x /usr/sbin/ufw ]
then
	/usr/sbin/ufw status 2>/dev/null		|
	sed -e 's/^/fix:software:UbuntuFireWall:status::/'
fi
for file in /etc/ufw/*.rules /etc/ufw/*.conf /etc/ufw/applications.d/*
do
	scc_check_file "${file}" "fix:software:UbuntuFireWall:${file}::" "#"
done

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

if [ -x /usr/sbin/up2date-config ]
then
	/usr/sbin/up2date-config </dev/null 2>/dev/null		|
	sed -n -e 's/^[0-9][0-9]*\. */fix:software:up2date-config::/p'
fi

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}" ]

if [ -d /etc/vmware ]
then
	scc_check_file /etc/vmware/config "fix:software:vmware:/etc/vmware/config::" "#"
	for vmnet in /etc/vmware/vmnet*
	do
		if [ -d "${vmnet}" ]
		then
			for type in dhcpd nat
			do
				scc_check_file "${vmnet}"/${type}/${type}.conf "fix:software:vmware:${vmnet}:${type}.conf::" "#"
			done
		fi
	done

	for version in /etc/vmware/license.gsx*
	do
		scc_check_file "${version}" "fix:software:vmware:config ${version}::" "#"
	done
	scc_check_file /etc/vmware/locations "fix:software:vmware:locations::" "#"
	scc_check_file /etc/vmware/vm-list "fix:software:vmware:virtual machines::" "#"
	scc_check_file /etc/vmware/vm-list-private "fix:software:vmware:private virtual machines::" "#"

	sed -n -e 's/"[ 	]*$//' -e 's/^config[ 	][ 	]*"//p' /etc/vmware/vm-list 2>/dev/null	|
	sort												|
	while read machine
	do
		# Show the full path of the virtual machine (vmx) file in the classification.
		scc_check_file "${machine}" "fix:software:vmware:installed machines:${machine}::" "#"
	done

	for file in /etc/vmware-tools/*.conf
	do
		scc_check_file "${file}" "fix:software:vmware:tools:${file}::" "#"
	done
fi

for file in /etc/openwbem/openwbem.conf /etc/openwbem/openwbem.conf.d/*
do
	scc_check_file "${file}" "fix:software:openwbem:${file}::" "#"
done

scc_check_file /var/lib/YaST2/you/config "fix:software:YaST:config::" "#"	|
sed -e 's/^fix:\(.*\)::LastUpdate/var:\1::LastUpdate/'

scc_check_file /var/lib/YaST2/you/youservers "var:software:YaST:youservers::" "#"

scc_check_file /etc/yum.conf "fix:software:yum:/etc/yum.conf::" "#"
for repo in /etc/yum.repos.d/*
do
	scc_check_file "${repo}" "fix:software:yum:${repo}::" "#"
done

for file in /etc/yum/* /etc/yum/*/*
do
	scc_check_file "${file}" "fix:software:yum:${file}::" "#"
done

# Updated software is registered in the following directory.
ls /var/lib/YaST2/you/installed 2>/dev/null		|
sed -e 's/\(.*\)-\([^-]*\)$/\2 \1/'			|
sort -k 1n						|
sed -e 's/^/fix:software:YaST:installed::/'

for file in zabbix_agent.conf zabbix_agentd.conf zabbix_server.conf
do
	scc_check_file "/etc/zabbix/${file}" "fix:software:zabbix:${file}::" "#"
done

scc_check_file /etc/zmd/zmd.conf "fix:software:Zenworks Linux Management:zmd.conf::" "#"

exit 0
