#! /bin/bash
#
# $Id: rc.autofs.in,v 1.3 1999/03/07 22:59:55 hpa Exp $
#
# rc file for automount using a Sun-style "master map".
# We first look for a local /etc/auto.master, then a YP
# map with that name
#
# On most distributions, this file should be called:
# /etc/rc.d/init.d/autofs or /etc/init.d/autofs
#

# For Redhat-ish systems
#
# chkconfig: 345 15 85
# description: Automounts filesystems on demand

# This is used in the Debian distribution to determine the proper
# location for the S- and K-links to this init file.
# The following value is extracted by debstd to figure out how to
# generate the postinst script. Edit the field to change the way the
# script is registered through update-rc.d (see the manpage for
# update-rc.d!)
#
FLAGS="defaults 21"

#
# Location of the automount daemon and the init directory
#
DAEMON=/usr/sbin/automount
initdir=/etc/init.d

#
# Determine which kind of configuration we're using
#
system=unknown
if [ -f /etc/debian_version ]; then
    system=debian
elif [ -f /etc/redhat-release ]; then
    system=redhat
else
    echo "$0: Unknown system, please port and contact autofs@linux.kernel.org" 1>&2
    exit 1
fi

if [ $system = redhat ]; then
    . $initdir/functions
fi

test -e $DAEMON || exit 0
thisscript="$0"
if [ ! -f "$thisscript" ]; then
    echo "$0: Cannot find myself" 1>&2
    exit 1
fi

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

#
# We can add local options here
# e.g. localoptions='rsize=8192,wsize=8192'
#
localoptions=''

#
# 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()
{
    if ! getmounts_file /etc/auto.master; then
	if ! getnismounts auto.master; then
	    echo "no autofs mounts configured!" 1>&2
	fi
    fi
}

function getmounts_file()
{
    #
    # Check for local maps to be loaded
    #
    local map="$1"
    shift
    if [ -f "$map" ]
    then
	cat "$map" | sed -e '/^#/d' -e '/^$/d' | process_master_file "$@"
    else
	return 1
    fi
}

function process_master_file()
{
    local line_options="$@" daemon_options
    while read dir map options
    do
	options="$line_options $options"
	case "$dir" in
	    +*)	getnismounts "${dir/+/}" $map $options
		continue;
	esac
	if [ ! -z "$dir" -a ! -z "$map" \
		-a x`echo "$map" | cut -c1` != 'x-' ]
	then
	    type=""
	    if [ -x $map ]; then
		type=program
	    elif [ -f $map ]; then
		type=file
	    elif [ -f /etc/$map ]; then
		type=file
		map=/etc/$map
	    else
		type=yp
	    fi
	    daemon_options=`munge_options daemon $options`
	    options=`munge_options mount $options`
	    if [ -n "$daemon_options" ]; then
		daemon_options="$daemon_options "
	    fi

	    if [ "$type" ]; then
		echo "$DAEMON $daemon_options-- $dir $type $map $local_options $options"
	    fi
	fi
    done
}

function getnismounts()
{
    #
    # Check for YellowPage maps to be loaded
    #
    local map="$1"
    shift
    if [ -e /usr/bin/ypcat ] && [ `ypcat -k "$map" 2>/dev/null | wc -l` -gt 0 ]
    then
	ypcat -k "$map" | process_master_file "$@"
    else
	return 1
    fi
}

#
# List active mounts
#
function active()
{
    ps ax|grep "[0-9]:[0-9][0-9] $DAEMON " |
	while read pid tt stat time command
	do
	    echo $command
	done
}

#
# Status lister.
#
function status()
{
    echo "Configured Mount Points:"
    echo "------------------------"
    getmounts | sed 's/ -- / /'
    echo ""
    echo "Active Mount Points:"
    echo "--------------------"
    active
}

function munge_options()
{
	local which="$1"
	shift
	echo "$@" | awk -v which="$which" '
BEGIN {
	RS="[, \n-]"
	FS="="
	daemon_opts[ "timeout" ] = "timeout"
	daemon_opts[ "t" ] = "timeout"
}
{
	if ( $0 ~ /^$/ )
		next
	if ( $1 in daemon_opts ) {
		daemon[ daemon_opts[ $1 ] ] = $2
	} else {
		mount[$0] = 1
	}
}
END {
	if ( which ~ "^daemon$" ) {
		if ( daemon["timeout"] ) {
			printf "--timeout=%s\n", daemon["timeout"]
		}
	} else {
		for ( a in mount ) {
			if ( length( out ) )
				out=out "," a
			else
				out=a
		}
		printf "%s\n", out
	}
}
'
}

#
# Redhat start/stop function.
#
function redhat()
{

#
# See how we were called.
#
case "$1" in
  start)
	# Check if the automounter is already running?
	if [ ! -f /var/lock/subsys/autofs ]; then
	    echo 'Starting automounter: '
	    getmounts | sed 's/ -- / /' | sh
	    touch /var/lock/subsys/autofs
	fi
	;;
  stop)
	kill -TERM $(/sbin/pidof /usr/sbin/automount)
	rm -f /var/lock/subsys/autofs
	;;
  reload|restart)
	if [ ! -f /var/lock/subsys/autofs ]; then
		echo "Automounter not running"
		exit 1
	fi
	echo "Checking for changes to /etc/auto.master ...."
        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 | sed 's/ -- / /' >$TMP1
	ps ax|grep "[0-9]:[0-9][0-9] automount " | (
	    while read pid tt stat time command; do
		echo "$command" >>$TMP2
		if ! grep -q "^$command" $TMP2; then
			kill -USR2 $pid
			echo "Stop $command"
		fi
	    done
	)
	cat $TMP1 | ( while read x; do
		if ! grep -q "^$x" $TMP2; then
			$x
			echo "Start $x"
		fi
        done )
	rm -f $TMP1 $TMP2
	;;
  status)
	status
	;;
  getmounts)
	getmounts
	;;
  active)
	active
	;;

  *)
	echo "Usage: $initdir/autofs {start|stop|restart|reload|status|getmounts|active}"
	exit 1
esac
}

#
# Debian start/stop functions.
#
function debian()
{
#
# See how we were called.
#
case "$1" in
    start)
	echo -n 'Starting automounter:'
	getmounts | while read cmd args
	do
		opt=${args%%-- *}
		rest=${args#*-- }
		mnt=${rest%% *}
		rest=${rest#* }
		echo -n " $mnt"
		pidfile=/var/run/autofs/`echo $mnt | sed 's,_,__,g;s,/,_:,g'`.pid
		start-stop-daemon --start --pidfile $pidfile --quiet \
			--exec $DAEMON -- $opt $mnt $rest
		#
		#	Automount needs a '--pidfile' or '-p' option.
		#	For now we look for the pid ourself.
		#
		ps ax | grep "[0-9]:[0-9][0-9] $DAEMON $opt$mnt" | (
			read pid tt stat time command
			echo $pid > $pidfile
			echo "$command" >> $pidfile
		)
	done
	echo "."
	;;
    stop)
	echo 'Stopping automounter.'
	start-stop-daemon --stop --quiet --signal USR2 --exec $DAEMON
	for file in /var/run/autofs/*.pid
	do
	    if [ -e "$file" ]
	    then
		pid=`head -n 1 $file`
		command=`tail -n 1 $file`
		if [ -z "`ps --no-heading $pid`" ]
		then
		    echo "Stopped $pid($command)."
		    rm -f $file
		else
		    echo "Couldn't stop $pid($command)."
		fi
	    fi
	done
	;;
    reload|restart)
	echo "Reloading automounter: checking for changes ... "
	TMP=/var/run/autofs.tmp
	getmounts | sed 's/ -- / /' >$TMP
	for i in /var/run/autofs/*.pid
	do
		pid=`head -n 1 $i 2>/dev/null`
		[ "$pid" = "" ] && continue
		command=`tail +2 $i`
		if ! grep -q "^$command" $TMP
		then
			echo "Stopping automounter: $command"
			kill -USR2 $pid
			rm -f $i
		fi
	done
	rm -f $TMP
	$thisscript start
	;;
    force-reload)
	$0 stop
	$0 start
	;;
    status)
	status
	;;
    getmounts)
	getmounts | sed 's/ -- / /'
	;;
    active)
	active
	;;
    *)
	echo "Usage: $initdir/autofs {start|stop|restart|reload|force-reload|status|getmounts|active}" >&2
	exit 1
	;;
esac
}

if [ $system = debian ]; then
	debian "$@"
elif [ $system = redhat ]; then
	redhat "$@"
fi

exit 0
