#!/bin/bash

# $1 is the kernel device name for the partition to be mounted I.E sdb1
# $2 is the kernel number for the partition I.E for $1 == uba1, $2 == 1

# The purpose of this script is to mount the partition passed in $1.

# We check if a partition any OTHER device is already mounted. If so we bail out. 
# I.E 2 USB keys are not supported.

# If there is a partition already mounted on OUR device, we numerically compare the partition
# Number of $2 with the current partition. We aim to mount the highest numerical partition of a 
# Device to give the user consistency; unmounting the current partition to achieve this if necessary.

# By default the kernel will report the partitions in a random order, so the above is necessary for 
# a key with 2 valid vfat partitions, otherwise we could mount a different partition on subsequent
# plug evets.

# All event logs are commented out to improve permformance.
#EventLog=/home/ubuntu/usb_event_log

# This script can be called concurrently from udev with different partitions. An interleave is
# possible where by both script calls decide nothing is currently mounted, and then both proceed to mount
# As we're only looking for one partition to be mounted we must lock the script in critical places.

lock_mount_usb() {
   LOCK_USB_FILE=/home/ubuntu/.usb_lock

   retry=30
   while ! mkdir $LOCK_USB_FILE 2> /dev/null; do
      if [ $retry -eq 0 ]; then
#         echo  "Can't lock $LOCK_USB_FILE" >> $EventLog
         exit 2
      fi
      sleep 1
      retry=$(($retry - 1))
   done
}

unlock_mount_usb() {
   rmdir $LOCK_USB_FILE || true
}

# Log Args.
#echo "Arg1:$1" >> $EventLog
#echo "Arg2:$2" >> $EventLog

# First determine the device the partition belongs to.
Device=`echo $1 | sed "s/[1-9]$//"`
#echo "Device:$Device" >> $EventLog

# We must lock here as 2 calls to the mount below by concurrent interleaving udev worker threads
# will cause 2 partitions to be erroneously mounted.
#echo "Requesting Lock for Partition $1" >> $EventLog
lock_mount_usb
#echo "Lock Aquired For Partition $1" >> $EventLog

# Next Check if anything is already mounted
if [ `mount | grep -c /mnt/usb-storage` != "0" ]; then

   # Get the mount output for OUR Device
   MountOutputForOurDevice=`mount | grep $Device`
#   echo "Mount line for Our Device:$MountOutputForOurDevice" >> $EventLog

   # There was something already mounted, was it on our device ?
   if [ "$MountOutputForOurDevice" != "" ]; then

      # It was on our device, determine current partition number on our device which is mounted.
      PartitionNumber=`echo $MountOutputForOurDevice | sed "s/^.*$Device//;s/ .*$//"`
#     echo "Partition Number $PartitionNumber on Device $Device is already mounted" >> $EventLog

      # Next compare the $2 partition number we're being asked to mount against existing part number.
      if [ $2 -gt $PartitionNumber ]; then
         # We must unmount the existing, as we'll mount the higher $2 below.
         /bin/umount -l /mnt/usb-storage
#         echo "Partition $2 is greater than $PartitionNumber so unmounting now" >> $EventLog
         # The Java is scanning .usbpresent, and could have read $PartitionNumber and parsed it.
         /bin/rm -f /home/ubuntu/.usbpresent
         # Sleep to allow UserSpace to notice
         sleep 1
      # We currently have the highest partition number mounted so ignore this partition.
      else
#         echo "Ignoring $1 as Partition $PartitionNumber on Device $Device is already mounted" >> $EventLog
#	 echo "Releasing Lock for Partition $1" >> $EventLog
         unlock_mount_usb
         exit 0
      fi

   # It was not on our device, so a 2nd USB key has been inserted, ignore it.
   else
#      echo "Ignoring 2nd USB Key on device $Device" >> $EventLog
#      echo "Releasing Lock for Partition $1" >> $EventLog
      unlock_mount_usb 
      exit 0
   fi
fi

# Mount $1
#echo "Mounting $1" >> $EventLog

# Create USB Directory
/bin/mkdir -p /mnt/usb-storage

# Mount USB to that directory on the partition specfiied by udev on %k
/bin/mount  -t vfat -o rw,noauto,users,exec,flush,quiet,nodev,nosuid,noatime,dmask=000,fmask=000,iocharset=utf8,codepage=850 /dev/$1 /mnt/usb-storage

# Create remount Script, this is because the Java umounts and mounts the USB after ops
# and as we now don't use fstab but automount using udev. This allows flexability when
# choosing which partition we're mounting. Old system was always sda1 regardless, now sdb[n]
# where n is the first vfat partition, passed to us as $1 which is %k in udev. 
echo "#!/bin/bash" > /home/ubuntu/.remount_usb
echo "# Remount USB" >> /home/ubuntu/.remount_usb
echo "/bin/umount /mnt/usb-storage" >> /home/ubuntu/.remount_usb
echo "/bin/mount -t vfat -o rw,noauto,users,exec,flush,quiet,nodev,nosuid,noatime,dmask=000,fmask=000,iocharset=utf8,codepage=850 /dev/$1 /mnt/usb-storage" >> /home/ubuntu/.remount_usb
chmod 777 /home/ubuntu/.remount_usb

# Touch .usbpresent
/bin/touch /home/ubuntu/.usbpresent

# Release concurrency lock
#echo "Releasing Lock for Partition $1" >> $EventLog
unlock_mount_usb

# Log Complete
#echo "Mount Complete for Partition $1" >> $EventLog
