#!/bin/sh
#
# mount/unmount script for usb-storage device
#

###################
# USE_SUPERMOUNT:
#	If you don't want to use supermount-ng,
#	Set USE_SUPERMOUNT=no

USE_SUPERMOUNT=yes

#
#functions
#

function allAttachedScsiUsb {
    local cdRom=0
    local nonCd=0

    #wait a few second until /proc updated.
    for (( i=1; i<30; i++ )); do
        if [ ! -e /proc/scsi/scsi ]; then
            sleep 0.1s
        else
            break
        fi
   done


    #determine dev name.
    for procEntry in $(allScsiFromProc) ; do
 
        if echo $procEntry | grep -q -e CD-ROM -e WORM > /dev/null ; then
            scsiDev="/dev/scd"$cdRom
            cdRom=`expr $cdRom + 1`
        elif echo $procEntry | grep -q -e Direct-Access -e Optical > /dev/null ; then
            scsiDev=`echo $nonCd | awk '{ print "/dev/sd" substr("abcdefghijklmnopqrstuvwxyz", $1+1, 1) }'`
            nonCd=`expr $nonCd + 1`
        else
           continue
        fi

        for usbHost in $(attachedUsbHost) ; do
            if echo $procEntry | grep -q $usbHost > /dev/null ; then
                if [ $1 == "WithName" ] ; then
                    for procFile in `find /proc/scsi/ -path '/proc/scsi/usb-storage*/*' -type f `; do
                        if grep -q $usbHost $procFile > /dev/null  ; then
                            #get Product name & translate  unsuitable character to _
                            productName=`grep Product $procFile | cut -b16- | tr " /!~#$%|*?" "_"`
                        fi
                    done

                    #dev name & product name is concatenated in 1 word.(for convinience)
                    echo "$scsiDev:$productName"
                elif [ $1 == "WithoutName" ] ; then
                    echo $scsiDev
                fi
            fi
        done
    done
}

function attachedUsbHost {
    #get usb-scsi host number.
    for procEntry in `find /proc/scsi/ -path '/proc/scsi/*/*' -type f`; do
        hostNum=`grep Host $procEntry | awk '{print $2}' | tr -d ":"`
        if grep -q 'Attached: Yes' $procEntry ; then
            echo $hostNum
        fi
    done
}

function allScsiFromProc {
    #get all scsi  host number.
    hostName=""
    for procInfo in `grep -e Host -e Type  /proc/scsi/scsi | awk '{print $2}'`; do
        #host name & device type is concatenated in 1 word.(for convinience)
        if echo $procInfo | grep -q scsi > /dev/null ; then
            hostName=$procInfo
        else
            echo $hostName":"$procInfo
            hostName=""
        fi
    done
}

function allPartFromFdisk {
    #fdisk sometimes take a few seconds to get disk info.
    sleep 0.5s
    /sbin/fdisk -l $1 | awk '{print $1}' | grep "/dev/"
}

function usbMountDevFromFstab {
    #extract supermount device
    grep usb-mount /etc/fstab | grep supermount | awk '{print $4}' | \
        awk -F"[,]" '{ sub("dev=","",$1); print $1}'

    #extract non-supermount device
    grep usb-mount /etc/fstab | grep -v supermount | awk '{print $1}'
}

function ckMountable {
    if [ ! -e /tmp/ckmount ]; then
        mkdir -p /tmp/ckmount
    fi
    #temporaryly mount for check mountable
    if mount $1 /tmp/ckmount; then
        umount /tmp/ckmount
        return 0
    else
        return 1
    fi
}

function autoMountSingle {
    local mountDev=`echo $1 | awk -F "/" '{print $3}'`
    local mountPoint="/mnt/""$2""-$mountDev"

    #check actualy mountable or not.
    if [ "$3" != "NoCheck" ]; then
        if ! ckMountable $1; then
            return 1
        fi 
    fi 

    #create mount dir if not exist
    if [ ! -e $mountPoint ]; then
        mkdir -p $mountPoint
    fi

    #add an fstab entry
    case "$USE_SUPERMOUNT" in
        yes|Yes|YES)
            echo -e \
            "none\t""$mountPoint""\tsupermount\t""dev=$1"",fs=ext2:vfat:iso9660:udf,defaults,users\t0 0\t""usb-mount" \
            >> /etc/fstab;
        ;;
        no|No|NO)
            echo -e \
            "$1\t""$mountPoint\t""auto\t""defaults,users\t""0 0\t""usb-mount" \
            >> /etc/fstab;
        ;;
    esac

    mount $mountPoint
}

function autoMountMulti {
    for scsiPart in $(allPartFromFdisk $1); do
    
        local mountDev=`echo $scsiPart | awk -F "/" '{print $3}'`
        local mountPoint="/mnt/""$2""-$mountDev"

        #check actualy mountable or not.
        if ! ckMountable $scsiPart; then
            continue
        fi 

        #create mount dir if not exist.
        if [ ! -e $mountPoint ]; then
            mkdir -p $mountPoint
        fi

        #add an fstab entry
        case "$USE_SUPERMOUNT" in
            yes|Yes|YES)
                echo -e \
                "none\t""$mountPoint""\tsupermount\t""dev=$scsiPart"",fs=ext2:vfat:iso9660:udf,defaults,users\t0 0\t""usb-mount" \
                >> /etc/.fstab.tmp;
            ;;
            no|No|NO)
                echo -e \
                "$scsiPart\t""$mountPoint\t""auto\t""defaults,users\t""0 0\t""usb-mount" \
                >> /etc/.fstab.tmp;
            ;;
        esac
    done

    if [ -e /etc/.fstab.tmp ]; then
        cat /etc/.fstab.tmp >> /etc/fstab

        for mountTmp in `cat /etc/.fstab.tmp | awk '{print $2}'`; do
            mount $mountTmp
        done

        rm -f /etc/.fstab.tmp
    fi
}

#
# main
#


if [ "$ACTION" = "add" ]; then
    for devInfo in $(allAttachedScsiUsb WithName); do
        #separate return value
        scsiDev=`echo $devInfo | awk -F ":" '{ print $1 }'`
        productName=`echo $devInfo | awk -F ":" '{ print $2 }'`
        
        #if device already exist in fstab or already mount,do nothing.
        if ! grep -q "$scsiDev" /proc/mounts && ! grep -q "$scsiDev" /etc/fstab; then
            if [ "$(allPartFromFdisk $scsiDev)" == "" ]; then
                #try to mount whole disk.(may be "superfloppy" formated)
                autoMountSingle $scsiDev $productName
            else
                #try to mount each partitions.
                autoMountMulti $scsiDev $productName
            fi

            #if All mount was fail, finaly mount whole disk.
            #(This is useful for removable media like flpppy disk.)
            if ! grep -q "$scsiDev" /proc/mounts; then
                autoMountSingle $scsiDev $productName NoCheck
            fi
        fi
    done

elif [ "$ACTION" = "remove" ]; then
    for fstabEntry in $(usbMountDevFromFstab); do
        devInfo=$(allAttachedScsiUsb WithoutName)
        if ! echo "$fstabEntry" | grep -q "$devInfo" || [ "$devInfo" == "" ] ; then
            mountPoint=`grep "$fstabEntry" /etc/fstab | awk '{print $2}'`
            umount -l $mountPoint

            #erase /etc/fstab entry.
            grep -v "$fstabEntry" /etc/fstab > /etc/.fstab.new
            mv -f /etc/.fstab.new /etc/fstab

            #delete mount point.
            if [ -e $mountPoint ]; then
                rmdir $mountPoint
            fi
        fi
    done
fi

