#!/bin/sh

set -e

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

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

# Populate some defaults in case /etc/default/alsa goes for a wander.
startosslayer="false"
force_stop_modules_before_suspend="false"
alsactl_store_on_shutdown="true"

[ -e /etc/default/alsa ] && . /etc/default/alsa
# $ALSA_KILL_OVERRIDE is only for use by this script, please don't set it
# yourself in /etc/default/alsa :)
if [ "$ALSA_KILL_OVERRIDE" = "force" ]; then
    export ALSA_KILL_OVERRIDE
    ALSA_KILL_MODE=force
elif [ ! -z "$ALSA_KILL_OVERRIDE" ]; then
    export ALSA_KILL_OVERRIDE
    ALSA_KILL_MODE=none
fi

case "$1" in
    start)
	if [ -f /proc/asound/version ]; then
	    alsa_version="$(head -1 /proc/asound/version | cut -f7 -d" " | sed 's/\(.*\)\.$/\1/')"
	elif modprobe snd > /dev/null 2>&1; then
	    if [ -f /proc/asound/version ]; then
		alsa_version="$(head -1 /proc/asound/version | cut -f7 -d" " | sed 's/\(.*\)\.$/\1/')"
	    else
		echo "Starting ALSA (unknown version): failed - internal error 1"
		exit 1
	    fi
	else
	    echo "Starting ALSA (unknown version): failed - ALSA modules not installed"
	    exit 1
	fi

	printf "Starting ALSA (version %s):" "$alsa_version"

	module_list="$(grep -E "^[[:space:]]*(alias|probe)[[:space:]]+snd-card-[0-9]+" \
		       /etc/modules.conf | sort -u | awk '{print $3}')"
	cards_exist=false
	if [ -z "$module_list" ]; then
	    if [ -d /proc/asound/card0 ]; then
		printf " ALSA appears to be compiled statically"
		cards_exist=true
	    else
		printf " warning, no drivers defined in /etc/modules.conf"
	    fi
	else
	    for module in $module_list; do
		module_name="${module#*-}"
		if modprobe "$module" > /dev/null 2>&1; then
		    printf " %s" "$module_name"
		    cards_exist=true
		else
		    printf " %s-failed" "$module_name"
		fi
	    done
	fi
	if [ "$cards_exist" = "true" ]; then
	    echo "."
	else
	    echo " failed"
	    exit 1
	fi
	
	if [ ! -L /dev/sndstat ]; then
	    rm -f /dev/sndstat && ln -s /proc/asound/oss/sndstat /dev/sndstat
	fi

	if [ "$startosslayer" = "true" ]; then
	    for module in mixer pcm seq; do
		modprobe "snd-${module}-oss" > /dev/null 2>&1 || true
	    done
	fi

	if [ "$alsactl_store_on_shutdown" = "true" ]; then
	    printf "Restoring ALSA mixer settings ... "
	    if alsactl restore > /dev/null 2>&1; then
		echo "done."
	    else
		echo "failed"
		exit 1
	    fi
	fi
	;;
    stop)
	if [ -d /proc/asound ]; then
	    if [ "$alsactl_store_on_shutdown" = "true" ]; then
		printf "Storing ALSA mixer settings ... "
		if alsactl store > /dev/null 2>&1; then
		    sleep 1
		    echo "done."
		else
		    echo "failed"
		fi
	    fi

	    if [ -f /proc/asound/version ]; then
		alsa_version="$(head -1 /proc/asound/version | cut -f7 -d" " | sed 's/\(.*\)\.$/\1/')"
	    else
		echo "Shutting down ALSA (unknown version): failed - internal error 3"
		exit 1
	    fi

	    printf "Shutting down ALSA (version %s): " "$alsa_version"
	    procs_using_sound="$(echo $({ find /dev -print0 | xargs -0 stat -Lc '%t:%n' | grep -E '^(e|74):' | cut -d: -f2-; } | while read REPLY; do fuser "$REPLY" || true; done | cut -f2- -d:))"
	    if [ ! -z "$procs_using_sound" ]; then
		if [ "$ALSA_KILL_MODE" = force ]; then
		    printf "(terminating processes) "
		    kill $procs_using_sound
		    sleep 2
		    kill -9 $procs_using_sound
		else
		    printf "aborting. (sound used by PIDs %s)\n" "$procs_using_sound"
		    exit 1
		fi
	    fi

	    rmmod -r $(lsmod | grep ^snd | awk '{print $1}')
	    echo "done."
	else
	    echo "Shutting down ALSA (unknown version): not running"
	fi
	;;
    restart|reload)
	$0 stop && $0 start
	;;
    force-*)
	ALSA_KILL_OVERRIDE="force" $0 "${1#*-}"
	;;
    *)
	echo "Usage: /etc/init.d/alsa {start|stop|restart|reload|force-stop|force-restart|force-reload}"
	exit 1
	;;
esac
