#!/bin/sh
#
# Automount hotplugged block devices, by Wout Mertens (wmertens@gentoo.org)
#
#
Linux v2.6 version
# This script is released under version 2 of the GPL.
# To install this, either make it /sbin/hotplug, or, if you have
# linux-hotplug installed, make it /etc/hotplug.d/block/automount.hotplug .
# It needs to be executable. I tested it with busybox's ash.
#
# The devices will be mounted for the console user if applicable.
#
# To work, this needs:
# - v2.6 kernel support:
# - hotplugging, /proc mounted, /sys mounted
# - filesystems that will be mounted, like vfat
# - sh, echo, sed, stat or ls, getent or grep passwd,
# mount, umount, mkdir, rmdir. logger is used if there.
#
# Possible improvements:
# - Call a notifier script when mounting/unmounting. This could create the
# desktop entry by itself.
# - Edit fstab instead, and give the "user" option. This depends more on
# the user/desktop knowing what he/it is doing.
# Changelog:
#
# - 2005-03-26 Mark Burazin (mark@burazin.net)
# - Multiple partitions are now correctly created as separate icons
#
# - 2005-03-20 Mark Burazin (mark@burazin.net)
# - Creation of desktop entry under /home/(current user)/Desktop
# - use supermount and subfs successfuly.
# - Solve bug where sometimes the icons were not deleted (problem was in spaces
# which were in some names eg. "JUMPDRIVE " -> "JUMPDRIVE")
# - Another issue of the delete bug is when the usb is quicker and we don't
# know the device name. There is a solution, but You must uncomment the "usbbug" line
# - allow a definition for using diffrent icons for diffrent drives check the
# PRODUCTS_* variables.
# Debugging
# set -xv
# exec > /tmp/hotplug.$$ 2>&1
# Configuration
ICON_PATH=/usr/kde/3.3/share/icons/default.kde/scalable/devices
PATH="/bin:/sbin:/usr/bin:/usr/sbin"
export PATH
# We only handle block device messages
[ "$1" != "block" ] && exit 0
# Proclaim stuff to the world
mesg () {
logger -t $0 "$*"
}
# Is path already mounted?
is_path_mounted () {
while read dev path rest
do
if [ "$path" = "$1" ]
then
return 0
fi
done < /proc/self/mounts
return 1
}
# Get mounted path for a device
get_mounted_path () {
while read dev path rest
do
if [ "$dev" = "$1" ]
then
echo "$path"
return 0
fi
done < /proc/self/mounts
return 1
}
get_product_info () {
# Here You can setup which are the default
# icons
ICON_HDD=hdd_mount.svgz
ICON_USBPENDRIVE=usbpendrive_mount.svgz
ICON_DEFAULT=$ICON_USBPENDRIVE
# And which icons to assign to which product id's, joust remove
# spaces from the name eg. "SOME USB DRIVE" -> "SOMEUSBDRIVE"
# and leave it surrounded by ":"
PRODUCTS_USBPENDRIVE=":JUMPDRIVE:"
PRODUCTS_HDD=":B200P0:24320:USBMSReader:USBCFReade r:"
# Find the name
PRODUCT=`cat /sys/$1/$2/device/model`
if [ -z "$PRODUCT" ]
then
PRODUCT=generic
else
PRODUCT=`echo $PRODUCT | sed 's/ //g'`
fi
# Find the vendor
VENDOR=`cat /sys/$1/$2/device/vendor`
if [ -z "$VENDOR" ]
then
VENDOR=vendor
else
VENDOR=`echo $VENDOR | sed 's/ //g'`
VENDOR=`echo $VENDOR | sed 's/-//g'`
fi
# Find out who we are going to mount it as
CONSOLEUSER=`stat -c%U /dev/console 2>/dev/null`
if [ -z "$CONSOLEUSER" ]
then
set `ls -l /dev/console`
CONSOLEUSER=$3
fi
[ -n "$CONSOLEUSER" ] || CONSOLEUSER=root
PASSWD=`getent passwd $CONSOLEUSER 2>/dev/null`
if [ -z "$PASSWD" ]
then
PASSWD=`grep "$CONSOLEUSER" /etc/passwd||grep root /etc/passwd`
fi
if [ -z "$PASSWD" ]
then
mesg "Could not get password entry for $CONSOLEUSER"
exit 1
fi
set `echo $PASSWD | sed 's/:/ /g'`
if [ $# -lt 4 ]
then
mesg "Bad password entry for $CONSOLEUSER"
exit 1
fi
USERID=$3
USERGID=$4
# if we have a quick usb unplug (can't determine product)
# then we need to find the icons by device and delete them.
if [ "$ACTION" = "remove" && $PRODUCT = "generic" ]
then
set `grep -l -e"$DEVICE" /home/$CONSOLEUSER/Desktop/*.desktop`
if [ $# -lt 1 ]
then
# this solves the usbbug, uncomment to allow this feature, but be careful
mesg "Deleting stale icon...$#"
rm /home/$CONSOLEUSER/Desktop/$#.desktop
fi
fi
#uncomment this so You can see the name for PRODUCTS_* variables
#mesg "Searching for product: ->$PRODUCT<-"
# Find the icon type
if [ ! -z `echo $PRODUCTS_USBPENDRIVE | grep -e:$PRODUCT:` ]
then
ICON_USE=$ICON_USBPENDRIVE
elif [ ! -z `echo $PRODUCTS_HDD | grep -e:$PRODUCT:` ]
then
ICON_USE=$ICON_HDD
else
ICON_USE=$ICON_DEFAULT
fi
}
# Wait for a file to appear
wait_for () {
local count=0
while [ $count -lt 10 ] && [ ! -e "$1" ]
do
sleep 1
done
[ $count -eq 10 ] && return 1
return 0
}
# Remove strange characters from a filename
clean_filename () {
# Note the lack of quotes around $1, this strips off spaces.
echo $1 | sed 's/[ /?*\"<>]/_/g'
}
# Figure out the device to mount
set `echo $DEVPATH | sed 's/\// /g'`
[ $# -ne 3 ] && exit 0
DEVICE=/dev/$3
if [ "$ACTION" = "remove" ]
then
# Is it ours?
dir=`get_mounted_path $DEVICE`
echo "$dir" | grep -q ^/mnt/usb || exit 0
get_product_info $1 $2 $ACTION $DEVICE
# Unmount it
[ -d "$dir" ] || exit 1
umount -lf "$dir"
rmdir "$dir"
# remove the desktop icon
mesg Unmounting $DEVICE, $dir $PRODUCT for user $CONSOLEUSER
SDEV=`echo $DEVICE | sed 's/\///g'`
rm "/home/$CONSOLEUSER/Desktop/$SDEV.desktop"
exit 1
fi
if [ "$ACTION" = "add" ]
then
# Is it a usb device? Exit if not.
ls -l /sys/$1/$2/device | sed 's/^.* -> //g' | grep -q usb || exit 0
# Mount it
# Make sure we have support for vfat
modprobe -q vfat
wait_for /sys/$1/$2/device/vendor || exit 1
get_product_info $1 $2 $ACTION
# Find out where we mount it
MOUNTPATH=/mnt/usb/`clean_filename "$PRODUCT"`
if is_path_mounted "$MOUNTPATH"
then
count=1
while is_path_mounted "${MOUNTPATH}_${count}"
do
count=$(( $count + 1 ))
done
MOUNTPATH="${MOUNTPATH}_${count}"
PRODUCT="${PRODUCT}_${count}"
fi
# Make sure it's a directory
if [ -e "$MOUNTPATH" ]
then
if [ ! -d "$MOUNTPATH" ]
then
mesg "$MOUNTPATH exists but is not a directory"
exit 1
fi
else
mkdir -p "$MOUNTPATH"
if [ $? -ne 0 ]
then
mesg "Could not create mountpoint $MOUNTPATH"
exit 1
fi
fi
# These options should prevent abuse and make it writeable for the
# console user.
if grep -q subfs /proc/filesystems
then
MOUNTOPTS="-s -t subfs -o fs=vfat:ext3:ext2:reiserfs,noatime,nosuid,umask=07 7,uid=$USERID,gid=$USERGID"
elif grep -q supermount /proc/filesystems
then
MOUNTOPTS="-s -t supermount -onoatime,nosuid,umask=077,uid=$USERID,gid=$USERGID "
else
#MOUNTOPTS="-s -onoatime,sync,dirsync,nosuid,umask=077,uid=$3,gid= $4"
MOUNTOPTS="-s -onoatime,sync,user,exec,umask=0000"
fi
mesg Mounting $DEVICE on $MOUNTPATH, options $MOUNTOPTS $ICON_USE
mount $MOUNTOPTS $DEVICE $MOUNTPATH
# Everything was mounted fine, create a Desktop icon
SDEV=`echo $DEVICE | sed 's/\///g'`
OUTPUTFILE="/home/$CONSOLEUSER/Desktop/$SDEV.desktop"
echo "[Desktop Entry]" > $OUTPUTFILE
echo "Version=1.0" >> $OUTPUTFILE
echo "Name=$VENDOR $PRODUCT" >> $OUTPUTFILE
echo "Encoding=UTF-8" >> $OUTPUTFILE
echo "Type=Link" >> $OUTPUTFILE
echo "URL=$MOUNTPATH" >> $OUTPUTFILE
echo "Dev=$DEVICE" >> $OUTPUTFILE
echo "Icon=$ICON_PATH/$ICON_USE" >> $OUTPUTFILE
chmod 777 $OUTPUTFILE
chown $CONSOLEUSER $OUTPUTFILE
chgrp users $OUTPUTFILE
fi
exit
Bookmarks