#!/bin/bash

SVER='3.0.11-10'
SDATE='2023 Dec 05'

##############################################################################
#  supportconfig - Gathers system troubleshooting information for SUSE Support
#  Copyright (C) 2001-2023 SUSE LLC
#
#  Creates a tar ball to attach to the support case or send to support. 
#  Collects comprehensive system information for troubleshooting and reducing
#  resolution time.
#
#  Disclaimer:
#  Detailed system information and logs are collected and organized in a
#  manner that helps reduce service request resolution times. Private system
#  information can be disclosed when using this tool. If this is a concern,
#  please prune private data from the log files. Several startup options 
#  are available to exclude more sensitive information. Use supportconfig -h 
#  to see these options.
##############################################################################
#
#  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; version 2 of the License.
#
#  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; if not, see <http://www.gnu.org/licenses/>.
#
#  Authors/Contributors:
#     Jason Record <jason.record@suse.com>
#
##############################################################################
# Default Options
##############################################################################
OPTION_APPARMOR=1
OPTION_AUDIT=1
OPTION_AUTOFS=1
OPTION_BOOT=1
OPTION_BTRFS=1
OPTION_DAEMONS=1
OPTION_CIMOM=1
OPTION_CRASH=1
OPTION_CRON=1
OPTION_DHCP=1
OPTION_DISK=1
OPTION_DNS=1
OPTION_DOCKER=1
OPTION_DRBD=1
OPTION_EMAIL=1
OPTION_ENV=1
OPTION_ETC=1
OPTION_EVMS=1
OPTION_HA=1
OPTION_HAPROXY=1
OPTION_HISTORY=0
OPTION_IB=1
OPTION_ISCSI=1
OPTION_KVM=1
OPTION_LDAP=1
OPTION_LVM=1
OPTION_LXC=1
OPTION_MEM=1
OPTION_MOD=1
OPTION_MPIO=1
OPTION_NET=1
OPTION_NFS=1
OPTION_NTP=1
OPTION_OCFS2=1
OPTION_OFILES=1
OPTION_PAM=1
OPTION_PRINT=1
OPTION_PROC=1
OPTION_SAM=1
OPTION_SAR=1
OPTION_SLERT=1
OPTION_SLP=1
OPTION_SMT=1
OPTION_SMART=0
OPTION_SMB=1
OPTION_SRAID=1
OPTION_SSH=1
OPTION_SSSD=1
OPTION_SYSCONFIG=1
OPTION_SYSFS=1
OPTION_TUNED=1
OPTION_UDEV=1
OPTION_UFILES=1
OPTION_UP=1
OPTION_WEB=1
OPTION_X=1
OPTION_XEN=1

ADD_OPTION_FSLIST=0
ADD_OPTION_LOGS=0
ADD_OPTION_MINDISK=0
ADD_OPTION_MAXYAST=0
ADD_OPTION_RPMV=0
ADD_OPTION_SLP=0
ADD_OPTION_LOCAL_ONLY=0

VAR_OPTION_BIN_TIMEOUT_SEC=120
VAR_OPTION_CONTACT_COMPANY=""
VAR_OPTION_CONTACT_EMAIL=""
VAR_OPTION_CONTACT_NAME=""
VAR_OPTION_CONTACT_PHONE=""
VAR_OPTION_CONTACT_STOREID=""
VAR_OPTION_CONTACT_TERMINALID=""
VAR_OPTION_CUSTOM_ARCH=""
VAR_OPTION_DMESG=0
VAR_OPTION_EXHAUSTIVE_MEM=0
VAR_OPTION_GPG_UID=""
VAR_OPTION_HBREPORT_DIRS='/var/log /root'
# reports must have the format hb_report.*\.tar\.bz2 in each directory
VAR_OPTION_JOURNALCTL_LINE_COUNT=10000
VAR_OPTION_JOURNALCTL_MAX_BOOTS=10
VAR_OPTION_LOG_DIRS='/var/log /tmp'
VAR_OPTION_LINE_COUNT=500
VAR_OPTION_MSG_MAXSIZE=26214400
VAR_OPTION_MSG_LINE_COUNT=200000
VAR_OPTION_PENGINE_FILES_LIMIT=250
: ${VAR_OPTION_RM_LOCAL_FILE:=0}
VAR_OPTION_SAR_FILES_LIMIT=30
VAR_OPTION_SILENT=0
VAR_OPTION_SBM=0
VAR_OPTION_UNIQUE_FILE=0
VAR_OPTION_HEADER_FILE='/usr/lib/supportconfig/header.txt'
SUSE_UPLOAD_NA_ASERVER='support-ftp.us.suse.com'
SUSE_UPLOAD_EMEA_ASERVER='support-ftp.emea.suse.com'
SUSE_UPLOAD_NA_HTTPS="https://${SUSE_UPLOAD_NA_ASERVER}/incoming/upload.php?appname=supportconfig&file={tarball}"
SUSE_UPLOAD_NA_FTPES="ftps://${SUSE_UPLOAD_NA_ASERVER}/incoming"
SUSE_UPLOAD_NA_FTP="ftp://anonymous@${SUSE_UPLOAD_NA_ASERVER}/incoming"
SUSE_UPLOAD_EMEA_HTTPS="https://${SUSE_UPLOAD_EMEA_ASERVER}/incoming/upload.php?appname=supportconfig&file={tarball}"
SUSE_UPLOAD_EMEA_FTPES="ftps://${SUSE_UPLOAD_EMEA_ASERVER}/incoming"
SUSE_UPLOAD_EMEA_FTP="ftp://anonymous@${SUSE_UPLOAD_EMEA_ASERVER}/incoming"
VAR_OPTION_UPLOAD_TARGET="${SUSE_UPLOAD_NA_HTTPS}"
VAR_OPTION_UPLOAD_TARGET_ALT="${SUSE_UPLOAD_NA_FTPES}"
VAR_OPTION_WAIT_TRACE=0

LANG=C
PATH="/sbin:/usr/sbin:/bin:/usr/bin:$PATH"
PATH_ORIG=$PATH
export PATH LANG
LIB_DIR='/usr/lib/supportconfig'
XPLUGIN_DIR="${LIB_DIR}/plugins"
CURRENT_SCRIPT=$(basename $0)
ARCHIVE_PREFIX='scc_'
unset CONTACT_SRNUM
UPLOAD_TARBALL=0
CSFILE=${CURRENT_SCRIPT}.txt
RPMFILE=rpm.txt
LSOF_FILE=open-files.txt
FSLIST_FILE=fs-files.txt
FSLIST_ADD_FILE="${LIB_DIR}/additional-files.list"
BASIC_ENVF=basic-environment.txt
XML_FILE=summary.xml
# Select compression method
if [[ -x "/usr/bin/xz" ]]; then
	COMPRESS="txz"
	COMPRESS_OPT="Jcf"
elif [[ -x "/usr/bin/bzip2" ]]; then
	COMPRESS="tbz"
	COMPRESS_OPT="jcf"
else
	COMPRESS="tgz"; 
	COMPRESS_OPT="zcf"
fi
SC_SRV=$(hostname) # %s
test "$SC_SRV" = "" && SC_SRV=suse
SC_DATE=$(date +"%y%m%d") # %d
SC_TIME=$(date +"%H%M") # %t
test -x /usr/bin/uuidgen && SC_UID="$(uuidgen 2>/dev/null)" || SC_UID="$(mktemp -u XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)" # %u
BASE="${ARCHIVE_PREFIX}%B"
ARCH=$(uname -i)
SAVE_LOGS_ONLY=0
USE_SAVED_LOGS_ONLY=0
ENCRYPTED_TARBALL=0
# Set bootloader type from sysconfig
eval $(cat /etc/sysconfig/bootloader | grep LOADER_TYPE)
# If environment is systemd, /sbin/init should be a symlink to systemd
file /sbin/init | grep "systemd" &>/dev/null && SYSTEMD=1 || SYSTEMD=0
IO_DELAYS=0

RUN_VAR_DIR="/var/run/supportconfig"
RUN_PID_FILE="${RUN_VAR_DIR}/supportconfig.pid"

# These are minimum options and should never be unset.
MIN_OPTION_RPM=1
MIN_OPTION_ENV=1
MIN_OPTION_HC=1
MIN_OPTION_HARDWARE=1
MIN_OPTION_YAST=1
MIN_OPTION_SYSLOGS=1
MIN_OPTION_AUTOMOD=1

trap "{ echolog TERMINATED BY USER; echo; exit 5; }" SIGINT
trap "{ echolog SKIPPED BY USER; return 4; }" SIGQUIT

unalias -a &>/dev/null

##############################################################################
# General Function Definitions
##############################################################################

title() {
	echo "============================================================================="
	echo "                     Support Utilities - Supportconfig"
	echo "                          Script Version: $SVER"
	echo "                          Script Date: $SDATE"
	echo 
	echo " Detailed system information and logs are collected and organized in a"
	echo " manner that helps reduce service request resolution times. Private system"
	echo " information can be disclosed when using this tool. If this is a concern,"
	echo " please prune private data from the log files. Several startup options"
	echo " are available to exclude more sensitive information. Supportconfig data is"
	echo " used only for diagnostic purposes and is considered confidential information."
	echo " See https://www.suse.com/company/legal/"
	echo "============================================================================="
	echo
}

show_help() {
	log2sys "Show Help Screen"
	echo " Usage: $CURRENT_SCRIPT [OPTION [OPTION ...]]"
	echo
	echo "  -h This screen"
	echo "  -A Activates all supportconfig functions with additional logging and full"
	echo "     rpm verification."
	echo "  -B <string> Custom tar ball file name element"
	echo "  -C Creates a new default $SC_CONF"
	echo "  -D Use defaults; ignore  $SC_CONF"
	echo "  -E <string> Contact email address"
	echo "  -F Display available supportconfig feature keywords (case-sensitive) used"
	echo "     with -i and -x"
	echo "  -G <gpg_uid> The GPG recipient's user ID used to encrypt the supportconfig tarball"
	echo "  -H <number> Limit number of included HA Policy engine files"
	echo "  -I <number> Default log file line count"
	echo "  -J Collect memory information from sysfs"
	echo "  -L Create a full file listing from '/'"
	echo "  -M <string> Contact terminal ID"
	echo "  -N <string> Contact name"
	echo "  -O <string> Contact company name"
	echo "  -P <string> Contact phone number"
	echo "  -Q Run in silent mode"
	echo "  -R <path> Log output directory"
	echo "  -S <number> Limit number of included SAR files"
	echo "  -T <seconds> Binary execution timeout"
	echo "  -U <URI string> Sets upload target URL and initiates an upload, supported"
	echo "                  services include: ftp, ftps, scp, https"
	echo "  -M <string> Contact store ID"
	echo "  -X <number> Max system logs line count"
	echo "  -a Upload the tar ball to the VAR_OPTION_UPLOAD_TARGET_ALT"
	echo "  -b Screen buffer mode"
	echo "  -d Exclude detailed disk info and scans"
	echo "  -f From directory. Don't collect report files, just use files in that"
	echo "     directory."
	echo "  -g Use gzip instead of the default bzip2 compression."
	echo "  -i <keyword list>"
	echo "     Include keywords. A comma separated list of feature keywords that specify"
	echo "     which features to include. Use -F to see a list of valid keywords."
	echo "  -k disable all commands that do automatic kernel module loading."
	echo "  -l Gathers additional rotated logs"
	echo "  -m Only gather a minimum amount of info: basic env, basic health, hardware,"
	echo "     rpm, messages, y2logs"
	echo "  -o Toggle listed features on or off"
	echo "  -p Disable all plugins"
	echo "  -q Add a uuid to the tar ball filename to ensure uniqueness"
	echo "  -r <srnum>"
	echo "     Includes the service request number when uploading the tar ball"
	echo "  -s Include full SLP service lists"
	echo "  -t Target directory. Just save log files here, do not create tarball."
	echo "  -u Upload the tar ball to the specified VAR_OPTION_UPLOAD_TARGET."
	echo "  -v Performs an rpm -V for each installed rpm  NOTE: This takes a long time"
	echo "     to complete"
	echo "  -w Enable verbose wait trace logging. Shows the start and stop times of each"
	echo "     command supportconfig is running."
	echo "  -x <keyword list>"
	echo "     Exclude keywords. A comma separated list of feature keywords that specify"
	echo "     which features to exclude. Use -F to see a list of valid keywords."
	echo "  -y Gathers full YaST log files."
	echo 
	echo "  Use Ctrl-\ to try and skip a function that is hanging."
	echo
	echo "-----------------------------------------------------------------------------"
	echo "  NOTE:"
	echo "  This tool will create a tar ball in the /var/log directory. Please attach"
	echo "  the log file tar ball to your open Service Request at the following URL:"
	echo "  https://scc.suse.com/support/requests"
	echo 
	echo "  If you cannot attach the tar ball to the SR, then email it to the engineer."
	echo
	echo "  Please submit bug fixes or comments via:"
	echo "  https://www.suse.com/support/report-a-bug/"
	echo
	title
}

log2sys() {
	MSG="$@"
	if (( $VAR_OPTION_DMESG )); then
		echo "supportconfig: [$(date +%y%m%d:%H:%M:%S)] $MSG" > /dev/kmsg
	else
		logger -t supportconfig "$MSG"
	fi
}

run_status() {
	[[ -d $RUN_VAR_DIR ]] || mkdir -p $RUN_VAR_DIR
	case $1 in
	"start")
		echo $$ > $RUN_PID_FILE
		chmod 644 $RUN_PID_FILE
		RC=0
		;;
	"stop")
		rm -f $RUN_PID_FILE
		RC=1
		;;
	*)
		if [[ -s $RUN_PID_FILE ]]; then
			RUN_PROC_DIR="/proc/$(cat $RUN_PID_FILE)"
			if [[ -d $RUN_PROC_DIR ]]; then
				RC=0
			else
				rm -f $RUN_PID_FILE
				RC=1
			fi
		else
			RC=1
		fi
		;;
	esac
	return $RC
}

wait_trace_on() {
	if (( $VAR_OPTION_WAIT_TRACE )); then
		OPT=$1
		case $OPT in
		-t) TEE=0; shift ;;
		*) TEE=1 ;;
		esac
		LOGGING="$@"
		WT_START=$(date +%T:%N)
		log2sys "<$WT_START> $LOGGING"
		if (( $TEE )); then
			printf "%s" "    <$WT_START> $LOGGING  " | tee -a ${LOG}/${CSFILE}
		else
			printf "%s" "    <$WT_START> $LOGGING  "
		fi
	fi
}

wait_trace_off() {
	if (( $VAR_OPTION_WAIT_TRACE )); then
		OPT=$1
		case $OPT in
		-t) TEE=0 ;;
		*) TEE=1 ;;
		esac
		WT_END=$(date +%T:%N)
		if (( $TEE )); then
			echo "<$WT_END>" | tee -a ${LOG}/${CSFILE}
		else
			echo "<$WT_END>"
		fi
	fi
}

# Input: logfilename logfiles...
conf_text_files() {
	LOGFILE=$LOG/$1
	shift
	for CONF in $@
	do
		echo "#==[ Configuration File ]===========================#" >> $LOGFILE
		if [ -f $CONF ]; then
			echo "# $CONF" >> $LOGFILE
			TEXTFILE=$(file -L $CONF | egrep -i "text|empty|XML")
			if [ -z "$TEXTFILE" ]; then
				echo "file $(file -L $CONF)" >> $LOGFILE
				echo "ERROR: Not a normal text file, excluding it." >> $LOGFILE
			else
				wait_trace_on "$CONF"
				if (( ADD_OPTION_LOGS )); then
					cat $CONF 2>> $LOG/$CSFILE | sed -e 's/\r//g' >> $LOGFILE 2>> $LOG/$CSFILE
				else
					cat $CONF 2>> $LOG/$CSFILE | sed -e '/^[[:space:]]*#/d' -e '/^[[:space:]]*;/d' -e '/^[[:space:]]*\/\//d' -e 's/\r//g' -e '/^$/d' >> $LOGFILE 2>> $LOG/$CSFILE
				fi
				wait_trace_off
			fi
			echo >> $LOGFILE
		else
			echo "# $CONF - File not found" >> $LOGFILE
		fi
		echo >> $LOGFILE
	done
}

# Input: logfilename logfiles...
conf_files() {
	LOGFILE=$LOG/$1
	shift
	for CONF in $@
	do
		echo "#==[ Configuration File ]===========================#" >> $LOGFILE
		if [ -f $CONF ]; then
			echo "# $CONF" >> $LOGFILE
			wait_trace_on "$CONF"
			if (( ADD_OPTION_LOGS )); then
				cat $CONF 2>> $LOG/$CSFILE | sed -e 's/\r//g' >> $LOGFILE 2>> $LOG/$CSFILE
			else
				cat $CONF 2>> $LOG/$CSFILE | sed -e '/^[[:space:]]*#/d;/^[[:space:]]*;/d;s/\r//g;/^[[:space:]]*$/d' >> $LOGFILE 2>> $LOG/$CSFILE
			fi
			echo >> $LOGFILE
			wait_trace_off
		else
			echo "# $CONF - File not found" >> $LOGFILE
		fi
		echo >> $LOGFILE
	done
}

# Input: logfilename lines logfiles...
# If lines = 0, includes the entire log file
log_files() {
	LOGFILE=$LOG/$1
	shift
	LOGLINES=$1
	shift
	for CONF in $@
	do
		BAD_FILE=$(echo "$CONF" | egrep "\.tbz$|\.bz2$|\.gz$|\.zip$|\.xz$")
		if [ -n "$BAD_FILE" ]; then
			continue
		fi
		echo "#==[ Log File ]=====================================#" >> $LOGFILE
		CONF=$(echo $CONF | sed -e "s/%7B%20%7D%7B%20%7D/ /g")
		if [ -f "$CONF" ]; then
			wait_trace_on "$CONF"
			if [ $LOGLINES -eq 0 ]; then
				echo "# $CONF" >> $LOGFILE
				sed -e 's/\r//g' "$CONF" >> $LOGFILE
			else
				echo "# $CONF - Last $LOGLINES Lines" >> $LOGFILE
				tail -$LOGLINES "$CONF" | sed -e 's/\r//g' >> $LOGFILE
			fi
			echo >> $LOGFILE
			wait_trace_off
		else
			echo "# $CONF - File not found" >> $LOGFILE
		fi
		echo >> $LOGFILE
	done
}

grep_log_files() {
	SKEY=$1
	shift
	LOGFILE=$LOG/$1
	shift
	LOGLINES=$1
	shift
	for CONF in $@
	do
		echo "#==[ Log File ]=====================================#" >> $LOGFILE
		if [ -f $CONF ]; then
			wait_trace_on "$CONF"
			if [ $LOGLINES -eq 0 ]; then
				echo "# grep -i $SKEY $CONF" >> $LOGFILE
				grep -i $SKEY $CONF | grep -v 'supportconfig:' | sed -e 's/\r//g' >> $LOGFILE
			else
				echo "# grep -i $SKEY $CONF - Last $LOGLINES Lines" >> $LOGFILE
				grep -i $SKEY $CONF | grep -v 'supportconfig:' | tail -$LOGLINES | sed -e 's/\r//g' >> $LOGFILE
			fi
			echo >> $LOGFILE
			wait_trace_off
		else
			echo "# $CONF - File not found" >> $LOGFILE
		fi
		echo >> $LOGFILE
	done
}

# log_entry file type label
log_entry() {
	LOGFILE=$LOG/$1
	shift
	ENTRY_TYPE=$1
	shift
	ENTRY_LABEL="$@"
	case $ENTRY_TYPE in
	command) ENTRY_HEADER="#==[ Command ]======================================#" ;;
	conf) ENTRY_HEADER="#==[ Configuration File ]===========================#";;
	log) ENTRY_HEADER="#==[ Log File ]=====================================#" ;;
	note) ENTRY_HEADER="#==[ Note ]=========================================#" ;;
	summary) ENTRY_HEADER="#==[ Summary ]======================================#" ;;
	*) ENTRY_HEADER="#==[ Entry ]========================================#";;
	esac
	echo "$ENTRY_HEADER" >> $LOGFILE
	echo "# $ENTRY_LABEL" >> $LOGFILE
	echo >> $LOGFILE
}

# Input: logfilename "text"
log_write() {
	LOGFILE=$LOG/$1
	shift
	echo "$@" >> $LOGFILE
}

xml_write() {
	if [ -n "$2" ]; then
		echo "  <$1>$2</$1>" >> $LOG/$XML_FILE
	else
		echo "  <$1 />" >> $LOG/$XML_FILE
	fi
}

echolog() {
	CSLOGFILE=$LOG/${CSFILE}
	if (( $VAR_OPTION_DMESG )); then
		echo "supportconfig: [$(date +%y%m%d:%H:%M:%S)]  $@" > /dev/kmsg
	fi
	if (( $VAR_OPTION_SILENT )); then
		echo "$@" >> $CSLOGFILE
	else
		if (( ! $VAR_OPTION_SBM )); then
			echo "$@" | tee -a $CSLOGFILE
		fi
	fi
}

echonlog() {
	CSLOGFILE=$LOG/${CSFILE}
	if (( $VAR_OPTION_SILENT )); then
		printf "%s " "$@" >> $CSLOGFILE
	else
		if (( ! $VAR_OPTION_SBM )); then
			printf "%s " "$@" | tee -a $CSLOGFILE
		fi
	fi
}

timed_progress() {
	CSLOGFILE=$LOG/${CSFILE}
	if (( $VAR_OPTION_SILENT )); then
		printf "." >> $CSLOGFILE
	else
		if (( $VAR_OPTION_SBM )); then
			printf "." >> $CSLOGFILE
		else
			printf "." | tee -a $CSLOGFILE
		fi
	fi
}

_sanitize_file() {
	CLEAN_FILE=${LOG}/$1
	REPLACED='*REMOVED BY SUPPORTCONFIG*'
	sed -i -e "\
	s/\(.*[P|p]ass\"\?:\).*/\1 $REPLACED/g;\
	s/\(.*[P|p]assword\"\?:\).*/\1 $REPLACED/g;\
	s/\(.*[P|p]ass[[:space:]]*=\).*/\1 $REPLACED/g;\
	s/\(.*[P|p]assword[[:space:]]*=\).*/\1 $REPLACED/g;\
	s/\(.*PASS=\).*/\1$REPLACED/g;\
	s/\(.*_PASSWORD[[:space:]]*=\).*/\1 $REPLACED/g;\
	s!\(<user_password>\).*\(</user_password>\)!\1$REPLACED\2!g;\
	s/\(^ProxyUser[[:space:]]*=\).*/\1 $REPLACED/g;\
	s/\(^credentials[[:space:]]*=\).*/\1 $REPLACED/g;\
	s/\(secret[[:space:]]*=\).*/\1 $REPLACED/g;\
	s/\($Param{'[s]*password'}[[:space:]]*=[[:space:]]*'\).*\(';\)/\1$REPLACED\2/g;\
	s/\(.*password[[:space:]]*=\).*/\1 $REPLACED/g;\
	s/\(.*password_in[[:space:]]*=\).*/\1 $REPLACED/g; \
	s/\(^echo -n\).*\(> \/sys\/kernel\/config\/target\/.*auth\/password.*\)/\1 $REPLACED \2/g" \
	$CLEAN_FILE
}

printlog() {
	CSLOGFILE=$LOG/${CSFILE}
	SMB_OVERIDE=0
	if [ "$1" = "-b" ]; then
		SMB_OVERIDE=1
		shift
	fi
	log2sys "$@"
	if (( $VAR_OPTION_SILENT )); then
		printf "  %-45s" "$@" >> $CSLOGFILE
	else
		if (( $VAR_OPTION_SBM )) || (( $SMB_OVERIDE )); then
			echo "$@" | tee -a $CSLOGFILE
		else
			printf "  %-45s" "$@" | tee -a $CSLOGFILE
		fi
	fi
}

printvrpmlog() {
	CSLOGFILE=$LOG/${CSFILE}
	test $VAR_OPTION_SILENT -gt 0 && printf "  %-40s %12s ... " "$1" "$2" >> $CSLOGFILE || printf "  %-40s %12s ... " "$1" "$2" | tee -a $CSLOGFILE
}

# Input: logfilename command
log_cmd() {
	EXIT_STATUS=0
	LOGFILE=$LOG/$1
	shift
	CMDLINE_ORIG="$@"
	CMDBIN=$(echo $CMDLINE_ORIG | awk '{print $1}')
	CMD=$(\which $CMDBIN 2>/dev/null | awk '{print $1}')
	echo "#==[ Command ]======================================#" >> $LOGFILE
	if [ -x "$CMD" ]; then
		CMDLINE=$(echo $CMDLINE_ORIG | sed -e "s!${CMDBIN}!${CMD}!")
		echo "# $CMDLINE" >> $LOGFILE
		wait_trace_on "$CMDLINE"
		echo "$CMDLINE" | bash  >> $LOGFILE 2>&1
		EXIT_STATUS=$?
		wait_trace_off
	else
		echo "# $CMDLINE_ORIG" >> $LOGFILE
		echo "ERROR: Command not found or not executible" >> $LOGFILE
		EXIT_STATUS=1
	fi
	echo >> $LOGFILE
	return $EXIT_STATUS
}

# Input: logfilename command
# Returns: 1 - command not found or not executable
#          2 - command returned an error
#         10 - command timed out
timed_log_cmd() {
	EXIT_STATUS=0
	TIMEOUT_PROGRESS=30
	LOGFILE=$LOG/$1
	shift
	CMDLINE_ORIG="$@"
	CMDBIN=$(echo $CMDLINE_ORIG | awk '{print $1}')
	SEMAPHORE_FILE="${LOGFILE}.$(basename ${CMDBIN}).$(date --utc +%s).SC__SEMAPHORE"
	SEMAPHORE_BIN=${SEMAPHORE_FILE}.sh
	SEMAPHORE_LOG=${SEMAPHORE_FILE}.out
	SEMAPHORE_ERR=${SEMAPHORE_FILE}.returncode
	SEMAPHORE_PID=${SEMAPHORE_FILE}.pid
	export SEMAPHORE_LOG
	CMD=$(\which $CMDBIN 2>/dev/null | awk '{print $1}')
	echo "#==[ Command ]======================================#" >> $LOGFILE
	if [ -x "$CMD" ]; then
		export CMDLINE=$(echo $CMDLINE_ORIG | sed -e "s!${CMDBIN}!${CMD}!")
		echo "# $CMDLINE" >> $LOGFILE
		wait_trace_on "$CMDLINE"
		echo "$SEMAPHORE_LOG" >> $LOGFILE
		LNUM=$(wc -l $LOGFILE | cut -d' ' -f1)
		# Create the temporary script that runs the app
cat << TEOF > $SEMAPHORE_BIN
echo \$\$ > $SEMAPHORE_PID
$CMDLINE >> $SEMAPHORE_LOG 2>&1
echo \$? > $SEMAPHORE_ERR
if [ -e $LOGFILE ]; then
 sed -i -e "\$(grep -n $SEMAPHORE_LOG $LOGFILE | cut -d: -f1)r $SEMAPHORE_LOG" $LOGFILE 2>/dev/null
 sed -i -e "/\$(basename $SEMAPHORE_LOG)/d" $LOGFILE 2>/dev/null
 rm -f $SEMAPHORE_LOG
fi
rm -f $SEMAPHORE_FILE 
TEOF
		TIME_CURRENT=0
		TIME_RCODE=0
		TIME_OUT=10
		touch $SEMAPHORE_FILE
		# Background the temporary script, it will delete the semaphore file when complete
		bash $SEMAPHORE_BIN &>/dev/null &
		while [ $TIME_CURRENT -lt $VAR_OPTION_BIN_TIMEOUT_SEC ]
		do
			if [ -e $SEMAPHORE_FILE ]; then
				# Still waiting on backgrounded binary
				sleep 1
				((TIME_CURRENT++))
				if [ $(( TIME_CURRENT % TIMEOUT_PROGRESS )) -eq 0 ]; then
					timed_progress
				fi
			else
				# Backgrounded binary completed
				TIME_CURRENT=$(( VAR_OPTION_BIN_TIMEOUT_SEC + 1 ))
				TIME_OUT=0
				rm -f $SEMAPHORE_BIN
				rm -f $SEMAPHORE_PID
				if [ -e $SEMAPHORE_ERR ]; then
					TIME_RCODE=$(< $SEMAPHORE_ERR)
					rm -f $SEMAPHORE_ERR
				fi
			fi
		done
		if (( TIME_RCODE )); then
			TIME_RCODE=2
		fi
		if (( TIME_OUT )); then
			echonlog "$CMDLINE_ORIG - Timed Out,"
			echo >> $LOGFILE
			echo "# ERROR: Command did not complete within the timeout period." >> $LOGFILE
			ps -eaf | grep $(cat $SEMAPHORE_PID) | grep -v grep >> $LOGFILE
			echo >> $LOGFILE
		fi
		wait_trace_off
	else
		echo "# $CMDLINE_ORIG" >> $LOGFILE
		echo "ERROR: Command not found or not executible" >> $LOGFILE
		EXIT_STATUS=1
	fi
	echo >> $LOGFILE
	EXIT_STATUS=$(( EXIT_STATUS + TIME_OUT + TIME_RCODE ))
	return $EXIT_STATUS
}

# Input: logfilename command
log_icmd() {
	LOGFILE=$LOG/$1
	shift
	CMDLINE="$@"
	echo "#==[ Command ]======================================#" >> $LOGFILE
	echo "# $CMDLINE" >> $LOGFILE
	wait_trace_on "$CMDLINE"
	$CMDLINE >> $LOGFILE 2>&1
	wait_trace_off
	echo >> $LOGFILE
}

ping_addr() {
	OF=$1
	ADDR_STRING="$2"
	ADDR_PING=$3
	if [ -n "$ADDR_PING" ]; then
		if log_cmd $OF "${4}ping -n -c1 -W1 $ADDR_PING"; then
			log_write $OF "# Connectivity Test, $ADDR_STRING $ADDR_PING: Success"
		else
			log_write $OF "# Connectivity Test, $ADDR_STRING $ADDR_PING: Failure"
		fi
	else
		log_write $OF "# Connectivity Test, $ADDR_STRING: Missing"
	fi
	log_write $OF
}

# Input: logfilename rpm
# Assumes the rpm is installed and $LOG/$RPMFILE has been created
rpm_verify() {
	RPMPATH=$LOG/$RPMFILE
	LOGFILE=$LOG/$1
	INPUT_RPM=$2
	echo "#==[ Verification ]=================================#" >> $LOGFILE
	if rpm -q $INPUT_RPM &>/dev/null
	then
		for RPM in $(rpm -q $INPUT_RPM)
		do
			echo "# rpm -V $RPM" >> $LOGFILE
			wait_trace_on "rpm -V $RPM"
			rpm -V $RPM >> $LOGFILE 2>&1
			ERR=$?
			wait_trace_off
			if [ $ERR -gt 0 ]; then
				echo "# Verification Status: Differences Found" >> $LOGFILE
			else
				echo "# Verification Status: Passed" >> $LOGFILE
			fi
			echo >> $LOGFILE
		done
		#cat $RPMPATH | grep "^$INPUT_RPM " >> $LOGFILE
		#echo >> $LOGFILE
		return 0
	else
		echo "# RPM Not Installed: $INPUT_RPM" >> $LOGFILE
		echo >> $LOGFILE
		return 1
	fi
}

gen_sysconfig() {
	log2sys "Overwriting $SC_CONF with default options."
	echo "####################################" > $SC_CONF
	echo "# Default Options" >> $SC_CONF
	echo "####################################" >> $SC_CONF
	for i in OPTION ADD_OPTION VAR_OPTION
	do
		grep "^${i}_" $0 | sort >> $SC_CONF
		echo >> $SC_CONF
	done
	echo
	return 0
}

log_options() {
	LOGFILE=$LOG/${CSFILE}
	conf_files ${CSFILE} $SC_CONF
	echo >> $LOGFILE
	echo "####################################" >> $LOGFILE
	echo "# Options Used" >> $LOGFILE
	echo "####################################" >> $LOGFILE
	for SRCH in OPTION_ ADD_OPTION_
	do
		for i in $(grep ^$SRCH $0 | cut -d= -f1 | sort)
		do
			printf "%-25s = %s\n" "$i" "$((i))" >> $LOGFILE
			continue

			if [ $((i)) -eq 0 ]; then
				printf "%-25s = \n" "$i" >> $LOGFILE
			else
				printf "%-25s = %s\n" "$i" "$((i))" >> $LOGFILE
			fi
		done
		echo >> $LOGFILE
	done
	# TODO
	# add VAR_OPTION_ parameters
}

check_service() {
	LOGFILE=$LOG/$1
	BASEFILE=$1
	SERVICE_NAME=$2
	SYSTEMD_DIR=/usr/lib/systemd/system
	if [ $SYSTEMD == 1 ] && [ -f $SYSTEMD_DIR/${SERVICE_NAME}.service ]; then
		log_cmd $BASEFILE "systemctl status $SERVICE_NAME"
		log_cmd $BASEFILE "systemctl is-enabled $SERVICE_NAME"
	else
		log_cmd $BASEFILE "chkconfig $SERVICE_NAME --list"
		log_cmd $BASEFILE "/etc/init.d/$SERVICE_NAME status"
	fi
	return $?
}

get_customer_info() {
	INFOLOG=$1
	LINE_ADDED=0
	test -n "$VAR_OPTION_CONTACT_COMPANY" && 		{ log_write $INFOLOG "Company:     $VAR_OPTION_CONTACT_COMPANY"; ((LINE_ADDED++)); }
	test -n "$VAR_OPTION_CONTACT_STOREID" && 		{ log_write $INFOLOG "Store ID:    $VAR_OPTION_CONTACT_STOREID"; ((LINE_ADDED++)); }
	test -n "$VAR_OPTION_CONTACT_TERMINALID" && 	{ log_write $INFOLOG "Terminal ID: $VAR_OPTION_CONTACT_TERMINALID"; ((LINE_ADDED++)); }
	test -n "$VAR_OPTION_CONTACT_NAME" && 			{ log_write $INFOLOG "Name:        $VAR_OPTION_CONTACT_NAME"; ((LINE_ADDED++)); }
	test -n "$VAR_OPTION_CONTACT_PHONE" && 		{ log_write $INFOLOG "Phone:       $VAR_OPTION_CONTACT_PHONE"; ((LINE_ADDED++)); }
	test -n "$VAR_OPTION_CONTACT_EMAIL" && 		{ log_write $INFOLOG "Email:       $VAR_OPTION_CONTACT_EMAIL"; ((LINE_ADDED++)); }
	test -n "$CONTACT_SRNUM" && 						{ log_write $INFOLOG "SR#:         $CONTACT_SRNUM"; ((LINE_ADDED++)); }
	if ((LINE_ADDED)); then log_write $INFOLOG; fi
}

addHeaderFile() {
	OPEN=$1
	if [ -s $VAR_OPTION_HEADER_FILE ]; then
		wait_trace_on "cat $VAR_OPTION_HEADER_FILE"
		log_entry $OPEN note $VAR_OPTION_HEADER_FILE
		cat $VAR_OPTION_HEADER_FILE >> $LOG/$OPEN
		log_write $OPEN
		wait_trace_off
	fi
}

basic_environment() {
	# This is a minimum required function, do not exclude
	printlog "Basic Environment..."
	test $MIN_OPTION_ENV -eq 0 && { echolog EXCLUDED; return 1; }
	addHeaderFile $BASIC_ENVF
	get_customer_info $BASIC_ENVF
	log_cmd $BASIC_ENVF 'date'
	log_cmd $BASIC_ENVF 'uname -a'
	RELEASE=$(ls -1 /etc/*release*)
	detectProducts $BASIC_ENVF
	detectVirtualization $BASIC_ENVF
	conf_files $BASIC_ENVF $RELEASE
	if ! ((NSA_CHECK)); then
		if [ $SLES_VER -lt 110 ]; then
			if rpm_verify $BASIC_ENVF SPident; then
				log_cmd $BASIC_ENVF 'SPident -vv'
			fi
		fi
		cat $LOG/$RPM_DIST_FILE >> $LOG/$BASIC_ENVF
		if rpm_verify $BASIC_ENVF SuSEfirewall2
		then
			log_write $BASIC_ENVF "#==[ Firewall Services ]============================#"
			log_write $BASIC_ENVF "# Service state"
			if (( SLES_VER >= 120 )); then
				wait_trace_on "systemctl status SuSEfirewall2.service"
				log_write $BASIC_ENVF "$(systemctl status SuSEfirewall2.service)"
				wait_trace_off
				wait_trace_on "systemctl status SuSEfirewall2_init.service"
				log_write $BASIC_ENVF "$(systemctl status SuSEfirewall2_init.service)"
				wait_trace_off
			else
				for i in $(rpm -ql SuSEfirewall2 | grep init.d)
				do
					FSRV=$(basename $i)
					wait_trace_on "chkconfig $FSRV --list"
					log_write $BASIC_ENVF "$(chkconfig $FSRV --list)"
					wait_trace_off
				done
			fi
			IPBIN="/usr/sbin/iptables"
			if [ -x $IPBIN ]; then
				TOTAL_FIREWALL_RULES=0
				for TABLE in filter nat mangle raw
				do
					if grep iptable_$TABLE /proc/modules &>/dev/null
					then
						wait_trace_on "$IPBIN -t $TABLE -nL | sed -e '/^$/d' -e '/^Chain/d' -e '/^target/d' | wc -l"
						FIREWALL_RULES=$($IPBIN -t $TABLE -nL | sed -e '/^$/d' -e '/^Chain/d' -e '/^target/d' | wc -l)
						TOTAL_FIREWALL_RULES=$(( TOTAL_FIREWALL_RULES + FIREWALL_RULES ))
						wait_trace_off
					fi
				done
				log_write $BASIC_ENVF
				log_write $BASIC_ENVF "$TOTAL_FIREWALL_RULES Active Firewall Rules"
				log_write $BASIC_ENVF
			fi
		fi
	fi
	echolog Done
}

basic_healthcheck() {
	# This is a minimum required function, do not exclude
	printlog "Basic Server Health Check..."
	test $MIN_OPTION_HC -eq 0 && { echolog EXCLUDED; return 1; }
	OF=basic-health-check.txt
	addHeaderFile $OF
	log_cmd $OF 'uptime'
	log_cmd $OF 'grep -H . /sys/devices/system/cpu/vulnerabilities/*'
	log_cmd $OF 'vmstat 1 4'
	test -x /usr/bin/mpstat && log_cmd $OF 'mpstat -P ALL 1 3'
	log_cmd $OF 'free -h'
	timed_log_cmd $OF 'df -h' || IO_DELAYS=1
	(( $IO_DELAYS )) || log_cmd $OF 'df -i'
	conf_files $OF '/proc/sys/kernel/tainted'
	TAINT=$(cat /proc/sys/kernel/tainted)
	TAINTED=0
	if [ ${#TAINT} -gt 1 ]; then
		TAINTED=1
	elif [ ${TAINT} -gt 0 ]; then
		TAINTED=1
	fi
	if (( TAINTED )); then
		# TAINT=$(( 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 ))
		# Refer to /usr/src/linux/include/linux/kernel.h and /usr/src/linux/kernel/panic.c (print_tainted function)
		TAINT_STRING=""

		# common to all versions
		test $((TAINT & 1))   -ne 0 && TAINT_STRING="${TAINT_STRING}P" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 2))   -ne 0 && TAINT_STRING="${TAINT_STRING}F" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 4))   -ne 0 && TAINT_STRING="${TAINT_STRING}S" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 8))   -ne 0 && TAINT_STRING="${TAINT_STRING}R" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 16))  -ne 0 && TAINT_STRING="${TAINT_STRING}M" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 32))  -ne 0 && TAINT_STRING="${TAINT_STRING}B" || TAINT_STRING="${TAINT_STRING} "

		case $SLES_VER in
		100)
		test $((TAINT & 64))  -ne 0 && TAINT_STRING="${TAINT_STRING}U" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 128)) -ne 0 && TAINT_STRING="${TAINT_STRING}X" || TAINT_STRING="${TAINT_STRING} "
		;;
		10*)
		test $((TAINT & 64))  -ne 0 && TAINT_STRING="${TAINT_STRING}U" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 128)) -ne 0 && TAINT_STRING="${TAINT_STRING}N" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 256)) -ne 0 && TAINT_STRING="${TAINT_STRING}X" || TAINT_STRING="${TAINT_STRING} "
		;;
		110|111)
		test $((TAINT & 64))         -ne 0 && TAINT_STRING="${TAINT_STRING}U" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 128))        -ne 0 && TAINT_STRING="${TAINT_STRING}D" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 256))        -ne 0 && TAINT_STRING="${TAINT_STRING}A" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 512))        -ne 0 && TAINT_STRING="${TAINT_STRING}W" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 1024))       -ne 0 && TAINT_STRING="${TAINT_STRING}C" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 2048))       -ne 0 && TAINT_STRING="${TAINT_STRING}I" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 1073741824)) -ne 0 && TAINT_STRING="${TAINT_STRING}N" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 2147483648)) -ne 0 && TAINT_STRING="${TAINT_STRING}X" || TAINT_STRING="${TAINT_STRING} "
		;;
		11*|12*)
		test $((TAINT & 64))         -ne 0 && TAINT_STRING="${TAINT_STRING}U" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 128))        -ne 0 && TAINT_STRING="${TAINT_STRING}D" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 256))        -ne 0 && TAINT_STRING="${TAINT_STRING}A" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 512))        -ne 0 && TAINT_STRING="${TAINT_STRING}W" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 1024))       -ne 0 && TAINT_STRING="${TAINT_STRING}C" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 2048))       -ne 0 && TAINT_STRING="${TAINT_STRING}I" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 4096))       -ne 0 && TAINT_STRING="${TAINT_STRING}O" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 8192))       -ne 0 && TAINT_STRING="${TAINT_STRING}E" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 16384))      -ne 0 && TAINT_STRING="${TAINT_STRING}L" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 32768))      -ne 0 && TAINT_STRING="${TAINT_STRING}K" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 65536))      -ne 0 && TAINT_STRING="${TAINT_STRING}H" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 1073741824)) -ne 0 && TAINT_STRING="${TAINT_STRING}N" || TAINT_STRING="${TAINT_STRING} "
		test $((TAINT & 2147483648)) -ne 0 && TAINT_STRING="${TAINT_STRING}X" || TAINT_STRING="${TAINT_STRING} "
		;;
		esac
		log_write $OF "Kernel Status -- Tainted: $TAINT_STRING"

		# common to all versions
		test $((TAINT & 1))   -ne 0 && log_write $OF "  TAINT: (P) Proprietary module has been loaded"
		test $((TAINT & 2))   -ne 0 && log_write $OF "  TAINT: (F) Module was forcibly loaded"
		test $((TAINT & 4))   -ne 0 && log_write $OF "  TAINT: (S) SMP with CPUs not designed for SMP"
		test $((TAINT & 8))   -ne 0 && log_write $OF "  TAINT: (R) Module was forcibly unloaded"
		test $((TAINT & 16))  -ne 0 && log_write $OF "  TAINT: (M) Machine check exception"
		test $((TAINT & 32))  -ne 0 && log_write $OF "  TAINT: (B) System has hit bad_page"

		case $SLES_VER in
		100)
		test $((TAINT & 64))  -ne 0 && log_write $OF "  TAINT: (U) Unsupported modules loaded"
		test $((TAINT & 128)) -ne 0 && log_write $OF "  TAINT: (X) Modules with external support loaded"
		;;
		10*)
		test $((TAINT & 64))  -ne 0 && log_write $OF "  TAINT: (U) Userspace-defined problems"
		test $((TAINT & 128)) -ne 0 && log_write $OF "  TAINT: (N) Unsupported modules loaded"
		test $((TAINT & 256)) -ne 0 && log_write $OF "  TAINT: (X) Modules with external support loaded"
		;;
		110|111)
		test $((TAINT & 64))         -ne 0 && log_write $OF "  TAINT: (U) Userspace-defined problems"
		test $((TAINT & 128))        -ne 0 && log_write $OF "  TAINT: (D) Imminent kernel function termination"
		test $((TAINT & 256))        -ne 0 && log_write $OF "  TAINT: (A) ACPI table overridden"
		test $((TAINT & 512))        -ne 0 && log_write $OF "  TAINT: (W) Taint on warning"
		test $((TAINT & 1024))       -ne 0 && log_write $OF "  TAINT: (C) Modules from drivers/staging are loaded"
		test $((TAINT & 2048))       -ne 0 && log_write $OF "  TAINT: (I) Working around severe firmware bug"
		test $((TAINT & 1073741824)) -ne 0 && log_write $OF "  TAINT: (N) Unsupported modules loaded"
		test $((TAINT & 2147483648)) -ne 0 && log_write $OF "  TAINT: (X) Modules with external support loaded"
		;;
		11*|12*)
		test $((TAINT & 64))         -ne 0 && log_write $OF "  TAINT: (U) Userspace-defined problems"
		test $((TAINT & 128))        -ne 0 && log_write $OF "  TAINT: (D) Kernel has oopsed before"
		test $((TAINT & 256))        -ne 0 && log_write $OF "  TAINT: (A) ACPI table overridden"
		test $((TAINT & 512))        -ne 0 && log_write $OF "  TAINT: (W) Taint on warning"
		test $((TAINT & 1024))       -ne 0 && log_write $OF "  TAINT: (C) Modules from drivers/staging are loaded"
		test $((TAINT & 2048))       -ne 0 && log_write $OF "  TAINT: (I) Working around severe firmware bug"
		test $((TAINT & 4096))       -ne 0 && log_write $OF "  TAINT: (O) Out-of-tree module has been loaded"
		test $((TAINT & 8192))       -ne 0 && log_write $OF "  TAINT: (E) Unsigned module has been loaded"
		test $((TAINT & 16384))      -ne 0 && log_write $OF "  TAINT: (L) A soft lockup has previously occurred"
		test $((TAINT & 32768))      -ne 0 && log_write $OF "  TAINT: (K) Kernel has been live patched"
		test $((TAINT & 65536))      -ne 0 && log_write $OF "  TAINT: (H) System restored from unsafe hibernate snapshot image"
		test $((TAINT & 1073741824)) -ne 0 && log_write $OF "  TAINT: (N) Unsupported modules loaded"
		test $((TAINT & 2147483648)) -ne 0 && log_write $OF "  TAINT: (X) Modules with external support loaded"
		;;
		esac

		log_write $OF
		LIST_MODULES_ANY=0
		for MODULE in $(cat /proc/modules | awk '{print $1}')
		do
			LIST_MODULE=0
			modinfo -l $MODULE &>/dev/null
			if [ $? -gt 0 ]; then
				log_write $OF "$(printf "%-25s %-25s %-25s" module=$MODULE ERROR "Module info unavailable")"
			else
				wait_trace_on "modinfo -l $MODULE"
				LIC=$(modinfo -l $MODULE | head -1)
				SUP=$(modinfo -F supported $MODULE | head -1)
				test -z "$LIC" && LIC=None
				test -z "$SUP" && SUP=no
				GPLTEST=$(echo $LIC | grep GPL)
				test -z "$GPLTEST" && ((LIST_MODULE++))
				test "$SUP" != "yes" && ((LIST_MODULE++))
				test $LIST_MODULE -gt 0 && log_write $OF "$(printf "%-25s %-25s %-25s" "module=$MODULE" "license=$LIC" "supported=$SUP")"
				LIST_MODULES_ANY=$((LIST_MODULES_ANY + LIST_MODULE))
				wait_trace_off
			fi
		done
		if [ $LIST_MODULES_ANY -eq 0 ]; then
			log_write $OF "Module List Unknown"
		fi
	else
		log_write $OF "Kernel Status -- Not Tainted"
	fi
	log_write $OF

	PSPTMP=$(mktemp $LOG/psout.XXXXXXXX)
	AARPTMP=$(mktemp $LOG/security-aareject.XXXXXXXX)
	PSTMP=$(basename $PSPTMP)
	AARTMP=$(basename $AARPTMP)

	log_cmd $PSTMP 'ps axwwo user,pid,ppid,%cpu,%mem,vsz,rss,stat,time,cmd'
	log_cmd $OF 'free -k'

	log_write $OF "#==[ Checking Health of Processes ]=================#"
	log_write $OF "# egrep \" D| Z\" $PSPTMP"
	log_write $OF "$(grep -v ^# "$PSPTMP" | egrep " D| Z")"

	TOPTMP=$(mktemp $LOG/top.XXXXXXXX)
	log_write $OF
	log_write $OF "#==[ Summary ]======================================#"
	log_write $OF "# Top 10 CPU Processes"
	ps axwwo %cpu,pid,user,cmd | sort -k 1 -r -n | head -11 | sed -e '/^%/d' > $TOPTMP
	log_write $OF "%CPU   PID USER     CMD"
	log_write $OF "$(< $TOPTMP)"
	log_write $OF

	log_write $OF "#==[ Summary ]======================================#"
	log_write $OF "# Top 10 Memory Processes"
	ps axwwo %mem,pid,user,cmd | sort -k 1 -r -n | head -11 | sed -e '/^%/d' > $TOPTMP
	log_write $OF "%MEM   PID USER     CMD"
	log_write $OF "$(< $TOPTMP)"
	log_write $OF
	rm -f $TOPTMP

	if rpm -q subdomain-parser &>/dev/null; then
		# apparmor for SLES9
		log_write $AARTMP "#==[ Summary ]======================================#"
		log_write $AARTMP "# AppArmor REJECT Messages"
		log_write $AARTMP "$(chkconfig boot.subdomain)"
		AAREJECT=$(grep 'SubDomain: REJECTING' /var/log/messages | wc -l)
		test -z "$AAREJECT" && AAREJECT=0
		if lsmod | grep subdomain &>/dev/null; then
			AALOADED="Loaded"
		else
			AALOADED="Not Loaded"
		fi
		log_write $AARTMP
		log_write $AARTMP "${AAREJECT} Reject Messages, AppArmor Module: $AALOADED"
		log_write $AARTMP
	elif rpm -q apparmor-parser &>/dev/null; then
		# apparmor for SLE10/11
		log_write $AARTMP "#==[ Summary ]======================================#"
		log_write $AARTMP "# AppArmor REJECT Messages"
		if (( SLES_VER >= 120 )); then
			log_write $AARTMP "$(systemctl status apparmor.service)"
		else
			log_write $AARTMP "$(chkconfig -l boot.apparmor)"
		fi
		APP_AUDIT_LOG="/var/log/audit/audit.log"
		test -f $APP_AUDIT_LOG && AAREJECT=$(egrep 'REJECTING|DENIED' $APP_AUDIT_LOG | wc -l) || AAREJECT=0
		test -z "$AAREJECT" && AAREJECT=0
		if [[ -x /usr/sbin/apparmor_status ]]; then
			/usr/sbin/apparmor_status --enabled &>/dev/null
			AASTAT=$?
			case $AASTAT in
			0) AALOADED="Loaded" ;;
			1) AALOADED="Disabled" ;;
			*) AALOADED="Loaded/Errors" ;;
			esac
		else
			AALOADED="Unknown"
		fi
		log_write $AARTMP
		log_write $AARTMP "${AAREJECT} Reject Messages, AppArmor Module: $AALOADED"
		log_write $AARTMP
	fi
	test -f $AARPTMP && cat $AARPTMP >> $LOG/$OF

	MCE_LOG='/var/log/mcelog'
	FILES=$MCE_LOG
	if [[ -s $MCE_LOG ]]; then
		log_cmd $OF "ls -l --time-style=long-iso $MCE_LOG"
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
	fi

	cat $PSPTMP >> $LOG/$OF
	rm $PSPTMP

	echolog Done
}

rpm_info() {
	# This is a minimum required function, do not exclude
	printlog "RPM Database..."
	test $MIN_OPTION_RPM -eq 0 && { echolog EXCLUDED; return 1; }
	addHeaderFile $RPMFILE
	if ((NSA_CHECK)); then
		log_write $RPMFILE "#==[ NSA Check ]====================================#"
		log_write $RPMFILE '# rpm -qa --queryformat "%-35{NAME} %-35{DISTRIBUTION} %{VERSION}-%{RELEASE}\n"'
		rpm -qa --queryformat "%-35{NAME} %-35{DISTRIBUTION} %{VERSION}-%{RELEASE}\n" >> $LOGFILE 2>&1
	else
		# rpm list of all files
		LOGFILE=$LOG/$RPM_DIST_FILE
		log_cmd $RPM_DIST_FILE 'rpm -qa --queryformat "%{DISTRIBUTION}\n" | sort | uniq'
		rpm -qa 2>/dev/null | sort > $LOG/$RPM_QA_FILE
		cat $LOG/$RPM_DIST_FILE >> $LOG/$RPMFILE
		log_cmd $RPMFILE "ls -l --time-style=long-iso /usr/local/bin /usr/local/sbin"
		log_write $RPMFILE "#==[ Command ]======================================#"
		log_write $RPMFILE '# rpm -qa --queryformat "%-35{NAME} %-35{DISTRIBUTION} %{VERSION}-%{RELEASE}\n" | sort -k 1,2 -t " " -i'
		printf "%-35s %-35s %s\n" NAME DISTRIBUTION VERSION >> $LOGFILE
		rpm -qa --queryformat "%-35{NAME} %-35{DISTRIBUTION} %{VERSION}-%{RELEASE}\n" | sort -k 1,2 -t " " -i >> $LOGFILE 2>&1
		log_write $RPMFILE
		log_cmd $RPMFILE "rpm -qa --last"
		log_write $RPMFILE "#==[ Command ]======================================#"
		log_write $RPMFILE '# rpm -qa --queryformat "%{SIGPGP:pgpsig}  %-35{VENDOR}  %{NAME}-%{VERSION}-%{RELEASE}\n" | sort -k 11 -t " " -i'
		printf "%-63s %-35s %s\n" SIGNATURE VENDOR PACKAGE >> $LOGFILE
		rpm -qa --queryformat "%{SIGPGP:pgpsig}  %-35{VENDOR}  %{NAME}-%{VERSION}-%{RELEASE}\n" | sort -k 11 -t " " -i >> $LOGFILE 2>&1
		log_write $RPMFILE
	fi
	echolog Done
}

# Run basic_healthcheck first TAINT & TAINT_STRING must be defined first
module_info() {
	printlog "System Modules..."
	test $OPTION_MOD -eq 0 && { echolog Excluded; return 1; }
	OF=modules.txt
	LOGFILE=$LOG/$OF
	addHeaderFile $OF
	log_cmd $OF 'lsmod | sort'
	for MODULE in $(cat /proc/modules | awk '{print $1}')
	do
		log_cmd $OF "modinfo $MODULE"
		MODPARM="/sys/module/$MODULE/parameters/"
		if [ -d $MODPARM ]; then
			log_write $OF "# Known Module Parameter Values"
			for i in $(ls -1 $MODPARM)
			do
				MODVALUE=$(cat ${MODPARM}$i 2>/dev/null)
				[ $? -ne 0 ] && MODVALUE="?"
				log_write $OF "${MODPARM}$i=$MODVALUE"
			done
			log_write $OF
		fi
		MODOPT=$(grep -R "options ${MODULE} " /etc/modprobe\.?* | grep -v ":# option")
		[ -n "$MODOPT" ] && { log_write $OF "# Module Configuration"; log_write $OF "$MODOPT"; log_write $OF; }
	done
	conf_files $OF /lib/modules/$(uname -r)/modules.dep
	if (( SLES_VER >= 120 )); then
		conf_files $OF /etc/modprobe.d/*
	else
		[[ -s /etc/modprobe.conf ]] && LIST=$(grep ^include /etc/modprobe.conf | awk '{print $2}') || LIST=''
		FILES=""
		for FILE in $LIST
		do
			if [ -d $FILE ]; then
				FILES="$FILES $(find -L $FILE -type f)"
			else
				FILES="$FILES $FILE"
			fi
		done
		conf_files $OF /etc/modprobe.conf $FILES
	fi
	echolog Done
}

messages_file() {
	# This is a minimum required function, do not exclude
	printlog "System Logs..."
	test $MIN_OPTION_SYSLOGS -eq 0 && { echolog EXCLUDED; return 1; }
	OF=messages.txt
	addHeaderFile $OF
	if [[ $ADD_OPTION_LOGS -gt 0 ]]; then
		FILES="$(ls -1 /var/log/warn-[[:digit:]]* 2>/dev/null) $(ls -1 /var/log/localmessages-[[:digit:]]* 2>/dev/null) $(ls -1 /var/log/messages-[[:digit:]]* 2>/dev/null)"
		[[ -n "$FILES" ]] && log_entry $OF note "Additional Rotated Logs Included in the Tar Ball"
		log_files $OF 0 /var/log/warn /var/log/localmessages /var/log/messages
		for CMPLOG in $FILES
		do
			FILE=$(basename $CMPLOG)
			FILEROOT=${LOG}/$(cut -d\. -f1 <<< ${FILE})
			cp $CMPLOG ${LOG}
			FILE_TYPE=$(file --brief --mime-type $CMPLOG 2>/dev/null)
			case $FILE_TYPE in
			"text/plain")
			;;
			"application/x-xz")
				wait_trace_on "xz -d ${LOG}/$FILE"
				xz -d ${LOG}/$FILE
			;;
			"application/x-bzip2")
				wait_trace_on "bzip2 -d ${LOG}/$FILE"
				bzip2 -d ${LOG}/$FILE
			;;
			"application/x-gzip")
				wait_trace_on "gzip -d ${LOG}/$FILE"
				gzip -d ${LOG}/$FILE
			;;
 			*)
				continue
			;;
			esac
			mv ${FILEROOT} ${FILEROOT}.txt
			wait_trace_off
		done
	else
		log_files $OF $VAR_OPTION_LINE_COUNT /var/log/warn
		for LOGFILE in /var/log/localmessages /var/log/messages
		do
			if [[ -e $LOGFILE ]]; then
				if [[ $VAR_OPTION_MSG_MAXSIZE -eq 0 ]]; then
					log_files $OF 0 $LOGFILE  # override and get the entire file
				else
					MSGSIZE=$(stat -c%s $LOGFILE)
					if [[ $MSGSIZE -gt $VAR_OPTION_MSG_MAXSIZE ]]; then
						log_files $OF $VAR_OPTION_MSG_LINE_COUNT $LOGFILE # the file exceeded the max size allowed, get specified lines of the file
					else
						log_files $OF 0 $LOGFILE # get the whole file
					fi
				fi
			fi
		done
	fi
	echolog Done
}

audit_info() {
	printlog "Auditing..."
	test $OPTION_AUDIT -eq 0 && { echolog Excluded; return 1; }
	OF=security-audit.txt
	if [ $SLES_VER -gt 90 ]; then
		if rpm_verify $OF audit; then
			addHeaderFile $OF
			check_service $OF auditd
			log_cmd $OF 'auditctl -s'
			log_cmd $OF 'auditctl -l'
			log_cmd $OF 'aureport'
			if [ -d /etc/audit ]; then
				FILES=$(find -L /etc/audit/ -type f)
				if [ -d /etc/audispd ]; then
					FILES="$FILES $(find -L /etc/audispd/ -type f)"
				fi
			else
				FILES="/etc/auditd.conf /etc/audit.rules"
			fi
			conf_files $OF $FILES
			FILES=$(find -L /var/log/audit/ -type f | egrep -v "/ltaudit/" | grep log$)
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
			echolog Done
		else
			echolog Skipped
		fi
	else
		if rpm_verify $OF laus; then
			addHeaderFile $OF
			check_service $OF audit
			FILES=$(find -L /etc/audit/ -type f)
			conf_files $OF $FILES
			log_cmd $OF 'aucat -v'
			echolog Done
		else
			echolog Skipped
		fi
	fi
}

yast_files() {
	# This is a minimum required function, do not exclude
	printlog "YaST Files..."
	test $MIN_OPTION_YAST -eq 0 && { echolog EXCLUDED; return 1; }
	hppsp_info
	# YaST files
	OF=y2log.txt
	addHeaderFile $OF
	rpm_verify $OF yast2-packager
	rpm_verify $OF yast2-packagemanager
	if rpm -q perl-Bootloader &> /dev/null; then
		rpm_verify $OF perl-Bootloader
	fi
	test -d /var/log/YaST2 && FILES=$(find -L /var/log/YaST2/ -type f | egrep -v "_dev_|\.tbz$|\.tgz$|\.gz$|\.bz2$|\.zip$") || unset FILES
	conf_files $OF /etc/youservers /etc/sysconfig/onlineupdate /etc/wgetrc 
	log_files $OF 0 /var/log/pbl.log
	(( ADD_OPTION_MAXYAST > 0 )) && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
	[[ -s /root/autoupg.xml ]] && FILES="/root/autoupg*xml" || FILES=''
	conf_files $OF /root/autoinst.xml $FILES /var/adm/autoinstall/cache/installedSystem.xml
	_sanitize_file $OF
	echolog Done
}

boot_info() {
	printlog "Boot Files..."
	test $OPTION_BOOT -eq 0 && { echolog Excluded; return 1; }
	OF=boot.txt
	addHeaderFile $OF
	log_cmd $OF "uname -a"
	KERNELS=$(cat $LOG/$RPMFILE | grep '^kernel-' | grep -v 'kernel-source' | awk '{print $1}')
	for KERNEL in $KERNELS
	do
		rpm_verify $OF $KERNEL
	done
	if rpm -q grub &> /dev/null; then
		rpm_verify $OF grub
		conf_files $OF /etc/grub.conf /boot/grub/menu.lst /boot/grub/device.map
		timed_log_cmd $OF 'hwinfo --framebuffer'
	fi
	if rpm -q grub2 &> /dev/null; then
		rpm_verify $OF grub2
		conf_files $OF /etc/default/grub /etc/default/grub_installdevice /boot/grub2/device.map
		BKOP=$ADD_OPTION_LOGS
		ADD_OPTION_LOGS=1 conf_files $OF /boot/grub2/grub.cfg
		ADD_OPTION_LOGS=$BKOP
	fi
	if rpm -q lilo &> /dev/null; then
		rpm_verify $OF lilo
		conf_files $OF /etc/lilo.conf /etc/yaboot.conf
	fi
	if rpm -q elilo &> /dev/null; then
		rpm_verify $OF elilo
		ELILOFILE=$(rpm -ql elilo | grep elilo.efi)
		ELILODIR=$(dirname $ELILOFILE)
		log_cmd $OF "ls -l --time-style=long-iso $ELILODIR"
		FILES="$(find /boot/ -type f 2>/dev/null | grep elilo.[conf,cfg]) $(find -L /etc/ -type f 2>/dev/null | grep elilo.[conf,cfg])"
		conf_files $OF $FILES
		log_cmd $OF "cksum $(ls -1 $ELILOFILE) $(find /boot/ -type f -name 'elilo.efi' 2>/dev/null)"
	fi
	if rpm -q efibootmgr &> /dev/null; then
		log_cmd $OF "efibootmgr -v"
	fi
	if rpm -q s390-tools &> /dev/null; then
		conf_files $OF /etc/zipl.conf
	fi

	test -e /usr/sbin/mcelog && log_cmd $OF "/usr/sbin/mcelog --ignorenodev --filter --dmi"
	test -s /var/log/mcelog && { log_cmd $OF "ls -l --time-style=long-iso /var/log/mcelog"; conf_files $OF /var/log/mcelog; }
	log_cmd $OF 'last -xF | egrep "reboot|shutdown|runlevel|system"'

	(( SLES_VER >= 120 )) && FILES='/var/log/boot.log' || FILES='/etc/inittab'
	conf_files $OF /proc/cmdline /etc/sysconfig/kernel $FILES /etc/init.d/boot.local /etc/init.d/before.local /etc/init.d/after.local /etc/init.d/halt.local

	log_cmd $OF 'ls -lR --time-style=long-iso /boot/'
	if [ $SLES_VER -gt 90 ]; then
		for i in $(find /boot/ -maxdepth 1 -type f -name \*initrd\* 2>/dev/null)
		do
			if file $i | grep -i "gzip compressed" &>/dev/null; then
				log_cmd $OF "zcat $i | cpio -itv 2>/dev/null"
			elif file $i | grep -i "xz compressed" &>/dev/null; then
				log_cmd $OF "xzcat $i | cpio -itv 2>/dev/null"
			fi
		done
	fi
	(( SLES_VER >= 120 )) && log_cmd $OF "lsinitrd -k $(uname -r)"
	if (( SLES_VER >= 120 )); then
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		log_cmd $OF 'journalctl --no-pager --disk-usage'
		if (( $ADD_OPTION_LOGS > 0 )); then
			log_cmd $OF 'journalctl --no-pager --list-boot'
			LIST_BOOTS=$(journalctl --no-pager --list-boot | wc -l)
			((LIST_BOOTS--))
			if (( LIST_BOOTS > 0 )); then
				BOOT_COUNT=1
				if (( VAR_OPTION_JOURNALCTL_MAX_BOOTS > 0 )); then
					JOURNALCTL_MAX_BOOTS=$VAR_OPTION_JOURNALCTL_MAX_BOOTS
				else
					#VAR_OPTION_JOURNALCTL_MAX_BOOTS of 0 means get all boots
					JOURNALCTL_MAX_BOOTS=$LIST_BOOTS
				fi
				for THIS_BOOT in $(seq 0 $LIST_BOOTS)
				do
					log_cmd $OF "journalctl --no-pager --boot $THIS_BOOT"
					((BOOT_COUNT < JOURNALCTL_MAX_BOOTS)) && ((BOOT_COUNT++)) || break
				done
			else
				log_cmd $OF "journalctl --no-pager --boot 0"
			fi
		else
			if (( VAR_OPTION_JOURNALCTL_LINE_COUNT > 0 )); then
				log_cmd $OF "journalctl --no-pager --boot 0 | head -n ${VAR_OPTION_JOURNALCTL_LINE_COUNT}"
			else
				log_cmd $OF "journalctl --no-pager --boot 0"
			fi
		fi
	else
		conf_files $OF /var/log/boot.msg /var/log/boot.omsg
	fi
	log_cmd $OF 'dmesg -T'
	echolog Done
}

smt_info() {
	printlog "SMT..."
	test $OPTION_SMT -eq 0 && { echolog Excluded; return 1; }
	OF=smt.txt
	addHeaderFile $OF
	if rpm_verify $OF smt; then
		check_service $OF smt
		CONF=/etc/smt.conf
		conf_files $OF /etc/smt.conf
		FILES=$(find -L /etc/smt.d/ -type f 2>/dev/null)
		conf_files $OF $FILES
		log_cmd $OF 'smt-catalogs'
		log_cmd $OF 'smt-catalogs -o'
		log_cmd $OF 'smt-list-registrations'
		log_cmd $OF 'smt-list-products'
		if [ -d /srv/www/htdocs/repo ]; then
			log_cmd $OF 'find -L /srv/www/htdocs/repo -print0 | sort -z | xargs -0 ls -ld --time-style=long-iso'
		fi
		FILES=$(find -L /var/log/ -type f | grep smt- | grep log$)
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		_sanitize_file $OF
		echolog Done
	else
		echolog Skipped
	fi
}

update_info() {
	printlog "Updates..."
	test $OPTION_UP -eq 0 && { echolog Excluded; return 1; }
	OF=updates.txt
	SKIP=0
	TIMEOUT=0
	addHeaderFile $OF
	if [ $SLES_VER -lt 110 ] && rpm_verify $OF rug
	then
		rpm_verify $OF lsb
		RUG_VER=$(rpm -q rug | tail -1 | cut -d- -f2 | cut -d\. -f1)
		log_cmd $OF 'date'
		if [ $RUG_VER -gt 6 ]; then
			# Time out as a group, if one rug command fails, all remaining rug commands fail
			for CMDOPT in prefs '--no-abbrev sl' ca lu pch
			do
				if [ $TIMEOUT -ge 10 ]; then
					log_write $OF "#==[ Command ]======================================#"
					log_write $OF "# Skipped \"rug $CMDOPT\" due to previous timeout"
					log_write $OF
				else
					timed_log_cmd $OF "rug $CMDOPT"
					TIMEOUT=$?
				fi
			done
		elif [ $RUG_VER -gt 1 ]; then
			for CMDOPT in prefs '--no-abbrev sl' ch pl
			do
				if [ $TIMEOUT -ge 10 ]; then
					log_write $OF "#==[ Command ]======================================#"
					log_write $OF "# Skipped \"rug $CMDOPT\" due to previous timeout"
					log_write $OF
				else
					timed_log_cmd $OF "rug $CMDOPT"
					TIMEOUT=$?
				fi
			done
		fi
	fi

	TIMEOUT=0
	if [ $SLES_VER -ge 110 ] && rpm_verify $OF zypper; then
		log_cmd $OF 'date'
		log_cmd $OF 'ls -lA --time-style=long-iso /etc/products.d/'
		for CMDOPT in services 'repos -d' patch-check patches list-patches products '--xmlout products'
		do
			if [ $TIMEOUT -ge 10 ]; then
				log_write $OF "#==[ Command ]======================================#"
				log_write $OF "# Skipped \"zypper $CMDOPT\" due to previous timeout"
				log_write $OF
			else
				timed_log_cmd $OF "zypper --non-interactive --no-gpg-checks $CMDOPT"
				TIMEOUT=$?
			fi
		done
		rpm_verify $OF lsb
		conf_files $OF /etc/zypp/zypp.conf /etc/zypp/credentials.d/NCCcredentials
	fi
	if (( SLES_VER >= 120 ))
	then
		if rpm_verify $OF SUSEConnect
		then
			rpm_verify $OF ruby2.1-rubygem-suse-connect
			log_cmd $OF "SUSEConnect --status"
			FILES=$(find /etc/zypp/credentials.d/ -type f 2>/dev/null)
			conf_files $OF /etc/SUSEConnect $FILES
		fi
	fi

	if rpm -q libzypp &> /dev/null; then
		QPBIN=$(rpm -ql libzypp | grep query-pool)
		test -n "$QPBIN" && timed_log_cmd $OF "$QPBIN products" || ((SKIP++))
	elif rpm -q libzypp-zmd-backend &> /dev/null; then
		QPBIN=$(rpm -ql libzypp-zmd-backend | grep query-pool)
		test -n "$QPBIN" && timed_log_cmd $OF "$QPBIN products" || ((SKIP++))
	fi

	if rpm -q zypper &> /dev/null; then
		log_cmd $OF 'installation_sources -s'
	fi

	if rpm_verify $OF suseRegister; then
		[ $SLES_VER -lt 110 ] && log_cmd $OF 'chkconfig suseRegister --list'
		FILES='/etc/suseRegister.conf /etc/sysconfig/suse_register'
		conf_files $OF $FILES
		if [ -d /var/lib/suseRegister/ ]; then
			FILES=$(find -L /var/lib/suseRegister/ -type f)
			conf_files $OF $FILES
		fi
	fi

	log_cmd $OF "env | grep -i proxy | grep -v CMDLINE"
	conf_files $OF /etc/sysconfig/proxy
	if [ -s /root/.curlrc ]; then
		conf_files $OF /root/.curlrc
		SC_PROXY_PASS=$(grep -i "^proxy-user" /root/.curlrc | sed -e 's/"//g' | awk '{print $3}' | cut -d\: -f2)
		sed -i -e "s/:${SC_PROXY_PASS}$/:*REMOVED BY SUPPORTCONFIG*/g;s/:${SC_PROXY_PASS}\"$/:*REMOVED BY SUPPORTCONFIG*\"/g" $LOG/$OF
	fi

	if rpm -q curl &>/dev/null; then
		# Test update server
		UPDATE_TEST_URL=''
		if [[ -s /etc/sysconfig/rhn/up2date ]]; then # get SUMA update URL
			UPDATE_TEST_URL=$( cat /etc/sysconfig/rhn/up2date | grep -i "^serverURL=" | cut -d= -f2)
		elif [[ -s /etc/SUSEConnect ]]; then # get SLE12 update URL
			UPDATE_TEST_URL=$( cat /etc/SUSEConnect | grep -i "^url: " | awk '{print $2}')
		elif [[ -s /etc/suseRegister.conf ]]; then # get SLE11 update URL
			UPDATE_TEST_URL=$( cat /etc/suseRegister.conf | grep -i "^url=" | cut -d= -f2)
		fi

		if [[ -n $UPDATE_TEST_URL ]]; then # a local update server URL was found
			if echo $UPDATE_TEST_URL | egrep -i "^http.*//" &>/dev/null; then
				LOCAL_TEST_PROTOCOL=$(echo $UPDATE_TEST_URL | awk -F/ '{print $1}')
				LOCAL_TEST_HOST=$(echo $UPDATE_TEST_URL | awk -F/ '{print $3}')
			else
				LOCAL_TEST_PROTOCOL=''
				LOCAL_TEST_HOST=$(echo $UPDATE_TEST_URL | awk -F/ '{print $1}')
			fi
			if [[ -n LOCAL_TEST_PROTOCOL ]]; then
				LOCAL_TEST_URL="${LOCAL_TEST_PROTOCOL}//${LOCAL_TEST_HOST}/"
			else
				LOCAL_TEST_URL="${UPDATE_TEST_HOST}"
			fi
			log_cmd $OF "curl --connect-timeout 10 --trace-ascii ${LOG}/updates-curl-trace_${LOCAL_TEST_HOST}.txt --digest --remote-time --fail ${LOCAL_TEST_URL}"
		else # no local update server URL found
			if (( ADD_OPTION_LOCAL_ONLY )); then
				log_entry $OF note "curl -- aborted: ADD_OPTION_LOCAL_ONLY set, no local update URLs found"
			else
				for SUSE_TEST_URL in 'https://updates.suse.com/' 'https://scc.suse.com/'
				do
					SUSE_TEST_HOST=$(echo $SUSE_TEST_URL | awk -F/ '{print $3}')
					log_cmd $OF "curl --connect-timeout 10 --trace-ascii ${LOG}/updates-curl-trace_${SUSE_TEST_HOST}.txt --digest --remote-time --fail $SUSE_TEST_URL"
				done
			fi
		fi
	else
		log_entry $OF note "curl -- not installed, aborted"
	fi

#zypper
	FILES=$(find -L /var/log/ -type f | grep zypp)
	test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES

#suseregister
	log_files $OF 0 '/root/.suse_register.log'
	FILES="/var/log/messages"
	[ $ADD_OPTION_LOGS -gt 0 ] && grep_log_files suse_register $OF 0 $FILES || grep_log_files suse_register $OF $VAR_OPTION_LINE_COUNT $FILES

	if (( SLES_VER >= 120 ))
	then
		conf_files $OF '/proc/kgr_in_progress'
		log_entry $OF note "Processes blocking kGraft patching"
		FOUND=0
		for i in $(find /proc -type f | grep -i kgr_in_progress)
		do
			VAL=$(cat $i 2>/dev/null)
			if [[ -n "$VAL" ]]
			then
				PPATH=$(dirname $i)
				if (( VAL > 0 ))
				then
					COMM=$(cat ${PPATH}/comm 2>/dev/null)
					KPID=$(basename ${PPATH})
					log_write $OF "$KPID: $COMM"
					FOUND=1
				fi
			fi
		done
		(( FOUND )) && log_write $OF
	fi
	_sanitize_file $OF
	echolog Done
}

pam_info() {
	printlog "PAM..."
	test $OPTION_PAM -eq 0 && { echolog Excluded; return 1; }
	OF=pam.txt
	addHeaderFile $OF
	rpm_verify $OF pam
	rpm_verify $OF pam-modules
	conf_files $OF /etc/nsswitch.conf /etc/nologin
	conf_files $OF /etc/passwd
	log_cmd $OF 'getent passwd'
	conf_files $OF /etc/group
	log_cmd $OF 'getent group'
	conf_files $OF /etc/sudoers
	(( SLES_VER >= 120 )) && log_cmd $OF 'loginctl --no-pager list-sessions'
	log_write $OF "#==[ Files in /etc/security ]=======================#"
	test -d /etc/security && FILES="$(find -L /etc/security/ -type f -name \*conf)" || FILES=""
	conf_files $OF $FILES
	log_write $OF "#==[ Files in /etc/pam.d ]==========================#"
	test -d /etc/pam.d && FILES="$(find -L /etc/pam.d/ -type f)" || FILES=""
	conf_files $OF $FILES
	echolog Done
}

sssd_info() {
	printlog "System Security Services..."
	test $OPTION_SSSD -eq 0 && { echolog Excluded; return 1; }
	OF=sssd.txt
	addHeaderFile $OF
	if rpm_verify $OF sssd; then
		rpm_verify $OF sssd-tool
		rpm_verify $OF python-sssd-config
		if (( SLES_VER >= 120 )); then
			log_cmd $OF 'systemctl status sssd.service'
		else
			check_service $OF sssd
		fi
		conf_files $OF "/etc/nsswitch.conf /etc/sssd/sssd.conf"
		SRVS_LDAP=$(grep "^[[:space:]]*ldap_uri" /etc/sssd/sssd.conf | cut -d= -f2 | sed -e 's/ *//g;s/,/ /g')
		if [ -n "$SRVS_LDAP" ]; then
			for URI in $SRVS_LDAP
			do
				ADDR=$(echo $URI | awk -F\/ '{print $NF}' | cut -d\: -f1)
				ping_addr $OF 'SSSD LDAP Server' $ADDR
			done
		fi
		SRVS_KRB5=$(egrep "^[[:space:]]*krb5_server|^[[:space:]]*krb5_kdcip" /etc/sssd/sssd.conf | cut -d= -f2 | sed -e 's/ *//g;s/,/ /g')
		if [ -n "$SRVS_KRB5" ]; then
			for URI in $SRVS_KRB5
			do
				ADDR=$(echo $URI | awk -F\/ '{print $NF}' | cut -d\: -f1)
				ping_addr $OF 'SSSD Kerberos Server' $ADDR
			done
		fi
		log_cmd $OF 'date +"%Y-%m-%d %H:%M"'
		log_cmd $OF 'ls -lR --time-style=long-iso /var/lib/sss/'
		if (( SLES_VER < 120 )); then
			[ -s /etc/init.d/sssd ] && SSSD_PIDF=$(grep '^PID_FILE' /etc/init.d/sssd | sed -e 's/ *//g' | cut -d= -f2)
			test -z "$SSSD_PIDF" && SLAPD_PIDF="/var/run/sssd.pid"
			if [ -f $SSSD_PIDF ]; then
				SSSD_PID=$(cat $SSSD_PIDF)
			else
				SSSD_PID=""
			fi
			if [ -n "$SSSD_PID" ]; then
				SSSD_PIDS=$(ps axwwo pid,ppid,cmd | grep ${SSSD_PID} | grep -v grep | awk '{print $1}' | sort -n)
				log_cmd $OF "ps axwwo user,pid,ppid,%cpu,%mem,vsz,rss,stat,time,cmd | egrep \"${SSSD_PID}|PPID\" | grep -v grep"
				for THISPID in $SSSD_PIDS
				do
					log_cmd $OF "lsof -b +M -n -l +fg -P -p $THISPID 2>/dev/null"
				done
			fi
		else
			SSSD_PID=$(systemctl show sssd.service -p ExecMainPID)
			SSSD_PID=${SSSD_PID#ExecMainPID=}
			if (( $SSSD_PID )); then
				SSSD_PIDS=$(ps axwwo pid,ppid,cmd | grep ${SSSD_PID} | grep -v grep | awk '{print $1}' | sort -n)
				log_cmd $OF "ps axwwo user,pid,ppid,%cpu,%mem,vsz,rss,stat,time,cmd | egrep \"${SSSD_PID}|PPID\" | grep -v grep"
				for THISPID in $SSSD_PIDS
				do
					log_cmd $OF "lsof -b +M -n -l +fg -P -p $THISPID 2>/dev/null"
				done
			fi
		fi
		log_cmd $OF 'grep pam_sss /etc/pam.d/*'
		FILES="/var/log/sssd/*"
		[ $ADD_OPTION_LOGS -gt 0 ] && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		FILES="/var/log/messages"
		[ $ADD_OPTION_LOGS -gt 0 ] && grep_log_files ' sssd' $OF 0 $FILES || grep_log_files ' sssd' $OF $VAR_OPTION_LINE_COUNT $FILES
		echolog Done
	else
		echolog Skipped
	fi
}

environment_info() {
	printlog "Environment..."
	test $OPTION_ENV -eq 0 && { echolog Excluded; return 1; }
	OF=env.txt
	addHeaderFile $OF
	log_icmd $OF 'ulimit -a'
	if (( SLES_VER >= 120 )); then
		log_cmd $OF 'systemctl status sysctl'
		conf_files $OF /etc/sysctl.conf /boot/sysctl.conf-* /lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /etc/sysctl.d/*.conf /run/sysctl.d/*.conf
	else
		log_cmd $OF 'chkconfig boot.sysctl'
		conf_files $OF /etc/sysctl.conf /etc/sysconfig/sysctl
	fi
	log_cmd $OF 'sysctl -a'
	log_cmd $OF 'getconf -a'
	log_cmd $OF 'ipcs -l'
	log_cmd $OF 'ipcs -a'
	log_cmd $OF 'CASAcli -l'
	test -d /etc/default && FILES=$(find -L /etc/default/ -type f) || FILES=""
	conf_files $OF $FILES /root/.xauth/export
	log_cmd $OF 'env'
	# s390 specific
	if [[ -e /dev/vmcp ]]; then
		log_cmd $OF 'vmcp query virtual all'
		log_cmd $OF 'vmcp query privclass'
		log_cmd $OF 'vmcp query cplevel'
		log_cmd $OF 'vmcp query mdc'
		log_cmd $OF 'vmcp query qioassist'
		log_cmd $OF 'vmcp query files'
		log_cmd $OF 'vmcp query userid'
	else
		case $(uname -i) in
		s390x) 
			log_write $OF "#==[ s390x Hardware Detected ]======================#"
			log_write $OF "# Consider loading vmcp for more info: modprobe vmcp"
			log_write $OF
			;;
		esac
	fi
	conf_files $OF /etc/profile /etc/profile.local /etc/profile.d/*
	conf_files $OF /etc/bash.bashrc /etc/csh\.* /etc/ksh*
	sed -i -e 's/\r//g' $LOG/$OF
	echolog Done
}

systemd_info() {
	printlog "SystemD..."
	test $OPTION_DAEMONS -eq 0 && { echolog Excluded; return 1; }
	OF=systemd.txt
	addHeaderFile $OF
	rpm_verify $OF systemd
	log_cmd $OF 'hostnamectl status'
	log_cmd $OF 'systemctl --failed'
	log_cmd $OF 'busctl --no-pager --system list'
	log_cmd $OF 'timedatectl --no-pager status'
	log_cmd $OF 'systemd-analyze --no-pager blame'
	log_cmd $OF 'systemd-cgtop --batch --iterations=1'
	log_cmd $OF 'systemd-cgls --no-pager --all --full'
	log_cmd $OF 'systemd-delta --no-pager'
	FILES=''
	[[ -d /etc/systemd ]] && FILES=$(find -L /etc/systemd -maxdepth 1 -type f)
	log_cmd $OF 'systemctl --no-pager show'
	conf_files $OF $FILES
	log_cmd $OF 'systemctl --no-pager --all list-units'
	log_cmd $OF 'systemctl --no-pager --all list-sockets'
	log_cmd $OF 'systemctl --no-pager list-unit-files'
	log_cmd $OF 'systemctl --no-pager list-jobs'
	log_cmd $OF 'systemctl --no-pager list-timers --all'
	for i in $(systemctl --no-pager --all list-units | sed 's/^[^-_:\\a-zA-Z0-9]*//' | egrep -v '^UNIT |^LOAD |^ACTIVE |^SUB |^To |^[[:digit:]]* ' | awk '{print $1}')
	do
		if [[ -z "$i" ]]
		then
			break
		else
			log_cmd $OF "systemctl show '$i'"
		fi
	done
	log_cmd $OF 'ls -alR /etc/systemd/'
	log_cmd $OF 'ls -alR /usr/lib/systemd/'
	echolog Done
}

tuned_info() {
	printlog "Tuning..."
	test $OPTION_TUNED -eq 0 && { echolog Excluded; return 1; }
	OF=tuned.txt
	addHeaderFile $OF
	if rpm_verify $OF tuned; then
		log_cmd $OF "systemctl status tuned.service"
		log_cmd $OF "tuned-adm active"
		FILES=$(find -L /etc/tuned/ -type f 2>/dev/null)
		conf_files $OF $FILES
		FILES=$(find -L /usr/lib/tuned/ -type f 2>/dev/null | grep "\.conf$")
		conf_files $OF $FILES
		FILES="/var/log/tuned/tuned.log"
		(( $ADD_OPTION_LOGS > 0 )) && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES

		if rpm_verify $OF sapconf; then
			log_cmd $OF "systemctl status sapconf.service"
			FILES="/var/log/sapconf.log"
			(( $ADD_OPTION_LOGS > 0 )) && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		echolog Done
	else
		echolog Skipped
	fi
}

docker_info() {
	printlog "Docker..."
	test $OPTION_DOCKER -eq 0 && { echolog Excluded; return 1; }
	OF=docker.txt
	addHeaderFile $OF
	[[ -e /usr/bin/docker ]] && DOCKER_PKG=`rpm -q --whatprovides /usr/bin/docker 2>/dev/null`
	[[ -z $DOCKER_PKG ]] && DOCKER_PKG='docker'
	if rpm_verify $OF $DOCKER_PKG
	then
		log_cmd $OF 'docker version'
		log_cmd $OF "systemctl status docker.service"
		log_cmd $OF 'docker info'
		log_cmd $OF 'docker images'
		log_cmd $OF 'docker ps --all'
		log_cmd $OF 'zypper --non-interactive --no-gpg-checks repos -d'
		FILES='/etc/sysconfig/docker'
		conf_files $OF $FILES
		if rpm_verify $OF ruby2.1-rubygem-sle2docker
		then
			log_cmd $OF 'sle2docker version'
			log_cmd $OF 'sle2docker list'
		fi
		for i in $(docker ps -a 2>/dev/null | grep -v "COMMAND" | awk '{print $1}');
		do
			log_cmd $OF "docker top $i"
			log_cmd $OF "docker logs $i"
			log_cmd $OF "docker inspect $i"
		done
		log_cmd $OF 'ls -al --time-style=long-iso /var/lib/docker/containers'
		log_cmd $OF 'journalctl -u docker'
	fi
	echolog Done
}

cron_info() {
	printlog "CRON..."
	test $OPTION_CRON -eq 0 && { echolog Excluded; return 1; }
	OF=cron.txt
	addHeaderFile $OF
	if rpm_verify $OF cron
	then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status cron.service"
		else
			check_service $OF cron
		fi
		conf_files $OF /var/spool/cron/allow /var/spool/cron/deny
		log_write $OF "### Individual User Cron Jobs ###"
		test -d /var/spool/cron/tabs && FILES=$(find -L /var/spool/cron/tabs/ -type f) || FILES=""
		conf_files $OF $FILES
		CRONS="cron.d cron.hourly cron.daily cron.weekly cron.monthly"
		log_write $OF "### System Cron Job File List ###"
		for CRONDIR in $CRONS
		do
			log_cmd $OF "find -L /etc/${CRONDIR}/ -type f"
		done
		log_write $OF "### System Cron Job File Content ###"
		conf_files $OF /etc/crontab
		for CRONDIR in $CRONS
		do
			FILES=$(find -L /etc/${CRONDIR}/ -type f)
			conf_files $OF $FILES
		done
		echolog Done
	else
		echolog Skipped
	fi
	printlog "AT..."
	log_write $OF "#----------------------------------------------------------------#"
	if rpm_verify $OF at
	then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status atd.service"
		else
			check_service $OF atd
		fi
		log_write $OF "### System at Job File List ###"
		log_cmd $OF "find -L /var/spool/atjobs/ -type f"
		log_write $OF "### System at Job File Content ###"
		FILES=$(find -L /var/spool/atjobs/ -type f)
		conf_files $OF $FILES
		echolog Done
	else
		echolog Skipped
	fi
}

soft_raid_info() {
	printlog "Software Raid..."
	test $OPTION_SRAID -eq 0 && { echolog Excluded; return 1; }
	OF=fs-softraid.txt
	addHeaderFile $OF
	conf_files $OF /proc/mdstat
	if rpm_verify $OF mdadm
	then
		log_cmd $OF 'mdadm --detail --scan'
	fi
	if rpm_verify $OF raidtools
	then
		LOGFILE=$LOG/$OF
		for MDEVICE in $(cat /proc/mdstat | grep ^md | awk '{print $1}')
		do
			echo "# lsraid -a /dev/$MDEVICE" >> $LOGFILE
			lsraid -a /dev/$MDEVICE >> $LOGFILE 2>&1
			echo >> $LOGFILE
		done
	fi
	conf_files $OF /etc/mdadm.conf /etc/raidtab
	echolog Done
}

lvm_info() {
	printlog "LVM..."
	test $OPTION_LVM -eq 0 && { echolog Excluded; return 1; }
	echonlog "Please Wait..."
	OF=lvm.txt
	local LVM_IO_DELAYS=0
	addHeaderFile $OF
	if rpm_verify $OF lvm2
	then
		echonlog Base
		VGBIN="vgs"
		LVBIN="lvs"
		log_cmd $OF "systemctl status 'lvm2-activation-early.service'"
		FILES="/etc/lvm/lvm.conf"
		timed_log_cmd $OF 'pvs' || LVM_IO_DELAYS=1
		if ! (( $LVM_IO_DELAYS )); then
			log_cmd $OF "vgs"
			log_cmd $OF "lvs"
		fi
		conf_files $OF $FILES
		log_cmd $OF 'dmsetup ls --tree'
		log_cmd $OF 'dmsetup table'
		log_cmd $OF 'dmsetup info'
		log_cmd $OF 'ls -l --time-style=long-iso /etc/lvm/backup/'
		conf_files $OF /etc/lvm/backup/*
		log_cmd $OF 'ls -l --time-style=long-iso /etc/lvm/archive/'
		conf_files $OF /etc/lvm/archive/*
		if ! (( $LVM_IO_DELAYS )); then
			echonlog Detail
			log_write $OF
			log_write $OF "###[ Detail Scans ]###########################################################################"
			log_write $OF
			log_cmd $OF 'pvdisplay -vv'
			log_cmd $OF 'vgdisplay -vv'
			log_cmd $OF 'lvdisplay -vv'
			log_cmd $OF 'pvs -vvvv'
			log_cmd $OF 'pvscan -vvv'
			log_cmd $OF "$VGBIN -vvvv"
			log_cmd $OF "$LVBIN -vvvv"
		fi
		echolog Done
	else
		echolog Skipped
	fi
}

mpio_info() {
	printlog "Multipathing..."
	test $OPTION_MPIO -eq 0 && { echolog Excluded; return 1; }
	OF=mpio.txt
	addHeaderFile $OF
	SKIP=0
	MPIO_RPM=$(rpm -qf `which multipath 2>/dev/null` 2>/dev/null)
	if [ -z "$MPIO_RPM" ]; then
		MPIO_RPM=multipath-tools
	fi
	if rpm_verify $OF $MPIO_RPM
	then
		if (( SLES_VER >= 120 )); then
			log_cmd $OF 'systemctl status multipathd.service'
			log_cmd $OF 'systemctl status multipathd.socket'
		else
			log_cmd $OF 'chkconfig boot.device-mapper'
			log_cmd $OF 'chkconfig boot.multipath'
			check_service $OF multipathd
		fi
		log_cmd $OF 'lspci -b'
		log_cmd $OF 'multipath -ll'
		log_cmd $OF 'ls -lR --time-style=long-iso /dev/disk/'
		conf_files $OF /etc/multipath.conf /etc/modprobe.conf.local /etc/sysconfig/hotplug /etc/sysconfig/kernel /etc/fstab
		log_cmd $OF 'lsscsi -g'
		log_cmd $OF 'dmsetup ls --tree'
		log_cmd $OF 'dmsetup table'
		log_cmd $OF 'dmsetup info'
		case $SLES_VER in
		80|90) log_cmd $OF "udevinfo -d" ;;
		10*) log_cmd $OF "udevinfo -e" ;;
		11*|12*) log_cmd $OF "udevadm info -e" ;;
		esac 
		test -d /proc/scsi && SCSI_DIRS=$(find /proc/scsi/ -type d) || SCSI_DIRS=""
		for SDIR in $SCSI_DIRS
		do
			# Skip unwanted scsi directories
			test "$SDIR" = "/proc/scsi" -o "$SDIR" = "/proc/scsi/sg" -o "$SDIR" = "/proc/scsi/mptspi" && continue
			FILES=$(find ${SDIR}/ -maxdepth 1 -type f 2>/dev/null)
			conf_files $OF $FILES
		done
		log_cmd $OF 'multipath -v3 -d'
	else
		((SKIP++))
	fi
	if rpm_verify $OF EMCpower.LINUX
	then
		test -x /sbin/powermt && log_cmd $OF 'powermt display dev=all'
	else
		((SKIP++))
	fi
	test $SKIP -lt 2 && echolog Done || echolog Skipped
}

detectProducts() {
	OUT=$1
	if rpm -q SUSE_SLES_SAP-release &>/dev/null
	then
		log_write $OUT "#==[ System ]=======================================#"
		log_write $OUT "# Product"
		log_write $OUT "SUSE Linux Enterprise Server for SAP Applications"
		log_write $OUT
	elif rpm -q 'SLES-for-VMware-release' &>/dev/null
	then
		log_write $OUT "#==[ System ]=======================================#"
		log_write $OUT "# Product"
		log_write $OUT "SUSE Linux Enterprise Server for VMware"
		log_write $OUT
	fi
}

detectVirtualization() {
	if echo $ARCH | egrep -v "i386|i586|i686|x86_64" &>/dev/null; then
		return 5
	fi
	OUT=$1
	log_write $OUT "#==[ System ]=======================================#"
	log_write $OUT "# Virtualization"
	NO_HYPER=1
	if [ -x /usr/sbin/dmidecode ]; then
		MANUFACTURERNAME=$(/usr/sbin/dmidecode -s system-manufacturer 2>/dev/null)
		SYSPRODNAME=$(/usr/sbin/dmidecode -s system-product-name 2>/dev/null)
		if [ -n "$MANUFACTURERNAME" ]; then
			log_write $OUT "Manufacturer:  $MANUFACTURERNAME"
			log_write $OUT "Hardware:      $SYSPRODNAME"
		else
			log_write $OUT "Hardware:      See hardware.txt"
		fi
	fi

	# Xen Hypervisor
	if [ -d /proc/xen ]; then
		NO_HYPER=0
		if [ -e /proc/xen/xsd_port ]; then
			log_write $OUT "Hypervisor:    Xen (/proc/xen)"
			log_write $OUT "Identity:      Virtual Machine Server - Dom0 (/proc/xen/xsd_port)"
		else
			log_write $OUT "Hypervisor:    Xen (/proc/xen)"
			log_write $OUT "Identity:      Virtual Machine - DomU (No /proc/xen/xsd_port)"
			if uname -r | grep -vi xen &>/dev/null; then
				log_write $OUT "Type:          Fully Virtualized (no xen kernel)"
			else
				log_write $OUT "Type:          Para Virtualized (xen kernel)"
			fi
		fi
	fi

	# KVM Hypervisor
	CPUMODEL=$(grep -i '^model name' /proc/cpuinfo | head -1)
	if grep '^kvm' /proc/modules &>/dev/null; then
		NO_HYPER=0
		if echo $CPUMODEL | grep -i 'QEMU Virtual CPU' &>/dev/null; then
			KVMID="Virtual Machine (QEMU Virtual CPU)"
		else
			KVMID="Virtual Machine Server (No QEMU Virtual CPU)"
		fi
		log_write $OUT "Hypervisor:    KVM (kvm kernel module loaded)"
		log_write $OUT "Identity:      $KVMID"
	elif echo $CPUMODEL | grep -i 'QEMU Virtual CPU' &>/dev/null; then
		NO_HYPER=0
		log_write $OUT "Hypervisor:    KVM (QEMU Virtual CPU)"
		log_write $OUT "Identity:      Virtual Machine (QEMU Virtual CPU)"
	fi

	# VMware Hypervisor
	if grep '^vmmon' /proc/modules &>/dev/null; then
		NO_HYPER=0
		log_write $OUT "Hypervisor:    VMware (vmmon loaded)"
		log_write $OUT "Identity:      Virtual Machine Server (Not vmware hardware platform)"
	elif echo $SYSPRODNAME | grep -i vmware &>/dev/null; then
		NO_HYPER=0
		log_write $OUT "Hypervisor:    VMware (hardware platform)"
		if rpm -q "SLES-for-VMware-release" &>/dev/null; then
			log_write $OUT "Identity:      Virtual Machine (SLES for VMware)"
		else
			log_write $OUT "Identity:      Virtual Machine (hardware platform)"
		fi
	fi

	# Microsoft Virtual Server Hypervisor
	if echo $MANUFACTURERNAME | grep -i microsoft &>/dev/null; then
		NO_HYPER=0
		log_write $OUT "Hypervisor:    Microsoft (manufacturer)"
		log_write $OUT "Identity:      Virtual Machine (hardware)"
	fi

	# Sun VirtualBox Hypervisor
	if grep '^vboxdrv' /proc/modules &>/dev/null; then
		NO_HYPER=0
		log_write $OUT "Hypervisor:    Sun VirtualBox (vboxdrv loaded)"
		log_write $OUT "Identity:      Virtual Machine Server (Not VirtualBox hardware platform)"
	elif echo $SYSPRODNAME | grep -i VirtualBox &>/dev/null; then
		NO_HYPER=0
		log_write $OUT "Hypervisor:    Sun VirtualBox (hardware platform)"
		log_write $OUT "Identity:      Virtual Machine (hardware platform)"
	fi

	if (( NO_HYPER )); then
		log_write $OUT "Hypervisor:    None"
		log_write $OUT "Identity:      Not Detected"
	fi

	log_write $OUT
}

hardware_info() {
	# This is a minimum required function, do not exclude
	printlog "Hardware..."
	test $MIN_OPTION_HARDWARE -eq 0 && { echolog EXCLUDED; return 1; }
	echonlog "Please Wait..."
	OF=hardware.txt
	addHeaderFile $OF
	log_cmd $OF 'procinfo'
	test $SLES_VER -ge 110 && log_cmd $OF 'lscpu'
	detectVirtualization $OF
	conf_files $OF /proc/cpuinfo /proc/cmdline /proc/ioports /proc/dma /proc/devices /proc/bus/usb/devices
	log_cmd $OF 'lspci -b'
	if [ $MIN_OPTION_AUTOMOD -eq 0 ]; then
		log_write $OF "#==[ Warning ]======================================#"
		log_write $OF "# Autoloading kernel modules disabled. Don't use -k."
		log_write $OF "# Excluding hwinfo"
		log_write $OF
		log_cmd $OF 'biosdecode'
	else
		timed_log_cmd $OF 'hwinfo -braille'
	fi
	log_cmd $OF 'dmidecode'
	log_cmd $OF 'lspci -nn'
	log_cmd $OF 'lspci -vvv'
	log_cmd $OF 'lsusb -vv'
	log_cmd $OF 'ls -al /dev | egrep "fd.*|dvd.*|cdr.*"'
	ALSABIN='/usr/sbin/alsa-info.sh'
	if [ -x $ALSABIN ]; then
		AVER=$(grep SCRIPT_VERSION= $ALSABIN | cut -d= -f2 | sed -e 's/\.//g')
		if [ $AVER -ge 0458 ]; then
			log_cmd $OF "$ALSABIN --stdout --no-upload --with-configs --with-devices --with-dmesg --with-alsactl"
		else
			log_cmd $OF "echo y | $ALSABIN --no-dialog --no-upload --with-configs --with-devices &>/dev/null"
			log_files $OF 0 /tmp/alsa-info.txt
		fi
	fi
	if uname -i | grep ppc64 &> /dev/null #Readded from previous commit, including it now.
	then
		platform=""
		if grep PowerNV /proc/cpuinfo &> /dev/null; then
			platform="PowerNV"
		elif grep pSeries /proc/cpuinfo &> /dev/null; then
			platform="pSeries"
		fi

		if rpm -q powerpc-utils &>/dev/null; then
			rpm_verify $OF powerpc-utils
			log_cmd $OF "ppc64_cpu --smt"
			log_cmd $OF "ppc64_cpu --cores-present"
			log_cmd $OF "ppc64_cpu --cores-on"
			log_cmd $OF "ppc64_cpu --run-mode"
			log_cmd $OF "ppc64_cpu --frequency"
			log_cmd $OF "ppc64_cpu --dscr"
			log_cmd $OF "nvram --print-config"
			if [ $platform == "pSeries" ]; then
				log_cmd $OF "serv_config -l"
				log_cmd $OF "bootlist -m both -r"
				log_cmd $OF "lparstat -i"
			fi
		fi
		if rpm -q lsvpd &>/dev/null; then
			rpm_verify $OF lsvpd
			log_cmd $OF "lscfg -vp"
			log_cmd $OF "lsmcode -A"
			log_cmd $OF "lsvpd --debug"
			if [ $platform == "pSeries" ]; then
				log_cmd $OF "lsvio -des"
			fi
		fi

		if rpm -q ppc64-diag &>/dev/null; then
			rpm_verify $OF ppc64-diag
			log_cmd $OF "usysattn"
			log_cmd $OF "usysident"
			log_cmd $OF "diag_encl -v"
		fi

		if [ $platform == "pSeries" ]; then
			if rpm -q servicelog &>/dev/null; then
				rpm_verify $OF servicelog
				log_cmd $OF "servicelog --dump"
				log_cmd $OF "servicelog_notify --list"
			fi
		fi

		PPC_DIR="${LOG}/ppc64"
		mkdir -p $PPC_DIR
		case $platform in
		"pSeries")
			log_entry $OF command "cp /proc/ppc64/eeh /proc/ppc64/lparcfg /proc/ppc64/systemcfg /var/log/platform /dev/nvram $PPC_DIR"
			cp /proc/ppc64/eeh /proc/ppc64/lparcfg /proc/ppc64/systemcfg /var/log/platform /dev/nvram $PPC_DIR 2>/dev/null

			if rpm -q rsct.core.utils &>/dev/null; then
				CTSNAP_DIR="${PPC_DIR}/ctsnap"
				mkdir -p $CTSNAP_DIR
				log_cmd $OF "ctsnap -xrunrpttr -d $CTSNAP_DIR"
			fi

			if [[ -f /var/log/drmgr ]]; then
				log_entry $OF command "cp /var/log/drmgr $PPC_DIR"
				cp /var/log/drmgr $PPC_DIR 2>/dev/null
			fi
			if [[ -f /var/log/drmgr.0 ]]; then
				log_entry $OF command "cp /var/log/drmgr.0 $PPC_DIR"
				cp /var/log/drmgr.0 $PPC_DIR 2>/dev/null
			fi
			;;
		"PowerNV")
			log_entry $OF command "cp /proc/ppc64/eeh /proc/ppc64/systemcfg /proc/ppc64/topology_updates /sys/firmware/opal/msglog /var/log/opal-elog /dev/nvram $PPC_DIR"
			cp /proc/ppc64/eeh /proc/ppc64/systemcfg /proc/ppc64/topology_updates /sys/firmware/opal/msglog /var/log/opal-elog /dev/nvram $PPC_DIR 2>/dev/null
			;;
		esac

		if [[ -d /proc/device-tree/ ]]; then
			SAVE_DIR="${PPC_DIR}/device-tree"
			mkdir -p $SAVE_DIR
			log_entry $OF command "cp -r /proc/device-tree/* $SAVE_DIR"
			cp -r /proc/device-tree/* $SAVE_DIR 2>/dev/null
		fi

                if [[ -d /sys/fs/pstore/ ]]; then
                        SAVE_DIR="${PPC_DIR}/pstore"
                        mkdir -p $SAVE_DIR
                        log_entry $OF command "cp -r /sys/fs/pstore/* $SAVE_DIR"
                        cp -r /sys/fs/pstore/* $SAVE_DIR 2>/dev/null
                fi

		if [[ -d /var/log/dump ]]; then
			log_cmd $OF "ls -l /var/log/dump"
		fi
	fi
	echolog Done
}

net_info() {
	printlog "Networking..."
	test $OPTION_NET -eq 0 && { echolog Excluded; return 1; }
	NAMESPACES=$(ip netns list)
	if [ -n "${NAMESPACES}" ] ; then
		net_info_namespace "network.txt" 
		ip netns list | while read NAMESPACE rest; do
			net_info_namespace "network-${NAMESPACE}.txt" "${NAMESPACE}"
		done
	else
		net_info_namespace "network.txt" 
	fi
	echolog Done
}

net_info_namespace() {
	OF=$1
	addHeaderFile $OF
	if [ -z "${2}" ] ; then
		NS=""
	else 
		NS="ip netns exec $2 "
		log_write $OF "#==[ Network namespace ${2} ]======================#"
	fi
	if [ -z "${NS}" ] ; then
		rpm_verify $OF sysconfig
		if (( SLES_VER >= 120 )) ; then
			rpm_verify $OF wicked
			log_cmd $OF "systemctl status network.service"
			log_cmd $OF "systemctl status nscd.service"
			log_cmd $OF "wicked ifstatus --verbose all"
			log_cmd $OF "wicked show-config"
		else
			check_service $OF network
			check_service $OF nscd
		fi
	fi
	log_cmd $OF "${NS}ifconfig -a"
	log_cmd $OF "${NS}ip addr"
	log_cmd $OF "${NS}ip route"
	log_cmd $OF "${NS}ip -6 route"
	log_cmd $OF "${NS}ip -s link"
	if [ -z "${NS}" ] ; then
		if [ $MIN_OPTION_AUTOMOD -ne 0 ]; then
			log_cmd $OF 'hwinfo --netcard'
		fi
		conf_files $OF /proc/sys/net/ipv4/ip_forward /etc/HOSTNAME
		log_cmd $OF "${NS}hostname"
		# s390 specific
		if grep vmcp /proc/modules &>/dev/null; then
			log_cmd $OF "vmcp query nic details"
			log_cmd $OF "vmcp query lan details"
			log_cmd $OF "vmcp query vswitch detail"
		else
			case $(uname -i) in
			s390x) 
				log_write $OF "#==[ s390x Hardware Detected ]======================#"
				log_write $OF "# Consider loading vmcp for more info: modprobe vmcp"
				log_write $OF
				;;
			esac
		fi
	fi
	IPADDRS=$(${NS}ip addr | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
	for IPADDR in $IPADDRS
	do
		ping_addr $OF 'Local Interface' $IPADDR "${NS}"
	done

	IPADDR=$(${NS}ip route list | awk '$1 == "default" {print $3}')
	ping_addr $OF 'Default Route' $IPADDR "${NS}"

	if [ -z "${NS}" ] ; then
		test -e /etc/resolv.conf && IPADDRS=$(grep ^nameserver /etc/resolv.conf | cut -d' ' -f2) || IPADDRS=""
		for IPADDR in $IPADDRS
		do
			ping_addr $OF 'DNS Server' $IPADDR "${NS}"
		done
	fi

	${NS}ip rule show | while read skip skip skip skip table rest
	do
		log_cmd $OF "${NS}ip route show table $table"
	done
	log_cmd $OF "${NS}ip route show table cache"
	log_cmd $OF "${NS}ip -6 route show table cache"
	log_cmd $OF "${NS}ip rule show"
	NICS=$(IFS="@: ";${NS}ip -o l | while read number nic dummy ; do echo $nic ; done)
	for NIC in ${NICS}
	do
		log_cmd $OF "${NS}tc -s -d qdisc show dev ${NIC}"
		log_cmd $OF "${NS}tc -s -d class show dev ${NIC}"
		log_cmd $OF "${NS}tc -s -d filter show dev ${NIC}"
	done
	log_cmd $OF "${NS}netstat -as"
	log_cmd $OF "${NS}netstat -nap"
	log_cmd $OF "${NS}netstat -nr"
	log_cmd $OF "${NS}netstat -i"
	log_cmd $OF "${NS}arp -v"
	log_cmd $OF "${NS}ip ntable show"
	if [ $MIN_OPTION_AUTOMOD -eq 0 ]; then
                log_write $OF "#==[ Warning ]======================================#"
                log_write $OF "# Autoloading kernel modules disabled. Don't use -k."
                log_write $OF "# Excluding IPsec command: xfrm"
                log_write $OF
        else
		log_cmd $OF "${NS}ip xfrm state list"
		log_cmd $OF "${NS}ip xfrm policy list"
	fi
	log_cmd $OF "${NS}ip maddr show"
	log_cmd $OF "${NS}ip mroute show"

	if [ $MIN_OPTION_AUTOMOD -eq 0 ]; then
		log_write $OF "#==[ Warning ]======================================#"
		log_write $OF "# Autoloading kernel modules disabled. Don't use -k."
		log_write $OF "# Excluding Bridge command: brctl"
		log_write $OF
	else
		if [ -x /sbin/brctl ]; then
			log_cmd $OF "${NS}brctl show"
			for BRIDGE in `${NS}brctl show | sed 1d | awk '{print$1}'` 
			do 
				log_cmd $OF "${NS}brctl showmacs $BRIDGE"
			done
		fi
	fi
	ETHTOOL_BIN=$(which ethtool 2>/dev/null)
	if [[ -x $ETHTOOL_BIN ]]; then
		NICS=$(IFS="@: ";${NS}ip -o l | while read number nic dummy ; do echo $nic ; done)
		for NIC in ${NICS}
		do
			log_cmd $OF "${NS}${ETHTOOL_BIN} ${NIC}"
			for OPTION in k i S g l m
			do
				log_cmd $OF "${NS}${ETHTOOL_BIN} -${OPTION} ${NIC}"
			done
		done
	fi
	if [ -z "${NS}" ] ; then
		log_cmd $OF "nscd -g"
		conf_files $OF /etc/hosts /etc/host.conf /etc/resolv.conf /etc/nsswitch.conf /etc/nscd.conf /etc/hosts.allow /etc/hosts.deny
		conf_files $OF /etc/sysconfig/SuSEfirewall2 /etc/sysconfig/personal-firewall
	fi
	for TABLE in filter nat mangle raw
	do
		if grep iptable_$TABLE /proc/modules &>/dev/null
		then
			log_cmd $OF "${NS}iptables -t $TABLE -nvL"
			log_cmd $OF "${NS}iptables-save -t $TABLE"
		else
			log_entry $OF command "iptables"
			log_write $OF "# NOTE: The iptable_$TABLE module is not loaded, skipping check"
			log_write $OF
		fi
	done
	for TABLE in filter nat mangle raw
	do
		if grep ip6table_$TABLE /proc/modules &>/dev/null
		then
			log_cmd $OF "${NS}ip6tables -t $TABLE -nvL"
			log_cmd $OF "${NS}ip6tables-save -t $TABLE"
		else
			log_entry $OF command "ip6tables"
			log_write $OF "# NOTE: The ip6table_$TABLE module is not loaded, skipping check"
			log_write $OF
		fi
	done
	if [ -z "${NS}" ] ; then
		test -d /etc/sysconfig/network && FILES=$(find -L /etc/sysconfig/network/ -maxdepth 1 -type f) || FILES=""
		conf_files $OF /etc/sysconfig/proxy $FILES 
		(( SLES_VER >= 120 )) && FILES=$(find /etc/wicked -type f 2>/dev/null | grep '\.xml$') || FILES=''
		conf_files $OF $FILES
		if [ -d /proc/net/bonding ]; then
			FILES=$(find /proc/net/bonding/ -type f)
			conf_files $OF $FILES 
		fi
		conf_files $OF /etc/services
		FILES=$(grep logfile /etc/nscd.conf 2> /dev/null | grep -v ^# | awk '{print $2}' | tail -1)
		test -n "$FILES" || FILES="/var/log/nscd.log"
		FILES="$FILES /var/log/NetworkManager"
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
	fi
	_sanitize_file $OF
}

disk_info() {
	printlog "Disk I/O..."
	test $OPTION_DISK -eq 0 && { echolog Excluded; return 1; }
	OF=fs-diskio.txt
	local DISK_IO_DELAYS=0
	addHeaderFile $OF
	timed_log_cmd $OF 'fdisk -l 2>/dev/null | grep Disk' || DISK_IO_DELAYS=1
	conf_files $OF /proc/partitions /etc/fstab
	[[ -x /usr/bin/findmnt ]] && log_cmd $OF "findmnt"
	log_cmd $OF "mount"
	conf_files $OF /proc/mounts /etc/mtab

	for DISK in $(cat /proc/partitions | grep -v ^m | grep -v ^$ | awk '{print $4}')
	do
		case $DISK in
		sd[a-z]|sd[a-z][a-z]) log_cmd $OF "parted -s /dev/$DISK unit s print" ;;
		hd[a-z]|hd[a-z][a-z]) log_cmd $OF "parted -s /dev/$DISK unit s print" ;;
		xvd[a-z]|xvd[a-z][a-z]) log_cmd $OF "parted -s /dev/$DISK unit s print" ;;
		dasd[a-z]|dasd[a-z][a-z]) 
			log_cmd $OF "dasdview -i -f /dev/$DISK"
			log_cmd $OF "dasdview -t info -f /dev/$DISK"
			;;
		cciss*) 
			CCISS_DISK=$(echo $DISK | cut -d/ -f2)
			case $CCISS_DISK in
			c[0-9]d[0-9]) log_cmd $OF "parted -s /dev/cciss/$CCISS_DISK unit s print" ;;
			esac
			CCISS_DISK=$(echo $DISK | cut -d\! -f2)
			case $CCISS_DISK in
			c[0-9]d[0-9]) log_cmd $OF "parted -s /dev/cciss/$CCISS_DISK unit s print" ;;
			esac
			;;
		esac
	done

	log_cmd $OF 'ls -lR --time-style=long-iso /dev/disk/'
	log_cmd $OF 'ls -l --time-style=long-iso /sys/block/'

	if [ $ADD_OPTION_MINDISK -eq 0 ]; then
		log_cmd $OF 'iostat -x 1 4'
		log_cmd $OF 'sg_map -i -x'
		if [ -d /sys/block ]; then
			IDE_DISKS=$(find /sys/block/ -maxdepth 1 | grep hd\.)
			SCSI_DISKS=$(find /sys/block/ -maxdepth 1 | grep sd\.)
			CCISS_DISKS=$(find /sys/block/ -maxdepth 1 | grep cciss\*)
		else
			IDE_DISKS=""
			SCSI_DISKS=""
			CCISS_DISKS=""
		fi


		if [ -n "$IDE_DISKS" -a -d /proc/ide ]; then
			log_write $OF "#==[ IDE Detailed Info ]============================#"
			log_write $OF "#---------------------------------------------------#"
			FILES=$(find /proc/ide/ -maxdepth 1 -type f 2>/dev/null)
			conf_files $OF $FILES
			if rpm_verify $OF hdparm
			then
				DISKS=$(find /proc/ide/ -maxdepth 1 | grep hd\. | sort)
				for DISK in $DISKS
				do
					CURRENT_DISK="/dev/$(basename $DISK)"
					log_cmd $OF "hdparm -vi $CURRENT_DISK"
				done
			fi
		fi

		if [ -n "$SCSI_DISKS" ]; then
			log_write $OF "#==[ SCSI Detailed Info ]===========================#"
			log_write $OF "#---------------------------------------------------#"
			log_cmd $OF 'lsscsi'
			log_cmd $OF 'lsscsi -H'
			(( $DISK_IO_DELAYS )) || log_cmd $OF "lsblk -o 'NAME,KNAME,MAJ:MIN,FSTYPE,LABEL,RO,RM,MODEL,SIZE,OWNER,GROUP,MODE,ALIGNMENT,MIN-IO,OPT-IO,PHY-SEC,LOG-SEC,ROTA,SCHED,MOUNTPOINT'"
			if log_cmd $OF 'scsiinfo -l'
			then
				FILES=$(scsiinfo -l)
				for DEVICE in $FILES
				do
					log_cmd $OF "scsiinfo -i $DEVICE"
				done
			fi
			log_cmd $OF 'lsscsi -v'
			test -d /proc/scsi && SCSI_DIRS=$(find /proc/scsi/ -type d) || SCSI_DIRS=""
			for SDIR in $SCSI_DIRS
			do
				test "$SDIR" = "/proc/scsi" -o "$SDIR" = "/proc/scsi/sg" -o "$SDIR" = "/proc/scsi/mptspi" && continue
				FILES=$(find ${SDIR}/ -maxdepth 1 -type f 2>/dev/null)
				conf_files $OF $FILES
			done
		fi

		if [ -n "$CCISS_DISKS" -a -d /proc/driver/cciss ]; then
			log_write $OF "#==[ CCISS Detailed Info ]==========================#"
			log_write $OF "#---------------------------------------------------#"
			FILES=$(find /proc/driver/cciss/ -maxdepth 1 -type f 2>/dev/null)
			conf_files $OF $FILES
		fi
		if ! (( $IO_DELAYS )); then
			DISKS=$(sfdisk -l 2>/dev/null | grep -i 'disk /' | awk '{print $2}' | sed -e 's/://g')
			if [[ -n $DISKS ]]; then
				for DISK in $DISKS
				do
					log_cmd $OF "sfdisk -d $DISK"
				done
			fi
		fi
	fi
	echolog Done
}

btrfs_info() {
	printlog "B-tree File System..."
	test $OPTION_BTRFS -eq 0 && { echolog Excluded; return 1; }
	OF=fs-btrfs.txt
	if rpm_verify $OF btrfsprogs; then
		addHeaderFile $OF
		log_cmd $OF "btrfs filesystem show"
		conf_files $OF /etc/fstab
		[[ -x /usr/bin/findmnt ]] && log_cmd $OF "findmnt" || log_cmd $OF "mount"
		(( $IO_DELAYS )) || log_cmd $OF "df -h"
		log_cmd $OF "modinfo btrfs"
		for DISK in $(mount | grep -i btrfs | awk '{ print $3 }')
		do
			log_cmd $OF "btrfs filesystem usage $DISK"
			log_cmd $OF "btrfs scrub status $DISK"
		done

		FILES="/var/log/messages"
		test $ADD_OPTION_LOGS -gt 0 && grep_log_files btrfs $OF 0 $FILES || grep_log_files btrfs $OF $VAR_OPTION_LINE_COUNT $FILES

		if rpm_verify $OF snapper; then
			log_cmd $OF "snapper list-configs"
			CONFIGS=$(snapper --table-style 0 list-configs | sed -e 's/[[:space:]]*//g;1,2d')
			for PAIR in $CONFIGS
			do
				CONFIG=$(echo $PAIR | cut -d\| -f1)
				SUB_VOL=$(echo $PAIR | cut -d\| -f2)
				log_cmd $OF "btrfs subvolume get-default $SUB_VOL"
				log_cmd $OF "btrfs subvolume list $SUB_VOL | grep -v '.snapshots'"
				log_cmd $OF "snapper -c $CONFIG list"
			done
			conf_files $OF /etc/sysconfig/snapper /etc/snapper/configs/* /etc/snapper/filters/*
		fi
		FILES="/var/log/snapper.log"
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		echolog Done
	else
		echolog Skipped
	fi
}

iscsi_info() {
	printlog "iSCSI..."
	test $OPTION_ISCSI -eq 0 && { echolog Excluded; return 1; }
	OF=fs-iscsi.txt
	addHeaderFile $OF
	case $SLES_VER in
	80|90) 
		if rpm_verify $OF linux-iscsi
		then
			log_cmd $OF 'iscsi-ls -l'
			conf_files $OF /etc/iscsi.conf /etc/initiatorname.iscsi
			log_cmd $OF 'sfdisk -l'
		fi
		;;
	10*|11*|12*)
		log_write $OF "#___________________________________________________________#"
		log_write $OF "#____[ iSCSI Target Information ]___________________________#"
		log_write $OF
		if rpm_verify $OF lio-utils
		then
			log_cmd $OF 'systemctl status target.service'
			log_cmd $OF 'lsmod | grep target_'
			log_cmd $OF 'lio_node --version'
			log_cmd $OF 'lio_node --listendpoints'
			OUTPUT=$(lio_node --listendpoints 2>/dev/null)
			TARGET_IQN=''
			TGPT=''
			if [[ -n $OUTPUT ]]
			then
				IN_STATE=0
				SAVE_IFS=$IFS
				IFS=$'\n'
				for i in $(echo "$OUTPUT")
				do
					if (( IN_STATE ))
					then
						if echo $i | egrep -i targetalias &>/dev/null
						then
							TGPT=$(echo $i | awk '{print $2}' | cut -d_ -f2)
							IN_STATE=0
							log_entry $OF note "Five Commands for Target IQN: $TARGET_IQN"
							for LIO_NODE_OPTION in listlunacls listnodeacls listnps listtpgattr listtpgparam
						  do
								log_cmd $OF "lio_node --$LIO_NODE_OPTION $TARGET_IQN $TGPT"
							done
					fi
					elif echo $i | egrep '^\\' &>/dev/null
					then
						TARGET_IQN=$(echo $i | awk '{print $2}')
						IN_STATE=1
					fi
				done
				IFS=$SAVE_IFS
			fi
			log_cmd $OF 'tcm_node --version'
			log_cmd $OF 'tcm_node --listhbas'
			log_cmd $OF 'tcm_node --listlugps'
			FILES="/etc/target/*"
		elif rpm_verify $OF iscsitarget
		then
			if (( SLES_VER >= 120 )); then
				log_cmd $OF 'systemctl status iscsitarget.service'
				FILES='/etc/iet/ietd.conf /proc/net/iet/volume /proc/net/iet/session'
			else
				check_service $OF iscsitarget
				log_cmd $OF 'ietadm --op show'
				FILES='/etc/ietd.conf /proc/net/iet/volume /proc/net/iet/session'
			fi
		fi
		conf_files $OF $FILES
		log_write $OF "#___________________________________________________________#"
		log_write $OF "#____[ iSCSI Initiator Information ]________________________#"
		log_write $OF
		if rpm_verify $OF open-iscsi
		then
			if (( SLES_VER >= 120 )); then
				log_cmd $OF 'systemctl status iscsi.service'
				log_cmd $OF 'systemctl status iscsid.service'
				log_cmd $OF 'systemctl status iscsid.socket'
				CHKSRV=0
			else
				log_cmd $OF 'chkconfig boot.open-iscsi'
				check_service $OF open-iscsi
				CHKSRV=$?
			fi
			log_cmd $OF 'iscsi-iname'
			conf_files $OF /etc/iscsid.conf
			if [ $CHKSRV -eq 0 ]; then
				log_cmd $OF 'iscsiadm -m session'
				if log_cmd $OF 'iscsiadm -m node'
				then
					if [ $SLES_VER -ge 102 ]; then
						NODES=$(iscsiadm -m node -P 1 | grep -i Target | awk '{print $2}')
						IBIN='iscsiadm -m node -T'
					else
						NODES=$(iscsiadm -m node | cut -d] -f1 | cut -d[ -f2)
						IBIN='iscsiadm -m node -r'
					fi
					for NODE in $NODES
					do
						log_cmd $OF "$IBIN $NODE"
					done
				fi
			fi
		fi
		;;
	esac
	_sanitize_file $OF
	echolog Done
}

nfs_info() {
	printlog "NFS..."
	test $OPTION_NFS -eq 0 && { echolog Excluded; return 1; }
	OF=nfs.txt
	addHeaderFile $OF
	if rpm -q nfs-client &>/dev/null; then
		if rpm_verify $OF nfs-client
		then
			rpm_verify $OF nfs-kernel-server
			if (( SLES_VER >= 120 ))
			then
				log_cmd $OF "systemctl status nfs.service"
				log_cmd $OF "systemctl status nfsserver.service"
				NFS_STATUS=$?
			else
				check_service $OF nfs
				check_service $OF nfsserver
				NFS_STATUS=$?
			fi
			log_cmd $OF 'exportfs -v'
			log_cmd $OF 'nfsstat'
			if timed_log_cmd $OF 'showmount'
			then
				log_cmd $OF 'showmount -e'
				log_cmd $OF 'showmount -a'
			fi
			conf_files $OF /etc/exports /etc/sysconfig/nfs
			log_cmd $OF "egrep '[[:space:]]nfs[[:space:]]|[[:space:]]nfs4[[:space:]]' /etc/fstab"
			IPADDRS=$(egrep '[[:space:]]nfs[[:space:]]|[[:space:]]nfs4[[:space:]]' /etc/fstab | egrep -v '^#|^;' | cut -d\: -f1 | sort | uniq)
			for IPADDR in $IPADDRS
			do
				ping_addr $OF 'NFS Server' $IPADDR
			done
			for IPADDR in $IPADDRS
			do
				log_cmd $OF "showmount -e $IPADDR"
			done
			echolog Done
		else
			echolog Skipped
		fi
	else
		if rpm_verify $OF nfs-utils
		then
			check_service $OF portmap
			check_service $OF nfslock
			check_service $OF nfs
			check_service $OF nfsserver
			log_cmd $OF 'exportfs -v'
			log_cmd $OF 'nfsstat'
			if timed_log_cmd $OF 'showmount'
			then
				log_cmd $OF 'showmount -e'
				log_cmd $OF 'showmount -a'
			fi
			conf_files $OF /etc/exports /etc/sysconfig/nfs
			echolog Done
		else
			echolog Skipped
		fi
	fi
}

ntp_info() {
	printlog "NTP..."
	test $OPTION_NTP -eq 0 && { echolog Excluded; return 1; }
	OF=ntp.txt
	addHeaderFile $OF
	if rpm_verify $OF ntp
	then
		CONFFILE=/etc/ntp.conf
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status ntpd.service"
		else
			check_service $OF ntp
		fi
		log_cmd $OF 'ntpq -p'
		conf_files $OF $CONFFILE
		IPADDRS=$(egrep "^peer |^server " $CONFFILE | awk '{print $2}' | sort | uniq)
		for IPADDR in $IPADDRS
		do
			ping_addr $OF 'NTP Server' $IPADDR
		done
		if [[ -f $CONFFILE ]]; then
			log_write $OF "#___________________________________________________________#"
			log_write $OF "#____[ Files Included in $CONFFILE ]____________________#"
			log_write $OF
			for KEYNAME in driftfile
			do
				FILES=$(grep ^${KEYNAME} $CONFFILE | awk '{print $2}')
				conf_files $OF $FILES
			done
			KEYNAME=logfile
			FILES=$(grep ^${KEYNAME} $CONFFILE | awk '{print $2}')
			[[ -z "$FILES" ]] && FILES=/var/log/ntp
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		echolog Done
	elif rpm_verify $OF chrony
	then
		NTP_DAEMON=1
		NTP_CRON=''
		CONFFILE="/etc/chrony.conf"
		log_cmd $OF "systemctl status chronyd.service"
		FILES="$CONFFILE /etc/chrony.keys"
		conf_files $OF $FILES
		if log_cmd $OF "chronyc -n sources -v"
		then
			log_cmd $OF "chronyc -n sourcestats -v"
			log_cmd $OF "chronyc -n tracking"
			log_cmd $OF "chronyc activity"
		else
			NTP_DAEMON=0
		fi
		if [[ -d /etc/cron.d ]]; then
			NTP_CRON=$(grep -li chronyd /etc/cron.d/* 2>/dev/null)
			if [[ -n $NTP_CRON ]]; then
				conf_files $OF $NTP_CRON
			fi
		fi
		log_cmd $OF "timedatectl"
		IPADDRS=$(egrep "^pool |^peer |^server " $CONFFILE | awk '{print $2}' | sort | uniq)
		for IPADDR in $IPADDRS
		do
			ping_addr $OF 'NTP Server' $IPADDR
		done
		if [[ -f $CONFFILE ]]; then
			log_write $OF "#___________________________________________________________#"
			log_write $OF "#____[ Files Included in $CONFFILE ]____________________#"
			log_write $OF
			for KEYNAME in driftfile
			do
				FILES=$(grep ^${KEYNAME} $CONFFILE | awk '{print $2}')
				conf_files $OF $FILES
			done
			KEYNAME=logdir
			LOGDIR=$(grep ^${KEYNAME} $CONFFILE | awk '{print $2}')
			[[ -z "$LOGDIR" ]] && LOGDIR='/var/log/chrony/'
			FILES=$(find $LOGDIR -type f)
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
			FILES="/var/log/messages"
			test $ADD_OPTION_LOGS -gt 0 && grep_log_files chrony $OF 0 $FILES || grep_log_files chrony $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		echolog Done
	else
		echolog Skipped
	fi
}

udev_info() {
	printlog "UDEV..."
	test $OPTION_UDEV -eq 0 && { echolog Excluded; return 1; }
	OF=udev.txt
	addHeaderFile $OF
	if rpm_verify $OF udev
	then
		UDEV_CONF=/etc/udev/udev.conf
		if (( SLES_VER >= 120 )); then
			log_cmd $OF 'systemctl status systemd-udevd.service'
			log_cmd $OF 'systemctl status systemd-udev-trigger.service'
		else
			log_cmd $OF 'chkconfig boot.udev'
		fi
		conf_files $OF $UDEV_CONF
		case $SLES_VER in
		80|90) log_cmd $OF "udevinfo -d" ;;
		10*) log_cmd $OF "udevinfo -e" ;;
		11*|12*) log_cmd $OF "udevadm info -e" ;;
		esac 
		if [[ -f $UDEV_CONF ]]; then
			. $UDEV_CONF
			for UDEV_DIR in /usr/lib/udev/rules.d ${udev_rules:=/etc/udev/rules.d}
			do
				if [[ -d $UDEV_DIR ]]; then
					FILES=$(find -L $UDEV_DIR/ -type f)
					conf_files $OF $FILES
				fi
			done
			test "$udev_db" != "" && log_cmd $OF "ls -l --time-style=long-iso ${udev_db}/"
		fi
		echolog Done
	else
		echolog Skipped
	fi
}

crash_info() {
	printlog "Crash Info..."
	# Call fslist_info first to search for core files
	test $OPTION_CRASH -eq 0 && { echolog Excluded; return 1; }
	OF=crash.txt
	addHeaderFile $OF
	SKIP=0
	if (( SLES_VER >= 120 )); then
		rpm_verify $OF kdump
		rpm_verify $OF kexec-tools
		log_cmd $OF "uname -r"
		log_cmd $OF "systemctl status kdump.service"
		log_cmd $OF "kdumptool calibrate"
		log_cmd $OF "kdumptool dump_config"
		conf_files $OF /proc/cmdline
		if rpm -q kdump &>/dev/null; then
			DUMPDIR=$(kdumptool dump_config | grep ^KDUMP_SAVEDIR | sed -e 's/"//g;s!file://!!g' | cut -d= -f2)
			if [[ -d $DUMPDIR ]]; then
				log_cmd $OF "find -L ${DUMPDIR}/"
			else
				log_entry $OF conf "KDUMP_SAVEDIR not found: ${DUMPDIR}"
			fi
		fi
		log_cmd $OF "sysctl kernel.sysrq"
		log_cmd $OF 'sysctl kernel 2>/dev/null | grep panic'
	else
		if rpm -q lkcdutils &>/dev/null; then
			rpm_verify $OF lkcdutils
			DUMPCFG="/etc/sysconfig/dump"
			log_cmd $OF "lkcd query"
			log_cmd $OF "chkconfig boot.lkcd"
			log_cmd $OF "chkconfig lkcd-netdump --list"
			conf_files $OF $DUMPCFG
			if [ -f $DUMPCFG ]; then
				DUMPDEV=$(grep ^DUMPDEV $DUMPCFG | sed -e 's/"//g' | cut -d= -f2)
				FOUND=$(echo $DUMPDEV | grep /dev)
				if [ -n "$FOUND" ]; then
					log_cmd $OF "ls -l --time-style=long-iso ${DUMPDEV}/"
				fi
			fi
			log_cmd $OF "sysctl kernel.sysrq"
			log_cmd $OF 'grep -A20 -i "saving lkcd dump" /var/log/boot.msg'
			test -d /var/log/dump && FILES=$(find -L /var/log/dump/ -type f 2>/dev/null | grep analysis) || FILES=""
			test -z "$FILES" || conf_files $OF $FILES
		fi
		if rpm -q kernel-kdump &>/dev/null; then
			rpm_verify $OF kernel-kdump
			DUMPCFG="/etc/sysconfig/kdump"
			rpm_verify $OF kexec-tools
			log_cmd $OF "uname -r"
			check_service $OF kdump
			conf_files $OF $DUMPCFG /proc/cmdline
			log_cmd $OF "sysctl kernel.sysrq"
			log_cmd $OF 'sysctl kernel 2>/dev/null | grep panic'
			if [ -f $DUMPCFG ]; then
				DUMPDIR=$(grep ^KDUMP_SAVEDIR $DUMPCFG | sed -e 's/"//g;s!file://!!g' | cut -d= -f2)
				if [ -d $DUMPDIR ]; then
					log_cmd $OF "find -L ${DUMPDIR}/"
				else
					log_entry $OF conf "KDUMP_SAVEDIR not found: ${DUMPDIR}"
				fi
			fi
		elif rpm -q kdump &>/dev/null; then
			rpm_verify $OF kdump
			DUMPCFG="/etc/sysconfig/kdump"
			rpm_verify $OF kexec-tools
			log_cmd $OF "uname -r"
			check_service $OF boot.kdump
			check_service $OF kexec
			conf_files $OF $DUMPCFG /proc/cmdline /sys/kernel/kexec_*
			log_cmd $OF "sysctl kernel.sysrq"
			log_cmd $OF 'sysctl kernel 2>/dev/null | grep panic'
			if [ -f $DUMPCFG ]; then
				DUMPDIR=$(grep ^KDUMP_SAVEDIR $DUMPCFG | sed -e 's/"//g;s!file://!!g' | cut -d= -f2)
				if [ -d $DUMPDIR ]; then
					log_cmd $OF "find -L ${DUMPDIR}/"
				else
					log_entry $OF conf "KDUMP_SAVEDIR not found: ${DUMPDIR}"
				fi
			fi
		fi
	fi

	ANALYZEVMCORE_PREFIX=$ARCHIVE_PREFIX

	for i in $(ls -1 /var/log/${ANALYZEVMCORE_PREFIX}analyzevmcore* 2>/dev/null)
	do
		log_write $OF "#==[ Kernel Core Logs ]==========================#"
		log_write $OF "# $i"
		cat $i >> $LOG/$OF
		log_write $OF
	done

	# Application core dump information
	log_write $OF "#==[ Application Crash Info ]==========================#"
	log_write $OF
	log_icmd $OF "ulimit -c"
	log_cmd $OF "sysctl kernel.core_uses_pid"
	log_cmd $OF "sysctl kernel.core_pattern"
	conf_files $OF "/etc/sysconfig/ulimit /etc/security/limits.conf"
	log_cmd $OF "grep -n 'ulimit -c' /etc/init.d/* 2>/dev/null"

	if [[ -x /usr/bin/coredumpctl ]]; then
		log_cmd $OF "/usr/bin/coredumpctl list"
		if coredumpctl list 2>/dev/null | grep PID &>/dev/null; then
			PIDLIST=$(coredumpctl list | grep -v PID | awk '{print $5}')
			for COREPID in $PIDLIST
			do
				log_cmd $OF "coredumpctl info $COREPID"
			done
		fi
	elif [[ -x /usr/bin/systemd-coredumpctl ]]; then
		log_cmd $OF "/usr/bin/systemd-coredumpctl list"
	fi
	CORE=$(cat /proc/sys/kernel/core_pattern 2>/dev/null)
	SEARCH_LIST=$(mktemp $LOG/crash.search.list.XXXXXXXX)
	COREFILE=""
	log_write $OF "#==[ Application Core Files ]==========================#"
	# Search core_pattern
	if [[ -d "$CORE" ]]; then
		log_write $OF "# Core Files Found in lsof-cwd, \$PATH, ld.so.conf: skipping invalid core_pattern: $CORE"
		COREDIR=''
		COREFILE='core'
	elif echo "$CORE" | grep '|' &>/dev/null; then
		log_write $OF "# Core Files Found in lsof-cwd, \$PATH, ld.so.conf: skipping piped core_pattern: $CORE"
		COREDIR=''
		COREFILE='core'
	elif echo "$CORE" | grep '/' &>/dev/null; then
		log_write $OF "# Core Files Found in $CORE, lsof-cwd, \$PATH, ld.so.conf"
		COREDIR=$(dirname "$CORE")
		COREFILE=$(basename "$CORE" | sed -e 's/\%./\*/g')
		ls -l --time-style=long-iso ${COREDIR}/${COREFILE} ${COREDIR}/${COREFILE}\.* ${COREDIR}/core ${COREDIR}/core\.* >> $SEARCH_LIST 2>/dev/null
	else
		log_write $OF '# Core File List in lsof-cwd, $PATH, ld.so.conf'
		COREFILE=$(echo $CORE | sed -e 's/\%./\*/g')
	fi

	# Search CWD per lsof
	if [[ -s ${LOG}/${LSOF_FILE} ]]; then
		SEARCH="$(cat ${LOG}/${LSOF_FILE} | grep '[[:space:]]cwd[[:space:]]' | awk '{print $9}' | sort | uniq)"
		for i in $SEARCH
		do
			ls -l --time-style=long-iso ${i}/${COREFILE} ${i}/${COREFILE}\.* ${i}/core ${i}/core\.* >> $SEARCH_LIST 2>/dev/null
		done
	fi
	# Search specific products
	SEARCH="/var/log/samba/cores/smbd/ /var/log/samba/cores/nmbd/"
	for i in $SEARCH
	do
		ls -l --time-style=long-iso ${i}/${COREFILE} ${i}/${COREFILE}\.* ${i}/core ${i}/core\.* >> $SEARCH_LIST 2>/dev/null
	done
	# Search $PATH
	SEARCH="$(echo $PATH | sed -e 's/:/ /g')"
	for i in $SEARCH
	do
		ls -l --time-style=long-iso ${i}/${COREFILE} ${i}/${COREFILE}\.* ${i}/core ${i}/core\.* >> $SEARCH_LIST 2>/dev/null
	done
	# Search ld.so.conf
	SEARCH="/lib /usr/lib /var/lib $(cat /etc/ld.so.conf | grep '^/')"
	for i in $SEARCH
	do
		ls -l --time-style=long-iso ${i}/${COREFILE} ${i}/${COREFILE}\.* ${i}/core ${i}/core\.* >> $SEARCH_LIST 2>/dev/null
	done
	# Search ld.so.conf includes
	LDINCLUDES=$(grep -i ^include /etc/ld.so.conf | awk '{print $2}')
	if [ -n "$LDINCLUDES" ]; then
		SEARCH=$(cat $LDINCLUDES 2>/dev/null)
		for i in $SEARCH
		do
			ls -l --time-style=long-iso ${i}/${COREFILE} ${i}/${COREFILE}\.* ${i}/core ${i}/core\.* >> $SEARCH_LIST 2>/dev/null
		done
	fi

	# include the core file list found
	cat $SEARCH_LIST | sort -k 9 | uniq | sed -e 's|//|/|g' > ${SEARCH_LIST}_U
	cat ${SEARCH_LIST}_U >> $LOG/$OF
	if [ -s ${SEARCH_LIST}_U ]; then
		FILES=$(cat ${SEARCH_LIST}_U | awk '{print $NF}')
	else
		FILES=""
	fi
	rm -f $SEARCH_LIST ${SEARCH_LIST}_U
	log_write $OF
	# determine the which app generated the core files found
	if [ -n "$FILES" ]; then
		log_cmd $OF "file $FILES"
	fi

	CHKBIN_PREFIX=$ARCHIVE_PREFIX

	for i in $(ls -1 /var/log/${CHKBIN_PREFIX}chkbin* 2>/dev/null)
	do
		log_write $OF "#==[ chkbin Logs ]==========================#"
		log_write $OF "# $i"
		cat $i >> $LOG/$OF
		log_write $OF
	done
	_sanitize_file $OF
	echolog Done
}

autofs_info() {
printlog "AUTOFS..."
	test $OPTION_AUTOFS -eq 0 && { echolog Excluded; return 1; }
	OF=fs-autofs.txt
	addHeaderFile $OF
	if rpm_verify $OF autofs || rpm_verify $OF autofs4 || rpm_verify $OF autofs5
	then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status autofs.service"
		else
			check_service $OF autofs
		fi
		[[ -x /usr/bin/findmnt ]] && log_cmd $OF "findmnt" || log_cmd $OF "mount"
		log_cmd $OF 'ps aux | grep automount | grep -v grep'
		conf_files $OF /etc/sysconfig/autofs
		log_cmd $OF 'grep ^automount: /etc/nsswitch.conf'
		for SCHEME in $(grep ^automount: /etc/nsswitch.conf | sed -e 's/^.*:[ \t]*//')
		do
			log_write $OF "#--[ Automount Scheme: $SCHEME ]--#"
			case "$SCHEME" in
			files)
				if [ -f /etc/auto.master ]; then
					AFSMAPS=$(cat /etc/auto.master | grep -v ^# | awk '{print $2}' | cut -d\: -f2)
					FILES=''
					for MAP in $AFSMAPS
					do
						if [ -e $MAP ]; then
							FILES="$FILES $MAP"
						elif [ -e /etc/$MAP ]; then
							FILES="$FILES /etc/$MAP"
						else
							FILES="$FILES $MAP"
						fi
					done
					conf_files $OF /etc/auto.master $FILES
				else
					log_write $OF "Missing /etc/auto.master"
					log_write $OF
				fi
				;;
			nis)
				if log_cmd $OF "ypcat -k auto.master"; then
					FILES=$(ypcat -k auto.master | grep -v ^# | awk '{print $2}' | cut -d\: -f2)
					for MAP in $FILES
					do
						log_cmd $OF "ypcat -k $MAP"
					done
				fi
				;;
			nisplus)
				log_cmd $OF "niscat -k auto_master.org_dir"
				;;
			ldap)
				conf_files $OF /etc/autofs_ldap_auth.conf
				log_cmd $OF "ldapsearch -x \"(&(objectclass=automountMap))\""
				log_cmd $OF "ldapsearch -x \"(&(objectclass=automount))\""
				log_cmd $OF "ldapsearch -x \"(&(objectclass=nisMap))\""
				log_cmd $OF "ldapsearch -x \"(&(objectclass=nisObject))\""
				;;
			esac
		done
		FILES="/var/log/messages"
		test $ADD_OPTION_LOGS -gt 0 && grep_log_files automount $OF 0 $FILES || grep_log_files automount $OF $VAR_OPTION_LINE_COUNT $FILES
		_sanitize_file $OF
		echolog Done
	else
		echolog Skipped
	fi
}

get_sles_ver() {
	KERNMAJ=$(uname -r | cut -d- -f1)
	KERNREL=$(uname -r | cut -d- -f2)
	KERNCNT=$(echo $KERNMAJ | sed -e 's/\./ /g' | wc -w)
	test $KERNCNT -lt 4 && KERNMAJ="${KERNMAJ}.0"
	KERNCNT=$(echo $KERNREL | sed -e 's/\./ /g' | wc -w)
	if [ $KERNCNT -eq 2 ]; then
		KERNREL="${KERNREL}.0"
	elif [ $KERNCNT -eq 1 ]; then
		KERNREL="${KERNREL}.0.0"
	fi
	KERNBASE="${KERNMAJ}.${KERNREL}"
	KERNVER=$(echo $KERNBASE | awk -F\. '{printf "%g%02g%03g%02g%03g%03g%03g\n", $1, $2, $3, $4, $5, $6, $7}')
	if   [ $KERNVER -ge 31200900001000000 ]; then SLES_VER=120;
#	elif [ $KERNVER -ge 30010100054002000 ]; then SLES_VER=114;
	elif [ $KERNVER -ge 30007600000011000 ]; then SLES_VER=113;
	elif [ $KERNVER -ge 30001300000027000 ]; then SLES_VER=112;
	elif [ $KERNVER -ge 20603212000007000 ]; then SLES_VER=111;
	elif [ $KERNVER -ge 20602719005000000 ]; then SLES_VER=110;
	elif [ $KERNVER -ge 20601660000085001 ]; then SLES_VER=104;
	elif [ $KERNVER -ge 20601660000054005 ]; then SLES_VER=103;
	elif [ $KERNVER -ge 20601660000021000 ]; then SLES_VER=102;
	elif [ $KERNVER -ge 20601646000012000 ]; then SLES_VER=101;
	elif [ $KERNVER -ge 20601621000008000 ]; then SLES_VER=100;
	elif [ $KERNVER -ge 20600500007097000 ]; then SLES_VER=90;
	elif [ $KERNVER -ge 20401900120000000 ]; then SLES_VER=80;
	else SLES_VER=90;
	fi
}

rpm_full_verify() {
	OF=rpm-verify.txt
	OFTMP=$LOG/$RPM_QA_FILE
	if [ $ADD_OPTION_RPMV -eq 1 ]; then
		printlog -b "Full RPM Verification..."
		addHeaderFile $OF
		STARTCNT=1
		ENDCNT=$(cat $OFTMP | wc -l)
		for RPMNAME in $(cat $OFTMP)
		do
			if (( $VAR_OPTION_SBM )); then
				log_cmd $OF "rpm -V $RPMNAME"
			else
				printvrpmlog $RPMNAME "$((STARTCNT++)) of $ENDCNT"
				log_cmd $OF "rpm -V $RPMNAME"
			fi
			echolog Done
		done
		rm -f $OFTMP
	fi
}

xen_info() {
	printlog "Xen..."
	test $OPTION_XEN -eq 0 && { echolog Excluded; return 1; }
	OF=xen.txt
	addHeaderFile $OF
	if rpm_verify $OF xen
	then
		XEN_FILES='/etc/sysconfig/xendomains'
		LIBVIRT_FILES='/etc/libvirt/libvirtd.conf /etc/libvirt/libxl.conf /etc/libvirt/libxl-lockd.conf /etc/libvirt/virtlockd.conf'
		# libvirt is recommended, but not required
		if (checkproc /usr/sbin/libvirtd) && [ -x /usr/bin/virsh ]; then
			LIBVIRT=1
		fi
		if [ -x '/usr/sbin/xend' ] && /usr/sbin/xend status; then
			XL_XM='/usr/sbin/xm'
			XEN_SVCS='xend xencommons xendomains xen-watchdog'
			XEN_FILES="/etc/xen/xend-config.sxp $XEN_FILES $LIBVIRT_FILES"
		else
			XL=1
			XL_XM='/usr/sbin/xl'
			XEN_SVCS='xencommons xendomains xen-watchdog'
			XEN_FILES="/etc/xen/xl.conf $XEN_FILES $LIBVIRT_FILES"
		fi
		rpm_verify $OF xen-tools
		rpm_verify $OF xen-libs
		rpm_verify $OF libvirt
		log_cmd $OF "sed -e '1,/{VERSION}/d' -e '/=====/,\$d' $RPMPATH | egrep \"libvirt|qemu|vmdp|xen\""
		log_cmd $OF 'uname -r'
		for SVC in $XEN_SVCS
		do
			check_service $OF $SVC
		done
		log_cmd $OF 'grep ^NETWORKMANAGER /etc/sysconfig/network/config'
		log_write $OF "NOTE: NETWORKMANAGER should be set to \"no\" for Xen"
		log_write $OF
		log_cmd $OF 'lscpu'
		case $LOADER_TYPE in
		grub)
			GRUB_CONF='/boot/grub/menu.lst'
			;;
		grub2)
			# customizations should not be in /boot/grub2/grub.cfg,
			# so just get the editable config file
			GRUB_CONF='/etc/default/grub'
			;;
		esac
		conf_files $OF "$GRUB_CONF $XEN_FILES"
		log_cmd $OF "$XL_XM info"
		log_cmd $OF "$XL_XM list"
		if (( LIBVIRT )); then
			log_cmd $OF 'virsh list'
		fi
		log_cmd $OF "$XL_XM vcpu-list"
		log_cmd $OF 'ls -alR /etc/xen/vm/'
		log_cmd $OF 'ls -alR /etc/xen/images/'


		test -d /etc/xen/vm && FILES=$(find -L /etc/xen/vm/ -type f | sort) || FILES=""
		conf_text_files $OF $FILES
		if (( LIBVIRT )); then
			for XENDOM in $(virsh list --all | grep "[[:space:]]*[[:digit:]]" | awk '{print $2}')
			do
				log_cmd $OF "virsh dumpxml $XENDOM"
			done
		fi
		log_cmd $OF "$XL_XM list -l"
		test -d /var/lib/xend/domains && FILES=$(find -L /var/lib/xend/domains/ -type f | grep config.sxp) || FILES=""
		conf_text_files $OF $FILES

		log_cmd $OF 'ip route list'
		log_cmd $OF 'ip -6 route list'
		log_cmd $OF 'arp -v'
		unset NETCMD
		unset XSCRIPTS
		XCONF=/etc/xen/xend-config.sxp

		if [ -s $XCONF ]; then
			NETCMDLINE=$(grep '^(network\-script' $XCONF | sed -e 's/(//g;s/)//g')
			NETCMDTEST=$(echo $NETCMDLINE | awk '{print $2}')
			if [ -n "$NETCMDTEST" ]; then
				if echo $NETCMDTEST | grep \' &> /dev/null; then
					NETCMD="/etc/xen/scripts/`echo $NETCMDTEST | sed -e s/\'//g`"
				else
					NETCMD="/etc/xen/scripts/$NETCMDTEST"
				fi
			fi
			XSCRIPTS=$(grep '\-script' $XCONF 2>/dev/null | grep '^(' | awk '{print $2}' | sed -e "s/)//g;s/'//g")
			test -n "$NETCMD" && log_cmd $OF "$NETCMD status"
		fi
		if [ $MIN_OPTION_AUTOMOD -eq 0 ]; then
			log_write $OF "#==[ Warning ]======================================#"
			log_write $OF "# Autoloading kernel modules disabled. Don't use -k."
			log_write $OF "# Excluding Bridge command: brctl"
			log_write $OF
		else
			if log_cmd $OF 'brctl show'; then
				for BRIDGE in `brctl show | grep -v ^bridge | egrep "^[a-z]|^[A-Z]" | awk '{print $1}'` 
				do 
					log_cmd $OF "brctl showmacs $BRIDGE"
				done
			fi
		fi

		for XSCRIPT in $XSCRIPTS
		do
			conf_text_files $OF /etc/xen/scripts/$XSCRIPT
		done


		if [ $ADD_OPTION_LOGS -gt 0 ]; then
			test -d /root/.cache/virt-manager && FILES="$(find /root/.cache/virt-manager/ -type f)" || FILES=""
			test -d /var/log/xen && FILES="$FILES $(find /var/log/xen/ -type f | sort)"
			test -d /var/log/libvirt && FILES="$FILES $(find /var/log/libvirt/ -name libvirtd.log* -type f | sort)"
			test -d /var/log/libvirt/libxl && FILES="$FILES $(find /var/log/libvirt/libxl/ -type f | sort)"
		else
			test -d /root/.cache/virt-manager && FILES=/root/.cache/virt-manager/virt-manager.log || FILES=""
			test -d /var/log/xen && FILES="$FILES $(find /var/log/xen/ -type f | grep 'log$' | sort)"
			test -d /var/log/libvirt && FILES="$FILES $(find /var/log/libvirt/ -name libvirtd.log -type f)"
			test -d /var/log/libvirt/libxl && FILES="$FILES $(find /var/log/libvirt/libxl/ -type f | grep 'log$' | sort)"
		fi
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES


		log_cmd $OF "$XL_XM dmesg"
		echolog Done
	else
		echolog Skipped
	fi
}

kvm_info() {
	printlog "KVM..."
	test $OPTION_KVM -eq 0 && { echolog Excluded; return 1; }
	OF=kvm.txt
	addHeaderFile $OF
	KVM=0
	for KVM_RPM in kvm qemu-kvm
	do
		rpm_verify $OF $KVM_RPM && KVM=1
	done
	if (( KVM ))
	then
		rpm_verify $OF libvirt
		rpm_verify $OF virt-manager
		log_cmd $OF "sed -e '1,/{VERSION}/d' -e '/=====/,\$d' $RPMPATH | egrep \"kvm|libvirt|virt-manager\""
		log_cmd $OF 'uname -r'
		check_service $OF libvirtd
		log_cmd $OF 'grep ^NETWORKMANAGER /etc/sysconfig/network/config'
		log_write $OF "NOTE: NETWORKMANAGER should be set to \"no\" for KVM"
		log_write $OF
		log_cmd $OF 'lscpu'
		log_cmd $OF 'kvm_stat -1'
		conf_files $OF '/etc/libvirt/libvirtd.conf /etc/libvirt/qemu-lockd.conf /etc/libvirt/virtlockd.conf'

		log_cmd $OF 'lsmod | grep ^kvm'

		for MODULE in `lsmod | grep ^kvm | cut -d ' ' -f 1`
		do
			log_cmd $OF "modinfo $MODULE"
		done

		if (checkproc /usr/sbin/libvirtd) && [ -x /usr/bin/virsh ]; then
			log_cmd $OF "virsh version"
			log_cmd $OF "virsh capabilities"
			log_cmd $OF "virsh nodeinfo"
			log_cmd $OF "virsh nodedev-list"
			log_cmd $OF "virsh list --all"
			for KVMDOM in $(virsh list | grep "[[:space:]]*[[:digit:]]" | awk '{print $2}')
			do
				log_cmd $OF "virsh vcpuinfo $KVMDOM"
				log_cmd $OF "virsh dominfo $KVMDOM"
				log_cmd $OF "virsh domjobinfo $KVMDOM"
				log_cmd $OF "virsh dommemstat $KVMDOM"
				log_cmd $OF "virsh dumpxml $KVMDOM"
				log_cmd $OF "virsh snapshot-list $KVMDOM"
			done

			for KVMDOM in $(virsh list --all | grep "[[:space:]]*-" | awk '{print $2}')
			do
				log_cmd $OF "virsh dominfo $KVMDOM"
				log_cmd $OF "virsh snapshot-list $KVMDOM"
			done
		fi

		log_cmd $OF 'ls -alR /etc/libvirt/qemu/'
		log_cmd $OF 'ls -alR /var/lib/kvm/images/'


		test -d /etc/libvirt/qemu/ && FILES=$(find -L /etc/libvirt/qemu/ -type f | sort) || FILES=""
		conf_text_files $OF $FILES

		log_cmd $OF 'ip route list'
		log_cmd $OF 'ip -6 route list'
		log_cmd $OF 'arp -v'

		if [ $MIN_OPTION_AUTOMOD -eq 0 ]; then
			log_write $OF "#==[ Warning ]======================================#"
			log_write $OF "# Autoloading kernel modules disabled. Don't use -k."
			log_write $OF "# Excluding Bridge command: brctl"
			log_write $OF
		else
			if log_cmd $OF 'brctl show'; then
				for BRIDGE in `brctl show | grep -v ^bridge | egrep "^[a-z]|^[A-Z]" | awk '{print $1}'`
				do
					log_cmd $OF "brctl showmacs $BRIDGE"
				done
			fi
		fi

		if [ $ADD_OPTION_LOGS -gt 0 ]; then
			test -d /root/.cache/virt-manager && FILES="$(find /root/.cache/virt-manager/ -type f)" || FILES=""
			test -d /var/log/libvirt && FILES="$FILES $(find /var/log/libvirt/ -name libvirtd.log* -type f | sort)"
			test -d /var/log/libvirt/qemu && FILES="$FILES $(find /var/log/libvirt/qemu/ -type f | sort)"
		else
			test -d /root/.cache/virt-manager && FILES=/root/.cache/virt-manager/virt-manager.log || FILES=""
			test -d /var/log/libvirt && FILES="$FILES $(find /var/log/libvirt/ -name libvirtd.log -type f)"
			test -d /var/log/libvirt/qemu && FILES="$FILES $(find /var/log/libvirt/qemu/ -type f | grep 'log$' | sort)"
		fi
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES

		echolog Done
	else
		echolog Skipped
	fi
}

lxc_info() {
	printlog "LXC..."
	test $OPTION_LXC -eq 0 && { echolog Excluded; return 1; }
	OF=lxc.txt
	addHeaderFile $OF
	LXC=0
	LIBVIRT_LXC=0
	rpm_verify $OF lxc && LXC=1
	rpm_verify $OF libvirt-daemon-driver-lxc && LIBVIRT_LXC=1
	if (( LIBVIRT_LXC || LXC )); then
		if (( LIBVIRT_LXC )); then
			check_service $OF libvirtd
			conf_files $OF '/etc/libvirt/lxc.conf'
			conf_files $OF '/etc/libvirt/libvirtd.conf'

			if (checkproc /usr/sbin/libvirtd) && [ -x /usr/bin/virsh ]; then
				log_cmd $OF "virsh version"
				log_cmd $OF "virsh capabilities | sed -e '/guest/,/\/guest/{H;d;}' -e 'x;/libvirt_lxc/!d' | grep -v '^$'"
				log_cmd $OF "virsh nodeinfo"
				log_cmd $OF "virsh -c lxc:/// list --all"
				for LXCDOM in $(virsh -c lxc:/// list | grep "[[:space:]]*[[:digit:]]" | awk '{print $2}')
				do
					log_cmd $OF "virsh -c lxc:/// dominfo $LXCDOM"
					log_cmd $OF "virsh -c lxc:/// dumpxml $LXCDOM"
				done

				for LXCDOM in $(virsh -c lxc:/// list --all | grep "[[:space:]]-" | awk '{print $2}')
				do
					log_cmd $OF "virsh -c lxc:/// dominfo $LXCDOM"
					log_cmd $OF "virsh -c lxc:/// dumpxml $LXCDOM"
				done
			fi

			log_cmd $OF 'ls -alR /etc/libvirt/lxc/'


			test -d /etc/libvirt/lxc/ && FILES=$(find -L /etc/libvirt/lxc/ -type f | sort) || FILES=""
			conf_text_files $OF $FILES

			if [ $ADD_OPTION_LOGS -gt 0 ]; then
				test -d /root/.cache/virt-manager && FILES="$(find /root/.cache/virt-manager/ -type f)" || FILES=""
				test -d /var/log/libvirt && FILES="$FILES $(find /var/log/libvirt/ -name libvirtd.log* -type f | sort)"
				test -d /var/log/libvirt/lxc && FILES="$FILES $(find /var/log/libvirt/lxc/ -type f | sort)"
			else
				test -d /root/.cache/virt-manager && FILES=/root/.cache/virt-manager/virt-manager.log || FILES=""
				test -d /var/log/libvirt && FILES="$FILES $(find /var/log/libvirt/ -name libvirtd.log -type f)"
				test -d /var/log/libvirt/lxc && FILES="$FILES $(find /var/log/libvirt/lxc/ -type f | grep 'log$' | sort)"
			fi
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES

		elif (( LXC )); then
			check_service $OF lxc
			conf_file $OF '/etc/libvirt/lxc.conf'
			log_cmd $OF 'lxc-checkconfig | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"'
			log_cmd $OF 'lxc-ls'
			test -d /etc/lxc/ && FILES=$(find -L /etc/lxc/ -type f -name config | sort) || FILES=""
			conf_text_files $OF $FILES
		fi

		echolog Done
	else
		echolog Skipped
	fi
}

apparmor_info() {
	printlog "AppArmor..."
	test $OPTION_APPARMOR -eq 0 && { rm -f $AARPTMP &>/dev/null; echolog Excluded; return 1; }
	OF=security-apparmor.txt
	addHeaderFile $OF
	SKIP=0
	if rpm_verify $OF subdomain-parser
	then
			rpm_verify $OF subdomain-parser-common
			rpm_verify $OF subdomain-utils
			rpm_verify $OF subdomain-profiles
			test -f $AARPTMP && cat $AARPTMP >> $LOG/$OF
			check_service $OF boot.subdomain
			log_cmd $OF 'unconfined'
	else
		((SKIP++))
	fi

	if rpm_verify $OF apparmor-parser
	then
		rpm_verify $OF apparmor-utils
		rpm_verify $OF apparmor-profiles
		test -f $AARPTMP && cat $AARPTMP >> $LOG/$OF
		if [[ -x /etc/init.d/boot.apparmor ]]; then
			log_cmd $OF "/etc/init.d/boot.apparmor status"
		else
			log_cmd $OF "systemctl status apparmor.service"
		fi
		log_cmd $OF 'unconfined'
		log_cmd $OF 'aa-status'
		log_cmd $OF 'aa-notify -l'
		[[ /etc/apparmor ]] && FILES=$(find -L /etc/apparmor/ | grep '\.conf$') || FILES=""
		conf_files $OF $FILES
		log_files $OF 0 /var/log/audit/audit.log
	else
		((SKIP++))
	fi

	rm -f $AARPTMP &>/dev/null
	test $SKIP -lt 2 && echolog Done || echolog Skipped
}

ha_info() {
	printlog "HA Cluster..."
	test $OPTION_HA -eq 0 && { echolog Excluded; return 1; }
	OF=ha.txt
	addHeaderFile $OF
	if (( SLES_VER >= 110 )); then
		if rpm_verify $OF pacemaker
		then
			log_cmd $OF "rpm -qa | egrep 'ais|resource-agents|cluster-glue|corosync|csync2|pacemaker|heartbeat'"
			if (( SLES_VER >= 120 ))
			then
				log_cmd $OF "systemctl status pacemaker.service"
				CONF_FILES="/etc/corosync/corosync.conf /etc/sysconfig/ctdb /etc/sysconfig/sbd"
			else
				rpm_verify $OF openais
				check_service $OF openais
				CONF_FILES="/etc/ais/openais.conf /etc/corosync/corosync.conf /etc/ais/amf.conf /etc/sysconfig/ctdb /etc/sysconfig/sbd"
			fi
			if (( $SLES_VER >= 111 )); then
				(( SLES_VER < 120 )) && log_cmd $OF 'chkconfig -l csync2'
				if [ -s /etc/xinetd.d/csync2 ]; then
					TMPORT=$(grep -i port /etc/xinetd.d/csync2 | awk '{print $3}')
					log_cmd $OF "netstat -nlp | grep $TMPORT"
				fi
			fi
			log_cmd $OF 'ntpq -p'
			log_cmd $OF 'crm_mon -r -1'
			log_cmd $OF 'crm_mon -r -n -1'
			log_cmd $OF 'crm_mon -A -1'
			log_cmd $OF 'corosync-cfgtool -s'
			log_cmd $OF 'crm configure show'
			log_cmd $OF 'crm corosync status'
			conf_files $OF $CONF_FILES
			if [ -s /etc/sysconfig/sbd ]; then
				. /etc/sysconfig/sbd
				for SBD in $(echo $SBD_DEVICE | sed -e 's/;/ /g')
				do
					if timed_log_cmd $OF "sbd -d $SBD list"; then
						log_cmd $OF "sbd -d $SBD dump"
					fi
				done
			fi
			if (( SLES_VER >= 111 )); then
				log_cmd $OF 'ls -lR --time-style=long-iso /etc/csync2'
				conf_files $OF /etc/csync2/csync2.cfg /etc/xinetd.d/csync2
			fi
			CURRENT_PATH=$(pwd)
			cd $LOG
			for HBRDIR in $VAR_OPTION_HBREPORT_DIRS
			do
				HBRS=$(find $HBRDIR -maxdepth 1 -type f 2>/dev/null | egrep "/hb[_-]?report[0-9a-zA-Z._-]*\.tar\.bz2$")
				if [ -n "$HBRS" ]; then
					for HBR_PATH in $HBRS
					do
						HBR=$(basename $HBR_PATH)
						log_cmd $OF "tar jxf ${HBR_PATH}"
						conf_files $OF "$LOG/${HBR%%.tar.bz2}/analysis.txt"
					done
				fi
			done
			cd $CURRENT_PATH
			CURRENT_CIB=''
			FILES=''
			if [[ -d /var/lib/heartbeat/ ]]; then
				FILES=$(find -L /var/lib/heartbeat/ -type f | egrep -v "cores|pengine|hb_uuid|cib\.xml")
				[[ -e /var/lib/heartbeat/crm/cib.xml ]] && CURRENT_CIB='/var/lib/heartbeat/crm/cib.xml'
				for i in $(find -L /var/lib/heartbeat/cores -type f)
				do
					log_cmd $OF "file $i"
				done
			fi
			if [[ -d /var/lib/pacemaker/ ]]; then
				TFILES=$(find -L /var/lib/pacemaker/ -type f | egrep -v "cores|pengine|hb_uuid|cib\.xml")
				FILES="$FILES $TFILES"
				[[ -e /var/lib/pacemaker/cib/cib.xml ]] && CURRENT_CIB='/var/lib/pacemaker/cib/cib.xml'
			fi
			log_cmd $OF 'cibadmin -Q'
			conf_files $OF $CURRENT_CIB $FILES
			FILES="/var/log/ha-log /var/log/pacemaker.log /var/log/ctdb/log.ctdb"
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
			CORBIN="/usr/sbin/corosync-fplay"
			if [ -x $CORBIN ]; then
				CLN=$($CORBIN 2>/dev/null | wc -l)
				if [ $CLN -gt 1000 ]; then
					log_cmd $OF 'corosync-fplay | head -500'
					log_cmd $OF 'corosync-fplay | tail -500'
				else
					log_cmd $OF 'corosync-fplay'
				fi
			fi
			echolog Done
		else
			echolog Skipped
		fi
	else
		if rpm_verify $OF heartbeat
		then
			check_service $OF heartbeat
			log_cmd $OF 'cl_status hbstatus'
			conf_files $OF /etc/ha.d/ha.cf /etc/ha.d/haresources
			log_cmd $OF 'ls -l --time-style=long-iso /etc/ha.d/authkeys/'
			log_cmd $OF 'ntpq -p'
			CHECKDIR="/var/lib/heartbeat/pengine"
			HALOG="$LOG/ha-pengine"
			if [ -d $CHECKDIR ]; then
				FOUND=$(find -L ${CHECKDIR}/ -type f)
				if [ -n "$FOUND" ]; then
					mkdir -p $HALOG
					log_write $OF "#==[ Command ]======================================#"
					if [ $ADD_OPTION_LOGS -gt 0 ]; then
						log_write $OF "# cp -a $CHECKDIR $HALOG"
						cp -a $CHECKDIR/* $HALOG &>/dev/null
					else
						log_write $OF "# cp $CHECKDIR $HALOG"
						log_write $OF "# NOTE: Only the newest $VAR_OPTION_PENGINE_FILES_LIMIT files are copied"
						for i in $(\ls -rA1t $CHECKDIR | tail -${VAR_OPTION_PENGINE_FILES_LIMIT})
						do
							cp ${CHECKDIR}/${i} $HALOG &>/dev/null
						done
					fi
					log_write $OF
				fi
			fi
			if cl_status hbstatus &>/dev/null
			then
				test $SLES_VER -ge 100 && log_cmd $OF 'crm_mon -r -1'
				log_cmd $OF 'cl_status listnodes'
				log_cmd $OF 'cl_status rscstatus'
				for HBNODE in $(cl_status listnodes 2>/dev/null)
				do
					log_cmd $OF "cl_status listhblinks $HBNODE"
					for HBLINK in $(cl_status listhblinks $HBNODE 2>/dev/null)
					do
						log_cmd $OF "cl_status hblinkstatus $HBNODE $HBLINK"
					done
				done
			fi
			test -d /var/lib/heartbeat && FILES=$(find -L /var/lib/heartbeat/ -type f | egrep -v "cores|pengine|hb_uuid") || FILES=""
			conf_files $OF /etc/ha_logd.cf $FILES
			test $SLES_VER -ge 100 && log_cmd $OF 'cibadmin -Q'
			FILES="/var/log/ha-log"
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
			echolog Done
		else
			echolog Skipped
		fi
	fi
}

slp_info() {
	printlog "SLP..."
	test $OPTION_SLP -eq 0 && { echolog Excluded; return 1; }
	OF=slp.txt
	addHeaderFile $OF
	if rpm_verify $OF openslp-server
	then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status slpd.service"
		else
			check_service $OF slpd
		fi
	fi
	if rpm_verify $OF openslp
	then
		conf_files $OF /etc/slp.conf
		if [ -s /etc/slp.conf ]; then
			IPADDRS=$(grep -i '^net.slp.DAAddresses' /etc/slp.conf | sed -e "s/[[:space:]]+//g;s/\'//g;s/\"//g" | cut -d= -f2 | sed -e "s/,/ /g")
			for IPADDR in $IPADDRS
			do
				ping_addr $OF 'SLP DA' $IPADDR
			done
		fi
		conf_files $OF /etc/slp.reg /etc/slp.spi
		if [ -d /etc/slp.reg.d ]; then
			FILES=$(find -L /etc/slp.reg.d/ -type f)
			conf_files $OF $FILES
		fi
		log_cmd $OF 'slptool findscopes'
		if [ $ADD_OPTION_SLP -gt 0 ]; then
			echonlog "Please Wait..."
			if log_cmd $OF 'slptool findsrvtypes'
			then
				echonlog Services
				STATE=0
				SRV_TYPES=''
				while read LINE
				do
					if [ $STATE -gt 0 ]; then
						SRV_TYPES="$SRV_TYPES $LINE"
					elif echo $LINE | grep findsrvtypes &>/dev/null; then
						STATE=1
					fi
				done < ${LOG}/${OF}
				for SERVICE in $SRV_TYPES
				do
					log_cmd $OF "slptool findsrvs $SERVICE"
				done
			fi
		else
			log_write $OF "ERROR: Unable to get full SLP service lists, check 'slptool findsrvtypes'"
		fi
	fi
	echolog Done
	FILES="/var/log/slpd.log"
	test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
}

ocfs2_info() {
	printlog "OCFS2..."
	test $OPTION_OCFS2 -eq 0 && { echolog Excluded; return 1; }
	OF=ocfs2.txt
	OCFS2_MODULES=0
	addHeaderFile $OF
	if rpm_verify $OF ocfs2-tools
	then
		if lsmod | grep ocfs2_stack_user[[:space:]] &>/dev/null && lsmod | grep ocfs2[[:space:]] &>/dev/null
		then
			OCFS2_MODULES=1
		fi
		case $SLES_VER in
		8*|9*|10*)
			check_service $OF o2cb
			check_service $OF ocfs2
			[[ -x /usr/bin/findmnt ]] && log_cmd $OF "findmnt" || log_cmd $OF "mount"
			timed_log_cmd $OF "mounted.ocfs2 -d"
			timed_log_cmd $OF "mounted.ocfs2 -f"
			conf_files $OF "/etc/ocfs2/cluster.conf /etc/sysconfig/o2cb"
			;;
		11*|12*)
			[[ -x /usr/bin/findmnt ]] && log_cmd $OF "findmnt" || log_cmd $OF "mount"
			(( OCFS2_MODULES )) && timed_log_cmd $OF "mounted.ocfs2 -d"
			(( OCFS2_MODULES )) && timed_log_cmd $OF "mounted.ocfs2 -f"
			log_cmd $OF "ps aux | grep ocfs2 | grep -v grep"
			log_cmd $OF "lsmod | grep ocfs2"
			;;
		esac
		CHECKDIR="/sys/o2cb"
		if [ -d $CHECKDIR ]; then
			FILES=$(find -L ${CHECKDIR}/ -type f)
			conf_files $OF $FILES
		fi
		CHECKDIR="/sys/kernel/config/cluster"
		if [ -d $CHECKDIR ]; then
			FILES=$(find -L ${CHECKDIR}/ -type f)
			conf_files $OF $FILES
		fi
		(( OCFS2_MODULES )) && DEVICES=$(/sbin/mounted.ocfs2 -d | grep ^/ | awk '{ print $1}') || DEVICES=''
		log_entry $OF x "OCFS2 Devices"
		log_write $OF $DEVICES
		log_write $OF
		if [[ -n "$DEVICES" ]]; then
			O2C=$(mktemp $LOG/ocfs2_commands.XXXXXXXX)
			for DEVICE in $DEVICES
			do
				log_entry $OF note "OCFS2 Superblock Info on Device $DEVICE"
				echo 'stats' > $O2C
				wait_trace_on "debugfs.ocfs2 -n -f $O2C $DEVICE"
				SLOTS=$(debugfs.ocfs2 -n -f $O2C $DEVICE | awk '/Max Node Slots:/ { print $4 }')
				wait_trace_off
				for CMD in 'stats' 'stat //global_bitmap' 'slotmap' 'stat //slot_map' 'stat //heartbeat'
				do
					echo $CMD > $O2C
					wait_trace_on "debugfs.ocfs2 -n -R \"$CMD\" $DEVICE"
					log_entry $OF command "debugfs.ocfs2 -n -R \"$CMD\" $DEVICE"
					debugfs.ocfs2 -n -f $O2C $DEVICE >> $LOG/$OF 2>&1
					log_write $OF
					wait_trace_off
				done
				log_entry $OF note "SLOT Details for $SLOTS Slots on $DEVICE"
				for SLOT in $(seq --format="%04g" 0 $[${SLOTS}-1])
				do
					for CMDEL in inode_alloc extent_alloc local_alloc truncate_log journal orphan_dir
					do
						CMD="stat //${CMDEL}:${SLOT}"
						wait_trace_on "debugfs.ocfs2 -n -R \"$CMD\" $DEVICE"
						echo $CMD > $O2C
						log_entry $OF command "debugfs.ocfs2 -n -R \"$CMD\" $DEVICE"
						debugfs.ocfs2 -n -f $O2C $DEVICE >> $LOG/$OF 2>&1
						log_write $OF
						wait_trace_off
					done
				done
			done
			rm -f $O2C
		fi
		FILES="/var/log/messages"
		test $ADD_OPTION_LOGS -gt 0 && grep_log_files ocfs $OF 0 $FILES || grep_log_files ocfs $OF $VAR_OPTION_LINE_COUNT $FILES
		echolog Done
	else
		echolog Skipped
	fi
}

drbd_info() {
	printlog "DRBD..."
	test $OPTION_DRBD -eq 0 && { echolog Excluded; return 1; }
	OF=drbd.txt
	addHeaderFile $OF
	if [[ -s /etc/drbd.conf ]]
	then
		rpm_verify $OF drbd
		check_service $OF drbd
		log_cmd $OF "egrep \"drbd\" $RPMPATH"
		log_write $OF
		log_cmd $OF "lsmod | grep drbd"
		log_cmd $OF "modinfo drbd"
		log_cmd $OF "drbd-overview"
		log_cmd $OF "drbdadm status" 
		log_cmd $OF "drbdadm dump"
		log_cmd $OF "cat /proc/drbd"
		log_cmd $OF "ps aux | grep drbd | grep -v grep"
		[[ -x /usr/bin/findmnt ]] && log_cmd $OF "findmnt" || log_cmd $OF "mount"
		(( $IO_DELAYS )) || log_cmd $OF "df -h"
		if [[ -s /etc/drbd.conf ]]; then
			DIRLIST=$(cat /etc/drbd.conf | grep ^include | cut -d\" -f2 | sed 's!\(.*\)/.*!\1/!' | sort | uniq)
			FILES=''
			for DIR in $DIRLIST
			do
				# We need to add "/etc/" since $DIR will have dir inside /etc/ 
				# However this find will find all files inside a specific folder It's okay
				# Will end up with /etc/drbd.conf/nfs.res nfs.RES nfs.stop .... 
				[[ -d "/etc/$DIR" ]] && FILES="$FILES $(find -L \"/etc/$DIR\" -type f)"
				[[ -d $DIR ]] && FILES="$FILES $(find -L $DIR -type f)"
			done
			conf_files $OF "/etc/drbd.conf $FILES"
		fi
		FILES="/var/log/messages"
		test $ADD_OPTION_LOGS -gt 0 && grep_log_files drbd $OF 0 $FILES || grep_log_files drbd $OF $VAR_OPTION_LINE_COUNT $FILES
		echolog Done
	else
		echolog Skipped
	fi
}

haproxy_info() {
	printlog "HAPROXY..."
	test $OPTION_HAPROXY -eq 0 && { echolog Excluded; return 1; }
	OF=haproxy.txt
	addHeaderFile $OF
	if [[ -s /etc/haproxy/haproxy.cfg ]]
	then
		rpm_verify $OF haproxy
		check_service $OF haproxy
		log_cmd $OF "egrep \"haproxy\" $RPMPATH"
		log_write $OF
		log_cmd $OF "ps aux | grep haproxy | grep -v grep"
		conf_files $OF "/etc/haproxy/haproxy.cfg"
		FILES="/var/log/messages"
		test $ADD_OPTION_LOGS -gt 0 && grep_log_files haproxy $OF 0 $FILES || grep_log_files haproxy $OF $VAR_OPTION_LINE_COUNT $FILES
		echolog Done
	else
		echolog Skipped
	fi
}

root_shell_history_info() {
	printlog "Command History..."
	test $OPTION_HISTORY -eq 0 && { echolog Excluded; return 1; }
	OF=shell_history.txt
	addHeaderFile $OF
	log_icmd $OF "history"
	echolog Done
}

memory_info() {
	printlog "Memory Details..."
	test $OPTION_MEM -eq 0 && { echolog Excluded; return 1; }
	OF=memory.txt
	addHeaderFile $OF
	log_cmd $OF "vmstat 1 4"
	log_cmd $OF "free -h"
	conf_files $OF /proc/meminfo /proc/vmstat
	log_cmd $OF 'sysctl -a 2>/dev/null | grep ^vm'
	[ -d /sys/kernel/mm/transparent_hugepage/ ] && FILES=$(find /sys/kernel/mm/transparent_hugepage/ -type f) || FILES=''
	conf_files $OF /proc/buddyinfo /proc/slabinfo /proc/zoneinfo $FILES
	if rpm -q numactl &>/dev/null; then
		log_cmd $OF 'numactl --hardware'
		log_cmd $OF 'numastat'
	fi
	if [ -x /usr/bin/pmap ]; then
		for I in $(ps axo pid)
		do
			log_cmd $OF "pmap $I"
		done
	fi
	echolog Done
}

open_files() {
	printlog "Open Files..."
	test $OPTION_OFILES -eq 0 && { echolog Excluded; return 1; }
	OF=$LSOF_FILE
	addHeaderFile $OF
	if rpm_verify $OF lsof
	then
		log_cmd $OF "lsof -b +M -n -l +fg -P 2>/dev/null"
		echolog Done
	else
		echolog Skipped
	fi
}

samba_info() {
	printlog "Samba..."
	test $OPTION_SMB -eq 0 && { echolog Excluded; return 1; }
	OF=samba.txt
	RPMPATH=$LOG/$RPMFILE
	addHeaderFile $OF

	log_cmd $OF "egrep \"samba|smb|cifs|libtallo|libtdb|libwbclient\" $RPMPATH"
	log_write $OF

	if rpm_verify $OF samba
	then
		for SERVICE in smb nmb
		do
			if (( SLES_VER >= 120 ))
			then
				log_cmd $OF "systemctl status ${SERVICE}.service"
			else
				check_service $OF ${SERVICE}
			fi
		done
		SAMBA_LIB="/var/lib/samba"
		SAMBA_KRB="$SAMBA_LIB/smb_krb5"
		if [ -d $SAMBA_LIB ]; then
			log_cmd $OF "ls -al $SAMBA_LIB"
			conf_files $OF $SAMBA_LIB/browse.dat $SAMBA_LIB/wins.dat
		fi
		if [ -d $SAMBA_KRB ]; then
			conf_files $OF /etc/krb5.conf ${SAMBA_KRB}/* 
		fi
	fi

	if rpm_verify $OF samba-client
	then
		conf_files $OF /etc/samba/smb.conf
		log_cmd $OF "testparm -sv"
		log_cmd $OF "pdbedit -L"
	fi

	if rpm_verify $OF samba-winbind
	then
		for SERVICE in winbind
		do
			if (( SLES_VER >= 120 ))
			then
				log_cmd $OF "systemctl status ${SERVICE}.service"
			else
				check_service $OF ${SERVICE}
			fi
		done
		log_cmd $OF 'wbinfo -u'
		log_cmd $OF 'wbinfo -g'
		log_cmd $OF 'wbinfo -p'
		log_cmd $OF 'wbinfo --own-domain'
		log_cmd $OF 'wbinfo --trusted-domains'
		log_cmd $OF 'wbinfo --check-secret'
		conf_files $OF /etc/samba/lmhosts /etc/nsswitch.conf /etc/security/pam_winbind.conf
	fi

	if [ -d /var/log/samba ]; then
		FILES=$(find -L /var/log/samba/ -type f | grep -v '/core')
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
	fi
	
	echolog Done
}

fslist_info() {
	printlog "File System List..."
	test $ADD_OPTION_FSLIST -eq 0 && { echolog Skipped; return 1; }
	echonlog "Please Wait..."
	OF=$FSLIST_FILE
	addHeaderFile $OF
	log_cmd $OF 'find / -path /.snapshots -prune -o -print'
	echolog Done
}

fslist_ufiles_info() {
	printlog "Additional Files List..."
	test $OPTION_UFILES -eq 0 && { echolog Skipped; return 1; }
	OF=fs-files-additional.txt
	addHeaderFile $OF
	UFUID=$(stat -c%u $FSLIST_ADD_FILE)
	conf_files $OF $FSLIST_ADD_FILE
	if [ "$UFUID" = "0" ]; then
		while read FILE
		do
			if [ -d "$FILE" ]; then
				log_write $OF "#==[ Directory ]====================================#"
				log_write $OF "# $FILE - Not a regular file"
				log_write $OF
			elif [ -e "$FILE" ]; then
				MIME1=$(file -Li "$FILE" | awk -F\: '{print $2}' | awk '{print $1}' | cut -d/ -f1)
				MIME2=$(file -Li "$FILE" | awk -F\: '{print $2}' | awk '{print $1}' | cut -d/ -f2)
				case $MIME1 in
				text) FILE=${FILE// /%7B%20%7D%7B%20%7D}; log_files $OF 0 "$FILE" ;;
				application)
					case $MIME2 in
					x-shellscript) FILE=${FILE// /%7B%20%7D%7B%20%7D}; log_files $OF 0 "$FILE" ;;
					x-perl) FILE=${FILE// /%7B%20%7D%7B%20%7D}; log_files $OF 0 "$FILE" ;;
					*) BFILE=$(basename "$FILE"); log_cmd $OF "uuencode -m \"$FILE\" \"$BFILE\"" ;;
					esac
					;;
				*) BFILE=$(basename "$FILE"); log_cmd $OF "uuencode -m \"$FILE\" \"$BFILE\"" ;;
				esac
			else
				FILE=${FILE// /%7B%20%7D%7B%20%7D}; log_files $OF 0 "$FILE"
			fi
		done < $FSLIST_ADD_FILE
		echolog Done
	else
		echolog Error
		log_write $OF "ERROR: Invalid owner for ${FSLIST_ADD_FILE}, must be owned by root"
	fi
}

smartmon_info() {
	printlog "SMART Disks..."
	test $OPTION_SMART -eq 0 && { echolog Excluded; return 1; }
	OF=fs-smartmon.txt
	addHeaderFile $OF
	if rpm_verify $OF smartmontools
	then
		check_service $OF smartd
		conf_files $OF /proc/partitions /etc/smartd.conf
		for DISK in $(cat /proc/partitions | grep -v ^m | grep -v ^$ | awk '{print $4}')
		do
			case $DISK in
			sd[a-z]|sd[a-z][a-z]) log_cmd smartmon-$DISK "smartctl --all /dev/$DISK" ;;
			hd[a-z]|hd[a-z][a-z]) log_cmd smartmon-$DISK "smartctl --all /dev/$DISK" ;;
			esac
		done
		log_write $OF "#==[ Quick Status Check ]===========================#"
		grep -i "^SMART overall" $LOG/smartmon-* | awk -F/ '{print $5}' >> $LOG/$OF
		log_write $OF 
		cat $LOG/smartmon-* >> $LOG/$OF
		rm -f $LOG/smartmon-*
		echolog Done
	else
		echolog Skipped
	fi
}

ldap_info() {
	printlog "LDAP..."
	test $OPTION_LDAP -eq 0 && { echolog Excluded; return 1; }
	OF=ldap.txt
	addHeaderFile $OF
	SKIP=0

	log_write $OF "#___________________________________________________________#"
	log_write $OF "#____[ LDAP Client Information ]____________________________#"
	log_write $OF
	if rpm_verify $OF pwdutils
	then
		conf_files $OF /etc/ldap.conf
		IPADDRS=$(grep -i '^uri[[:space:]]' /etc/ldap.conf | sed -e 's!uri[[:space:]]*!!g;s!ldap://!!g;s!ldaps://!!g;s!ldapi://[[:alnum:][:punct:]]*!!g')
		for I in $IPADDRS
		do
			IPADDR=$(echo $I | sed -e "s/:[[:digit:]]*//g")
			ping_addr $OF 'LDAP Server' $IPADDR
		done
		conf_files $OF /etc/nsswitch.conf /etc/sysconfig/ldap
	else
		((SKIP++))
	fi

	# Right now only openLDAP v2 is supported
	if rpm_verify $OF openldap2-client
	then
		LDAP_BIN="/usr/bin/ldapsearch"
		conf_files $OF /etc/openldap/ldap.conf
		IPADDRS=$(grep -i '^uri[[:space:]]' /etc/openldap/ldap.conf | sed -e 's!uri[[:space:]]*!!g;s!ldap://!!g;s!ldaps://!!g;s!ldapi://[[:alnum:][:punct:]]*!!g')
		for I in $IPADDRS
		do
			IPADDR=$(echo $I | sed -e "s/:[[:digit:]]*//g")
			ping_addr $OF 'LDAP Server' $IPADDR
		done
		log_write $OF "#==[ Search for LDAP Server's root DSE ]============#"
		if log_cmd $OF "$LDAP_BIN -x -b \"\" -s base \"objectclass=*\""; then
			log_write $OF "LDAP Connection: Success"
		else
			log_write $OF "LDAP Connection: FAILED"
		fi
		log_write $OF
	else
		((SKIP++))
	fi

	# Right now only openLDAP v2 is supported
	log_write $OF "#___________________________________________________________#"
	log_write $OF "#____[ LDAP Server Information ]____________________________#"
	log_write $OF
	if rpm_verify $OF openldap2
	then
		SLAPD_CONF="/etc/openldap/slapd.conf"
		# Extract the SLAPD directory from the conf file
		if [ -f $SLAPD_CONF ]; then
			SLAPD_DIR=$(grep -i ^directory $SLAPD_CONF | awk '{print $2}')
			test -z "$SLAPD_DIR" && SLAPD_DIR="/var/lib/ldap"
			SLAPD_PIDF=$(grep -i ^pidfile $SLAPD_CONF | awk '{print $2}')
			test -z "$SLAPD_PIDF" && SLAPD_PIDF="/var/run/slapd/slapd.pid"
			if [ -f $SLAPD_PIDF ]; then
				SLAPD_PID=$(cat $SLAPD_PIDF)
			else
				SLAPD_PID=""
			fi
			SLAPD_SCHEMAS=$(grep ^include $SLAPD_CONF | awk '{print $2}')
		fi
		check_service $OF ldap
		log_cmd $OF "netstat -nlp | grep slapd"
		log_cmd $OF "ls -al /etc/openldap/schema"
		conf_files $OF $SLAPD_CONF /etc/sysconfig/openldap
		if [ -d $SLAPD_DIR ]; then
			conf_files $OF $SLAPD_DIR/DB_CONFIG
			log_cmd $OF "ls -al $SLAPD_DIR"
		fi
		log_cmd $OF "lsof -b +M -n -l +fg -P -p $SLAPD_PID"
		log_write $OF "#___________________________________________________________#"
		log_write $OF "#____[ Schema Files Included in LDAP Server ]_______________#"
		log_write $OF
		log_write $OF "$SLAPD_SCHEMAS"
		log_write $OF
		conf_files $OF $SLAPD_SCHEMAS
	else
		((SKIP++))
	fi

	test $SKIP -lt 3 && echolog Done || echolog Skipped
}

etc_info() {
	printlog "ETC..."
	test $OPTION_ETC -eq 0 && { echolog Excluded; return 1; }
	OF=etc.txt
	addHeaderFile $OF
	conf_files $OF $(find -L /etc/ -type f | egrep "conf$|cfg$" | egrep -v "rhn/rhn.conf$")
	[ -d /etc/logrotate.d ] && conf_files $OF /etc/logrotate.d/*
	conf_files $OF /etc/rc.dialout /etc/ppp/options /etc/ppp/ioptions /etc/ppp/peers/pppoe
        _sanitize_file $OF
	echolog Done
}

sysconfig_info() {
	printlog "SYSCONFIG..."
	test $OPTION_SYSCONFIG -eq 0 && { echolog Excluded; return 1; }
	OF=sysconfig.txt
	addHeaderFile $OF
	for FILE in $(find -L /etc/sysconfig/ -maxdepth 1 -type f | sort -f)
	do
		conf_files $OF $FILE
	done
	for FDIR in $(find -L /etc/sysconfig/ -maxdepth 1 -type d | grep -v "/etc/sysconfig/$" | sort)
	do
		for FILE in $(find -L ${FDIR}/ -type f | sort)
		do
			conf_files $OF $FILE
		done
	done
	_sanitize_file $OF
	echolog Done
}

proc_info() {
	printlog "PROC..."
	test $OPTION_PROC -eq 0 && { echolog Excluded; return 1; }
	OF=proc.txt
	addHeaderFile $OF

	if (( SLES_VER >= 120 )); then
		# Check process name space against the default name space
		log_write $OF "#==[ Processes with a Different Default Name Space ]==#"
		log_write $OF "# name_space : process_id : command"
		NS_IPC_DEFAULT="$(readlink /proc/1/ns/ipc | sed 's/\[/\\[/;s/\]/\\]/')"
		NS_NET_DEFAULT="$(readlink /proc/1/ns/net | sed 's/\[/\\[/;s/\]/\\]/')"
		NS_PID_DEFAULT="$(readlink /proc/1/ns/pid | sed 's/\[/\\[/;s/\]/\\]/')"
		NS_UTS_DEFAULT="$(readlink /proc/1/ns/uts | sed 's/\[/\\[/;s/\]/\\]/')"
		for PID_PATH in /proc/[0-9]*
		do
			wait_trace_on "Compare $PID_PATH name space with the default"
			if [[ -e ${PID_PATH} ]]
			then
				CMD_LINE=$(cat ${PID_PATH}/cmdline 2>/dev/null | tr '\0' ' ')
				STATE=$(sed -n 's/^State:[[:blank:]]\+\([^[:blank:]]\)[[:blank:]]\+.*/\1/p' 2>/dev/null < ${PID_PATH}/status)
				PID=$(basename $PID_PATH)
				NS_IPC="$(readlink ${PID_PATH}/ns/ipc 2>/dev/null | sed 's/\[/\\[/;s/\]/\\]/')"
				NS_NET="$(readlink ${PID_PATH}/ns/net 2>/dev/null | sed 's/\[/\\[/;s/\]/\\]/')"
				NS_PID="$(readlink ${PID_PATH}/ns/pid 2>/dev/null | sed 's/\[/\\[/;s/\]/\\]/')"
				NS_UTS="$(readlink ${PID_PATH}/ns/uts 2>/dev/null | sed 's/\[/\\[/;s/\]/\\]/')"
				if [[ "$STATE" != "Z" || "$STATE" != "D" ]]
				then
					if [[ -n "$CMD_LINE" ]]
					then
						[[ "$NS_IPC_DEFAULT" != "$NS_IPC" ]] && log_write $OF "ipc : $PID : $CMD_LINE"
						[[ "$NS_NET_DEFAULT" != "$NS_NET" ]] && log_write $OF "net : $PID : $CMD_LINE"
						[[ "$NS_PID_DEFAULT" != "$NS_PID" ]] && log_write $OF "pid : $PID : $CMD_LINE"
						[[ "$NS_UTS_DEFAULT" != "$NS_UTS" ]] && log_write $OF "uts : $PID : $CMD_LINE"
					fi
				fi
			fi
			wait_trace_off
		done
		log_write $OF
	fi	

	FILES=$(find /proc/ -maxdepth 1 -type f 2>/dev/null | egrep -iv "kcore$|kpagecount$|kpageflags$|kpagecgroup$|vmcore$|config.gz$|kmsg$|sysrq-trigger$|kallsyms$|mm$|ssstm|pagetypeinfo$" | sort -f)
	conf_files $OF $FILES
	conf_files $OF /proc/mounts /proc/zoneinfo
	ADDPROCS="/proc/sys/kernel/ /proc/scsi/ /proc/net/ /proc/dasd/"
	for PROCDIR in $ADDPROCS
	do
		FILES=$(find $PROCDIR -maxdepth 1 -type f 2>/dev/null | egrep -iv "rt_acct$|/sched_domain/" | sort -f)
		conf_files $OF $FILES
	done
	FULLPROCS="/proc/irq/ /proc/sys/"
	FILTER="fs/binfmt_misc/register|net/ipv4/route/flush|net/ipv6/route/flush|vm/compact_memory|base_reachable_time|scan_unevictable_pages|/sched_domain/"
	for PROCDIR in $FULLPROCS
	do
		FILES=$(find $PROCDIR -type f 2>/dev/null | egrep -iv "$FILTER" | sort -f)
		conf_files $OF $FILES
	done
	# only include cpu0 sched_domain information, all others are excluded
	SCHED_DOMAIN='/proc/sys/kernel/sched_domain/cpu0'
	if [[ -d ${SCHED_DOMAIN} ]]; then
		FILES=$(find ${SCHED_DOMAIN} -type f 2>/dev/null | sort -f)
		conf_files $OF $FILES
	fi
	echolog Done
}

drm_sub_info() {
    log_cmd $OF 'systool -vc drm'
    log_cmd $OF 'ls -lR --time-style=long-iso /sys/class/drm'
    log_cmd $OF 'modetest'
    log_cmd $OF 'intel_reg_dumper'
    for i in /sys/class/drm/card?/device/uevent
    do
	module=$(cat $i | grep DRIVER | cut -d= -f2)
	log_cmd $OF "modeprint $module"
    done
    for i in /sys/class/drm/card*-*
    do
	log_cmd $OF "cat $i/status $i/enabled "
	log_cmd $OF 'hexdump -e '"'16/1 "'"%2.2x ""  "'"' -e '16/1 "'"%_p""\n"'"' $i/edid"
    done
    log_cmd $OF 'dmesg -T | grep drm'
    if grep -v 'drm.debug=' /proc/cmdline &>/dev/null; then
	log_write $OF "Warning, enable drm.debug=0xe on boot options line"
    fi
}

x_info() {
        local verify_list
	local xserver_present=n
	local drm_present=n

	printlog "X..."
	test $OPTION_X -eq 0 && { echolog Excluded; return 1; }
	OF=x.txt
	addHeaderFile $OF
	case $SLES_VER in
	80|90) if rpm_verify $OF XFree86
	then
		log_cmd $OF 'ls -al /dev | egrep "video.*|mouse.*"'
		log_cmd $OF '3Ddiag'
		rpm_verify $OF XFree86-Mesa
		rpm_verify $OF XFree86-libs
		timed_log_cmd $OF 'hwinfo --framebuffer'
		conf_files $OF /etc/XF86Config /etc/X11/XF86Config
		if rpm_verify $OF sax2
		then
			log_cmd $OF 'sysp -q mouse'
			log_cmd $OF 'sysp -c'
			log_cmd $OF 'sysp -q keyboard'
			FILES="/var/log/SaX.log"
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		FILES="/var/log/XFree86.[0,1].log /var/log/xdm.errors /root/.X.err /root/.xsession-errors"
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		echolog Done
	else
		echolog Skipped
	fi
	;;
	10*)
                log_cmd $OF 'ls -al /dev | egrep "video.*|mouse.*"'
                log_cmd $OF '3Ddiag'
                rpm_verify $OF Mesa
                rpm_verify $OF xorg-x11-libs
                timed_log_cmd $OF 'hwinfo --framebuffer'
                conf_files $OF /etc/sysconfig/displaymanager /etc/sysconfig/windowmanager /etc/X11/xorg.conf
                log_cmd $OF 'intel_reg_dumper'
                log_cmd $OF 'lspci -n'
                log_cmd $OF 'modetest'

                if rpm_verify $OF sax2
		then
                        log_cmd $OF 'sysp -q mouse'
                        log_cmd $OF 'sysp -c'
                        log_cmd $OF 'sysp -q keyboard'
                        log_files $OF $VAR_OPTION_LINE_COUNT /var/log/SaX.log
		fi
	;;
	11*)
		for i in xorg-x11-Xvnc xorg-x11-libs xorg-x11
		do
		    rpm -q $i &> /dev/null && rpm_verify $OF $i
		done
		if rpm_verify $OF xorg-x11-server
		then
		    xserver_present=y
		    rpm_verify $OF Mesa
		    if rpm_verify $OF sax2
		    then
			log_cmd $OF 'sysp -q mouse'
			log_cmd $OF 'sysp -c'
			log_cmd $OF 'sysp -q keyboard'
			log_files $OF $VAR_OPTION_LINE_COUNT /var/log/SaX.log
		    fi
		    log_cmd $OF 'bash -c "for i in /sys/class/input/input*; do echo -n \"\$i: \"; echo -n \$i/event* \"  \" | sed -e \"s#\$i/##\"; cat \$i/name; done"'
		    log_cmd $OF 'ls -al /dev | egrep "video.*|mouse.*"'
		    log_cmd $OF '3Ddiag'
		    [ $SLES_VER -ge 113 ] && log_cmd $OF 'mokutil --sb-state'
		    log_cmd $OF 'cat /proc/fb'
		    grep -q "VESA" /proc/fb && timed_log_cmd $OF 'hwinfo --framebuffer'
		    log_cmd $OF 'lspci -nn'

		    conf_files $OF /etc/sysconfig/displaymanager /etc/sysconfig/windowmanager /etc/xinetd.d/vnc
		    [ -e /etc/X11/xorg.conf ] && conf_files $OF /etc/X11/xorg.conf

		    FILES="/var/log/Xorg.[0,1].log /var/log/Xorg.0.log.old /var/log/xdm.errors /root/.X.err /root/.xsession-errors"
		    test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		if [ -d /sys/class/drm ]
		then
		    drm_present=y
		    if [ "$xserver_present" = "n" ]
		    then
			[ $SLES_VER -ge 113 ] && log_cmd $OF 'mokutil --sb-state'
			log_cmd $OF 'lspci -nn'
		    fi
		    drm_sub_info
		fi
		if [ "$xserver_present" = "y" -o "$drm_present" = "y" ]
		then
		    echolog Done
		else
		    echolog Skipped
		fi
	;;
	12*)
		MESA="Mesa Mesa-32bit Mesa-demo-x Mesa-libEGL1 Mesa-libEGL1-32bit Mesa-libGL1 \
		Mesa-libGL1-32bit Mesa-libGLESv2-2 Mesa-libGLESv2-2-32bit Mesa-libglapi0 \
                Mesa-libglapi0-32bit"

		XORG_APPS="appres autocutsel bitmap editres fonttosfnt glamor  iceauth listres luit \
                mkfontdir mkfontscale numlockx rendercheck rgb s2tc sessreg setxkbmap \
                viewres x11-tools x11perf xauth xbacklight xbitmaps xclock xconsole \
                xcursorgen xdm xdmbgrd xdpyinfo xev xeyes xfd xfontsel xfsdump xfsprogs \
                xgamma xhost xinit xinput xkbcomp xkbevd xkbprint xkbutils xkill xlogo \
                xlsatoms xlsclients xlsfonts xmag xmessage xmodmap intel-gpu-tools xprop \
                xrandr xrdb xrestop xscope xset xsetmode xsetpointer xsetroot xvinfo xwd \
                xwininfo"

		XORG_FONTS="gnu-unifont-bitmap-fonts efont-unicode-bitmap-fonts baekmuk-bitmap-fonts \
                arabic-bitmap-fonts intlfonts-arabic-bitmap-fonts \
                intlfonts-chinese-big-bitmap-fonts intlfonts-chinese-bitmap-fonts \
                intlfonts-euro-bitmap-fonts intlfonts-japanese-big-bitmap-fonts \
                intlfonts-japanese-bitmap-fonts terminus-bitmap-fonts \
                wqy-bitmap-fonts x11-japanese-bitmap-fonts"

		XORG_LIBS="libGLU1 libGLw1 libICE6 libSM6 libX11-6 libX11-data libX11-xcb1 libXRes1 \
                libXau6 libXaw3d8 libXaw7 libXaw8 libXcomposite1 libXcursor1  libXdamage1 \
                libXdmcp6 libXevie1 libXext6 libXfixes3 libXfont1 libXfontcache1 libXft2 \
                libXi6 libXinerama1 libXiterm1 libXmu6 libXmuu1 libXp6 libXpm4 libXprintUtil1 \
                libXrandr2 libXrender1 libXt6 libXt6-32bit libXtst6 libXvMC1 libXxf86dga1 \
                libXxf86misc1 libXxf86vm1 libdmx1 libdrm2  libXv1 libdrm_intel1 \
                libdrm_nouveau2 libdrm_radeon1 libevdev-tools libevdev2 libfontenc1 \
                libgssglue1 libmtdev1 libpciaccess0 libsmartcols1 libsmbclient-raw0 \
                libsmbclient0 libsmbconf0 libsmbios2 libsmbldap0 libsmi libsmi2 libvdpau1 \
                libxcb-dri2-0 libxcb-glx0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \
                libxcb-randr0 libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-shm0 \
                libxcb-sync1 libxcb-util1 libxcb-xf86dri0 libxcb-xfixes0 libxcb-xkb1 \
                libxcb-xv0 libxcb1 libxkbfile1 libxtables10"

		XORG_32_LIBS="libGLU1-32bit libGLw1-32bit libICE6-32bit libSM6-32bit libX11-6-32bit \
                libX11-xcb1-32bit libXRes1-32bit libXau6-32bit libXaw3d8-32bit libXaw7-32bit \
                libXcomposite1-32bit libXcursor1-32bit libXdamage1-32bit libXdmcp6-32bit \
                libXext6-32bit libXfixes3-32bit libXft2-32bit libXi6-32bit libXinerama1-32bit \
                libXmu6-32bit libXp6-32bit libXpm4-32bit libXprintUtil1-32bit libXrandr2-32bit \
                libXrender1-32bit libXxf86vm1-32bit libXtst6-32bit libXv1-32bit libdrm2-32bit \
                libfontenc1-32bit libglut3-32bit libdrm_intel1-32bit libdrm_nouveau2-32bit \
                libdrm_radeon1-32bit libgssglue1-32bit libpciaccess0-32bit \
                libsmbclient-raw0-32bit libsmbclient0-32bit libsmbconf0-32bit \
                libsmbldap0-32bit libvdpau1-32bit libxcb-dri2-0-32bit libxcb-glx0-32bit \
                libxcb-render0-32bit libxcb-shm0-32bit libxcb-util1-32bit libxcb-xfixes0-32bit \
                libxcb-xkb1-32bit libxcb1-32bit libxkbfile1-32bit"

		XORG_DRIVERS="vaapi-intel-driver xf86-input-evdev xf86-input-synaptics xf86-input-vmmouse \
                xf86-input-void xf86-input-wacom xf86-video-ati xf86-video-cirrus \
                xf86-video-fbdev xf86-video-intel xf86-video-mga xf86-video-modesetting \
                xf86-video-nouveau xf86-video-nv xf86-video-qxl xf86-video-v4l \
                xf86-video-vesa xf86-video-vmware"

                XORG_STUFF="xcursor-themes xkeyboard-config xkeyboard-config-lang xorg-docs"

                XORG_DUMMY="xorg-x11 xorg-x11-driver-input xorg-x11-driver-video xorg-x11-essentials \
                xorg-x11-fonts xorg-x11-fonts-core xorg-x11-libX11-ccache xorg-x11-libs \
                xorg-x11-server xorg-x11-server-extra"

		XORG_PACKAGES="$MESA $XORG_APPS $XORG_FONTS $XORG_LIBS $XORG_32_LIBS $XORG_DRIVERS $XORG_STUFF"
		for i in $XORG_PACKAGES xorg-x11-Xvnc tigervnc xorg-x11-server
		do
		    rpm -q $i &> /dev/null && verify_list="$verify_list $i"
		done
		[ -n "$verify_list" ] && rpm_verify $OF "$verify_list"
		if rpm -q xorg-x11-server &>/dev/null
		then
		    xserver_present=y
		    log_cmd $OF 'bash -c "for i in /sys/class/input/input*; do echo -n \"\$i: \"; echo -n \$i/event* \"  \" | sed -e \"s#\$i/##\"; cat \$i/name; done"'
		    log_cmd $OF 'ls -al /dev | egrep "video.*"'
		    [ $SLES_VER -ge 1130 ] && log_cmd $OF 'mokutil --sb-state'
		    log_cmd $OF 'cat /proc/fb'
		    grep -q "VESA" /proc/fb && timed_log_cmd $OF 'hwinfo --framebuffer'
		    log_cmd $OF 'lspci -nn'

		    conf_files $OF /etc/sysconfig/displaymanager /etc/sysconfig/windowmanager /etc/xinetd.d/vnc
		    if [ -e /etc/X11/xorg.conf ]
		    then
			xorg_conf=/etc/X11/xorg.conf
			TMPLOG=$ADD_OPTION_LOGS
		    else [ -d /etc/X11/xorg.conf.d ]
			xorg_conf='/etc/X11/xorg.conf.d/*'
			TMPLOG=0
		    fi
		    [ -n "$xorg_conf" ] && ADD_OPTION_LOGS=$TMPLOG conf_files $OF $xorg_conf

		    FILES="/var/log/Xorg.[0,1].log /var/log/Xorg.0.log.old /var/log/xdm.errors /root/.X.err /root/.xsession-errors"
		    test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		if [[ -d /sys/class/drm ]]
		then
		    drm_present=y
		    if [ "$xserver_present" == "n" ]
		    then
			log_cmd $OF 'mokutil --sb-state'
			log_cmd $OF 'lspci -nn'
		    fi
		    drm_sub_info
		fi

		if [ "$xserver_present" = "y" -o "$drm_present" = "y" ]
		then
		    echolog Done
		else
		    echolog Skipped
		fi
	;;
	esac
}

ssh_info() {
	printlog "SSH..."
	test $OPTION_SSH -eq 0 && { echolog Excluded; return 1; }
	OF=ssh.txt
	addHeaderFile $OF
	if rpm_verify $OF openssh
	then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status sshd.service"
		else
			check_service $OF sshd
		fi
		conf_files $OF /etc/ssh/sshd_config /etc/ssh/ssh_config /etc/pam.d/sshd
		log_cmd $OF 'netstat -nlp | grep sshd'
		echolog Done
	else
		echolog Skipped
	fi
}

slert_info() {
	printlog "SLERT..."
	test $OPTION_SLERT -eq 0 && { echolog Excluded; return 1; }
	OF=slert.txt
	addHeaderFile $OF
	if rpm_verify $OF kernel-rt
	then
		log_cmd $OF "uname -r"
		[ -e /etc/init.d/slert ] && check_service $OF slert
		if rpm -q cpuset &>/dev/null; then
			rpm_verify $OF cpuset
			if [ -e /etc/init.d/cset ]; then
				CSETSRV=cset
				check_service $OF $CSETSRV
			elif [ -e /etc/init.d/cset.init.d ]; then
				CSETSRV='cset.init.d'
				check_service $OF $CSETSRV
			fi
			CSETFILES="/etc/cset.conf /etc/init.d/$CSETSRV"
		else
			CSETFILES=""
		fi
		log_cmd $OF "ps -eo pid,user,args,ni,rtprio --sort -rtprio"
		conf_files $OF /etc/slert/setup /proc/cpuinfo /etc/sysconfig/cset $CSETFILES
		if [ -e /proc/irq/default_smp_affinity ]; then
			conf_files $OF /proc/irq/default_smp_affinity /proc/irq/*/smp_affinity
		fi
		log_cmd $OF "grep cpuset /etc/mtab"
		CPUSET=$(grep ' cpuset ' /etc/mtab | cut -d' ' -f2)
		if [ -n "$CPUSET" ]; then
			log_cmd $OF "find -L ${CPUSET}/ -type f"
			FILES=$(find -L ${CPUSET}/ -type f)
			conf_files $OF $FILES
			for TASKS in $(find -L ${CPUSET}/ -type f | grep tasks)
			do
				log_write $OF "#==[ Task Scheduling ]==============================#"
				log_write $OF "# Threads in CPUSET: $TASKS"
				log_write $OF
				for TASK in $(cat $TASKS)
				do
					log_cmd $OF chrt -p $TASK
				done
			done
		else
			for TASK in $(ps axo pid | sed -e '/PID/d')
			do
				test -e /proc/$TASK && log_cmd $OF "chrt -p $TASK"
			done
		fi
		echolog Done
	else
		echolog Skipped
	fi
}

print_info() {
	printlog "Printing..."
	test $OPTION_PRINT -eq 0 && { echolog Excluded; return 1; }
	OF=print.txt
	addHeaderFile $OF
	SKIP=0
	if rpm_verify $OF cups
	then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status cups.service"
		else
			check_service $OF cups
		fi
		log_cmd $OF 'netstat -nlp | grep cupsd'
		BEP=$(ls -1 /usr/lib*/cups/backend/parallel 2>/dev/null | head -n1)
		if [ $SLES_VER -ge 110 ]; then
			if [ $MIN_OPTION_AUTOMOD -eq 0 ]; then
				log_write $OF "#==[ Warning ]======================================#"
				log_write $OF "# Autoloading kernel modules disabled. Don't use -k."
				log_write $OF "# Excluding $BEP"
				log_write $OF
			else
				test -x "$BEP" && log_cmd $OF "$BEP"
			fi
		else
			test -x "$BEP" && log_cmd $OF "$BEP"
		fi
		BEU=$(ls -1 /usr/lib*/cups/backend/usb 2>/dev/null | head -n1)
		test -x "$BEU" && log_cmd $OF "$BEU"
		test -d /etc/cups/ppd && PPDFILES=$(find -L /etc/cups/ppd/ -type f) || PPDFILES=""
		conf_files $OF /etc/sysconfig/cups /etc/sysconfig/printer /etc/printcap /etc/cups/cupsd.conf /etc/cups/printers.conf /etc/cups/mime.types /etc/cups/mime.convs $PPDFILES

		test -d /etc/cups/ppd && PPDFILES=$(find -L /etc/cups/ppd/ -type f) || PPDFILES=""
		conf_files $OF /etc/sysconfig/printer /etc/printcap /etc/cups/cupsd.conf /etc/cups/printers.conf /etc/cups/mime.types /etc/cups/mime.convs $PPDFILES
		FILES="/var/log/cups/error_log /var/log/cups/error_log.test /tmp/prnlog"
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
	else
		((SKIP++))
	fi

	if rpm_verify $OF cups-client
	then
		timed_log_cmd $OF 'lpstat -t'
		log_cmd $OF 'lpc status'
	else
		((SKIP++))
	fi

	test $SKIP -lt 2 && echolog Done || echolog Skipped
}

sar_info() {
	printlog "SAR Files..."
	test $OPTION_SAR -eq 0 && { echolog Excluded; return 1; }
	OF=sar.txt
	addHeaderFile $OF
	SARDIR=/var/log/sa
	SARSCDIR=$LOG/sar
	if rpm_verify $OF sysstat; then
		if [ -d $SARDIR ]; then
			FOUND=$(ls -A1 $SARDIR)
			if [ -n "$FOUND" ]; then
				mkdir -p $SARSCDIR
				log_entry $OF command "cp $SARDIR/sa* $SARSCDIR"
				if [ $ADD_OPTION_LOGS -gt 0 ]; then
					cp $SARDIR/sa* $SARSCDIR &>/dev/null
				else
					log_write $OF "# NOTE: Only the newest $VAR_OPTION_SAR_FILES_LIMIT files are copied"
					for i in $(\ls -A1 $SARDIR/sa* 2>/dev/null | tail -$VAR_OPTION_SAR_FILES_LIMIT)
					do
						cp $i $SARSCDIR &>/dev/null
					done
				fi
				echolog Done
			else
				echolog Skipped
			fi
		else
			echolog Skipped
		fi
	else
		echolog Skipped
	fi
}

dns_info() {
	printlog "DNS..."
	test $OPTION_DNS -eq 0 && { echolog Excluded; return 1; }
	SKIP=0
	OF=dns.txt
	addHeaderFile $OF
	if rpm_verify $OF bind; then
		check_service $OF named
		[ $SKIP -gt 0 ] && log_cmd $OF 'netstat -nlp | grep named'
		FILES=$(grep ^include /etc/named.conf | cut -d';' -f1 | sed -e 's/"//g'  | awk '{print $2}')
		conf_files $OF /etc/named.conf $FILES /etc/sysconfig/named
		ZDIR=$(grep ^[[:space:]]*directory /etc/named.conf | cut -d';' -f1 | sed -e 's/"//g'  | awk '{print $2}')
		if [ -n "$ZDIR" ]; then
			FILES=$(find -L ${ZDIR}/ -mount -type f 2>/dev/null | grep zone | grep -v '/proc/') || unset FILES
			conf_files $OF $FILES
			FILES=$(find -L ${ZDIR}/ -mount -type f 2>/dev/null | egrep -v "localtime|zone" | grep -v '/proc/') || unset FILES
			conf_files $OF $FILES
		fi
		log_cmd $OF "grep named /var/log/warn"
		log_cmd $OF "grep named /var/log/messages"
		echolog Done
	else
		echolog Skipped
	fi
}

dhcp_info() {
	printlog "DHCP..."
	test $OPTION_DHCP -eq 0 && { echolog Excluded; return 1; }
	OF=dhcp.txt
	addHeaderFile $OF
	SKIP=0
	if rpm_verify $OF dhcp-server; then
		check_service $OF dhcpd
		log_cmd $OF 'netstat -nlp | grep dhcp'
		conf_files $OF /etc/sysconfig/dhcpd
		conf_files $OF /etc/dhcpd.conf /var/lib/dhcp/db/dhcpd.leases
		log_cmd $OF "grep ' dhcpd' /var/log/warn"
		log_cmd $OF "grep ' dhcpd' /var/log/messages"
		echolog Done
	else
		echolog Skipped
	fi
}

cimom_info() {
	printlog "CIMOM..."
	test $OPTION_CIMOM -eq 0 && { echolog Excluded; return 1; }
	OF=cimom.txt
	addHeaderFile $OF
	SKIP=0
	if rpm_verify $OF openwbem; then
		log_cmd $OF "egrep -i \"cim|provider\" $RPMPATH"
		check_service $OF owcimomd
		conf_files $OF /etc/openwbem/openwbem.conf
		log_cmd $OF 'ls -lR --time-style=long-iso /etc/openwbem/'
		for i in cert key
		do
			unset OWSSLCHECK
			OWSSLCHECK=$(grep "^http_server.SSL_${i}" /etc/openwbem/openwbem.conf | awk '{print $3}')
			if [ -n "$OWSSLCHECK" ]; then
				if [ -L $OWSSLCHECK ]; then
					case $SLES_VER in
					90*) log_cmd $OF "readlink -fv $OWSSLCHECK" ;;
					10*|11*|12*) log_cmd $OF "readlink -ev $OWSSLCHECK" ;;
					esac
				fi
			fi
		done
		log_cmd $OF 'owenumnamespace -u https://localhost/root/cimv2'
		log_cmd $OF 'owenumclassnames -u https://localhost/root/cimv2'
		test -f /var/lib/openwbem/loadmof.log && FILES="/var/lib/openwbem/loadmof.log /var/lib/openwbem/loadmof.log.*" || unset FILES
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
	else
		((SKIP++))
	fi
	if rpm_verify $OF sblim-sfcb; then
		log_cmd $OF "egrep -i \"cim|provider\" $RPMPATH"
		check_service $OF sfcb
		log_cmd $OF "netstat -nlp | grep sfcb"
		conf_files $OF /etc/sfcb/sfcb.cfg
		log_cmd $OF "ls -lR --time-style=long-iso /etc/sfcb/"
	else
		((SKIP++))
	fi

	test $SKIP -lt 2 && echolog Done || echolog Skipped
}

ib_info() {
	printlog "InfiniBand..."
	test $OPTION_IB -eq 0 && { echolog Excluded; return 1; }
	OF=ib.txt
	addHeaderFile $OF
	case $SLES_VER in
	10*|11*)
		if rpm_verify $OF ofed; then
			check_service $OF openibd
			conf_files $OF /etc/infiniband/openib.conf
			log_cmd $OF 'lspci -b'
			log_cmd $OF 'lspci -nn'
			log_cmd $OF 'lsmod'
			log_cmd $OF 'ibv_devinfo -v'
			log_cmd $OF 'ibdiagnet'
			FILES=$(find /tmp/ -type f -name \*ibdiagnet\* 2>/dev/null)
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
			echolog Done
		else
			echolog Skipped
		fi
		;;
	12*)
		if rpm_verify $OF rdma-core; then
			log_cmd $OF "systemctl status rdma.service"
			conf_files $OF "/etc/rdma/* /etc/infiniband/*"
			log_cmd $OF 'lspci -b'
			log_cmd $OF 'lspci -nn'
			log_cmd $OF 'lsmod'
			log_cmd $OF 'ibv_devinfo -v'
			log_cmd $OF 'ibdiagnet'
			FILES=$(find /tmp/ -type f -name \*ibdiagnet\* 2>/dev/null)
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
			echolog Done
		else
			echolog Skipped
		fi
		;;
	esac
}

web_info() {
	printlog "Web..."
	test $OPTION_WEB -eq 0 && { echolog Excluded; return 1; }
	SKIP=0
	OF=web.txt
	addHeaderFile $OF
	if rpm_verify $OF apache2; then
		if (( SLES_VER >= 120 ))
		then
			log_cmd $OF "systemctl status apache2.service"
		else
			check_service $OF apache2
		fi
		conf_files $OF /etc/sysconfig/apache2 /etc/apache2/httpd.conf
		FILES=$(find -L /etc/apache2/ -type f | grep 'conf$' | grep -v 'httpd.conf')
		conf_files $OF $FILES
		FILES=$(find -L /var/log/apache2/ -type f)
		test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		TOMCAT=$(cat $LOG/$RPM_QA_FILE | grep '^tomcat')
		for i in $TOMCAT
		do
			rpm_verify $OF $i
		done
		for WEB_SERVICE in $(ls -1 /etc/init.d/*tomcat* 2>/dev/null)
		do
			check_service $OF $(basename $WEB_SERVICE)
		done
		if [ -s /etc/sysconfig/j2ee ]; then
			conf_files $OF /etc/sysconfig/j2ee
			. /etc/sysconfig/j2ee
			conf_files $OF $CATALINA_HOME/conf/server.xml
			FILES="$CATALINA_HOME/logs/catalina.out $CATALINA_HOME/logs/localhost_log*"
			test $ADD_OPTION_LOGS -gt 0 && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		fi
		echolog Done
	else
		echolog Skipped
	fi
}

hppsp_info() {
	OFPSP=psp.txt
	if [ -s /var/log/hppldu.log ]; then
		addHeaderFile $OFPSP
		PSPFILES="/var/log/hppldu.log"
		test $ADD_OPTION_LOGS -gt 0 && log_files $OFPSP 0 $PSPFILES || log_files $OFPSP $VAR_OPTION_LINE_COUNT $PSPFILES
		if [ -d /var/hp ]; then
			PSPCFILES="$(find -L /var/hp/ -type f)"
			conf_files $OFPSP $PSPCFILES
		fi
	fi
}

sysfs_info() {
	printlog "SYSFS..."
	test $OPTION_SYSFS -eq 0 && { echolog Excluded; return 1; }
	OF=sysfs.txt
	addHeaderFile $OF
	EXHAUSTIVE_MEM_LIMIT=16000000000
	log_entry $OF command "/bin/find /sys | sed -e 's/\\/\\\\/g' | xargs ls -ld --time-style=long-iso"
	/bin/find /sys | sed -e 's/\\/\\\\/g' | xargs ls -ld --time-style=long-iso >> ${LOG}/${OF} 2>&1
	log_write $OF
	log_cmd $OF "systool"
	for ITEM in $(systool)
	do
		case $ITEM in
		Supported) SBUS=0; SCLS=0; SDEV=0; SMOD=0 ;;
		buses:) SBUS=1; continue ;;
		classes:) SCLS=1; continue ;;
		devices:) SDEV=1; continue ;;
		modules:) SMOD=1; continue ;;
		esac
		if (( SBUS )); then
			# collecting memory info from sysfs can be time consuming
			# skip it on systems with 16TB  or ram or more unless exhaustive
			# option is used
			if [[ $ITEM == "memory" ]]; then
				mem=$(grep 'MemTotal' /proc/meminfo | awk '{print $2}')
				test $mem -gt $EXHAUSTIVE_MEM_LIMIT -a $VAR_OPTION_EXHAUSTIVE_MEM -eq 0 && continue
				echonlog "Please Wait..."
				echonlog "Memory"
			fi
			log_cmd $OF "systool -vb $ITEM"
		elif (( SCLS )); then
			log_cmd $OF "systool -vc $ITEM"
		elif (( SMOD )); then
			log_cmd $OF "systool -vm $ITEM"
		fi
	done
	echolog Done
}

timed_cmd_cleanup() {
	PIDS2KILL=$(\ps axwwo pid,cmd | grep SC__SEMAPHORE | grep -v grep | awk '{print $1}')
	if [[ -n "$PIDS2KILL" ]]; then
		test $VAR_OPTION_SILENT -eq 0 && { echo; }
		if (( $VAR_OPTION_SBM )); then
			printlog -b "Command Clean Up..."
		else
			printlog -b "Command Clean Up"
		fi
		while [[ -n "$PIDS2KILL" ]]
		do
			wait_trace_on "kill $PIDS2KILL"
			kill -9 $PIDS2KILL &>/dev/null
			sleep 1
			PIDS2KILL=$(\ps axwwo pid,cmd | grep SC__SEMAPHORE | grep -v grep | awk '{print $1}')
			wait_trace_off
		done
	fi
}

ascii_plugin() {
	FOUND=$(file $PLUGIN_BIN | grep -i elf 2>/dev/null)
	if [[ -n "$FOUND" ]]; then
		return 1
	else
		return 0
	fi
}

bad_plugin_dir() {
	if [ -d $XPLUGIN_DIR ]; then
		XPLUGIN_DIR_OWNER=$(stat -c %u $XPLUGIN_DIR)
		XPLUGIN_DIR_GRP=$(stat -c %g $XPLUGIN_DIR)
		XPLUGIN_DIR_MODE=$(stat -c %a $XPLUGIN_DIR)

		test $XPLUGIN_DIR_OWNER -eq 0 && OWNER_DENIED=0 || OWNER_DENIED=1
		case $XPLUGIN_DIR_GRP in
		0) GROUP_DENIED=0 ;;
		*)	if [ ${#XPLUGIN_DIR_MODE} -eq 3 ]; then
				case ${XPLUGIN_DIR_MODE:1:1} in
				0|1|4|5) GROUP_DENIED=0 ;;
				*) GROUP_DENIED=1 ;;
				esac
			else
				# Don't allow suid, guid, or sticky bits to be set
				GROUP_DENIED=1
			fi
		esac
		if [ ${#XPLUGIN_DIR_MODE} -eq 3 ]; then
			case ${XPLUGIN_DIR_MODE:2:1} in
			0|1|4|5) OTHER_DENIED=0 ;;
			*) OTHER_DENIED=1 ;;
			esac
		else
			# Don't allow suid, guid, or sticky bits to be set
			OTHER_DENIED=1
		fi

		BAD_DIR=0
		test $OWNER_DENIED -gt 0 && ((BAD_DIR++))
		test $GROUP_DENIED -gt 0 && ((BAD_DIR++))
		test $OTHER_DENIED -gt 0 && ((BAD_DIR++))
		test $BAD_DIR -gt 0 && return 0 || return 1
	else
		# good plugin directory
		return 1
	fi
}

exec_plugins() {
	if [ -d $XPLUGIN_DIR ]; then
		printlog "Supportconfig Plugins:"
		if bad_plugin_dir; then
			echolog Skipped
			return 5
		fi
		echolog $PLUGIN_CNT
		for PLUGIN_FEATURE in $PLUGIN_FEATURES
		do
			PLUGIN=${PLUGIN_FEATURE/p/}
			printlog "  Plugin: ${PLUGIN}..."
			test $((PLUGIN_OPTION_${PLUGIN})) -eq 0 && { echolog Excluded; continue; }
			PLUGIN_ERROR=0
			PLUGIN_SKIP=0
			PLUGIN_LOG_FILE="plugin-${PLUGIN}.txt"
			PLUGIN_LOG="${LOG}/${PLUGIN_LOG_FILE}"
			PLUGIN_BIN="${XPLUGIN_DIR}/${PLUGIN}"
			addHeaderFile $PLUGIN_LOG_FILE

			log_write $PLUGIN_LOG_FILE "#==[ Plugin ]=======================================#"			
			log_write $PLUGIN_LOG_FILE "# Output: $PLUGIN_BIN"
			log_write $PLUGIN_LOG_FILE

			if [ -x $PLUGIN_BIN ]; then
				log_cmd $PLUGIN_LOG_FILE "$PLUGIN_BIN"
				PLUGIN_RC=$?
				if [ $PLUGIN_RC -ne 0 ]; then
					if [ $PLUGIN_RC -eq 111 ]; then
						((PLUGIN_SKIP++))
					else
						((PLUGIN_ERROR++))
					fi
				fi
			else
				log_write $PLUGIN_LOG_FILE "ERROR: Missing or non-executible plugin"
				((PLUGIN_ERROR++))
			fi
			log_write $PLUGIN_LOG_FILE

			log_write $PLUGIN_LOG_FILE "#==[ Plugin ]=======================================#"			
			log_write $PLUGIN_LOG_FILE "# File: cat -n $PLUGIN_BIN"
			log_write $PLUGIN_LOG_FILE

			if ascii_plugin; then
				cat -n $PLUGIN_BIN >> $PLUGIN_LOG 2>&1
			else
				log_write $PLUGIN_LOG_FILE "Excluding non ASCII file"
			fi
			log_write $PLUGIN_LOG_FILE

			if ((PLUGIN_ERROR)); then
				echolog Error
			elif ((PLUGIN_SKIP)); then
				echolog Skipped
			else
				echolog Done
			fi
		done
	fi
}

set_to_min() {
	init_plugins off
	for SRCH in OPTION_ ADD_OPTION_
	do
		for i in $(grep ^$SRCH $0 | cut -d= -f1 | sort)
		do
			(( $i=0 ))
		done
	done
	for SRCH in MIN_OPTION_ ADD_OPTION_MIN_
	do
		for i in $(grep ^$SRCH $0 | cut -d= -f1 | sort)
		do
			(( $i=1 ))
		done
	done
}

set_to_all() {
	init_plugins on
	for SRCH in OPTION_ ADD_OPTION_ MIN_OPTION_
	do
		for i in $(grep ^$SRCH $0 | cut -d= -f1 | sort)
		do
			(( $i=1 ))
		done
	done
	for SRCH in ADD_OPTION_MIN_
	do
		for i in $(grep ^$SRCH $0 | cut -d= -f1 | sort)
		do
			(( $i=0 ))
		done
	done
}

set_to_default() {
	log2sys "Set Default Features"
	init_plugins on
	DEF_FILE=$(mktemp /tmp/supportconfig-defoption.XXXXXXXXXXXXXX)
	for SRCH in OPTION_ ADD_OPTION_ MIN_OPTION_ VAR_OPTION_
	do
		for i in $(grep ^$SRCH $0 | sort)
		do
			echo "$i" >> $DEF_FILE
		done
	done
	grep ^VAR_OPTION_ $0 | sort >> $DEF_FILE
	. $DEF_FILE
	rm -f $DEF_FILE
}

valid_srnum() {
	log2sys "Validate SR Number"
	if echo $CONTACT_SRNUM | grep "^[[:digit:]]*$" &>/dev/null; then
		return 0
	else
		return 1
	fi
}

check_log_dir() {
	# if supportconfig repeats execution too fast, make sure the directory is unique so files are not overwritten
	ORIGBASE=$BASE
	if [ -d ${LOG}/${BASE} -o -f ${LOG}/${BASE}.${COMPRESS} ]; then
		BASE="${ORIGBASE}_%u"
		normalize_base
	fi
}

get_features() {
	log2sys "Display Feature Set"
	FEATURES=$(grep ^OPTION_ $0 | cut -d= -f1 | sed -e 's/OPTION_//g')
	ADDITIONAL_FEATURES=$(grep ^ADD_OPTION_ $0 | cut -d= -f1 | sed -e 's/ADD_OPTION_/a/g')
	echo $FEATURES $ADDITIONAL_FEATURES $PLUGIN_FEATURES
}

# Default state is "on", unless "off" is specified as a parameter
init_plugins() {
	PLUGIN_FEATURES=""
	PLUGIN_CNT=0
	case $1 in
	off) FEATURE_STATE=0; log2sys "Plugins: OFF" ;;
	*) FEATURE_STATE=1; log2sys "Plugins: ON" ;;
	esac
	if [ -d $XPLUGIN_DIR ]; then
		for FILE in $(\ls -A1 $XPLUGIN_DIR)
		do
			if [ -x ${XPLUGIN_DIR}/${FILE} ]; then
				PLUGIN_FEATURES="p${FILE} $PLUGIN_FEATURES"
				((PLUGIN_CNT++))
			fi
		done
	fi
	for PLUGIN_FEATURE in $PLUGIN_FEATURES
	do
		eval PLUGIN_OPTION_${PLUGIN_FEATURE/p/}=$FEATURE_STATE
	done
}

# Requires one parameter with value "on" or "off"
selected_features() {
	INVALID_KEYWORDS=0
	case $1 in
	on) FEATURE_STATE=1 ;;
	off) FEATURE_STATE=0 ;;
	*) exit_code 10 "ERROR: selected_features: Invalid FEATURE_STATE, $1" ;;
	esac
	FEATURE_LIST="$(get_features)"
	for FEATURE in $(echo $SELECTED_FEATURE_LIST | sed -e 's/,/ /g')
	do
		if echo $FEATURE_LIST | grep $FEATURE &>/dev/null; then
			case ${FEATURE:0:1} in
			a) eval ADD_OPTION_${FEATURE/a/}=${FEATURE_STATE} ;;
			p) eval PLUGIN_OPTION_${FEATURE/p/}=${FEATURE_STATE} ;;
			*) eval OPTION_${FEATURE}=${FEATURE_STATE} ;;
			esac
		else
			echo "ERROR: Invalid Feature Keyword: $FEATURE"
			((INVALID_KEYWORDS++))
		fi
	done
	if (( INVALID_KEYWORDS )); then
		echo
		echo "Valid keywords listed below. They are case sensitive."
		echo
		get_features
		echo
		exit_code 11
	fi
}

toggle_features() {
	INVALID_KEYWORDS=0
	FEATURE_LIST="$(get_features)"
	for FEATURE in $(echo $SELECTED_FEATURE_LIST | sed -e 's/,/ /g')
	do
		if echo $FEATURE_LIST | grep $FEATURE &>/dev/null; then
			case ${FEATURE:0:1} in
			a) [ $(( ADD_OPTION_${FEATURE/a/} )) -eq 0 ] && eval ADD_OPTION_${FEATURE/a/}=1 || eval ADD_OPTION_${FEATURE/a/}=0 ;;
			p) [ $(( PLUGIN_OPTION_${FEATURE/p/} )) -eq 0 ] && eval PLUGIN_OPTION_${FEATURE/p/}=1 || eval PLUGIN_OPTION_${FEATURE/p/}=0 ;;
			*) [ $(( OPTION_${FEATURE} )) -eq 0 ] && eval OPTION_${FEATURE}=1 || eval OPTION_${FEATURE}=0 ;;
			esac
		else
			echo "ERROR: Invalid Feature Keyword: $FEATURE"
			((INVALID_KEYWORDS++))
		fi
	done
	if (( INVALID_KEYWORDS )); then
		echo
		echo "Valid keywords listed below. They are case sensitive."
		echo
		get_features
		echo
		exit_code 11
	fi
}

ehr() {
	echo "-----------------------------------------------------------------------------"
}

encrypt_tarball() {
	log2sys "Encrypt Tar Ball"
	FOUND_KEY=$(gpg --list-keys 2>/dev/null | grep "$VAR_OPTION_GPG_UID" 2>/dev/null)
	if [ -z "$FOUND_KEY" ]; then
		echo "ERROR: GPG key not found: $VAR_OPTION_GPG_UID"
		echo "       File encryption failed, aborting"
		echo
		gpg --list-keys
		exit_code 13
	fi
	if (( VAR_OPTION_SILENT )); then
		gpg --batch --yes --trust-model always --encrypt --recipient "$VAR_OPTION_GPG_UID" $TARBALL &> /dev/null
		ERR=$?
		if [ $ERR -ne 0 ]; then
			exit_code 13 "ERROR: gpg failed, RC=$ERR, aborting"
		fi
	else
		if (( $VAR_OPTION_SBM )); then
			echo "Encrypting Tar Ball..."
		else
			echo "Encrypting Tar Ball"
			ehr
		fi
		echo
		echo "Using GPG Key:  $VAR_OPTION_GPG_UID"
		echo "Command:        gpg --batch --yes --trust-model always --encrypt --recipient \"$VAR_OPTION_GPG_UID\" $TARBALL"
		wait_trace_on "gpg --batch --yes --trust-model always --encrypt --recipient "$VAR_OPTION_GPG_UID" $TARBALL"
		gpg --batch --yes --trust-model always --encrypt --recipient "$VAR_OPTION_GPG_UID" $TARBALL
		ERR=$?
		wait_trace_off
		if [ $ERR -ne 0 ]; then
			exit_code 13 "ERROR: gpg failed, RC=$ERR, aborting"
		fi
		ENCRYPTED_TARBALL=1
		echo "Encrypted File: ${TARBALL}.gpg"
		echo
	fi
}

upload_tarball() {
	if (( UPLOAD_TARBALL )); then
		log2sys "Uploading Tar Ball"
		TARBALL_FILE=$(basename $TARBALL)
		FTPES_OPTIONS="--ssl-reqd"
		UPLOAD_SERVICE=$(echo ${VAR_OPTION_UPLOAD_TARGET} | cut -d: -f1)
		if (( VAR_OPTION_SILENT )); then
			case $UPLOAD_SERVICE in
			ftps|ftpes)
				UPLOAD_URL=$(sed -e 's/ftpes:/ftp:/g;s/ftps:/ftp:/g' <<< ${VAR_OPTION_UPLOAD_TARGET})
				if (( ENCRYPTED_TARBALL )); then
					curl -sT ${TARBALL}.md5 ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.md5 &>/dev/null
					curl -sT ${TARBALL}.gpg ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.gpg &>/dev/null
				else
					curl -sT ${TARBALL}.md5 ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.md5 &>/dev/null
					curl -sT ${TARBALL} ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE} &>/dev/null
				fi
				;;
			ftp)
				UPLOAD_URL=${VAR_OPTION_UPLOAD_TARGET}
				if (( ENCRYPTED_TARBALL )); then
					curl -sT "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5" &>/dev/null
					curl -sT "${TARBALL}.gpg" "${UPLOAD_URL}/${TARBALL_FILE}.gpg" &>/dev/null
				else
					curl -sT "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5" &>/dev/null
					curl -sT "${TARBALL}" "${UPLOAD_URL}/${TARBALL_FILE}" &>/dev/null
				fi
				;;
			scp)
				UPLOAD_URL=$(echo ${VAR_OPTION_UPLOAD_TARGET} | sed -e 's!scp://!!g;s!/!:/!')
				if (( ENCRYPTED_TARBALL )); then
					scp -qp "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5" &>/dev/null
					scp -qp "${TARBALL}.gpg" "${UPLOAD_URL}/${TARBALL_FILE}.gpg" &>/dev/null
				else
					scp -qp "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5" &>/dev/null
					scp -qp "${TARBALL}" "${UPLOAD_URL}/${TARBALL_FILE}" &>/dev/null
				fi
				;;
			https)
				UPLOAD_URL_MD5=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}.md5/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
				if (( ENCRYPTED_TARBALL )); then
					UPLOAD_URL=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}.gpg/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
					curl -s -L -A SupportConfig -T "${TARBALL}.md5" "${UPLOAD_URL_MD5}" &>/dev/null
					curl -s -L -A SupportConfig -T "${TARBALL}.gpg" "${UPLOAD_URL}" &>/dev/null
				else
					UPLOAD_URL=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
					curl -s -L -A SupportConfig -T "${TARBALL}.md5" "${UPLOAD_URL_MD5}" &>/dev/null
					curl -s -L -A SupportConfig -T "${TARBALL}" "${UPLOAD_URL}" &>/dev/null
				fi
				;;
			*)
				exit 7
				;;
			esac
		else
			if (( $VAR_OPTION_SBM )); then
				echo "Uploading Tar Ball..."
			else
				echo "Uploading Tar Ball"
				ehr
			fi
			echo
			case $UPLOAD_SERVICE in
			ftps|ftpes)
				UPLOAD_URL=$(sed -e 's/ftpes:/ftp:/g;s/ftps:/ftp:/g' <<< ${VAR_OPTION_UPLOAD_TARGET})
				if (( VAR_OPTION_SBM )); then
					wait_trace_on -t "curl -sT ${TARBALL}.md5 ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.md5"
					curl -sT ${TARBALL}.md5 ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.md5 &>/dev/null
					wait_trace_off -t
					if (( ENCRYPTED_TARBALL )); then
						wait_trace_on -t "curl -sT ${TARBALL}.gpg ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.gpg"
						curl -sT ${TARBALL}.gpg ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.gpg &>/dev/null
						wait_trace_off -t
					else
						wait_trace_on -t "curl -sT ${TARBALL} ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}"
						curl -sT ${TARBALL} ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE} &>/dev/null
						wait_trace_off -t
					fi
				else
					echo "curl -#T ${TARBALL}.md5 ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.md5"
					echo
					curl -#T ${TARBALL}.md5 ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.md5
					echo
					if (( ENCRYPTED_TARBALL )); then
						echo "curl -#T ${TARBALL}.gpg ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.gpg"
						echo
						curl -#T ${TARBALL}.gpg ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}.gpg
					else
						echo "curl -#T ${TARBALL} ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}"
						echo
						curl -#T ${TARBALL} ${FTPES_OPTIONS} ${UPLOAD_URL}/${TARBALL_FILE}
					fi
				fi
				;;
			ftp)
				UPLOAD_URL=${VAR_OPTION_UPLOAD_TARGET}
				if (( VAR_OPTION_SBM )); then
					wait_trace_on -t "curl -sT \"${TARBALL}.md5\" \"${UPLOAD_URL}/${TARBALL_FILE}.md5\""
					curl -sT "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5" &>/dev/null
					wait_trace_off -t
					if (( ENCRYPTED_TARBALL )); then
						wait_trace_on -t "curl -sT \"${TARBALL}.gpg\" \"${UPLOAD_URL}/${TARBALL_FILE}.gpg\""
						curl -sT "${TARBALL}.gpg" "${UPLOAD_URL}/${TARBALL_FILE}.gpg" &>/dev/null
						wait_trace_off -t
					else
						wait_trace_on -t "curl -sT \"${TARBALL}\" \"${UPLOAD_URL}/${TARBALL_FILE}\""
						curl -sT "${TARBALL}" "${UPLOAD_URL}/${TARBALL_FILE}" &>/dev/null
						wait_trace_off -t
					fi
				else
					echo "curl -#T \"${TARBALL}.md5\" \"${UPLOAD_URL}/${TARBALL_FILE}.md5\""
					echo
					curl -#T "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5"
					echo
					if (( ENCRYPTED_TARBALL )); then
						echo "curl -#T \"${TARBALL}.gpg\" \"${UPLOAD_URL}/${TARBALL_FILE}.gpg\""
						echo
						curl -#T "${TARBALL}.gpg" "${UPLOAD_URL}/${TARBALL_FILE}.gpg"
					else
						echo "curl -#T \"${TARBALL}\" \"${UPLOAD_URL}/${TARBALL_FILE}\""
						echo
						curl -#T "${TARBALL}" "${UPLOAD_URL}/${TARBALL_FILE}"
					fi
				fi
				;;
			scp)
				UPLOAD_URL=$(echo ${VAR_OPTION_UPLOAD_TARGET} | sed -e 's!scp://!!g;s!/!:/!')
				if (( VAR_OPTION_SBM )); then
					wait_trace_on -t "scp -qp \"${TARBALL}.md5\" \"${UPLOAD_URL}/${TARBALL_FILE}.md5\""
					scp -qp "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5" &>/dev/null
					wait_trace_off -t
					if (( ENCRYPTED_TARBALL )); then
						wait_trace_on -t "scp -qp \"${TARBALL}.gpg\" \"${UPLOAD_URL}/${TARBALL_FILE}.gpg\""
						scp -qp "${TARBALL}.gpg" "${UPLOAD_URL}/${TARBALL_FILE}.gpg" &>/dev/null
						wait_trace_off -t
					else
						wait_trace_on -t "scp -qp \"${TARBALL}\" \"${UPLOAD_URL}/${TARBALL_FILE}\""
						scp -qp "${TARBALL}" "${UPLOAD_URL}/${TARBALL_FILE}" &>/dev/null
						wait_trace_off -t
					fi
				else
					echo "scp -p \"${TARBALL}.md5\" \"${UPLOAD_URL}/${TARBALL_FILE}.md5\""
					echo
					scp -p "${TARBALL}.md5" "${UPLOAD_URL}/${TARBALL_FILE}.md5"
					echo
					if (( ENCRYPTED_TARBALL )); then
						echo "scp -p \"${TARBALL}.gpg\" \"${UPLOAD_URL}/${TARBALL_FILE}.gpg\""
						echo
						scp -p "${TARBALL}.gpg" "${UPLOAD_URL}/${TARBALL_FILE}.gpg"
					else
						echo "scp -p \"${TARBALL}\" \"${UPLOAD_URL}/${TARBALL_FILE}\""
						echo
						scp -p "${TARBALL}" "${UPLOAD_URL}/${TARBALL_FILE}"
					fi
				fi
				;;
			https)
				UPLOAD_URL_MD5=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}.md5/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
				if (( VAR_OPTION_SBM )); then
					wait_trace_on -t "curl -s -L -A SupportConfig -T \"${TARBALL}.md5\" \"${UPLOAD_URL_MD5}\""
					curl -s -L -A SupportConfig -T "${TARBALL}.md5" "${UPLOAD_URL_MD5}" &>/dev/null
					wait_trace_off -t
					if (( ENCRYPTED_TARBALL )); then
						UPLOAD_URL=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}.gpg/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
						wait_trace_on -t "curl -s -L -A SupportConfig -T \"${TARBALL}.gpg\" \"${UPLOAD_URL}\""
						curl -s -L -A SupportConfig -T "${TARBALL}.gpg" "${UPLOAD_URL}" &>/dev/null
						wait_trace_off -t
					else
						UPLOAD_URL=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
						wait_trace_on -t "curl -s -L -A SupportConfig -T \"${TARBALL}\" \"${UPLOAD_URL}\""
						curl -s -L -A SupportConfig -T "${TARBALL}" "${UPLOAD_URL}" &>/dev/null
						wait_trace_off -t
					fi
				else
					echo "curl -v -L -A SupportConfig -T \"${TARBALL}.md5\" \"${UPLOAD_URL_MD5}\""
					echo
					curl -v -L -A SupportConfig -T "${TARBALL}.md5" "${UPLOAD_URL_MD5}"
					echo
					if (( ENCRYPTED_TARBALL )); then
						UPLOAD_URL=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}.gpg/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
						echo "curl -v -L -A SupportConfig -T \"${TARBALL}.gpg\" \"${UPLOAD_URL}\""
						echo
						curl -v -L -A SupportConfig -T "${TARBALL}.gpg" "${UPLOAD_URL}"
					else
						UPLOAD_URL=$(sed -e "s/{[Tt][Aa][Rr][Bb][Aa][Ll][Ll]}/${TARBALL_FILE}/g" <<< ${VAR_OPTION_UPLOAD_TARGET})
						echo "curl -v -L -A SupportConfig -T \"${TARBALL}\" \"${UPLOAD_URL}\""
						echo
						curl -v -L -A SupportConfig -T "${TARBALL}" "${UPLOAD_URL}"
					fi
				fi
				;;
			*)
				echo "ERROR: Unsupported upload service type: ${UPLOAD_SERVICE}"
				echo
				echo "  Supported service types: ftp, ftps/ftpes, https, scp"
				echo "  Example URI: ${SUSE_UPLOAD_NA_FTPES}"
				echo
				echo "  VAR_OPTION_UPLOAD_TARGET=\"${VAR_OPTION_UPLOAD_TARGET}\""
				;;
			esac
			echo
		fi
	fi
}

post_lsmod_list() {
	OF=modules.txt
	log_write $OF "#==[ Command ]======================================#"
	log_write $OF "# lsmod - Post run module list"
	MOD_FIRST=$(mktemp $LOG/mod-first-XXXXXXXXXXXXXXX)
	MOD_LAST=$(mktemp $LOG/mod-last-XXXXXXXXXXXXXXX)

	# Get module list before running supportconfig commands
	wait_trace_on "grep -n '#==\[ Command \]' $LOG/$OF"
	LN_INIT=$(grep -n '#==\[ Command \]' $LOG/$OF | head -1 | cut -d: -f1)
	LN_FIN=$(grep -n '#==\[ Command \]' $LOG/$OF | head -2 | tail -1 | cut -d: -f1)
	LN_TOTAL=$((LN_FIN - LN_INIT))
	head -$LN_TOTAL $LOG/$OF | sed -e '/^#/d;/Module.*Size.*Used/d;/^$/d' | cut -d' ' -f1 | sort > $MOD_FIRST
	MOD_CNT_BEFORE=$(cat $MOD_FIRST | wc -l)
	log_write $OF "Modules Loaded Before Suportconfig:       $MOD_CNT_BEFORE"
	wait_trace_off

	# Get module list after running supportconfig commands
	wait_trace_on "lsmod | sed -e '1d' | cut -d' ' -f1 | sort"
	lsmod | sed -e '1d' | cut -d' ' -f1 | sort > $MOD_LAST
	MOD_CNT_AFTER=$(cat $MOD_LAST | wc -l)
	log_write $OF "Modules Loaded After Suportconfig:        $MOD_CNT_AFTER"
	wait_trace_off

	# Show the module list difference
	MOD_CNT_ADDED=$((MOD_CNT_AFTER - MOD_CNT_BEFORE))
	log_write $OF "Modules Loaded Incident to Supportconfig: $MOD_CNT_ADDED"
	if [ $MOD_CNT_ADDED -gt 0 ]; then
		log_write $OF
		diff $MOD_FIRST $MOD_LAST | grep '>' >> $LOG/$OF
		log_write $OF
		log_write $OF "Use -k to prevent supportconfig from loading modules"
		log_write $OF "needed for system analysis. Using -k is not recommended."
		log_write $OF "See supportconfig(8)."
	fi
	log_write $OF
	log_write $OF

	# clean up
	rm -f $MOD_FIRST $MOD_LAST
}

remove_local_tarball() {
	if [ $VAR_OPTION_RM_LOCAL_FILE -gt 0 ]; then
		log2sys "Deleting $TARBALL"
		echo "Deleting local supportconfig file: $TARBALL"
		rm -f $TARBALL ${TARBALL}.md5
		echo
	else
		log2sys "Saved Tar Ball: $TARBALL"
	fi
}

exit_code() {
	XC=$1
	shift
	MSG="$@"
	[ -n "$MSG" ] && log2sys "$MSG"
	log2sys "END"
	exit $XC
}

normalize_base() {
	# Valid identifiers for tar ball filename
	# %r - SR number if provided
	# %s - Server's hostname
	# %d - Supportconfig run date
	# %t - Supportconfig run time
	# %u - Unique ID, UUID (prefered) or Seconds since 1970
	# %B - Base filename options = %s_%d_%t
	test -n "$CONTACT_SRNUM" && BASE=$(echo $BASE | sed -e "s/%r/SR${CONTACT_SRNUM}/g") || BASE=$(echo $BASE | sed -e "s/%r//g") 
	BASE=$(echo $BASE | sed -e "s/%s/${SC_SRV}/g")
	BASE=$(echo $BASE | sed -e "s/%d/${SC_DATE}/g")
	BASE=$(echo $BASE | sed -e "s/%t/${SC_TIME}/g")
	BASE=$(echo $BASE | sed -e "s/%u/${SC_UID}/g")
	BASE=$(echo $BASE | sed -e "s/%B/${SC_SRV}_${SC_DATE}_${SC_TIME}/g")
}

write_xml_file() {
	wait_trace_on "write_xml_file supportconfig"
	echo \<\?xml\ version=\"1.0\"\?\> >> $LOG/$XML_FILE
	if [ -s $VAR_OPTION_HEADER_FILE ]; then
		echo '<note>' >> $LOG/$XML_FILE
		cat $VAR_OPTION_HEADER_FILE >> $LOG/$XML_FILE
		echo '</note>' >> $LOG/$XML_FILE
	fi
	echo '<summary>' >> $LOG/$XML_FILE
	xml_write 'scriptversion' "${SVER}"
	xml_write 'scriptdate' "${SDATE}"
	xml_write 'rundate' "${SC_DATE}"
	xml_write 'runtime' "${SC_TIME}"
	xml_write 'logdir' "${LOG}"
	HOSTOUT=$(hostname --long 2>/dev/null)
	if [ -n "$HOSTOUT" ]; then
		xml_write 'hostname' "$HOSTOUT"
	else
		xml_write 'hostname' "$(hostname 2>/dev/null)"
	fi
	xml_write 'arch' "$(uname -i)"
	xml_write 'kernel' "$(uname -r)"
	if [ -s /etc/SuSE-release ]; then
		if rpm -q 'SUSE_SLES_SAP-release' &>/dev/null; then
			xml_write 'sle_type' 'SUSE Linux Enterprise Server for SAP Applications'
		elif rpm -q 'SLES-for-VMware-release' &>/dev/null; then
			xml_write 'sle_type' 'SUSE Linux Enterprise Server for VMware'
		elif grep -i 'enterprise server' /etc/SuSE-release &>/dev/null; then
			xml_write 'sle_type' 'SUSE Linux Enterprise Server'
		elif grep -i 'enterprise desktop' /etc/SuSE-release &>/dev/null; then
			xml_write 'sle_type' 'SUSE Linux Enterprise Desktop'
		else
			xml_write 'sle_type' ''
		fi
		xml_write 'sle_version' "$(sed -ne 's/VERSION = //p' /etc/SuSE-release)"
		xml_write 'sle_patchlevel' "$(sed -ne 's/PATCHLEVEL = //p' /etc/SuSE-release)"
	else
		xml_write 'sle_type' ''
		xml_write 'sle_version' ''
		xml_write 'sle_patchlevel' ''
	fi

	echo '</summary>' >> $LOG/$XML_FILE
	echo '<customer>' >> $LOG/$XML_FILE
	test -n "$VAR_OPTION_CONTACT_COMPANY" && 		{ xml_write 'company' "$VAR_OPTION_CONTACT_COMPANY"; }
	test -n "$VAR_OPTION_CONTACT_STOREID" && 		{ xml_write 'storeid' "$VAR_OPTION_CONTACT_STOREID"; }
	test -n "$VAR_OPTION_CONTACT_TERMINALID" && 	{ xml_write 'terminalid' "$VAR_OPTION_CONTACT_TERMINALID"; }
	test -n "$VAR_OPTION_CONTACT_NAME" && 			{ xml_write 'contact' "$VAR_OPTION_CONTACT_NAME"; }
	test -n "$VAR_OPTION_CONTACT_PHONE" && 		{ xml_write 'phone' "$VAR_OPTION_CONTACT_PHONE"; }
	test -n "$VAR_OPTION_CONTACT_EMAIL" && 		{ xml_write 'email' "$VAR_OPTION_CONTACT_EMAIL"; }
	xml_write 'srnum' "$CONTACT_SRNUM"
	echo '</customer>' >> $LOG/$XML_FILE
	wait_trace_off

	if [ -d /etc/products.d ]; then
		echo '<products>' >> $LOG/$XML_FILE
		for i in $(find -L /etc/products.d/ -type f)
		do
			if file $i | grep XML &>/dev/null; then
				wait_trace_on "write_xml_file $i"
				sed -e 1d $i >> $LOG/$XML_FILE
				wait_trace_off
			fi			
		done
		echo '</products>' >> $LOG/$XML_FILE
	fi
	sed -i -e '/^[[:space:]]*$/d' $LOG/$XML_FILE
}

email_info() {
	printlog "Email..."
	test $OPTION_EMAIL -eq 0 && { echolog Excluded; return 1; }
	OF=email.txt
	addHeaderFile $OF
	if rpm_verify $OF postfix; then
		EXCLUDE_LIST="/etc/postfix/sasl_passwd"
		log_cmd $OF "systemctl status postfix.service"
		log_cmd $OF "postconf -n"
		log_cmd $OF "postconf -d"
		log_cmd $OF "postqueue -p"
		log_cmd $OF "postqueue -j"
		log_cmd $OF 'bash -c "comm -23 <(postconf -n) <(postconf -d)"'
		FILES=$(find /etc/postfix/ ! -name '*.rpmnew' -type f -exec sh -c 'f=$1; file -bL --mime $f | grep -q "^text/plain" && echo $f' {} {} \; | egrep -v "${EXCLUDE_LIST}" | sort)
		conf_files $OF $FILES
		FILES="/var/log/mail.err /var/log/mail.warn /var/log/mail.info /var/log/mail"
		(( $ADD_OPTION_LOGS > 0 )) && log_files $OF 0 $FILES || log_files $OF $VAR_OPTION_LINE_COUNT $FILES
		_sanitize_file $OF
		echolog Done
	else
		echolog Skipped
	fi
}

##############################################################################
#  main 
##############################################################################

log2sys "BEGIN Version: $SVER"

CURRENTUID=$(id -u)
if [ $CURRENTUID -ne 0 ]; then
	echo "ERROR: You must be logged in as root."
	echo "       $(id)"
	echo
	exit_code 1 "ERROR: You must be logged in as root"
fi

# check for valid conf file
if [ -s ${SC_CONF:="/etc/${CURRENT_SCRIPT}.conf"} ]; then
	if [ -x /usr/bin/dos2unix ]; then
		/usr/bin/dos2unix $SC_CONF &>/dev/null
	else
		sed -i -e 's/\r//g' $SC_CONF &>/dev/null
	fi
	. ${SC_CONF}
fi

init_plugins on
get_sles_ver
NSA_CHECK=0
ALL_ARGS="$@"
while getopts :\#AB:CDE:FG:H:I:JLM:N:O:P:QR:S:T:U:W:X:abcdf:ghi:klmo:pqr:st:uvwx:y TMPOPT
do
	case $TMPOPT in
	\:)	clear; title
			case $OPTARG in
			*) echo "ERROR: Missing Argument -$OPTARG"
				;;
			esac
			echo; show_help; exit_code 0 "ERROR: Missing Argument -$OPTARG" ;;
	\?)	clear; title
			case $OPTARG in
			*) echo "ERROR: Invalid Option -$OPTARG"
				;;
			esac
			echo; show_help; exit_code 0 "ERROR: Invalid Options -$OPTARG" ;;
	A) set_to_all ;;
	B) VAR_OPTION_CUSTOM_ARCH="$OPTARG" ;;
	C) clear; title; echo "Overwriting $SC_CONF with default options."; gen_sysconfig; exit_code 0 ;;
	D) set_to_default ;;
	E) VAR_OPTION_CONTACT_EMAIL="$OPTARG" ;;
	F) get_features; exit_code 0 ;;
	G) VAR_OPTION_GPG_UID="$OPTARG" ;;
	H) VAR_OPTION_PENGINE_FILES_LIMIT=$OPTARG ;;
	I) VAR_OPTION_LINE_COUNT=$OPTARG ;;
	J) VAR_OPTION_EXHAUSTIVE_MEM=1 ;;
	L) ADD_OPTION_FSLIST=1 ;;
	Q) VAR_OPTION_SILENT=1 ;;
	T) VAR_OPTION_BIN_TIMEOUT_SEC=$OPTARG ;;
	O) VAR_OPTION_CONTACT_COMPANY="$OPTARG" ;;
	M) VAR_OPTION_CONTACT_TERMINALID="$OPTARG" ;;
	N) VAR_OPTION_CONTACT_NAME="$OPTARG" ;;
	P) VAR_OPTION_CONTACT_PHONE="$OPTARG" ;;
	R) VAR_OPTION_LOG_DIRS="$OPTARG" ;;
	X) VAR_OPTION_MSG_MAXSIZE=$OPTARG ;;
	S) VAR_OPTION_SAR_FILES_LIMIT=$OPTARG ;;
	U) VAR_OPTION_UPLOAD_TARGET="$OPTARG" && UPLOAD_TARBALL=1 ;;
	W) VAR_OPTION_CONTACT_STOREID="$OPTARG" ;;
	a) UPLOAD_TARBALL=1; VAR_OPTION_UPLOAD_TARGET=${VAR_OPTION_UPLOAD_TARGET_ALT} ;;
	b) VAR_OPTION_SBM=1 ;;
	c) ADD_OPTION_LOCAL_ONLY=1 ;;
	d) ADD_OPTION_MINDISK=1 ;;
	g) COMPRESS="tgz"; COMPRESS_OPT="zcf" ;;
	h) title; show_help; exit_code 0 ;;
	i) SELECTED_FEATURE_LIST=$OPTARG; set_to_min; selected_features on ;;
	k) MIN_OPTION_AUTOMOD=0 ;;
	l) ADD_OPTION_LOGS=1 ;;
	p) init_plugins off ;;
	m) set_to_min ;;
	o) SELECTED_FEATURE_LIST=$OPTARG; toggle_features ;;
	q) VAR_OPTION_UNIQUE_FILE=1 ;;
	r) CONTACT_SRNUM=$OPTARG;
		if valid_srnum; then
			BASE="${ARCHIVE_PREFIX}%r_%B"
		else
			clear; title
			echo "ERROR: Invalid SR Number, -${TMPOPT} $CONTACT_SRNUM"
			echo "       Must be a numeric value only"
			echo; show_help; exit_code 2
		fi ;;
	\#) set_to_min; MIN_OPTION_HC=0; MIN_OPTION_HARDWARE=0; MIN_OPTION_YAST=0; MIN_OPTION_SYSLOGS=0; NSA_CHECK=1; COMPRESS="tgz"; COMPRESS_OPT="zcf" ;;
	s) ADD_OPTION_SLP=1 ;;
	u) UPLOAD_TARBALL=1 ;;
	v) ADD_OPTION_RPMV=1 ;;
	w) VAR_OPTION_WAIT_TRACE=1; VAR_OPTION_SBM=1 ;;
	x) SELECTED_FEATURE_LIST=$OPTARG; set_to_all; selected_features off ;;
	y) ADD_OPTION_MAXYAST=1 ;;
	t) TARGET_DIRECTORY=$OPTARG && SAVE_LOGS_ONLY=1;;
	f) FROM_DIRECTORY=$OPTARG  && USE_SAVED_LOGS_ONLY=1;;
	esac
done

test $ADD_OPTION_LOGS -gt 0 && ADD_OPTION_MAXYAST=1

umask 0077
log2sys "Initialize"

if [ -n "$TARGET_DIRECTORY" ]; then
	VAR_OPTION_LOG_DIRS=$TARGET_DIRECTORY
fi

# Ensures files uploaded have unique file names
if (( UPLOAD_TARBALL )); then
	VAR_OPTION_UNIQUE_FILE=1
fi

# Add custom tar ball name element
if [ -n "$VAR_OPTION_CUSTOM_ARCH" ]; then
	TMP=$(echo "$VAR_OPTION_CUSTOM_ARCH" | sed -e 's/ /_/g')
	BASE="${ARCHIVE_PREFIX}${TMP}"
fi

if (( VAR_OPTION_UNIQUE_FILE )); then
	NOTFOUND=$(echo $BASE | grep '%u')
	test -z "$NOTFOUND" && BASE="${BASE}_%u" #add UID if not present already
fi

if [ -n "$FROM_DIRECTORY" ]; then
	VAR_OPTION_LOG_DIRS=$FROM_DIRECTORY
	BASE=$(ls -t $FROM_DIRECTORY | grep nts | head -n1)
fi

for LOG in $VAR_OPTION_LOG_DIRS
do
	# If a full path was not assigned, the cwd will be prepended to the LOG path
	VALID_LOG=$(echo $LOG | grep '^/')
	if [ -z "$VALID_LOG" ]; then
		VALID_LOG=$(echo $LOG | grep '^\./')
		CURRENT_PATH="$(pwd)"
		if [ -n "$VALID_LOG" ]; then
			LOG="${CURRENT_PATH}/${LOG:2}"
		else
			LOG="${CURRENT_PATH}/${LOG}"
		fi
	fi
	# Create the paths
	normalize_base
	[ $USE_SAVED_LOGS_ONLY -eq 0 ] && check_log_dir
	LOG=${LOG}/${BASE}
	if mkdir -p $LOG &>/dev/null; then 
		unset LOGERROR
		break
	else
		echo "ERROR: Cannot create $LOG"
		LOGERROR=1
	fi
done

test $LOGERROR && { echo; exit_code 3; }
export LOG

if [ "$USE_SAVED_LOGS_ONLY" != "1" ]; then

	if ! (( $VAR_OPTION_SILENT )); then
		if ! (( $VAR_OPTION_SBM )); then
			clear
		fi
	fi
	test $VAR_OPTION_SILENT -gt 0 && title >> $LOG/$BASIC_ENVF || title | tee -a $LOG/$BASIC_ENVF
	if run_status; then
		echo "Error: A supportconfig instance is already running, PID $(cat ${RUN_PID_FILE})"
		echo
		exit_code 10
	else
		run_status start
	fi

	RPM_QA_FILE_PATH=$(mktemp ${LOG}/rpm_qa.XXXXXXXXXX)
	RPM_DIST_FILE_PATH=$(mktemp ${LOG}/rpm_dist.XXXXXXXXXX)
	RPM_QA_FILE=$(basename $RPM_QA_FILE_PATH)
	RPM_DIST_FILE=$(basename $RPM_DIST_FILE_PATH)

	addHeaderFile $CSFILE
	log_entry $CSFILE note "Privacy Statement"
	log_write $CSFILE "Detailed system information and logs are collected and organized in a"
	log_write $CSFILE "manner that helps reduce service request resolution times. Private system"
	log_write $CSFILE "information can be disclosed when using this tool. If this is a concern,"
	log_write $CSFILE "please prune private data from the log files. Several startup options"
	log_write $CSFILE "are available to exclude more sensitive information. Supportconfig data is"
	log_write $CSFILE "used only for diagnostic purposes and is considered confidential information."
	log_write $CSFILE "See https://www.suse.com/company/legal/"
	log_write $CSFILE
	rpm_verify ${CSFILE} supportutils

	echolog "Gathering system information"
	log_write ${CSFILE} 	"  Script Version:    ${SVER}"
	log_write ${CSFILE} 	"  Script Date:       ${SDATE}"
	echolog 					"  Data Directory:    ${LOG}"
	log2sys "Data Directory: ${LOG}"

	if bad_plugin_dir; then
		echolog "  WARNING: Invalid plugin directory, all plugins will be skipped."
		echo    "           See $CSFILE for details."
		log_write ${CSFILE} "   Plugin Directory:  $XPLUGIN_DIR"
		log_write ${CSFILE} "   Owner.Group:       ${XPLUGIN_DIR_OWNER}.${XPLUGIN_DIR_GRP}"
		log_write ${CSFILE} "   Access Rights:     $XPLUGIN_DIR_MODE"
		log_write ${CSFILE} "   The plugin directory should be writable only for root and group root."
		log_write ${CSFILE} "   Currently SUID, SGID and sticky bits are not allowed."
	fi
	log_write ${CSFILE} "  Environment Value: $SLES_VER ($KERNVER)"
	log_write ${CSFILE} "  Command with Args: $0 $ALL_ARGS"
	log2sys "Supportconfig Args: $ALL_ARGS"

	test -s $SC_CONF && log_write ${CSFILE} "  Using Options:     $SC_CONF"
	echolog

	log_options

	basic_healthcheck	#Minimum Requirement
	rpm_info				#Minimum Requirement
	basic_environment	#Minimum Requirement
	open_files
	module_info
	memory_info
	disk_info
	btrfs_info
	tuned_info
	yast_files			#Minimum Requirement
	fslist_info
	audit_info
	crash_info
	email_info
	ntp_info
	proc_info
	boot_info
	slert_info
	update_info
	smt_info
	ha_info
	ocfs2_info
	drbd_info
	haproxy_info
	pam_info
	ldap_info
	sssd_info
	cimom_info
	environment_info
	root_shell_history_info
	etc_info
	sysconfig_info
	sysfs_info
	systemd_info
	docker_info
	cron_info
	udev_info
	lvm_info
	soft_raid_info
	mpio_info
	net_info
	web_info
	ib_info
	dns_info
	dhcp_info
	slp_info
	ssh_info
	iscsi_info
	samba_info
	nfs_info
	autofs_info
	sar_info
	apparmor_info
	xen_info
	kvm_info
	lxc_info
	x_info
	print_info
	smartmon_info
	[[ -s ${FSLIST_ADD_FILE} ]] && fslist_ufiles_info
	hardware_info		#Minimum Requirement
	rpm_full_verify
	exec_plugins
	(( OPTION_MOD > 0 )) && post_lsmod_list
	log2sys "Finished Gathering"
	messages_file		#Minimum Requirement
	write_xml_file

	rm -f $LOG/$RPM_QA_FILE $LOG/$RPM_DIST_FILE
	timed_cmd_cleanup
	test $VAR_OPTION_SILENT -eq 0 && { echo; }

else
	test $VAR_OPTION_SILENT -eq 0 && { clear; title; }
fi

# don't continue if SAVE_LOGS_ONLY is set
[ "$SAVE_LOGS_ONLY" = "1" ] && exit_code 0;


# creating tar ball for NTS
TARBALL=${LOG}.${COMPRESS}
log2sys "Creating Tar Ball"
if ! (( $VAR_OPTION_SILENT )); then
	if (( $VAR_OPTION_SBM )); then
		echo 'Creating Tar Ball...'
	else
		echo 'Creating Tar Ball'
	fi
fi

cd $LOG
cd ..
wait_trace_on -t "tar ${COMPRESS_OPT} ${TARBALL} --mode='ug+rw' ${BASE}/*"
tar ${COMPRESS_OPT} ${TARBALL} --mode='ug+rw' ${BASE}/*
LOGSIZE=$(ls -lh ${TARBALL} | awk '{print $5}')
wait_trace_off -t
wait_trace_on -t "md5sum $TARBALL"
md5sum $TARBALL | awk '{print $1}' > ${TARBALL}.md5
LOGMD5=$(cat ${TARBALL}.md5)
wait_trace_off -t

rm -rf $LOG

if [ $VAR_OPTION_SILENT -eq 0 ]; then
cat << EOF1

==[ DONE ]===================================================================
  Log file tar ball: ${TARBALL}
  Log file size:     ${LOGSIZE}
  Log file md5sum:   ${LOGMD5}
=============================================================================


EOF1
fi

trap "{ echo TERMINATED BY USER; echo; exit 5; }" SIGINT
trap "{ echo SKIPPED BY USER; return 4; }" SIGQUIT

test -n "$VAR_OPTION_GPG_UID" && encrypt_tarball
upload_tarball
remove_local_tarball
run_status stop
log2sys "END"


