#!/bin/bash
#
# Install Script for the OMNIKEY CardMan 4040 smartcard reader.
#
# Version 2.0.0
# OMNIKEY
# www.omnikey.com
#

#
# Variables
#
device=cm4040_cs
shlib="ifdok_cm4040_lnx-2.0.0.so"
moddir="/lib/modules"
#
# Version of pcscd, which has to be installed
#
pcscd_refmaj=1
pcscd_refmin=2
pcscd_reffin=0

release=`uname -r`
release_minor=`uname -r|cut -f2 -d.`
release_build=`uname -r|cut -f1 -d-|cut -f3 -d.`

#
# Check if pcmcia_utils are used, this is done at kernels > 2.6.13-rc1
#
use_pcmciautils=0
if [ $release_minor -gt 4 ]; then
    if [ $release_build -gt 13 ]; then
        use_pcmciautils=1
    else
        use_pcmciautils=0 
    fi
fi

if [ $release_minor -le 4 ] ; then
  krnmod=cm4040_cs.o
else
  krnmod=cm4040_cs.ko
fi
instpath="${moddir}/${release}/kernel/drivers/pcmcia/"
home=`pwd`


################################################################
# Set PCMCIA script path
################################################################
SetPcmciaPath()
{
RETCODE=0
#
#SuSE
#
  if [ -x /sbin/init.d/pcmcia ]; then
    pcmciascript=/sbin/init.d/pcmcia
  fi
#
# Redhat, Mandrake
#
  if [ -x /etc/rc.d/init.d/pcmcia ]; then
    pcmciascript=/etc/rc.d/init.d/pcmcia
  fi
#
# Knoppix (Debian based)
#
  if [ -x /etc/init.d/pcmcia ]; then
    pcmciascript=/etc/init.d/pcmcia
  fi

  if [ "$pcmciascript" = "" ]; then
    RETCODE=1
  fi
  return $RETCODE
}

################################################################
# Set PCSC library path
################################################################
SetPcscPath()
{
local RETCODE=0

#
# If not found try to find manually
#
  if [ -f /usr/lib/libpcsclite-core.so ]; then
    pcsclib=/usr/lib
  elif [ -f /usr/local/lib/libpcsclite-core.so ]; then
    pcsclib=/usr/local/lib
  elif [ -d /usr/pcsc/lib ]; then
    pcsclib=/usr/pcsc/lib
  elif [ -d /usr/lib/pcsc ]; then
   pcsclib=/usr/lib/pcsc
  elif [ -d /usr/local/pcsc/lib ]; then
    pcsclib=/usr/local/pcsc/lib
  elif [ -f /usr/local/lib/libpcsclite.so ]; then
    pcsclib=/usr/local/lib
  elif [ -f /usr/local/lib/libpcsclite.a ]; then
    pcsclib=/usr/local/lib
  else
    RETCODE=1
  fi

  return $RETCODE
}

################################################################
# Search PCSCD
################################################################
SearchPcsc()
{
local RETCODE=0

  pcscd_location=`which pcscd 2>/dev/null`
  if [ "$pcscd_location" != "" ]; then
    return $RETCODE
  fi
#
# Try to find pcscd manually in different locations
#
  if [ -x /sbin/pcscd ]; then
    pcscd_location=/sbin/pcscd
  elif [ -x /usr/sbin/pcscd ]; then
    pcscd_location=/usr/sbin/pcscd
  elif [ -x /usr/local/sbin/pcscd ]; then
    pcscd_location=/usr/local/sbin/pcscd
  else
    RETCODE=1
  fi

  return $RETCODE
}

################################################################
# Check PCSC version
################################################################
CheckPcscVersion()
{
local RETCODE=0
local PCSC_VERSION
local PCSC_MAJ
local PCSC_MIN
local PCSC_FIN
local PCSC_BETA

  if [ -z $pcscd_location ]; then
    RETCODE=1
    return $RETCODE
  fi

  PCSC_VERSION=`$pcscd_location --version | head -1 | cut -f3 -d\ `
  PCSC_MAJ=`echo $PCSC_VERSION | cut -f1 -d.`
  PCSC_MIN=`echo $PCSC_VERSION | cut -f2 -d.`
  PCSC_FIN=`echo $PCSC_VERSION | cut -f3 -d. | cut -f1 -d-`
  PCSC_BETA=`echo $PCSC_VERSION | head -1 | cut -f3 -d'.' | cut -f2 -da`

  echo "Found PCSC version $PCSC_MAJ.$PCSC_MIN.$PCSC_FIN in $pcsclib"

  if [ \( \( $PCSC_MAJ -eq $pcscd_refmaj \) -a \( $PCSC_MIN -eq $pcscd_refmin \) -a \( $PCSC_FIN -ge $pcscd_reffin \) \) \
       -o \
       \( \( $PCSC_MAJ -eq $pcscd_refmaj \) -a \( $PCSC_MIN -gt $pcscd_refmin \) \) \
       -o \( $PCSC_MAJ -gt $pcscd_refmaj \) ]; then
    return $RETCODE
  fi

  RETCODE=1

  return $RETCODE
}

################################################################
# Restart PCSC version
################################################################
RestartPcsc()
{
  echo Restarting PC/SC ...
  if [ -f /etc/fedora-release ]; then
      /etc/rc.d/init.d/pcscd stop
      sleep 2
      /etc/rc.d/init.d/pcscd start
  elif [ -f /etc/debian-version ]; then
      /etc/init.d/pcscd stop
      sleep 2
      /etc/init.d/pcsc start
  else
      killall -SIGHUP pcscd > /dev/null
  fi  
}

################################################################
# Main
################################################################
echo
echo Installing OMNIKEY CardMan 4040 smartcard reader driver ...
echo
#
# Check if user has root privileges
# s
if [ `id -u` -ne 0 ]; then
  echo You must have root privileges to install the driver.
  exit 1
fi
#
# Is PCMCIA installed ?
#
if [ $use_pcmciautils -eq 0 ]; then
  SetPcmciaPath
  if [ $? -ne 0 ]; then
    echo PCMCIA support is not installed.
    echo Go visit pcmcia-cs.sourceforge.net
    echo and install the latest version of PCMCIA support
    exit 2
  fi
fi
  
#
# Are PCSC libraries installed ?
#
SetPcscPath
if [ $? -ne 0 ]; then
  echo PCSC-Lite is not installed.
  echo Go visit www.linuxnet.com
  echo and install at least version $pcscd_refmaj.$pcscd_refmin.$pcscd_reffin of pcsc-lite.
  exit 3
fi
#
# Find PCSCD
#
SearchPcsc
if [ $? -ne 0 ]; then
  echo PCSC-Lite is not installed.
  echo Go visit www.linuxnet.com
  echo and install at least version $pcscd_refmaj.$pcscd_refmin.$pcscd_reffin of pcsc-lite.
  exit 4
fi
#
# Check PCSC version
#
CheckPcscVersion
if [ $? -ne 0 ]; then
  echo Install at least version $pcscd_refmaj.$pcscd_refmin.$pcscd_reffin of pcsc-lite.
  exit 5
fi

# ##########################################
# Check which source code we have to use
# ##########################################

#
# Go to source dirctory
#
cd ./src;
#
# Rename makefile
#
  echo Creating makefile ...
  if [ $release_minor -le 4 ] ; then
    cp ./makefile.2.4.x ./makefile
  else
    cp ./makefile.2.6.x ./Makefile
  fi

#
# Use rigth .c and .h files
#
    cfilename="no_file_found"
    hfilename="no_file_found"
    found=0

    # if kernel is < 2.6.13 the old 2.4-sources can be used
    if [ $release_minor -eq 6 ] ; then
        if [ $release_build -lt 13 ] ; then
            echo "Kernel < 2.6.13 is used, use kernel module 2.4.x"
            cfilename="./cm4040_cs.c.2.4.x";
            hfilename="./cm4040_cs.h.2.4.x";
            found=1
        fi
    fi

    if [ $found -eq 0 ]; then

        # check if a file like cm4040_cs.c.2.6.17 exists, if not
        # try to copy a file like cm4040_cs.c.2.6.x
    
        echo searching for ./cm4040_cs.c.2.$release_minor.$release_build
        if [ -f ./cm4040_cs.c.2.$release_minor.$release_build ]; then
            cfilename="./cm4040_cs.c.2.$release_minor.$release_build"
            hfilename="./cm4040_cs.h.2.$release_minor.$release_build"
        else
            echo "No specific kernel module found, try to find a more general"
            echo searching ./cm4040_cs.c.2.$release_minor.x
            if [ -f ./cm4040_cs.c.2.$release_minor.x ]; then
                cfilename="./cm4040_cs.c.2.$release_minor.x"
                hfilename="./cm4040_cs.h.2.$release_minor.x"
            else
                # no specific or general files found,.. 
                echo "Couldn't find a file matching your kernel $release."
                echo "Please check if such a file exists (should contain"
                echo "your kernel major, minor and build or x)."
                echo "if it does not exist, please contact OMNIKEY for support."
                echo "(e-mail: support@omnikey.com)"
                exit 1
            fi
        fi
    fi

    echo trying to copy $filename
    cp $cfilename ./cm4040_cs.c
    cp $hfilename ./cm4040_cs.h

#
# Make clean
#
  echo Cleaning build directory ...
  if [ ! -f ./${krnmod} ]; then
    rm -f ./${krnmod}
  fi
#
# Build kernel module
#
  echo Building kernel module ...
  make;
  if [ ! -f ./${krnmod} ]; then
    echo "Couldn't build kernel module."
    echo "Compile it by yourself or"
    echo "contact OMNIKEY for further details."
    echo "(e-mail: support@omnikey.com)"
    exit 1
  fi
#
# Copy kernel module
#
  echo Copying kernel module ${krnmod} to ${instpath}
  mv ./${krnmod} ${instpath}/${krnmod}
  chmod 644 ${instpath}/${krnmod}
  if [ -d $moddir/$release/pcmcia ]; then
    ln -s ${instpath}/${krnmod} $moddir/$release/pcmcia/${krnmod}
  fi
#
# Install kernel module
#
  /sbin/depmod -a
  
#
# Copy shared library to standard library directory
#
  cd ${home};
  echo ${home}
  echo Copy ${shlib} to ${pcsclib}
  cp ./${shlib} ${pcsclib}
#
# Create reader PCMCIA installer script
#
if [ $use_pcmciautils -eq 0 ]; then
  grep ${device} /etc/pcmcia/config > /dev/null
  if [ $? -ne 0 ]; then
     echo Create PCMCIA device dictionary entry for CardMan 4040
     cat > /etc/pcmcia/${device}.conf << eofconf
device "cm4040_cs"
class "smartcard" module "cm4040_cs"

card "CardMan 4040"
version "OMNIKEY", "CardMan 4040"
bind "cm4040_cs"
eofconf
  fi
fi
  
#
# Create smartcard device class script
#
if [ $use_pcmciautils -eq 0 ]; then
  if [ ! -f /etc/pcmcia/smartcard ]; then
    echo Creating smartcard device class script
    cp ./smartcard /etc/pcmcia/smartcard;
    chmod 755 /etc/pcmcia/smartcard;
  else
    echo There already exists a file named /etc/pcmcia/smartcard
    echo Please check that this file works
    echo Insert the reader and run the following command
    echo /etc/pcmcia/smartcard start cmx0
    echo Now you should see the device /dev/cmx0
    echo Creating a separate script for CardMan 4040
    echo /etc/pcmcia/smartcard.cm4040
    cp ./smartcard /etc/pcmcia/smartcard.cm4040
    chmod 755 /etc/pcmcia/smartcard.cm4040;
  fi
fi

#
# Add reader.conf entry for PSCSC
#
  if [ -f /etc/fedora-release ]; then
      READERCONF="/etc/reader.conf.d/cardman4040.conf"
  else
      READERCONF="/etc/reader.conf"
  fi

  grep -q $shlib $READERCONF 2> /dev/null
  if [ $? -ne 0 ]; then
    echo Adding reader entry to $READERCONF
    mv $READERCONF $READERCONF.bak 2> /dev/null
    cat > $READERCONF << eof
#
# Configuration file for CardMan 4040 smartcard reader.
#

FRIENDLYNAME		"OMNIKEY CardMan 4040 Socket 0"
DEVICENAME		/dev/null
LIBPATH			${pcsclib}/${shlib}
CHANNELID		0
eof
  fi

#
# Restart PCMCIA
#
if [ $use_pcmciautils -eq 0 ]; then
  echo Restarting PCMCIA layer ...
  sh $pcmciascript stop
  sleep 1
  sh $pcmciascript start
fi

#
# Restart PC/SC
#
  RestartPcsc

  echo Installing OMNIKEY CardMan 4040 successfully done
