#! /bin/sh
# /etc/rc.d/init.d/capi reps. /etc/init.d/capi	-- CAPI device init script
#
# File Version:		2005.02.21
#
# Copyright (c) 2000-2004 Herbert U. Huebner 
#
#    Permission to use, copy, modify, and distribute this software/file
#    for any purpose with or without fee is hereby granted, provided that
#    the above copyright notice and this permission notice appear in all
#    copies.
#
#    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
#    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#    IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
#    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#    USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#    SUCH DAMAGE.
#
# See http://mungo.homelinux.org or http://www.friendglow.net
#
#
# Please, note:	CAPI init must start before network init (starts as 10) 
#		else the network ppp device setup will try to load the
#		ISDN HISAX drivers from the isdn4k-utils package instead.
#
#		Please sent any changes or additions to
# 		  Herbert U. Huebner 
#		I try to collect this stuff in order to get a unified
#		startup script ready for the community.
#		Bluetooth setup is already integrated in the next release,
#		it's left out here because the test cycle isn't finished
#               for use with kernel 2.6.x
#
# capi          Start/Stop the capi 2.0 daemon.
#
# chkconfig: 235 09 82
# description: CAPI is a UNIX program that starts the CAPI 2.0 interface \
#              for CAPI compatible devices, like AVM PCI and USB devices, \
#              certain Eicon DIVA cards, certain Siemens Gigaset devices, \
#	       certain Hagenuk external modems, etc..
# processname: capi
# config: /etc/capi.conf
# pidfile: /var/run/capicard.pid

# Check for missing programs
# The regular path is /sbin but other distributions might have it in /usr/sbin
test -x /sbin/capiinit -o -x /usr/sbin/capiinit || exit 5

# Source function library.
if [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
. /etc/init.d/functions
fi

RETVAL=0

# Try to work around hotplug/udev issues in kernel 2.6.x
# on several distributions
#
# This fixes the CAPI /dev/ entries that are wrong in 
# certain kernel 2.6.x based distributions.
#
# Someone introduced the devices capi20.?? as 
# character-major-191
# That is incorrect, char-major-191 is reserved for PCMCIA!
#
# In addition the naming scheme is partial incorrect.
# The device name for the first device is /dev/capi20. Some
# distributions like Fedora Core 3 use the name /dev/capi.
# The child devices are assigned to capi20.??
# - were ?? denotes the number.
# A maximum of 20 additional devices are defined in the kernel
# documentation. udev creates 31 with a wrong name.
# Special in the naming scheme is that child name behind the 
# period sign must constist of two digits and the first 10 
# devices - 0 to 9 - must have a leading 0.
#
# However, hotplug/udev assigns them to capi0 to capi31 which
# is wrong.

# This adds CAPI dev entries on installations that don't
# install them by default
createcapi()
{
# and to kernel 2.6 based installations. Now the program
# capiinit finds it's correct char-major-68 devices and in 
# case of udev ignores the incorrect entries.
#
# We split the process in two parts because of leading zeros
# Variables used:
# C	= device counter
# CE	= device name extension = capi20.CE
# CN	= device node number    = 68 CN
#
# This is the controlling device and isn't named .CE
# so we treat it extra.
# /dev/capi20       = mknod -m 660 /dev/capi20 c 68 0
if [ ! -c /dev/capi20 ] >/dev/null 2>&1; then
   mknod -m 660 /dev/capi20 c 68 0
   chown root.dialout /dev/capi20
fi

# all other devices   = mknod -m 660 /dev/capi20.?? c 68 ?
# with variable below = mknod -m 660 /dev/capi20.?? c 68 ?
#
# Don't mess around with the following because it needs special
# arithmetic expressions.
# I.e. computers start calculationg with 0, human beeings with 1
#      and bash doesn't like floating numbers out of the box.
#
C=0
CE=0
CC=20
CN=0
while [ $C -lt 20 ]; do
CE=`echo "scale=2; $CC+$C/100" | bc -l`
if [ ! -c /dev/capi$CE ] >/dev/null 2>&1; then
   let CN=$C+1
   mknod -m 660 /dev/capi$CE c 68 $CN
   chown root.dialout /dev/capi$CE
fi
C=`expr $C + 1`
done
}

# Because udev is slow it takes a while until it's devices show up.
# While we have created our devices with createcapi udev id behind
# and overwrites our /dev/capi20 major device.
# So we need to run it here gain AFTER our device ist initializes!
# Thats's why we give the system a little break for 5 seconds ;-)
capicreate()
{
# Old style
#if [ ! -c /dev/capi20 ] >/dev/null 2>&1; then
#   mknod -m 660 /dev/capi20 c 68 0
#fi

# The system takes a little break until udev has changed the assignment again ;-)
sleep 5s
if (ls -l /dev/capi20 | grep '191') >/dev/null 2>&1; then
   rm -f /dev/capi20
   mknod -m 660 /dev/capi20 c 68 0
   chown root.dialout /dev/capi20
fi

}


# See how we were called.
case "$1" in
  start)
	echo -n "Starting the CAPI 2.0 daemon: "
	if [ -f /dev/.udev.tdb ]; then
	   createcapi
	fi
	daemon capiinit start
	RETVAL=$?
	echo
	[ $RETVAL -eq 0 ] && touch /var/lock/subsys/capicard
	if [ -f /dev/.udev.tdb ]; then
	   capicreate
	fi
	;;
  stop)
	echo -n "Stopping the CAPI 2.0 daemon: "
	# udev on kernel 2.6 might have overwritten the original capi20 device
	# That's why we need to overwrite the udev entry again
	if [ -f /dev/.udev.tdb ]; then
	   createcapi
	fi
	daemon capiinit stop
	RETVAL=$?
	# udev in kernel 2.6 does not allow to remove the kernel module capifs!
	# Therefore, in case your CAPI card/adapter needs re-initialized you MUST
	# restart your computer.
	# Kernel 2.4 didn't have his problem. All kernel CAPI modules have been
	# removed with the appropriate rmmod command.
	echo
	[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/capicard
	;;
  status)
	daemon capiinit show
	# Just to make sure udev does not bite us.
	if [ -f /dev/.udev.tdb ]; then
	   createcapi
	fi
	RETVAL=$?
	;;
  restart)
  	$0 stop
	$0 start
	RETVAL=$?
	;;
  *)
	echo "Usage: capi {start|stop|show|restart}"
	exit 1
esac

exit $RETVAL


