#!/bin/sh # Automount hotplugged usb storage devices. Copyright (c) 2002, Wout Mertens # This script is released under the GPL. # The usb devices will be mounted for the console user. # To work, this needs: # - kernel support: # - hotplugging, /proc, usbdevfs and devfs # - as modules: usb-storage, sd_mod, scsi_mod # - filesystems that will be mounted, like vfat # - ls, tr, echo, awk, basename, stat, grep, mount, umount, mkdir, rm, sed # TODO Fix usb.agent so that /var/run/usb gets created if missing # TODO Some rigid way of getting this run. Currently, I do # grep usb-storage /lib/modules/*/modules.usbmap|sed 's/usb-storage/automount_usb/' >> /etc/hotplug/usb.usermap # TODO Lots of testing # TODO nice way of setting options # TODO Also, the error checking should probably be more robust # TODO Some clean way of handling disconnects while writing. # TODO Make a generic event system for GUIs that shows that something was # mounted for the user. Proposal: /etc/hotplug/gui.agent gets # called with ACTION=add/remove, NAME=nice_name, PATH=new_path, etc. # Not just for new storage, scanners and so on are useful too... # Dump debug mesg () { #return /usr/bin/logger -t $0 "$*" } # Figure out the device to mount NUM=`basename $DEVICE|sed 's/^0*//'` SERIAL=`awk -F= '/^T:.*/{if($0~/Dev#= *'$NUM' /){t=1}else{t=0}}t==1&&/SerialNumber/{print $2;exit}' /proc/bus/usb/devices` PRODUCT=`awk -F= '/^T:.*/{if($0~/Dev#= *'$NUM' /){t=1}else{t=0}}t==1&&/Product/{print $2;exit}' /proc/bus/usb/devices` # Use the serial or the product name to find which scsi host was just created if [ -n "$SERIAL" ]; then SCSI=`grep -l $SERIAL /proc/scsi/usb-storage-*/*|tail -1` elif [ -n "$PRODUCT" ]; then SCSI=`grep -l $PRODUCT /proc/scsi/usb-storage-*/*|tail -1` fi mesg Device No. $NUM, serial $SERIAL, name $PRODUCT, path $SCSI # Mount it if [ -n "$SCSI" ]; then # The name of the file is the number of the SCSI host SCSI=`basename $SCSI` PARTS=`ls /dev/scsi/host$SCSI/*/*/*/part*` MOUNTPATH=/mnt/usb/`echo $PRODUCT|tr '[ /?*"]' _` if [ -e "$MOUNTPATH" ]; then if mount|grep "$MOUNTPATH">/dev/null; then # TODO I'm too lazy to write proper collision avoidance code MOUNTPATH="$MOUNTPATH".$$ fi fi # I'm hoping that mount ignores options that don't apply to the fs # These options should prevent abuse and make it writeable for the # console user. MOUNTOPTS='-osync,nosuid'`stat -c',uid=%u,gid=%g' /dev/console` mesg Mounting $PARTS on $MOUNTPATH, options $MOUNTOPTS [ `echo $PARTS|wc -w` -eq 1 ] && MOUNTDIRECT=1 REMOVE= for i in $PARTS; do if [ -n "$MOUNTDIRECT" ]; then T=$MOUNTPATH else T=$MOUNTPATH/`basename $i` fi mkdir -p $T if mount $MOUNTOPTS $i $T; then REMOVE="umount $T;$REMOVE;rmdir $T" else rmdir $T fi done # Create remover echo "#!/bin/sh" > $REMOVER echo $REMOVE | sed 's/;;/;/g' >> $REMOVER chmod +x $REMOVER else exit 1 fi