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

#
# Plesk script
#


# Migration manager tables will be managed by plesk

set_apache_params()
{
	apache_user="apache"
	apache_UID=80
	apache_group="apache"
	apache_GID=80

	user_apxs="/usr/sbin/apxs"

	set_apache_params_linux

	apache_service="$apache_service_name"

	apache_httpd_conf="$HTTPD_CONF_D/httpd.conf"
	apache_httpd_conf2="$HTTPD_CONF_D/httpd2.conf"
	apache_httpd_conf_in="$HTTPD_CONF_D/httpd.conf.in"

	apache_httpd_include="$HTTPD_INCLUDE_D/zz010_psa_httpd.conf"

	APACHE_CERT="$HTTPD_CONF_D/httpd.pem"
	APACHE_ROOT="/usr"

	min_suexec_UID=10000
	max_suexec_UID=16000
	min_suexec_GID=$min_suexec_UID
	max_suexec_GID=$max_suexec_UID

	suexec_storage=/usr/local/psa/suexec
	suexec=/usr/sbin/suexec
	suexec_dir=/usr/sbin
	suexec_file=suexec

	rpm_httpd_bin=/usr/sbin/httpd
}

set_apache_params_linux()
{
	apache_pid_file="$APACHE_ROOT/logs/httpd.pid"
	apache_lock_file="$APACHE_ROOT/logs/httpd.lock"
	product_lock_file="$HTTPD_CONF_D/cnf.lock"
	apache_service_name="httpd"

	apache_modules_d="/usr/lib/httpd/modules"
}

# mode: shell-script

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

module_exists()
{
	[ -n "$1" ] || return 1
	test -n "$2" && test -e "${apache_modules_d}/$2" && return
	test -e "${apache_modules_d}/mod_$1.so"
}

# Run before it
#        read_conf
#        # set_common_params
#        set_apache_params
add_apache_module()
{
	local module_name="$1"

	if ! module_exists $module_name; then
		p_echo "Shared object mod_${module_name}.so not found in ${apache_modules_d}...skipped."
		return
	fi

# On redhat/centos some modules has own configs: perl, python
		local config="${apache_httpd_conf}"
		if [ -e "$HTTPD_INCLUDE_D/$module_name.conf" ]; then
			config="$HTTPD_INCLUDE_D/$module_name.conf"
		fi
		cat $config | 			perl -e '
				@lines = <STDIN>;
				$found = 0;
				$lastline = 0;
				for ($i=0; $i<=$#lines; $i++)
				{
					if ( @lines[$i] =~ /^\s*?#\s*?LoadModule.*@ARGV[0]_module.*mod_@ARGV[0].so/ )
					{
						if ( $found > 0 || $deep > 0 )
						{
							@lines[$i] =~ s/^(.*)$/####This line was duplicated: $1/;
						}else{
							@lines[$i] =~ s/^\s*?#\s*?L/L/;
							$found++;
						}
					}
					elsif ( @lines[$i] =~ /^\s*?(LoadModule.*@ARGV[0]_module.*mod_@ARGV[0].so)/ )
					{
						if ( $found > 0 || $deep > 0 )
						{
							@lines[$i] =~ s/^(.*)$/####This line was duplicated: $1/;
						}else{
							$found++;
						}
					}
					elsif ( @lines[$i] =~ /^[^#\s]*?<If/ )
					{
						$deep++;
					}
					elsif ( @lines[$i] =~ /^[^#\s]*?<\/If/ )
					{
						$deep--;
					}
					if ( @lines[$i] =~ /LoadModule.*_module.*mod_.*so/  && $deep <= 0 )
					{
						$lastline = $i;
					}
				}
				if ( $found == 0 && $lastline > 0 )
				{
					print @lines[0..$lastline];
					print "LoadModule @ARGV[0]_module @ARGV[1]/mod_@ARGV[0].so\n";
					print @lines[$lastline+1..$#lines];
				}else{
					print @lines;
				}
			' "${module_name}" "${apache_modules_d}" 		> $config.new
		mv $config.new $config
}

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
}

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
	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 [ -x  "$SYSTEM_RC_D/$service" ]; then
		service_script="$SYSTEM_RC_D/$service"
	elif [ ! -z "${PRODUCT_RC_D}" -a -x "$PRODUCT_RC_D/$service" ]; then
		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"
	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 $@ >>$product_log 2>&1
			;;
		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 >> $product_log 2>&1

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

	return $ret
}

is_function()
{
	local type_output="`type -t \"$1\" 2>/dev/null`"
	case "$type_output" in
		*function)
			return 0
		;;
		*)
			return 1
		;;
	esac
}

# 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="$*"

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

	smart_undo_install

	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 "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()
{
	p_echo
	if [ $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 "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"
}

send_error_report()
{
	{
		echo $@
		echo ""
		if [ -n "$error_report_context" ]; then
			echo "Context: $error_report_context"
			echo ""
		fi
		test -t 0 || cat -
	} | env PATH=${PRODUCT_BOOTSTRAPPER_DIR}:$PRODUCT_ROOT_D/admin/sbin send-error-report "install" >/dev/null 2>&1
}

# vim:syntax=sh

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
}

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
}

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
}

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

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
}

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
}

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
}

#-*- vim:syntax=sh

register_service(){

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


# chkconfig for RedHat based
	/sbin/chkconfig --add "$1"
	/sbin/chkconfig "$1" on

	suc
}

#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
}

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
}

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

	setenforce "$SELINUX_ENFORCE"
}

#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/init.d
	PLESK_LIBEXEC_DIR="/usr/lib/plesk-9.0"
	PLESK_DB_DIR="/var/lib/plesk"
	POSTFIX_LIBEXEC_DIR="/usr/libexec/postfix"
	PRODUCT_BOOTSTRAPPER_DIR="/usr/local/psa/bootstrapper/pp10.12.0-bootstrapper"

	set_common_params_linux 

	detect_vz
}

set_common_params_linux()
{
	get_hostname="hostname -f"
	fstab="/etc/fstab"
	cp_preserve="cp --preserve=all --remove-destination"
	machine="linux"
	sendmail="/usr/sbin/sendmail"
	ps="ps axw"
	ps_long="ps axuw"
	false_shell="/bin/false"
	dummy_home="/"
	compress="gzip -9 -c"
	uncompress="gunzip -c"
	uudecode="uudecode -o /dev/stdout"
	ifconfig="/sbin/ifconfig -a"
	inet_str="inet addr"

	if [ -f /etc/slackware-version ]; then
	    linux_distr="slackware"
	    useradd_options=""
	    sndml_ini="/etc/rc.d/init.d/sendmail"
	    mail_local="/usr/libexec/mail.local"
	    dummy_shell=""
	    named_osrelease=0
	else
	    useradd_options="-M"
	    if [ -f /etc/mandrake-release ]; then
		linux_distr="mandrake"
	    elif [ -f /etc/fedora-release ]; then
		linux_distr="fedora"
	    elif [ -f /etc/SuSE-release ]; then
		linux_distr="suse"
		useradd_options="-r"
	    elif [ -f /etc/debian_version ]; then
		linux_distr="debian"
		get_domainname="dnsdomainname"
		useradd_options=""
	    else
		linux_distr="redhat"
	    fi

	    sndml_ini="/etc/init.d/sendmail"
	    mail_local="/usr/libexec/mail.local"
	    if [ -x /sbin/nologin ]; then
		dummy_shell="/sbin/nologin"
	    else
		dummy_shell="/bin/false"
	    fi
	    bash_shell="/bin/bash"
	    rbash_shell="/bin/rbash"
	    uudecode_full="/usr/bin/uudecode"
	    named_osrelease=`cat /proc/sys/kernel/osrelease | perl -F"/[.-]/" -n -a  -e 'printf "%02u%02u%02u\n", $F[0],$F[1],$F[2]'`
	fi

	return 0
}
## @@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
}

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
}

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

mysql_anydb()
{
	$mysql_client $mysql_user $mysql_passwd $mysql_args "$@" 2>>"$product_log"

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

mysql_start_linux_suse_ex()
{
	if [ -x "/sbin/service" ]; then
		action_cmd="/sbin/service mysql"
	else
		action_cmd="$SYSTEM_RC_D/$mysql_service"
	fi

	$action_cmd start >> $product_log 2>&1
}

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

	mysql_start_linux_suse_ex
	local 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
		mysql_start_linux_suse_ex
		rc="$?"
	fi

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

###	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 -TERM 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"

	if [ -f /proc/net/if_inet6 ]; then 
		FLAGS="flags                   = KEEPALIVE IPv6"
	else
		FLAGS="flags                   = KEEPALIVE"
	fi

	case "$superserver" in
	    inetd)
		poppassd_rec="poppassd stream tcp nowait/1000 root /usr/sbin/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
server                  = $PRODUCT_ROOT_D/admin/sbin/poppassd
}"
		;;
	    *)
		    die "Super server name unknown"
		;;
	esac

	super_server_action "$action" poppassd "$poppassd_rec"
}

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
}

## @@constructor set_qmail_params
qmail_super_server_config()
{
    local action="$1"
    local service="$2"
    qmail_xinetd_templates

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

qmail_xinetd_templates()
{
    local TRUE_BIN
    TRUE_BIN=$QMAIL_DIR/bin/true

    if [ -f /proc/net/if_inet6 ]; then
	    V6_FLAGS="flags		= IPv6"
    else
	    V6_FLAGS=""
    fi

smtp_rec="service smtp
{
	socket_type     = stream
	protocol        = tcp
	wait            = no
	disable		= no
	user            = root
	$V6_FLAGS
	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
	$V6_FLAGS
	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
	$V6_FLAGS
	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
	
}

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
}

# mode: shell-script

product_log=`mktemp /tmp/vps_optimized_webdav_fix.XXXXXX`
read_conf
set_common_params	
set_apache_params

fixed_already_flag="$PRODUCT_ROOT_D/var/.vps_optimized_webdav_fix.flag"

rc=0

# Init log file
echo "START LOGGING: `date`" > $product_log
echo "SCRIPT: $0 $@" >> $product_log
chmod 600 "$product_log"

if [ -f "$fixed_already_flag" ]; then
	pnnl_echo "Module dav_fs is already fixed"
	exit 0
fi


add_apache_module "dav_fs"

pnnl_echo "Restarting http server"
if ! pleskrc apache restart >>$product_log 2>&1; then
	pnnl_echo " ... FAILED"
	rc=1
else
	pnnl_echo " ... ok"
	touch "$fixed_already_flag"
	rc=0
fi

if [ "$rc" != "0" ]; then
	p_echo "Operation completed with errors"
	echo "Check execution log $product_log for details"
else
	p_echo "Operation completed successfully"
fi

exit $rc
