On Sun, 25 Oct 2009, Rogério Brito wrote:

> I'm fine with getting things as simple as possible, as long as they are
> portable.

Another patch (includes previous patch) against svn trunk, attached.


Cheers,

-- 
Cristian
Index: usbmount.conf
===================================================================
--- usbmount.conf	(revision 73)
+++ usbmount.conf	(working copy)
@@ -42,6 +42,7 @@
 
 FS_MOUNTOPTIONS=""
 
-# If set to "yes", more information will be logged via the syslog
-# facility.
-VERBOSE="no"
+# If set to "yes", more information will be logged via the syslog facility.
+VERBOSE=no
+
+SYMLINK_MODEL_DIR=/var/run/usbmount
Index: 00_remove_model_symlink
===================================================================
--- 00_remove_model_symlink	(revision 73)
+++ 00_remove_model_symlink	(working copy)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# This script removes the model name symlink in /var/run/usbmount.
+# This script removes the model name symlink in $SYMLINK_MODEL_DIR.
 # Copyright (C) 2005 Martin Dickopp
 #
 # This file is free software; the copyright holder gives unlimited
@@ -13,11 +13,19 @@
 #
 set -e
 
-ls /var/run/usbmount | while read name; do
-    if test "`readlink \"/var/run/usbmount/$name\" || :`" = "$UM_MOUNTPOINT"; then
-	rm -f "/var/run/usbmount/$name"
+set -x
+exec 2> /tmp/${0##*/}.$$.log
+
+[ ! -r /etc/usbmount/usbmount.conf ] || . /etc/usbmount/usbmount.conf
+
+cd $SYMLINK_MODEL_DIR
+IFS='
+'
+for name in *; do
+    [ -L "$name" ] || continue
+    syml=$SYMLINK_MODEL_DIR/$name
+    if [ "$(readlink "$syml" || :)" = "$UM_MOUNTPOINT" ]; then
+	rm -f "$syml"
 	break
     fi
 done
-
-exit 0
Index: 00_create_model_symlink
===================================================================
--- 00_create_model_symlink	(revision 73)
+++ 00_create_model_symlink	(working copy)
@@ -13,28 +13,45 @@
 #
 set -e
 
+log="logger -p user.warning -t ${0##*/}[$$]"
+
+[ ! -r /etc/usbmount/usbmount.conf ] || . /etc/usbmount/usbmount.conf
+
 # Replace spaces with underscores, remove special characters in vendor
 # and model name.
-UM_VENDOR=`echo "$UM_VENDOR" | sed 's/ /_/g; s/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-]//g'`
-UM_MODEL=`echo "$UM_MODEL" | sed 's/ /_/g; s/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-]//g'`
+UM_VENDOR=$(echo "$UM_VENDOR" |
+	sed -e 's/[[:blank:]]\+/_/g; s/[^[:alnum:]._-]//g')
+UM_MODEL=$(echo "$UM_MODEL" |
+	sed -e 's/[[:blank:]]\+/_/g; s/[^[:alnum:]._-]//g')
 
 # Exit if both vendor and model name are empty.
-test -n "$UM_VENDOR" || test -n "$UM_MODEL" || exit 0
+[ "$UM_VENDOR" ] || [ "$UM_MODEL" ] || {
+    case "$VERBOSE" in
+	[Yy]*)
+	    $log "empty vendor and model name"
+	    ;;
+    esac
+    exit 0
+}
 
 # Build symlink name.
-if test -n "$UM_VENDOR" && test -n "$UM_MODEL"; then
+if [ "$UM_VENDOR" ] && [ "$UM_MODEL" ]; then
     name="${UM_VENDOR}_$UM_MODEL"
 else
     name="$UM_VENDOR$UM_MODEL"
 fi
 
 # Append partition number, if any, to the symlink name.
-partition=`echo "$UM_DEVICE" | sed 's/^.*[^0123456789]\([0123456789]*\)/\1/'`
-if test -n "$partition"; then
-    name="${name}_$partition"
-fi
+partition=$(expr "$UM_DEVICE" : '.*[^0-9]\([0-9]*\)' || :)
+[ -z "$partition" ] || name="${name}_$partition"
 
 # If the symlink does not yet exist, create it.
-test -e "/var/run/usbmount/$name" || ln -sf "$UM_MOUNTPOINT" "/var/run/usbmount/$name"
-
-exit 0
+# If the symlink points to the wrong thing, recreate it.
+syml=$SYMLINK_MODEL_DIR/$name
+if [ -e "$syml" ]; then
+    [ "$(readlink "$syml" || :)" != "$UM_MOUNTPOINT" ] || exit 0
+    $log "symlink '$syml' and mount point '$UM_MOUNTPOINT' mismatch;" \
+	"removing symlink"
+    rm -f "$syml"
+fi
+ln -sf "$UM_MOUNTPOINT" "$syml"
Index: usbmount
===================================================================
--- usbmount	(revision 73)
+++ usbmount	(working copy)
@@ -16,162 +16,191 @@
 set -e
 exec > /dev/null 2>&1
 
+SELF=${0##*/}
+TAG=$SELF[$$]
+
 ######################################################################
 # Auxiliary functions
 
+is_verbose() {
+    case $VERBOSE in
+	[Yy]*)
+	    return 0
+	    ;;
+    esac
+    return 1
+}
+
 # Log a string via the syslog facility.
-log()
-{
-    if [ $1 != debug ] || expr "$VERBOSE" : "[yY]" > /dev/null; then
-	logger -p user.$1 -t "usbmount[$$]" -- "$2"
+log() {
+    local level
+
+    level=$1
+    if [ "$level" != debug ] || is_verbose; then
+	shift
+	logger -p user.$level -t $TAG -- "$*"
     fi
 }
 
+# Test if the first parameter is in the list given by the second parameter.
+in_list() {
+    local v
 
-# Test if the first parameter is in the list given by the second
-# parameter.
-in_list()
-{
     for v in $2; do
 	[ "$1" != "$v" ] || return 0
     done
     return 1
 }
 
+export_some() {
+	export UM_DEVICE=$DEVNAME
+	export UM_MOUNTPOINT=$MOUNTPOINT
+	export UM_FILESYSTEM=$FSTYPE
+}
 
 ######################################################################
 # Main program
 
+#//# No point continuing if /sbin/blkid is not available.
+blkid=$(which blkid 2>/dev/null) || {
+	log err "cannot locate blkid"
+	exit 1
+}
+
 # Default values for configuration variables.
 ENABLED=1
+#//# Quoting these values adds nothing useful.
 MOUNTPOINTS=
+MOUNTPOINT=
 FILESYSTEMS=
 MOUNTOPTIONS=
 FS_MOUNTOPTIONS=
 VERBOSE=no
+CONF=/etc/$SELF/$SELF.conf
+FSTAB=/etc/fstab
 
-if [ -r /etc/usbmount/usbmount.conf ]; then
-    . /etc/usbmount/usbmount.conf
-    log debug "loaded usbmount configurations"
+# Read configuration file.
+if [ -r $CONF ]; then
+    . $CONF
+    log debug "configuration loaded"
 fi
 
-if [ "${ENABLED:-1}" -eq 0 ]; then
-    log info "usbmount is disabled, see /etc/usbmount/usbmount.conf"
+#//# Arithmetic, not string evaluation.
+if [ ${ENABLED:-1} -eq 0 ]; then
+    log info "$SELF is disabled, see $CONF"
     exit 0
 fi
 
-if [ ! -x /sbin/blkid ]; then
-    log err "cannot execute /sbin/blkid"
+# Per Policy 9.3.2, directories under /var/run have to be checked
+# after every reboot.
+#//# /var/run/$SELF is used in a lot of places; use a conf variable instead.
+[ -d "$SYMLINK_MODEL_DIR" ] || mkdir -p "$SYMLINK_MODEL_DIR" || {
+    log err "cannot create the $SYMLINK_MODEL_DIR directory"
     exit 1
-fi
+}
 
-# Per Policy 9.3.2, directories under /var/run have to be created
-# after every reboot.
-if [ ! -e /var/run/usbmount ]; then
-    mkdir -p /var/run/usbmount
-    log debug "creating /var/run/usbmount directory"
-fi
-
 umask 022
 
-
+#//# Useless quotes removed.
 if [ "$1" = add ]; then
-
     # Acquire lock.
-    log debug "trying to acquire lock /var/run/usbmount/.mount.lock"
-    lockfile-create --retry 3 /var/run/usbmount/.mount || \
-	{ log err "cannot acquire lock /var/run/usbmount/.mount.lock"; exit 1; }
-    trap '( lockfile-remove /var/run/usbmount/.mount )' 0
-    log debug "acquired lock /var/run/usbmount/.mount.lock"
+    log debug "trying to acquire lock $SYMLINK_MODEL_DIR/.mount.lock"
+    lockfile-create --retry 3 "$SYMLINK_MODEL_DIR/.mount" || {
+	log err "cannot acquire lock $SYMLINK_MODEL_DIR/.mount.lock"
+	exit 1
+    }
+    #//# The trap does not need to be run in a subshell?
+    trap 'lockfile-remove "$SYMLINK_MODEL_DIR/.mount"' EXIT
+    log debug "acquired lock $SYMLINK_MODEL_DIR/.mount.lock"
 
     # Grab device information from device and "divide it"
     #   FIXME: improvement: implement mounting by label (notice that labels
     #   can contain spaces, which makes things a little bit less comfortable).
-    DEVINFO=$(/sbin/blkid -p $DEVNAME)
-    FSTYPE=$(echo "$DEVINFO" | sed 's/.*TYPE="\([^"]*\)".*/\1/g; s/[[:space:]]*//g;')
-    UUID=$(echo "$DEVINFO"   | sed 's/.*UUID="\([^"]*\)".*/\1/g; s/[[:space:]]*//g;')
-    USAGE=$(echo "$DEVINFO"  | sed 's/.*USAGE="\([^"]*\)".*/\1/g; s/[[:space:]]*//g;')
+    DEVINFO=$($blkid -p $DEVNAME) || {
+	log debug "no info found on $DEVNAME"
+	exit 0
+    }
+    FSTYPE=$(expr "$DEVINFO" : '.*TYPE="\([^"]\+\)".*')
+    UUID=$(expr "$DEVINFO" : '.*UUID="\([^"]\+\)".*')
+    USAGE=$(expr "$DEVINFO" : '.*USAGE="\([^"]\+\)".*')
 
-    if ! echo $USAGE | egrep -q "(filesystem|disklabel)"; then
-	log info "$DEVNAME does not contain a filesystem or disklabel"
-	exit 1
-    fi
+    case $USAGE in
+	filesystem|disklabel)
+	    ;;
+	*)
+	    log info "$DEVNAME does not contain a filesystem or disklabel"
+	    exit 1
+	    ;;
+    esac
 
     # Try to use specifications in /etc/fstab first.
-    if egrep -q "[[:space:]]*$DEVNAME" /etc/fstab; then
-	log info "executing command: mount $DEVNAME"
-	mount $DEVNAME
-
-    elif grep -q $UUID /etc/fstab; then
-        log info "executing command: mount -U $UUID"
-	mount -U $UUID
-
+    if egrep -q "^[[:blank:]]*$DEVNAME[[:blank:]]" $FSTAB; then
+	cmd="mount $DEVNAME"
+	log info "executing command: $cmd"
+	$cmd
+    elif [ "$UUID" ] && egrep -q "^[[:blank:]]*UUID=$UUID[[:blank:]]" $FSTAB; then
+	cmd="mount -U $UUID"
+	log info "executing command: $cmd"
+	$cmd
     else
 	log debug "$DEVNAME contains filesystem type $FSTYPE"
 
-	fstype=$FSTYPE
 	# Test if the filesystem type is in the list of filesystem
 	# types to mount.
-	if in_list "$fstype" "$FILESYSTEMS"; then
+	if in_list "$FSTYPE" "$FILESYSTEMS"; then
+
 	    # Search an available mountpoint.
 	    for v in $MOUNTPOINTS; do
-		if [ -d "$v" ] && ! grep -q "^[^ ][^ ]*  *$v " /proc/mounts; then
-		    mountpoint="$v"
-		    log debug "mountpoint $mountpoint is available for $DEVNAME"
+		if [ -d "$v" ] &&
+		   ! egrep -q "^[^[:blank:]]+[[:blank:]]+$v[[:blank:]]+" /proc/mounts; then
+		    MOUNTPOINT=$v
+		    log debug "mountpoint $MOUNTPOINT is available for $DEVNAME"
 		    break
 		fi
 	    done
-	    if [ -n "$mountpoint" ]; then
+	    if [ "$MOUNTPOINT" ]; then
 		# Determine mount options.
 		options=
 		for v in $FS_MOUNTOPTIONS; do
-		    if expr "$v" : "-fstype=$fstype,."; then
-			options="$(echo "$v" | sed 's/^[^,]*,//')"
-			break
-		    fi
+		    #//# Optimized.
+		    ! options=$(expr "$v" : \
+			    "-fstype=$FSTYPE,\([^[:blank:]]\+\)") || break
 		done
-		if [ -n "$MOUNTOPTIONS" ]; then
-		    options="$MOUNTOPTIONS${options:+,$options}"
-		fi
+		#//# Shortened.
+		[ -z "$MOUNTOPTIONS" ] ||
+			options="$MOUNTOPTIONS${options:+,$options}"
 
 		# Mount the filesystem.
-		log info "executing command: mount -t$fstype ${options:+-o$options} $DEVNAME $mountpoint"
-		mount "-t$fstype" "${options:+-o$options}" "$DEVNAME" "$mountpoint"
+		#//# Optimized.
+		cmd="mount -t$FSTYPE ${options:+-o$options} $DEVNAME $MOUNTPOINT"
+		log info "executing command: $cmd"
+		$cmd
 
 		# Determine vendor and model.
 		vendor=
-		if [ -r "/sys$DEVPATH/device/vendor" ]; then
-		    vendor="`cat \"/sys$DEVPATH/device/vendor\"`"
-		elif [ -r "/sys$DEVPATH/../device/vendor" ]; then
-		    vendor="`cat \"/sys$DEVPATH/../device/vendor\"`"
-		elif [ -r "/sys$DEVPATH/device/../manufacturer" ]; then
-		    vendor="`cat \"/sys$DEVPATH/device/../manufacturer\"`"
-		elif [ -r "/sys$DEVPATH/../device/../manufacturer" ]; then
-		    vendor="`cat \"/sys$DEVPATH/../device/../manufacturer\"`"
-		fi
-		vendor="$(echo "$vendor" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')"
+		#//# Much shorter, less forks.
+		read vendor < "/sys$DEVPATH/device/vendor" ||
+		read vendor < "/sys$DEVPATH/../device/vendor" ||
+		read vendor < "/sys$DEVPATH/device/../manufacturer" ||
+		read vendor < "/sys$DEVPATH/../device/../manufacturer" || :
 
 		model=
-		if [ -r "/sys$DEVPATH/device/model" ]; then
-		    model="`cat \"/sys$DEVPATH/device/model\"`"
-		elif [ -r "/sys$DEVPATH/../device/model" ]; then
-		    model="`cat \"/sys$DEVPATH/../device/model\"`"
-		elif [ -r "/sys$DEVPATH/device/../product" ]; then
-		    model="`cat \"/sys$DEVPATH/device/../product\"`"
-		elif [ -r "/sys$DEVPATH/../device/../product" ]; then
-		    model="`cat \"/sys$DEVPATH/../device/../product\"`"
-		fi
-		model="$(echo "$model" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')"
+		#//# Much shorter, less forks.
+		read model < "/sys$DEVPATH/device/model" ||
+		read model < "/sys$DEVPATH/../device/model" ||
+		read model < "/sys$DEVPATH/device/../product" ||
+		read model < "/sys$DEVPATH/../device/../product" || :
 
 		# Run hook scripts; ignore errors.
-		export UM_DEVICE="$DEVNAME"
-		export UM_MOUNTPOINT="$mountpoint"
-		export UM_FILESYSTEM="$fstype"
-		export UM_MOUNTOPTIONS="$options"
+		#//# Some quoting here was superfluous.
+		export_some
+		export UM_MOUNTOPTIONS=$options
 		export UM_VENDOR="$vendor"
 		export UM_MODEL="$model"
-		log info "executing command: run-parts /etc/usbmount/mount.d"
-		run-parts /etc/usbmount/mount.d || :
+		#//# Optimized.
+		cmd="run-parts /etc/$SELF/mount.d"
+		log info "executing command: $cmd"
+		$cmd || :
 	    else
 		# No suitable mount point found.
 		log warning "no mountpoint found for $DEVNAME"
@@ -180,29 +209,31 @@
 	fi
     fi
 elif [ "$1" = remove ]; then
-
     # A block or partition device has been removed.
     # Test if it is mounted.
-    while read device mountpoint fstype remainder; do
+    while read device MOUNTPOINT FSTYPE remainder; do
 	if [ "$DEVNAME" = "$device" ]; then
 	    # If the mountpoint and filesystem type are maintained by
 	    # this script, unmount the filesystem.
-	    if in_list "$mountpoint" "$MOUNTPOINTS" &&
-		in_list "$fstype" "$FILESYSTEMS"; then
-		log info "executing command: umount -l $mountpoint"
-		umount -l "$mountpoint"
+	    if in_list "$MOUNTPOINT" "$MOUNTPOINTS" &&
+	       in_list "$FSTYPE" "$FILESYSTEMS"; then
+		cmd="umount -l $MOUNTPOINT"
+		log info "executing command: $cmd"
+		$cmd
 
 		# Run hook scripts; ignore errors.
-		export UM_DEVICE="$DEVNAME"
-		export UM_MOUNTPOINT="$mountpoint"
-		export UM_FILESYSTEM="$fstype"
-		log info "executing command: run-parts /etc/usbmount/umount.d"
-		run-parts /etc/usbmount/umount.d || :
+		export_some
+		#//# Optimized.
+		cmd="run-parts /etc/$SELF/umount.d"
+		log info "executing command: $cmd"
+		$cmd || :
 	    fi
 	    break
 	fi
     done < /proc/mounts
+else
+    log debug "surprise: action '$1'"
+    exit 1
 fi
 
-log debug "finishing execution of usbmount"
-exit 0
+log debug "$SELF execution finished"

Reply via email to