#
# DESCRIPTION:
#
#     mount system media under $MEDIA_MNT
#
# part of the LiveBackup project:  
#
#                     http://livebackup.sourceforge.net/
#
# Copyright 2006-2010 by Wolfgang Rohrmoser <info@rohrmoser-engineering.de>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#


#
# Try to mount if not already mounted, 
# fs and path arguments are optional. 
#
# If path is defined the 
# media is searched for a subdirectory 
# containing the media files
#
# SYNOPSIS:
#             try_mount dev=<dev> fs=[<fs>] path=[<path>]
# 
_try_mount()
{
    if [ "$(is_lb_mounted)" ]; then
        # nothing to do
        return
    fi

    local dev=$(parseopts dev $*)
    local fs=$(parseopts fs $*)
    local path=$(parseopts path $*)

    if [ $LB_DEBUG -gt 2 ]; then
	echo "_try_mount(): dev=$dev fs=$fs path=$path"
    fi

    if [ $fs ]; then
	fs_opt="-t $fs"
    else
	fs_opt=""
    fi

    # check for proper mount options
    test -w /etc/mtab && m_opt="-n"

    #
    # extract filename from path
    #
    file=""
    if [ ! "$(echo $path | grep -e '/$')" ]; then
	test -z "$file" && file=$(echo $path | sed -n 's/^.*\/\(.*\.cloop\).*$/\1/p')
	test -z "$file" && file=$(echo $path | sed -n 's/^.*\/\(.*\.iso\).*$/\1/p')
	test -n "$file" && path=$(echo $path | sed -n 's/\(^.*\)\/\(.*\..*\).*$/\1/p')
    fi

    if [ $LB_DEBUG -gt 2 ]; then
	mount $m_opt -o ro,noatime $fs_opt $dev $MEDIA_MNT 
	mstat=$?
    else
	mount $m_opt -o ro,noatime $fs_opt $dev $MEDIA_MNT > /dev/null 2>&1 
	mstat=$?
    fi

    if [ $mstat -ne 0 ]; then
	if [ $LB_DEBUG -eq 5 ]; then
	    echo "mount failed with exit code:  $mstat, press <return> to continue .."
            read -t 10 ans
	fi
	return
    fi

    if [ "$(is_lb_mounted)" ]; then
        MOUNTED_MEDIA_DEVICE=$dev
        msg -i "system media found on device $dev"
        return
    fi

    if [ $LB_DEBUG -gt 2 ]; then
	echo "_try_mount(): trying with path=$path file=$file"
    fi

    if [ "$(echo $file | grep cloop)" ]; then
	_try_cloopmount $file $path 
    elif [ "$(echo $file | grep iso)" ]; then
	_try_isomount $file $path 
    elif [ "$path" ] && [ -f $MEDIA_MNT/$path/$POLICYFILE ]; then
        mount -n --bind $MEDIA_MNT/$path $MEDIA_MNT
    fi
	    
    if [ $(is_lb_mounted) ]; then
	MOUNTED_MEDIA_DEVICE=$dev 
	msg -i "system media found on device $dev"
    else
	umount $m_opt $MEDIA_MNT > /dev/null 2>&1
    fi
    
}


#
# loop mount of an iso file
# 
_try_isomount()
{
    local f=$2/$1

    test -w /etc/mtab && m_opt="-n"

    if [ $LB_DEBUG -gt 2 ]; then
	echo "_try_isomount()"
	ls -l $MEDIA_MNT/$f
    fi

    if [ ! -f $MEDIA_MNT/$f ]; then
	return
    fi

    mount $m_opt -o ro,loop $MEDIA_MNT/$f $MEDIA_MNT 
    mstat=$?

    if [ $mstat -ne 0 ]; then
	if [ $LB_DEBUG -eq 5 ]; then
	    echo "mount failed with exit code:  $mstat, press <return> to continue .."
            read -t 10 ans
	fi
	return
    fi

    if [ $(is_lb_mounted) ]; then
	msg -i "mounted image file $dev:$MEDIA_MNT/$f"
    else
	umount $m_opt $MEDIA_MNT > /dev/null 2>&1
    fi
}

#
# use a compressed cloop image
# 
_try_cloopmount()
{
    local f=$2/$1

    if [ $LB_DEBUG -gt 2 ]; then
	echo "_try_cloopmount()"
	ls -l $MEDIA_MNT/$f
    fi

    if [ ! -f $MEDIA_MNT/$f ]; then
	return
    fi

    modprobe -v cloop
    losetup /dev/cloop $MEDIA_MNT/$f 
    mount -n -o ro /dev/cloop $MEDIA_MNT 
    mstat=$?

    if [ $mstat -ne 0 ]; then
	if [ $LB_DEBUG -eq 5 ]; then
	    echo "mount failed with exit code:  $mstat, press <return> to continue .."
            read -t 10 ans
	fi
	return
    fi

    if [ $(is_lb_mounted) ]; then
	msg -i "use comressed image file $dev:$MEDIA_MNT/$f"
    else
	umount $m_opt $MEDIA_MNT > /dev/null 2>&1
        losetup -d /dev/cloop
    fi
}


#
# scriplet starts here
#

if [ ! $(is_lb_mounted) ]; then

    msg -i "searching for boot media ...."

    #
    # support for IDE devices
    #
    IDE_DEVICES="/dev/hd*"
    IDE_FS="iso9660"

    #
    # support for SATA devices
    #
    SATA_DEVICES="/dev/sd*"
    SATA_FS="iso9660"

    #
    # support for SCSI CDROM devices
    #
    SCSI_DEVICES="/dev/scd*"
    SCSI_FS="iso9660"

    #
    # usb device support 
    #
    USB_DEVICES=""
    if [ -d /proc/bus/usb ]; then
	mount -n -t usbfs none /proc/bus/usb
	if [ -f /proc/bus/usb/devices ]; then 
	    if [ "$(grep Driver /proc/bus/usb/devices | grep storage)" ]; then 
		USB_DEVICES="/dev/sd*"
		USB_FS="vfat ext2 ext3 iso9660"
	    fi
	fi
    fi

    if [ $LB_DEBUG -gt 2 ]; then 
	msg -e -i "supported filesystems:\n $(cat /proc/filesystems)"
    fi

    #
    # ensure the mount point exists
    # 
    mkdir -p $MEDIA_MNT

    # get commandline args
    if [ "$MEDIADEV" != "not_set" ]; then
	dev=$(echo $MEDIADEV | cut -f 1 -d ':')
        fs=$(echo $MEDIADEV | cut -s -f 2 -d ':')
        path=$(echo $MEDIADEV | cut -s -f 3 -d ':')
    fi

    #
    # try a suggested device first
    #
    if [ "$dev" ]; then
	for i in $(seq 0 3); do
	    if [ ! "$(is_lb_mounted)" ]; then
		msg -i "($i) search $dev $fs $path"
		_try_mount dev=$dev fs=$fs path=$path 
		sleep 3
	    fi
	done
    fi


    #
    # search IDE devices
    #
    for dev in $IDE_DEVICES; do
	for fs in $IDE_FS; do 
	    _try_mount dev=$dev fs=$fs path=$path 
	done
    done
    for dev in $IDE_DEVICES; do
	_try_mount dev=$dev path=$path  
    done

    #
    # search SATA devices
    #
    for dev in $SATA_DEVICES; do
	for fs in $SATA_FS; do 
	    _try_mount dev=$dev fs=$fs path=$path 
	done
    done
    for dev in $SATA_DEVICES; do
	_try_mount dev=$dev path=$path 
    done

    #
    # search SCSI devices
    #
    for dev in $SCSI_DEVICES; do
	for fs in $SCSI_FS; do 
	    _try_mount dev=$dev fs=$fs path=$path 
	done
    done
    for dev in $SCSI_DEVICES; do
	_try_mount dev=$dev path=$path 
    done

    #
    # search USB media
    #
    if [ ! "$(is_lb_mounted)" ] && [ "$USB_DEVICES" ]; then
        msg -i "waiting for usb storage device ..."
        sleep 10
        for dev in $USB_DEVICES; do
            for fs in $USB_FS; do 
                _try_mount dev=$dev fs=$fs path=$path 
            done
        done
        for dev in $USB_DEVICES; do
            _try_mount dev=$dev path=$path 
        done
    fi


    #
    # final check
    #
    while [ ! $(is_lb_mounted) ]; do

	msg -c "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
	msg -c "ERROR: no system media found, stopped ... "
	msg -c "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

	rescue_shell "mount system media under $MEDIA_MNT, boot continues after exit" 

    done


    if [ "$DEVLOCK" = "yes" ] && [ "$MOUNTED_MEDIA_DEVICE" ]; then
        blockdev --setro $MOUNTED_MEDIA_DEVICE
        if [ $? -eq 0 ]; then
            msg -i "$MOUNTED_MEDIA_DEVICE locked ..."
        else
            msg -c "ERROR: failed to lock $MOUNTED_MEDIA_DEVICE"
        fi
    fi


fi


#
# Local Variables: 
# mode: shell-script
# End: 
#
