changeset 12:f004b506c789

misc: use same hierarchy as installation
author David Demelier <markand@malikania.fr>
date Wed, 08 Nov 2017 08:53:04 +0100
parents 416a0219249d
children f73e67cd0b71
files INSTALL.md Makefile bin/dmenu_bg bin/dmenu_filesel bin/dmenu_power bin/dmenu_ssh dmenu.subr dmenu_bg dmenu_filesel dmenu_power dmenu_ssh libexec/dmenutools/dmenu.subr
diffstat 12 files changed, 500 insertions(+), 510 deletions(-) [+]
line wrap: on
line diff
--- a/INSTALL.md	Wed Nov 08 06:39:02 2017 +0100
+++ b/INSTALL.md	Wed Nov 08 08:53:04 2017 +0100
@@ -11,9 +11,11 @@
 Basic installation
 ------------------
 
-You can use all scripts directly or you can install it using `make install`. By
-default it will be installed to **/usr/local/bin**, this can be changed using
-PREFIX variable.
+Add the **bin/** directory to your path or you can install the scripts using
+`make install` target as root.
+
+An additional variable `PREFIX` can be set to specify the installation
+directory.
 
 Examples:
 
--- a/Makefile	Wed Nov 08 06:39:02 2017 +0100
+++ b/Makefile	Wed Nov 08 08:53:04 2017 +0100
@@ -17,8 +17,8 @@
 PREFIX=/usr/local
 
 install:
-	install -D -m 0755 dmenu_bg ${PREFIX}/bin
-	install -D -m 0755 dmenu_filesel ${PREFIX}/bin
-	install -D -m 0755 dmenu_power ${PREFIX}/bin
-	install -D -m 0755 dmenu_ssh ${PREFIX}/bin
-	install -D -m 0644 dmenu.subr ${PREFIX}/libexec/dmenutools/dmenu.subr
+	install -D -m 0755 bin/dmenu_bg ${PREFIX}/bin
+	install -D -m 0755 bin/dmenu_filesel ${PREFIX}/bin
+	install -D -m 0755 bin/dmenu_power ${PREFIX}/bin
+	install -D -m 0755 bin/dmenu_ssh ${PREFIX}/bin
+	install -D -m 0644 libexec/dmenutools/dmenu.subr ${PREFIX}/libexec/dmenutools/dmenu.subr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/dmenu_bg	Wed Nov 08 08:53:04 2017 +0100
@@ -0,0 +1,63 @@
+#!/bin/sh
+#
+# dmenu_bg -- prompt for a background
+#
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+TOOL="bg"
+TOP=$(dirname "$(readlink -f "$0")")
+
+dmt_bg_usage()
+{
+    echo "usage: dmenu_bg [directory]" 1>&2;
+    exit 1
+}
+
+. ${TOP}/../libexec/dmenutools/dmenu.subr
+
+# Check for an optional directory.
+if [ $# -ge 1 ]; then
+    directory="$1"
+elif [ -n "${bg_directory}" ]; then
+    directory="${bg_directory}"
+else
+    directory="${XDG_PICTURES_DIR:-${HOME}}"
+fi
+
+# Use user bg_cmd if defined, otherwise find one.
+if [ -z "${bg_cmd}" ]; then
+    if command -v feh > /dev/null 2>&1; then
+        bg_cmd="feh --bg-scale"
+    elif command -v hsetroot > /dev/null 2>&1; then
+        bg_cmd="hsetroot -fill"
+    elif command -v fbsetbg > /dev/null 2>&1; then
+        bg_cmd="fbsetbg"
+    else
+        dmt_fatal "no background manager found"
+        # NOTREACHED
+    fi
+fi
+
+# Optional lines.
+lines=${bg_lines:-16}
+
+file=$(${TOP}/dmenu_filesel -l ${lines} ${directory})
+
+if [ -n "${file}" ]; then
+    ${bg_cmd} ${file}
+fi
+
+# vim: syntax=sh:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/dmenu_filesel	Wed Nov 08 08:53:04 2017 +0100
@@ -0,0 +1,111 @@
+#!/bin/sh
+#
+# dmenu_filesel -- prompt for a file or directory
+#
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+TOOL="filesel"
+TOP=$(dirname "$(readlink -f "$0")")
+
+dmt_filesel_usage()
+{
+    echo "usage: dmenu_filesel [-t file|directory]" 1>&2;
+    exit 1
+}
+
+dmt_filesel_list()
+{
+    # Allow '.' only if traget must be directory.
+    if [ "${ftype}" = "directory" ]; then
+        list=".\n"
+    fi
+    list="${list}..\n"
+
+    if [ -n "$(ls -A ${root})" ]; then
+        # TODO: Add some filters.
+        for i in ${root}*; do
+            list="${list}$(basename "${i}")\n"
+        done
+    fi
+
+    echo -e ${list} | sort
+}
+
+ftype="file"
+lines="16"
+
+while getopts "l:t:" opt; do
+    case ${opt} in
+    l)
+        lines=${OPTARG}
+        ;;
+    t)
+        if [ "${OPTARG}" = "f" ] || [ "${OPTARG}" = "file" ]; then
+            ftype="file"
+        elif [ "${OPTARG}" = "d" ] || [ "${OPTARG}" = "directory" ]; then
+            ftype="directory"
+        fi
+        ;;
+    *)
+        dmt_filesel_usage
+        # NOTREACHED
+    esac
+done
+
+shift $((OPTIND - 1))
+
+# Start from here.
+if [ $# -ge 1 ]; then
+    root="${1}/"
+else
+    root="/"
+fi
+
+while [ -z "${selection}" ]; do
+    entry="$(dmt_filesel_list | dmenu -p "${root}" -l ${lines})"
+
+    # Abort on empty selection.
+    if [ -z "${entry}" ]; then
+        exit 1
+    fi
+
+    if [ "${entry}" = ".." ]; then
+        parent="$(dirname ${root})"
+
+        if [ "${parent}" = "/" ]; then
+            root="/"
+        else
+            root="${parent}/"
+        fi
+
+        continue;
+    fi
+
+    # If directory, goes deeper.
+    path="${root}${entry}"
+
+    if [ -d "${path}" ]; then
+        if [ -r "${path}" ]; then
+            root="${path}/"
+        else
+            continue
+        fi
+    else
+        selection="${path}"
+    fi
+done
+
+echo "${selection}"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/dmenu_power	Wed Nov 08 08:53:04 2017 +0100
@@ -0,0 +1,172 @@
+#!/bin/sh
+#
+# dmenu_power -- dmenu prompt for system shutdown
+#
+# Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+TOOL="power"
+TOP=$(dirname "$(readlink -f "$0")")
+
+. ${TOP}/../libexec/dmenutools/dmenu.subr
+
+# Default user values.
+: "${power_hibernate_enable:=1}"
+: "${power_reboot_enable:=1}"
+: "${power_shutdown_enable:=1}"
+: "${power_suspend_enable:=1}"
+
+os=$(uname -s)
+
+# Check for systemctl on Linux.
+if command -v systemctl > /dev/null 2>&1; then
+    has_systemctl=1
+fi
+
+#
+# Create a list of commands.
+# -------------------------------------------------------------------
+#
+dmt_power_list()
+{
+    for i in hibernate reboot shutdown suspend; do
+        eval enabled="\${power_${i}_enable}"
+
+        if [ ${enabled} -eq 1 ]; then
+            list="${list}$i\n"
+        fi
+    done
+
+    echo -e $(echo ${list} | sed -e s'/\\n$//')
+}
+
+#
+# Do hibernation
+# -------------------------------------------------------------------
+#
+# Supports: Linux, OpenBSD
+#
+dmt_power_hibernate()
+{
+    if [ -n "${power_hibernate_cmd}" ]; then
+        ${power_hibernate_cmd}
+    elif [ "${has_systemctl}" -eq 1 ]; then
+        systemctl hibernate
+    else
+        case "${os}" in
+        Linux)
+            echo 'disk' | sudo -A tee -a /sys/power/state
+            ;;
+        OpenBSD)
+            ZZZ
+            ;;
+        *)
+            dmt_fatal "hibernation not supported on this system"
+            ;;
+        esac
+    fi
+}
+
+#
+# Do reboot
+# -------------------------------------------------------------------
+#
+# Supports: all
+#
+dmt_power_reboot()
+{
+    if [ -n "${power_reboot_cmd}" ]; then
+        ${power_reboot_cmd}
+    elif [ "${has_systemctl}" -eq 1 ]; then
+        systemctl reboot
+    else
+        sudo -A shutdown -r now
+    fi
+}
+
+#
+# Do shutdown
+# -------------------------------------------------------------------
+#
+# Supports: all
+#
+dmt_power_shutdown()
+{
+    if [ -n "${power_shutdown_cmd}" ]; then
+        ${power_shutdown_cmd}
+    elif [ "${has_systemctl}" -eq 1 ]; then
+        systemctl poweroff
+    else
+        case ${os} in
+        Linux)
+            sudo -A shutdown -h now
+            ;;
+        *)
+            sudo -A shutdown -p now
+            ;;
+        esac
+    fi
+}
+
+#
+# Do suspend
+# -------------------------------------------------------------------
+#
+# Supports: Linux, OpenBSD, FreeBSD (if has not been broken in a new release).
+#
+dmt_power_suspend()
+{
+    if [ -n "${power_suspend_cmd}" ]; then
+        ${power_suspend_cmd}
+    elif [ "${has_systemctl}" -eq 1 ]; then
+        systemctl suspend
+    else
+        case "${os}" in
+        Linux)
+            echo 'mem' | sudo -A tee -a /sys/power/state
+            ;;
+        FreeBSD)
+            # Good luck.
+            sudo -A acpiconf -s 3
+            ;;
+        OpenBSD)
+            zzz
+            ;;
+        *)
+            dmt_fatal "suspend not supported on this system"
+            ;;
+        esac
+    fi
+}
+
+cmd=$(dmt_power_list | dmenu -p "power")
+
+# TODO: change this with a substitution.
+case "${cmd}" in
+hibernate)
+    dmt_power_hibernate
+    ;;
+reboot)
+    dmt_power_reboot
+    ;;
+shutdown)
+    dmt_power_shutdown
+    ;;
+suspend)
+    dmt_power_suspend
+    ;;
+esac
+
+# vim: syntax=sh:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/dmenu_ssh	Wed Nov 08 08:53:04 2017 +0100
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# dmenu_ssh -- ssh prompt for dmenu
+#
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+TOOL="ssh"
+TOP=$(dirname "$(readlink -f "$0")")
+
+. ${TOP}/../libexec/dmenutools/dmenu.subr
+
+# Default user values.
+: "${ssh_lines:=0}"
+
+# Requirements.
+if [ -z "${term}" ]; then
+    dmt_fatal "no terminal set, see dmenutools.conf"
+fi
+if ! which ssh > /dev/null 2>&1; then
+    dmt_fatal "missing ssh"
+fi
+if [ ! -r "${HOME}/.ssh/config" ]; then
+    dmt_fatal "missing ${HOME}/.ssh/config" 1>&2;
+fi
+
+args="-p ssh"
+
+if [ "${ssh_lines}" -gt 0 ]; then
+    args="-l ${ssh_lines} ${args}"
+fi
+
+host=$(grep -Ei "Host\s" ${HOME}/.ssh/config | awk '{ print $2 '} | dmenu ${args})
+
+if [ -n "${host}" ]; then
+    ${term} -e ssh ${host}
+fi
--- a/dmenu.subr	Wed Nov 08 06:39:02 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-#!/bin/sh
-#
-# dmenu.subr -- common operations for dmenutools
-#
-# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-# Directory for configuration.
-if [ -z "${XDG_CONFIG_HOME}" ]; then
-    XDG_CONFIG_HOME=${HOME}/.config
-fi
-
-# Open user optional configuration.
-if [ -r ${XDG_CONFIG_HOME}/dmenutools.conf ]; then
-    . ${XDG_CONFIG_HOME}/dmenutools.conf
-fi
-
-# Find a terminal.
-if [ -z "${term}" ]; then
-    for t in urxvt st terminator terminator xterm; do
-        if command -v ${t} > /dev/null 2>&1; then
-            term=${t}
-            break
-        fi
-    done
-fi
-
-#
-# dmt_fatal
-# -------------------------------------------------------------------
-#
-# Log a fatal error through fatal_cmd helper.
-# 
-dmt_fatal()
-{
-    ${fatal_cmd} "$1"
-    exit 1
-}
-
-#
-# dmt_run
-# -------------------------------------------------------------------
-#
-# Run dmenu with parameters specified from both configuration and arguments.
-#
-dmt_run()
-{
-    dmenu $*
-}
-
-#
-# dmt_boolean
-# -------------------------------------------------------------------
-# 
-# Check if a variable is a boolean value.
-#
-dmt_boolean()
-{
-    v=$(echo $1 | tr '[:upper:]' '[:lower:]')
-
-    if [ $v = "1" ] || [ $v = "yes" ] || [ $v = "on" ] || [ $v = "true" ]; then
-        return 0
-    fi
-
-    return 1
-}
-
-# Determine a fatal helper.
-if [ -z "${fatal_cmd}" ]; then
-    if command -v notify-send > /dev/null 2>&1; then
-        fatal_cmd="notify-send"
-    elif command -v xmessage > /dev/null 2>&1; then
-        fatal_cmd="xmessage"
-    else
-        fatal_cmd="echo"
-    fi
-fi
-
-if ! command -v dmenu > /dev/null 2>&1; then
-    dmt_fatal "dmenu is missing"
-fi
-
-# vim: syntax=sh:
--- a/dmenu_bg	Wed Nov 08 06:39:02 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-#!/bin/sh
-#
-# dmenu_bg -- prompt for a background
-#
-# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="bg"
-TOP=$(dirname "$(readlink -f "$0")")
-
-dmt_bg_usage()
-{
-    echo "usage: dmenu_bg [directory]" 1>&2;
-    exit 1
-}
-
-if [ -r ${TOP}/dmenu.subr ]; then
-    . ${TOP}/dmenu.subr
-elif [ -r ${TOP}/../libexec/dmenutools/dmenu.subr ]; then
-    . ${TOP}/../libexec/dmenutools/dmenu.subr
-fi
-
-# Check for an optional directory.
-if [ $# -ge 1 ]; then
-    directory="$1"
-elif [ -n "${bg_directory}" ]; then
-    directory="${bg_directory}"
-else
-    directory="${XDG_PICTURES_DIR:-${HOME}}"
-fi
-
-# Use user bg_cmd if defined, otherwise find one.
-if [ -z "${bg_cmd}" ]; then
-    if command -v feh > /dev/null 2>&1; then
-        bg_cmd="feh --bg-scale"
-    elif command -v hsetroot > /dev/null 2>&1; then
-        bg_cmd="hsetroot -fill"
-    elif command -v fbsetbg > /dev/null 2>&1; then
-        bg_cmd="fbsetbg"
-    else
-        dmt_fatal "no background manager found"
-        # NOTREACHED
-    fi
-fi
-
-# Optional lines.
-lines=${bg_lines:-16}
-
-file=$(${TOP}/dmenu_filesel -l ${lines} ${directory})
-
-if [ -n "${file}" ]; then
-    ${bg_cmd} ${file}
-fi
-
-# vim: syntax=sh:
--- a/dmenu_filesel	Wed Nov 08 06:39:02 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-#!/bin/sh
-#
-# dmenu_filesel -- prompt for a file or directory
-#
-# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="filesel"
-TOP=$(dirname "$(readlink -f "$0")")
-
-dmt_filesel_usage()
-{
-    echo "usage: dmenu_filesel [-t file|directory]" 1>&2;
-    exit 1
-}
-
-dmt_filesel_list()
-{
-    # Allow '.' only if traget must be directory.
-    if [ "${ftype}" = "directory" ]; then
-        list=".\n"
-    fi
-    list="${list}..\n"
-
-    if [ -n "$(ls -A ${root})" ]; then
-        # TODO: Add some filters.
-        for i in ${root}*; do
-            list="${list}$(basename "${i}")\n"
-        done
-    fi
-
-    echo -e ${list} | sort
-}
-
-ftype="file"
-lines="16"
-
-while getopts "l:t:" opt; do
-    case ${opt} in
-    l)
-        lines=${OPTARG}
-        ;;
-    t)
-        if [ "${OPTARG}" = "f" ] || [ "${OPTARG}" = "file" ]; then
-            ftype="file"
-        elif [ "${OPTARG}" = "d" ] || [ "${OPTARG}" = "directory" ]; then
-            ftype="directory"
-        fi
-        ;;
-    *)
-        dmt_filesel_usage
-        # NOTREACHED
-    esac
-done
-
-shift $((OPTIND - 1))
-
-# Start from here.
-if [ $# -ge 1 ]; then
-    root="${1}/"
-else
-    root="/"
-fi
-
-while [ -z "${selection}" ]; do
-    entry="$(dmt_filesel_list | dmenu -p "${root}" -l ${lines})"
-
-    # Abort on empty selection.
-    if [ -z "${entry}" ]; then
-        exit 1
-    fi
-
-    if [ "${entry}" = ".." ]; then
-        parent="$(dirname ${root})"
-
-        if [ "${parent}" = "/" ]; then
-            root="/"
-        else
-            root="${parent}/"
-        fi
-
-        continue;
-    fi
-
-    # If directory, goes deeper.
-    path="${root}${entry}"
-
-    if [ -d "${path}" ]; then
-        if [ -r "${path}" ]; then
-            root="${path}/"
-        else
-            continue
-        fi
-    else
-        selection="${path}"
-    fi
-done
-
-echo "${selection}"
--- a/dmenu_power	Wed Nov 08 06:39:02 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-#!/bin/sh
-#
-# dmenu_power -- dmenu prompt for system shutdown
-#
-# Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="power"
-TOP=$(dirname "$(readlink -f "$0")")
-
-if [ -r ${TOP}/dmenu.subr ]; then
-    . ${TOP}/dmenu.subr
-elif [ -r ${TOP}/../libexec/dmenutools/dmenu.subr ]; then
-    . ${TOP}/../libexec/dmenutools/dmenu.subr
-fi
-
-# Default user values.
-: "${power_hibernate_enable:=1}"
-: "${power_reboot_enable:=1}"
-: "${power_shutdown_enable:=1}"
-: "${power_suspend_enable:=1}"
-
-os=$(uname -s)
-
-# Check for systemctl on Linux.
-if command -v systemctl > /dev/null 2>&1; then
-    has_systemctl=1
-fi
-
-#
-# Create a list of commands.
-# -------------------------------------------------------------------
-#
-dmt_power_list()
-{
-    for i in hibernate reboot shutdown suspend; do
-        eval enabled="\${power_${i}_enable}"
-
-        if [ ${enabled} -eq 1 ]; then
-            list="${list}$i\n"
-        fi
-    done
-
-    echo -e $(echo ${list} | sed -e s'/\\n$//')
-}
-
-#
-# Do hibernation
-# -------------------------------------------------------------------
-#
-# Supports: Linux, OpenBSD
-#
-dmt_power_hibernate()
-{
-    if [ -n "${power_hibernate_cmd}" ]; then
-        ${power_hibernate_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl hibernate
-    else
-        case "${os}" in
-        Linux)
-            echo 'disk' | sudo -A tee -a /sys/power/state
-            ;;
-        OpenBSD)
-            ZZZ
-            ;;
-        *)
-            dmt_fatal "hibernation not supported on this system"
-            ;;
-        esac
-    fi
-}
-
-#
-# Do reboot
-# -------------------------------------------------------------------
-#
-# Supports: all
-#
-dmt_power_reboot()
-{
-    if [ -n "${power_reboot_cmd}" ]; then
-        ${power_reboot_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl reboot
-    else
-        sudo -A shutdown -r now
-    fi
-}
-
-#
-# Do shutdown
-# -------------------------------------------------------------------
-#
-# Supports: all
-#
-dmt_power_shutdown()
-{
-    if [ -n "${power_shutdown_cmd}" ]; then
-        ${power_shutdown_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl poweroff
-    else
-        case ${os} in
-        Linux)
-            sudo -A shutdown -h now
-            ;;
-        *)
-            sudo -A shutdown -p now
-            ;;
-        esac
-    fi
-}
-
-#
-# Do suspend
-# -------------------------------------------------------------------
-#
-# Supports: Linux, OpenBSD, FreeBSD (if has not been broken in a new release).
-#
-dmt_power_suspend()
-{
-    if [ -n "${power_suspend_cmd}" ]; then
-        ${power_suspend_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl suspend
-    else
-        case "${os}" in
-        Linux)
-            echo 'mem' | sudo -A tee -a /sys/power/state
-            ;;
-        FreeBSD)
-            # Good luck.
-            sudo -A acpiconf -s 3
-            ;;
-        OpenBSD)
-            zzz
-            ;;
-        *)
-            dmt_fatal "suspend not supported on this system"
-            ;;
-        esac
-    fi
-}
-
-cmd=$(dmt_power_list | dmenu -p "power")
-
-# TODO: change this with a substitution.
-case "${cmd}" in
-hibernate)
-    dmt_power_hibernate
-    ;;
-reboot)
-    dmt_power_reboot
-    ;;
-shutdown)
-    dmt_power_shutdown
-    ;;
-suspend)
-    dmt_power_suspend
-    ;;
-esac
-
-# vim: syntax=sh:
--- a/dmenu_ssh	Wed Nov 08 06:39:02 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-#!/bin/sh
-#
-# dmenu_ssh -- ssh prompt for dmenu
-#
-# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="ssh"
-TOP=$(dirname "$(readlink -f "$0")")
-
-if [ -r ${TOP}/dmenu.subr ]; then
-    . ${TOP}/dmenu.subr
-elif [ -r ${TOP}/../libexec/dmenutools/dmenu.subr ]; then
-    . ${TOP}/../libexec/dmenutools/dmenu.subr
-fi
-
-# Default user values.
-: "${ssh_lines:=0}"
-
-# Requirements.
-if [ -z "${term}" ]; then
-    dmt_fatal "no terminal set, see dmenutools.conf"
-fi
-if ! which ssh > /dev/null 2>&1; then
-    dmt_fatal "missing ssh"
-fi
-if [ ! -r "${HOME}/.ssh/config" ]; then
-    dmt_fatal "missing ${HOME}/.ssh/config" 1>&2;
-fi
-
-args="-p ssh"
-
-if [ "${ssh_lines}" -gt 0 ]; then
-    args="-l ${ssh_lines} ${args}"
-fi
-
-host=$(grep -Ei "Host\s" ${HOME}/.ssh/config | awk '{ print $2 '} | dmenu ${args})
-
-if [ -n "${host}" ]; then
-    ${term} -e ssh ${host}
-fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libexec/dmenutools/dmenu.subr	Wed Nov 08 08:53:04 2017 +0100
@@ -0,0 +1,95 @@
+#!/bin/sh
+#
+# dmenu.subr -- common operations for dmenutools
+#
+# Copyright (c) 2016-2017 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+# Directory for configuration.
+if [ -z "${XDG_CONFIG_HOME}" ]; then
+    XDG_CONFIG_HOME=${HOME}/.config
+fi
+
+# Open user optional configuration.
+if [ -r ${XDG_CONFIG_HOME}/dmenutools.conf ]; then
+    . ${XDG_CONFIG_HOME}/dmenutools.conf
+fi
+
+# Find a terminal.
+if [ -z "${term}" ]; then
+    for t in urxvt st terminator terminator xterm; do
+        if command -v ${t} > /dev/null 2>&1; then
+            term=${t}
+            break
+        fi
+    done
+fi
+
+#
+# dmt_fatal
+# -------------------------------------------------------------------
+#
+# Log a fatal error through fatal_cmd helper.
+# 
+dmt_fatal()
+{
+    ${fatal_cmd} "$1"
+    exit 1
+}
+
+#
+# dmt_run
+# -------------------------------------------------------------------
+#
+# Run dmenu with parameters specified from both configuration and arguments.
+#
+dmt_run()
+{
+    dmenu $*
+}
+
+#
+# dmt_boolean
+# -------------------------------------------------------------------
+# 
+# Check if a variable is a boolean value.
+#
+dmt_boolean()
+{
+    v=$(echo $1 | tr '[:upper:]' '[:lower:]')
+
+    if [ $v = "1" ] || [ $v = "yes" ] || [ $v = "on" ] || [ $v = "true" ]; then
+        return 0
+    fi
+
+    return 1
+}
+
+# Determine a fatal helper.
+if [ -z "${fatal_cmd}" ]; then
+    if command -v notify-send > /dev/null 2>&1; then
+        fatal_cmd="notify-send"
+    elif command -v xmessage > /dev/null 2>&1; then
+        fatal_cmd="xmessage"
+    else
+        fatal_cmd="echo"
+    fi
+fi
+
+if ! command -v dmenu > /dev/null 2>&1; then
+    dmt_fatal "dmenu is missing"
+fi
+
+# vim: syntax=sh: