#!/usr/bin/bash
#
# Author: Lee Keitel
# License: MIT
#

## Script version
VERSION="3.0.4"

## Directory of running script
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPTPATH="$DIR/$(basename "$0")"

## Current datetime
DATENOW="$(date "+%F %H:%M:%S")"

echoError() {
	>&2 echo -e "$1"
}

CONFFILE=""

# Import portable configuration
if [ -f "$DIR/sysreporter.conf" ]; then
	CONFFILE="$DIR/sysreporter.conf"
# Import server specific configuration
elif [ -f /etc/sysreporter/sysreporter.conf ]; then
	CONFFILE="/etc/sysreporter/sysreporter.conf"
else
	echoError "No configuration file found"
	exit 1
fi

# Safely load in configuration options
shopt -s extglob
unixconfig="/tmp/$(basename $CONFFILE).unix"
tr -d '\r' < $CONFFILE > $unixconfig # Ensure unix line endings
while IFS='= ' read lhs rhs; do
	if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then
		rhs="${rhs%%\#*}"    # Del inline right comments
		rhs="${rhs%%*( )}"   # Del trailing spaces
		rhs="${rhs%\"*}"     # Del opening string quotes
		rhs="${rhs#\"*}"     # Del closing string quotes
		declare $lhs="$rhs"
	fi
done < $unixconfig

# Check and set any missing configuration settings
if [ -z ${SERVERNAME+x} ]; then SERVERNAME="$(hostname)"; fi
if [ -z ${MAILER+x} ]; then MAILER="ssmtp"; fi
if [ -z ${EMAIL_TO+x} ]; then EMAIL_TO=""; fi
if [ -z ${EMAIL_REPORT+x} ]; then
	[ -n "$EMAIL_TO" ] && EMAIL_REPORT=true || EMAIL_REPORT=false
fi
if [ -z ${EMAIL_FROM+x} ]; then EMAIL_FROM="root@$SERVERNAME"; fi
if [ -z ${TITLE+x} ]; then TITLE="Server Report for $SERVERNAME on $DATENOW"; fi
if [ -z ${EMAIL_SUBJECT+x} ]; then EMAIL_SUBJECT="Server Report - $SERVERNAME"; fi
if [ -z ${REPORTSDIR+x} ]; then REPORTSDIR="$DIR/reports.d"; fi
if [ -z ${TEMPDIR+x} ]; then TEMPDIR="$DIR/tmp"; fi
if [ -z ${FILTER+x} ]; then FILTER=*; fi
if [ -z ${LOGFILE+x} ]; then LOGFILE="$TEMPDIR/compiledlog.log"; fi
if [ -z ${TEMPMAIL+x} ]; then TEMPMAIL="$TEMPDIR/mail"; fi
if [ -z ${CMDTIMEOUT+x} ]; then CMDTIMEOUT=20; fi

# Functions
cleanup() {
	cat /dev/null > "$LOGFILE"
	cat /dev/null > "$TEMPMAIL"
}

checkTmpDir() {
	if [ ! -d "$TEMPDIR" ]; then
		mkdir -p "$TEMPDIR"
		if [ $? != 0 ]; then
			echoError "Can't make temporary directory $TEMPDIR"
			exit 1
		fi
	fi
}

print_to_report() {
	echo -e "$1" >> "$LOGFILE"
}

print_header() {
	print_to_report ">>> $1 <<<\n"
}

cmd_show() {
	ENABLED_ARR=()
	DISABLED_ARR=()

	cd "$REPORTSDIR"
	for f in $FILTER; do
		if [ -x "$f" ]; then
			ENABLED_ARR+=("$f")
		else
			DISABLED_ARR+=("$f")
		fi
	done
	cd "$DIR"

	echo "Configuration:"
	echo "Conf File: $CONFFILE"
	echo "Reports Dir: $REPORTSDIR"
	echo "Servername: $SERVERNAME"
	echo "Title: $TITLE"
	echo "Email Report: $EMAIL_REPORT"
	echo "Send Email To: $EMAIL_TO"
	echo "Command Timeout: $CMDTIMEOUT seconds"
	echo
	echo "Enabled Reports:"
	for f in "${ENABLED_ARR[@]}"; do echo "$f"; done
	echo
	echo "Disabled Reports:"
	for f in "${DISABLED_ARR[@]}"; do echo "$f"; done
}

cmd_enable_disable() {
	cd "$REPORTSDIR"
	for f in $FILTER; do
		if [[ "$f" =~ "$2" ]]; then
			case $1 in
			enable)
				echo "Enabling $f"
				chmod +x $f
				;;
			disable)
				echo "Disabling $f"
				chmod -x $f
			esac
		fi
	done
	cd "$DIR"
}

cmd_run() {
	checkTmpDir
	cleanup
	print_header "$TITLE"

	cd "$REPORTSDIR"
	for f in $FILTER; do
		if [ -x "$f" ]; then
			REPORT="$(timeout $CMDTIMEOUT ./$f)"
			if [ $? -eq 124 ]; then
				print_to_report "--- Truncated report, command $f timed out ---"
			fi
			# We'll print whatever header and body as received
			print_header "$(echo "$REPORT" | head -1)"
			print_to_report "$(echo "$REPORT" | tail -n +2)"
			print_to_report
		fi
	done
	cd "$DIR"

	case "$1" in
	stdout)
		cat "$LOGFILE"
		;;
	email)
		;&
	*) # Default, implied "email"
		mail_report
	esac
	return
}

mail_report() {
	if ! $EMAIL_REPORT; then
		return 0
	fi

	if [ -z "$(which $MAILER 2> /dev/null)" ]; then
		echoError "Can't send mail, mailer $MAILER not found"
		return 1
	fi

	if [ -z "$EMAIL_TO" ]; then
		echoError "No email addresses specified, can't send email"
		return 1
	fi

	echo "To: $EMAIL_TO" >> "$TEMPMAIL"
	echo "From: $EMAIL_FROM" >> "$TEMPMAIL"
	echo "Subject: $EMAIL_SUBJECT" >> "$TEMPMAIL"
	echo >> "$TEMPMAIL"
	cat "$LOGFILE" >> "$TEMPMAIL"
	$MAILER "$EMAIL_TO" < "$TEMPMAIL"
}

cmd_usage() {
	cmd_version
	echo
	echo "Usage: $(basename $0) [command] [options]"
	echo
	echo "Commands:"
	echo "    run [stdout|email]"
	echo "    show"
	echo "    enable"
	echo "    disable"
	echo "    help"
	echo "    version"
}

cmd_version() {
	echo "System Reporter"
	echo "Get system stats and email them to a sysadmin"
	echo "Version $VERSION"
}

cd "$DIR"

# Dispatch command to appropiate function
case "$1" in
	run) shift;				cmd_run "$@" ;;
	show) shift;			cmd_show "$@" ;;
	enable|disable) 		  cmd_enable_disable "$@" ;;
	version|--version) shift;  cmd_version "$@" ;;
	*) cmd_usage "$@" ;;
esac
exit 0
