#!/bin/sh set -eu msg_start='[....] Starting %s... ' msg_stop='[....] Stopping %s... ' msg_restart='[....] Restarting %s... ' msg_start_ok='[ ok ] Starting %s... done' msg_stop_ok='[ ok ] Stopping %s... done' msg_restart_ok='[ ok ] Restarting %s... done' msg_start_fail='[fail] Starting %s... failed' msg_stop_fail='[fail] Stopping %s... failed' msg_restart_fail='[fail] Restarting %s... failed' XDG_DATA_HOME= XDG_CONFIG_HOME= XDG_DATA_DIRS= XDG_CONFIG_DIRS= XDG_CACHE_HOME= PIDDIR= SERVICES= load_service() { local service="${1}" shift 1 XDG_DATA_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}" XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-${HOME}/.config}" XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" XDG_CONFIG_DIRS="${XDG_CONFIG_DIRS:-/etc/xdg}" XDG_CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/.cache}" PIDDIR="${XDG_CACHE_HOME}/homerc/run" # Default functions stop() { :; } restart() { stop && start; } status() { :; } # TODO: Errors . "${XDG_CONFIG_HOME}/homerc/${service}" || return 1 return 0 } log() { local service="${1}" local action="${2}" local var="${3}" shift 3 if ! tty 1>/dev/null 2>&1; then return 0 fi case "${action}" in 'start' | 'stop' | 'restart') eval "printf \"\\r\${msg_${action}${var}}\" \"\${service}\"" case "${var}" in ?*) printf '\n' esac esac return 0 } act() { local service="${1}" local action="${2}" shift 2 local out= log "${service}" "${action}" '' if out="$("${action}" 2>&1)"; then log "${service}" "${action}" '_ok' case "${out}" in ?*) printf '%s\n' "${out}" esac return 0 else log "${service}" "${action}" '_fail' case "${out}" in ?*) printf '%s\n' "${out}" esac return 1 fi } match_session() { local needle="${1}" local haystack="${2}" shift 2 local hay= IFS=',' for hay in ${haystack}; do unset IFS case "${hay}" in '') continue;; "${needle}" | "${needle}:"*) return 0;; esac done unset IFS return 1 } chg_sessions() { local service="${1}" local old_sessions="${2}" local new_sessions="${3}" shift 3 local is_running= local should_run= is_running=false should_run=false for session in ${SESSIONS}; do if match_session "${session}" "${old_sessions}"; then is_running=true fi if match_session "${session}" "${new_sessions}"; then should_run=true fi done if ${is_running} && ! ${should_run}; then act "${service}" 'stop' || return 1 fi if ! ${is_running} && ${should_run}; then act "${service}" 'start' || return 1 fi return 0 } usage() { printf 'Usage: %s {start|stop|restart|status}\n' "${progname}" return 0 } main() { local service= local action= if [ ${#} -ne 2 ]; then usage 1>&2 return 1 fi service="${1}" action="${2}" case "${action}" in 'start' | 'stop' | 'restart' | 'status') load_service "${service}" || return 1 act "${service}" "${action}" || return 1 ;; *';'*) load_service "${service}" || return 1 chg_sessions "${service}" \ "${action%%;*}" "${action#*;}" || return 1 ;; *) usage 1>&2 return 1 ;; esac return 0 } main "${@}"