#!/bin/sh
#
# etercifs CIFS support for Linux kernel
#
# Authors: Vitaly Lipatov <lav@etersoft.ru>
#          Konstantin Baev <kipruss@altlinux.org>
#
# chkconfig: 345 03 80
#
# description:  linux cifs module \
#               Multiplatform init script \
#               2006, 2007, 2008, 2009 Public domain
#
# modulename: etercifs
#
RMMOD=/sbin/rmmod
MODPROBE=/sbin/modprobe
INSMOD=/sbin/insmod

if [ -f /etc/etercifs.conf ] ; then
  . /etc/etercifs.conf
fi

[ -n "$SRC_DIR" ] || SRC_DIR=/usr/src
[ -n "$DATADIR" ] || DATADIR=/usr/share/etercifs
[ -n "$MODULENAME" ] || MODULENAME=etercifs
[ -n "$BUILT" ] || BUILT=0
[ -n "$DKMS" ] || DKMS=1
[ -n "$CHECK_VERSION" ] || CHECK_VERSION=1

ORIGMODULENAME=cifs

OUTFORMAT=/etc/init.d/outformat
[ -x $OUTFORMAT ] || OUTFORMAT=/etc/init.d/etercifs.outformat

if which tput >/dev/null && test -x $OUTFORMAT ; then
        . $OUTFORMAT
else
    MOVE_TO_COL(){ :; }
    SETCOLOR_SUCCESS(){ :; }
    SETCOLOR_FAILURE(){ :; }
    SETCOLOR_WARNING(){ :; }
    SETCOLOR_NORMAL(){ :; }
fi

# TODO: use printf?
success()
{
    MOVE_TO_COL
    echo -n '[ '
    SETCOLOR_SUCCESS
    echo -n 'DONE'
    SETCOLOR_NORMAL
    echo ' ]'
}

failure()
{
    MOVE_TO_COL
    echo -n '['
    SETCOLOR_FAILURE
    echo -n 'FAILED'
    SETCOLOR_NORMAL
    echo ']'
}

passed()
{
    MOVE_TO_COL
    echo -n '['
    SETCOLOR_WARNING
    echo -n 'PASSED'
    SETCOLOR_NORMAL
    echo ']'
}

get_pid()
{
    # TODO: use pgrep
    PIDOF=/bin/pidof
    if [ -x $PIDOF ] ; then
        dpid=`$PIDOF $1`
    else
        dpid="$(ps axh | grep $1 | grep -v grep | sed -e 's/ *\(.*\)/\1/' -e 's/ \+/ /g' | grep -v " /bin/sh " | grep -v "^$$ " |  cut -f1 -d\  | head -1)"
    fi
    return $dpid
}

get_module_version()
{
    MODVER=`modinfo etercifs | grep ^version:`
    MODVER=`echo $MODVER | sed 's|version:||g'`
    MODVER=`echo $MODVER | sed 's| ||g'`
}

get_loaded_module_version()
{
    LOADEDMODVER=`cat /sys/module/$MODULENAME/version 2>/dev/null`
}

is_loaded()
{
    get_pid $1
    test -n "$dpid"
}

is_moduled()
{
    lsmod | grep "^$MODULENAME" > /dev/null
}

is_origmoduled()
{
    lsmod | grep "^$ORIGMODULENAME" > /dev/null
}

umount_cifs()
{
    WASCIFS=
    if mount | grep cifs 2>/dev/null ; then
        WASCIFS=1
    fi
    echo -n "Unmounting CIFS resources... "
    umount -t cifs -a || { failure ; return 1; }
    success

    if cat /proc/mounts | grep ' cifs ' ; then
        echo -n "Unmounting lost CIFS resources..."
        # we have something to unmount, which is not in /etc/mtab
        for i in $(cat /proc/mounts | grep ' cifs ' | cut -d' ' -f2); do
            umount "$i" || { failure; return 1; }
        done
        success
    fi
}

mount_cifs()
{
    echo -n "Mounting CIFS resources... "
    mount -t cifs -a || { failure ; return 1; }
    success
}

load_module()
{
    local i
    if is_origmoduled ; then
        umount_cifs
        echo -n "Removing vanilla kernel module $ORIGMODULENAME... "
        $RMMOD $ORIGMODULENAME || { failure ; return ; }
        success
    fi

    echo -n "Loading kernel module $MODULENAME... "

    get_module_version

    if [ "$MODULEVERSION" != "$MODVER" ] && [ "$CHECK_VERSION" -eq 1 ] ; then
        [ $MODVER ] && {
            failure
            show_module_version
            echo "    Please, run 'service etercifs build' to build the etercifs module (recommended)"
            #echo "    or run 'CHECK_VERSION=0 service etercifs restart' to disable check."
            return
        }
    fi

    $MODPROBE $MODULENAME && { success ; return ; }
    echo -n "$MODULENAME from Etersoft is not found, "
    echo -n "trying to compile it..."
    if [ $BUILT -ne 1 ] ; then
        build_module
        BUILT=1
        start
    fi
}

start()
{
    load_module
    if is_moduled ; then
        test -n "$WASCIFS" && mount_cifs || :
    fi
}

stop()
{
    umount_cifs
    echo -n "Unloading kernel module $MODULENAME... "
    is_moduled || { passed ; return ; }
    $RMMOD $MODULENAME || { failure ; echo "You have to umount all CIFS resources before module unloading."; return ; }
    success
}

show_module_version()
{
    echo "    package $MODULENAME version $MODULEVERSION"
    if [ $MODVER ] ; then
        echo "    kernel module $MODULENAME version $MODVER is built for current kernel"
    else
        echo "    kernel module $MODULENAME is built"
    fi
    if [ "$MODULEVERSION" != "$MODVER" ] ; then
        [ $MODVER ] && echo "    WARNING!!! Versions of the package $MODULENAME and built module $MODULENAME DON'T MATCH!!!"
    fi
}

show_loaded_module_version()
{
    if [ $LOADEDMODVER ] ; then
        echo "    kernel module $MODULENAME version $LOADEDMODVER is loaded"
        if [ "$MODULEVERSION" != "$LOADEDMODVER" ] ; then
            [ $MODVER ] && echo "    WARNING!!! Versions of the package $MODULENAME and loaded module $MODULENAME DON'T MATCH!!!"
        fi
    else
        echo "    WARNING!!! Can't get version of loaded module $MODULENAME!"
    fi
}

status()
{
    local PRECOMP
    echo "CIFS module status:"
    if is_moduled ; then
        get_module_version
        show_module_version
        get_loaded_module_version
        show_loaded_module_version
    else
        if is_origmoduled ; then
            echo "    vanilla kernel module $ORIGMODULENAME loaded"
        fi
        echo "    WARNING!!! Kernel module $MODULENAME is not loaded!"
        echo "    WINE@Etersoft won't run on the CIFS resource!"
    fi
}

build_module()
{
    if [ -r $SRC_DIR/dkms.conf ] && [ `which dkms 2>/dev/null` ] && [ $DKMS -eq 1 ] ; then
        cd $DATADIR
        DKMSBUILD=1 sh buildmodule.sh
    else
        cd $DATADIR
        sh buildmodule.sh
    fi
}

test_build_module()
{
    cd $DATADIR
    TESTBUILD=1 sh buildmodule.sh
}

case "$1" in
    start)
        start
        ;;
    condstop|stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    build)
        build_module
        ;;
    testbuild)
        test_build_module
        ;;
    status)
        status
        ;;
    condrestart)
        if is_moduled ; then
            stop
            start
        else
            echo -n "Etersoft CIFS module..." && passed
        fi
        ;;
    *)
        echo "Usage: etercifs {start|stop|restart|build|testbuild|condrestart|condstop|status}"
esac

