#!/bin/bash
# 2008-04-10
AUTHOR="tyler@tolaris.com"
NAME="smount"
UNAME="sumount"
VERSION="1.3.4"
DESC="Mount/unmount remote fuse.sshfs filesystems in /tmp/"
# Warning: sanitises username/host input before running sshfs, 
#    but will allow invalid input.
# Warning: assumes /tmp/HOSTNAME is empty or doesn't exist
# Warning: is not multiuser friendly

IFS=' 
	'

die() {
	OUTPUT="$@"
	[ -n "$OUTPUT" ] && printf -- "$OUTPUT\n" >&2
	exit 1
}

CheckPrerequisites() {
	MISSING=""
	for i in "$@" ; do
		type "$i" > /dev/null 2>&1 || MISSING="$i $MISSING"
	done
	if [ -n "$MISSING" ] ; then
		die "Please install: $MISSING"
	fi
}

VersionAndExit() {
	echo "$NAME version $VERSION, by $AUTHOR"
	exit 0
}

UsageAndExit() {
   if [ -n "$2" ] ; then echo -e "$2\n" ; fi
   printf "\
Usage: $NAME [-h|-V] [user@]host ...\n\
       <$NAME -u|$UNAME> [host] [...]\n\
\n\
$DESC\n\
\n\
  -l	list mounted fuse.sshfs filesystems\n\
  -u	unmount host (same as \"$UNAME host\")
        if host not specified, unmount all hosts\n\
  -h	display help\n\
  -V	display version\n\
"
   exit $1
}

# Check prerequisites
CheckPrerequisites sshfs fusermount

# defaults
TEMP=/tmp
RETCODE=0

while getopts ":hValu" options; do
   case $options in
      h ) UsageAndExit 0;;
      V ) VersionAndExit 0;;
      a ) ;;
      l ) STATUSMODE="1";;
      u ) UMOUNTMODE="1";;
      * ) UsageAndExit 1 "Option unknown: -$OPTARG";;
   esac
done

# Clear $@ of switches and grab target list
shift $(($OPTIND - 1))
TARGETLIST=$@

# Implicit unmount mode?
if [ "$UNAME" = `basename "$0"` ] ; then
   UMOUNTMODE="1"
fi

# Unmount all mode?
if [ -n "$UMOUNTMODE" -a -z "$TARGETLIST" ] ; then
   MOUNTPOINTS=`mount -l -t fuse.sshfs | cut -f 3 -d ' '`
   for i in $MOUNTPOINTS ; do
      fusermount -u $i || echo "fusermount $TEMP/$HOST failed."
      if [ "$?" -ne 0 ] ; then
         let $((RETCODE++))
		else
         rmdir $i
      fi
   done
   exit $RETCODE
fi

# Status mode?
if [ -n "$STATUSMODE" -o -z "$TARGETLIST" ] ; then
   mount -l -t fuse.sshfs
   exit 0
fi

# Loop on targets, mounting or unmounting
for TARGET in $TARGETLIST ; do
   
   HOST=`echo "$TARGET" | sed 's/^.*@//;s/[^a-zA-Z0-9.-].*$//'`
   REMOTE_USER=`echo "$TARGET" | grep -o '^.*@' | sed 's/@//'`
   
   if [ -z "$REMOTE_USER" ] ; then
      REMOTE_USER=root
   fi

   # Unmount?
   if [ -n "$UMOUNTMODE" ] ; then
      fusermount -u $TEMP/$HOST
      if [ "$?" -ne 0 ] ; then
         echo "fusermount $TEMP/$HOST failed."
         let $((RETCODE++))
      else
         rmdir $TEMP/$HOST
      fi

   # Or mount?
   else
      if [ ! -d $TEMP/$HOST ] ; then mkdir $TEMP/$HOST ; fi
      sshfs $REMOTE_USER@$HOST:/ $TEMP/$HOST/ 2> /dev/null
      # did sshfs fail?
      if [ "$?" -ne 0 ] ; then
         echo "sshfs to $REMOTE_USER@$HOST failed."
         let $((RETCODE++))
         rmdir $TEMP/$HOST
      fi
   fi
done

exit $RETCODE
