#!/bin/sh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/sbin/svcmd/umountall/umountall.sh 1.5.1.1 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2001,2011 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)85        1.5.1.1  src/bos/usr/sbin/svcmd/umountall/umountall.sh, uw7cmds, bos720 8/3/11 06:47:16

# Copyright (c) 1998 The Santa Cruz Operation, Inc.. All Rights Reserved. 
#                                                                         
#        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF THE               
#                   SANTA CRUZ OPERATION INC.                             
#                                                                         
#   The copyright notice above does not evidence any actual or intended   
#   publication of such source code.                                      

# Reset PATH and add /usr/bin and /usr/sbin, to ensure that,
# the correct command binaries are referred by the command.
unset PATH
export PATH=/usr/bin:/usr/sbin


CAT=umountall.cat; export CAT
MULTFSTS=1
NOH_F=2
NOH_L_R=3
NOLANDR=4
BADARGS=5
FSTNOTL=6
FSTNOTR=7
INVALID_FST=8
USAGE=9

usage() 
{
	dspmsg $CAT $USAGE "Usage:\numountall [-ks] [-F FStype] [-l|-r]\numountall [-ks] [-h host]\n" 1>&2
	exit 2
}
Host=
FSType=
kill=
FCNT=0
CNT=0
ALL_FSTS=
REMOTE_FSTS=
REMOTEFS_SPEC=

# gather all filesystem types
grep -v \# /etc/vfs | grep -v % |
awk '{print $1}' |
while read fsname
do
        ALL_FSTS="${ALL_FSTS}.$fsname"
done
# gather remote filesystem types
grep -v \# /etc/vfs | 
grep remote |
awk '{print $1}' |
while read rfsname
do
	REMOTE_FSTS="${REMOTE_FSTS}.$rfsname"
done

while getopts ?rlksF:h: c
do
	case $c in
	r)	RFLAG="r" export RFLAG; CNT=`/usr/bin/expr $CNT + 1`;;
	l)	LFLAG="l" export LFLAG; CNT=`/usr/bin/expr $CNT + 1`;;
	k) 	kill="yes" export kill;;
	s)	;;# serialize the umounts. i.e. do nothing
	h)	Host=$OPTARG export Host;;
	F)	FSType=$OPTARG export FSType
		FCNT=`/usr/bin/expr $FCNT + 1`;;
	\?)	usage
		;;
	esac
done
if test -n "$FSType"
then
	VALID_FST=`echo $ALL_FSTS $FSType | awk '{print index($1, $2)}'`
	REMOTEFS_SPEC=`echo $REMOTE_FSTS $FSType | awk '{print index($1, $2)}'`
else
	VALID_FST=-1
	REMOTEFS_SPEC=-1
fi
shift `/usr/bin/expr $OPTIND - 1`
if test $FCNT -gt 1
then
	dspmsg $CAT $MULTFSTS "%s: more than one FSType specified\n" $0 1>&2
	exit 2
fi
if test VALID_FST -eq 0
then
	dspmsg $CAT $INVALID_FST "%s: FSType %s invalid or not found\n" $0 $FSType 1>&2
	exit 0
fi
if test -n "$FSType" -a -n "$Host"
then
	dspmsg $CAT $NOH_F "%s: -h option incompatible with -F option\n" $0 1>&2
	usage
fi
if test $CNT -gt 0 -a -n "$Host"
then
	dspmsg $CAT $NOH_L_R "%s: -h option incompatible with -l and -r options\n" $0 1>&2
	usage
fi
if test $CNT -gt 1
then
	dspmsg $CAT $NOLANDR "%s: options -r and -l incompatible\n" $0 1>&2
	usage
fi
if test $# -gt 0
then
	dspmsg $CAT $BADARGS "%s: arguments not supported\n" $0 1>&2
	usage
fi
if test  $REMOTEFS_SPEC -gt 0 -a "$LFLAG" = "l"
then
	dspmsg $CAT $FSTNOTL "%s: option -l and FSType %s are incompatible\n" $0 $FSType 1>&2
	usage
fi
if test $REMOTEFS_SPEC -eq 0 -a "$RFLAG" = "r"
then
	dspmsg $CAT $FSTNOTR "%s: option -r and FSType %s are incompatible\n" $0 $FSType 1>&2
	usage
fi

# get information on mounted filesystems from mount command
# the fields piped on are: dev	mountp	FSType	node (if node exists)
mount |
awk '{ line[i++] = $0; } END { while (i > 2) {print line[--i]; } }' |
awk '{ if ( index($3,"/")==1) { printf "%s\t%s\t%s\t%s\n", $2, $3, $4, $1 } else { printf "%s\t%s\t%s\tNO_NODE\n", $1, $2, $3 } }' |

(
	PENDING_UMOUNT=
	IS_REMOTE=
	umount_one()
	{
		IS_REMOTE=`echo $REMOTE_FSTS $1 | awk '{print index($1, $2)}'`
		if [ -n "$FSType" -a "$FSType" != $1 ]
		then
			return
		fi
		if [ "$LFLAG" = "l" -a $IS_REMOTE -gt 0 ]
		then
			return
		fi
		if [ "$RFLAG" = "r" -a $IS_REMOTE -eq 0 ] 
		then
			return
		fi
		if [ -n "$Host" -a "$Host" != $3 ] 
		then
			return
		fi
		if [ ${kill} ]
		then
			/usr/sbin/fuser -k $2 >/dev/null 2>&1
			PENDING_UMOUNT="${PENDING_UMOUNT} $2"
		else 
			/usr/sbin/umount $2
		fi
	}

	while read dev mountp fstype node
	do
		case "${mountp}" in
		/  | /usr | /var | /proc | '' )
			continue
			;;
		* )
			umount_one $fstype $mountp $node 
			;;	
		esac
	done

	if [ "${PENDING_UMOUNT}" != "" ]
	then
		# allow time for kills to finish from /usr/sbin/fuser
		sleep 10
		for mountp in ${PENDING_UMOUNT}
		do
			/usr/sbin/umount ${mountp}
		done
	fi
)