#!/bin/sh
#
# Copyright (c) 1999-2008 Parallels
# All rights reserved
#

#
# Plesk script
#


get_certificate()
{
	local dst="$1"
	local src="${certificate_file}"
# Check or generate new default certificate
	[ -s "$src" ] || generate_default_certificate
 	set_ac 0 0 0400 "${src}"
	cp -fp $src $dst
}

generate_default_certificate()
{
	# Currently I have no will to accurately rewrite the stuff below
	# so I just add support for (optional) file parameter. Actually
	# one need to accurately handle temporary files, directory creation
	# etc. Probably next time...
	local cert_file

	cert_file="${certificate_file}"
	if [ -s "$cert_file" ]; then
		p_echo "default certificate already exists"
		return
	fi

	# This var also can safely be made local. It's not used outside
	local OPENSSL_CNF is_temp_cnf rc

	OPENSSL_CNF=${PRODUCT_ROOT_D}/admin/conf/openssl.cnf
	is_temp_cnf=0

	if [ ! -f "${OPENSSL_CNF}" ]; then
		# Well, base psa package isn't yet installed. 
		# let's form a temporary config file
		OPENSSL_CNF=$(mktemp /tmp/openssl.cnf.XXXXXX)
		[ $? != 0 ] && die "Unable to create temporary file"
		cat >>${OPENSSL_CNF} <<EOF
[ req ]
attributes=req_attributes
distinguished_name=req_distinguished_name

[ req_attributes ]
challengePassword               = A challenge password
unstructuredName                = An optional company name

[ req_distinguished_name ]
countryName             = Country Name
stateOrProvinceName     = State or Province Name
localityName            = Locality Name
organizationName        = Organisation Name
organizationalUnitName  = Organization Unit Name
commonName              = Common Name
emailAddress            = Email Address
EOF
		is_temp_cnf=1
	fi

	echo "US
Virginia
Herndon
Parallels
Plesk
plesk
info@plesk.com


" | openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
	-config ${OPENSSL_CNF} -set_serial `date +%s` -keyout "${cert_file}_" \
	-out "${cert_file}_" >> $product_log 2>&1

	# preserve exit code
	rc=$?

	if [ $rc -eq 0 ]; then
		cat "${cert_file}_" | sed -e 's/^\(-----END.*\)/\1\
/' > $cert_file
		set_ac 0 0 0400 "${cert_file}"
	fi
	# cleanup temporary files
	rm -f "${cert_file}_" ||:
	if [ "x$is_temp_cnf" = "x1" ]; then
		rm -f ${OPENSSL_CNF} ||:
	fi
	return $rc
}

remove_tmp_state()
{
	if [ -d "/tmp/.state" ]; then
		rm -Rf "/tmp/.state" >> $product_log 2>&1
	fi
}

true apache_status_linux_debian apache_stop_BSD

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
}

apache_stop_BSD()
{
	local apache_script

	if [ "$std_to_pkg" -ne 0 ]; then
		apache_script="$PRODUCT_ROOT_D/rc.d/httpd"
	else
		apache_script="$PRODUCT_RC_D/$apache_service_name"
	fi

	$apache_script stop 2>/dev/null
}
configure_courier_authpsa()
{
    local action conf rc err_count restart_needed
    action=$1
    restart_needed=0
    err_count=0
    for conf in pop3d pop3d-ssl imapd imapd-ssl; do
	/usr/local/psa//admin/bin/courier_authpsa_configure "$conf" "$action" 2>>"$product_log"
	rc=$?
	case "$rc" in
	    0)
		;;
	    110)
		restart_needed=110
		;;
	    *)
		err_count=$(($err_count + 1)) # error was already reported in stderr
		;;
	esac
    done

    if [ $err_count -gt 0 ]; then
	echo "Some configuration files weren't processed successfully. See \"$product_log\" for details" >&2
    fi

    return $restart_needed
}


#courier-imap

set_courier_imap_params()
{
	IMAPD_CERT="/usr/local/psa/courier-imap/share/imapd.pem"
	POP3D_CERT="/usr/local/psa/courier-imap/share/pop3d.pem"

	courier_service="courier-imap"
}

## @@constructor set_courier_imap_params

configure_courier()
{
	if [ "X$DEMO_VERSION" = "Xyes" ]; then
		return 0;
	fi

	p_echo
	p_echo
	cd "$PRODUCT_ROOT_D" || die "cd $PRODUCT_ROOT_D"
	p_echo "===> Configuring Courier-IMAP server"
	p_echo

	local restart_needed
	restart_needed=0

	set_courier_imap_params

	if [ ! -f "$IMAPD_CERT" ]; then
		inten="generate Certificate for Courier-IMAP server for IMAP-SSL"
		echo_try $inten
		get_certificate "$IMAPD_CERT" || die $inten
		set_ac 0 0 0400 "$IMAPD_CERT"
		suc
		restart_needed=110
	fi

	if [ ! -f "$POP3D_CERT" ]; then
		inten="copy default SSL Certificate for Courier-IMAP server for POP3-SSL"
		echo_try $inten
		cp -fp "$IMAPD_CERT" "$POP3D_CERT" || die $inten
		suc
		restart_needed=110
	fi

	# Comment services for imap, imaps pop3, pop3s in super server internet [x]inetd
	# Should inetd/xinetd be restarted after this operation?
	courier_imap_comment_inetd_services

	inten="Configure Courier IMAP for Plesk-specific authentication"
	echo_try $inten
	configure_courier_authpsa add
	rc=$?
	if [ $rc -eq 110 ]; then
		restart_needed=110
	fi
	suc

	# always restart upon fresh installation
	if [ "X$do_upgrade" != "X1" -o $restart_needed -eq 110 ]; then
		pleskrc courier restart
	fi
}

courier_imap_comment_inetd_services()
{
	set_super_server_params
	super_server_action comment "imap"
	super_server_action comment "imap2"
	super_server_action comment "imap4"
	super_server_action comment "imaps"

	super_server_action comment "pop3"
	super_server_action comment "pop-3"
	super_server_action comment "pop3s"
}

# db_test test_query awk_script
# Runs test_query and processes it with awk_script. If the output is
# not empty, return 0, otherwise return 1. Hint: supply '1' for
# awk_script to test just for the presence of any output.
db_test()
{
	local any_db=
	eval `sh_get_args '--any-db) any_db=yes;;'`

	local test_query="$1"
	local awk_script="$2"

	if [ -n "$any_db" ]; then
		local output="`mysql_raw_anydb -e \"$test_query\" 2>>\"$product_log\"`"
	else
		local output="`mysql_raw -e \"$test_query\" 2>>\"$product_log\"`"
	fi
	local status=$?
	if [ "$status" -ne 0 ]; then
		p_echo "$output"
		die "run the following SQL query: $1"
	fi

	echo -n "$output" | awk -F '\t' -- "$awk_script" | test `wc -l` -ne 0
}

proftpd_super_server_config()
{
	local action="$1"

	case "$superserver" in
	    inetd)
		    ftp_rec="ftp stream tcp nowait root $PROFTPD_ROOT/sbin/proftpd proftpd -c $PROFTPD_ETC_D/proftpd.conf"
		    ;;
	    xinetd)
		    ftp_rec="service ftp
{
	socket_type		= stream
	protocol		= tcp
	wait			= no
	disable			= no
	user			= root
	instances		= UNLIMITED
	server			= $PROFTPD_ROOT/sbin/proftpd
	server_args		= -c $PROFTPD_ETC_D/proftpd.conf
}"
		    ;;
	    *)
		    die "Super server name unknown"
		    ;;
	esac

	super_server_action "$action" ftp "$ftp_rec"
}
# Usage:  pleskrc <service> <action>
pleskrc()
{
	[ 2 -le $# ] || die "Not enough arguments"

	local service_name=$1
	local action=$2
	local ret=0
	local inten
	local service_script
	local wflag

	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 "Empty service name for $service_name"

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

	if [ -f  "$SYSTEM_RC_D/$service" ]; then
		[ -x "$SYSTEM_RC_D/$service" ] || wflag=1
		service_script="$SYSTEM_RC_D/$service"
	elif [ ! -z ${PRODUCT_RC_D} -a -f "$PRODUCT_RC_D/$service" ]; then
		[ -x "$PRODUCT_RC_D/$service" ] || wflag=1
		service_script="$PRODUCT_RC_D/$service"
	fi

	if [ "$action" = "exists" ]; then 
		[ -n "$service_script" ] && return 0 || return 1
	else
		[ -z "$service_script" ] && die "Unable to handle $service"

		if [ -n "$wflag" ]; then
			SR_WARNING="$service: script is not executable"
			service_restart_warning
			return 0
		fi
	fi


	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 [ -n ${service_script} ]; then
		action_cmd="$service_script"
	fi


	case "$action" in
		start)
			pleskrc $service_name status || $action_cmd $action $@
			;;
		stop)
			if pleskrc $service_name status; then
				$action_cmd $action $@
			else
				true
			fi
		    ;;
		restart)
			if pleskrc $service_name status; then 
				$action_cmd "restart" $@
			else 
				$action_cmd "start" $@
			fi
		    ;;
		reload)
		    if pleskrc $service_name status; then
				$action_cmd "reload" $@
			else
				true
			fi
		    ;;
		status)
		    $action_cmd "status"
		    ;;
	    *)
		    $action_cmd $action $@ 
		    ;;
	esac

	ret="$?"
	if [ "$action" != "status" ]; then
		[ "$ret" -eq 0 ] && suc || warn $inten
	fi

	return $ret
}

is_function()
{
	local type_output="`LANG=C LC_ALL=C LC_MESSAGES=C type \"$1\" 2>/dev/null | head -n 1`"
	case "$type_output" in
		*function)
			return 0
		;;
		*)
			return 1
		;;
	esac
}

p_echo()
{
[ -z "$product_log" ] || echo "$@" >> "$product_log" 2>&1
echo "$@"
}

pnnl_echo()
{
    echo -n "$*" >> "$product_log" 2>&1
    echo -n "$*" 
}

die()
{
	PACKAGE_SCRIPT_FAILED="$*"

	if [ "X$trigger_uninstall" != "X1" ]; then
		printf "\a\a"
		p_echo
		p_echo "ERROR while trying to $*"
		echo "Check the error reason(see log file: ${product_log}), fix and try again"
		p_echo
		if [ "X$do_patch" != "X1" -a "X$do_reconfigure" != "X1" ]; then
			p_echo "Aborting..."
			p_echo
		fi
	fi

	smart_undo_install

	selinux_close

	exit 1

}

simply_die()
{
    p_echo "$@" >&2
    exit 1
}

# This function needs for some print warning when some services cannot restart
# if called with arg, then we add arg to variable SR_WARNING and print warning
# message for arg, else print warning message for SR_WARNING
service_restart_warning()
{
	if [ "X$1" != "X" ]; then
		if [ "X${SR_WARNING}" = "X" ]; then
			SR_WARNING=$1
		else
			for i in ${SR_WARNING}; do
				if [ "$i" = "$1" ]; then
					break
				fi
			done
			if [ "$1" != "$i" ]; then
				SR_WARNING=$SR_WARNING" "$1
			fi
		fi
		p_echo "WARNING!"
		p_echo "Some problems occured when $1 restart, check it after installation/upgrade complete"
	        p_echo
	 	p_echo "Continue..."
		p_echo
	else
		if [ "X${SR_WARNING}" != "X" ]; then
			p_echo "WARNING!"
		        p_echo "Some problems occured when following services restart:"
			for i in ${SR_WARNING}; do
				p_echo $i
			done
			p_echo "Don't forget to check it after installation/upgrade complete"
        		p_echo
	       	        p_echo "More information can be found in log file: ${product_log}"
			p_echo
		fi
	fi
}

warn()
{
local inten
inten="$1"
p_echo
p_echo "WARNING!"
pnnl_echo "During the $inten found some problems"
echo "(see log file: ${product_log})"
p_echo
p_echo "Continue..."
p_echo

}

report_problem()
{
	p_echo "***** $process problem report *****"
	echo "***** $process problem report *****" >> "$product_problems_log" 2>&1

	p_echo "$1"
	echo "$1" >> "$product_problems_log" 2>&1

	p_echo "$2"
	echo "$2" >> "$product_problems_log" 2>&1

	problems_occured=1
}

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

suc()
{
	p_echo "done"
}

mk_backup()
{
	target="$1"
	dup="$2"
	opts="$3"

	if [ -L "$target" ]; then
		rm "$target"
	elif [ -$opts "$target" ]; then
		if [ ! -$opts "$target.$product_suffo" ]; then
			case "$dup" in
				mv)
					mv -f $target $target.$product_suffo || die "mv -f $target $target.$product_suff"
					;;
				cp)
					cp -fp $target $target.$product_suffo || die "cp -fp $target $target.$product_suff"
					;;
				*)
					p_echo " mk_backup: wrong option -- must be 'cp' or 'mv'"
					die "mk_backup"
					;;
			esac
		else
			case "$dup" in
				mv)
					mv -f $target $target.$product_suff || die "mv -f $target $target.$product_suff"
					;;
				cp)
					cp -fp $target $target.$product_suff || die "cp -fp $target $target.$product_suff"
					;;
				*)
					p_echo " mk_backup: wrong option -- must be 'cp' or 'mv'"
					die "mk_backup"
					;;
			esac
		fi
	else
		case "$opts" in
			f|d)
				;;
			*)
				p_echo " mk_backup: wrong option -- must be 'f' or 'd'"
				die "mk_backup"
				;;
		esac
	fi
}

# accumulates chown and chmod
set_ac()
{
	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"
}

detect_vz()         
{                   
    local vzcheck_file
        
    PLESK_VZ=0
    vzcheck_file="/proc/self/status"
                    
    if [ ! -f ${vzcheck_file} ]; then
        return 1; 
    fi              
                    
    grep -q -E '^envID\:[[:space:]]*([[:digit:]]+)$' < ${vzcheck_file} >/dev/null 2>&1
                    
    if [ $? -eq 0 ]; then
        PLESK_VZ=1  
        return 0;
    fi      
    return 1;
}       

call_optional_function()
{
	export LANG=C LC_MESSAGES=C LC_ALL=C
	local type_output="`type \"$1\" 2>/dev/null | head -n 1`"
	case "$type_output" in
		*function)
			"$@"
			;;
		*)
			return 0
			;;
	esac
}

sh_get_args()
{
	echo 'while true; do case "$1" in '"$1"'*) break;; esac; shift; done'
}

sequence()
{
	if type seq >/dev/null 2>&1; then
		seq $*
	elif type jot >/dev/null 2>&1; then
		jot $*
	else
		die "Unable to find seq or jot command"
	fi
}
set_super_server_params()
{
    case "${machine}_${linux_distr}" in
	linux_*)
	    superserver_mode=native
		superserver=xinetd
	    set_xinetd_params $superserver_mode
	;;
	BSD*)
	    superserver_mode=native
		superserver=inetd
	    set_inetd_params $superserver_mode
	;;
	*)
	    die "Unable to detect super server type"
	;;
    esac

    super_server_action configure
}

true superserver_reconfig

set_inetd_params()
{	
    superserver_conf="/etc/inetd.conf"

    if [ "$superserver_mode" = compat ]; then
	if [ -x "$PRODUCT_RC_D/xinetd" ]; then 
	    superserver_service="xinetd"
		superserver_binary="/usr/sbin/xinetd"
	elif [ -x "$PRODUCT_RC_D/inetd" ]; then 
	    superserver_service="inetd"
		superserver_binary="/usr/sbin/inetutils-inetd"
	elif [ -x "$PRODUCT_RC_D/openbsd-inetd" ]; then
	    superserver_service="openbsd-inetd"
		superserver_binary="/usr/sbin/inetd"
	else
	    die "Unable to find script for superserver"
	fi
    else
	superserver_service="inetd"
    fi

    superserver_dir="/etc"
}

set_xinetd_params()
{
    superserver_conf="/etc/xinetd.conf"
    superserver_service="xinetd"
    superserver_dir="/etc/xinetd.d"
}

superserver_reconfig()
{
    pleskrc superserver reload
}

configure_xinetd_compat()
{
	local inten="configure xinetd compatibility mode with $superserver"
	if [ "$linux_distr" = "debian" -o "$linux_distr" = "ubuntu" ]; then
		[ "$superserver_service" = "xinetd" ] || return 1
		[ -f "/etc/default/xinetd" ] || return 1
		grep -q 'XINETD_OPTS=.*-inetd_compat' /etc/default/xinetd && return 1
		echo_try $inten

		if ! grep -q '^\s*XINETD_OPTS' /etc/default/xinetd; then
			echo 'XINETD_OPTS="-inetd_compat"' >>/etc/default/xinetd
			suc
			return 0
		fi

		eval `grep '^\s*XINETD_OPTS' /etc/default/xinetd`
		XINETD_OPTS="$XINETD_OPTS -inetd_compat"
		local tmp_file=`mktemp /tmp/xinetdXXXXXX`
		sed -e "s/XINETD_OPTS.*/XINETD_OPTS=\"$XINETD_OPTS\"/g" /etc/default/xinetd > $tmp_file && mv -f $tmp_file /etc/default/xinetd
		suc
		return 0
	fi
	return 1
}


super_server_action()
{
    local in out
    local action="$1"
    local service="$2"
    local template="$3"

    inten="$action $service service record for $superserver_service daemon"

    case "$action" in
	remove) ;;
	register)
		[ -z "$template" ] && die "Template for super server $action was not defined"
		;;
	comment|disable)
		;; 
	configure)
		case "$superserver_mode" in
		    native)
			register_service $superserver_service defaults defaults
			;;
		    compat)
			configure_xinetd_compat && pleskrc superserver restart
			;;
		    *)
			die "Mode for $superserver_service was not defined"
			;;
		esac

		return 0
		;;
	*)
		die "Some arguments was not defined or defined incorrect for action with super server"
		;;
    esac 

    case "$superserver" in
	inetd)
		super_server_modify_inetd "$service" "$action" "$template"
		;;
	xinetd)
		super_server_modify_xinetd "$service" "$action" "$template"
		;;
	*)
		die "Unable to define super server type"
		;;	
    esac

    if [ $? -ne 0 ]; then
	die $inten 
    fi
}

super_server_modify_inetd()
{
	local service="$1"
	local action="$2"
	local template="$3"

	case "$action" in
		comment|disable)
			grep -q "^$service[[:space:]]" $superserver_conf || return 0
			sed -e "s|^$service|#$service|g" < "$superserver_conf" > "$superserver_conf.tmp" 			&& mv -f "$superserver_conf.tmp" "$superserver_conf" 			|| return 1
			;;
		remove)
			if [ -x /usr/sbin/update-inetd ]; then
				/usr/sbin/update-inetd --enable "$service"
				/usr/sbin/update-inetd --remove "$service"
			else
				grep -q "^$service[[:space:]]" $superserver_conf || return 0
				sed -e "s|^$service[[:space:]].*||g" < "$superserver_conf" > "$superserver_conf.tmp" 			    	&& mv -f "$superserver_conf.tmp" "$superserver_conf" 			    	|| return 1
			fi
			;;
		register)
			if [ -x /usr/sbin/update-inetd ]; then
				/usr/sbin/update-inetd --enable "$service"
				/usr/sbin/update-inetd --remove "$service"
				/usr/sbin/update-inetd --add "$template"
			else
				egrep -q "$template" $superserver_conf
				if [ "$?" -ne "0" ]; then 
					super_server_modify_inetd comment $service && 					echo "$template" >> $superserver_conf || return 1
				fi
			fi
			;;
	esac

	return 0
}

super_server_modify_xinetd()
{
	local file
	local service="$1"
	local action="$2"
	local template="$3"

	for file in $superserver_dir/*; do
		grep -q "$service" $file 1>$product_log 2>&1 || continue

		case "$action" in
		    remove)
			    awk "/^[[:space:]]*(#|[[:space:]])*service[[:space:]]+$service($|[[:space:]]+)/,/.*}.*/ 				{next;} {print}
			    " <$file >$file.tmp 			    && mv -f $file.tmp $file || return 1
			    ;;
		    comment)
			    awk "/^[[:space:]]*service[[:space:]]+$service($|[[:space:]]+)/,/.*}.*/ 			       { print \"#\"\$0; next; }
			       {print}
			    " < $file > $file.tmp 			    && mv -f $file.tmp $file || return 1
			    ;;
		esac
	done

	case "$action" in
	    register)
		    echo "$template" > "$superserver_dir/${service}_psa" || return 1
		    ;;
	    disable)
			[ -f "$superserver_dir/${service}_psa" ] && mv -f "$superserver_dir/${service}_psa" "$superserver_dir/${service}.psa"
		    ;;
	esac

	return 0
}

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
}

package_script_begin_pkg()
{
	package_script_begin
}

package_script_end_pkg()
{
	package_script_end
}

package_script_begin()
{
	local title

	if [ "X$process" = "X" ]; then
		if   [ "X$do_reconfigure" = "X1" ]; then
		process="reconfiguration"
		elif  [ "X$do_upgrade" = "X1" ]; then
		process="upgrade"
		else
		    process="installing"
		fi
	fi

	product_log="/tmp/${PACKAGE_NAME}_${PACKAGE_VERSION}_${PACKAGE_RELEASE}_${process}.`date +%y%m%d.%H.%M`.log"
	product_problems_log="/tmp/${PACKAGE_NAME}_${PACKAGE_VERSION}_${PACKAGE_RELEASE}_problems.`date +%y%m%d.%H.%M`.log"
	title="`package_script_log_title`"
	echo "START $title" >>"$product_log" \
	&& echo "START $title" >>"$product_problems_log" \
	&& chmod 600 "$product_log" "$product_problems_log" \
	|| {
		echo "Cannot write installation log $product_log, $product_problems_log" >&2
		exit 1
	}
	problems_occured=0

	product_default_conf
	initial_conf
	set_common_params
	read_conf
}

package_script_end()
{
	local title
	title="`package_script_log_title`"

	packagemng_set_dirty_flag

	echo "STOP $title" >>"$product_log"
	echo "STOP $title" >>"$product_problems_log"
}

package_script_log_title()
{
	local stage
	case "$do_upgrade" in
		0) stage="installing";;
		1) stage="upgrading";;
		*) stage="installing";;
	esac
	if [ -n "$PACKAGE_DEB_ACTION" ]; then
		stage="$stage (deb action: $PACKAGE_DEB_ACTION)"
	fi
	echo "$PACKAGE_NAME-$PACKAGE_VERSION-$PACKAGE_RELEASE $stage AT `date`"
}

# <fun> <function name(s)> NAME VERSION RELEASE [DEB_ACTION]
package_script_call_main_function()
{
	package_script_call_main_function_begin "$@"

	for package_func in $1; do
		if ! call_optional_function "$package_func"; then
			break
		fi
	done

	package_script_end_handler ok
}

package_script_call_main_function_begin()
{
	PACKAGE_NAME="$2"
	PACKAGE_VERSION="$3"
	PACKAGE_RELEASE="$4"
	PACKAGE_DEB_ACTION="$5"
	package_script_begin_this_system

	trap "package_script_end_handler error" HUP PIPE INT QUIT TERM EXIT
}

package_script_end_handler()
{
	case "$1" in
	error)
		if [ -z "$PACKAGE_SCRIPT_FAILED" ]; then
			PACKAGE_SCRIPT_FAILED="Package script failed"
		fi
		;;
	ok) PACKAGE_SCRIPT_FAILED=
		;;
	esac

	trap - EXIT

	package_script_end_this_system
}


package_script_begin_this_system()
{
    package_script_begin_pkg
}

package_script_end_this_system()
{
    package_script_end_pkg
}

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
}

kill_pids()
{
	ex_f="$1"
	owner="$2"

	for i in `$ps_long | grep $ex_f | grep -v grep | grep -v httpsdctl | grep -v apachectl | grep $owner | awk '{print $2}' -`; do
		if [ $i -gt 1 ]; then
			$K_TERM $i >> $product_log 2>&1
		fi
	done
}

wait_after_stop()
{
        PIDS=`echo "$1" | tr ' ' ,`
        count=${2:-50}

	echo_try "Terminate processes $PIDS" >> $product_log

	while [ 0$count -gt 0 ]; do
		if [ "X$machine" = "XDarwin" ]; then 
	           col_procs="`ps -p $PIDS 2>/dev/null|wc -l| xargs echo`"
                   [ 0$col_procs -lt 2 ] && break
		else
                   ps -p $PIDS > /dev/null 2>&1 || break
		fi

		count=`expr $count - 1`
        	[ 0$count -eq 0 ] && kill -9 $1 > /dev/null 2>&1

                sleep 1
	done

	suc
        return 0
}
add_service2etc_services()
{
	### this function adds service description into /etc/services

	service=$1
	port=$2
	protocol=$3 ### can be empty

	if [ -z "$service" ]; then
		warn "add_service_network_service() error: service does not specified."
		return
	fi

	echo $port | grep '^[0-9][0-9]*$' >/dev/null
	if [ 0$? -ne 0 ]; then
		warn "add_service_network_service() error: '$service' service port number '$port' is invalid."
		return
	fi

	if [ ! -z "$protocol" ]; then
		if [ "$protocol" != "tcp" -a  "$protocol" != "udp" ]; then
			warn "add_service_network_service() error: '$service' service protocol name '$protocol' is invalid."
			return
		fi
		protocol_expr="$protocol"
	else
		protocol_expr='..*'
	fi

	grep -q -E "^[[:space:]]*${service}[[:space:]]*${port}/${protocol_expr}(([[:space:]]*"'$'")|([[:space:]]*#.*"'$'"))" $services
	if [ $? -ne 0 ]; then
		awk '{if ($1 != "'$service'" && $2 ~ "^'$port'/'$protocol_expr'([^0-9]|$)") {print "#"$0"\n'$service'\t"$2} else {print $0}}' \
		<$services >"$services.tmp" \
		&& mv -f "$services.tmp" $services >> $product_log 2>&1
	fi
}

delete_user()
{
	local rm_user

	rm_user="$1"

	# if it is mailman user, remove its crontab from system
	if [ "X${rm_user}" = "X${mailman_user}" ]; then

		inten="remove crontab of ${rm_user}"
		echo "y" | $crontab -u "${mailman_user}" -r >> $product_log 2>&1 || die "$inten"

	fi

	inten="remove user $rm_user"
	echo_try "$inten"

	case "$machine" in
		BSD)
			echo "y" | pw userdel $rm_user>> $product_log 2>&1 && suc 
			pwd_mkdb /etc/master.passwd >> $product_log 2>&1
		;;
		linux|solaris)
			userdel  $rm_user>> $product_log 2>&1 && suc || die "$inten"
		;;
		Darwin)
			niutil -destroy / /users/"$rm_user" >> $product_log 2>&1 && suc || die "$inten"
			reload_darwin_netinfo
		;;
	esac
}

delete_group()
{
	local rm_group

	rm_group="$1"

	inten="remove group $rm_group"
	echo_try "$inten"

	case "$machine" in
		BSD)
			pw groupdel $rm_group>> $product_log 2>&1
			pwd_mkdb /etc/master.passwd >> $product_log 2>&1
		;;
		linux|solaris)
			mk_backup "/etc/group" cp f
			if [ -f "/etc/group" ]; then
				sed -e "/$rm_group/d" < /etc/group > /etc/group.tmp || die $inten
				mv -f /etc/group.tmp /etc/group  >> $product_log 2>&1
				if [ "$?" -ne 0 ]; then
					rsr_backup "/etc/group" cp f
					die $inten
				fi
			fi
		;;
		Darwin)
			niutil -destroy / /groups/"$rm_group" >> $product_log 2>&1 && suc || die "$inten"
			reload_darwin_netinfo
		;;
	esac
	suc
}

reload_darwin_netinfo()
{
    if [ -f /var/run/memberd.pid ]; then
	kill -HUP `cat /var/run/memberd.pid`
    else
	SystemStarter start memberd
    fi

    return 0
}
initial_conf()
{
	DEMO_VERSION="no"
	PRODNAME="psa"
	PRODUCT_NAME="Plesk"
	product_full="Plesk"
	product=${PRODNAME}
	PRODUCT_FULL_NAME="Plesk"

	product_etc="/etc/${PRODNAME}"
	prod_conf_t="/etc/psa/psa.conf"
	prodkey="$product_etc/$PRODNAME.key"

	minimal_changes="0"

	MYSQL_VERS="4.1.18"
	POSTGRESQL_VERS="7.4.11"
	EXTERNAL_PACKAGES="localedata"
	EXTERNAL_PACKAGES_DIR="tmp/packages"

	BUILDER_UID="10007"

	PERL5LIB=/usr/local/psa/lib/perl5/site_perl/5.8.8:/usr/local/psa/lib/perl5/site_perl/5.8.8/mach
	export PERL5LIB

        support_contact="http://www.parallels.com/support"
	sales_email="sales@parallels.com"

	product_version="9.5.3"
	product_db_version="0953"
	product_build="95101022.03"
	conceived_os_vendor=FreeBSD
	conceived_os_version="6.1"
	osrels="fr6.1"

	# This variable contains all versions, which is supported by
	# cumulative upgrade
	known_product_versions="71 75 80 81 82 83 84 86 90 92 93 95"

	prev_product="plesk"
	prev_clients_group="${prev_product}cln"

        clients_group="${product}cln"
        clients_GID=10001

        services_group="${product}serv"
        services_GID=10003

        product_suff="saved_by_${product}".`date "+%m.%d;%H:%M"`
        product_suffo="saved_by_${product}"

	PREV_PRODUCT_ROOT_D="/usr/local/${prev_product}"

	# plesk default password
	if [ "X$DEMO_VERSION" = "Xyes" ]; then
		PRODUCT_DEFAULT_PASSWORD="plesk"
	else
		PRODUCT_DEFAULT_PASSWORD="setup"
	fi
}

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
			[ 0$ignore_miss_conf -ne 1 ] && p_echo "Unable to find product configuration file: $prod_conf_t"
			return 1
		fi
	fi
	return 0
}

get_my_cnf_param()
{
	local my_cnf cnf_files

	cnf_files="/etc/my.cnf /etc/mysql/my.cnf /var/db/mysql/my.cnf"

	for my_cnf in ${cnf_files}; do
		if [ -f ${my_cnf} ]; then
			break
		fi
	done

	[ -f ${my_cnf} ] && r=`perl -e '$p="'"$1"'";
	undef $/; $_=<>; s/#.*$//gm;
	/\[mysqld\](.*?)\[/sg;
	$_=substr($1, rindex $1,"$p") and
	/$p\s*=(.*)/m and print $1
	' ${my_cnf}`
	echo $r
}

get_mysql_socket()
{
	mysql_socket="/tmp/mysql.sock"

	local mysqlsock=`get_my_cnf_param  socket`
	local MYSQL_SOCKETS="/var/lib/mysql/mysql.sock /tmp/mysql.sock /var/run/mysqld/mysqld.sock"

	for i in $mysql_socket $mysqlsock $MYSQL_SOCKETS; do
	    if [ -S "$i" ]; then
		    MYSQL_UNIX_PORT=$i
		    export MYSQL_UNIX_PORT
		    mysql_socket="$i"
		    break
	    fi
	done
}

 #default values

product_default_conf()
{

PRODUCT_ROOT_D=/usr/local/psa
PRODUCT_RC_D=/usr/local/etc/rc.d
PRODUCT_ETC_D=/usr/local/etc/psa
PLESK_LIBEXEC_DIR=/usr/local/libexec/plesk-9.0
HTTPD_VHOSTS_D=/usr/local/www/vhosts
HTTPD_CONF_D=dynamic
HTTPD_INCLUDE_D=dynamic
HTTPD_BIN_D=/usr/local/sbin
HTTPD_LOG_D=/var/log
HTTPD_SERVICE=dynamic
QMAIL_ROOT_D=/usr/local/psa/qmail
PLESK_MAILNAMES_D=/usr/local/psa/qmail/mailnames
RBLSMTPD=/usr/local/psa/qmail/bin/rblsmtpd
COURIER_IMAP_ROOT_D=/usr/local/psa/courier-imap
FTPD_CONF=/usr/local/psa/ftpd/etc/proftpd.conf
FTPD_CONF_INC=/usr/local/psa/ftpd/etc/proftpd.include
FTPD_BIN_D=/usr/local/psa/ftpd/bin
FTPD_VAR_D=/usr/local/psa/ftpd/var
FTPD_SCOREBOARD=/usr/local/psa/ftpd/var/scoreboard
NAMED_RUN_ROOT_D=/var/named
NAMED_OPTIONS_CONF=/etc/namedb/named.conf.include.plesk-options
NAMED_ZONES_CONF=/etc/namedb/named.conf.include.plesk-zones
WEB_STAT=/usr/local/psa/webalizer/bin/webalizer
LOGROTATE=/usr/local/psa/logrotate/sbin/logrotate
MYSQL_VAR_D=/var/db/mysql
MYSQL_BIN_D=/usr/local/bin
PGSQL_DATA_D=/usr/local/pgsql/data
PGSQL_BIN_D=/usr/local/bin
DUMP_D=/usr/local/psa/var/dumps
DUMP_TMP_D=/tmp
MAILMAN_ROOT_D=/usr/local/mailman
MAILMAN_VAR_D=/usr/local/mailman
PYTHON_BIN=/usr/local/bin/python2.5
CATALINA_HOME=/usr/local/tomcat5.5
DRWEB_ROOT_D=/usr/local/drweb
DRWEB_ETC_D=/usr/local/etc/drweb
GPG_BIN=/usr/local/bin/gpg
TAR_BIN=/usr/bin/tar
AWSTATS_ETC_D=/usr/local/etc/awstats
AWSTATS_BIN_D=/usr/local/psa/awstats/wwwroot/cgi-bin
AWSTATS_TOOLS_D=/usr/local/psa/awstats/tools
AWSTATS_DOC_D=/usr/local/psa/awstats/wwwroot
OPENSSL_BIN=/usr/bin/openssl
LIB_SSL_PATH=/lib/libssl.so
LIB_CRYPTO_PATH=/lib/libcrypto.so
CLIENT_PHP_BIN=/usr/local/psa/bin/php-cli
CGI_PHP_BIN=/usr/local/www/cgi-bin/cgi_wrapper/cgi_wrapper

}


#Need for register/unregister services into /etc/rc.conf for BSD OSes.
#Create or change strings such as service_option_variable="variable"
rc_service()
{
   local service="$1"
   local option="$2"
   local variable="$3"
   local comment="$4"
 
   local config="/etc/rc.conf"

   if [ "X$variable" = "Xdefault" ]; then
      remove_option_string "${service}_${option}" "$config"
      return 0
   fi

   if [ ! -f /etc/rc.conf ]; then
      die 'File /etc/rc.conf not found!'
   fi

   if [ "X$service" = "X" -o "X$option" = "X" -o "X$variable" = "X" ]; then
      die
   fi

   local flag="`grep "${service}_${option}" $config`"
   
   if [ "X$flag" = "X" ]; then
        if [ "X$comment" = "Xyes" ]; then
           echo "#Option for $service created by Plesk installer." >> $config
	fi
	echo "${service}_${option}=\"${variable}\"" >> $config || die 
   else
        sed -i "" -e 's|\('"${service}_${option}"'.*=\"\).*|\1'"${variable}"'\"|' $config  || die
   fi

   return 0
}

register_service()
{
    register_service_freebsd "$@"
}

register_service_freebsd()
{
    rc_service "$1" "enable" "YES" "yes"
}

unregister_service()
{
    unregister_service_freebsd "$@"
}

unregister_service_freebsd()
{
    rc_service "$1" "enable" "NO"
}

remove_option_string()
{
    #using: remove_option_string <option> <file>
    substring="$1"
    file="$2"

    awk '{
	if ($0 ~ "^'"$substring"'") {
	    next;
	}; 
	print $0; 
    }' < $file  > $file.tmp

    mv $file.tmp $file
}
# vim:syntax=sh

selinux_is_active()
{
	if [ -z "$SELINUX_ENFORCE" ]; then
		selinux_getenforce
	fi

	case "$SELINUX_ENFORCE" in
	Enforcing|Permissive) return 0;;
	*) return 1;;
	esac
}

selinux_get_mount_dir()
{
	unset SELINUX_MOUNT_DIR

	if awk '$2 == "/selinux"{exit(1)}' /proc/mounts && mkdir -p /selinux; then
		SELINUX_MOUNT_DIR=/selinux
	else
		SELINUX_MOUNT_DIR="`mktemp -d /tmp/selinuxXXXXXX`"
	fi >>"$product_log" 2>&1
}

selinux_getenforce()
{
	if [ "$1" = "--check" -a -n "$SELINUX_ENFORCE" ]; then
		return
	fi
	unset SELINUX_ENFORCE

	if ! ( command -v selinuxenabled >/dev/null 2>&1 && selinuxenabled ); then
		SELINUX_ENFORCE=Disabled
		return
	fi

	if awk '$3 == "selinuxfs"{exit(1)}' /proc/mounts; then
		selinux_get_mount_dir
		mount -t selinuxfs none "$SELINUX_MOUNT_DIR"
	fi

	if ! command -v getenforce >/dev/null 2>&1; then
		SELINUX_ENFORCE=Disabled
		return
	fi

	SELINUX_ENFORCE="`getenforce`"
	if test $? -ne 0; then
		SELINUX_ENFORCE=Disabled
		return
	fi
}

selinux_init()
{
	unset SELINUX_ENFORCE
	if selinux_is_active; then
		setenforce Permissive
	else
		unset SELINUX_ENFORCE
	fi
}

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

	setenforce "$SELINUX_ENFORCE"
}

selinux_relabel_dir()
{
	if ! command -v restorecon >/dev/null 2>&1; then
		return
	fi
	if [ "$1" = "-F" ]; then
		selinux_set_force_arg
		shift
	else
		SELINUX_FORGE_ARG=
	fi
	
	if [ "$1" = "-e" ]; then
		selinux_set_exclude_arg "$2"
		shift 2
	else
		SELINUX_EXCLUDE_ARG=
	fi

	restorecon $SELINUX_FORGE_ARG $SELINUX_EXCLUDE_ARG -R "$@" >>"$product_log" 2>&1 || report_problem "Error while setting SELinux types for '$dir'"
}

selinux_set_force_arg()
{
	SELINUX_FORGE_ARG="" 
}

selinux_set_exclude_arg()
{
	selinux_set_exclude_arg_pass "$1"
}

selinux_set_exclude_arg_pass()
{
	SELINUX_EXCLUDE_ARG=""
}


#set_params

set_common_params()
{
	common_var=0

	PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
	LANG=C
	export PATH LANG
	umask 022
	ulimit -n 65535 2>/dev/null

	K_HUP="/bin/kill -HUP"
	K_KILL="/bin/kill -KILL"
	K_TERM="/bin/kill -TERM"
	K_USR2="/bin/kill -USR2"

	users_created=""
	groups_created=""

	certificate_file="$PRODUCT_ETC_D/httpsd.pem"
	services="/etc/services"
	mtab="/etc/mtab"
	[ -f "/etc/rsyslog.conf" ] && syslog_conf="/etc/rsyslog.conf" || syslog_conf="/etc/syslog.conf"
	syslog_conf_ng="/etc/syslog-ng/syslog-ng.conf"
	get_hostname="hostname"
	get_domainname="domainname"

	#VZP used to determine that we're inside SVE
	vza_file="/var/vzagent"

	#default parameters
	tar="tar"
	crontab="/usr/bin/crontab"

	cp_preserve="cp -p"
	SYSTEM_RC_D=/etc/rc.d
	PLESK_LIBEXEC_DIR="/usr/local/libexec/plesk-9.0"
	PLESK_DB_DIR="/var/db/plesk"
	POSTFIX_LIBEXEC_DIR="/usr/local/libexec/postfix"

	set_common_params_freebsd 

	detect_vz
}

set_common_params_freebsd()
{
	machine="BSD"
        fstab="/etc/fstab"
	sendmail="/usr/sbin/sendmail"
	mail_local="/usr/libexec/mail.local"
	ps="ps axw"
	ps_long="ps axfwu"
	dummy_shell="/sbin/nologin"
	dummy_home="/"
	false_shell="/usr/bin/false"
	bash_shell="/usr/local/bin/bash"
	rbash_shell="/usr/local/bin/rbash"
	compress="gzip -9 -c"
	uncompress="gunzip -c"
	uudecode="uudecode -p"
	uudecode_full="/usr/bin/uudecode"
	ifconfig="/sbin/ifconfig -a"
	inet_str="inet"
	os_version=`uname -v | sed -e 's/^.*FreeBSD[ \t][ \t]*\([0-9\.][0-9\.]*\)-.*$/\1/'`
	tar="gtar"
	named_osrelease=040100 # "must be >= 020218 for  named -u <named> "

	return 0
}
packagemng_set_dirty_flag()
{
	if [ -f ${PRODUCT_ROOT_D}/admin/bin/packagemng ]; then
	    ${PRODUCT_ROOT_D}/admin/bin/packagemng --set-dirty-flag 1>>$product_log 2>&1
	fi
}

mailman_status_BSD()
{
	local pidfile="${MAILMAN_ROOT_D}/data/master-qrunner.pid"

	if [ -f "$pidfile" ]; then
	    pid="`cat $pidfile`"
	    if [ -z "$pid" ]; then
		    warn "pidfile does not correct"
		    return 1
	    fi

	    ps ax | grep -q $pid 2>&1 >$product_log
	    [ $? -eq 0 ] && return 0
	fi

	return 1
}

remove_modules()
{
	p_echo
	p_echo "===> Removing modules"

	local moduledir
	for moduledir in $PRODUCT_ROOT_D/var/modules/*; do
		if [ -d "$moduledir" -a -x "$moduledir/uninstall" ]; then
			local module=`basename $moduledist`
			echo_try "uninstall $module module"
			"$moduledir/uninstall" && suc || warn "uninstallation of $module module"
		fi
	done
}


# mysql

set_mysqld_params()
{
	mysql_user="mysql"
	mysql_UID=3306
	mysql_group="mysql"
	mysql_GID=3306

	product_db_sql="$PRODUCT_ETC_D/db/${PRODNAME}_db.sql"

	set_mysql_server_params
	set_mysql_client_params
}

## @@constructor set_mysqld_params

set_mysql_server_params()
{
	local service

	MYSQL_ROOT="$PRODUCT_ROOT_D/mysql"
	mysql_bindir="$MYSQL_BIN_D"

	get_mysql_socket

	if [ -x "${PRODUCT_RC_D}/mysql-server" ]; then
	    mysql_service="mysql-server"
	elif [ -x "${PRODUCT_RC_D}/mysql-server.sh" ]; then
	    mysql_service="mysql-server.sh"
	elif [ -x "${PRODUCT_RC_D}/mysqld" ]; then
	    mysql_service="mysqld"
	elif [ -x "${PRODUCT_RC_D}/mysql" ]; then
	    mysql_service="mysql"
	elif [ "X$DEMO_VERSION" = "Xyes" ]; then
	    mysql_service="mysqld"
	else
	    die "$inten"	
	fi
}

true mysql_start mysql_stop mysql_status

set_mysql_client_params()
{
	mysql_client="$MYSQL_BIN_D/mysql"

#	Override these variables as needed
	mysql_db_name="$PRODNAME"
	mysql_passwd_file="$product_etc/.${PRODNAME}.shadow"
	prev_mysql_passwd_file="$PREV_PRODUCT_ROOT_D/admin/conf/admin.conf"

 	if [ -z "$mysql_unconfigured" ];then
#	Need for mysql_status related function
		set_mysql_server_params	
		set_mysql_auth
	fi

	mysql_args="-N"
	mysql_args_raw="-Br"

	# For backward compatibility only, should use mysql() and mysql_raw() instead
	mysql=mysql
	mysql_raw=mysql_raw
}

# iF YOUR package want to use mysql db you must call this function directly
set_mysql_auth()
{
	local inten="set up mysql authentification"
	get_admin_passwd

	pleskrc mysql start

	mysql_user="--user=admin"
	mysql_passwd="--password=$admin_passwd"
	unset mysql_defaults

	mysql_test_connection 60 || die "$inten"
	suc
}

get_admin_passwd()
{
    [ -z "$admin_passwd" ] || return 0

    if [ -f "$mysql_passwd_file" ]; then
		admin_passwd=`cat "$mysql_passwd_file"`
		return 0
    fi
    admin_passwd="$PRODUCT_DEFAULT_PASSWORD"
}

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

mysql_anydb()
{
	if test -z "$DB_IS_MYSQL41_COMPATIBLE"; then
		mysql41_init
	fi

	if [ "$DB_IS_MYSQL41_COMPATIBLE" != "compatible" -a "X$machine" != "XBSD" ]; then
		mysql41_exec_wrapper $mysql_client $mysql_user $mysql_passwd $mysql_args "$@" 2>>"$product_log"
	else
		$mysql_client $mysql_user $mysql_passwd $mysql_args "$@" 2>>"$product_log"
	fi

	local status=$?
	if [ $status -gt 0 ]; then
		$mysql_client $mysql_user $mysql_passwd $mysql_args -D$mysql_db_name $mysql_args_raw -e "show innodb status" >>"$product_log" 2>&1
	fi
	return $status
}

# the function removes the "character set xxx" and "collate xxx" construction
# from -e * arguments, if there are any.
# otherwise, it removes the same things from standard input
mysql41_exec_wrapper()
{
	perl -e '$has_command = 0;
		$program = $ARGV[0];
		splice (@ARGV, 0, 1);
		sub remove_charsets($)
		{
			$refStr = shift;
			$$refStr =~ s/\b(medium|long|tiny)?text\s+character\s+set\s+binary(\s+collate\s+[\w]+)?\b/ $1blob /ig;
            $$refStr =~ s/\b(medium|long|tiny)?text\s+character\s+set\s+[\w]+\s+collate\s+[\w]+_bin\b/ $1blob /ig;
			$$refStr =~ s/(\bcharacter\s+set\s+binary(\s+collate\s+[\w]+)?\b)/ binary /ig;
			$$refStr =~ s/(\bcharacter\s+set\s+[\w]+\s+collate\s+[\w]+_bin\b)/ binary /ig;
			$$refStr =~ s/(\b(character\s+set|collate)\s+[\w]+\b)//ig;
		}
		foreach $n (0 .. $#ARGV) {
			if ($ARGV[$n] eq "-e") {
				$has_command = 1;
				remove_charsets \($ARGV[$n + 1]);
			}
		}
		if ($has_command) {
			exec $program, @ARGV or die "Cannot execute mysql";
		} else {
			open out_command, "|-", $program, @ARGV or die "Cannot start mysql";
			while (<STDIN>) {
				remove_charsets \($_);
				print out_command $_;
			}
			close out_command or die($! ? "Mysql returned an error: $!" : "Mysql exited with non-zero status $?");
		}' -- "$@"
}

# Invoke mysql without any wrapper or something else
mysql_direct()
{
	$mysql_client $mysql_defaults $mysql_user $mysql_passwd $mysql_args "$@" 2>>"$product_log"
}

# Invoke mysql in raw mode
mysql_raw()
{
	mysql $mysql_args_raw "$@"
}

mysql_raw_anydb()
{
	mysql_anydb $mysql_args_raw "$@"
}

mysql_test_connection()
{
	inten="establish test connection"
	echo_try $inten
	attempts=${1:-1}	
	for i in `sequence $attempts`; do
		echo "" | mysql_direct mysql >> "$product_log" 2>&1
		if [ "$?" -eq "0" ]; then
			p_echo "connected"
			return 0
		fi
		[ "$attempts" -eq "1" ] || sleep 2
	done

	p_echo "failed"
	return 1
}

mysql41_init()
{
	# not_installed is the default state
	# we must init it to avoid endless cycle
	DB_IS_MYSQL41_COMPATIBLE=not_installed
	if ! mysql_anydb </dev/null >>"$product_log" 2>&1; then
		return
	fi

	if db_test --any-db "SHOW VARIABLES LIKE 'version'" '$2 !~ /^(3|4\.0)\./'; then
		# if database is not yet initiailized, assume it compatible
		# otherwise, check the flag
		if
			db_test --any-db "SHOW DATABASES" '/^psa$/' 			&& db_test "SHOW TABLES" '/^misc$/' 			&& ! db_test "SELECT val FROM misc WHERE param = 'mysql41_compatible'" '/true/'
		then
			DB_IS_MYSQL41_COMPATIBLE='not_compatible'
		else
			DB_IS_MYSQL41_COMPATIBLE='compatible'
		fi
	fi
}

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

	inten="stop MySQL server"
	echo_try $inten

	$PRODUCT_RC_D/$mysql_service stop >> $product_log 2>&1

	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

		case $machine in
			BSD*|Darwin*)
				#In BSD systems mysqld must to be killed without -9 flag
				killall mysqld mysqld_safe >> $product_log 2>&1
			;;
			*)
				# I just want to be sure that mysql really stopped
				killall -9 mysqld mysql safe_mysqld mysqld_safe >> $product_log 2>&1
			;;
		esac
		sleep $i
	done

	die "$inten"
}

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
# Common RPM mysql's and FreeBSD
	$PRODUCT_RC_D/$mysql_service status >> $product_log 2>&1 		&& 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
}

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
}

poppassd_super_server_config()
{
	local action="$1"

	case "$superserver" in
	    inetd)
		poppassd_rec="poppassd stream tcp nowait/1000 root /usr/libexec/tcpd $PRODUCT_ROOT_D/admin/sbin/poppassd"
		;;	
	    xinetd)
		poppassd_rec="service poppassd
{
socket_type             = stream
protocol                = tcp
port                    = 106
wait                    = no
disable                 = no
user                    = root
instances               = 1000
flags                   = KEEPALIVE
server                  = $PRODUCT_ROOT_D/admin/sbin/poppassd
}"
		;;
	    *)
		    die "Super server name unknown"
		;;
	esac

	super_server_action "$action" poppassd "$poppassd_rec"
}


# vim:syntax=sh

mail_restore_all()
{
	# temporary solution to close #143977 and #144076: three keys to turn on
	if [ ! -e "$PRODUCT_ROOT_D/version" ]; then
		echo "$PRODUCT_ROOT_D/version isn't yet on its place. Deferring mail_restore execution to a later stage" >&2
		return
	fi
	if [ ! -x "/usr/local/libexec/plesk-9.0/mailsrv_entities_dump" ]; then
		echo "/usr/local/libexec/plesk-9.0/mailsrv_entities_dump isn't yet on its place. Deferring mail_restore execution to a later stage" >&2
		return
	fi
	if [ ! -x "/usr/local/libexec/plesk-9.0/mail_restore" ]; then
		echo "/usr/local/libexec/plesk-9.0/mail_restore isn't yet on its place. Deferring mail_restore execution to a later stage" >&2
		return
	fi

	# FIXME: There's a possible race during upgrade procedure. Noone
	# managed to catch the bug in debug mode, so be stupid:
	sync; sync; sleep 3

	inten="executing mail_restore to synchronize mail server settings and Plesk Database"
	echo_try $inten
	/usr/local/libexec/plesk-9.0/mail_restore
	suc
	# A temporary solution for http://bugs.plesk.ru/show_bug.cgi?id=143786
	"${PRODUCT_ROOT_D}/admin/sbin/mailmng" --restart-service
}
	
mail_init_conf()
{
	/usr/local/libexec/plesk-9.0/mailsrv_conf_init
	if [ -x /sbin/restorecon ]; then
		/sbin/restorecon /etc/aliases.db
	fi
	# if Mailman is installed, adapt its configs for QMail
	if [ -f "/usr/local/mailman/Mailman/mm_cfg.py" ]; then
		/usr/local/libexec/plesk-9.0/mailman_conf_init "/usr/local/mailman/Mailman/mm_cfg.py" ||:
	fi
}

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
}

# this fucntion designed for use on Debian-based systems only.
# this restriction comes from using extended mode of GNU sed.
disable_inetd_mail()
{
	return 0
}

disable_foreign_mtas()
{
	[ -n "$1" ] || simply_die "No MTA to disable"

	for mta in $@; do
		if [ "$mta" = "qmail" ]; then
# disable_qmail work only on superserver part
			disable_qmail
		fi

		if pleskrc $mta exists; then
			pleskrc $mta stop
			unregister_service $mta
		fi

# Special code for sendmail
		if [ "$mta" = "sendmail" ]; then
# On FreeBSD we need to disable +3 services of sendmail
# see bottom of http://www.freebsd.org/cgi/man.cgi?query=rc.sendmail&sektion=8
			unregister_service "sendmail_submit"
			unregister_service "sendmail_outbound"
			unregister_service "sendmail_msp_queue"
			:
		fi # sendmail
		if [ "$mta" = "postfix" ]; then
# kill postfix, if it is not killed yet (146005)
			local postfix_pid="`$ps | grep "postfix\/master" | grep -v grep | awk '{print $1}' -`"
			if [ "X$postfix_pid" != "X" ]; then
				echo_try "shutdown running postfix"
				$K_TERM $postfix_pid > /dev/null 2>&1
				if [ "$?" -ne "0" ]; then
					wait_after_stop $postfix_pid
				fi
			fi
		fi # postfix

		if [ "$mta" = "qmail" ]; then
# Forcly kill qmail-send (146877)
			local qmail_pid="`$ps | grep "qmail-send" | grep -v grep | awk '{print $1}' -`"
			if [ "X$qmail_pid" != "X" ]; then
				echo_try "shutdown running qmail-send"
				$K_TERM $qmail_pid > /dev/null 2>&1
				if [ "$?" -ne "0" ]; then
					wait_after_stop $qmail_pid
				fi
			fi
		fi # qmail
done
}

set_mail_params()
{
	HANDLERS_USER="mhandlers-user"
	MAIL_USERGROUP="popuser"
}

set_foreign_mtas_params()
{
	# need for pleskrc to work properly
	exim_service="exim"
	exim4_service="exim4"
	sendmail_service="sendmail"
}

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

	set_syslog_params
	mail_log="$PRODUCT_ROOT_D/var/log/maillog"
	case "$machine" in
		Darwin)
			mail_log_str="$mail_log"
            ;;
		*)
			mail_log_str="-$mail_log"
			;;
	esac
	
	[ -d "$PRODUCT_ROOT_D/var/log" ] || mkdir -p "$PRODUCT_ROOT_D/var/log" 
	touch $mail_log
	selinux_relabel_dir "$PRODUCT_ROOT_D/var/log"

	[ -f $syslog_conf ] && set_maillog $mail_log $mail_log_str $inten >> $product_log 2>&1 
	[ -f $syslog_conf_ng ] && set_maillog_ng $mail_log $inten  >> $product_log 2>&1 

	reload_maillog
}

reload_maillog()
{
	# 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
		pleskrc syslog restart
	else
		pleskrc syslog reload
	fi

	if [ "$syslog_service" = "syslog" -a "$PLESK_VZ" = "1" ]; then
# 146355 - syslog service returns false on VZ
		/etc/init.d/$syslog_service restart
	fi
}

_set_maillog_ng_change()
{
    local conf_file mail_log inten bak_ext

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

#     [ -z "$bak_ext" ] && bak_ext=.bak

    echo_try "$inten"

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

    ## Set log in $PRODUCT_ROOT_D/var/log/maillog
    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()
{
	mail_log=$1
	mail_log_str=$2
 	inten=$3
	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
			sed -e "s|^mail\.\*.*$|mail.*						$mail_log_str|" \
			< $syslog_conf > $syslog_conf.tmp && \
			mv -f $syslog_conf.tmp $syslog_conf || die "$inten"
		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|\(^.*\)\([[:space:]]\)\(\/var\/log\/messages\)|\1\2-\3|' < $syslog_conf > $syslog_conf.tmp && \
#           mv -f $syslog_conf.tmp $syslog_conf || die "$inten"

	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
}

comment_out_comsat()
{

    if [ -f "$superserver_conf" ]; then
	mk_backup $superserver_conf cp f

	grep_res=`egrep '^comsat' $superserver_conf`
	inten="comment out comsat service record from $superserver_conf"
	echo_try $inten

	case "$grep_res" in
		comsat*)
			sed -e "s/^comsat/#comsat/g" < "$superserver_conf" > "$superserver_conf.${product}_tmp" || die
			mv -f "$superserver_conf.${product}_tmp" "$superserver_conf" && suc || die $inten
			;;
		*)
			p_echo " there is no comsat service record in $superserver_conf"
			;;
	esac
    fi
}

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
}

disable_qmail()
{
    qmail_super_server_config remove smtp
    qmail_super_server_config remove smtps
    qmail_super_server_config remove submission
    superserver_reconfig
}
#qmail

set_qmail_params()
{
    QMAIL_DIR="/usr/local/psa/qmail"
    QMAIL_USERS="alias:2021:nofiles:false:alias  qmaild:2020:nofiles:false:  qmaill:2022:nofiles:false:  qmailp:2023:nofiles:false:  qmailq:2520:qmail:  qmailr:2521:qmail:  qmails:2522:qmail:"
    QMAIL_GROUPS="qmail:2520  nofiles:2020"

    #variable from psa.conf but used in mail-qc-driver
    #so we need define this before install psa base package
    if [ -z "$QMAIL_ROOT_D" ]; then 
	    QMAIL_ROOT_D="/usr/local/psa/qmail"
    fi

    mm_mailgroup=110

    qmail_service="qmail"
    qmail_extra_cmd=""
    qmail_log="/var/log/maillog"
}

## @@constructor set_qmail_params

set_syslog_params()
{
	syslog_service="syslogd"
# FIXME: quick fix of 142129
	if [ "${machine}" = "linux" -a ! -x "$PRODUCT_RC_D/$syslog_service" -a -x "$PRODUCT_RC_D/rsyslog" ]; then
		syslog_service="rsyslog"
		syslog_binary="/sbin/rsyslogd"
	else
		syslog_binary="/sbin/syslogd"
	fi
}
## @@constructor set_syslog_params

qmail_super_server_config()
{
    local action="$1"
    local service="$2"

    case "$superserver" in
	inetd)
		qmail_inetd_templates
		;;
	xinetd)
		qmail_xinetd_templates
		;;
	*)
		die "Super server name unknown"
		;;
    esac

   	eval "template=\$${service}_rec"

    super_server_action "$action" "$service" "$template"
}

qmail_inetd_templates()
{
	maxconn=''
	if [ "$linux_distr" = "debian" ]; then 
	    maxconn='.1000'
	fi

	smtp_rec="smtp stream tcp nowait$maxconn root $QMAIL_DIR/bin/tcp-env tcp-env /usr/bin/env SMTPAUTH=1 END=1 $QMAIL_DIR/bin/relaylock $QMAIL_DIR/bin/qmail-smtpd $QMAIL_DIR/bin/smtp_auth $QMAIL_DIR/bin/true $QMAIL_DIR/bin/cmd5checkpw $QMAIL_DIR/bin/true"

	smtps_rec="smtps stream tcp nowait$maxconn root $QMAIL_DIR/bin/tcp-env tcp-env /usr/bin/env SMTPAUTH=1 END=1 $QMAIL_DIR/bin/relaylock $QMAIL_DIR/bin/qmail-smtpd $QMAIL_DIR/bin/smtp_auth $QMAIL_DIR/bin/true $QMAIL_DIR/bin/cmd5checkpw $QMAIL_DIR/bin/true"

	submission_rec="submission stream tcp nowait$maxconn qmaild $QMAIL_DIR/bin/tcp-env tcp-env /usr/bin/env SUBMISSION=1 SMTPAUTH=1 END=1 $QMAIL_DIR/bin/qmail-smtpd $QMAIL_DIR/bin/smtp_auth $QMAIL_DIR/bin/true $QMAIL_DIR/bin/cmd5checkpw $QMAIL_DIR/bin/true"

}

qmail_xinetd_templates()
{
    local TRUE_BIN
    TRUE_BIN=$QMAIL_DIR/bin/true
smtp_rec="service smtp
{
	socket_type     = stream
	protocol        = tcp
	wait            = no
	disable		= no
	user            = root
	instances       = UNLIMITED
	env             = SMTPAUTH=1
	server          = $QMAIL_DIR/bin/tcp-env
	server_args     = -Rt0 $QMAIL_DIR/bin/relaylock $QMAIL_DIR/bin/qmail-smtpd $QMAIL_DIR/bin/smtp_auth $TRUE_BIN $QMAIL_DIR/bin/cmd5checkpw $TRUE_BIN
}" 

smtps_rec="service smtps
{
	socket_type     = stream
	protocol        = tcp
	wait            = no
	disable		= no
	user            = root
	instances       = UNLIMITED
	env             = SMTPAUTH=1
	server          = $QMAIL_DIR/bin/tcp-env
	server_args     = -Rt0 $QMAIL_DIR/bin/relaylock $QMAIL_DIR/bin/qmail-smtpd $QMAIL_DIR/bin/smtp_auth $TRUE_BIN $QMAIL_DIR/bin/cmd5checkpw $TRUE_BIN
}" 

submission_rec="service submission
{
	socket_type     = stream
	protocol        = tcp
	wait            = no
	disable		= no
	user            = qmaild
	instances       = UNLIMITED
	env             = SUBMISSION=1 SMTPAUTH=1
	server          = $QMAIL_DIR/bin/tcp-env
	server_args     = -Rt0 $QMAIL_DIR/bin/qmail-smtpd $QMAIL_DIR/bin/smtp_auth $TRUE_BIN $QMAIL_DIR/bin/cmd5checkpw $TRUE_BIN
}" 

}


rsr_backup()
{
	target="$1"
	dup="$2"
	opts="$3"
	common_var=0

#	if [ -$opts "$target" ]; then
		if [ -$opts "$target.$product_suff" ]; then
			case "$dup" in
				mv)
					mv -f  $target.$product_suff $target>> $product_log 2>&1
					common_var=1
					return 1
					;;
				cp)
					cp -fp  $target.$product_suff $target>> $product_log 2>&1
					common_var=1
					return 1
					;;
				*)
					p_echo " rsr_backup: wrong option -- must be 'cp' or 'mv'"
					;;
			esac
		else
			if [ -$opts "$target.$product_suffo" ]; then
			    case "$dup" in
				mv)
					mv -f  $target.$product_suffo $target>> $product_log 2>&1
					common_var=1
					return 1
					;;
				cp)
					cp -fp  $target.$product_suffo $target>> $product_log 2>&1
					common_var=1
					return 1
					;;
				*)
					p_echo " rsr_backup: wrong option -- must be 'cp' or 'mv'"
					;;
			    esac
			fi
		fi
#	else
#		case "$opts" in
#			f|d)
#				;;
#			*)
#				p_echo " rsr_backup: wrong option -- must be 'f' or 'd'"
#				;;
#		esac
#	fi
}

restore_named()
{
	cd "$PRODUCT_ROOT_D" >> $product_log 2>&1
	[ -f /etc/sysconfig/named ] && mv -f "/etc/sysconfig/named" "/etc/sysconfig/named.bak"
	rsr_backup "/etc/sysconfig/named" mv f

	[ -L $named_conf ] && rm -f "$named_conf"
	rsr_backup "$named_conf" mv f

	[ -L $rndc_conf ] && rm -f "$rndc_conf"
	rsr_backup "$rndc_conf" mv f

	case "$machine" in
		BSD*)
			rsr_backup /etc/named.boot mv f
			;;
		linux)
		    case "$linux_distr" in
			redhat)
			    chkconfig --add named >> $product_log 2>&1
#			    std_named_sh="/etc/rc.d/init.d/named"
#			    rsr_backup $std_named_sh mv f
#				if [ -f "$std_named_sh" ]; then
#					mv -f "$std_named_sh.${product}" "$std_named_sh"
#				fi
				;;
			slackware)
			    rsr_backup /etc/rc.d/rc.inet2 cp f
				;;
		    esac
			rsr_backup /etc/named.boot mv f
			;;
		solaris)
			rsr_backup /etc/named.boot mv f
			;;
	esac
}


restore_sendmail()
{
	[ -L $sendmail ] && rm -f "$sendmail"
	[ -L /usr/lib/sendmail ] && rm -f "/usr/lib/sendmail"

	rsr_backup "$sendmail" mv f

	case "$machine" in
		BSDI)
			rsr_backup /etc/sendmail.cf mv f
			;;
		*)
			;;
	esac

	if [ -f "$mail_local" ]; then
#		case "$machine" in
#			BSD)
#				chflags schg "$mail_local" >> $product_log 2>&1
#				;;
#			*)
#				;;
#		esac

		rsr_backup "$mail_local" mv f

		chmod 4555 "$mail_local" >> $product_log 2>&1
	fi
	case "$machine" in
		linux )
		    case "$linux_distr" in
			redhat)
			    chkconfig --add sendmail >> $product_log 2>&1
#			    rsr_backup "$sndml_ini" mv f
				;;
			slackware)
			     rsr_backup /etc/rc.d/rc.M mv f
				;;
		    esac
			;;
		solaris)
			rsr_backup "$sndml_ini" mv f
			;;
		*)
			;;
	esac

}

delete_startup_scripts()
{
	cd "$PRODUCT_ROOT_D" >> $product_log 2>&1

	case "$machine" in
		BSD)
			rm -f /usr/local/etc/rc.d/${product}.sh >> $product_log 2>&1
	#		rsr_backup /etc/rc.conf cp f

			rc_service "sendmail" "enable" "YES"
			rc_service "named" "enable" "YES"
			rc_service "mysqld" "enable" "NO"
			;;
		BSDI)
			if [ -f /etc/rc.local.${product} ]; then
				cp -p  /etc/rc.local.${product} /etc/rc.local >> $product_log 2>&1
			fi
			;;
		linux)
		    case "$linux_distr" in
			redhat)
			    chkconfig --del ${product}
			    rm -f /etc/rc.d/init.d/${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc0.d/K15${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc1.d/K15${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc2.d/K15${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc3.d/S77${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc4.d/S77${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc5.d/S77${product} >> $product_log 2>&1
#			    rm -f /etc/rc.d/rc6.d/K15${product} >> $product_log 2>&1
				;;
			slackware)
			    if [ -f /etc/rc.d/rc.local.${product} ]; then
				cp -p  /etc/rc.d/rc.local.${product} /etc/rc.d/rc.local >> $product_log 2>&1
			    fi
				;;
		    esac
		    ;;
		solaris)
			rm -f  /etc/init.d/${product} >> $product_log 2>&1
			if [ -f /etc/rc0.d/K01${product} ]; then
				rm -f /etc/rc0.d/K01${product} >> $product_log 2>&1
			fi

			if [ -f /etc/rc1.d/K01${product} ]; then
				rm -f /etc/rc1.d/K01${product} >> $product_log 2>&1
			fi

			if [ -f /etc/rc2.d/S77${product} ]; then
				rm -f /etc/rc2.d/S77${product} >> $product_log 2>&1
			fi
			;;
	esac
}

delete_crontab()
{

	$crontab -l 2>/dev/null > /tmp/crontab.${product}

	sed -e "s/^.*\/${product}\/admin\/sbin\/statistics.*//g" \
		-e "s/^.*\/${product}\/bin\/mysqldump.*//g" \
		-e "s/^.*\/usr\/sbin\/ntpdate.*//g" \
		< /tmp/crontab.${product} > /tmp/crontab.${product}_tmp

	mv -f /tmp/crontab.${product}_tmp /tmp/crontab.${product} >> $product_log 2>&1

	$crontab /tmp/crontab.${product}  >> $product_log 2>&1

	rm -f /tmp/crontab.${product} >> $product_log 2>&1

}

remove_ftpuser()
{
	user=$1
	ftpusers_file="/etc/ftpusers"

	egrep "^$user" $ftpusers_file >> /dev/null 2>&1

	case "$?" in
			0)
				sed -e "/$user/d" < $ftpusers_file > $ftpusers_file.tmp
				mv -f $ftpusers_file.tmp $ftpusers_file
				;;
			1)
				;;
			*)
				;;
	esac

}

remove_product_users_groups()
{

#	delete users of this(unsuccessful) installation
	for i in $users_created; do
		delete_user "$i"
	done
#	delete users with group=psacln (ftpusers and webusers)
	for i in `perl -e '$gid=getgrnam("'$clients_group'"); exit if (($gid eq "") || ($gid == 0)); while(($n,$u,$g) = (getpwent)[0,2,3]) {print "$n\n" if (($gid == $g) && ($u >= 500))}'`
	do
		delete_user "$i"
		remove_ftpuser "$i"
	done
#	delete users psaadm, psaftp
#	delete_user "$admin_user"  >> "$product_log" 2>&1
#	delete_user "$anonftp_user"  >> "$product_log" 2>&1

#	delete groups of this(unsuccessful) installation
	for i in $groups_created; do
		delete_group "$i"
	done
#	delete groups psaadm, psaftp, psacln
	delete_group "$admin_group"  >> "$product_log" 2>&1
	delete_group "$anonftp_group"  >> "$product_log" 2>&1
	delete_group "$clients_group"  >> "$product_log" 2>&1

}


undo_install()
{
	p_echo

	if pleskrc mysql status; then
		p_echo "===>Removing installed $PRODUCT_NAME components ... "
		remove_modules
		pleskrc mysql stop

		mysql_pid_file=$mysql_bddir/*.pid
		if [ -f "$mysql_pid_file" ]; then
			rm -f "$mysql_pid_file"
		fi
	fi

	$START_SH stop >> "$product_log" 2>&1

	proftpd_super_server_config remove

	super_server_action remove pop3
	super_server_action remove pop-3
	super_server_action remove imap4
	super_server_action remove imap2
	super_server_action remove imap
	qmail_super_server_config remove smtp
	qmail_super_server_config remove smtps
	qmail_super_server_config remove submission
	poppassd_super_server_config remove

	remove_product_users_groups

	if [ -f "/etc/ftpchroot" ]; then
	    sed -e "s/^@$clients_group//g" < /etc/ftpchroot > /etc/ftpchroot.tmp
	    mv -f /etc/ftpchroot.tmp /etc/ftpchroot  >> $product_log 2>&1
	fi

	if [ -f /etc/shells ]; then
	    case "$machine" in
		BSD|BSDI)
		    sed -e "s/[/]*sbin[/]*nologin//" < /etc/shells > /etc/shells.tmp
		;;
		linux|solaris)
		    sed -e "s/[/]*bin[/]*false//" < /etc/shells > /etc/shells.tmp
		;;
	    esac
	    mv -f /etc/shells.tmp /etc/shells  >> $product_log 2>&1
	fi

	remove_tmp_state

	restore_named
	restore_sendmail
	delete_startup_scripts
	delete_crontab

	cd /usr/local  >> $product_log 2>&1

	suc
}

smart_undo_install()
{
	[ "X$trigger_uninstall" = "X1" -o "X$do_patch" = "X1" -o "X$do_reconfigure" = "X1" ] && return
	[ "X$PLESK_INSTALLER_NOUNDO" != "X" ] && return
	# trigger_uninstall - trigger what smart_undo_install is already working now(recurrence)
	trigger_uninstall=1

	if [ "X$can_uninstall" = "X1" ]; then
		if [ "X$do_upgrade" = "X1" ]; then
			undo_upgrade
		else
		    if [ "X$machine" != "XBSD" ]; then
			undo_install
		    fi
		fi
	fi

	# put suggestions for user what to do
	call_optional_function failure_note
}
undo_upgrade()
{
	p_echo   "    The attempt to upgrade $prev_product_full"
	p_echo   "    from version $prev_version to $product_full $product_version has failed."

	if [ -f "$product_sav_tar" ]; then
	
		p_echo 

		p_echo "    Now restore contents of $PRODUCT_NAME from $product_sav_tar"
		p_echo 
		get_pid $PRODUCT_ROOT_D/mysql/bin/safe_mysqld true root
		req_pid=$common_var
		if [ $req_pid -gt 1 ]; then
			$K_KILL $req_pid >> $product_log 2>&1 
			sleep 2
			mysql_pid_file=$mysql_bddir/*.pid
			kill_pids $PRODUCT_ROOT_D/mysql/libexec/mysqld mysql
			sleep 2
			if [ -f "$mysql_pid_file" ]; then
				rm -f $mysql_pid_file
			fi
		fi

		$START_SH stop >> $product_log 2>&1
		sleep 2

		rm -Rf $PRODUCT_ROOT_D
		qmail_super_server_config remove "smtp"
		qmail_super_server_config remove "smtps"
		proftpd_super_server_config remove
		poppassd_super_server_config remove
		

		cd /
        	tar xvf $product_sav_tar > /dev/null 2>&1
		case "$?" in
			0)
#				rm -f $product_sav_tar 		
			;;
			*)
				p_echo 
				p_echo 
				p_echo "ERROR: restoration of files from $product_sav_tar has failed."
				p_echo "       Please restore them manually."
				p_echo 
				p_echo "Exiting..."
				p_echo 
				exit 0
			;;
		esac
	fi
	
}

reconfigure_watchdog()
{
    [ -x $PRODUCT_ROOT_D/admin/bin/modules/watchdog/wd ] && $PRODUCT_ROOT_D/admin/bin/modules/watchdog/wd --adapt || true
}


set_postfix_params()
{
	postfix_service="postfix"
}

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
}
detect_upgrade()
{
    clean_install
    local ver_with_pkg="810"
    local version_file="$PRODUCT_ROOT_D/version"
    local PKGNAME='psa-mail-qc-driver'

    local isBasePackage="yes"
    local SkipDetect=""

    ## Stage 0. 
    if [ ! -z $SkipDetect ]; then
       return 0
    fi

    #version with epoch  
    local portupgrade_version="`pkg_info -q -O ports-mgmt/portupgrade | awk -F '-' '{print $2}' | \
				awk -F ',' '{print $2$1}' | sed -e 's|\([[:digit:]]*\)\.\([[:digit:]]\).*|\1\2|g'`"

    if [ 0222 -gt 0$portupgrade_version ]; then
        echo ""
        echo "Version portupgrade is incorrect. "
        echo "Make sure that version portupgrade is 2.2 or above."
        echo "Exiting..."
        exit 1
    fi

    ## Upgrade detected in portupgrade
    ## if exists installed port it's already pkg -> pkg upgrade.
    if [ ! -z "$UPGRADE_PORT" ]; then
        upgrade_pkg

        ## Hack for resurect version file for base package.
        if `echo $UPGRADE_PORT | grep -q 'psa-8.1.0'`; then
            echo "8.1.0 `uname -s` `uname -r| awk -F '-' '{print $1}'` ${ver_with_pkg}000000.00" > $version_file
        fi

        return 0
    fi

    ## Upgrade not detected in portupgrade
    ### Clean install
    if [ ! -d $PRODUCT_ROOT_D ]; then
        clean_install
        return 0
    fi

    ### Base packages(no need mysql in depends).
    if [ "X$isBasePackage" = "Xyes" ]; then
	if [ ! -f $version_file ]; then
	    clean_install
            return 0
	fi

	install_ver="`cat $version_file | awk '{print $1}'| sed -e 's|\.||g'`"
	if [ 0$install_ver -lt $ver_with_pkg ]; then
	    upgrade_std
	else
	    upgrade_pkg
	fi
	
	return 0
    fi

    set_mysqld_params
    get_mysql_socket
    pleskrc mysql start 1

    query="SELECT db_version from upgrade_history"
    versions="`echo "$query" | $mysql`"

    if [ "X$versions" = "X" ]; then
	clean_install
	return 0
    else
	local doStdUpgrade=0

	for ver in $versions; do
	    if [ 0$ver_with_pkg -gt 0$ver ]; then 
		doStdUpgrade=1
	    fi
	done 

	if [ 0$doStdUpgrade -ne 0 ]; then 
	    upgrade_std
	else
	    clean_install
	fi
    fi

    return 0
}
    
clean_install()
{
    do_upgrade=0
    std_to_pkg=0
}

upgrade_pkg()
{
    do_upgrade=1
    std_to_pkg=0
}

upgrade_std()
{
    do_upgrade=1
    std_to_pkg=1
}

# vim:syntax=sh

install_qmail_certificate()
{
    local server_cert="$QMAIL_ROOT_D/control/servercert.pem"
    local client_cert="$QMAIL_ROOT_D/control/clientcert.pem"
    local rc=0

    if [ ! -f "$server_cert" ]; then
        inten="copy default SSL Certificate for qmail"
        echo_try "$inten"
        get_certificate "$server_cert"
        rc="$?"
        set_ac qmaild qmail 0640 "$server_cert" 
        rm -f "$client_cert"
        ln -s "$server_cert" "$client_cert"
    fi
    return "$rc"
}

enable_qmail()
{
    if type update-alternatives >/dev/null 2>&1; then
        # SuSe, Debian and Ubuntu not use alternatives for MTAs
	    if [ "$linux_distr" != "suse" -a "$linux_distr" != "debian" -a "$linux_distr" != "ubuntu" ]; then
            /usr/sbin/update-alternatives --set mta "$QMAIL_ROOT_D/bin/sendmail"
        fi
    fi

    ## FIXME: set *default* SMTP service invocation parameters
    # actual Plesk defaults on that matter should be kept in sync
    qmail_super_server_config register smtp

    if [ "$machine-$linux_distr" = "linux-suse" ]; then
	add_service2etc_services 'smtps' 465 'tcp'
    fi

    ## FIXME: set *default* SMTPS service invocation parameters
    # actual Plesk defaults on that matter should be kept in sync
    qmail_super_server_config register smtps
    qmail_super_server_config register submission
    # comment submission service by default
    qmail_super_server_config disable submission
    superserver_reconfig

    register_service qmail defaults defaults
    pleskrc qmail start
}


mail_qc_driver_install_post()
{
    ## FIXME this code shouldn't be executed if we do an upgrade from pre-9
    # Plesk, regardless of mail-qc-driver package status
	selinux_init
    p_echo

    select_maillog

    p_echo "Configuring Qmail-CourierIMAP Plesk Mail Driver..."

    set_super_server_params
    comment_out_comsat

	disable_inetd_mail

    set_mail_params
    set_postfix_params
    set_qmail_params
    set_foreign_mtas_params

    mail_init_conf

    install_qmail_certificate

    register_service qmail defaults defaults

    if [ "$machine" = "BSD" ]; then
        mkdir -p /var/db/plesk/mail/auth
		rm -f $sendmail
		ln -s /usr/local/psa/qmail/bin/sendmail $sendmail
    fi

    # since we provide server-specific courier auth module
    # it's better to configure courier after the module
    # is actually installed
    configure_courier

    disable_foreign_mtas postfix exim exim4 sendmail
    enable_qmail

    # restore if mailer switched from another(e.g. postfix)
    # this function requires configured qmail (enable_qmail is called)
    mail_restore_all
    chown alias /usr/local/psa/handlers/spool

    "$PRODUCT_ROOT_D/admin/sbin/mailmng" --restart-service


	inten="Reconfigure watchdog"
	echo_try $inten
	reconfigure_watchdog
	selinux_close
}

mail_qc_driver_upgrade_new_post()
{
	if [ "$machine" = "BSD" ]; then
		mail_qc_driver_install_post
	else
		configure_courier
	fi
}

type="$2"

if [ "X${PLESK_INSTALLER_DEBUG}" = "X1" ]; then
    set -x
fi

package_script_begin
detect_upgrade

case "$type" in
     PRE-INSTALL)
        if [ "$do_upgrade" = "0" ]; then
                 package_script_call_main_function mail_qc_driver_install_pre mail-qc-driver 9.5.3 fr6.1.build95101022.03
        else
	         package_script_call_main_function mail_qc_driver_upgrade_new_pre mail-qc-driver 9.5.3 fr6.1.build95101022.03
        fi
     ;;
     POST-INSTALL)
        if [ "$do_upgrade" = "0" ]; then
	         package_script_call_main_function mail_qc_driver_install_post mail-qc-driver 9.5.3 fr6.1.build95101022.03
        else
                 package_script_call_main_function mail_qc_driver_upgrade_new_post mail-qc-driver 9.5.3 fr6.1.build95101022.03
        fi
     ;;
     *)
          exit 1
     ;;
esac

exit 0