#!/sbin/runscript
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

depend() {
	local myneed="net"
	local myuse=""

	# Only have Portmap as a dependency if there is a nfs mount in fstab 
	# that should be mounted at boot time.  Also filter out comments.
	local nfsmounts=$(awk '!/^#/ && ($3=="nfs" || $3=="nfs4") && $4 !~ /noauto/ { print $0 }' /etc/fstab)

	if [[ -n ${nfsmounts} ]] ; then
		myneed="${myneed} portmap"
		myuse="${myuse} nfs nfsmount"
	else
		myuse="${myuse} portmap"
	fi

	need ${myneed}
	use ${myuse}
}

remove_net_fs() {
	local fs
	rcfilesystems=" ${rcfilesystems} "
	for fs in "$@" ; do
		rcfilesystems=${rcfilesystems// ${fs} / }
	done
	rcfilesystems=${rcfilesystems# } # remove front and
	rcfilesystems=${rcfilesystems% } #   back spaces
}

start() {
	local rcfilesystems=${NET_FS_LIST}

	# Only try to mount NFS filesystems if portmap was started.
	# This is to fix "hang" problems for new users who do not
	# add portmap to the default runlevel.
	if ! service_started portmap ; then
		remove_net_fs nfs nfs4
	fi
	rcfilesystems=${rcfilesystems// /,}   # convert to comma-separated

	ebegin "Mounting network filesystems"
	mount -at ${rcfilesystems} >/dev/null

	if [[ $? != 0 ]] ; then
		ewend 1 "Could not mount all network filesystems!"
	else
		eend 0
	fi

	return 0
}

stop() {
	local rcfilesystems=${NET_FS_LIST}

	# We let the afs init script handle unmounting afs stuff
	# because it requires special handling of the afs daemon
	# and similar ugly cruft
	if service_started afs-client ; then
		remove_net_fs afs
	fi

	rcfilesystems=${rcfilesystems// /,}   # convert to comma-separated

	local ret
	ebegin "Unmounting network filesystems"
	[[ -z $(umount -art ${rcfilesystems} 2>&1) ]]
	ret=$?
	eend ${ret} "Failed to simply unmount filesystems"
	[[ ${ret} == 0 ]] && return 0

	# `umount -a` will fail if the filesystems are in use.
	# Here we use fuser to kill off processes that are using 
	# the filesystems so that we can unmount properly.
	# We will gradually use harsher kill signals so that the 
	# processes know we aren't screwing around here ;).
	declare -a siglist=( "TERM" "KILL" "KILL" )
	local retry=0
	local remaining="go"

	while [[ -n ${remaining} && ${retry} -lt 3 ]] ; do
		# Populate $remaining with a newline-delimited list of network 
		# filesystems.  Mount points have spaces swapped for '\040' (see 
		# fstab(5)) so we have to translate them back to spaces.
		remaining="$(awk '$3 ~ /'${NET_FS_LIST// /|}'/ { if ($2 != "/") print $2 }' /proc/mounts | sort -r)"
		# Since we have to worry about the spaces being quoted properly, 
		# we'll use `set --` and then "$@" to get the correct result.
		IFS=$'\n'
		set -- ${remaining//\\040/ }
		unset IFS
		[[ -z ${remaining} ]] && break

		# try to unmount again
		ebegin $'\t'"Unmounting network filesystems (retry #$((retry+1)))"
		/bin/fuser -s -k -${siglist[$((retry++))]} -m "$@"
		sleep 5
		umount "$@" &>/dev/null
		eend $? $'\t'"Failed to unmount filesystems"
	done
}

# vim:ts=4
