#!/bin/sh

# Mounts and explores pendrives
#
# Based on Eko M. Budi's excellent script, copyright 2004
# Extensions and refinements by Hanu-mizzle, 2005
#
# License: GNU GPL

MNT_USB_STORAGE=/mnt/usb-storage

# Check for existing usb-mount points, which we will prefer
if mount | grep -q "^.* on $MNT_USB_STORAGE"; then
  echo "usb-mount handled it, exploring..."
  for DIR in $(ls $MNT_USB_STORAGE); do
    explorer $MNT_USB_STORAGE/$DIR &
  done
  exit 0
fi

# Load modules if necessary and wait for them to register
if ! /sbin/lsmod | grep -q "^usb_storage"; then
  /sbin/modprobe usb-storage &> /dev/null
  WAIT=yes
fi
if ! /sbin/lsmod | grep -q "^sg"; then
  /sbin/modprobe sg &> /dev/null
  WAIT=yes
fi

# Wait for new modules to register
if [ $WAIT ]; then
  sleep 5
fi

# Determine user through ownership of console
USB_USER=$(ls -l /dev/console | perl -nlae 'print $F[2];')
# This should work OK
USB_GROUP=users

# If we are running a 2.6 series kernel, we can take advantage of the dmask
# option to mount. Otherwise we have to settle for just umask. Boo!
case $(uname -r) in
  2.6*) MASK="umask=117,dmask=007" ;;
  *) MASK="umask=007" ;;
esac

# Options for all file systems
OPT_COMMON="sync,dirsync"
# Options for all MS file systems; file systems like FAT have to be
# assimilated to Unix style permissions with these options
OPT_WIN="uid=$USB_USER,gid=$USB_GROUP,$MASK"

# This function determines the options that need to be passed to mount
# for a given device
mount_options () {
  local FS=`sudo disktype $1 | \
            grep -m 1 "file system" | \
            perl -nlae 'print $F[0];'`
  case $FS in
    Ext2)
      MOUNT_OPTIONS="-t ext2 -o noatime,$OPT_COMMON" ;;
    Ext3)
      MOUNT_OPTIONS="-t ext3 -o noatime,$OPT_COMMON" ;;
    ReiserFS)
      MOUNT_OPTIONS="-t reiserfs -o noatime,$OPT_COMMON" ;;
    NTFS)
      MOUNT_OPTIONS="-t ntfs -o quiet,noatime,$OPT_WIN,$OPT_COMMON" ;;
    FAT16|FAT32)
      MOUNT_OPTIONS="-t vfat -o shortname=mixed,quiet,noatime,$OPT_WIN,$OPT_COMMON" ;;
    "")
      echo "Something is wrong with this partition!"
      return 1 ;;
    *)
      # Assume FAT filesystem
      MOUNT_OPTIONS="-t vfat -o shortname=mixed,quiet,noatime,$OPT_WIN,$OPT_COMMON" ;;
  esac
}

# Find all devices that are usb-storage. If there are none, then the script
# quits after notifying the user of this condition. The way this works is by
# finding all the SCSI hosts which are in /proc/scsi/usb-storage. Then the
# devices are found by association through the use of sg_map, whose output
# looks like this:

# /dev/sg0  3 0 0 0  0  /dev/sda
# /dev/sg1  4 0 0 0  0  /dev/sdb

# Where the second field is the virtual host (each mass storage device has
# its own) and the last field is the device. I ASSume there is only one
# partition on the device, which is probably true 99.9999% of the time. This
# was also the behavior of the old script, so I'm not going to make things
# needlessly complicated

# The old version used the output of dmesg. It was really ugly. :D

DEVS=$(sudo /usr/bin/sg_map -x | \
       perl -nlae 'print "$F[$#F]1" if -f "/proc/scsi/usb-storage/$F[1]"');

if [ ! "$DEVS" ]; then
  echo "No pendrives found"
  message "ERROR" "No pendrives found"
else
  # Mount each device
  for DEV in $DEVS; do
    # This is if the device is already mounted; the loop continues to the next
    # device
    if mount | grep -q "^$DEV"; then
      continue;
    fi
    # This function will set the variable MOUNT_OPTIONS globally. I really
    # wish functions could return strings. What a hack :evil:
    mount_options $DEV
    # Export the options so that they apply to each subshell
    export MOUNT_OPTIONS
    # Export DEV to each subshell as well
    export DEV
    # This tells the subshell where to mount an individual drive
    export MOUNT_ID=$(sudo /usr/X11/bin/mkpdmount);
    # Here the subshell is run. Because it runs in the background,
    # multiple flash drives can be used, and their associated
    # explorer can be closed out
    (sudo /bin/mount $DEV $MOUNT_ID $MOUNT_OPTIONS &&
     explorer $MOUNT_ID &&
     sudo /bin/umount $MOUNT_ID &&
     sudo /usr/X11/bin/rmpdmount $MOUNT_ID) &
  done
fi

exit 0
