#!/sbin/runscript
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/dev-db/mysql-init-scripts/files/mysqlmanager.rc6,v 1.1 2007/01/12 16:54:20 chtekk Exp $

# external binaries used: which, sed, tac

depend() {
	use dns net localmount netmount nfsmount
	#provide mysql
}

# int in_list(char * elem, char * list)
function in_list() {
	local elem=${1:-"none"}
	local list=${2:-","}

	[[ "${list}" == "${list/,${elem},/}" ]] \
	&& return 1 \
	|| return 0
}

do_escape() {
	# Ihatethisreallyverymuch
	#echo "$1" | sed -e "s|'| |" -e "s|=|='|" -e "s|$|'|"
	echo "$1"
}

# int get_slot_config(srv_slot=0, srv_num)
get_slot_config() {
	[[ ${DEBUG} -ge 4 ]] && einfo ">>> get_slot_config(\"${1}\", \"${2}\")"

	srv_slot="${1:-"0"}"
	srv_num="${2}"
	MY_SUFFIX="-${srv_slot}"
	[[ "${MY_SUFFIX}" == '-0' ]] && MY_SUFFIX=''

	basedir="" pidfile="" socket=""

	local tmp_eval="mysqlmanager_slot_${srv_slot}${srv_num:+"_"}${srv_num}[@]"
	local conf_d_parameters="${!tmp_eval}"
	[[ ${conf_d_parameters[*]} == '()' ]] && conf_d_parameters=''

	MY_CNF="/etc/mysql${MY_SUFFIX}/my.cnf"
	# summa of unmanaged parameters
	# some parameters may be present multiple times
	unmanagedparams=""

	# grab the parameters from conf.d/mysql definition
	for my_default in ${conf_d_parameters[*]} ; do
		case "${my_default}" in
			mycnf=*) MY_CNF="${my_default#mycnf=}" ;;
			basedir=*) basedir="${my_default#basedir=}" ;;
			pid-file=*) pidfile="${my_default#pid-file=}" ;;
			socket=*) socket="${my_default#socket=}" ;;
			*=*)
				# list of parameters we already have
				# prepend "--" because my_print_defaults do it
				unmanagedparams="${unmanagedparams} --$( do_escape "${my_default}" )"
				;;
			*)
				unmanagedparams="${unmanagedparams} --${my_default}"
				;;
		esac
	done

	if [[ ! -r "${MY_CNF}" ]] ; then
		ewarn "Cannot access ${MY_CNF} !"
		MY_CNF=""
		my_defaults=""
	else
		local my_print_defaults="$(which my_print_defaults${MY_SUFFIX} 2>/dev/null)"
		if [[ ! -x "${my_print_defaults}" ]] ; then
			eerror "my_print_defaults NOT found or not executable"
			my_defaults=""
		else
			my_defaults=$( ${my_print_defaults} \
			--loose-verbose \
			--config-file="${MY_CNF}" \
			manager )
		fi
	fi

	# grab needed parameters from my.cnf, don't override the ones from
	# conf.d/mysql
	for my_default in ${my_defaults} ; do
		case "${my_default}" in
			--pid-file=*)
				[[ -z "${pidfile}" ]] && pidfile="${my_default#--pid-file=}" ;;
			--socket=*)
				[[ -z "${socket}" ]] && socket="${my_default#--socket=}" ;;
		esac
	done

	# still empty, I'm in doubt if assign a default or break, will see
	basedir="${basedir:-"/usr"}"
	pidfile="${pidfile:-"/var/run/mysqld/mysqlmanager${MY_SUFFIX}.pid"}"
	socket="${socket:-"/var/run/mysqld/mysqlmanager${MY_SUFFIX}.sock"}"

	if [[ ${DEBUG} -ge 3 ]] ; then
		einfo "basedir    => ${basedir}"
		einfo "pidfile    => ${pidfile}"
		einfo "socket     => ${socket}"
		einfo "Unamanged  => ${unmanagedparams}"
	fi

	# push these out to the script
	export MY_SUFFIX MY_CNF pidfile basedir socket
	export unmanagedparams
	[[ ${DEBUG} -ge 4 ]] && einfo "<<< get_slot_config() ok"
	return 0
}

start() {
	[[ ${DEBUG} -ge 4 ]] && einfo ">>> start()"
	MYSQL_GLOB_PID_FILE=${MYSQL_GLOB_PID_FILE:-"/var/run/svc-started-${SVCNAME}"}
	# servers are defined in /etc/conf.d/mysql
	local serverlist=${!mysqlmanager_slot_*}
	# provide default for empty conf.d/mysql
	if [[ -z "${serverlist}" ]] ; then
		serverlist=0
		export mysqlmanager_slot_0=()
	fi
	local retstatus timeout
	local globretstatus=1
	local srv_slot srv_num
	# server MUST NOT share same location for these
	local pidfilelist=',' socketlist=','

	# additional security
	rm -f "${MYSQL_GLOB_PID_FILE}" ; touch "${MYSQL_GLOB_PID_FILE}"
	if [[ $? -ne 0 ]] ; then
		eerror "cannot create MYSQL_GLOB_PID_FILE: ${MYSQL_GLOB_PID_FILE}"
		[[ ${DEBUG} -ge 4 ]] && einfo "<<< start() KO"
		return 1
	fi

	ebegin
	# try to start each server
	for srv in ${serverlist[*]} ; do
		einfo "working on ${srv}"

		srv_slot="${srv#mysqlmanager_slot_}"
		if [[ "${srv_slot}" == "${srv_slot#*_}" ]] ; then
			srv_num=''
		else
			srv_num="${srv_slot#*_}"
		fi
		srv_slot="${srv_slot%%_*}"

		retstatus=0
		get_slot_config "${srv_slot}" "${srv_num}" || retstatus=1

		# timeout (seconds) before declaring the startup failed

		# pre_run checks
		if [[ "$retstatus" -eq 0 ]] ; then
			if in_list "${pidfile}" "${pidfilelist}" ; then
				retstatus=3
				eerror "Sorry, won't start with same pid-file: ${pidfile}"
			fi
			if in_list "${socket}" "${socketlist}" ; then
				retstatus=5
				eerror "Sorry, won't start with same socket: ${socket}"
			fi
		fi

		if [[ $retstatus -eq 0 ]] ; then
			# additional security
			rm -f ${pidfile} ${socket}
			einfo "Starting mysqlmanager${MY_SUFFIX:+"_"}${srv_slot}${srv_num:+"_"}${srv_num} (${MY_CNF})"

			[[ ${DEBUG} -ge 2 ]] && echo "starting mysqlmanager with: "${basedir}/sbin/mysqlmanager${MY_SUFFIX} ${unmanagedparams} --pid-file=${pidfile} --socket=${socket}

			start-stop-daemon --quiet --start --background \
				--pidfile "${pidfile}" \
				--exec ${basedir}/sbin/mysqlmanager${MY_SUFFIX} \
				-- \
					${MY_CNF:+"--defaults-file="}${MY_CNF} \
					${unmanagedparams} \
					--pid-file=${pidfile} \
					--socket=${socket}

			retstatus=$?

			if [[ "${retstatus}" -eq 0 ]] ; then
				pidfilelist="${pidfilelist}${pidfile},"
				socketlist="${socketlist}${socket},"
				globretstatus=0
				echo "${srv_slot}${srv_num:+"_"}${srv_num}=${pidfile}" >> "${MYSQL_GLOB_PID_FILE}"
			fi
		fi
	done
	# successfull if at least one mysqlmanager started
	[[ ${DEBUG} -ge 4 ]] && einfo "<<< start()"
	eend $globretstatus
}

stop () {
	MYSQL_GLOB_PID_FILE=${MYSQL_GLOB_PID_FILE:-"/var/run/svc-started-${SVCNAME}"}
	local runwhat pidfile shutdown_elem
	local PID cnt timeout
	local retstatus=0
	local shutdown_list="$(< "${MYSQL_GLOB_PID_FILE}" )"

	# shutdown in reverse order
	ebegin
	for shutdown_elem in $shutdown_list; do
		runwhat=${shutdown_elem%%=*}
		pidfile=${shutdown_elem#*=}
		timeout=${STOPTIMEOUT:-"10"}

		einfo "Stopping mysqlmanager (${runwhat})"

		PID=$(cat "${pidfile}" 2>/dev/null)
		start-stop-daemon --stop --quiet --pidfile="${pidfile}"
		[[ ${DEBUG} -ge 1 ]] && echo ""
		while [[ -n "$PID" && $( kill -0 $PID 2>/dev/null ) && "${timeout}" -ge 1 ]] ; do
			timeout=$(($timeout - 1))
			[[ ${DEBUG} -ge 1 ]] && echo -n $(( $STOPTIMEOUT - $timeout ))
			sleep 1
		done
		if [[ "${timeout}" -lt 1 ]] ; then
			retstatus=$(( $retstatus + 1 ))
		fi
	done

	[[ "$retstatus" -eq 0 ]] && rm -f "$MYSQL_GLOB_PID_FILE"
	eend $retstatus
}
