#!/bin/sh
#
# chkconfig: 345 48 52
# description: Automounts filesystems on demand
# processname: /usr/sbin/automount
# config: /etc/auto.master
# pidfile: /var/run/automount.xxx.pid

WITHOUT_RC_COMPAT=1

# Source function library.
. /etc/init.d/functions

PIDFILE=/var/run/automount
LOCKFILE=/var/lock/subsys/autofs
SKIPFILE=/var/lock/subsys/autofs.skip
DAEMON=/usr/sbin/automount
CONFIGFILE=/etc/auto.master
TABFILE=/etc/auto.tab
RETVAL=0

YPCAT=/usr/bin/ypcat
LDAPAUTOMASTER=/usr/lib/autofs/autofs-ldap-auto-master

# Get config.
SourceIfNotEmpty /etc/sysconfig/autofs &&
	[ "$ENABLE" != no ] &&
	[ -x "$DAEMON" ] ||
	exit 0

function skip()
{
	[ -s "$CONFIGFILE" ] && [ -s "$TABFILE" ] || return 0
	return 1
}

#
# Check for all maps that are to be loaded
#

function enable()
{
    echo
}

function disable()
{
    echo
}

#
# Check for all maps that are to be loaded
#
function getschemes()
{
    grep ^automount: /etc/nsswitch.conf | sed -e 's/^.*://' -e 's/\[.*\]/ /g'
}

function catnismap()
{
    if [ -z "$1" ] ; then
        map="auto_master"
    else
        map="$1"
    fi
    [ -x "$YPCAT" ] || return 0
    "$YPCAT" -k "$map" 2> /dev/null | sed -e '/^#/d' -e '/^$/d'
}

function getfilemounts()
{
    local nismap
    if [ -f "$CONFIGFILE" ] ; then
        cat "$CONFIGFILE" | grep -v '^\+' | sed -e '/^#/d' -e '/^$/d'
        for nismap in `cat "$CONFIGFILE" | grep '^\+' | sed -e '/^#/d' -e '/^$/d'`; do
            catnismap `echo "$nismap" | sed -e 's/^\+//'`
        done
    fi
}

function getnismounts()
{
    YPMAP=`catnismap auto.master`
    if [ -z "$YPMAP" ]; then
       catnismap
    else
       catnismap auto.master
    fi
}

function getldapmounts()
{
    [ -x "$LDAPAUTOMASTER" ] || return 0
    "$LDAPAUTOMASTER" 2> /dev/null
}

function getrawmounts()
{
    local scheme
    for scheme in `getschemes` ; do
        case "$scheme" in
            files)
                if [ -z "$filescheme" ] ; then
                    getfilemounts
                    filescheme=1
                    export filescheme
                fi
                ;;
            nis)
                if [ -z "$nisscheme" ] ; then
                    getnismounts
                    nisscheme=1
                    export nisscheme
                fi
                ;;
            ldap*)
                if [ -z "$ldapscheme" ] ; then
                    getldapmounts
                    ldapscheme=1
                    export ldapscheme
                fi
                ;;
        esac
    done
}

#
# This function will build a list of automount commands to execute in
# order to activate all the mount points. It is used to figure out
# the difference of automount points in case of a reload
#
function getmounts()
{
    #
    # Check for local maps to be loaded
    #
    local knownmaps=
    local dir map options maptype mapoptions startupoptions pidtail
    getrawmounts | (
	while read dir map options; do
	    # We can't do empty or direct host maps, so don't bother trying.
	    if [ -n "$map" -a "$map" = "-hosts" ] ; then
		continue
	    fi
	    # These checks screen out duplicates and skip over directories
	    # where the map is '-'.
	    if [ -n "$dir" -a -n "$map" \
		-a "`echo $map |cut -c1`" != '-' \
		-a -z "`echo $knownmaps |grep $dir/`" ]; then
		# If the options include a -t or --timeout or a -g or --ghost
		# parameter, then pull those particular options out.

		startupoptions=
		if echo "$options" | grep -qE -- '\B-(t\b|-timeout\b=)' ; then
		    startupoptions="--timeout=$(echo $options |\
			sed 's/.*-\(t[^0-9]*\|-timeout\)[ \t=]*\([0-9][0-9]*\).*$/\2/g')"
		elif echo "$DAEMONOPTIONS" | grep -q -- '-t' ; then
		    # It's okay to be sloppy with DAEMONOPTIONS as there is no
		    # possibility of conflicting with mount or map options.
		    startupoptions="--timeout=$(echo $DAEMONOPTIONS | \
			sed 's/.*--*t\(imeout\)*[ \t=]*\([0-9][0-9]*\).*$/\2/g')"
		fi

		# Check for the ghost option
		if echo "$options" | grep -qE -- '\B-(g\b|-ghost\b)' ; then
		    startupoptions="$startupoptions --ghost"
		fi

		# Check for verbose
		if echo "$DAEMONOPTIONS $options" | grep -qE -- '\B-(v\b|-verbose\b)' ; then
		    startupoptions="$startupoptions --verbose"
		fi

		# Check for debug
		if echo "$DAEMONOPTIONS $options" | grep -qE -- '\B-(d\b|-debug\b)' ; then
		    startupoptions="$startupoptions --debug"
		fi

		# Other option flags are intended for maps.
		mapoptions="$(echo "$DAEMONOPTIONS $options" |\
		    sed   's/-\(t[^0-9]*\|-timeout\)[ \t=]*\([0-9][0-9]*\)//g' |
		    sed   's/-\(g\b\|-ghost\b\)//g' |
		    sed   's/-\(v\b\|-verbose\b\)//g' |
		    sed   's/-\(d\b\|-debug\b\)//g')"
	
		# Break up the maptype and map, if the map type is specified
		maptype=`echo $map | cut -f1 -d:`
		# Handle degenerate map specifiers
		if [ "$maptype" = "$map" ] ; then
		    if [ -x "$map" ]; then
			maptype=program
		    elif [ -x "/etc/$map" ]; then
			maptype=program
			map=`echo /etc/$map | sed 's^//^/^g'`
		    elif [ -f "$map" ]; then
			maptype=file
		    elif [ "$map" = "hesiod" -o "$map" = "userhome" ] ; then
			maptype=$map
			map=
		    elif [ "$map" = "multi" ] ; then
			maptype=$map
			map=
		    else
			maptype=yp
			if [ "$UNDERSCORETODOT" = "0" ] ; then
			    map=`basename $map | sed 's^//^/^g'`
			else
			    map=`basename $map | sed -e s/^auto_home/auto.home/ -e s/^auto_mnt/auto.mnt/`
			fi
		    fi
		fi

		map=`echo $map | cut -f2- -d:`
		pidtail=`echo $dir | sed 's/\//./g'`
		startupoptions="--pid-file $PIDFILE$pidtail.pid $startupoptions"
    
		echo "$DAEMON $startupoptions $dir $maptype $map $mapoptions $LOCALOPTIONS" | sed -e 's/	/ /g' -e 's/  / /g'

	    fi
	    knownmaps=" $dir/ $knownmaps"
	done
    )
}

#
# Status lister.
#
function status()
{
	echo "Configured Mount Points:"
	echo "------------------------"
	getmounts
	echo ""
	echo "Active Mount Points:"
	echo "--------------------"
	ps --no-headers axwww |grep "[0-9]:[0-9][0-9] $DAEMON " | (
		while read pid tt stat time command; do echo $command; done
	)
}

function start()
{
	if skip; then
		touch "$SKIPFILE"
		RETVAL=0
		return $RETVAL
	fi
		
	# Make sure the autofs filesystem type is available.
	if ! fgrep -qs autofs /proc/filesystems; then
		if ! action "Loading autofs support:" modprobe -k autofs4 2>/dev/null; then
			RETVAL=1
			return $RETVAL
		fi
	fi

	echo -n 'Starting automounter: '
	getmounts |sh &&
	{
		RETVAL=0
		success "automounter startup"
	} || {
		failure "automounter startup"
		RETVAL=1
	}
	echo
	rm -f "$SKIPFILE"
	[ $RETVAL -eq 0 ] && touch "$LOCKFILE"
	return $RETVAL
}

function stop()
{
	
	RETVAL=0
	if ! action "Stopping automounter:" \
	    /sbin/start-stop-daemon --stop --quiet --oknodo \
		--signal USR2 --retry 5 --exec $DAEMON; then
	    RETVAL=1
	    return $RETVAL
	fi

	umount -a -f -l -t autofs ||:
	[ $RETVAL -eq 0 ] && rm -f "$LOCKFILE"
	return $RETVAL
}

function restart()
{
	stop
	start
}

function reload()
{
	if [ ! -f $LOCKFILE ]; then
		echo "Automounter not running"
		RETVAL=1
		return $RETVAL
	fi
	echo "Checking for changes to $CONFIGFILE ...."
        TMP1=`mktemp /tmp/autofs.XXXXXX` || { echo "could not make temp file" >& 2; exit 1; }
        TMP2=`mktemp /tmp/autofs.XXXXXX` || { echo "could not make temp file" >& 2; exit 1; }
	getmounts >$TMP1
	ps --no-headers axwww |grep "[0-9]:[0-9][0-9] $DAEMON " | (
	    while read pid tt stat time command; do
		echo "$command" >>$TMP2
		if ! grep -qs "^$command" $TMP2; then
			while kill -USR2 $pid; do
			    sleep 3
			done
			echo "Stop $command"
		fi
	    done
	)
	( while read x; do
		if ! grep -q "^$x" $TMP2; then
			$x
			echo "Start $x"
		fi
        done ) <$TMP1
	rm -f $TMP1 $TMP2
}

# See how we were called.
case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	status)
		status
		;;
	reload)
		reload
		;;
	restart)
		restart
		;;
	condstop)
		if [ -e "$LOCKFILE" ]; then
			stop
		fi
		;;
	condrestart)
		if [ -e "$LOCKFILE" ]; then
			restart
		fi
		;;
	skipstart)
		if [ -e "$SKIPFILE" -a ! -e "$LOCKFILE" ]; then
			start
		fi
		;;
	*)
		echo "Usage: ${0##*/} {start|stop|status|reload|restart|condstop|condrestart}"
		RETVAL=1
esac

exit $RETVAL
