#!/bin/bash
#
# /sbin/service         Handle boot and runlevel services
#

sd_booted()
{
    test -d /sys/fs/cgroup/systemd/
}

#
# Only root should do
#
if ! sd_booted && test "$(id -u)" -ne 0; then
   echo "${0##*/}: only root can use ${0##*/}" 1>&2
   exit 1
fi

#
# Location of our service scripts
#
RCDIR="/etc/init.d"

# legacy actions
actiondir="/usr/lib/initscripts/legacy-actions"

#
# Clean environment
#
PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
test -n "$TERM" || TERM=raw
test -n "$SYSTEMD_NO_WRAP" && export SYSTEMD_NO_WRAP
LANG=POSIX
export PATH TERM LANG

typeset -i reloaded=0
daemon_reload()
{
        local state
        ((reloaded)) && return
        state=$(systemctl --full --no-legend --no-pager --property=NeedDaemonReload show "$1" 2>/dev/null)
        test "$state" = "NeedDaemonReload=no" && return
        systemctl daemon-reload
        let reloaded++
}

is_service()
{
        local state=$(systemctl --full --no-legend --no-pager --type=service --property=LoadState show "$1.service" 2>/dev/null)
        test "$state" = "LoadState=loaded"
}

is_target()
{
        local state=$(systemctl --full --no-legend --no-pager --type=target --property=LoadState show "$1.target" 2>/dev/null)
        test "$state" = "LoadState=loaded"
}


is_systemd_action()
{
        case "$1" in
                start|stop|reload|restart|try-restart|force-reload|status) return 0 ;;
        esac
        return 1
}
exec_rc ()
{
    local rc=''
    local -i ret
    if sd_booted && test -z "$SYSTEMD_NO_WRAP"; then
        if is_systemd_action "$2"; then
                if is_service "$1"; then
                        daemon_reload "$1.service"
                        systemctl "$2" --full "$1.service"
                        ret=$?
                        if [ "$2" = status ]; then
                                systemctl is-active "$1.service" > /dev/null 2>&1
                                ret=$?
                        fi
                        return $ret
                elif is_target "$1"; then
                        daemon_reload "$1.target"
                        systemctl "$2" "$1.target"
                        ret=$?
                        if [ $ret -eq 0 -a "$2" = "status" ]; then
                                local l=$(systemctl show -p ConsistsOf $1.target 2>/dev/null)
                                local s
                                systemctl is-active "$1.target" > /dev/null 2>&1
                                ret=$?
                                test $ret -ne 0 && return $ret
                                for s in ${l#ConsistsOf=} ; do
                                        echo
                                        systemctl status --full "$s"
                                        systemctl is-active "$s" > /dev/null 2>&1
                                        ret=$?
                                        test $ret -ne 0 && return $ret
                                done
                        fi
                        return $ret
                fi
                echo "$1 is neither service nor target!?" >&2
                return "1"
        elif [ -x "$actiondir/$1/$2" ]; then
                rc="$actiondir/$1/$2"
                shift 2
        elif [ ${0##*/} = service ] ; then
                echo "Usage: $0 "$1" {start|stop|reload|restart|try-restart|force-reload|status}"
                return 1
        else
                echo "Usage: $0 {start|stop|reload|restart|try-restart|force-reload|status}"
                return 1
        fi
    fi
    if [ -z "$rc" ]; then
        rc="${RCDIR}/$1"
        shift
    fi
    env -i LANG=$LANG PATH=$PATH TERM=$TERM SYSTEMD_NO_WRAP=$SYSTEMD_NO_WRAP "$rc" ${1+"$@"}
}

check_rc ()
{
        local rc="$1"
        shift
        if test -x ${RCDIR}/$rc; then
                return 0
        fi
        if sd_booted ; then
                if is_service "$rc" || is_target "$rc"; then
                        return 0
                fi
        fi
        return 1
}

check_wrapper ()
{
    local n="${0##*/}"
    if test "${n#rc}" != "$n"; then
        rc="${n#rc}"
        return 0
    else
        rc="$1"
        return 1
    fi
}

usage ()
{
    echo "Usage: ${0##*/} [--help | --status-all | <service> [<args>| --full-restart]]" 1>&2
    exit 1
}

help ()
{
    echo "Usage: ${0##*/} [<options> | <service> [<args>]]"
    echo "Available <options>:"
    echo "  -h,--help        This help."
    echo "  -s,--status-all  List out status of all services."
    echo "Usage for specific <service>:"
    echo "  ${0##*/} service_name argument [option]"
    exit 0
}


  status_all=0
full_restart=0
        args=""
while test $# -gt 0; do
    opt=
    if test "${1::1}" = "-"; then
        if test ${#1} -gt 2 -a "${1::2}" = "--" ; then
            opt="${1:2}"
        else
            opt="${1:1}"
        fi
        shift
    else
        args="${args:+$args }$1"
        shift
        continue
    fi

    case "$opt" in
    status-all|s)   status_all=1 ;;
    full-restart) full_restart=1 ;;
    h*)                     help ;;
    *)                     usage ;;
    esac

    case "${0##*/}" in
    rc*)
        if [ -n "$opt" ]; then
            echo "Usage: $0 {start|stop|reload|restart|try-restart|force-reload|status}"
            exit 1
        fi
    esac
done


#
# Determine the status of all services
#
if test $status_all -gt 0 ; then
    if test -n "$args" ; then
        usage 1>&2
        exit 1
    fi
    if sd_booted; then
            systemctl --full --no-legend --no-pager --type=service list-units
    else
            for rc in ${RCDIR}/*; do
                test ! -x "$rc" -o -d "$rc"    && continue
                rc=${rc##*/}
                case "$rc" in
                *.local|*.rpm*|*.ba*|*.old|*.new) continue ;;
                *.dpkg|*.save|*.swp|*.core)       continue ;;
                *.disabled)                       continue ;;
                boot|rc|single|halt|reboot)       continue ;;
                powerfail|rx|Makefile|README)     continue ;;
                skeleton|*.d)                     continue ;;
                esac
                exec_rc $rc status
            done
    fi
    exit 0
fi

#
# Do a full restart of a few services
#
if test $full_restart -gt 0 ; then
    if test -z "$args" ; then
        usage 1>&2
        exit 1
    fi
    for rc in $args; do
        if check_rc $rc ; then
            echo "${0##*/}: no such service $rc" 1>&2
            exit 1
        fi
    done
    status=0
    for rc in $args; do
        exec_rc $rc stop
        exec_rc $rc start
        test $? -gt 0 && status=1
    done
    exit $status
fi


#
# Execute single service with options
#
if test -z "${args}" ; then
    usage 1>&2
    exit 1
fi

set -- $args
if ! check_wrapper "$@"; then
    shift
fi
if ! check_rc "$rc" ; then
    echo "${0##*/}: no such service $rc" 1>&2
    exit 1
fi

exec_rc $rc ${1+"$@"}
exit $?
