#!/bin/sh

# Shell script to collect boot data.
# Copyright (C) 2001-2004 Open Challenge B.V.
# Copyright (C) 2004 OpenEyeT Professional Services.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING.
# If not, write to the Free Software Foundation,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Contact information: www.OpenEyeT.nl/scc/index.html 

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

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

scc_check_file /etc/bcheckrc		"fix:boot:config:/etc/bcheckrc::"		"#"
scc_check_file /etc/lvmrc		"fix:boot:config:/etc/lvmrc::"			"#"
scc_check_file /etc/pre_init_rc		"fix:boot:config:/etc/pre_init_rc::"		"#"
scc_check_file /etc/bootparams		"fix:boot:config:/etc/bootparams::"		"#"
scc_check_file /boot/loader.rc		"fix:boot:config:/boot/loader.rc::"		"#"
scc_check_file /etc/rc.config		"fix:boot:config:/etc/rc.config::"		"#"
scc_check_file /etc/rc.conf		"fix:boot:config:/etc/rc.conf::"		"#"
scc_check_file /etc/rc.securelevel	"fix:boot:config:/etc/rc.securelevel::"		"#"
scc_check_file /etc/rc.local		"fix:boot:config:/etc/rc.local::"		"#"
scc_check_file /etc/rc.d/rc.local	"fix:boot:config:/etc/rc.d/rc.local::"		"#"
scc_check_file /etc/rc.d/rc.sysinit	"fix:boot:config:/etc/rc.d/rc.sysinit::"	"#"
scc_check_file /etc/rc.lkm		"fix:boot:config:/etc/rc.lkm::"			"#"
scc_check_file /etc/rc.subr		"fix:boot:config:/etc/rc.subr::"		"#"
scc_check_file /etc/sysctl.conf		"fix:boot:config:/etc/sysctl.conf::"		"#"
scc_check_file /stand/bootconf		"fix:boot:config:/stand/bootconf::"		"#"
scc_check_file /etc/rc.shutdown		"fix:boot:config:/etc/rc.shutdown::"		"#"
scc_check_file /etc/shutdown.allow	"fix:boot:config:/etc/shutdown.allow::"		"#"	|
sort
scc_check_file /bosinst.data		"fix:boot:install:/bostinst.data::"		"#"

if [ -x /usr/sbin/bootinfo ]
then
	# Contributed by Doug Probst.
	echo "fix:boot:devices::IPL Device: $(bootinfo -b )"
	bootlist -m normal -o		|
	awk 'BEGIN	{ printf( "fix:boot:devices::bootlist:" ); }
			{ printf( "  %s", $0 ); }
		END	{ printf( "\n" ); }'
fi

if [ -x /usr/bin/lifcp -o -x /usr/sbin/idisk ]
then
	raw_boot=""
	if [ -x /usr/sbin/vxdctl ]
	then
		raw_boot="$(/usr/sbin/vxdctl list 2>/dev/null |
				sed -n -e 's@.*disk \([^ ]*\) .*@/dev/rdsk/\1@p')"
	fi
	if [ -f /etc/lvmtab ]
	then
		boot=$(/sbin/lvlnboot -v 2>&1 | awk '/Disk/ { print $1 } ')
		raw_boot="${raw_boot} $(echo "${boot}" | sed -e 's/dsk/rdsk/' -e 's/ .*//')"
	fi
	for b in ${raw_boot}
	do
		if [ ! -c "${b}" ]
		then
			continue
		fi

		if [ -x /usr/bin/lifcp ]
		then
			/usr/bin/lifcp "${b}:AUTO" ${TMP1_FILE} 2>${TMP1_FILE}
			if [ -f ${TMP1_FILE} ]
			then
				tr -d "\000" <${TMP1_FILE}			|
				sed -e "s@^@fix:boot:device:${b}::autoboot:	@"
			fi
			rm -f ${TMP1_FILE}

			# Remove the date and time. This reduces the amount of
			# differences when comparing snapshots of different systems.
			/usr/bin/lifls -l "${b}"				|
			sed	-e 's@../../..  *..:..:.. *$@@'		\
				-e "s@^@fix:boot:device:${b}::lifls:	@"
		fi

		if [ -x /usr/sbin/idisk ]
		then
			/usr/sbin/idisk "${raw}" 2>/dev/null			|
			sed -e "s@^@fix:boot:device:${b}::idisk:	@"
		fi

		if [ -x /usr/sbin/efi_ls ]
		then
			# Remove the date and time. This reduces the amount of
			# differences when comparing snapshots of different systems.
			/usr/sbin/efi_ls -d "${raw}" 2>/dev/null			|
			awk '/^total/	{
						printf( "fix:boot:device:%s::efi_ls:	%s\n", b, $0 );
						next;
					}
					{
						data = "";
						if ( NF > 1 )
						{
							data = sprintf( "%-40s %s", $1, $(NF) );
						}
						printf( "fix:boot:device:%s::efi_ls:	%s\n", b, data );
					}' b="${b}"
		fi
	done

	if [ -f /etc/lvmtab ]
	then
		# Sometimes the label 'Boot' is replaced by 'PV Name'.
		# Replace the latter by the first.
		# Ignore the messages caused by inactive volume groups in a ServiceGuard environment.
		/sbin/lvlnboot -v 2>&1						|
		sed	-e 's/^PV Name:/Boot:/'				\
			-e '/Volume group not activated/d'		\
			-e '/Cannot display volume group/d'		\
			-e '/is an alternate link/d'			\
			-e 's/^/fix:boot:info::lvlnboot:	/'
	fi

	if [ -x /usr/sbin/vxdctl ]
	then
		/usr/sbin/vxdctl list 2>/dev/null |
		sed -e 's/^/fix:boot:info::vxdctl:	/'
	fi
fi

if [ -x /usr/sbin/dmesg -a "${OS_NAME}" = "SunOS" ]
then
	/usr/sbin/dmesg					|
	grep "^root on"					|
	tail -1						|
	sed -e 's/^/fix:boot:root-device::/'
fi

# On *BSD systems, the boot-messages are preserved in a seperate file.
# The number of Hz may change between reboots.
scc_check_file "/var/run/dmesg.boot" "fix:boot:/var/run/dmesg.boot::" "#"	|
sed -e "s/fix:\(.*Hz\)/var:\1/"

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

for file in /etc/rc.config.d/* /etc/rc.conf.d
do
	fname="${file##*/}"           # get file basename
	if [ -f "${file}" -a "${fname}" != "core" ]
	then
		if [ "${OS_NAME}" = "HP-UX" -a "${fname##*[.,~\#]}" != "${fname}" ]
		then
			# HPUX is strict on the names of files in this directory, check the code in /etc/rc.config
			continue
		fi

		awk '/^[ 	]*$/	{ next }
			/^[ 	]*#/	{ next }
					{ print p $0; data_shown=1 }
			END	{
					if ( ! data_shown )
					{
						# Indicate the presence of this file, even if it contains only
						# blank/comment lines. Add an empty line.
						print p;
					}
				}' p="fix:boot:rc-file:${file}::" "${file}"
	fi
done

for entry in /usr/local/etc/*
do
	if [ -d "${entry}" ]
	then
		# Ignore ssh as it also contains the private key file.
		# Ignore rc.d as it contains the start-stop scripts itself (for FreeBSD).
		# Ingore codepages for FreeBSD.
		if [	"${entry}" != "/usr/local/etc/ssh" -a	\
			"${entry}" != "/usr/local/etc/rc.d" -a	\
			"${entry}" != "/usr/local/etc/codepages"	]
		then
			for f in ${entry}/*
			do
				scc_check_file "${f}" "fix:boot:rc-file:${entry##*/}/${f##*/}::" "#"
			done
		fi
	else
		# OSF1: Do not record the profiles of the users.
		name="${entry##*/}"
		if [ "${name%.*}" != "profile" ]	
		then
			scc_check_file "${entry}" "fix:boot:rc-file:${entry##*/}::" "#"
		fi
	fi
done

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

for file in /etc/default/* /etc/defaults/*
do
	scc_check_file "${file}" "fix:boot:defaults:${file}::" "#"
done

if [ -x /usr/sbin/prtconf ]
then
	if [ "$OS_NAME" = "AIX" ]
	then
		# Contributed by Doug Probst.
		echo "fix:boot:firmware::prtconf:$(/usr/sbin/prtconf 2>/dev/null | awk -F, '/Firmware Version/ {print $2}')"
	else
		/usr/sbin/prtconf -V 2>/dev/null		|
		sed -e 's/^/fix:boot:firmware::prtconf:	/'
	fi
fi

scc_check_file /etc/inittab "fix:boot:file:/etc/inittab::" "#"

scc_check_file /boot/grub/device.map "fix:boot:grub:/boot/grub/device.map::" "#"
scc_check_file /boot/grub/menu.lst "fix:boot:grub:/boot/grub/menu.lst::" "#"

if [ -x /sbin/lilo ]
then
	/sbin/lilo -q -v 2>/dev/null			|
	sed -e 's/^/fix:boot:lilo::/'
fi

scc_check_file /proc/cmdline "fix:boot:kernel /proc/cmdline::" "#"

for dir in /sbin/rc*.d /etc/rc?.d /etc/rc.d/rc?.d
do
	# On RH7 /etc/rc?.d are symlinks to /etc/rc.d/rc?.d
	if [ -h "${dir}" -o ! -d "${dir}" ]
	then
		continue
	fi

	ls -l "${dir}"			|
	awk '{
		if ( NF < 8 )
		{
			next;
		}
		if ( $(NF-1) == "->" )
		{
			print $(NF-2), $(NF-1), $NF;
		}
		else
		{
			print $NF;
		}
	}'				|
	sed -e "s@^@fix:boot:run level:${dir}::@"
done

if [ -x /usr/bin/svcs ]
then
	/usr/bin/svcs -a 2>/dev/null			|
	awk '/svc:/ { print $3 }'			|
	sort						|
	while read entry
	do
		label=${entry#svc:/}
		/usr/bin/svcs -l "${entry}" 2>/dev/null		|
		sed	-e "/^contract_id/d"		\
			-e "s@^@${label}:	@"	\
			-e "s@:@::@"			\
			-e "s@/@:@"				|
		sed -e "s/^/fix:boot:svcs:/"
	done
fi

if [ -x /sbin/chkconfig ]
then
	/sbin/chkconfig --list 2>/dev/null		|
	sed -e '/^xinetd based services/,$d'		|
	sort						|
	sed -e 's/^/fix:boot:run level:chkconfig::/'
fi

if [ -x /usr/sbin/setboot ]
then
	/usr/sbin/setboot 2>&1						|
	sed -e 's/^/fix:boot:stable-storage::/'
fi

if [ -x /sbin/consvar ]
then
	/sbin/consvar -l 2>&1				|
	sed -e 's/^/fix:boot:firmware::/'
fi

exit 0
