#!/bin/bash

# Log file for cc scripts
EXITFILE="/var/log/YaST2/cc-scripts.log"
# error file for cc scripts - if exists, something went wrong
EXITERR="/var/log/YaST2/cc-scripts.err"

cc_echo_log() {
	# this logic is for ensuring that the file ends up on the hard disk
	# even the function is called outside the chroot
	[ -d "/mnt/var/log" ] && {
		[ -f "$EXITFILE" ] && {
			cat $EXITFILE >> /mnt/$EXITFILE
			rm -f $EXITFILE
		}
		# after the copying of the file contents, set the target
		# file name to the chroot file
		EXITFILE="/mnt/$EXITFILE"
	}

	[ ! -d $(dirname $EXITFILE) ] && {
		mkdir -p $(dirname $EXITFILE) || {
			echo "Directory for $EXITFILE cannot be created"
			exit 255
		}
		chmod 755 $(dirname $EXITFILE)
	}

	echo "$0: $@" >> $EXITFILE
}

# This is the function to be used instead of echo
# $@ data to be echoed
# return: nothing, but output on screen and log file
cc_echo() {
	cc_echo_log "$@"
	echo $@
}

# Execute a command and capture its output to log
# $@ command to be executed
# return: return code of the executed command
cc_exec_log() {
	local ret
	local out

	cc_echo_log "Executing: $@"

	"$@" 2>&1 | while IFS='' read out
	do
		cc_echo_log "$out"
	done
	# return the result code of the command
	ret=${PIPESTATUS[0]}
	return $ret
}

# Replace a given file with a new file and back up the old file
# The function ensures that the permissions are kept
# $1: new file that will be overwritten over the old old one (i.e. source)
# $2: file to be replaced (i.e. destination)
cc_replace() {
	local src=$1
	local dst=$2

	local date=$(date +"%Y%m%d%H%M%S")

	[ -z "$src" -o -z "$dst" ] && {
		echo "Missing input parameters" >&2
		return
	}

	[ ! -e "$src" -o ! -e "$dst" ] && {
		echo "Files missing" >&2
		return
	}

	local mode=$(stat -L -c '%a' $dst)
	local owner=$(stat -L -c '%U.%G' $dst)

	# Create backup
	cc_exec_log cp $dst $dst.$date
	cc_exec_log chmod $mode $dst.$date
	cc_exec_log chown $owner $dst.$date

	# copy the new file
	cc_exec_log cp -p $src $dst
	cc_exec_log chmod $mode $dst
	cc_exec_log chown $owner $dst
}

# Exit handler - to be used instead of exit()
# It uses the same parameter as exit()
# $1: exit code
# return: function NEVER returns
cc_exit() {
	local code=$1

	[ "$code" -ne 0 ] && {
		cc_echo "$0: non-recoverable ERROR exit code $code"
		[ -d "/mnt/var/log" ] && {
			[ -f "$EXITERR" ] && mv $EXITERR /mnt/$EXITERR
			EXITERR="/mnt/$EXITERR"
		}
		[ ! -d $(dirname $EXITERR) ] && {
			mkdir -p $(dirname $EXITERR) || {
				echo "Directory for $EXITERR cannot be created"
				exit 255
			}
		}
		touch $EXITERR
	}

	exit $code
}

# Report any error occurred during CC config
# in case there is an error, it returns with error code 1 - autoyast should
# cause a rerun of the script to block
report_error() {
	[ -e "$EXITERR" ] && {
		cc_echo "FAILURE: CC configuration performed with at least one error"
		cc_echo "FAILURE: Check contents of $EXITFILE for details"
		cc_echo "FAILURE: You may reboot now but the system is NOT in the evaluated configuration"
		cc_echo "FAILURE: You may also check the log file on a different console"
		exit 1
	}

	cc_echo "Common Criteria Evaluated Configuration"
	cc_echo "successfully established"
	[ "$HOSTTYPE" = "s390x" ] && {
		cc_echo
		cc_echo "The system will boot into runlevel 3"
		cc_echo "when you hit the return key now."
	}
	cc_echo
	cc_echo "Please provide system-specific settings"
	cc_echo "in the following dialogs"
	[ "$HOSTTYPE" = "s390x" ] && {
		cc_echo "by executing the command"
	        cc_echo "\"firstboot\""
	}
}

# When this "library" is pulled in, we log who called us
cc_echo_log "--- Starting execution of $0 ---"
