#!/bin/bash
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
#

#
# Plesk script
#


### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.


true apache_status_linux_debian

apache_status_linux_debian()
{
	get_pid "/usr/sbin/apache2" false
	local pid=$common_var
	if test "$pid" -ne 1; then
# running
		return 0
	fi
	return 1
}

set_apsc_params()
{
	odbc_config_bin="/usr/bin/odbc_config" # present at least on CentOS 5
	if [ -x "$odbc_config_bin" ]; then
		odbc_dsn_conf=`$odbc_config_bin --odbcini 2>> "$product_log"`
		odbc_drivers_conf=`$odbc_config_bin --odbcinstini 2>> "$product_log"`
	fi
	if [ -z "$odbc_dsn_conf" ]; then
		odbc_dsn_conf="/etc/odbc.ini"
	fi
	if [ -z "$odbc_drivers_conf" ]; then
		odbc_drivers_conf="/etc/odbcinst.ini"
	fi

	odbc_isql_bin="/usr/bin/isql"
	odbc_iusql_bin="/usr/bin/iusql"

	odbc_mysql_drivers="/usr/lib/x86_64-linux-gnu/odbc/libmyodbc5w-plesk.so"
	for d in $odbc_mysql_drivers; do
		[ -s $d ] || continue
		odbc_mysql_driver="$d"
		break
	done

	if [ -z "$odbc_mysql_driver" ]; then
		die "No ODBC MySQL mysql drivers found, trying $odbc_mysql_drivers"
	fi

	if [ -s "/usr/lib/x86_64-linux-gnu/sw/libmysqlserver.so.2.0" ]; then
		apsc_driver_library="/usr/lib/x86_64-linux-gnu/sw/libmysqlserver.so.2.0"
	elif [ -s "/usr/lib/x86_64-linux-gnu/libmysqlserver.so.2.0" ]; then
		apsc_driver_library="/usr/lib/x86_64-linux-gnu/libmysqlserver.so.2.0"
	else
		die "find MySQL mysql platform driver for APSC"
	fi
}

check_ini_section_exists()
{
	local section="$1"
	local file="$2"
	grep -q "\[$section\]" "$file" >/dev/null 2>&1
}

check_odbc_driver_exists()
{
	# We could use odbcinst here, but it wouldn't save us much trouble
	local driver="$1"
	check_ini_section_exists "$driver" "$odbc_drivers_conf"
}

remove_ini_section()
{
	local section="$1"
	local file="$2"
	[ -r "$file" ] || return 0
	awk "/\[.*\]/ { del = 0 } /\[$section\]/ { del = 1 } ( del != 1 ) { print }" "$file" > "$file.new" && 	mv -f "$file.new" "$file"
}

remove_odbc_driver()
{
	local driver="$1"
	remove_ini_section "$driver" "$odbc_drivers_conf"
}

apsc_try_create_odbc_driver()
{
	check_odbc_driver_exists "$apsc_odbc_driver_name" && return 1

	local odbc_mysql_driver64=
	if echo "$odbc_mysql_driver" | grep -q lib64 2>/dev/null ; then
		odbc_mysql_driver64="$odbc_mysql_driver"
	fi

	cp -f "$odbc_drivers_conf" "$odbc_drivers_conf.new" && 	cat <<EOF >> "$odbc_drivers_conf.new" && mv -f "$odbc_drivers_conf.new" "$odbc_drivers_conf"
[$apsc_odbc_driver_name]
Description = MySQL driver for Plesk
Driver      = $odbc_mysql_driver
Setup       = 
FileUsage   = 1
Driver64    = $odbc_mysql_driver64
Setup64     = 
UsageCount  = 1

EOF
	local rc="$?"
	[ "$rc" -eq 0 ] || rm -f "$odbc_drivers_conf.new"
	return "$rc"
}

apsc_modify_odbc_driver()
{
	# just remove the one that bothers us
	remove_odbc_driver "$apsc_odbc_driver_name"
}

### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
# vim:ft=sh
# Usage:  pleskrc <service> <action>
pleskrc()
{
	[ 2 -le $# ] || die "Not enough arguments"

	local service_name=$1
	local action=$2
	local ret=0
	local inten
	shift
	shift

	# Now check redefined functions
	if test "$machine" = "linux" && is_function "${service_name}_${action}_${machine}_${linux_distr}"; then
		"${service_name}_${action}_${machine}_${linux_distr}" "$@"
		return $?
	elif is_function "${service_name}_${action}_${machine}"; then
		"${service_name}_${action}_${machine}" "$@"
		return $?
	elif is_function "${service_name}_${action}"; then
		"${service_name}_${action}" "$@"
		return $?
	fi

	# Not redefined - call default action
	eval "service=\$${service_name}_service"
	[ -n "$service" ] || die "$action $service_name service (Empty service name for '$service_name')"

	inten="$action service $service"
	[ "$action" = "status" -o "$action" = "exists" ] || echo_try "$inten"

	service_ctl "$action" "$service" "$service_name"

	ret="$?"
	if [ "$action" != "status" -a "${action}" != "exists" ]; then
		if [ "$ret" -eq 0 ]; then
			suc
		else
			[ ! -x "/bin/systemctl" ] || /bin/systemctl status "${service}.service" >> "$product_log" 2>&1
			warn "$inten"
		fi
	fi

	return $ret
}

# NOTE:
#	Function service_ctl is just helper for pleskrc().
#	Do not call it directly, use pleskrc()!!!
service_ctl()
{
	local action=$1
	local service=$2
	local service_name=$3

	if [ "$action" != "exists" ]; then
		_service_exec $service exists;
		if [ "$?" != "0" ]; then
			warn "attempt to ${inten} - control script doesn't exist or isn't executable"
			return 1
		fi
	fi

	case "$action" in
		start)
			pleskrc "$service_name" status || _service_exec "$service" "$action"
			;;
		stop)
			! pleskrc "$service_name" status || _service_exec "$service" "$action"
			;;
		restart)
			if pleskrc "$service_name" status; then
				_service_exec "$service" "$action"
			else
				_service_exec "$service" start
			fi
			;;
		reload)
			! pleskrc "$service_name" status || _service_exec "$service" "$action"
			;;
		status)
			_service_exec "$service" status
			;;
		*)
			_service_exec "$service" "$action"
			;;
	esac >> "$product_log"
}

_service_exec()
{
	local service=$1
	local action=$2

	local action_cmd
	local sysvinit_service="/etc/init.d/$service"

	if [ -x "/bin/systemctl" ]; then
		case "${action}" in
			exists)
				if /bin/systemctl list-unit-files | awk 'BEGIN { rc = 1 } $1 == "'$service'.service" { rc = 0;} END { exit rc }'; then
					return 0 # systemd unit
				elif [ -x "$sysvinit_service" ]; then
					return 0 # sysvinit compat
				fi
				return 1 # not found
				;;
			status)
				action="is-active"
				;;
			reload)
				action='reload-or-try-restart'
				;;
		esac
		/bin/systemctl "$action" "${service}.service"
	else
		if [ -x "/usr/sbin/invoke-rc.d" ]; then
			action_cmd="/usr/sbin/invoke-rc.d $service"
		elif [ -x "/sbin/service" ]; then
			action_cmd="/sbin/service $service"
		elif [ -x "/usr/sbin/service" ]; then
			action_cmd="/usr/sbin/service $service"
		else
			action_cmd="$sysvinit_service"
		fi

		if [ "$action" = "exists" ]; then
			[ -x "$sysvinit_service" ] && return 0 || return 1
		else
			$action_cmd $action
		fi
	fi
}

is_function()
{
	local type_output="`type \"$1\" 2>/dev/null | head -n1 | awk '{print $NF}'`"
	test "X${type_output}" = "Xfunction"
}

# echo message to product log, unless debug
p_echo()
{
    if [ -n "$PLESK_INSTALLER_DEBUG" -o -n "$PLESK_INSTALLER_VERBOSE" -o -z "$product_log" ] ; then
        echo "$@"
    else
        echo "$@" >> "$product_log" 2>&1
    fi
}

# echo message to product log without new line, unless debug
pnnl_echo()
{
    if [ -n "$PLESK_INSTALLER_DEBUG" -o -n "$PLESK_INSTALLER_VERBOSE" -o -z "$product_log" ] ; then
        echo -n "$*"
    else
        echo -n "$*" >> "$product_log" 2>&1
    fi
}

die()
{
	PACKAGE_SCRIPT_FAILED="$*"

	printf "\a\a"
	report_problem \
		"ERROR while trying to $*" \
		"Check the error reason(see log file: ${product_log}), fix and try again"

	selinux_close

	exit 1
}

warn()
{
	local inten
	inten="$1"
	p_echo
	p_echo "WARNING!"
	pnnl_echo "Some problems are found during $inten"
	p_echo "(see log file: ${product_log})"
	p_echo
	p_echo "Continue..."
	p_echo

	product_log_tail | send_error_report_with_input "Warning: $inten"

	[ -n "$PLESK_INSTALLER_DEBUG" -o -n "$PLESK_INSTALLER_VERBOSE" ] || \
	product_log_tail
}

# Use this function to report failed actions.
# Typical report should contain
# - reason or problem description (example: file copying failed)
# - how to resolve or investigate problem (example: check file permissions, free disk space)
# - how to re-run action (example: perform specific command, restart bootstrapper script, run installation again)
report_problem()
{
	[ -n "$product_problems_log" ] || product_problems_log="/dev/stderr"

	p_echo
	if [ "0$problems_occured" -eq 0 ]; then
		echo "***** $process problem report *****" >> "$product_problems_log" 2>&1
	fi
	for problem_message in "$@"; do
		p_echo "$problem_message"
		echo "$problem_message" >> "$product_problems_log" 2>&1
	done
	p_echo

	product_log_tail | send_error_report_with_input "Problem: $@"

	[ -n "$PLESK_INSTALLER_DEBUG" -o -n "$PLESK_INSTALLER_VERBOSE" ] || \
		product_log_tail

	problems_occured=1
}

echo_try()
{
	msg="$*"
	pnnl_echo " Trying to $msg... "
}

suc()
{
	p_echo "done"
}

# do not call it w/o input! Use send_error_report in these cases.
send_error_report_with_input()
{
	get_product_versions
	{
		echo "$@"
		echo ""
		if [ -n "$error_report_context" ]; then
			echo "Context: $error_report_context"
			echo ""
		fi
		if [ -n "$RP_LOADED_PATCHES" ]; then
			echo "Loaded runtime patches: $RP_LOADED_PATCHES"
			echo ""
		fi
		cat -
	} | $PRODUCT_ROOT_D/admin/bin/send-error-report --version "$product_this_version" install >/dev/null 2>&1
}

# accumulates chown and chmod
set_ac()
{
	local u_owner g_owner perms node
	u_owner="$1"
	g_owner="$2"
	perms="$3"
	node="$4"

	chown $u_owner:$g_owner $node || die "chown $u_owner:$g_owner $node"
	chmod $perms $node || die "chmod $perms $node"
}

true superserver_status_linux_debian
superserver_status_linux_debian()
{
    get_pid "/usr/sbin/xinetd" false
    local pid=$common_var
    if test "$pid" -ne 1; then
# running
        return 0
    fi
    return 1
}
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
#-*- vim:syntax=sh

product_log_name_ex()
{
	local aux_descr="$1"
	local action="${CUSTOM_LOG_ACTION_NAME-installation}"

	if [ -n "$aux_descr" ]; then
		aux_descr="_${aux_descr}"
	fi

	if [ -n "$CUSTOM_LOG_NAME" ]; then
		echo "${CUSTOM_LOG_NAME}${action:+_$action}${aux_descr}.log"
	else
		echo "plesk_12.5.30${action:+_$action}${aux_descr}.log"
	fi
}

product_log_name()
{
	product_log_name_ex
}

product_problems_log_name()
{
	product_log_name_ex "problems"
}

problems_log_tail()
{
	[ -f "$product_problems_log" ] || return 0
	tac "$product_problems_log" | awk '/^START/ { exit } { print }' | tac
}

product_log_tail()
{
	[ -f "$product_log" ] || return 0
	{
		tac "$product_log" | awk '/^START/ { exit } { print }' | tac
	} 2>/dev/null
}

cleanup_problems_log()
{
	[ -f "$product_problems_log" ] || return 0
	touch "$product_problems_log.tmp"
	chmod 0600 "$product_problems_log.tmp"
	awk 'BEGIN 						{ st = "" } 
		 /^START/ 					{ st=$0; next } 
		 /^STOP/ && (st ~ /^START/) { st=""; next } 
		 (st != "") 				{ print st; st="" } 
		 							{ print }
		' "$product_problems_log" > "$product_problems_log.tmp" && 	mv -f "$product_problems_log.tmp" "$product_problems_log" || 	rm -f "$product_problems_log.tmp"
	
	if [ ! -s "$product_problems_log" ]; then 
		rm -f "$product_problems_log"
	fi
}

mktemp_log()
{
	local logname="$1"
	local dir="$2"

	if ! expr match "$logname" '/' > /dev/null; then
		logname="$dir/$logname"
	fi
	dir="`dirname $logname`"
	if [ ! -d "$dir" ]; then
		mkdir -p "$dir" || { echo "Unable to create log directory : $dir"; exit 1; }
		if [ "`id -u`" = "0" ]; then
			set_ac root 0 0700 "$dir"
		fi
	fi

	if echo $logname  | grep -q XXX > /dev/null; then
		mktemp "$logname"
	else
		echo "$logname"
	fi
}

log_is_in_dev()
{
	local logfile="$1"
	expr match "$logfile" '/dev/' > /dev/null
	return $?
}

start_writing_logfile()
{
	local logfile="$1"
	local title="$2"
	! log_is_in_dev "$logfile" || return 0
	echo "START $title" >> "$logfile" || { echo "Cannot write installation log $logfile" >&2; exit 1; }
	[ ! "`id -u`" = "0" ] || set_ac root 0 0600 "$logfile"
}

create_product_log_symlink()
{
	local logfile="$1"
	local prevdir="$2"

	local prevlog="$prevdir/`basename $logfile`"
	[ -e "$prevlog" ] || ln -sf "$logfile" "$prevlog"
}

log_start()
{
	true product_log_name product_problems_log_name mktemp_log

	local title="$1"
	local custom_log="$2"
	local custom_problems_log="$3"

	local product_log_dir="/var/log/plesk/install"

	product_log="$product_log_dir/`product_log_name`"
	product_problems_log="$product_log_dir/`product_problems_log_name`"
	problems_occured=0

	# init product log
	[ ! -n "$custom_log" ] || product_log="$custom_log"
	product_log=`mktemp_log "$product_log" "$product_log_dir"`

	# init problems log
	if [ -n "$custom_problems_log" ]; then
		product_problems_log=`mktemp_log "$custom_problems_log" "$product_log_dir"`
	elif [ -n "$custom_log" ]; then
		product_problems_log="$product_log"
	else
		product_problems_log=`mktemp_log "$product_problems_log" "$product_log_dir"`
	fi

	# write starting message into logs
	start_writing_logfile "$product_log" "$title"
	if [ "$product_log" != "$product_problems_log" ]; then
		start_writing_logfile "$product_problems_log" "$title"
	fi

	# create compat symlinks if logs are written to default localtions
	if [ -z "$custom_log" -a -z "$CUSTOM_LOG_NAME" ]; then
		create_product_log_symlink "$product_log" "/tmp"
		[ ! -z "$custom_problems_log" ] || create_product_log_symlink "$product_problems_log" "/tmp"
	fi

	is_function profiler_setup && profiler_setup "$title" || :
}

log_transaction_start()
{
	LOG_TRANSACTION_TITLE="$1"
	LOG_TRANSACTION_SUBJECT="$2"
	local log_transaction_custom_logfile="$3"
	local log_transaction_custom_problems_logfile="$4"

	transaction_begin autocommit
	log_start "$LOG_TRANSACTION_TITLE" "$log_transaction_custom_logfile" "$log_transaction_custom_problems_logfile"
	transaction_add_commit_action "log_transaction_stop"
}

log_transaction_stop()
{
	log_stop "$LOG_TRANSACTION_TITLE" "$LOG_TRANSACTION_SUBJECT"
}

log_stop()
{
	local title="$1"
	local subject="$2"

	if [ "$product_log" = "$product_problems_log" ] || 			log_is_in_dev "$product_problems_log"; then
		[ -e "$product_log" ] && echo "STOP $title" >>"$product_log"
		is_function profiler_stop && profiler_stop || :
		return
	fi

	if [ -z "$subject" ]; then
		subject="[${title}]"
	fi

	# check if problems are non-empty, check for problems_occured
	local status
	local problem_lines="`problems_log_tail | wc -l`"
	if [ "$problem_lines" -eq 0 ]; then
		status="completed successfully"
	else
		if [ $problems_occured -ne 0 ]; then
			status="failed"
		else
			status="completed with warnings"
		fi
	fi

	if [ -e "$product_log" ]; then
		p_echo
		p_echo "**** $subject $status."
		p_echo
	fi

	if [ "$problem_lines" -ne 0 ]; then
		[ ! -e "$product_log" ] || problems_log_tail >>"$product_log" 2>&1
		problems_log_tail
	fi

	[ ! -e "$product_log" ] || echo "STOP $title" >>"$product_log"
	if [ $problems_occured -ne 0 ]; then
		echo "STOP $title: PROBLEMS FOUND" >>"$product_problems_log"
	else
		[ ! -s "$product_problems_log" ] || echo "STOP $title: OK" >>"$product_problems_log"
	fi

	if [ "X${PLESK_INSTALLER_KEEP_PROBLEMS_LOG}" = "X" ]; then
		cleanup_problems_log
	fi

	# remove symlink to problems log if the log was removed
	local linkpath="/tmp/`basename $product_problems_log`"
	if [ -L "$linkpath" -a ! -e "$linkpath" ]; then
		rm -f "$linkpath"
	fi

	is_function profiler_stop && profiler_stop || :
}
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.

get_pid()
{
	local i

	local ex_f="$1"
	local opt="$2"
	local owner="$3"

	local min_num="1"

	# Use pidof by default, bug 121868, except for FreeBSD - 140182
	if type pidof >/dev/null 2>&1 && [ "$os" != "BSD" ]; then
		for pid in `pidof -o $$ -o $PPID -o %PPID -x $ex_f`; do
			# Check for owner
			[ "$opt" = "true" -a "$owner" != "`ps -p $pid -o ruser=`" ] && continue
			min_num=$pid
			break
		done
		common_var=$min_num
		return $min_num
	fi

	case "$opt" in
		false)
			for i in `$ps_long | grep $ex_f | grep -v grep | grep -v httpsdctl | grep -v apachectl | awk '{print $2}' -`; do
				min_num=$i
				break
			done
			;;
		true)
			for i in `$ps_long | grep $ex_f | grep -v grep | grep -v httpsdctl | grep -v apachectl | grep "$owner" | awk '{print $2}' -`; do
				min_num=$i
				break
			done
			;;
		*)
			p_echo "get_pid: wrong parameter"
			die "get_pid $ex_f $opt $owner"
			;;
	esac

	common_var=$min_num
	return $min_num
}

### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
get_userID()
{
# try to get UID
	common_var=`id -u "$1" 2>/dev/null` 

# if id returns 0 the all is ok
	test "$?" -eq "0" -a -n "$common_var"
}

get_groupID()
{
# try to get GID, id -g doesn't show groups without users
	common_var=`getent group $1 2>/dev/null | awk -F':' '{print $3}'`

# We have non-empty value if success
	test -n "$common_var"
}

read_conf()
{
	[ -n "$prod_conf_t" ] || prod_conf_t=/etc/psa/psa.conf

	if [ -s $prod_conf_t ]; then
		tmp_var=`perl -e 'undef $/; $_=<>; s/#.*$//gm;
		         s/^\s*(\S+)\s*/$1=/mg;
		         print' $prod_conf_t`
		eval $tmp_var
	else
		if [ "X$do_upgrade" = "X1" ]; then
			p_echo "Unable to find product configuration file: $prod_conf_t. Default values will be used."
			return 1
		fi
	fi
	return 0
}

# setup new value for parameter
# $1 config file name $2 paramater name, $3 parameter value
conf_setval()
{
	cat "$1" | awk -v varname="$2" -v varvalue="$3" 		'BEGIN { f = 0 }
		{ if ($1 == varname) { f = 1; print varname "\t" varvalue } else { print $0 } }
		END { if (f == 0) { print "\n" varname "\t" varvalue } }' 			> "$1.new" && 	mv -f "$1.new" "$1" && 	chmod 644 "$1"
}
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.

#-*- vim:ft=sh

register_service() {

	[ -n "$1" ] || die "register_service: service name not specified"
	local inten="register service $1"
	echo_try "$inten"

	{


		# update-rc.d for Debian/Ubuntu (not SuSE)
		/usr/sbin/update-rc.d "$1" defaults

	}

	suc
}

selinux_close()
{
	if [ -z "$SELINUX_ENFORCE" -o "$SELINUX_ENFORCE" = "Disabled" ]; then
		return
	fi

	setenforce "$SELINUX_ENFORCE"
}
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
# -*- vim:syntax=sh

set_syslog_params()
{
	syslog_conf_ng="/etc/syslog-ng/syslog-ng.conf"

	syslog_conf=""
	for config in rsyslog.conf rsyslog.early.conf syslog.conf; do
		[ -f "/etc/$config" ] && syslog_conf="$syslog_conf /etc/$config"
	done

	syslog_service=""
	syslog_binary=""

	# Make sure the sequence of services is correlate with binaries
	local syslog_services="syslog sysklogd rsyslog syslog-ng"
	local syslog_binaries="syslogd syslogd rsyslogd syslog-ng"

	for service in $syslog_services; do
		[ -x "$PRODUCT_RC_D/${service}" ] && 			syslog_service="$service" && break
	done

	for binary in $syslog_binaries; do
		for bin_path in /sbin /usr/sbin; do
			[ -x "$bin_path/${binary}" ] && 				syslog_binary="$bin_path/${binary}" && break
		done
		[ -n "$syslog_binary" ] && break
	done

}
## @@constructor set_syslog_params

true syslog_status_linux_debian
syslog_status_linux_debian()
{
	get_pid "$syslog_binary" false
	local pid=$common_var
	if test "$pid" -ne 1; then
		# running
		return 0
	fi
	return 1
}

true syslog_reload_linux_suse
true syslog_reload

syslog_reload_linux_suse()
{
	if [ "$syslog_service" = "rsyslog" -a "$syslog_binary" = "/sbin/rsyslogd" ]; then
		# Suse 13.1 man 8 rsyslogd:
		# So it is advised to use HUP only for closing files, and a "real restart" (e.g. /etc/rc.d/rsyslogd restart) to activate configuration changes.
		service_ctl restart $syslog_service syslog
	else
		service_ctl reload $syslog_service syslog
	fi
}

syslog_reload()
{
	# set_syslog_params must be called in outed function

	if [ "X$syslog_service" = "Xrsyslog" ]; then
		# Bug 142129
		# rsyslog service registration is necessary
		# it is workaround on default rsyslog service registration behaviour
		register_service rsyslog 2345 16 74
		# then we restart it
	fi

	if [ "$syslog_service" = "syslog" -o "$syslog_service" = "rsyslog" ] && [ "$PLESK_VZ" = "1" ]; then
		# 146355 - rsyslog/syslog service returns false on VZ
		service_ctl restart $syslog_service syslog
	elif [ "X$syslog_service" = "Xrsyslog" ]; then
		service_ctl restart $syslog_service syslog
	else
		service_ctl reload $syslog_service syslog
	fi
}

get_product_versions()
{
	local prod_root_d="/opt/psa"
	
	product_name="psa"
	product_this_version="12.5.30"
	product_this_version_tag="testing"
	if [ -z "$product_prev_version" ]; then
		if [ -r "$prod_root_d/version.upg" ]; then
			product_prev_version=`cat "$prod_root_d/version.upg" | awk '{ print $1 }'`
		elif [ -r "$prod_root_d/version" ]; then
			product_prev_version=`cat "$prod_root_d/version" | awk '{ print $1 }'`
		else
			product_prev_version="$product_this_version"
		fi
	fi
}

#Invoke mysql
mysql()
{
	mysql_anydb -D$mysql_db_name "$@"
}

mysql_anydb()
{
	(
		export MYSQL_PWD="$mysql_passwd"
		$mysql_client $mysql_host $mysql_user $mysql_args "$@" 2>>"$product_log"
		local status=$?

		if [ $status -gt 0 ]; then
			$mysql_client $mysql_host $mysql_user $mysql_args -D$mysql_db_name $mysql_args_raw -e "SHOW ENGINE innodb status" >>"$product_log" 2>&1
		fi
		unset MYSQL_PWD
		return $status
	)
}

# -- end of mysqlnd old passwords upgrade --
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
# -*- vim:ft=sh

# MySQL service action handlers

true mysql_start_linux_suse
mysql_start_linux_suse()
{
	local rc
	
	inten="start service mysql"
	echo_try "$inten"

	service_ctl start $mysql_service mysql
	rc="$?"

	# bug 52690. MySQL init script reports failure if protected mysqld is running (true for SuSE >= 11.3)
	if [ "$rc" -ne 0 ]; then
		local mysqld_bin="/usr/sbin/mysqld"
		killall -TERM mysqld >> $product_log 2>&1
		if [ -x "$mysqld_bin" ]; then
			for i in 2 4 8 16 32; do
				get_pid "$mysqld_bin" false
				local pid="$common_var"
				if test "$pid" -eq 1; then
					break
				fi
				killall -TERM mysqld >> $product_log 2>&1
				sleep $i
			done
		fi
		service_ctl start $mysql_service mysql
		rc="$?"
	fi

	[ "$rc" -eq 0 ] && suc || warn "$inten"
	return $rc
}

###	FIXME: probably need var service_restart warn
true mysql_stop
mysql_stop()
{
	local op_result i

	inten="stop MySQL server"
	echo_try $inten

	service_ctl stop $mysql_service mysql
	op_result=$?

	if [ "X$linux_distr" = "Xdebian" ]; then
		# Debian has well designed mysql stopping code
		[ "$op_result" -eq 0 ] || die $inten
		suc
		return 0
	fi

	for i in 2 4 6 8 16; do
		if ! mysql_status ; then
			suc
			return 0
		fi

		# I just want to be sure that mysql really stopped
		killall -TERM mysqld mysql safe_mysqld mysqld_safe >> $product_log 2>&1

		sleep $i
	done

	die "$inten"
}

true mysql_status
mysql_status()
{
	local file

    #Check with native script first
	#debian script always return 0. bug #111825
	[ "X$linux_distr" = "Xdebian" ] && msqld_status_supported="no"
	
	if [ -z "$msqld_status_supported" ]; then
		# MySQL AB packages doesn't know about status command
		if LC_MESSAGES=C $PRODUCT_RC_D/$mysql_service 2>&1 | grep -q "status"; then
			msqld_status_supported="yes"
		else
			msqld_status_supported="no"
		fi
	fi

	if [ "$msqld_status_supported" = "yes" ]; then
		service_ctl status $mysql_service mysql && return 0
	fi

	if [  "$msqld_status_supported" = "no" ]; then
		# MySQL AB packages
		file="/usr/sbin/mysqld"
	fi

    if [ -x "$file" ]; then
		#standard build and debian
		get_pid "$file" false
		pid=$common_var
		if test "$pid" -ne 1; then
			echo "$file (pid $pid) is running..." >>$product_log 2>&1
			return 0
		else
			echo "$file is stopped" >>$product_log 2>&1
			return 1
		fi
	fi

	return 1
}
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
#-*- vim:syntax=sh

set_named_params()
{
	# set up default values
	bind_UID=53
	bind_GID=53
	bind_user="bind";
	bind_group="bind";

	# get UID of named user, if exists
	if get_userID $bind_user; then
	    bind_UID=$common_var;
	fi

	# get GID of named group, if exists
	if get_groupID $bind_group; then
	    bind_GID=$common_var;
	fi

	# path to directory of internal named
	NAMED_ROOT_D="${PRODUCT_ROOT_D:?'PRODUCT_ROOT_D is undefined'}/named"

	# path to directory of named pid file
	bind_run="${NAMED_RUN_ROOT_D:?'NAMED_RUN_ROOT_D is undefined'}/var/run/named"

	named_service="bind9"
	named_log="/dev/null"
	
	# path to named config file
	named_conf="/etc/named.conf"
	rndc_conf="/etc/rndc.conf"
	rndc_namedb_conf="/etc/namedb/rndc.conf"
	rndc_bind_conf="/etc/bind/rndc.conf"

	#140025. Restrict CPU cores for Bind
	bind_number_of_workers=2
}

debian_fix_named_iniscript()
{
	start_script="/etc/init.d/bind9"
	if [ -f $start_script ]; then
		# replace pidfile path to the one in chroot; ensure named is dead after 'rndc stop'
		# be carefull not to make replacements more than one time
		sed -e 's|/var/run/bind/run/named.pid|/var/named/run-root/var/run/named/named.pid|g' 			-e 's|\([^a-zA-Z0-9_.]\)/var/run/named/named.pid|\1/var/named/run-root/var/run/named/named.pid|g' 			-e '/killall\|rndc stop -p/!    s|\(/usr/sbin/rndc stop\)|\1 ; sleep 1 ; killall -9 named|g' 			-e '/killall/!                  s|\(/usr/sbin/rndc stop -p\s*\)| ( \1 ; sleep 1 ; killall -9 named ) 2>/dev/null |g' 			< "$start_script" > "$start_script.tmp" &&
		mv -f "$start_script.tmp" "$start_script" &&
		chmod 755 "$start_script"
	fi
}


true named_status_linux_debian
named_status_linux_debian()
{
    get_pid "/usr/sbin/named" false
    local pid=$common_var
    if test "$pid" -ne 1; then
# running
		return 0
    fi
    return 1
}

true exim_status_linux_debian
exim_status_linux_debian()
{
	get_pid /usr/lib/exim/exim3 false
	local pid=$common_var

	if test "$pid" -ne 1; then
		#running
		return 0;
	fi
	return 1
}

### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
#-*- vim:syntax=sh

maillog_create_compat_symlink()
{
	mkdir -p "$PRODUCT_ROOT_D/var/log"
	[ -e "$PRODUCT_ROOT_D/var/log/maillog" -a ! -L "$PRODUCT_ROOT_D/var/log/maillog" ] || ln -sf "$mail_log" "$PRODUCT_ROOT_D/var/log/maillog"
}

select_maillog()
{
	local mail_log inten
	mail_log="/var/log/maillog"
	inten="set maillog file to $mail_log"

	set_syslog_params


	if [ "X$syslog_service" = "Xrsyslog" ]; then
		pleskrc syslog reload
		maillog_create_compat_symlink
		return
	fi

	touch $mail_log
	chmod 0640 $mail_log

	local rsyslog_mail_log="${mail_log}"

	for config in $syslog_conf; do
		if [ -f "$config" ]; then
			if [ "${config}" = "/etc/rsyslog.conf" ]; then
				set_maillog $config "${rsyslog_mail_log}" "${inten}" >> $product_log 2>&1
			else
				set_maillog $config "${mail_log}" "${inten}" >> $product_log 2>&1
			fi
		fi
	done

	[ -f $syslog_conf_ng ] && set_maillog_ng "$mail_log" "$inten"  >> "$product_log" 2>&1

	pleskrc syslog reload
	maillog_create_compat_symlink
}

_set_maillog_ng_change()
{
    local conf_file mail_log inten bak_ext

    conf_file=$1
    mail_log=$2
    inten=$3
    bak_ext=$4

    echo_try "$inten"

    local mloc_cmd mloc_arg
    local ws
    ws=$(echo -ne " \t")

    ## Set log to $mail_log
    mloc_cmd="-e"
    mloc_arg='s|^\(['"$ws"']*destination['"$ws"']\+mail['"$ws"']*{[^"]*"\)[^"]*\(.*\)$|\1'"$mail_log"'\2|'

    ## By default SuSE-9.3 and SuSE-10 syslog-ng settings
    ## doesn't allow any 'mail' log messages to be put into
    ## /var/log/messages. We wish to allow mail.warn to pass
    ## through the filter, so we need to tune the conditions...
    ## So we change
    ## filter f_messages   { not facility(news, mail) and not filter(f_iptables); };
    ## to
    ## filter f_messages   { not (facility(news) or filter(f_iptables)) or filter(f_mailwarn); };
    ##
    ## I'm not sure if the whole filter is well optimized though
    ##
    ## Here I don't try to perform a sofisticated replace. The proper way
    ## would require a deep analisys of the current configuration and
    ## I don't see any sense to do it at this time, probably once in a future...

    local mfmt_cmd mfmt_arg
    mfmt_cmd=-e
    mfmt_arg='s|^\(['"$ws"']*filter['"$ws"']\+f_messages['"$ws"']*{\).*|\1 not (facility(news) or filter(f_iptables)) or filter(f_mailwarn); };|'

    ## now execute the entire command *IN-PLACE*
    ## all modern sed's (well at least on supported systems
    ## do support this option.

    ## One HAVE NOT TO quite mail_log_expr and mf_expr below!
    sed $mloc_cmd "$mloc_arg" $mfmt_cmd "$mfmt_arg" "-i$bak_ext" "$conf_file" || die "$intent"
}

set_maillog_ng() {
    local mail_log intent
    mail_log=$1
    intent=$2

	if [ -f "${syslog_conf_ng}.in" ]; then
	    _set_maillog_ng_change "${syslog_conf_ng}.in" "$mail_log" "$intent" ".bak" && 		/sbin/SuSEconfig --module syslog-ng
	else
# Modest SuSE 1.20 doens't rule syslog through SuSE-config, bug 118238
		_set_maillog_ng_change "${syslog_conf_ng}" "$mail_log" "$intent" ".bak"
	fi

}

set_maillog()
{
	local syslog_conf mail_log inten mail_log_str log_str num
	syslog_conf=$1
	mail_log=$2
	inten=$3

	mail_log_str="-$mail_log"

	echo_try "$inten"

	log_str="^mail.*[[:space:]]*$mail_log*"
	grep "$log_str" $syslog_conf > /dev/null
	if [ "$?" -ne 0 ]; then
		grep '^mail\.\*' $syslog_conf > /dev/null
		if [ "$?" -eq 0 ]; then
			## if line "mail.*       ..." is exist then
			## replace this with new line
			grep -q '^mail\.\*.*;' $syslog_conf
			if [ $? -eq 0 ]; then
				sed -e "s|^mail\.\*.*\(;.*\)$|mail.*					$mail_log_str\1|" 					< $syslog_conf > $syslog_conf.tmp
			else
				sed -e "s|^mail\.\*.*$|mail.*						$mail_log_str|" 					< $syslog_conf > $syslog_conf.tmp
			fi
			mv -f $syslog_conf.tmp $syslog_conf
		else
			## if line "mail.*       ..." is NOT exist then
			## search "*.       ..." line
			num=`awk '{if ((my==0) && (index($1, "*.") == 1)) {my=1; print FNR;}}' < $syslog_conf`
			if [ "0$num" -gt "0" ]; then
				## if line "*.       ..." is exist then
				## disable all lines beginning with "mail."
				## and insert new line "mail.*      ..." before this
				sed -e 's/^\(mail\.\)/#\1/' 					-e ''${num}'i					mail.*						'$mail_log_str'' 					< $syslog_conf > $syslog_conf.tmp && 				mv -f $syslog_conf.tmp $syslog_conf || die "$inten"
			else
				## if line "*.       ..." is NOT exist then
				## disable all lines beginning with "mail."
				## and insert new line "mail.*      ..." at the end of file
				sed -e 's/^\(mail\.\)/#\1/'	< $syslog_conf > $syslog_conf.tmp && 				echo "mail.*						$mail_log_str" >> $syslog_conf.tmp && 				mv -f $syslog_conf.tmp $syslog_conf || die "$inten"
			fi
		fi
	fi

	sed -e 's|\(^.*\)maili\none\;\(.*\)|\1\2|g' < $syslog_conf > $syslog_conf.tmp &&           mv -f $syslog_conf.tmp $syslog_conf || die "$inten"
	echo 'mail.none			-/var/log/messages' >> /var/log/messages 

	suc
}

### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
transaction_begin()
{
	[ -n "$TRANSACTION_STARTED" ] && die "Another transaction in progress!"
	TRANSACTION_STARTED="true"
	TRANSACTION_ROLLBACK_FUNCS=
	TRANSACTION_COMMIT_FUNCS=
	local transaction_autocommit="$1"
	if [ -n "$transaction_autocommit" ]; then
		trap "transaction_commit" PIPE EXIT
		trap "transaction_rollback" HUP INT QUIT TERM
	else
		trap "transaction_rollback" HUP PIPE INT QUIT TERM EXIT
	fi
}

transaction_rollback()
{
	[ -z "$TRANSACTION_STARTED" ] && die "Transaction is not started!"
	# perform rollback actions
	local f
	for f in ${TRANSACTION_ROLLBACK_FUNCS}; do
		"$f"
	done
	TRANSACTION_STARTED=
	TRANSACTION_ROLLBACK_FUNCS=
	TRANSACTION_COMMIT_FUNCS=
	trap - HUP PIPE INT QUIT TERM EXIT
	exit 1
}

transaction_commit()
{
	[ -z "$TRANSACTION_STARTED" ] && die "Transaction is not started!"
	# perform commit actions
	local f
	for f in ${TRANSACTION_COMMIT_FUNCS}; do
		"$f"
	done
	TRANSACTION_STARTED=
	TRANSACTION_ROLLBACK_FUNCS=
	TRANSACTION_COMMIT_FUNCS=
	trap - HUP PIPE INT QUIT TERM EXIT
}

transaction_add_commit_action()
{
	[ -z "$TRANSACTION_STARTED" ] && die "Transaction is not started!"
	# FIFO commit order
	[ -z "$TRANSACTION_COMMIT_FUNCS" ] \
		&& TRANSACTION_COMMIT_FUNCS="$1" \
		|| TRANSACTION_COMMIT_FUNCS="$TRANSACTION_COMMIT_FUNCS $1"
}

true postfix_status
postfix_status()
{
	# here be dragons.
	# the practical experience shows that simple checking of status of
	# Postfix "master" process is not enough. So we read Postfix master
	# process pid file if any, then try to look for a process with
	# name ``qmgr'' and parent pid being equal to
	# the pid read from the pidfile. If pgrep finds such a process
	# it returns 0, if not its exit status is non-zero.
	# pgrep is portable enough to prefer it to "hand-made" alternatives
	# such as famous ``ps | grep $name | grep -v grep...'' pipes
	# bug 147822. do not interrupt installation for FreeBSD

	[ -f "/var/spool/postfix/pid/master.pid" ] || return 1

	local ppid

	read ppid </var/spool/postfix/pid/master.pid 2>/dev/null
	if [ $? -ne 0 -o -z "$ppid" ]; then
		# not found or other error
		return 1;
	fi
	pgrep -P $ppid qmgr >/dev/null 2>/dev/null
}
### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
# vim: ft=sh

distupgrade_add_message()
{
	if [ -z "$DISTUPGRADE_MESSAGES" ]; then
		DISTUPGRADE_MESSAGES="$*"
	else
		DISTUPGRADE_MESSAGES="$DISTUPGRADE_MESSAGES\n$*"
	fi
}

distupgrade_show_messages()
{
	printf "\n$DISTUPGRADE_MESSAGES\n"
}

distupgrade_deb_prepare()
{
	export PLESK_INSTALLER_VERBOSE=1
	export PLESK_INSTALLER_DEBUG=1
	export DEBIAN_FRONTEND=noninteractive
	export LANG=C

	backup_suffix="saved_by_plesk_distupgrade"

	aptitude_env="env DEBIAN_FRONTEND=noninteractive LANG=C"
	aptitude_options="--assume-yes -o Dpkg::options::=--force-confdef -o Dpkg::Options::=--force-confnew -o APT::Get::AllowUnauthenticated=true $ADDITIONAL_APTITUDE_OPTIONS"
	if [ "$USE_APT_GET" = "yes" ]; then
		aptitude="$aptitude_env apt-get"
	else
		aptitude="$aptitude_env aptitude"
		aptitude_options="--allow-untrusted $aptitude_options"
	fi

	sources_list="/etc/apt/sources.list"
	sources_list_d="/etc/apt/sources.list.d"
	sources_list_ai_back="$sources_list.ai_back"

	autoinstaller="/opt/psa/admin/sbin/autoinstaller"

	bootstrapper_flag="/tmp/pp-bootstrapper-mode.flag"

	apache_disabled_modules_path="/var/lib/plesk/distupgrade_apache_disabled_modules.txt"

	DISTUPGRADE_MESSAGES=""

	[ "$opt_debug" = "0" ] || set -x
}

distupgrade_deb_set_up()
{
	touch "$bootstrapper_flag"
	distupgrade_deb_hold_packages $packages_to_exclude
}

distupgrade_deb_tear_down()
{
	distupgrade_deb_unhold_packages $packages_to_exclude
	rm -f "$bootstrapper_flag"
}

distupgrade_deb_check_updates()
{
	if [ -e "$sources_list.$backup_suffix" ]; then
		distupgrade_add_message "Skip check for latest packages are installed since $sources_list has been already updated"
		return 0
	fi
	$aptitude update || return $?
	local available_updates=`aptitude search -F '%p' --disable-columns '~U'`
	[ "$?" = "0" ] || return 1
	if [ -n "$available_updates" ]; then
		echo "The following packages are not up-to-date:"
		echo $available_updates
		echo "You should install the latest updates before performing dist-upgrade"
		return 1
	fi
	return 0
}

distupgrade_deb_revert_packages_configuration()
{
	local packages="$PACKAGE_CONGIFS_TO_REVERT"
	local revert_packages=""

	[ -n "$packages" ] || return 0

	for p in $packages; do
		local pi=`echo $p | cut -f 1 -d@`
		local configs="`echo $p | cut -f2- -d@ | tr @ ' '`"
		if dpkg -s "$pi" >/dev/null 2>&1; then
			for conf in $configs; do
				[ -e "$conf" ] || continue
				if [ -e "$conf.$backup_suffix" ]; then
					distupgrade_add_message "Config file '$conf' is already reverted. Skip."
					continue
				fi
				mv "$conf" "$conf.$backup_suffix" || true
				revert_packages="$revert_packages $pi"

				distupgrade_add_message "Config file '$conf' is reverted to package state. User version of file is saved in '$conf.$backup_suffix'."
			done
		fi
	done
	[ -n "$revert_packages" ] || return 0
	apt-get -o Dpkg::Options::="--force-confmiss" install --reinstall $revert_packages
}

distupgrade_deb_remove_files_pre()
{
	local files="$REMOVE_FILES_PRE"
	[ -n "$files" ] || return 0
	for f in $files; do
		if expr match "$f" "-" > /dev/null; then
			# "-/path/to/file" -- marked to remove. No message is required.
			f=`echo $f | cut -c 2-`
			rm -f "$f"
		elif [ -e "$f" ]; then
			# "/path/to/file" -- marked to rename (backup)
			mv "$f" "$f.$backup_suffix"
			distupgrade_add_message "File '$f' is renamed to '$f.$backup_suffix'."
		fi
	done
}

distupgrade_deb_handle_mailman_queue()
{
	local unshunt="/var/lib/mailman/bin/unshunt"
	local qfiles_d="/var/lib/mailman/qfiles"
	local workaround_unshunt="$1"

	[ -d "$qfiles_d" ] || return 0

	if [ "$workaround_unshunt" -gt 0  -a -x "$unshunt" ]; then
		"$unshunt"
	fi

	local files="`find "$qfiles_d" -type f`"

	if [ -n "$files" ] ; then
		if [ "$workaround_unshunt" -gt 0 ]; then
			rm -f $files
		else
			echo "The directory "$qfiles_d" contains files. It needs to be empty for the upgrade to work properly."
			return 1
		fi
 	fi
}

distupgrade_deb_fix_aps_db_driver_library()
{
	set_apsc_params
	if [ ! -f "$apsc_driver_library" ];	then
		echo "find MySQL platform driver library"
		return 1
	fi
	conf_setval "/etc/psa/psa.conf" APS_DB_DRIVER_LIBRARY "$apsc_driver_library"

	apsc_odbc_driver_name="MySQL"

	apsc_modify_odbc_driver
	apsc_try_create_odbc_driver
}

distupgrade_deb_fix_named_initscript()
{
	read_conf
	set_named_params

	pleskrc named stop
	debian_fix_named_iniscript
	pleskrc named restart
}

distupgrade_deb_force_install_packages()
{
	local packages="$PACKAGES_TO_FORCE_INSTALL"
	local forced_packages=""

	[ -n "$packages" ] || return 0

	for p in $packages; do
		local pi=`echo $p | cut -f 1 -d@`
		local pu
		if expr match "$p" ".*@" >/dev/null 2>&1; then
			pu=`echo $p | cut -f 2 -d@`
		else
			pu="$pi"
		fi
		if dpkg -s "$pi" >/dev/null 2>&1; then
			forced_packages="$forced_packages $pu"
		fi
	done
	$aptitude $aptitude_options install $forced_packages
}

distupgrade_deb_pre_install_packages()
{
	local packages="$PACKAGES_TO_INSTALL_PRE"
	[ -n "$packages" ] || return 0
	$aptitude $aptitude_options install $packages
}

distupgrade_deb_post_install_packages()
{
	local packages="$PACKAGES_TO_INSTALL_POST"
	local forced_packages=""

	[ -n "$packages" ] || return 0

	for p in $packages; do
		local pi=`echo $p | cut -f 1 -d@`
		local pu=`echo $p | cut -f 2 -d@`
		if dpkg -s "$pi" >/dev/null 2>&1; then
			forced_packages="$forced_packages $pu"
		fi
	done
	[ "`arch`" != "x86_64" ] || dpkg --add-architecture i386
	$aptitude update || return $?
	$aptitude $aptitude_options install $forced_packages || return $?
	[ "`arch`" != "x86_64" ] || dpkg --remove-architecture i386
}

distupgrade_deb_cleanup_apache_configuration()
{
	local modules="$APACHE_MODULES_TO_DISABLE"
	local enabled_modules_d="/etc/apache2/mods-enabled"
	local disabled_modules=""

	local httpd_modules_ctl="/opt/psa/admin/sbin/httpd_modules_ctl"

	[ -n "$modules" ] || return 0

	for m in $modules; do
		if [ -x "$httpd_modules_ctl" ]; then
			"$httpd_modules_ctl" --status --all-modules | egrep "^$m\s+on" || continue
		fi
		a2dismod "$m"
		rm -f "$enabled_modules_d/$m.conf"
		rm -f "$enabled_modules_d/$m.load"

		distupgrade_add_message "Apache module '$m' has been disabled."
		disabled_modules="$disabled_modules $m"
	done
	echo $disabled_modules >> $apache_disabled_modules_path
}

distupgrade_deb_restore_apache_configuration()
{
	[ -s "$apache_disabled_modules_path" ] || return 0

	local modules="`cat $apache_disabled_modules_path`"

	for m in $modules; do
		a2enmod "$m"
		distupgrade_add_message "Apache module '$m' has been enabled."
	done

	rm -f "$apache_disabled_modules_path"

	conf_setval "/etc/psa/psa.conf" HTTPD_INCLUDE_D "/etc/apache2/conf-enabled"
}

distupgrade_deb_upgrade_apt_repo()
{
	local path="$1"
	local suffix="$2"
# source.list entry format : deb [ options ] uri distribution [component1] [component2] [...]
	perl -i$suffix -pale "if (\$F[0] eq 'deb' || \$F[0] eq 'deb-src') { \$F[\$F[1] =~ /^\[/ ? 3 : 2] =~ s/^$PREV_CODENAME/$NEXT_CODENAME/; \$_ = join ' ', @F }" "$path"
}

distupgrade_deb_upgrade_apt_repos()
{
	if [ ! -e "$sources_list.$backup_suffix" ]; then
		cp -f "$sources_list" "$sources_list.$backup_suffix"
		"$autoinstaller" --skip-cleanup --check-updates
		rm -f "$sources_list_ai_back"

		distupgrade_deb_upgrade_apt_repo "$sources_list"
		distupgrade_add_message "'$sources_list' has been updated: '$PREV_CODENAME' is replaced with '$NEXT_CODENAME', Plesk repositories were added. Original file is saved in '$sources_list.$backup_suffix'."
	else
		distupgrade_add_message "'$sources_list' has been already updated. Skip."
	fi

	if ls "$sources_list_d"/*.list > /dev/null 2>&1; then
		for list in "$sources_list_d"/*.list; do
			if [ ! -e "$list.$backup_suffix" ]; then
				distupgrade_deb_upgrade_apt_repo "$list" ".$backup_suffix"
				distupgrade_add_message "'$list' has been updated: '$PREV_CODENAME' is replaced with '$NEXT_CODENAME'. Original file is saved in '$list.$backup_suffix'."
			else
				distupgrade_add_message "'$list' has been already updated. Skip."
			fi
		done
	fi
}

distupgrade_deb_check_plesk_packages_have_updates()
{
	local out_of_date
	out_of_date=`$autoinstaller --select-product plesk --select-release-current --show-components | perl -nale 		'print $F[0] if $F[0] =~ /common|panel|engine/ && $F[1] eq "[upgrade]"'`
	
	if [ -n "$out_of_date" ]; then
		echo "Some of essential Plesk components are not upgraded:" $out_of_date
		echo "You may either upgrade them manually upgrade them or rerun utility with option --skip-check-latest"

		return 1
	fi
}

distupgrade_deb_hold_packages()
{
	for p in "$@"; do
		echo "$p hold" | dpkg --set-selections
	done
}

distupgrade_deb_unhold_packages()
{
	for p in "$@"; do
		echo "$p install" | dpkg --set-selections
	done
}

distupgrade_ubuntu_allow_unauthenticated()
{
	printf "[Distro]\nAllowUnauthenticated=yes\n" > /etc/update-manager/release-upgrades.d/plesk-unauth.cfg
}

distupgrade_ubuntu_cleanup_allow_unauthenticated()
{
	rm -f /etc/update-manager/release-upgrades.d/plesk-unauth.cfg
}

distupgrade_deb_work_pre()
{
	if [ ! -e "$sources_list.$backup_suffix" ]; then
# It's rather dangerous to perform any apt-related actions in pre-stage if sources.list is updated to the next release
		$aptitude update || return $?
		distupgrade_deb_revert_packages_configuration
		$aptitude $aptitude_options dist-upgrade || return $?
	fi
	distupgrade_deb_cleanup_apache_configuration
	distupgrade_deb_remove_files_pre
	distupgrade_deb_upgrade_apt_repos

	for func in $DISTUPGRADE_ADDITIONAL_ACTION_PRE; do
		$func || return $?
	done
}

distupgrade_deb_work_post()
{
	distupgrade_deb_post_install_packages
	distupgrade_deb_restore_apache_configuration
	distupgrade_deb_fix_aps_db_driver_library
	distupgrade_deb_fix_named_initscript

# restore mail logging configuration in syslog
	select_maillog

	for func in $DISTUPGRADE_ADDITIONAL_ACTION_POST; do
		$func || return $?
	done

	# restore user's sources.lsit
	mv -f "$sources_list.$backup_suffix" "$sources_list"
	distupgrade_deb_upgrade_apt_repo  "$sources_list" ".$backup_suffix"
	distupgrade_add_message "'$sources_list' has been updated: '$PREV_CODENAME' is replaced with '$NEXT_CODENAME'. Original file is saved in '$sources_list.$backup_suffix'"

	/opt/psa/bootstrapper/pp12.5.30-bootstrapper/bootstrapper.sh post-install BASE || {
		echo "Bootstrapper post-install actions for component base failed"
		return 1
	}
	/opt/psa/bootstrapper/pp12.5.30-bootstrapper/bootstrapper.sh repair || {
		echo "Bootstrapper repair actions failed"
		return 1
	}
	service psa restart

	"$autoinstaller" --select-product plesk --select-release-current --upgrade-installed-components || {
		echo "Upgrade of installed Plesk components failed"
		return 1
	}
}

distupgrade_deb_parse_args()
{
	local PN=`basename $0`
	shift
	local TEMP="`getopt -o hx:ds --long help,exclude:,debug,skip-check-latest,workaround-mailman-unshunt -n "$PN" -- "$@"`"
	if [ $? -ne 0 ] ; then echo "Error during parsing command line arguments." >&2 ; exit 1 ; fi
	eval set -- "$TEMP"

	local usage=" usage:
-x, --exclude <package>       keep packages from upgrading
-s, --skip-check-latest       skip check for the latest packages are installed
--workaround-mailman-unshunt  unshunt messages in mailman queue before upgrade
-d, --debug                   enable debug logging
-h, --help                    show this help
"

	packages_to_exclude=""
	opt_debug=0
	opt_skip_check_latest=0
	opt_workaround_mailman_unshunt=0

	while true; do
		case "$1" in
			-x|--exclude) packages_to_exclude="$packages_to_exclude $2"; shift 2;;
			-s|--skip-check-latest) opt_skip_check_latest=1; shift;;
			--workaround-mailman-unshunt) opt_workaround_mailman_unshunt=1; shift;;
			-d|--debug) opt_debug=1; shift;;
			-h|--help) echo "$usage"; exit 0;;
			--) shift; break ;;
			*) echo "Unexpected option: $1"; exit 1;;
		esac
	done
}

distupgrade_error_message()
{
	local stage="$1"
	echo "Some error during dist-upgrade $stage stage occurs." 
	echo "Check $DISTUPGRADE_LOG for error details."
	echo "Visit $DISTUPGRADE_DOC for information about troubleshooting and recovering dist-upgrade."
}

distupgrade_deb_main_pre()
{
	distupgrade_deb_parse_args "$@" && 	distupgrade_deb_prepare && # before-distupgrade checks in user-mode:
	{ [ "$opt_skip_check_latest" -gt 0 ] || distupgrade_deb_check_updates; } && 	distupgrade_deb_handle_mailman_queue $opt_workaround_mailman_unshunt && #
	distupgrade_deb_set_up && 	distupgrade_deb_work_pre && 	distupgrade_show_messages || 	{ distupgrade_error_message "pre"; return 1; }

	echo "Now you can perform dist-upgrade to $NEXT_CODENAME using any method you like."
	[ -z "$HELP_URL" ] || echo "You can visit $HELP_URL for more information."
	[ -z "$DISTUPGRADE_POST_SCRIPT" ] || echo "After system dist-upgrade is finished run '$DISTUPGRADE_POST_SCRIPT'."
}

distupgrade_deb_main_middle()
{
	$aptitude update && 	distupgrade_deb_pre_install_packages  || return $?
	$aptitude $aptitude_options upgrade
	local upgrade_ret=$?
	if [ "$upgrade_ret" -ne "0" ]; then
# workaround for PPP-12052 Postgresql dist-upgrade failed
		echo "Safe-upgrade step failed with exit code $upgrade_ret. Trying to rerun safe-upgrade step."
		$aptitude $aptitude_options upgrade || return $?
	fi

	distupgrade_deb_force_install_packages && 	$aptitude $aptitude_options $APTITUDE_DISTUPGRADE_NEW_ADD_OPTS dist-upgrade || 	{ distupgrade_error_message "middle"; return 1; }
}

distupgrade_deb_main_post()
{
	distupgrade_deb_parse_args "$@" && 	distupgrade_deb_prepare && 	{ [ "$opt_skip_check_latest" -gt 0 ] || distupgrade_deb_check_plesk_packages_have_updates; } && 	distupgrade_deb_work_post && 	distupgrade_deb_tear_down && 	distupgrade_show_messages || 	{ distupgrade_error_message "post"; return 1; }

	echo "Plesk distupgrade finished."
	echo "If problems occur, please check $DISTUPGRADE_LOG for errors."
}

distupgrade_deb_main()
{
	distupgrade_deb_parse_args "$@" && 	distupgrade_deb_prepare && 	"$DISTUPGRADE_PRE_SCRIPT" --skip-check-latest "$@" || return $?
	distupgrade_deb_main_middle || return $?
	"$DISTUPGRADE_POST_SCRIPT" --skip-check-latest "$@" || return $?
}

distupgrade_deb_run()
{
	DISTUPGRADE_LOG="$1"
	local func="$2"

	shift 2

	log_transaction_start "Distupgrade" "Distupgrade" "$DISTUPGRADE_LOG"
	"$func" "$@" < /dev/null 2>&1 | tee -a "$DISTUPGRADE_LOG"
	exit "${PIPESTATUS[0]}"
}

### Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
# vim: ft=sh

true distupgrade_deb_main distupgrade_deb_main_pre distupgrade_deb_main_post distupgrade_deb_run

PREV_CODENAME="precise"
NEXT_CODENAME="trusty"

HELP_URL="https://help.ubuntu.com/14.04/serverguide/installing-upgrading.html"

USE_APT_GET="yes"

PACKAGE_CONGIFS_TO_REVERT="apache2.2-common@/etc/apache2/apache2.conf rsyslog@/etc/rsyslog.conf ntp@/etc/apparmor.d/usr.sbin.ntpd awstats@/etc/awstats/awstats.conf isc-dhcp-client@/etc/apparmor.d/sbin.dhclient bind9@/etc/init.d/bind9"
PACKAGES_TO_FORCE_INSTALL="mysql-server@mysql-server-5.5 \
	psa-tomcat-configurator psa-tomcat-configurator@openjdk-7-jdk \
	apache2 apache2-mpm-prefork libapache2-mod-php5 libapache2-mod-python \
	php5-cgi php5-cli php5-common \
	php5-curl php5-fpm php5-gd php5-imap php5-mysql php5-sqlite php5-xsl
"
PACKAGES_TO_INSTALL_POST="psa-kav8@psa-kav8:i386 libapache2-mod-rpaf-psa@libapache2-mod-rpaf"

APACHE_MODULES_TO_DISABLE="rpaf ssl dir"

DISTUPGRADE_ADDITIONAL_ACTION_PRE="distupgrade_ubuntu_allow_unauthenticated ubuntu_12_14_disable_asp_apache_module"
DISTUPGRADE_ADDITIONAL_ACTION_POST="distupgrade_ubuntu_cleanup_allow_unauthenticated ubuntu_12_14_reconfigure_php_modules"

ubuntu_12_14_reconfigure_php_modules()
{
	local old_php_conf_d="/etc/php5/conf.d"
	local php_d="/etc/php5/apache2/conf.d /etc/php5/cgi/conf.d /etc/php5/cli/conf.d"

	/usr/sbin/ion_loader.sh install
	rm -f $old_php_conf_d/ioncube-loader*
	rm -f $old_php_conf_d/00-ioncube-loader*

	for conf in $old_php_conf_d/*.ini; do
		for conf_d in $php_d; do
			cp -f --update "$conf" "$conf_d"
		done
		mv -f "$conf" "$conf.$backup_suffix"
	done
}

ubuntu_12_14_disable_asp_apache_module()
{
	# PPP-12055 ASP scripting does not work after distupgrade from ubuntu12 - get error 500
	local asp_package="libapache-asp-perl"

	if dpkg -s "$asp_package" > /dev/null 2>&1; then
		$aptitude $aptitude_options purge "$asp_package"
		distupgrade_add_message "Package '$asp_package' was removed since Ubuntu 14 doesn't support ASP-scripting."
	fi
}

DISTUPGRADE_PRE_SCRIPT="/opt/psa/bin/distupgrade.helper.ubt12-ubt14_pre.x64.sh"
DISTUPGRADE_POST_SCRIPT="/opt/psa/bin/distupgrade.helper.ubt12-ubt14_post.x64.sh"
DISTUPGRADE_DOC="http://docs.plesk.com/en-US/current/administrator-guide/server-administration/distupgrade-support/"

distupgrade_deb_run "/var/log/plesk/install/plesk-distupgrade.log" distupgrade_deb_main_post "$0" "$@"
