#!/bin/dash # vim:se ft=sh ts=4 sw=4 et tw=80 cin cino=(0,ml,\:0: # # Copyright (C) 2009 DaTaPaX, GPL Licensed # halmount/halumount #------------- # Mounts and unmounts using hal (via dbus) # # More info: # http://people.freedesktop.org/~david/hal-spec/hal-spec.html # ToDo # * Read in defaults for help display from Hal # Version APP_VER="0.21" # Program name PROG="$(basename $0)" MOUNTNAME="halmount" UMOUNTNAME="halumount" mounting() { test "$PROG" != "$UMOUNTNAME"; } # Default FS type FSTYPE="" # Default mount options OPTIONS="" # Default Destination directory DESTDIR="" # Default to listing devices LIST="" EJECT="" usage() { cat <] [-o ] [destdir] $UMOUNTNAME -l $UMOUNTNAME [-o ] -h|--help - Displays this help -l - List available devices for mounting/unmounting -t - Filesystem type (default: auto) -o - Mount options - Label, UUID or device node of device to mount (eg: /dev/sdb1) - Destination mount directory (under /media, default: ) Examples: $MOUNTNAME /dev/sdb1 $MOUNTNAME 'APPLE IPOD' iPod $UMOUNTNAME 'APPLE IPOD' ! exit $1 } abort() { echo >&2 $2 exit $1 } lookup() { hal-get-property --udi "$1" --key "$2" | sed 1q; } search() { hal-find-by-property --key "$1" --string $2; } send() { dbus-send "$@" >/dev/null || abort $? "ERROR: dbus-send failed"; } is_mounted() { test "$(lookup $1 volume.is_mounted)" = true; } while getopts ehlo:t: opt do case $opt in e) EJECT=1;; h) usage 0;; l) LIST=1 break;; o) OPTIONS="$OPTARG";; t) FSTYPE="$OPTARG";; '?') usage 1;; esac done if mounting; then OPTIONS="${OPTIONS},uid=$(id -u)" fi shift $(($OPTIND - 1)) # If listing, no mount point or destination directory will be accepted if [ -z "$LIST" ]; then DEVICE="$1"; shift if mounting && [ $# -gt 0 ]; then DESTDIR="$1"; shift fi fi if [ "$#" -ne 0 ]; then abort 1 "ERROR: Too many arguments" fi if [ -n "$LIST" ]; then # List devices search info.category volume | while read udi; do info="" for i in fstype uuid label; do info="$info $(lookup $udi volume.$i)"; done dev="$(lookup $udi block.device)" mounted= case "$(lookup $udi volume.is_mounted)" in false) mounting && echo "$dev $info";; true) mounting || echo "$dev $(lookup $udi volume.mount_point) $info";; esac done exit 0 fi if [ -z "$DEVICE" ]; then abort 2 "ERROR: No device specified" fi if [ ! -b "$DEVICE" ]; then DEVICE=$(blkid -U "$DEVICE" || blkid -L "$DEVICE") fi # Retrieve the UDI for this device udi="$(search block.device "$DEVICE")" # First, check if it's a destination dir (for unmounting) if [ -z "$udi" ] && ! mounting; then # mount_point does not contain a trailing slash DESTDIR="${DEVICE%/}" udi="$(search volume.mount_point "$DESTDIR")" fi # No device if [ -z "$udi" ]; then abort 3 "ERROR: Couldn't find device in Hal" fi if mounting; then if is_mounted $udi; then abort 4 "Device $DEVICE already mounted on $(lookup $udi volume.mount_point)" fi # NOTE: --print-reply req'd for blocking send --system --print-reply --dest=org.freedesktop.Hal \ $udi \ org.freedesktop.Hal.Device.Volume.Mount \ string:"$DESTDIR" \ string:"$FSTYPE" \ array:string:"$OPTIONS" if [ "$DESTDIR" = "" ]; then echo "Mounted $DEVICE to $(lookup $udi volume.mount_point)" fi else # Unmounting method=org.freedesktop.Hal.Device.Volume.Unmount if [ -n "$EJECT" ]; then method=org.freedesktop.Hal.Device.Volume.Eject elif ! is_mounted $udi; then abort 4 "Device $DEVICE is not currently mounted" fi # NOTE: --print-reply req'd for blocking send --system --print-reply --dest=org.freedesktop.Hal \ $udi \ $method \ array:string:"$OPTIONS" fi