Advertisement
Archman

obdevicemenu

Jan 15th, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 22.01 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. #=============================================================================#
  4. #          FILE: obdevicemenu                                                 #
  5. #       VERSION: 1.7.0                                                        #
  6. #                                                                             #
  7. #   DESCRIPTION: obdevicemenu is an Openbox pipe menu that uses udisks to     #
  8. #                easily mount, unmount or eject removable devices. An         #
  9. #                extensive configuration file allows desktop notifications    #
  10. #                about the success or failure of operations, as well as the   #
  11. #                modification of several other options.                       #
  12. #       LICENSE: GPL2                                                         #
  13. #        AUTHOR: Jamie Nguyen                                                 #
  14. #=============================================================================#
  15.  
  16. # Copyright (C) 2011 Jamie Nguyen
  17. #
  18. # This program is free software; you can redistribute it and/or modify it
  19. # under the terms of the GNU General Public License v2 as published by the
  20. # Free Software Foundation.
  21. #
  22. # This program is distributed in the hope that it will be useful, but WITHOUT
  23. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  24. # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  25. # more details.
  26. #
  27. # You should have received a copy of the GNU General Public License along with
  28. # this program; if not, write to the Free Software Foundation, Inc.,
  29. # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  30.  
  31.  
  32. #-------------------------------------#
  33. #           CONFIGURATION             #
  34. #-------------------------------------#
  35. # {{{
  36.  
  37. unset GREP_OPTIONS
  38.  
  39. declare filemanager="/usr/bin/pcmanfm"
  40. declare notify="/usr/bin/notify-send"
  41. declare notify_options="--expire-time=3000"
  42. declare optical_devices="-E ^/dev/sr[0-9]+"
  43. declare removable_devices="-E ^/dev/sd[b-z][0-9]*|^/dev/mmcblk[0-9]+p*[0-9]*"
  44. declare mount_options="--mount-options nosuid,noexec,noatime"
  45.  
  46. declare -i show_internal=0
  47. declare -i show_notifications=1
  48. declare -i show_optical_device_filename=1
  49. declare -i show_removable_device_filename=1
  50. declare -i fancy_sort=0
  51. declare -i run_post_mount=0
  52. declare -i run_post_unmount=0
  53.  
  54. declare -a blacklist=( )
  55.  
  56. declare CONFIGFILE
  57.  
  58. if [[ -n "${XDG_CONFIG_HOME}" ]]; then
  59.     CONFIGFILE="${XDG_CONFIG_HOME}/obdevicemenu/config"
  60. else
  61.     CONFIGFILE="${HOME}/.config/obdevicemenu/config"
  62. fi
  63.  
  64. if [[ ! -f "${CONFIGFILE}" ]]; then
  65.     CONFIGFILE="/etc/obdevicemenu.conf"
  66. fi
  67.  
  68. if [[ -f "${CONFIGFILE}" ]]; then
  69.     . "${CONFIGFILE}"
  70.     if (( $? != 0 )); then
  71.         printf '%s\n' "<openbox_pipe_menu>"
  72.         printf '%s\n' "<separator label=\"obdevicemenu\" />"
  73.         printf '%s\n' "<item label=\"Failed to source configuration file\" />"
  74.         printf '%s\n' "</openbox_pipe_menu>"
  75.         exit 1
  76.     fi
  77. fi
  78.  
  79. if ! command -v udisks2 >/dev/null 2>&1; then
  80.     printf '%s\n' "<openbox_pipe_menu>"
  81.     printf '%s\n' "<separator label=\"obdevicemenu\" />"
  82.     printf '%s\n' "<item label=\"Udisks not installed\" />"
  83.     printf '%s\n' "</openbox_pipe_menu>"
  84.     exit 1
  85. fi
  86. # }}}
  87.  
  88. #-------------------------------------#
  89. #            INTERNAL API             #
  90. #-------------------------------------#
  91. # {{{
  92.  
  93. notify() {
  94.     if [ -z "${notify_options}" ]; then
  95.         $notify "$*"
  96.     else
  97.         $notify ${notify_options} "$*"
  98.     fi
  99. }
  100.  
  101. # Functions to retrieve information. These functions simply parse the output
  102. # of udisks --show-info.
  103. info_blank() {
  104.     udisks --show-info ${1} \
  105.         | grep -m 1 -w "^[[:space:]]*blank:" \
  106.         | awk '{print $2}'
  107. }
  108. info_ejectable() {
  109.     udisks --show-info ${1} \
  110.         | grep -m 1 -w "^[[:space:]]*ejectable:" \
  111.         | awk '{print $2}'
  112. }
  113. info_has_media() {
  114.     udisks --show-info ${1} \
  115.         | grep -m 1 -w "^[[:space:]]*has media:" \
  116.         | awk '{print $3}'
  117. }
  118. info_internal() {
  119.     udisks --show-info ${1} \
  120.         | grep -m 1 -w "^[[:space:]]*system internal:" \
  121.         | awk '{print $3}'
  122. }
  123. info_label() {
  124.     local info_label=
  125.     info_label="$(udisks --show-info ${1} \
  126.         | grep -m 1 -w "^  label:" \
  127.         | awk '{gsub(/_/,"");$1="";print substr($0, index($0,$2))}')"
  128.     [[ -n "${info_label}" ]] && printf '%s\n' "${info_label}"
  129. }
  130. info_media() {
  131.     udisks --show-info ${1} \
  132.     | grep -m 1 -w "^[[:space:]]*media:" \
  133.     | awk '{gsub(/_/,"");print $2}'
  134. }
  135. info_model() {
  136.     udisks --show-info ${1} \
  137.         | grep -m 1 -w "^[[:space:]]*model:" \
  138.         | awk '{gsub(/_/,"");$1="";print substr($0, index($0,$2))}'
  139. }
  140. info_mounted() {
  141.     udisks --show-info ${1} \
  142.         | grep -m 1 -w "^[[:space:]]*is mounted:" \
  143.         | awk '{print $3}'
  144. }
  145. info_mountpath() {
  146.     udisks --show-info ${1} \
  147.         | grep -m 1 -w "^[[:space:]]*mount paths:" \
  148.         | awk '{$1="";$2="";print substr($0, index($0,$3))}'
  149. }
  150. info_type() {
  151.     udisks --show-info ${1} \
  152.         | grep -m 1 -w "^[[:space:]]*type:" \
  153.         | awk '{gsub(/_/,"");print $2}'
  154. }
  155. info_vendor() {
  156.     udisks --show-info ${1} \
  157.         | grep -m 1 -w "^[[:space:]]*vendor:" \
  158.         | awk '{gsub(/_/,"");$1="";print substr($0, index($0,$2))}'
  159. }
  160. # The size of the device/partition is given in bytes, so let's convert that
  161. # to something more readable. Rounding done in bash is not accurate at all
  162. # but we'll mitigate that by only rounding when the numbers get quite large.
  163. convert_size() {
  164.     local -i old_size="${1}"
  165.     local new_size=
  166.  
  167.     printf '%s\n' "${old_size}" | grep -ow -E ^[1-9]{1}[0-9]*$ >/dev/null 2>&1
  168.     (( $? != 0 )) && return 1
  169.  
  170.     if (( old_size > 21474836480 )); then
  171.         new_size="$((${old_size}/1073741824)) GB"
  172.     elif (( old_size > 10485760 )); then
  173.         new_size="$((${old_size}/1048576)) MB"
  174.     elif (( old_size > 10240 )); then
  175.         new_size="$((${old_size}/1024)) kB"
  176.     else
  177.         new_size="${old_size} bytes"
  178.     fi
  179.  
  180.     printf '%s\n' "${new_size}"
  181. }
  182. info_device_size() {
  183.     local info_device_size=
  184.     info_device_size="$(udisks --show-info ${1} \
  185.         | grep -m 1 -w "^[[:space:]]*size:" \
  186.         | awk '{print $2}')"
  187.     if [[ -n "${info_device_size}" ]]; then
  188.         info_device_size="$(convert_size "${info_device_size}")"
  189.         printf '%s\n' "${info_device_size}"
  190.     fi
  191. }
  192. info_partition_size() {
  193.     local info_partition_size=
  194.     info_partition_size="$(udisks --show-info ${1} \
  195.         | grep -m 1 -w "  size:" \
  196.         | awk '{print $2}')"
  197.     if [[ -n "${info_partition_size}" ]]; then
  198.         info_partition_size="$(convert_size "${info_partition_size}")"
  199.         printf '%s\n' "${info_partition_size}"
  200.     fi
  201. }
  202.  
  203. # Functions to perform udisks commands.
  204.  
  205. # Eject the device, unmounting with a call to action_unmount if required.
  206. action_eject() {
  207.     local devname="${1}"
  208.     local -i mounted=0
  209.     mounted="$(info_mounted "${devname}")"
  210.     if (( mounted == 1 )); then
  211.         action_unmount "${devname}"
  212.     fi
  213.     mounted="$(info_mounted "${devname}")"
  214.     if (( mounted == 0 )); then
  215.         if (( show_notifications == 1 )); then
  216.             if command -v "${notify}" >/dev/null 2>&1; then
  217.                 notify "$(printf '%s\n' "Ejecting ${devname} ...")"
  218.                 notify "$(udisks --eject ${devname})"
  219.             fi
  220.         else
  221.             udisks --eject ${devname}
  222.         fi
  223.     fi
  224. }
  225. # Mount the device if it is not already mounted, and run the post_mount hook
  226. # after a successful mount operation if it has been enabled.
  227. action_mount() {
  228.     local devname="${1}"
  229.     if (( show_notifications == 1 )); then
  230.         if command -v "${notify}" >/dev/null 2>&1; then
  231.             notify "$(printf '%s\n' "Mounting ${devname} ...")"
  232.             notify "$(udisks --mount ${devname} ${mount_options})"
  233.         fi
  234.     else
  235.         udisks --mount ${devname} ${mount_options}
  236.     fi
  237.  
  238.     if (( run_post_mount == 1 )); then
  239.         post_mount ${devname}
  240.     fi
  241. }
  242. # Open the device with the filemanager specified in the configuration file,
  243. # mounting with a call to action_mount if required.
  244. action_open() {
  245.     local devname="${1}"
  246.     local info_mountpath="$(info_mountpath "${devname}")"
  247.     if [[ -n "${info_mountpath}" ]]; then
  248.         $filemanager "${info_mountpath}"
  249.     else
  250.         $filemanager
  251.     fi
  252. }
  253. # Unmount the device if it is not already unmounted, and run the post_unmount
  254. # hook after a successful unmount operation if it has been enabled.
  255. action_unmount() {
  256.     local devname="${1}"
  257.     if (( show_notifications == 1 )); then
  258.         if command -v "${notify}" >/dev/null 2>&1; then
  259.             notify "$(printf '%s\n' "Unmounting ${devname} ...")"
  260.             notify "$(udisks --unmount ${devname})"
  261.         fi
  262.         mounted="$(info_mounted ${devname})"
  263.         if (( mounted == 1 )); then
  264.             notify "$(printf '%s\n' "${devname} unmounted successfully")"
  265.         fi
  266.     else
  267.         udisks --unmount ${devname}
  268.     fi
  269.  
  270.     if (( run_post_unmount == 1 )); then
  271.         post_unmount ${devname}
  272.     fi
  273. }
  274. action_unmount_all() {
  275.     for devname in $*; do
  276.         action_unmount ${devname}
  277.     done
  278. }
  279. action_info() {
  280.     local devname="${1}"
  281.     local devmajor="${devname%%[0-9]*}"
  282.  
  283.     udisks --show-info ${devname} >/dev/null 2>&1
  284.     if (( $? != 0 )); then
  285.         printf '%s\n' "<openbox_pipe_menu>"
  286.         printf '%s\n' "<item label=\"Udisks failed.\" />"
  287.         printf '%s\n' "</openbox_pipe_menu>"
  288.         exit 0
  289.     fi
  290.  
  291.     local info_label="$(info_label "${devname}")"
  292.     local info_vendor="$(info_vendor "${devmajor}")"
  293.     local info_model="$(info_model "${devmajor}")"
  294.     local info_device_size="$(info_device_size "${devmajor}")"
  295.     local info_type="$(info_type "${devname}")"
  296.     local info_media="$(info_media ${devname})"
  297.  
  298.     if [[ "${devname}" != "${devmajor}" ]]; then
  299.         local info_partition_size="$(info_partition_size "${devname}")"
  300.     fi
  301.  
  302.     printf '%s\n' "<openbox_pipe_menu>"
  303.  
  304.     printf '%s\n' "<separator label=\"Device information\" />"
  305.  
  306.     [[ -n "${info_device_filename}" ]] && \
  307.         printf '%s\n' "<item label=\"device: ${devname}\" />"
  308.     [[ -n "${info_label}" ]] && \
  309.         printf '%s\n' "<item label=\"label: ${info_label}\" />"
  310.     [[ -n "${info_vendor}" ]] && \
  311.         printf '%s\n' "<item label=\"vendor: ${info_vendor}\" />"
  312.     [[ -n "${info_model}" ]] && \
  313.         printf '%s\n' "<item label=\"model: ${info_model}\" />"
  314.     [[ -n "${info_type}" ]] && \
  315.         printf '%s\n' "<item label=\"type: ${info_type}\" />"
  316.     [[ -n "${info_media}" ]] && \
  317.         printf '%s\n' "<item label=\"media: ${info_media}\" />"
  318.     [[ -n "${info_partition_size}" ]] && \
  319.         printf '%s\n' "<item label=\"size (partition): ${info_partition_size}\" />"
  320.     [[ -n "${info_device_size}" ]] && \
  321.         printf '%s\n' "<item label=\"size (device): ${info_device_size}\" />"
  322.  
  323.     printf '%s\n' "</openbox_pipe_menu>"
  324. }
  325. fancy_sort() {
  326.     # This is a very hacky way to sort devices so that /dev/sdc11 wont come
  327.     # before /dev/sdc2, which happens due to a shortcoming of the sort command.
  328.  
  329.     # We wont tell bash that partition_number is a number, otherwise it
  330.     # breaks when leading zeros are added (interpreted as hex).
  331.     local devname= devmajor= partition_number=
  332.     local -i array_position=0
  333.  
  334.     # First lets put a leading zero in front of single digits (sdc1 -> sdc01).
  335.     # We are going to ignore /dev/mmcblk*p* devices... too complicated to sort.
  336.     array_position=0
  337.     for devname in ${removable[@]}; do
  338.         if [[ "${devname}" =~ ^/dev/dm-[0-9]+ ]]; then
  339.             devmajor="${devname%%[0-9]*}"
  340.         elif [[ "${devname}" =~ ^/dev/fd[0-9]+ ]]; then
  341.             devmajor="${devname%%[0-9]*}"
  342.         elif [[ "${devname}" =~ ^/dev/sd[a-z][0-9]+ ]]; then
  343.             devmajor="${devname%%[0-9]*}"
  344.         else
  345.             array_position=$((++array_position)); continue
  346.         fi
  347.  
  348.         if [[ "${devname}" = "${devmajor}" ]]; then
  349.             array_position=$((++array_position)); continue
  350.         fi
  351.  
  352.         partition_number="${devname#${devmajor}}"
  353.         removable[${array_position}]=${devmajor}$(printf '%02d' "${partition_number}")
  354.         array_position=$((++array_position))
  355.     done
  356.  
  357.     # Now the device array can be sorted properly.
  358.     removable=( $(printf '%s\n' "${removable[@]}" | sort) )
  359.  
  360.     # Now let's remove those leading zeros that we added.
  361.     array_position=0
  362.     for devname in ${removable[@]}; do
  363.         if [[ "${devname}" =~ ^/dev/dm-[0-9]+ ]]; then
  364.             devmajor="${devname%%[0-9]*}"
  365.         elif [[ "${devname}" =~ ^/dev/fd[0-9]+ ]]; then
  366.             devmajor="${devname%%[0-9]*}"
  367.         elif [[ "${devname}" =~ ^/dev/sd[a-z][0-9]+ ]]; then
  368.             devmajor="${devname%%[0-9]*}"
  369.         else
  370.             array_position=$((++array_position)); continue
  371.         fi
  372.  
  373.         if [[ "${devname}" = "${devmajor}" ]]; then
  374.             array_position=$((++array_position)); continue
  375.         fi
  376.  
  377.         partition_number="${devname#${devmajor}}"
  378.         removable[${array_position}]=${devmajor}${partition_number#0}
  379.         array_position=$((++array_position))
  380.     done
  381. }
  382.  
  383. # }}}
  384.  
  385. #-------------------------------------#
  386. #           MENU FUNCTIONS            #
  387. #-------------------------------------#
  388. # {{{
  389.  
  390. device_menu() {
  391.     local -a removable=( )
  392.     local -a optical=( )
  393.     local -a mounted_removable=( )
  394.     local -a mounted_optical=( )
  395.     local -i total_removable=0
  396.  
  397.     printf '%s\n' "<openbox_pipe_menu>"
  398.  
  399.     udisks --enumerate-device-files >/dev/null 2>&1
  400.     if [[ $? -ne 0 ]]; then
  401.         printf '%s\n' "<item label=\"Udisks failed.\" />"
  402.         printf '%s\n' "</openbox_pipe_menu>"
  403.         exit 0
  404.     fi
  405.  
  406.     # Here we list devices matched by the "removable_devices" regex specified in
  407.     # the configuration file.
  408.  
  409.     printf '%s\n' "<separator label=\"Removable media\" />"
  410.  
  411.     removable=( $(udisks --enumerate-device-files \
  412.         | grep -ow ${removable_devices} | sort) )
  413.  
  414.     if (( fancy_sort == 1 )); then
  415.         fancy_sort
  416.     fi
  417.  
  418.     for devname in ${removable[@]}; do
  419.         local devmajor=
  420.         local info_label=
  421.         local -i info_internal=
  422.         local -i mounted=
  423.         local -i partitions=
  424.  
  425.         # Check here to see if a device such as /dev/sdb has partitions. If there
  426.         # are partitions, such as /dev/sdb1, then hide /dev/sdb from being shown.
  427.         if [[ "${devname}" =~ ^/dev/mmcblk[0-9]+p*[0-9]* ]]; then
  428.             devmajor="${devname%%p[0-9]*}"
  429.             if [[ "${devname}" = "${devmajor}" ]]; then
  430.                 partitions="$(udisks --enumerate-device-files \
  431.                     | grep -ow -E ^${devname}p[0-9]+ -c)"
  432.                 if (( partitions > 0 )); then
  433.                     continue
  434.                 fi
  435.             fi
  436.         else
  437.             devmajor="${devname%%[0-9]*}"
  438.             if [[ "${devname}" = "${devmajor}" ]]; then
  439.                 partitions="$(udisks --enumerate-device-files \
  440.                     | grep -ow -E ^${devname}[0-9]+ -c)"
  441.                 if (( partitions > 0 )); then
  442.                     continue
  443.                 fi
  444.             fi
  445.         fi
  446.  
  447.         info_internal="$(info_internal "${devmajor}")"
  448.  
  449.         if (( info_internal == 1 )) && (( show_internal == 0 )); then
  450.             continue
  451.         fi
  452.  
  453.         if (( info_internal == 0 )) || (( show_internal == 1 )); then
  454.  
  455.             # Hide blacklisted devices.
  456.             for string in ${blacklist[@]}; do
  457.                 udisks --show-info "${devname}" | grep -E "${string}" >/dev/null 2>&1
  458.                 (( $? == 0 )) && continue 2
  459.             done
  460.        
  461.             total_removable=$((++total_removable))
  462.            
  463.             info_label="$(info_label "${devname}")"
  464.             # If no label is present, then use information about the device
  465.             # instead.
  466.             if [[ -z "${info_label}" ]]; then
  467.                 info_label="$(info_label "${devmajor}")"
  468.                 [[ -z "${info_label}" ]] && info_label="$(info_model "${devmajor}")"
  469.                 [[ -z "${info_label}" ]] && info_label="$(info_vendor "${devmajor}")"
  470.                 if [[ -z "${info_label}" ]]; then
  471.                     info_label="No label"
  472.                 else
  473.                     info_label="No label (${info_label})"
  474.                 fi
  475.             fi
  476.  
  477.             mounted="$(info_mounted "${devname}")"
  478.             if (( mounted == 0 )); then
  479.                 if (( show_removable_device_filename == 1 )); then
  480.                     printf '%s' "<menu id=\"mount${devname}\" "
  481.                     printf '%s' "label=\"${devname#/dev/}: ${info_label}\" "
  482.                     printf '%s' "execute=\"$0 --mount-menu removable "
  483.                     printf '%s' "${devname}\" />"
  484.                     printf '\n'
  485.                 else
  486.                     printf '%s' "<menu id=\"mount${devname}\" "
  487.                     printf '%s' "label=\"${info_label}\" "
  488.                     printf '%s' "execute=\"$0 --mount-menu removable "
  489.                     printf '%s' "${devname}\" />"
  490.                     printf '\n'
  491.                 fi
  492.             else
  493.                 if (( show_removable_device_filename == 1 )); then
  494.                     printf '%s' "<menu id=\"mount${devname}\" "
  495.                     printf '%s' "label=\"${devname#/dev/}: "
  496.                     printf '%s' "${info_label} (mounted)\" "
  497.                     printf '%s' "execute=\"$0 --mount-menu removable "
  498.                     printf '%s' "${devname}\" />"
  499.                     printf '\n'
  500.                 else
  501.                     printf '%s' "<menu id=\"mount${devname}\" "
  502.                     printf '%s' "label=\"${info_label} (mounted)\" "
  503.                     printf '%s' "execute=\"$0 --mount-menu removable "
  504.                     printf '%s' "${devname}\" />"
  505.                     printf '\n'
  506.                 fi
  507.                 mounted_removable[${#mounted_removable[*]}]=${devname}
  508.             fi
  509.         fi
  510.     done
  511.  
  512.     if (( total_removable == 0 )); then
  513.         printf '%s\n' "<item label=\"None\" />"
  514.     elif (( ${#mounted_removable[*]} > 0 )); then
  515.         printf '%s\n' "<item label=\"Unmount all\">"
  516.         printf '%s\n' "<action name=\"Execute\">"
  517.         printf '%s\n' "<command>$0 --unmount-all-removable \
  518.             ${mounted_removable[*]}</command>"
  519.         printf '%s\n' "<prompt>Unmount all removable devices?</prompt>"
  520.         printf '%s\n' "</action>"
  521.         printf '%s\n' "</item>"
  522.     fi
  523.  
  524.     # Here we list devices matched by the "optical_devices" regex specified in
  525.     # the configuration file.
  526.     printf '%s\n' "<separator label=\"Optical media\" />"
  527.  
  528.     optical=( $(udisks --enumerate-device-files \
  529.         | grep -ow ${optical_devices} | sort) )
  530.  
  531.     if (( ${#optical[*]} == 0 )); then
  532.         printf '%s\n' "<item label=\"None\" />"
  533.         printf '%s\n' "</openbox_pipe_menu>"
  534.         return 0
  535.     fi
  536.  
  537.     for devname in ${optical[@]}; do
  538.         local info_label=
  539.         local -i info_blank=0
  540.         local -i info_has_media=0
  541.         local -i mounted=0
  542.  
  543.         info_has_media="$(info_has_media "${devname}")"
  544.  
  545.         # Hide blacklisted devices.
  546.         for string in ${blacklist[@]}; do
  547.             udisks --show-info "${devname}" | grep -E "${string}" >/dev/null 2>&1
  548.             (( $? == 0 )) && continue 2
  549.         done
  550.  
  551.         if (( info_has_media == 0 )); then
  552.             printf '%s\n' "<item label=\"${devname#/dev/}: None\" />"
  553.         else
  554.             info_blank="$(info_blank "${devname}")"
  555.             if (( info_blank == 1 )); then
  556.                 info_label="Blank media"
  557.             else
  558.                 info_label="$(info_label ${devname})"
  559.                 [[ -z "${info_label}" ]] && info_label="$(info_model "${devname}")"
  560.                 [[ -z "${info_label}" ]] && info_label="No label"
  561.             fi
  562.  
  563.             mounted="$(info_mounted "${devname}")"
  564.             if (( mounted == 0 )); then
  565.                 if (( show_optical_device_filename == 1 )); then
  566.                     printf '%s' "<menu id=\"mount${devname}\" "
  567.                     printf '%s' "label=\"${devname#/dev/}: ${info_label}\" "
  568.                     printf '%s' "execute=\"$0 --mount-menu optical "
  569.                     printf '%s' "${devname}\" />"
  570.                     printf '\n'
  571.                 else
  572.                     printf '%s' "<menu id=\"mount${devname}\" "
  573.                     printf '%s' "label=\"${info_label}\" "
  574.                     printf '%s' "execute=\"$0 --mount-menu optical "
  575.                     printf '%s' "${devname}\" />"
  576.                     printf '\n'
  577.                 fi
  578.             else
  579.                 if (( show_optical_device_filename == 1 )); then
  580.                     printf '%s' "<menu id=\"mount${devname}\" "
  581.                     printf '%s' "label=\"${devname#/dev/}: "
  582.                     printf '%s' "${info_label} (mounted)\" "
  583.                     printf '%s' "execute=\"$0 --mount-menu optical "
  584.                     printf '%s' "${devname}\" />"
  585.                     printf '\n'
  586.                 else
  587.                     printf '%s' "<menu id=\"mount${devname}\" "
  588.                     printf '%s' "label=\"${info_label} (mounted)\" "
  589.                     printf '%s' "execute=\"$0 --mount-menu optical "
  590.                     printf '%s' "${devname}\" />"
  591.                     printf '\n'
  592.                 fi
  593.                 mounted_optical[${#mounted_optical[*]}]=${devname}
  594.             fi
  595.         fi
  596.     done
  597.    
  598.     if (( ${#mounted_optical[*]} > 0 )); then
  599.         printf '%s\n' "<item label=\"Unmount all\">"
  600.         printf '%s\n' "<action name=\"Execute\">"
  601.         printf '%s\n' "<command>$0 --unmount-all-optical \
  602.             ${mounted_optical[*]}</command>"
  603.         printf '%s\n' "<prompt>Unmount all optical devices?</prompt>"
  604.         printf '%s\n' "</action>"
  605.         printf '%s\n' "</item>"
  606.     fi
  607.  
  608.     printf '%s\n' "</openbox_pipe_menu>"
  609. }
  610. # Here we provide a submenu for each device, which displays the available
  611. # actions that can be performed.
  612. mount_menu() {
  613.     local media_type="${1}"
  614.     local devname="${2}"
  615.     local info_label="${3}"
  616.     local devname_short="${devname##*/}"
  617.     local -i info_ejectable=0
  618.     local -i mounted=0
  619.  
  620.     printf '%s\n' "<openbox_pipe_menu>"
  621.  
  622.     if [[ "${media_type}" = "removable" ]]; then
  623.         if (( show_removable_device_filename == 1 )); then
  624.             printf '%s\n' "<separator label=\"${devname}\" />"
  625.         else
  626.             printf '%s\n' "<separator label=\"${info_label}\" />"
  627.         fi
  628.     elif [[ "${media_type}" = "optical" ]]; then
  629.         if (( show_optical_device_filename == 1 )); then
  630.             printf '%s\n' "<separator label=\"${devname}\" />"
  631.         else
  632.             printf '%s\n' "<separator label=\"${info_label}\" />"
  633.         fi
  634.     fi
  635.  
  636.     mounted="$(info_mounted "${devname}")"
  637.  
  638.     if (( mounted == 0 )); then
  639.         printf '%s\n' "<item label=\"Open\">"
  640.         printf '%s\n' "<action name=\"Execute\">"
  641.         printf '%s\n' "<command>$0 --mount-and-open ${devname}</command>"
  642.         printf '%s\n' "</action>"
  643.         printf '%s\n' "</item>"
  644.  
  645.         printf '%s\n' "<item label=\"Mount\">"
  646.         printf '%s\n' "<action name=\"Execute\">"
  647.         printf '%s\n' "<command>$0 --mount-device ${devname}</command>"
  648.         printf '%s\n' "</action>"
  649.         printf '%s\n' "</item>"
  650.     else
  651.         printf '%s\n' "<item label=\"Open\">"
  652.         printf '%s\n' "<action name=\"Execute\">"
  653.         printf '%s\n' "<command>$0 --open-directory ${devname}</command>"
  654.         printf '%s\n' "</action>"
  655.         printf '%s\n' "</item>"
  656.  
  657.         printf '%s\n' "<item label=\"Unmount\">"
  658.         printf '%s\n' "<action name=\"Execute\">"
  659.         printf '%s\n' "<command>$0 --unmount-device ${devname}</command>"
  660.         printf '%s\n' "</action>"
  661.         printf '%s\n' "</item>"
  662.     fi
  663.    
  664.     info_ejectable="$(info_ejectable "${devname}")"
  665.  
  666.     if (( info_ejectable == 1 )); then
  667.         printf '%s\n' "<item label=\"Eject\">"
  668.         printf '%s\n' "<action name=\"Execute\">"
  669.         printf '%s\n' "<command>$0 --eject-device ${devname}</command>"
  670.         printf '%s\n' "</action>"
  671.         printf '%s\n' "</item>"
  672.     fi
  673.  
  674.     printf '%s' "<menu id=\"showinfo${devname##*/}\" "
  675.     printf '%s' "label=\"Info\" "
  676.     printf '%s' "execute=\"$0 --show-info ${devname}\" />"
  677.     printf '\n'
  678.  
  679.     printf '%s\n' "</openbox_pipe_menu>"
  680. }
  681. # }}}
  682.  
  683. #-------------------------------------#
  684. #              INT MAIN               #
  685. #-------------------------------------#
  686.  
  687. if (( $# == 0 )); then
  688.     device_menu
  689.     exit 0
  690. fi
  691.  
  692. # The script calls itself with different options in order to get nested pipe
  693. # menus.
  694. case "${1}" in
  695.     "--mount-menu")
  696.         mount_menu ${2} ${3}
  697.         ;;
  698.     "--mount-device")
  699.         action_mount "${2}"
  700.         ;;
  701.     "--unmount-device")
  702.         action_unmount "${2}"
  703.         ;;
  704.     "--eject-device")
  705.         action_eject "${2}"
  706.         ;;
  707.     "--open-directory")
  708.         action_open "${2}"
  709.         ;;
  710.     "--mount-and-open")
  711.         action_mount "${2}" && action_open "${2}"
  712.         ;;
  713.     "--show-info")
  714.         action_info "${2}"
  715.         ;;
  716.     "--unmount-all-removable")
  717.         shift 1 && action_unmount_all $@
  718.         ;;
  719.     "--unmount-all-optical")
  720.         shift 1 && action_unmount_all $@
  721.         ;;
  722. esac
  723.  
  724. # vim: set ts=4 sw=4 noet foldmethod=marker :
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement