#!/bin/sh ## User options: FUSEROOT="$HOME/fuse" mount () { [ ! -f "$1" ] && return DEVICE="$(cdemu status | awk 'NR>2 && $2==0 {print $1; found=1; exit} END {if(! found)print NR-2}')" DEV_COUNT="$(cdemu device-mapping | awk 'END {print NR-3}')" if cdemu status | grep -q "$1"; then echo >&2 "Image alredy mounted" return fi if [ "$DEVICE" -gt "$DEV_COUNT" ]; then while [ "$DEVICE" -gt "$DEV_COUNT" ]; do if ! cdemu add-device; then echo >&2 "Error adding device" return fi DEV_COUNT="$(cdemu device-mapping | awk 'END {print NR-3}')" done ## WARNING: adding a new device takes some time. If we want to avoid errors, ## we need to sleep until it is ready. echo "Waiting until ready..." while [ -z "$(cdemu device-mapping | awk -v devnum="$DEV_COUNT" 'NR>2 && $1==devnum {print $2}')" ]; do sleep 1 done fi cdemu load "$DEVICE" "$1" if [ $? -ne 0 ] && command -v fuseiso >/dev/null 2>&1; then echo "Falling back to fuseiso." # LIST="$(mount | awk -v root="$FUSEROOT" '$1 == "fuseiso" && $3 ~ root {print $3}')" LIST=$(mount | awk -v root="$FUSEROOT" '$1 == "fuseiso" && $3 ~ root {sub(/^fuseiso on /,"");sub(/ type fuse.fuseiso [^ ]*$/, ""); print $0}') ALREADY="$(lsof -c fuseiso -F n | grep "$1")" if [ -n "$ALREADY" ]; then echo "Image alredy mounted." return fi COUNT=0 while echo "$LIST" | grep -q "$FUSEROOT/drive-$COUNT"; do COUNT=$((COUNT+1)) done mkdir -p "$FUSEROOT/drive-$COUNT" fuseiso -p "$1" "$FUSEROOT/drive-$COUNT" else NODE="$(cdemu device-mapping | awk -v devnum="$DEVICE" 'NR>2 && $1==devnum {print $2}')" ## TODO: This is terrible, but checking cdemu status does not work. Maybe ## a kernel limitation. echo "Mounting..." sleep 2 udiskie-mount "$NODE" fi } umount () { [ ! -d "$1" ] && return NODE="$(df | awk -v mount="$1" '$0 ~ mount {node=$1; gsub(/[^%]+% /, ""); if ($0 ~ mount){print node; exit}}')" if [ -n "$NODE" ]; then udiskie-umount "$1" DEVICE=$(cdemu device-mapping | awk -v node="$NODE" '$2 == node {print $1; exit}') cdemu unload "$DEVICE" elif command -v fuseiso >/dev/null; then fusermount -u "$1" rmdir "$1" >/dev/null 2>&1 fi } usage () { cat <&2 Usage: ${0##*/} FILES ${0##*/} -u FOLDERS Mount image files using CDEmu or fall back to fuseriso if available. It will not mount an image if already mounted. Options: -h: Show this help. -u: Unmount folders. EOF } OPT_UNMOUNT=false while getopts ":hu" opt; do case $opt in h) usage exit 1 ;; u) OPT_UNMOUNT=true ;; \?) usage exit 1 ;; esac done shift $((OPTIND - 1)) if [ $# -eq 0 ]; then usage exit 1 fi ## realpath is needed to check if image was already mounted or not. for i in udiskie cdemu realpath; do if ! command -v $i >/dev/null 2>&1; then echo >&2 "'$i' not found" exit 1 fi done if ! cdemu status >/dev/null 2>&1; then echo >&2 "CDemu failed to start" return fi if $OPT_UNMOUNT; then for i ; do umount "$(realpath "$i")" done else for i ; do mount "$(realpath "$i")" done fi