scc-collect(1)



NAME


	scc-collect - collect system configuration in a SCC-snapshot

RELEASE


	scc	1.23.185

SYNOPSIS


	scc-collect [ -a|--alternate <arg> ]
	            [ -e|--extra <user_mod> ] [ -S|--selection <mod> ]
	            [ -h|--help ] [ -i|--interactive ]

DESCRIPTION


	This program collects configuration data from a system and writes
	it to stdout as a SCC-snapshot. A snapshot is a file containing 
	configuration data. Each line of configuration-data is prefixed with
	a classification. Refer to scc(4) for a detailed description of the
	format of the contents of a snapshot.

	Part of the classification is an indicator whether the data is fixed 
	or variable. This makes it possible to compare snapshots and report 
	any difference in the configuration data that was supposed to be fixed.

	The entire process of creating a new snapshot, comparing it with the
	previous one and adding the differences to a logbook is done by 
	scc-log(1).

	The collection of configuration data is performed by means of 
	modules, located in directory /opt/scc/bin/scc_modules. There are two
	kinds of modules: system and user. The distinction is made by means
	of the names: scc_9999_s_<name> and scc_9999_u_<name>. Where 9999
	stands for a four digit number used to determine the order of the
	execution of the modules. The _s_ and _u_ indicate the system and
	user modules. When a system and user module use the same four-digit
	number, the system module is executed first. System modules are 
	distributed by scc. Each site can extend the functionality of SCC
	by adding user modules.

	When a user module is executed and the -i option is not used, the
	output of the module is stored in a file that is added to the snapshot
	for later calls of this script (to avoid changes in the logbook).
	User module data is kept in /var/opt/scc/data/plugin_data/<module>.

	When a user module requires additional arguments, the -a option
	can be used. Note that each started user module is started with
	these arguments.

	When the code of a user module changes, scc-collect automatically
	ignores any changes in the scc-data of this module on the next run
	of the user-module. To test module scc_1234_u_abc, use the
	following steps:

	   - run all system modules and the user-module to catch changes:
	     scc -e scc_1234_u_abc
	   - change the user-module
	   - test the user-module:
	     scc-collect -i -e scc_1234_u_abc
	   - rerun the system modules and the user-module and store the output:
	     scc -e scc_1234_u_abc

	Note: when you change a user-module without running it, you will
	loose all changes (for the module) that will be made before the 
	next run.

	scc-collect and its modules use sensible defaults to avoid that 
	many systems require a configuration file. When the defaults are
	insufficient, copy /etc/opt/scc/newconfig/scc-localize to
	/etc/opt/scc/conf/scc-localize and uncomment the required variables.
	When the --no_conf_sub_dir option was used with the relocate script,
	the copy is not required.

ARGUMENTS


	None.

OPTIONS


	-a|--alternative <arg>  Start each user module with argument <arg>.
	-e|--extra <user_mod>   Run extra user module <user_mod>. Refer to the DESCRIPTION
	                        section for a detailed description of modules.
	                        <user_mod> can contain shell filename wildcards.
	                        To find the matching modules, the program searches
	                        for *<user_mod>* when checking user modules.
	-S|--selection <mod>    Run selected (system or user) module(s).
	                        Where <mod> can contain shell filename wildcards.
	-h|--help               Display the syntax and exit.
	-i|--interactive        Run the program interactively. Without this option,
	                        the program does not run when stdin is a tty.

EXAMPLES


	To execute all user modules, specify:

		scc-collect -i -e "scc_????_u_".

EXTERNAL INFLUENCES


	The HP Support Tools Manager (stm) is not called when the environment
	variable SCC_IGNORE_STM is set. During install by SD-UX, it is set
	to avoid running stm.

	RPM is locked during installation of SCC, ignore rpm during installs
	of SCC. The install-scripts set the environment variable 
	SCC_INSTALL_PHASE.

	Use the environment variable SCC_PROFILING in scc-localize to add
	timing data to the snapshot. This enables you to locate possible performance 
	bottlenecks. The default value activates profiling and performance
	data is added to the snapshot.
	The profile data has classification: "stats:profiling::"

	Use environment variable SCC_DATA to specify an alternative directory
	for the SCC data files. Should be an absolute path.

	Use environment variable SCC_DEBUG to run module(s) with set -x enabled.
	This works by invoking scc-collect itself and not when it is called
	via scc-log.

DIAGNOSTICS


	This program writes the following messages to stderr:

	Syntax error, use: scc-collect [ -a|--alternate <arg> ] [ -e|--extra <user_mod> ]
	            [ -h|--help ] [ -i|--interactive ]
	A syntax error has been detected and reported.

	scc-collect: Syntax error, missing argument for option <option>
	The indicated option is missing argument(s).

	scc-collect: use -i option to run interactive
	Avoid immediately running all collection scripts interactively.
	
	scc-collect: non-executable module: <module>
	Correct the permissions of the module in the directory
	/opt/scc/bin/scc_modules.

	scc-collect: missing data for module: <module>
	The file /var/opt/scc/data/plugin_data/<module> is missing.
	Run the module with the -m option to generate the datafile.
	

RETURN VALUE


	Upon completion, the program returns one of the following values:

		0 successful completion
		1 syntax error
		2 runtime error

COPYRIGHT


	scc-collect is free software under the terms of the GNU General Public 
	License. Copyright (C) 2001-2004 Open Challenge B.V.,
	2004-2005 OpenEyeT Professional Services, 2005-2015 QNH.

FILES


	/opt/scc/bin/scc_modules - directory with modules
		scc_utils - utilities for modules
		scc_[0-9][0-9][0-9][0-9]_s_*
		system modules, always executed
		scc_[0-9][0-9][0-9][0-9]_u_*
	        user modules, executed via --extra option
	/var/opt/scc/data/plugin_data/<module> - output of user module
	/var/opt/scc/data - directory for data files
		scc.<hostname>.cur - current SCC-snapshot
		scc.<hostname>.html - current SCC-snapshot in HTML-format
		scc.<hostname>.old - previous SCC-snapshot
		scc.<hostname>.new - new (temporary) SCC-snapshot
		scc.<hostname>.log - logbook for changes in SCC-snapshot
		scc.<hostname>.log.html - logbook in HTML-format
		scc.<hostname>.keep - data kept from a previous run

	/etc/opt/scc/conf/scc_local_* - specification for module scc_0640_s_local

SEE ALSO


	scc(1), scc-cmp(1), scc-collect(1), scc-log(1), scc-log2html(1),
	scc-plugin(1), scc-snap2html(1), scc(4), scc(5)

VERSION


	$Revision: 5843 $

)	;;
	echo "${ProgName}: alternative SCC_DATA (${SCC_DATA}) should be an absolute path" >&2
xit 2;;
ac

Perform the security settings before calling any program.
TH=/sbin:/usr/sbin:/usr/bin:/bin:/usr/lib:${SCC_BIN};	export PATH

${SCC_BIN}/scc_modules/scc_utils

Indicate the directory for temporary files.
port TMPDIR=${SCC_TMP}
port TMP=${SCC_TMP}

port SHELL=/bin/sh

ask 022
! -d ${SCC_DATA} ] && mkdir -p ${SCC_DATA} 2>/dev/null
! -d ${SCC_DATA}/plugin_data ] && mkdir -p ${SCC_DATA}/plugin_data 2>/dev/null
ask 077
! -d ${SCC_TMP} ] && mkdir -p ${SCC_TMP} 2>/dev/null

[ ! -w ${SCC_DATA} ]
en
cho "${ProgName}: insufficient permissions to write in data directory: ${SCC_DATA}" >&2
xit 2


${SCC_TMP}

Now we can start:
port ODMDIR="${ODMDIR:-}"
port SCC_PROFILING="${SCC_PROFILING:-yes}"
port SCC_IGNORE_STM="${SCC_IGNORE_STM:-}"
port SCC_INSTALL_PHASE="${SCC_INSTALL_PHASE:-}"
port SCC_INSTALL_METHOD="${SCC_INSTALL_METHOD:-}"

Unset this variable when it is empty to avoid default (UTC).
[ -z "${TZ:-}" ]
en
nset TZ


D_LINE="${ProgName} [ -h|--help ] [ -a|--alternative <arg> ] [ -e|--extra <user_mod> ] [ -S|--selection <mod> ] [ -i|--interactive ]"
NTAX_ERROR="Syntax error, use: ${CMD_LINE}"

SSING_OPT_ARG="${ProgName}: Syntax error, missing argument for option:"
gs=""
teractive=0
er_module=""
lect_module=""
ile [ $# -gt 0 ]

ase "${1}" in
a|--alternative)	[ -z "${2:-}" ] && echo "${MISSING_OPT_ARG}: ${1}" >&2 && exit 1
		args="${2}"
		shift 2
		;;
e|--extra)		# Empty is permitted, missing not
		[ -z "${2:-}" ] && [ "${2+defined}" != "defined" ] && echo "${MISSING_OPT_ARG}: ${1}" >&2 && exit 1
		user_module="${2:-}"
		shift 2
		;;
S|--selection)		# Empty is permitted, missing not
		[ -z "${2:-}" ] && [ "${2+defined}" != "defined" ] && echo "${MISSING_OPT_ARG}: ${1}" >&2 && exit 1
		select_module="${2:-}"
		shift 2
		;;
h|--help)		echo "${CMD_LINE}"
		exit 0
		;;
i|--interactive)	interactive=1;
		shift 1
		;;
)			echo "${SYNTAX_ERROR}" >&2
		exit 1
		;;
sac
ne

-r ${SCC_CONF}/scc-localize ] && . ${SCC_CONF}/scc-localize

y="$(which tty 2>/dev/null)"
[ -x "${tty}" -a ${interactive} -eq 0 ]
en

Ignore output and message for ttylinux.

f tty -s >/dev/null 2>/dev/null
hen
echo "${ProgName}: use -i option to run interactive" >&2
exit 2
i


ndom="$(get_RANDOM)"
port TMP1_FILE=${SCC_TMP}/scc_collect1_$$_${random}
port TMP2_FILE=${SCC_TMP}/scc_collect2_$$_${random}
port TMP3_FILE=${SCC_TMP}/scc_collect3_$$_${random}
port PROC_FILE=${SCC_TMP}/scc_ps_$$_${random}
port SYSCTL_DATA=${SCC_TMP}/scc_sysctl_$$_${random}

Some commands adjust the width of their output according to COLUMNS, unset
this variable to avoid differences in the snapshots.
port COLUMNS=300		# always use the same width.
set LINES
set DISPLAY

_NAME=$(uname -s)
stname_exe="$(which hostname 2>/dev/null)"
[ -x "${hostname_exe}" ]
en
ostname=$(hostname 2>/dev/null)
se
ostname=${HOSTNAME:-}

[ -z "${hostname}" ]
en
ostname="empty"		# same value as in scc and scc-log

STNAME=${hostname%%.*}
port OS_NAME hostname HOSTNAME

c_linux_distro		# Set SCC_LINUX_DISTRO to the proper value.

[ -z "${SCC_KEEP_CONFIG:-}" ]
en
CC_KEEP_CONFIG=${SCC_DATA}/scc.${HOSTNAME}.keep

C_KEEP_NEW=${SCC_TMP}/scc.keep_$$_${random}
-f ${SCC_KEEP_NEW}
uch ${SCC_KEEP_NEW} ${SCC_KEEP_CONFIG}
port SCC_KEEP_CONFIG SCC_KEEP_NEW

w_keep_version="keep_file_version:1.2"
ep_version=$(grep "^${new_keep_version}$" ${SCC_KEEP_CONFIG} 2>/dev/null)
[ "${keep_version}" != "${new_keep_version}" ]
en

The version of the keep-file does not match with the version

used by scc-collect. This means that the file has been written
by an incompatible version of scc-collect. Erase the keep-file.
${SCC_KEEP_CONFIG}

ho "${new_keep_version}" >>${SCC_KEEP_NEW}

ap 'rm -f ${TMP1_FILE} ${TMP2_FILE} ${TMP3_FILE} ${PROC_FILE} ${SYSCTL_DATA} ${SCC_KEEP_NEW}' 0
ap "exit 2" 1 2 3 15

Store the current processes for later use.
Reduce the length of the lines.
On some systems java code is part of the output, resulting in lines exceeding 2KB and errors from grep.
Indicated by Doug Probst and Mattijs de Ruijter.
se "${OS_NAME}" in
SD)	ps -ajxww -o user,pid,ppid,state,pri,%cpu,%mem,vsz,rss,tty,start,time,command	|
ut -c1-300 >${PROC_FILE}
;

F1)	ps axww -o user,pid,ppid,state,pri,%cpu,%mem,vsz,rss,tty,start,time,command	|
ut -c1-300 >${PROC_FILE}
;

X)	ps -Af										|
ut -c1-300 >${PROC_FILE}
;

iku)	ps >${PROC_FILE}
;

	# Try to collect the process hierarchy.
usybox_check ps
f [ $? -ne 0 ]
hen
busybox_ps				|
cut -c 1-300 >${PROC_FILE}
lse
UNIX95= ps -Hef 2>/dev/null		|
cut -c1-300 >${PROC_FILE}
if [ "$(wc -l <$PROC_FILE)" -lt 10 ]			# Not supported?
then
	ps -ef 2>/dev/null			|
	cut -c1-300 >${PROC_FILE}
fi
i
;
ac

_NIS_MASTER=0;		export IS_NIS_MASTER
S_DATA_DIR="";		export NIS_DATA_DIR
ep -l ypxfrd ${PROC_FILE} >/dev/null 2>/dev/null
[ $? -eq 0 ]
en
S_NIS_MASTER=1
IS_DATA_DIR=$(grep "^[ 	]*DIR" /var/yp/Makefile 2>/dev/null	|
	tail -n 1						|
	sed -e 's/^[ 	]*DIR[ 	]*=[ 	]*//' -e 's/[ 	].*//')
f [ ! -d "${NIS_DATA_DIR}" ]
hen
NIS_DATA_DIR=/etc
i


Not part of scc-utils as it should not be called by the modules.
c_crypt_init()
{

Get the crypt-key from the keep-config-file, otherwise initialize.


cc_keep_crypt_tag="scc-crypt-key"

xport crypt_key=$(sed -n -e "s@^${scc_keep_crypt_tag}:@@p" ${SCC_KEEP_CONFIG} 2>/dev/null)
f [ ! -n "${crypt_key}" ]
hen
r1="$(get_RANDOM)"
sleep 1			# when ${RANDOM} is empty, we use the seconds, wait to make r1 != r2
r2="$(get_RANDOM)"
crypt_key="${r1}${r2}"
i
cho "${scc_keep_crypt_tag}:${crypt_key}" >>${SCC_KEEP_NEW}

eturn 0;
}

w=$(date '+%H.%M.%S')
ur=${now%%.*}
ur=${hour#0}	# avoid 'octal' arithmetic
n=${now%.*}
n=${min#*.}
n=${min#0}	# avoid 'octal' arithmetic
c=${now##*.}
c=${sec#0}	# avoid 'octal' arithmetic

ck_prev=$(( sec + ( 60 * min ) + ( 3600 * hour ) ));		export tick_prev
tal_time=0;							export total_time

For several commands we need to know the name of the HP-UX kernel.
[ -x /usr/sbin/kmpath ]
en

This is only available for HP-UX 11.*

PUX_KERNEL="$(/usr/sbin/kmpath 2>/dev/null)"

UX_KERNEL=${HPUX_KERNEL:-/stand/vmunix}
port HPUX_KERNEL

The adb-command, used to retrieve settings from the kernel, uses two sets of format strings.
Indicated by Harry van Wiggen.
[ "${OS_NAME}" = "HP-UX" ]
en
xport HPUX_ADB_STRING_FORMAT="S"
xport HPUX_ADB_NMBR_FORMAT="D"
alue="$(echo "boot_string/${HPUX_ADB_STRING_FORMAT}"	|
usr/bin/adb "${HPUX_KERNEL}" /dev/kmem 2>/dev/null)"
f [ -z "${value}" ]
hen
HPUX_ADB_STRING_FORMAT="ls"
HPUX_ADB_NMBR_FORMAT="ld"
i


Edit scc-localize to change the default setting of this variable.
[ -z "${MAX_SYS_ACCOUNT_ID:-}" ]
en
AX_SYS_ACCOUNT_ID=500
f [ "${OS_NAME}" = "HP-UX" -o "${OS_NAME}" = "SunOS" ]
hen
MAX_SYS_ACCOUNT_ID=100		# check logins(1)
i

port MAX_SYS_ACCOUNT_ID

c_crypt_init;

	START: GENERAL
${SCC_PROFILING} ] && scc_timing "scc-collect:start of run"

C_MODULE="";					export SCC_MODULE
C_RELEASE="1.23.185";			export SCC_RELEASE
(
d ${SCC_BIN}/scc_modules
or SCC_MODULE in scc_[0-9][0-9][0-9][0-9]_[su]_*
o
if [ -x "${SCC_MODULE}" ]
then
	case "${SCC_MODULE}" in
	scc_*~)		continue;;		# Ignore (vim) copies.
	esac

	echo "moduleSTART:${SCC_MODULE}" >>${SCC_KEEP_NEW}
	module_has_run=0

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

	[ ${SCC_PROFILING} ] && scc_timing "${SCC_MODULE}:start of module"

	case "${SCC_MODULE}" in
	scc_[0-9][0-9][0-9][0-9]_s_*)		# scc system module
		if [ -z "${select_module}" ]
		then
			./"${SCC_MODULE}" 2>&1
			module_has_run=1
		else
			case "${SCC_MODULE}" in
			*${select_module}*)	./"${SCC_MODULE}" 2>&1
						module_has_run=1;;
			esac
		fi
		;;

	scc_[0-9][0-9][0-9][0-9]_u_*)		# scc user module
		if [ "${user_module}" -o "${select_module}" ]
		then
			# Check whether the module should be run;
			# Only user modules can have arguments.
			case "${SCC_MODULE}" in
			*${user_module}*|*${select_module}*)	# run the user module
					checksum="$(sed -e '/^[ 	]*#/d'	\
							-e '/^[ 	]*$/d' ${SCC_MODULE}	| scc_checksum)"
					if [ ${interactive} -eq 1 ]
					then
						echo "var:MoDuLe:start::${SCC_MODULE}:${checksum}"
						./"${SCC_MODULE}" ${args} 2>&1
						module_has_run=1
						echo "var:MoDuLe:end::${SCC_MODULE}:"
					else
						# Surround the data with these tags, when a module
						# is changed, scc-log detects this and removes the
						# data of the module from the current and new snapshot
						# before comparing them. This makes it possible to update
						# modules without changes reported in the logbook.
						{
							echo "var:MoDuLe:start::${SCC_MODULE}:${checksum}"
							./"${SCC_MODULE}" ${args} 2>&1
							module_has_run=1
							echo "var:MoDuLe:end::${SCC_MODULE}:"
						} >"${SCC_DATA}/plugin_data/${SCC_MODULE}"
					fi
					;;
			esac;
		fi

		if [ ${interactive} -eq 0 ]
		then
			# Send the plugin-data of new user-modules only when it exists.
			if [ -s ${SCC_DATA}/plugin_data/${SCC_MODULE} ]
			then
				# Incorporate the output of the user module.
				cat "${SCC_DATA}/plugin_data/${SCC_MODULE}"
			fi
		fi
		;;
	esac

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

	if [ ${module_has_run} -eq 0 ]
	then
		# The module has not run.
		# Preserve its data from the keep-file into the new keep-file.
		sed -n -e "/^moduleSTART:${SCC_MODULE}/,/^moduleEND:${SCC_MODULE}/p" ${SCC_KEEP_CONFIG} 2>/dev/null	|
		sed -e "/^module.*:${SCC_MODULE}/d" >>${SCC_KEEP_NEW}
	fi
	echo "moduleEND:${SCC_MODULE}" >>${SCC_KEEP_NEW}
else
	echo "fix:messages::non-executable module: ${SCC_MODULE}"
fi	# if [ -x "${SCC_MODULE}" ]
one	# for SCC_MODULE in scc_[0-9][0-9][0-9][0-9]_[su]_*
	|
c_to_ascii	|
d -e 's@\(.*scc_...._._.*: [0-9][0-9]* [Kk]illed\)@var:messages::\1@'

	END
${SCC_PROFILING} ] && scc_timing "scc-collect:end of run"

${SCC_KEEP_NEW} ${SCC_KEEP_CONFIG}

it 0