#!/bin/sh
#
# ALSA initscript
#

set -e

PATH=/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin

if [ "$(id -u)" != "0" ] && [ "$1" != "--help" ] &&
   [ "$1" != "help" ] && [ ! -z "$1" ]; then
	echo "$0: To $1 ALSA, you must be root."
	exit 1
fi

# Default settings
alsactl_store_on_shutdown="always autosave"
runlevels_save='[2-5]'

[ -f /etc/default/alsa ] && . /etc/default/alsa

restore_mixer_settings()
{
	if msg="$(alsactl restore 2>&1)"; then
		return 0
	else
		echo "${0}: Error: alsactl restore failed with message '$msg'." >&2
		return 1
	fi
}

store_mixer_settings_if_allowed()
{
	if [ "$alsactl_store_on_shutdown" != "never autosave" ]; then
		if runlevel | grep -E "^$runlevels_save " > /dev/null 2>&1 \
		   || runlevel | grep -E " $runlevels_save\$" > /dev/null 2>&1
		then
			printf "Storing ALSA mixer settings..."
			if alsactl store > /dev/null 2>&1; then
				sleep 1
				echo "done."
				return 0
			else
				echo "failed."
				return 1
			fi
		fi
	fi
}

start()
{
	printf "Starting ALSA..."
	restore_mixer_settings || :
	echo "done."
	return 0
}

stop()
{
	store_mixer_settings_if_allowed || return 1
	return 0
}

force_stop()
{
	set_procs_using_sound() {
		procs_using_sound="$(lsof +D /dev -F rt | awk '/^p/ {pid=$1} /^t/ {type=$1} /^r0x(74|e)..$/ && type == "tCHR" {print pid}' | cut -c 2- | uniq)"
	}
	set_procs_using_sound
	if [ "$procs_using_sound" ] ; then
		printf "Terminating processes: "
		for attempt in 1 2 3 ; do
			printf "${procs_using_sound}..."
			kill $procs_using_sound || :
			sleep 1
			set_procs_using_sound
			[ "$procs_using_sound" ] || break
		done
		# Either no more procs using sound or attempts ran out
		if [ "$procs_using_sound" ] ; then
			printf "(with SIGKILL) ${procs_using_sound}..."
			kill -9 $procs_using_sound || :
			sleep 1
		fi
		set_procs_using_sound
		if [ "$procs_using_sound" ] ; then
			echo "failed."
			return 1
		fi
		echo "done."
	fi
	store_mixer_settings_if_allowed || :
	rmmod=""
	case "$(modprobe --version 2>&1)" in
		modprobe*) rmmod="rmmod -r" ;;
		module-init-tools*) rmmod="modprobe -r" ;;
	esac
	printf "Unloading sound driver modules..."
	for i in $(lsmod | awk '/^snd/ {print $1}'); do
		$rmmod $i >/dev/null 2>&1 || :
	done
	if [ "$(lsmod | awk '/^snd/ {print $1}')" ] ; then
		echo "failed."
		return 1
	else
		echo "done."
		return 0
	fi
}

case "$1" in
	start)
		start || exit $?
		;;
	stop)
		stop || exit $?
		;;
	restart|reload)
		stop || :
		start || exit $?
		;;
	force-stop)
		force_stop || exit $?
		;;
	force-restart|force-reload)
		force_stop || :
		start || exit $?
		;;
	*)
		echo "Usage: /etc/init.d/alsa {start|stop|restart|reload|force-stop|force-restart|force-reload}" >&2
		exit 3
		;;
esac
