#! /bin/sh
#
# mountvirtfs	Mount all the virtual filesystems the kernel
#		provides and that are required by default.
#
#		This script can be called several times without
#		damage; it tries to mount the virtual filesystems
#		only if not mounted yet, and only updates /etc/mtab
#		if it is writable and there is a need.
#
# Version:	@(#)mountvirtfs  2.85-12  21-Mar-2004  miquels
#

set -e

PATH=/lib/init:/bin:/sbin

. /etc/default/devpts
. /etc/default/tmpfs

dir_writable () {
	if [ -d "$1/" ] && [ -w "$1/" ] && touch -a "$1/" 2>/dev/null
	then
		return 0
	fi
	return 1
}

domount () {

	# Do we support this filesystem type ?
	TYPE=
	if [ $1 = proc ]
	then
		TYPE=proc
	elif egrep -qs "$1\$" /proc/filesystems
	then
		TYPE=$1
	elif egrep -qs "$2\$" /proc/filesystems
	then
		TYPE=$2
	fi
	if [ "$TYPE" = "" ]
	then
		return
	fi

	# Try to create directory.
	parent=${3%/*}
	if [ ! -d $3 ] && dir_writable $parent
	then
		mkdir $3
	fi

	# See if anything is mounted yet
	if ! mountpoint -q $3
	then
		# No, do it now
		mount $MOUNT_N -t $TYPE $4 $TYPE $3
	else
		# Need to update mtab only ?
		if [ -n "$DO_MTAB" ] &&
		   ! egrep -sq "^([^ ]+) +$3 +" /etc/mtab
		then
				mount -f -t $TYPE $4 $TYPE $3
		fi
	fi
}

#
#	We only create/modify /etc/mtab if the location where it is
#	stored is writable.  If /etc/mtab is a symlink into /proc/
#	then it is not writable.
#
DO_MTAB=
MOUNT_N=-n
MTAB_PATH="`readlink -f /etc/mtab || :`"
case "$MTAB_PATH" in
	/proc/*)
		;;
	/*)
		if dir_writable ${MTAB_PATH%/*}
		then
			DO_MTAB=Yes
			MOUNT_N=
		fi
		;;
esac

if [ -n "$DO_MTAB" ] && [ ! -f /etc/mtab ]
then
	:> /etc/mtab
fi

# Mount standard /proc and /sys.
domount proc "" /proc
domount sysfs "" /sys

# Mount /dev/pts. Create master ptmx node if needed.
if dir_writable /dev && [ ! -c /dev/ptmx ]
then
	mknod --mode=666 /dev/ptmx c 5 2
fi
domount devpts "" /dev/pts -ogid=$TTYGRP,mode=$TTYMODE

# Mount tmpfs (formerly shmfs).
if [ -n "$TMPFS_SIZE" ]
then
	tmpfs_opt="-osize=${TMPFS_SIZE}"
fi
domount tmpfs shmfs /dev/shm $tmpfs_opt

# Mount usbfs/usbdevfs if /proc/bus/usb is present.
if [ -d /proc/bus/usb ]
then
	domount usbfs usbdevfs /proc/bus/usb
fi

