#!/bin/bash

export MAINDIR=/usr/local/Reductor
export LOCKDIR=/var/lock/reductor/
export BINDIR=${MAINDIR}/bin
export USERDIR=${MAINDIR}/userinfo
export HOOKDIR=${USERDIR}/hooks
export CONTRIB=${MAINDIR}/contrib
export CACHEDIR=${MAINDIR}/cache
export CONFIG=${USERDIR}/config
export MENULIB=${MAINDIR}/usr/share/menu_lib
export PRIVATE_KEY=${USERDIR}/provider.pem
export CHROOTDIR=${MAINDIR}/reductor_container
export MODULES=${CHROOTDIR}/lib/modules
export SSLDIR=${CHROOTDIR}/gost-ssl
export SSLSSLDIR=${SSLDIR}/ssl
export SSLPRIVATEDIR=${SSLDIR}/ssl
export OPENSSL=/gost-ssl/bin/openssl
export LISTDIR=${MAINDIR}/lists
export PROCLIST=/proc/net/ipt_reductor/block_list
export LOGDIR=/var/log/reductor
export LOGFILE=$LOGDIR/reductor.log
export NETWORK_SCRIPTS=/etc/sysconfig/network-scripts
export TMPDIR=/tmp/reductor/
export UPDATER=/usr/local/bin/reductor_updater.sh
export BACKUPDIR=${USERDIR}/backups/
export DUMPXML=$SSLDIR/php/dump.xml
export VENVBIN=$CHROOTDIR/virtualenv/bin/
export VENVLIBS=$CHROOTDIR/virtualenv/lib/python2.6/site-packages/

export REPO_HOST="download5.carbonsoft.ru"
export CARBONSOFT_BLACKHOLE="95.213.143.204"
export CRITICAL_UPDATE_URL="http://$REPO_HOST/carbon_reductor/centos/last_critical_update.txt"
export GOTO_SUPPORT="обратитесь в техподдержку по адресу http://helpdesk.carbonsoft.ru"
export NETWORK_SETUP_LINK="Информация о том, как настроить зеркало трафика самостоятельно имеется в статье: http://docs.carbonsoft.ru/pages/viewpage.action?pageId=48398419"
export NO_CONNECTION="Не могу связаться с сервером сигнатур! Проверьте работу сети."

export ip_regex="([0-9]{1,3}\.){3}[0-9]{1,3}"
export ip_or_ipmask_regex="([0-9]{1,3}\.){3}[0-9]{1,3}(/[0-9]{1,2})?"

get_reductor_instcode() {
	[ ! -f /proc/net/ipt_reductor/block_list ] && echo "No proc entry, bad" >&2 && return 0
	read _ num < /proc/net/ipt_reductor/block_list
	echo $num
}

show_msg() {
	if ! which dialog &>/dev/null || [ "$TERM" = 'dump' ] ; then
		echo "$@"
	else
		dialog --stdout --msgbox "$@" 0 0
	fi
}

show_menu_with_msg() {
	show_msg "$@"
	$BINDIR/menu
}

show_msg_and_run() {
	run="$1"
	shift
	show_msg "$@"
	$run
}

warning() {
	log "WARNING $*" >&2
}


get_reductor_state() {
	local state
	state="$($BINDIR/modules_ctl get_state_human ipt_reductor)"
	echo "$state"
	echo "$state" > $LOGDIR/reductor_state.log
}

ask() {
	dialog --yesno "$@" 0 0
}

show_file() {
	if [ "$TERM" = 'dump' ]; then
		cat $1
	else
		dialog --textbox "$1" 0 0
	fi
}

die() {
	show_msg "$@"
	exit 0
}

dialog_read() {
	dialog --stdout --inputbox "$1" "${2:-0}" "${3:-0}"
}

check_connect() {
	ping -c 1 "docs.carbonsoft.ru" &>/dev/null
}

check_connect_repo() {
	ping -c 1 $REPO_HOST &>/dev/null
}


is_module_loaded() {
	[ -f $PROCLIST ]
}

terminate() {
	show_msg "$@"
	exit 1
}

terminate_auto() {
	echo "$@" >&2
	exit 1
}

__terminate() {
	[ "$auto" = '1' ] && terminate_auto "$@" || terminate "$@"
}

get_version() {
	if [ "$(<$MAINDIR/etc/version)" -lt 200000 ] && [ -f $MAINDIR/etc/reductor.version ]; then
		cat $MAINDIR/etc/reductor.version
		return 0
	fi
	cat /usr/local/Reductor/etc/version
}

log() {
	echo "$(date +"%Y-%m-%d %H:%M:%S") $HOSTNAME ${0##*/}[$$]: $*"
}

create_message() {
	local mode="$1"
	local mailto="$2"
	local filename="$3"
	if [ "$mode" = 'support2admin' ]; then
		echo "From: feedback.reductor@carbonsoft.ru
To: $mailto
Content-Type: text/plain; charset = \"UTF-8\"
Subject: Проблема с Carbon Reductor"
	fi

	if [ "$mode" = 'admin2support' ]; then
		echo "From: ${autoupdate[email]}
To: feedback.reductor@carbonsoft.ru
Content-Type: text/plain; charset = \"UTF-8\"
Subject: Проблема с Carbon Reductor"
	fi

	date +"%Y-%m-%d %H:%M:%S"
	echo
	echo "# Сообщение:"
	echo
	cat $filename
	echo
	$BINDIR/support_info.sh add_info
	echo
	ip -o -4 a | sed -e 's/brd.*//g'
	echo
	echo "Настройка отправки этих писем находится в локальном меню сервера: "
	echo "- menu -> Прочие настройки... -> Слать отчёт об ошибках разработчикам"
	echo "- menu -> Прочие настройки... -> Слать отчёт об ошибках администратору"
}

sendmail() {
	mkdir -p $CHROOTDIR/$TMPDIR
	chroot $CHROOTDIR /bin/msmtp --host=smtp.carbonsoft.ru --port=25251 --connect-timeout=10 "$@"
}

#usage: send_alarm /tmp/message.txt
send_alarm() {
	__send_alarm "$@"
}

__send_alarm() {
	local filename="$1"
	local output=$TMPDIR/mail/$$
	local mail
	feedback="feedback.reductor@carbonsoft.ru"

	if [ "${misc['diagnostic2admin']}" != '1' ]; then
		return 0
	fi

	mkdir -p $TMPDIR/mail/

	if [ -n "${misc['admin_email']}" ]; then
		for mail in ${misc['admin_email']}; do
			create_message support2admin "$mail" "$filename" | sendmail -f $feedback -t "$mail"
		done
		return 0
	fi
	mail="${autoupdate['email']}"
	create_message support2admin "$mail" "$filename" | sendmail -f "$feedback" -t "$mail"
}

get_rpm_url() {
	local reductor_url="http://$REPO_HOST/reductor/reductor.rpm"
	if [ "${reductorupdate['branch']:-master}" = 'devel' ]; then
		reductor_url="http://$REPO_HOST/reductor/devel/reductor.rpm"
	fi
	echo "$reductor_url"
}

check_version() {
	local reductor_url
	reductor_url="$(get_rpm_url)"
	curl "$reductor_url" | grep -o "http://.*rpm" > /tmp/reductor/new_rpm_url
	current_version="$(rpm -q reductor | egrep -o '[0-9]{3}-[0-9]{3}' | tr -d '-')"
	if [ -z "$current_version" ] && [ -f $MAINDIR/etc/version ]; then
		read current_version < $MAINDIR/etc/version
	fi
	IFS='.-' read _ _ _ version build _ < /tmp/reductor/new_rpm_url
	new_version=$version$build
	[ "$new_version" -gt "$current_version" ]
}

get_last_config() {
	mkdir -p $USERDIR/backups/
	find $USERDIR/backups/ -type f -name "config_*" -exec stat -c '%n %Y' {} \; | sort -nk 2 | tail -1 | cut -d ' ' -f1
}

set_consoletype_serial() {
	export CONSOLETYPE=serial
	export BOOTUP=serial
	export MOVE_TO_COL=
	export SETCOLOR_SUCCESS=
	export SETCOLOR_FAILURE=
	export SETCOLOR_WARNING=
	export SETCOLOR_NORMAL=
}


echo_result() {
	result=$?
	[ "$result" = '0' ] && echo_success || echo_failure
	echo
	if [ "${1:-}" = 'return' ]; then
		return $result
	fi
}

get_reg_params() {
	echo "regnumber=${reg['regnumber']}&installcode=$(get_reductor_instcode)&actcode=${reg['actcode']}&email=${autoupdate['email']}&company=${autoupdate['operator']// /%20}&version=$(get_version)"
}

insert_module() {
	if ! lsmod | grep -wq $1; then
		chroot $CHROOTDIR depmod -a
		if ! chroot $CHROOTDIR modprobe $1; then
			local tmpfile=/tmp/report.$$
			local msg="failed clean modprobe $1 try force"

			echo "$msg" >> "$tmpfile"
			log "$msg" >> $LOGFILE
			send_alarm "$tmpfile"
			sleep 3
			rm -f "$tmpfile"
			chroot $CHROOTDIR modprobe -f $1
		fi
	fi
}

module_unload() {
	if lsmod | fgrep -wq "$1"; then
		rmmod "$1"
	fi
}

__exit() {
	RETVAL=$?
	if [ "$RETVAL" != 0 ]; then
		echo -n "ERROR($RETVAL): $0 "
		for ((i=${#FUNCNAME[@]}; i>0; i--)); do
			echo -n "${FUNCNAME[$i-1]} "
		done | sed -e 's/ $/\n/; s/ / -> /g'
	fi
	return $RETVAL
}

chroot_mount() {
	local dir=$CHROOTDIR/dev
	if ! mount | grep -q $dir; then
		mount -t devtmpfs none $dir
	fi

	local dir=$CHROOTDIR/proc
	if ! mount | grep -q $dir; then
		mount -t proc none $dir
	fi
}

chroot_umount() {
	for dir in $CHROOTDIR/dev $CHROOTDIR/proc; do
		if mount | grep -q $dir; then
			umount $dir
		fi
	done
}

url_lists() {
	echo $LISTDIR/load/url_http.load
	mkdir -p $HOOKDIR/custom_url_lists/
	find $HOOKDIR/custom_url_lists -type f
}

domain_custom_lists() {
	mkdir -p $HOOKDIR/custom_domains
	find $HOOKDIR/custom_domains -type f
}

route_device() {
	ip r g 8.8.8.8 | egrep -o "eth[0-9]+"
}

mirror_devices() {
	local devices
	devices="$(brctl show | egrep -o "eth[0-9\.]+$")"
	if [ ! -n "${devices:-}" ]; then
		devices="$(ip -o link show label eth* | grep -v "$(route_device)": | awk '{print $2}' | cut -d ':' -f1)"
	fi
	echo $devices
}

set_lock() {
	local lockfile="$1"
	local timeout="$2"
	local fd="$3"
	local is_fatal="${4:-1}"
	echo -n "$(log Захватываем $lockfile...) "
	eval "exec $fd>$lockfile"
	if ! flock -x -w "$timeout" "$fd"; then
		echo "FAIL"
		[ "$is_fatal" = '1' ] && exit $fd || return $fd
	fi
	echo "OK"
}

release_lock() {
	local lockfile="$1"
	local fd="$2"
	log "Отпускаем $lockfile"
	flock -u $fd
}
