#!/bin/sh
#
# Called from udev
#
# Attempt to mount any added block devices and umount any removed devices
#
#
# Adapted for Infomir/MAG520-RDK 2021-07-28

. /etc/utils/shell-utils.sh
DEBUG=0

MOUNTS_CACHE="/ram/mounts.cache"
QT_SEND_EVENT="/usr/local/share/app/bin/sendqtevent"
SATA_DEV="null"
MEDIA_TYPE="0"
DEV_PATH_ATTR_NAME="devPath"

MEDIA_TYPE_SD="3"
MEDIA_TYPE_MMC="4"

NTFSLABEL_PROG="/bin/true"
BLKID_PROG="/sbin/blkid"
VAR_FORCE_RO="mount_media_ro"

UDEVADM_BIN="/bin/udevadm"


MOUNT="/bin/mount"
PMOUNT="/usr/bin/pmount"
UMOUNT="/bin/umount"

ACTION=$1
# DEVPATH value is base64 encoded (see UDEV rule, as well as task rm#36204). So, it should be decoded to be used properly
DEVPATH=$(echo "$2" | base64 -d)

udev_db=$($UDEVADM_BIN info -q property -p $DEVPATH)
udev_read_property() {
    eval `echo $udev_db | tr ' ' '\n' | grep $1=`
}

udev_read_property DEVNAME
udev_read_property DEVTYPE
udev_read_property ID_SERIAL_SHORT
if [ "$ID_SERIAL_SHORT" == "" ]; then
    ID_SERIAL_SHORT="UNASSIGNED"
fi
udev_read_property ID_FS_TYPE
udev_read_property ID_VENDOR
udev_read_property ID_MODEL
udev_read_property ID_PART_ENTRY_NUMBER

getCodePageCurrent(){
    currLang=$(read_nvram_var "language")
    case ${currLang} in
        "de")
            echo -n "850"
        ;;
        "ru")
	    log "using cp 866..."
            echo -n "866"
        ;;
        *)
	    log "using default cp 866..."
            echo -n "866"
        ;;
    esac
}

getDiskLabel() {
    diskOfInterest="/dev/${1}"
    #echo "diskOfInterest = '${diskOfInterest}'"
    case ${2} in
        "ntfs")
            ${NTFSLABEL_PROG} -nf ${diskOfInterest} 2>/dev/null
        ;;
        "ext2")
        ;;
        "ext3")
        ;;
        "ext4")
        ;;
        "vfat")
	        ${BLKID_PROG} -c /ram/blkid.tab ${diskOfInterest} | /root/bin/iconv -f $(getCodePageCurrent) -t utf8 | sed -n 's/^.*LABEL="\([^"]*\).*/\1/gp'
        ;;
        *)
    	    echo -n "UNKNOWN"
        ;;
    esac
}

getFsTypeIndex() {
    case ${1} in
        "ntfs")
            echo -n "5"
        ;;
        "ext2")
            echo -n "3"
        ;;
        "ext3")
            echo -n "4"
        ;;
        "ext4")
            echo -n "6"
        ;;
        "vfat")
            echo -n "2"
        ;;
        *)
            echo -n "0"
        ;;
    esac
}

doUnmount()
{
    log "[+] UNMOUNT DEVICE (DEVPATH: '${DEVPATH}')"

    MOUNT_POINT=$(getMountPointByDevPath ${DEVPATH})

    if [ -n "${MOUNT_POINT}" ] && [ -d "${MOUNT_POINT}" ]; then
        log "[+] Un-mounting '${MOUNT_POINT}'..."
        $UMOUNT -l "${MOUNT_POINT}"
        log "[+] Removing '${MOUNT_POINT}'..."
        rmdir "${MOUNT_POINT}"
        log "[+] Removing database record for this device"
        excludeByDevPath ${MOUNTS_CACHE} ${DEVPATH}
        log "[+] Send event to Application"
        ${QT_SEND_EVENT} -a -ks 0x71 -kqt 0x51
    fi
}

doMount() 
{
    log "[+] MOUNT DEVICE (DEVPATH: '${DEVPATH}')"

    # useful UDEV env IDs: ID_FS_VERSION, ID_FS_USAGE, ID_PART_ENTRY_UUID, ID_PART_ENTRY_NUMBER
    # log "DEVNAME: ${DEVNAME}, DEV_NAME: ${DEV_NAME}, DEVTYPE: ${DEVTYPE}, ID_FS_TYPE: ${ID_FS_TYPE}, ID_FS_LABEL: ${ID_FS_LABEL}, ID_SERIAL_SHORT: ${ID_SERIAL_SHORT}, ID_PART_ENTRY_NUMBER: ${ID_PART_ENTRY_NUMBER}, ID_VENDOR: ${ID_VENDOR}, ID_MODEL: ${ID_MODEL}, DEVPATH: ${DEVPATH}"

    if [[ "${DEVTYPE}" != "partition" ]]; then
        log "[i] We only want to mount devices of 'partition' type. Abort automount"
        return
    fi
	
    if [ "${ID_FS_TYPE}" == "" ]; then
    log "[!] ID_FS_TYPE is empty! Abort automount"
    exit -1
    fi

    fstype=${ID_FS_TYPE}
    fsTypeIndex=$(getFsTypeIndex ${ID_FS_TYPE})
    if [ "${fsTypeIndex}" == "0" ]; then
    log "[!] ID_FS_TYPE is unknown! Abort automount"
    exit -1
    fi

    size=$(cat /sys${DEVPATH}/size 2> /dev/null)
    if [ -z "${size}" ]; then
        log "[!] Unable to get size! Abort automount"
        return
    fi
    size=$(( size * 512 ));

    # count "entire disk" as single partition number 0
    if [ "$ID_PART_ENTRY_NUMBER" == "" ]; then
        ID_PART_ENTRY_NUMBER="0"
    fi

    # this name will be used for mount point
    FULL_NAME="USB-${ID_SERIAL_SHORT}-${ID_PART_ENTRY_NUMBER}"

    # handle SD cards
    if [ -n "`echo ${DEV_NAME} | sed -n 's/^\(mmc\).*$/\1/pg'`" ]; 
    then 
        MEDIA_TYPE=${MEDIA_TYPE_SD}
        FULL_NAME="SD-${ID_SERIAL_SHORT}-${ID_PART_ENTRY_NUMBER}"
        if [ "$ID_MODEL" == "" ] && [ "$ID_VENDOR" == "" ] ; then
            ID_MODEL="SD Card"
        fi
    else 
        if [ "$ID_SERIAL_SHORT" == "UNASSIGNED" ]; then
            FULL_NAME="HDD-SATA-${ID_PART_ENTRY_NUMBER}"
            ID_SERIAL_SHORT="HDD-SATA-${ID_PART_ENTRY_NUMBER}"
            MEDIA_TYPE="1"
        else
            MEDIA_TYPE="2"
        fi
    fi


    FOLDER_TO_CREATE="/media/${FULL_NAME}"

    # clean old mounts
    excludeByDevPath ${MOUNTS_CACHE} ${DEVPATH}
    while [ 1 ]; 
    do 
        $UMOUNT -l $FOLDER_TO_CREATE 2>/dev/null 
        if [ $? != 0 ]; 
            then break; 
        fi 
    done

    if [ ! -f "$FOLDER_TO_CREATE" ]; then
        log "[+] Creating mount point '$FOLDER_TO_CREATE'..."
        mkdir "$FOLDER_TO_CREATE"
    fi

    IS_READ_ONLY="0"
    EXTRA_OPT="noatime,nodiratime"

    # check for force RO mode
    isRO=$(read_nvram_var $VAR_FORCE_RO)
    if [ "$isRO" == "true" ]; then
        MOUNT_OPT="ro";
    else 
        MOUNT_OPT="rw";
    fi

    case $fstype in
        "ntfs")
            DEV_MODEL=`$RDIR_APP Model`
            log "/bin/ntfs-3g -o iocharset=utf8,$EXTRA_OPT $DEVNAME \"$FOLDER_TO_CREATE\""
            /bin/ntfs-3g -o iocharset=utf8,$EXTRA_OPT $DEVNAME "$FOLDER_TO_CREATE"
            #IS_READ_ONLY="1"
        ;;
        "ext2")
            log "$MOUNT -o $MOUNT_OPT,$EXTRA_OPT $DEVNAME \"$FOLDER_TO_CREATE\""
            $MOUNT -o $MOUNT_OPT,$EXTRA_OPT $DEVNAME "$FOLDER_TO_CREATE"
        ;;
        "ext3")
            $MOUNT -o $MOUNT_OPT,$EXTRA_OPT $DEVNAME "$FOLDER_TO_CREATE"
        ;;
        "vfat")
            log "mount -o $MOUNT_OPT,iocharset=utf8,$EXTRA_OPT $DEVNAME \"$FOLDER_TO_CREATE\""
            $MOUNT -o $MOUNT_OPT,iocharset=utf8,$EXTRA_OPT $DEVNAME "$FOLDER_TO_CREATE"
        ;;
        *)
            log "$MOUNT -o $MOUNT_OPT,$EXTRA_OPT $DEVNAME \"$FOLDER_TO_CREATE\""
            $MOUNT -o $MOUNT_OPT,$EXTRA_OPT $DEVNAME "$FOLDER_TO_CREATE"
        ;;
    esac
    # check for mount error code
    RET=$?
    if [ "$RET" != "0" ]; then
        log "mount error! removing mount point..."
        rmdir "$FOLDER_TO_CREATE"
        exit -1
    fi
    log "Device mounted OK"

    freeSize=`df -k | grep /ram/media/$FULL_NAME | awk '{print $4}'`
    if [ -z "${freeSize}" ]; then
        freeSize=0
    else
        freeSize=$((${freeSize}*1024))
    fi

    READ_ONLY_STATUS=`$MOUNT | grep /ram/media/$FULL_NAME | sed -n "s/^.*(\(rw\).*$/\1/p"`
    log "READ_ONLY_STATUS=${READ_ONLY_STATUS}"
    if [ "${READ_ONLY_STATUS}" = "rw" ]; then
        IS_READ_ONLY="0"
    else
        IS_READ_ONLY="1"
    fi

    log "[+] Creating database record for this device"
    echo "key:${FULL_NAME}:{\"sn\":\"${ID_SERIAL_SHORT}\",\"vendor\":\"${ID_VENDOR}\",\"model\":\"${ID_MODEL}\",\"size\":${size},\"freeSize\":${freeSize},\"label\":\"${label}\",\"partitionNum\":${ID_PART_ENTRY_NUMBER},\"isReadOnly\":${IS_READ_ONLY},\"mountPath\":\"${FOLDER_TO_CREATE}\",\"mediaType\":${MEDIA_TYPE},\"fsType\":${fsTypeIndex},\"${DEV_PATH_ATTR_NAME}\":\"${DEVPATH}\"}" >> $MOUNTS_CACHE

    log "[+] Send event to Application"
    ${QT_SEND_EVENT} -a -ks 0x70 -kqt 0x50
}

# EXECUTION POINT

DEV_NAME="`basename "$DEVNAME"`"

if [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && [ -n "$ID_FS_TYPE" -o "$media_type" = "cdrom" ]; then
    doMount
fi

if [ "$ACTION" = "remove" ] || [ "$ACTION" = "change" ] && [ -x "$UMOUNT" ]; then
    doUnmount
fi
