imagemount 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #!/bin/sh
  2. ## User options:
  3. FUSEROOT="$HOME/fuse"
  4. mount () {
  5. [ ! -f "$1" ] && return
  6. DEVICE="$(cdemu status | awk 'NR>2 && $2==0 {print $1; found=1; exit} END {if(! found)print NR-2}')"
  7. DEV_COUNT="$(cdemu device-mapping | awk 'END {print NR-3}')"
  8. if cdemu status | grep -q "$1"; then
  9. echo >&2 "Image alredy mounted"
  10. return
  11. fi
  12. if [ "$DEVICE" -gt "$DEV_COUNT" ]; then
  13. while [ "$DEVICE" -gt "$DEV_COUNT" ]; do
  14. if ! cdemu add-device; then
  15. echo >&2 "Error adding device"
  16. return
  17. fi
  18. DEV_COUNT="$(cdemu device-mapping | awk 'END {print NR-3}')"
  19. done
  20. ## WARNING: adding a new device takes some time. If we want to avoid errors,
  21. ## we need to sleep until it is ready.
  22. echo "Waiting until ready..."
  23. while [ -z "$(cdemu device-mapping | awk -v devnum="$DEV_COUNT" 'NR>2 && $1==devnum {print $2}')" ]; do
  24. sleep 1
  25. done
  26. fi
  27. cdemu load "$DEVICE" "$1"
  28. if [ $? -ne 0 ] && command -v fuseiso >/dev/null 2>&1; then
  29. echo "Falling back to fuseiso."
  30. # LIST="$(mount | awk -v root="$FUSEROOT" '$1 == "fuseiso" && $3 ~ root {print $3}')"
  31. LIST=$(mount | awk -v root="$FUSEROOT" '$1 == "fuseiso" && $3 ~ root {sub(/^fuseiso on /,"");sub(/ type fuse.fuseiso [^ ]*$/, ""); print $0}')
  32. ALREADY="$(lsof -c fuseiso -F n | grep "$1")"
  33. if [ -n "$ALREADY" ]; then
  34. echo "Image alredy mounted."
  35. return
  36. fi
  37. COUNT=0
  38. while echo "$LIST" | grep -q "$FUSEROOT/drive-$COUNT"; do
  39. COUNT=$((COUNT+1))
  40. done
  41. mkdir -p "$FUSEROOT/drive-$COUNT"
  42. fuseiso -p "$1" "$FUSEROOT/drive-$COUNT"
  43. else
  44. NODE="$(cdemu device-mapping | awk -v devnum="$DEVICE" 'NR>2 && $1==devnum {print $2}')"
  45. ## TODO: This is terrible, but checking cdemu status does not work. Maybe
  46. ## a kernel limitation.
  47. echo "Mounting..."
  48. sleep 2
  49. udiskie-mount "$NODE"
  50. fi
  51. }
  52. umount () {
  53. [ ! -d "$1" ] && return
  54. NODE="$(df | awk -v mount="$1" '$0 ~ mount {node=$1; gsub(/[^%]+% /, ""); if ($0 ~ mount){print node; exit}}')"
  55. if [ -n "$NODE" ]; then
  56. udiskie-umount "$1"
  57. DEVICE=$(cdemu device-mapping | awk -v node="$NODE" '$2 == node {print $1; exit}')
  58. cdemu unload "$DEVICE"
  59. elif command -v fuseiso >/dev/null; then
  60. fusermount -u "$1"
  61. rmdir "$1" >/dev/null 2>&1
  62. fi
  63. }
  64. usage () {
  65. cat <<EOF>&2
  66. Usage: ${0##*/} FILES
  67. ${0##*/} -u FOLDERS
  68. Mount image files using CDEmu or fall back to fuseriso if available. It will
  69. not mount an image if already mounted.
  70. Options:
  71. -h: Show this help.
  72. -u: Unmount folders.
  73. EOF
  74. }
  75. OPT_UNMOUNT=false
  76. while getopts ":hu" opt; do
  77. case $opt in
  78. h)
  79. usage
  80. exit 1 ;;
  81. u)
  82. OPT_UNMOUNT=true ;;
  83. \?)
  84. usage
  85. exit 1 ;;
  86. esac
  87. done
  88. shift $((OPTIND - 1))
  89. if [ $# -eq 0 ]; then
  90. usage
  91. exit 1
  92. fi
  93. ## realpath is needed to check if image was already mounted or not.
  94. for i in udiskie cdemu realpath; do
  95. if ! command -v $i >/dev/null 2>&1; then
  96. echo >&2 "'$i' not found"
  97. exit 1
  98. fi
  99. done
  100. if ! cdemu status >/dev/null 2>&1; then
  101. echo >&2 "CDemu failed to start"
  102. return
  103. fi
  104. if $OPT_UNMOUNT; then
  105. for i ; do
  106. umount "$(realpath "$i")"
  107. done
  108. else
  109. for i ; do
  110. mount "$(realpath "$i")"
  111. done
  112. fi