#!/usr/bin/sh #---------------------------------------------------------------------------- # /usr/sbin/service - system service control wrapper # # Creation: 2022-10-01 dv # Last Update: $Id$ # # Copyright (c) 2003-@@YEAR@@ the eisfair team, team(at)eisfair(dot)org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. #---------------------------------------------------------------------------- # include eislib . /var/install/include/eislib SYSTEMCTL="/usr/bin/systemctl" RCDIR="/etc/rc2.d" INITDIR="/etc/init.d" # system V management functions is_sysvscript() { test -f "/etc/init.d/${1}" return $? } sysv_is_enabled() { local package="${1}" local start_script=$(ls ${RCDIR}/S??${package} 2>/dev/null) test -n "${start_script}" return $? } sysv_is_active() { local package="${1}" sysv_command "${package}" "status" > /dev/null return $? } sysv_enable() { local package="${1}" if ! sysv_is_enabled ${package} then local kill_script=$(ls ${RCDIR}/K??${package} 2>/dev/null) if [ -z "${kill_script}" ] then # failed to enable sysv script return 1 fi local stop_seq=$(basename "${kill_script}" | grep -o -E '[0-9]+' | head -n1) local start_seq=$((100 - stop_seq)) local start_script="${RCDIR}/S${start_seq}${package}" ln -sr "${INITDIR}/${package}" "${start_script}" return $? fi return 0 } sysv_disable() { local package="${1}" if sysv_is_enabled "${package}" then local start_script=$(ls ${RCDIR}/S??${package} 2>/dev/null) rm -f "${start_script}" return $? fi return 0 } sysv_command() { "${INITDIR}/${1}" "${2}" return $? } # systemd management functions is_systemd_installed() { test -f "${SYSTEMCTL}" return $? } is_systemd_service() { if is_systemd_installed then local state=$(${SYSTEMCTL} --full --no-legend --no-pager --type=service --property=LoadState show "${1}" 2>/dev/null) test "$state" = "LoadState=loaded" return $? fi return 1 } systemd_is_enabled() { ${SYSTEMCTL} is-enabled "${1}" >/dev/null 2>&1 return $? } systemd_is_active() { ${SYSTEMCTL} is-active "${1}" >/dev/null 2>&1 return $? } systemd_enable() { local package="${1}" if ! systemd_is_enabled ${package} then ${SYSTEMCTL} enable "${package}" >/dev/null 2>&1 return $? fi return 0 } systemd_disable() { local package="${1}" if systemd_is_enabled "${package}" then ${SYSTEMCTL} disable "${package}" >/dev/null 2>&1 return $? fi return 0 } systemd_command() { ${SYSTEMCTL} ${no_pager} "${2}" "${1}" return $? } systemd_get_service_description() { if is_systemd_service "${package}" then local desc="$(${SYSTEMCTL} cat ${package} | grep Description | cut -f2 -d= | sed 's/^LSB: //1')" if [ -z "${desc}" ] then case "${package}" in *.*) echo "${package}" ;; *) echo "${package}.service" ;; esac else echo "${desc}" fi fi } # general command handlers enable() { local packages="${1}" local package local result=0 for package in ${packages} do if is_sysvscript "${package}" then if ! sysv_enable "${package}" then result=1 fi fi if is_systemd_service "${package}" then if ! systemd_enable "${package}" then result=1 fi fi done return ${result} } disable() { local packages="${1}" local package local result=0 for package in ${packages} do if is_sysvscript "${package}" then if ! sysv_disable "${package}" then result=1 fi fi if is_systemd_service "${package}" then if ! systemd_disable "${package}" then result=1 fi fi done return ${result} } issue_command() { local package="${1}" local command="${2}" local result=0 if is_sysvscript "${package}" then if ! sysv_command "${package}" "${command}" then result=1 fi else if is_systemd_service "${package}" && ! systemd_command "${package}" "${command}" then result=1 fi fi return ${result} } issue_commands() { local packages="${1}" local command="${2}" local verbose="${3}" local action="${4}" local package local result=0 for package in ${packages} do local desc="$(systemd_get_service_description ${package})" if [ "${verbose}" = true ] && [ -n "${desc}" ] then echo " * ${action} ${desc} ..." if ! issue_command "${package}" "${command}" then mecho --fail result=1 else mecho --ok fi else if ! issue_command "${package}" "${command}" then result=1 fi fi done return ${result} } issue_sysv_command() { local packages="${1}" local command="${2}" local package local result=0 for package in ${packages} do if is_sysvscript "${package}" then if ! sysv_command "${package}" "${command}" then result=1 fi else if is_systemd_service "${package}" then echo "\"${command}\" is invalid for \"${package}\"!" >&2 else echo "\"${package}\" is not a valid service!" >&2 fi result=1 fi done return ${result} } # function returns success if at least one of the packages is a service is_service() { local packages="${1}" local package for package in ${packages} do if is_sysvscript "${package}" then return 0 fi if is_systemd_service "${package}" then return 0 fi done return 1 } # function returns success if at least one of the packages is enabled is_enabled() { local packages="${1}" local package for package in ${packages} do if is_sysvscript "${package}" && sysv_is_enabled "${package}" then return 0 fi if is_systemd_service "${package}" && systemd_is_enabled "${package}" then return 0 fi done return 1 } # function returns success if at least one of the packages is active is_active() { local packages="${1}" local package for package in ${packages} do if is_sysvscript "${package}" && sysv_is_active "${package}" then return 0 fi if is_systemd_service "${package}" && systemd_is_active "${package}" then return 0 fi done return 1 } show_message() { if [ -n "${1}" ] then mecho --info "$1 ..." fi } # command line help show_help() { cat < message to be displayed --help show this help screen possible values for COMMAND: is-service check whether a package name denotes a service is-enabled check whether a service is enabled is-active check whether a service is running / active enable enable a service for autostart disable disable a service for autostart start manually start a service stop manually stop a service restart manually stop and restart a service try-restart restart service only if it is already running status show status of a service reload reload configuration files daemon-reload reloads unit files (only effective when systemd is installed) EOF } main() { local verbose=false local message="" no_pager='' # since systemctl prints no output by itself, we do it locally # when systemd is installed. This default behaviour can be changed # using --quiet switch if is_systemd_installed then verbose=true fi # read option switches while [ "${1:0:2}" = "--" ] do case ${1} in --help) shift show_help exit 0 ;; --quiet) shift verbose=false ;; --msg) shift if [ "${1}" != "" -a "${1:0:2}" != "--" ] then message="${1}" shift else echo 'error: missing argument for --msg!' >&2 show_help exit 1 fi ;; --msg=*) message="${1:6}" shift ;; *) echo "error: invalid command line switch \"$1\"!" >&2 show_help exit 1 ;; esac done # check for sufficient command line arguments local action="${1}" if [ "${action}" = "daemon-reload" ] && [ "$#" -ne 1 ] then show_help exit 1 elif [ "${action}" != "daemon-reload" ] && [ "$#" -lt 2 ] then show_help exit 1 fi shift local packages="" while [ "$#" -gt 0 ] do packages="${packages} ${1}" shift done case "${action}" in "daemon-reload") if is_systemd_installed then show_message "${message}" ${SYSTEMCTL} daemon-reload >/dev/null 2>&1 exit $? fi ;; "is-service") show_message "${message}" if is_service "${packages}" then exit 0 fi exit 1 ;; "is-enabled") show_message "${message}" if is_enabled "${packages}" then exit 0 fi exit 1 ;; "is-active") show_message "${message}" if is_active "${packages}" then exit 0 fi exit 1 ;; "start") show_message "${message}" issue_commands "${packages}" "start" "${verbose}" "Starting" ;; "stop") show_message "${message}" issue_commands "${packages}" "stop" "${verbose}" "Stopping" ;; "restart") show_message "${message}" issue_commands "${packages}" "restart" "${verbose}" "Restarting" ;; "try-restart") show_message "${message}" issue_commands "${packages}" "try-restart" "${verbose}" "Restarting (try)" ;; "status") no_pager='--no-pager --full' show_message "${message}" issue_commands "${packages}" "status" "false" "" ;; "reload") show_message "${message}" issue_commands "${packages}" "reload" "${verbose}" "Reloading" ;; "force-reload") show_message "${message}" issue_commands "${packages}" "force-reload" "${verbose}" "Reloading (forced)" ;; "enable") show_message "${message}" enable "${packages}" ;; "disable") show_message "${message}" disable "${packages}" ;; *) show_message "${message}" issue_sysv_command "${packages}" "${action}" ;; esac } main "${@}"