#! /bin/sh
#
# Installation of CAPI4Linux drivers & tools, v200209030824
# (PCI/PnP/ISA/PCMCIA/USB, ISDN/DSL)

# INIT: Common definitions
ESC=`echo -en "\033"`
RED="${ESC}[1;31m"
NORM=`echo -en "${ESC}[m\017"`
TGZVER=2.4.18-4GB
INITDIR=/etc/init.d
LIBMOD=/lib/modules/`uname -r`
DOCDIR=/usr/share/doc
SBINDIR=/usr/sbin
FWDIR=/usr/lib/isdn
EPDIR=/etc/pcmcia
MODDIR=$LIBMOD/misc
PCMCIADIR=$LIBMOD/pcmcia-external
ICONFIG=/etc/sysconfig/isdn
HPCONFIG=/etc/sysconfig/hotplug
PCCONFIG=/etc/sysconfig/pcmcia
LOGFILE=install.log

# INIT: Define some return codes for this script
no_error=0		# Documentation follows... ;-)
err_options=1		# Error in option
err_kver=2		# Invalid kernel version
err_root=3		# User "root" is required
err_pppd=4		# pppd has not been installed
err_pver=5		# Invalid pppd version
err_ctrl=6		# Too many controllers
err_make=7		# Error caused by make
err_init=8		# Error in initialize()
err_type=9		# Invalid value in $type 
err_remove=10		# Could not find files to be removed
err_verify=11		# Verification found problems
err_ctrlchk=12		# Double/parallel installation check
err_stop=13		# Error while stopping CAPI
err_usb=14		# Error while analyzing USB bus
err_nyi=15		# Not yet implemented

# INIT: Scan command line, map known stuff to corresponding variables
opt_check_kernel=1
opt_check_pppd=1
opt_compile=0
opt_identify=0
opt_update=0
opt_remove=0
opt_verify=0
opt_do_rpm=1
opt_debug=0
opt_string=""
opt_count=0
opt_ok=0

# INIT: Include card specific stuff
. ./install.card
kern=`uname -r`
cardname=`head -n 1 install.card | cut -b 3-`
name="${card#x}"
if [ "$name" != "$card" ]; then
	prefix=fx
else
	prefix=fc
fi
if echo $card | grep "usb" > /dev/null; then
	USB=1
else
	USB=0
fi
if echo $card | grep "pcmcia" > /dev/null; then
	PCMCIA=1
else
	PCMCIA=0
fi

# INIT: Parsing the command line
while [ "$1" != "" ]; do
	opt_ok=1
	case $1 in
	
	-c)	# Compile driver prior to its installation. For use 
		# with option -k... (Problem: New kernel for an al-
		# ready installed SuSE)
		opt_compile=1
		;;
	-d)	# Debug mode: Copy log messages also to console
		opt_debug=1
		;;
	-i)	# Identify: Just print the name of the controller
		# this archive belongs to.
		opt_identify=1
		;;
	-k)	# Disable check for correct kernel version. WARNING! 
		# Binary modules copied into the filesystem may not 
		# work with your kernel!
		opt_check_kernel=0
		;;
	-m)	# Do not unpack the rpm packages. The rpm packages
		# contain pre-compiled kernel modules so that this
		# option may be useful with -k and -c...
		opt_do_rpm=0
		;;
	-p)	# Disable check for pppd version. 
		opt_check_pppd=0
		;;
	-r)	# Remove the driver. Note: Target of this removal
		# is removing everything that may cause conflicts
		# with a subsequent new installation or may be 
		# invoked on the next reboot. After "install -r",
		# there are definitely things left but they should
		# not cause problems. (e.g. CAPI tools&libraries 
		# will remain...)
		opt_remove=1
		;;
	-u)	# Update the driver, do not repeat full installation
		# procedure. Note: This only copies the driver and
		# the RPM packages, no changes to the boot infra-
		# structure will be made.
		opt_update=1
		;;
	-v)	# Verify the installation. Note: This can probably
		# never check everything that may cause problems.
		# However, some vital elements for the correct
		# operation of the driver can be checked, some of
		# the (partly well known) problems can automagically
		# be detected...
		opt_verify=1
		;;
	*)	# Reserved for future use. :-)
		opt_ok=0
		;;
	esac
	if [ $opt_ok -eq 1 ]; then
		opt_string="$opt_string $1"
		opt_count=`expr $opt_count + 1`
	fi
	shift
done
if [ $opt_remove -eq 1 -a $opt_update -eq 1 ]; then
	echo "Error in options, -r and -u???"
	exit $err_options
fi
if [ $opt_remove -eq 1 -a $opt_compile -eq 1 ]; then
	echo "Error in options, -r and -c???"
	exit $err_options
fi
if [ $opt_remove -eq 1 -a $opt_verify -eq 1 ]; then
	echo "Error in options, -r and -v???"
	exit $err_options
fi

# TASK: Execute "-i" option
if [ $opt_identify -eq 1 ]; then
	echo "This is the install package for the $cardname driver."
	if [ $opt_count -lt 2 ]; then
		exit 0;
	fi
fi
	
# INIT: Include hotplug configuration
if test -f $HPCONFIG; then
	. $HPCONFIG
fi

# INIT: Define logger functions, start log file

echo1() {
	# Normal log message. Copy to console in debug mode...
	echo -e "$1" >> $LOGFILE
	if [ $opt_debug -eq 1 ]; then
		echo -e "$1"
	fi
}

echo2() {
	# Normal message, written to log and console
	echo -n "console: " >> $LOGFILE
	echo -e "$1" | tee -a $LOGFILE
}

echo3() {
	# Warning message, written to log and console (in red)
	echo "warning: $1" >> $LOGFILE
	echo -e "\a${RED}$1${NORM}"
}

line=`ls insta* | tr " a-z_.\n" [-*]`
echo1 "$line\n* Installation log (`date`):" 
echo1 "Kernel: $kern"
echo1 "Card: $prefix$name"
cat release.txt >> $LOGFILE
echo1 "Accepted options: $opt_string"

# TEST: Kernel version
if [ $opt_check_kernel -eq 1 ]; then
	if [ "$kern" != "$TGZVER" ]; then
		echo2 "Invalid kernel version... found $kern, expected: $TGZVER."
		exit $err_kver
	fi
else
	echo1 "Tgzver: $TGZVER"
fi

# INIT: Find archives...
LIBVER=`ls c4l-lib-* | cut -b9-18`
SYSVER=`ls c4l-sys-* | cut -b9-18`
echo1 "Libver: $LIBVER"
echo1 "Sysver: $SYSVER"
echo1 "Files:"
ls -laR | grep -E -e "\..*:" -e "c4l-.*" -e "instal.*" -e "$prefix.*" >> $LOGFILE 2>> $LOGFILE

# TEST: sanity check
if [ "$type" == "" ]; then
	echo3 "Oops! Archive type missing."
	exit $err_type
fi

# TEST: Am I root?
user=`id -u`
if [ "$user" != "0" ]; then
	echo2 "./install must be started by \"root\"."
	exit $err_root
fi

# TEST: Does pppd exist?
which pppd > /dev/null
if [ 0 -ne $? ]; then
	echo2 "pppd has not been installed!"
	exit $err_pppd
fi

# TEST: Check pppd's version
pppd --version 2> tmp
cat tmp >> $LOGFILE
if [ $opt_check_pppd -eq 1 ]; then
	pver=`cat tmp | cut -d" " -f3`
	if [ "$pver" != "2.4.1" ]; then
		echo2 "This installer has only been tested for pppd 2.4.1!"
		exit $err_pver
	fi
fi
rm tmp

# TEST: Does /dev/capi exist?
if ! test -d /dev/capi; then
	mkdir /dev/capi
fi

# Just to separate the preparatory steps above from the rest of the file... :-)

forall() {
	# Arguments:	$1 ........ Name of a script to be applied to all drivers
	#		$2 ........ Path, added in front of the names...
	#
	local name
	for name in fcclassic fcpci fcpnp fcdsl fcpcmcia fcusb fcusb2 fxusb; do
		$1 $name $2
	done
}

uninstall() {
	# Arguments:	$1 ........ Name of object file to be removed
	#		$2 ........ Path to object file to be removed
	#
	if test -f $2/$1.o; then
		rm -v $2/$1.o >> $LOGFILE
	fi
}

find_module() {
	# Arguments:	$1 ........ Name of object file to be found
	#
	local rs=`find /lib/modules -name $1.o -print`
	local rc=0
	if ! test -z "$res"; then
		echo1 "* Found $res"
		rc=1
	fi
	return $rc
}

add_unload() {
	# Arguments:	$1 ........ Name of USB module being installed
	#
	local ULDVAR=HOTPLUG_USB_MODULES_TO_UNLOAD
	if ! echo $HOTPLUG_USB_MODULES_TO_UNLOAD | grep "$1 " > /dev/null; then
		echo1 "* Enabling 'removal on unplug'"
		if ! test -f $HPCONFIG.old; then
			echo1 "Saving $HPCONFIG"
			cp -vf $HPCONFIG $HPCONFIG.old | tee -a $LOGFILE
		fi
		local HMTU="$1 $HOTPLUG_USB_MODULES_TO_UNLOAD"
		echo1 "Modifying $HPCONFIG for $ULDVAR"
		cat $HPCONFIG | sed "s/$ULDVAR.*/$ULDVAR=\"$HMTU\"/" > tmp
		cp -f tmp $HPCONFIG
		echo1 "* Value of $ULDVAR:"
		echo1 "Current: \"$HOTPLUG_USB_MODULES_TO_UNLOAD\""
		echo1 "Updated: \"$HMTU\""
		rm tmp
	fi 
}

del_unload() {
	# Arguments:	$1 ........ Name of USB module being uninstalled
	#
	local ULDVAR=HOTPLUG_USB_MODULES_TO_UNLOAD
	if echo $HOTPLUG_USB_MODULES_TO_UNLOAD | grep "$1 " > /dev/null; then
		local HMTU=""
		echo1 "* Disabling 'removal on unplug'"
		for drv in $HOTPLUG_USB_MODULES_TO_UNLOAD; do
			if [ "$drv" != "$1" ]; then
				HMTU="$drv $HMTU"
			fi
		done
		echo1 "Modifying $HPCONFIG for $ULDVAR"
		cat $HPCONFIG | sed "s/$ULDVAR.*/$ULDVAR=\"$HMTU\"/" > tmp
		rm -f $HPCONFIG
		cp -f tmp $HPCONFIG
		echo1 "* Value of $ULDVAR:"
		echo1 "Current: \"$HOTPLUG_USB_MODULES_TO_UNLOAD\""
		echo1 "Updated: \"$HMTU\""
	fi 
}

i4l_modules() {
	#
	local i4l=1
	for mod in isdn capidrv hisax slhc; do
		if lsmod | grep "^$mod " > /dev/null 2>&1; then
			echo1 "* Module $mod is running"
			i4l=0
		fi
	done
	return $i4l
}

capi_start() {
	#
	echo2 "Starting CAPI..."
	local log0=`wc -l < /var/log/messages`
	$SBINDIR/capiinit start 2> /dev/null
	local log1=`wc -l < /var/log/messages`
	tail -n `expr $log1 - $log0` /var/log/messages >> $LOGFILE
}	

capi_appllist() {
	# Arguments:	$1 ........ capidrv detect flag
	#
	local lapp=`lsof | grep /dev/capi | grep -v fcdsl_thr | awk '{ print $1 }' | uniq`
	echo -e -n "List of registered applications:\n$lapp" | tee -a $LOGFILE
	if [ $1 -ne 0 ]; then
		echo "capidrv.o (I4L kernel module)" | tee -a $LOGFILE
	else
		echo "" | tee -a $LOGFILE
	fi
}

capi_stopable() {
	# Arguments:	$1 ........ Number of applications (proc/capi/applications)
	# 		$2 ........ Number of USB controllers
	#		$3 ........ Number of PCMCIA controllers
	#
	# Uses:		$capidrv .. capidrv detect flag
	#
	if [ $1 -ne 0 ]; then
		echo3 "There is/are $1 CAPI application(s) registered."
		capi_appllist $capidrv
		echo2 "Please stop all applications and restart the installer..."
		echo ""
		return 1
	fi
	if [ $2 -ne 0 -o $3 -ne 0 ]; then
		echo3 "There are USB or PCMCIA controllers running."
		echo2 "Please remove the controller in order to enable the"
		echo2 "installer to stop CAPI, then restart the installation..."
		echo ""
		return 2
	fi
	if ! test -f /etc/capi.conf; then
		echo3 "CAPI has been started without capiinit!"
		echo2 "Please manually stop CAPI and restart the installer."
		echo ""
		return 3
	fi
}

capi_stop() {
	#
	if test -f /etc/capi.conf; then
		echo2 "Stopping CAPI..."
		local log0=`wc -l < /var/log/messages`
		if [ $USB -eq 1 ]; then
			# Module is not in /etc/capi.conf!
			rmmod $prefix$name > /dev/null 2>&1
		fi
		$SBINDIR/capiinit stop 2> /dev/null
		local log1=`wc -l < /var/log/messages`
		tail -n `expr $log1 - $log0` /var/log/messages >> $LOGFILE
	else
		echo1 "Could not stop CAPI: /etc/capi.conf missing..."
	fi
}

notify () {
	# Arguments: 	$1 ........ error code (< 0: internal use only)
	#		$2 ........ error message
	#
	if ! test -z "$2"; then
		echo2 "$2"
	fi
	error=$1
	if test -z "$error_list"; then
		error_list=$1
	else
		error_list="$error_list $1"
	fi
}

check_rpm() {
	# Arguments:	$1 ........ context of invocation (0: Cleaning, 1: Setup, 2: Check)
	#
	local RPMVER=""
	local CURVER=""
	for rpm in `rpm -qa | grep c4l- > /dev/null 2>&1`; do
		RPMVER=`echo $rpm | cut -b9-18`
		if echo $rpm | grep c4l-lib > /dev/null 2>&1; then
			CURVER=$LIBVER
		else
			CURVER=$SYSVER
		fi
		if [ "$CURVER" != "$RPMVER" ]; then
			if [ $1 -eq 2 ]; then
				echo1 "Check: $rpm"
			else
				rpm -e $rpm >> $LOGFILE 2>&1
				echo1 "Removed: $rpm"
			fi
		else
			echo1 "Found: $rpm"
		fi
	done	
}
	
check_usb_bus () {
	# Arguments:	$1 ........ 1st USB product id for this driver package
	#		$2 ........ 2nd USB product id ... etc.
	#
	local numdev=0
	local my_dev=0
	local ix=0
	local max=0
	local arg

	while ! test -z "$1"; do
		arg[$ix]=$1
		shift
		ix=`expr $ix + 1`
	done
	max=$ix
	cat /proc/bus/usb/devices | grep ^P: | tr = " " | awk '{ print $3,$5 }' > tmp.cub
	while read vendor product; do
		if [ "$vendor" == "057c" ]; then
			numdev=`expr $numdev + 1`
			ix=0
			while [ $ix -lt $max ]; do
				if [ "$product" == "${arg[$ix]}" ]; then
					my_dev=1
				fi
				ix=`expr $ix + 1`
			done
		fi
	done < tmp.cub
	rm tmp.cub
	if [ $numdev -gt 1 ]; then
		return 2
	fi
	if [ $numdev -eq 1 -a $my_dev -eq 0 ]; then
		return 1
	fi
}

# TEST: Is CAPI running?
query_ecc=1
if ! test -f /proc/capi/controller; then
	ncards=0
	ucards=0
	pcards=0
	nappls=0
	echo1 "* CAPI not active"
else
        cat /proc/capi/controller | awk '{ print $2 }' | uniq > tmp
        ncards=`cat tmp | wc -l | awk '{ print $1 }'`
	ucards=`cat tmp | grep usb | wc -l | awk '{ print $1 }'`
	pcards=`cat tmp | grep pcmcia | wc -l | awk '{ print $1 }'`
	nappls=`cat /proc/capi/applications | wc -l | awk '{ print $1 }'`
	
	# TEST: CAPI running, no controllers attached
	if [ $ncards -eq 0 ]; then
		echo1 "* CAPI active (no controllers)"
		rm tmp
		ncards=-1
	else
		query_ecc=0
		echo1 "* CAPI active (total $ncards/usb $ucards/pcmcia $pcards)"
	fi
fi

# TEST: Set capidrv flag (application w/o name)
if lsmod | grep "^capidrv " > /dev/null 2>&1; then
	capidrv=1
else
	capidrv=0
fi

# TEST: In case of no running controllers...
if [ $query_ecc -eq 1 ]; then
	if test -f /etc/capi.conf; then
		if ! cat /etc/capi.conf | grep "^[a-f].*" > tmp0 2> /dev/null; then
			cat $LIBMOD/modules.usbmap | awk '{ print $1,$3 }' | grep "^f[cx]usb[2] 0x057c" > tmp0 2> /dev/null
		fi
		cat tmp0 | awk '{ print $1 }' | uniq > tmp
		rm -f tmp0
	fi
fi

# INIT: Get list of installed C4L controllers
if test -s tmp; then
	fclist=`cat tmp`
	rm tmp
else
	fclist=""
fi

# TEST: Anybody out there? 
if [ $opt_verify -eq 0 -a $opt_remove -eq 0 ]; then
	if ! test -z "$fclist"; then
		self=0
		other=0
		oclist=" "
		for c in $fclist; do
			if [ "$c" == "$prefix$name" ]; then
				self=1
			else
				other=1
				oclist="$oclist$c "
			fi
		done
		if [ "$card" != "dsl" ]; then
			if [ $other -eq 1 ]; then
				echo3 "Cannot install more than one CAPI controller!"
				echo2 "Please deinstall:$oclist"
				exit $err_ctrlchk
			fi
		fi
		if [ $opt_update -eq 0 ]; then
			if [ $self -eq 1 ]; then
				echo3 "The controller has already been installed!"
				exit $err_ctrlchk
			fi
		fi
	fi
fi

# TASK: Verification of an installed driver
if [ $opt_verify -eq 1 ]; then
	error=0
	error_list=""
	echo2 "Verifying $cardname installation..."
	if test -f /etc/SuSE-release; then
		cat /etc/SuSE-release >> $LOGFILE
	fi
	echo1 "* CAPI device"
	ls -la /dev/capi* >> $LOGFILE 2>&1
	echo1 "* CAPI filesystem"
	mount | grep capifs >> $LOGFILE 2> /dev/null
	if [ $ncards -gt 0 ]; then
		echo2 "Found $ncards CAPI controller(s)."
		if [ $nappls -ne 0 ]; then
			echo2 "Found $nappls CAPI application(s) registered."
			capi_appllist $capidrv
		fi
	fi
	echo1 "* Checking RPM packages..."
	check_rpm 2
	if ! rpm --verify c4l-sys-$SYSVER >> $LOGFILE; then
		notify 1 "CAPI driver rpm check failed."
	fi
	if ! rpm --verify c4l-lib-$LIBVER >> $LOGFILE; then
		notify 2 "CAPI tools&library rpm check failed."
	fi
	# Error code 3: /etc/init.d/capi4linux boot script missing...
	if ! test -f /etc/capi.conf; then
		notify 4 "/etc/capi.conf missing!"
	else
		echo1 "\n* /etc/capi.conf"
		if ! cat /etc/capi.conf | tee -a $LOGFILE | grep $prefix$name > /dev/null 2>&1; then
			notify 5 "Invalid /etc/capi.conf: $prefix$name entry missing!"
		fi
	fi	
	if test -f $ICONFIG/cfg-contr0; then
		notify 6 "YaST may have been invoked after the CAPI4Linux installation."
	fi
	if ! test -z "$loadfile1"; then
		if ! test -f $FWDIR/$loadfile1; then
			notify 7 "Firmware file $FWDIR/$loadfile1 missing."
		fi
		if ! test -z "$loadfile2"; then
			if ! test -f $FWDIR/$loadfile2; then
				notify 7 "Firmware file $FWDIR/$loadfile2 missing."
			fi
		fi
	fi
	i4l_modules
	forall find_module ""
	if ! test -f $MODDIR/$prefix$name.o; then
		notify 8 "Driver $MODDIR/$prefix$name.o missing."
	fi
	if ! check_card; then
		notify 9 ""
	fi
	
	echo1 "\n* Loaded modules"
	lsmod >> $LOGFILE
	echo1 "\n* /proc/cpuinfo"
	cat /proc/cpuinfo >> $LOGFILE

	case $type in
	
	1)	# Internal controllers (PCI, ISA, PnP)
		echo1 "* /proc/interrupts"
		cat /proc/interrupts >> $LOGFILE 2> /dev/null
		echo1 "\n* /proc/ioports"
		cat /proc/ioports >> $LOGFILE 2> /dev/null
		echo1 ""
		if ! test -f $INITDIR/capi4linux; then
			notify 10 "Boot script $INITDIR/capi4linux missing."
		fi
		;;
	2)	# PCMCIA controllers
		if ! rpm -qa | grep pcmcia-3.1.31 > /dev/null 2>&1; then
			notify 10 "External PCMCIA package not installed."
		fi
		;;
	3)	# USB controllers
		if ! test -f $INITDIR/capi4linux; then
			notify 10 "Boot script $INITDIR/capi4linux missing."
		fi
		check_usb_bus $pid1 $pid2
		case $? in
			0)	# nop
				;;
			1)	notify 10 "Driver/controller mismatch."
				;;
			2)	notify 10 "Too many USB controllers."
				;;
		esac
		;;
	*)	# Reserved for future use
		echo2 "Unknown archive type."
		;;
	esac
	if [ $error -ne 0 ]; then
		echo3 "The installation may have a problem... [$error_list]"
	fi
	echo2 "Verification completed."
	echo2 "(Please also read $LOGFILE for more information!)"
	exit $err_verify
fi

# TASK: Stop CAPI for installation or removal
if [ $ncards -ne 0 ]; then
	if ! capi_stopable $nappls $ucards $pcards; then
		# Message produced by capi_stopable()
		exit $err_stop
	fi
	capi_stop 
	if lsmod | grep capi > /dev/null 2>&1; then
		# Should not happen: capiinit stop failed...
		echo3 "Could not stop CAPI, please reboot after installation!"
	fi
fi
		
# TASK: Remove an installed driver
if [ $opt_remove -eq 1 ]; then
	echo2 "Removing driver for $cardname..."
	ok=1
	kill_ecc=1
	if test -f /etc/capi.conf; then
		if ! cat /etc/capi.conf | grep $prefix$name > /dev/null 2>&1; then
			echo2 "Inavlid controller."
			exit $err_remove
		fi
	else
		echo2 "/etc/capi.conf already removed, $prefix$name installation assumed..."
	fi	
	if ! test -f $INITDIR/capi4linux; then
		echo2 "$INITDIR/capi4linux missing."
		exit $err_remove
	fi
	insserv -r $INITDIR/capi4linux
	rm -vf $INITDIR/capi4linux >> $LOGFILE
	case $type in
		1)	# Internal controller
			if [ "$name" == "dsl" ]; then
				kill_ecc=0
			fi
			;;
		2)	# PCMCIA controller
			;;
		3)	# USB controller
			;;
		*)	# Reserved for future use
			echo2 "Unknown archive type."
			ok=0
			;;
	esac
	if [ $ok -eq 1 ]; then
		if test -f /etc/capi.conf; then
			if [ $kill_ecc -eq 1 ]; then
				rm -fv /etc/capi.conf >> $LOGFILE
			else
				cat /etc/capi.conf | sed "s/^$prefix$name.*/# removed/" > tmp
				rm -f /etc/capi.conf
				mv -v tmp /etc/capi.conf >> $LOGFILE
			fi
		fi
		if ! test -f $MODDIR/$prefix$name.o; then
			echo2 "Driver $prefix$name.o already removed."
		else
			rm -fv $MODDIR/$prefix$name.o >> $LOGFILE
		fi
		echo1 "* Installed RPM packages:"
		if ! rpm -qa | grep "c4l-" >> $LOGFILE 2>&1; then
			echo2 "CAPI tools/libraries already removed."
		else
			check_rpm 0
		fi
		if test -f $ICONFIG/saved.cfg-contr0; then
			mv -vf $ICONFIG/saved.cfg-contr0 $ICONFIG/cfg-contr0 >> $LOGFILE
		fi
		if test -d $DOCDIR/CAPI4Linux; then
			rm -rf $DOCDIR/CAPI4Linux >> $LOGFILE
		fi
		remove_card
		echo1 "* Running depmod -a:"
		depmod -a >> $LOGFILE 2>&1
	fi
	echo2 "Remove completed."
	exit 0
fi

# TEST: Install on running i4l?
if i4l_modules; then
	if [ $opt_update -eq 0 ]; then
		echo2 "Stopping I4L..."
		rcisdn stop > /dev/null 2>&1
	fi
fi

# INIT: Request for compilation
if [ $opt_compile -eq 1 ]; then
	echo2 "Generating driver..."
	make drv
	if ! test -f src.drv/$prefix$name.o; then
		echo2 "Oops, could not generate driver module!"
		exit $err_make
	fi
	cp -vf src.drv/$prefix$name.o . >> $LOGFILE
fi

# INIT: Call card-specific initializer...
initialize $opt_update
if [ $? -ne 0 ]; then
	echo2 "Card-specific pre-install failed."
	exit $err_init
fi

if [ $opt_update -eq 0 ]; then
	echo2 "Installing driver for $cardname..."

	# TEST: Look for configured i4l controllers...
	nctrl=`ls $ICONFIG/cfg-contr[0-9] 2> /dev/null | wc -l | awk '{ print $1 }'`
	if [ $nctrl -ne 0 ]; then
		# There are controllers configured by YaST
		if [ $nctrl -ne 1 ]; then
			# There is more than one controller!
			echo2 "You can at most run one passive controller!"
			exit $err_ctrl
		fi
		echo2 "Deactivating I4L..."
		echo1 "* Renaming cfg-contr0 to saved.cfg-contr0"
		(cd $ICONFIG; mv cfg-contr0 saved.cfg-contr0)
	fi

	# INIT: Install a new service in the SuSE boot procedure for runlevels
	# 2, 3 and 5.
	cp -vf capi4linux $INITDIR/capi4linux >> $LOGFILE
	insserv -d capi4linux
	(cd $INITDIR; ls -laR | grep capi4linux) >> $LOGFILE
	
	# INIT: Perform bus-specific stuff...
	case $type in

	1)	echo1 "* Installing a PCI/PnP/ISA controller"
		;;
	2)	echo1 "* Installing a PCMCIA controller"
		if ! rpm -qa | grep pcmcia-3.1.31 > /dev/null 2>&1; then
			echo3 "External PCMCIA package not installed."
		fi
		if ! test -f $PCCONFIG; then
			echo3 "Could not find PCMCIA config file $PCCONFIG!"
		fi
		;;
	3)	echo1 "* Installing an USB controller"
		hcc=0
		for i in uhci usb-uhci usb-ohci ehci-hcd; do
			if lsmod | grep "$i " > /dev/null 2>&1; then
				hcc=1
			fi
		done
		if [ $hcc -eq 0 ]; then
			# No host controller driver -> no USB?
			echo3 "Could not find a host controller driver!"
		fi
		check_usb_bus $pid1 $pid2
		case $? in
			0)	# nop
				;;
			1)	echo3 "Driver/controller mismatch."
				exit $err_usb
				;;
			2)	echo3 "Too many USB controllers."
				exit $err_usb
				;;
		esac
		;;
	*)	echo2 "Unknown archive type."
		exit 0
		;;
	esac
	
	# INIT: Remove old drivers...
	forall uninstall $MODDIR
	uninstall fcpcmcia_cs $PCMCIADIR

	# TEST: Does /usr/share/doc/CAPI4Linux/ exist...?
	if ! test -d $DOCDIR/CAPI4Linux/de; then
		mkdir -p $DOCDIR/CAPI4Linux/de
		mkdir -p $DOCDIR/CAPI4Linux/en
	fi
	echo1 "* $DOCDIR/CAPI4Linux ok"
else
	echo2 "Updating driver..."
fi

# TEST: Check for old archives...
echo "* Scanning for old archives..." >> $LOGFILE
check_rpm $opt_do_rpm

# TASK: Unpacking the archive... (install & update)
if [ $opt_do_rpm -eq 1 ]; then
	echo2 "Copying CAPI drivers..."
	rpm --upgrade --force c4l-sys-$SYSVER-1.i386.rpm 2>> $LOGFILE
	echo2 "Copying CAPI tools..."
	rpm --upgrade --force c4l-lib-$LIBVER-1.i386.rpm 2>> $LOGFILE
fi
echo2 "Copying driver module..."
if ! test -d $MODDIR; then
	echo1 "* Creating directory $MODDIR"
	mkdir -p $MODDIR
fi
cp -vf $prefix$name.o $MODDIR >> $LOGFILE

# INIT: Call card specific installer
install_card $opt_update

# INIT: Create/update /etc/capi.conf
if [ $opt_update -eq 0 ]; then
	if [ "$card" == "dsl" ]; then
		if test -f /etc/capi.conf; then
			if ! cat /etc/capi.conf | grep fcdsl > /dev/null; then
				cat $card.conf >> /etc/capi.conf
			fi
		else
			cp -vf $card.conf /etc/capi.conf >> $LOGFILE
		fi
	else
		cp -vf $card.conf /etc/capi.conf >> $LOGFILE
	fi
fi
cp -vf install_passive-d.html $DOCDIR/CAPI4Linux/de/install_passive.html
cp -vf install_passive-e.html $DOCDIR/CAPI4Linux/en/install_passive.html

# TASK: If any, copy firmware file(s)
if [ "$loadfile1" != "" ]; then
	echo2 "Copying firmware..."
	if ! test -d $FWDIR; then
		echo1 "* Creating $FWDIR"
		mkdir -p $FWDIR
	fi
	cp -vf $loadfile1 $FWDIR/$loadfile1 >> $LOGFILE
	# Second firmware file?
	if [ "$loadfile2" != "" ]; then
		cp -vf $loadfile2 $FWDIR/$loadfile2 >> $LOGFILE
	fi
fi
										
# INIT: Call depmod with patched modules.conf, new modules etc.
if [ $opt_update -eq 0 ]; then
	echo1 "* Running depmod -a:"
	depmod -a >> $LOGFILE 2>&1
fi

# INIT: Call card-specific finalizer...
finalize $opt_update

# INIT: Call archive-specific finalizer...
if [ $opt_update -eq 0 ]; then
	if test -f scripts/final; then
		scripts/final $prefix$name
	fi
	if [ $kick -eq 1 ]; then
		capi_start
	fi
	if [ $USB -eq 1 -o $PCMCIA -eq 1 ]; then
		echo ""
		echo "The driver for the $cardname gets loaded, when the controller"
		echo "is plugged in... (If it is already connected to your computer, please"
		echo "first remove and then connect it again.)"
	fi
else
	if [ $ncards -ne 0 ]; then
		echo1 "* Restart CAPI with new modules"
		capi_start
	fi
	echo2 "Update has been completed."
fi

echo1 "* Leaving install script\n"

