#!/bin/bash -e
#
# /etc/init.d/alsa This shell script takes care of starting and stopping
#                  ALSA sound driver.
#
# This script requires /usr/sbin/alsactl program from alsa-utils package.
#
# Copyright (c) by Jaroslav Kysela <perex@jcu.cz> 
#
# Slightly modified for Debian GNU/Linux by Wichert Akkerman.
#                                           Masato Taruishi.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
# For RedHat 5.0+:
# chkconfig: 2345 87 14
# description: ALSA driver
#

if [ ! -f /usr/share/alsa-base/snd-dev-utils ]; then
  exit 0
fi

. /usr/share/alsa-base/snd-dev-utils

if [ -e /etc/alsa/alsa-base.conf ]; then
 . /etc/alsa/alsa-base.conf
fi

get_alsa_version

alsactl=""
get_alsactl

function start() {

  # insert all sound modules

    update_modutils_conf

  # Note: configuration actually lives in /etc/modutils/alsa,
  # however, since modprobe knows nothing about that, we use
  # /etc/modules.conf instead.
    found_driver="false"
    echo -n "Starting ALSA sound driver (version $alsa_version):"

  # First load the ALSA common driver and check whether devfs properly
  # can be available when the working kernel has devfs support.
    if ! /sbin/modprobe snd; then
      echo " failed."
      /sbin/modprobe -r snd
      exit 0
    fi
    if [ -f /dev/.devfsd ]; then
      if [ ! -e /dev/snd ]; then
        # you are using the kernel with devfs but disabling devfs.
        echo " no devfs available (even though using the kernel with devfs)."
        exit 0
      fi
    else 
      if [ -d /proc/asound/dev ] && [ ! -e /dev/snd ]; then
        # you are using the kernel without devfs so simply create
        # symlink
        ln -s /proc/asound/dev /dev/snd
      fi
    fi 
    /sbin/modprobe -r snd

    awk '/^((alias)|(probe)) +snd-card-[0-9]/ {print $3}' /etc/modules.conf | ( \
    while read line; do
      found_driver="found"
      desc=`echo $line | cut -d- -f2-`
      if /sbin/modprobe $line >/dev/null 2>&1; then
	echo -n " $desc"
	found_driver="detect"
      else
        echo -n " ($desc)"
      fi
    done
    case $found_driver in
      detect)
        echo "."
        ;;
      false)
        if [ $alsa_version = "none" ]; then
          echo " no driver installed."; exit 1
        else
          echo " no sound cards defined."; exit 1
        fi
        ;;
      found)
        echo
        exit 1
        ;;
    esac
  ) || exit 0
  #

  # Enabling sound devices for alsactl.
  get_sound_devs
  enable_sound_devs


  # restore driver settings
  #
  if [ -x "$alsactl" ]; then
    echo -n "Restoring ALSA mixer settings..."
    $alsactl restore >/dev/null 2>&1 || true
    echo "done."
  else
    echo "alsactl not found, mixer settings will not be restored."
  fi
}


function startoss() {
  [ "$startosslayer" = true ] &&
    for i in mixer pcm seq ; do /sbin/modprobe snd-${i}-oss >/dev/null 2>&1 ; done
}

function detect_stop() {
  #
  # remove all sound modules
  #
  clean=0
  modprobe -r snd-seq-oss
  modprobe -r snd-pcm-oss
  modprobe -r snd-mixer-oss
  /sbin/lsmod | grep -E "^snd" | ( while read line; do \
     /sbin/rmmod `echo $line | cut -d ' ' -f 1` >/dev/null 2>&1 || clean=1; \
  done
  # remove the 2.2 soundcore module (if possible)
  /sbin/rmmod soundcore >/dev/null 2>&1 || true
  if [ $clean = 1 ]; then
    exit 1
  fi
  )
  if [ $? = 1 ]; then
    return 1
  fi
}

function stop() {
  #
  # store driver settings
  #
  if [ -x "$alsactl" ]; then
    echo -n "Storing ALSA mixer settings..."
    $alsactl store >/dev/null 2>&1 || true
    sleep 1
    echo "done."
  else
    echo "alsactl not found."
  fi

  echo -n "Shutting down ALSA sound driver (version $alsa_version): "

  # Make sure that no devices are opened while
  # we are killing the procs that have devices open
  get_sound_devs
  get_sound_devs_proc
  disable_sound_devs
  #chmod 000 $sound_devs_proc  As of drivers 0.5.8a these permissions can't be changed

  if [ "$ALSA_KILL_MODE" = "force" ]; then
    kill_procs_using_sound_devs
  else
    get_procs_using_sound_devs
    if [ -n "$procs_using_sound_devs" ]; then
      echo "no. (sound is being used by pid $procs_using_sound_devs)"
      chmod 660 $sound_devs_dev
      exit 0
    fi
  fi
  #
  # remove all sound modules
  #
  detect_stop
  enable_sound_devs
  #chmod 600 $sound_devs_proc  As of drivers 0.5.8a these permissions can't be changed

  if [ ! -f /dev/.devfsd ] && [ -L /dev/snd ]; then
    rm -f /dev/snd
  fi

}

function detect_start() {
  #
  # run only detect module
  #
  /sbin/modprobe snd-detect >/dev/null 2>&1 || true
}

# Initialize some variables.

# See how we were called.
case "$1" in
  start)
        # Start driver.
	if [ ! -d /proc/asound ]; then
	  start && startoss
	else
	  if [ -f /proc/asound/detect ]; then
	    echo -n "Shutting down ALSA sound detect module (version $alsa_version): "
	    detect_stop
	    echo "done."
	    start && startoss
          else
	    echo "ALSA driver (version $alsa_version) is already running."
	  fi
	fi
        ;;
  stop)
        # Stop daemons.
	if [ -d /proc/asound ]; then
	  if [ -f /proc/asound/detect ]; then
	    detect_stop
	  else
	    if stop; then
              echo "done."
            else
              echo "failed."
            fi
	  fi
	else
	  echo "ALSA driver isn't running."
	fi
        ;;
  force-stop)
	ALSA_KILL_MODE="force" $0 stop
	;;
  restart)
	$0 stop && $0 start
	;;
  force-reload)
  	ALSA_KILL_MODE="force" $0 restart
	;;
  force-restart)
        ALSA_KILL_MODE="force" $0 stop
        $0 start
	;;
  *)
        echo "Usage: /etc/init.d/alsa {start|stop|restart|force-reload|force-stop|force-restart}"
        exit 1
esac

exit 0
