aboutsummaryrefslogtreecommitdiff
path: root/systemctl
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2021-06-11 16:58:25 -0400
committerB. Stack <bgstack15@gmail.com>2021-06-11 16:58:41 -0400
commit82fd33f85381ed6c74528e4110d97a39da41327e (patch)
tree176b9c22a2e349e72a6656f73cb68ee05d262596 /systemctl
downloadsystemctl-service-shim-upstream/0.0.1.tar.gz
systemctl-service-shim-upstream/0.0.1.tar.bz2
systemctl-service-shim-upstream/0.0.1.zip
Diffstat (limited to 'systemctl')
-rwxr-xr-xsystemctl528
1 files changed, 528 insertions, 0 deletions
diff --git a/systemctl b/systemctl
new file mode 100755
index 0000000..a4d8d54
--- /dev/null
+++ b/systemctl
@@ -0,0 +1,528 @@
+#!/bin/sh
+# Filename: systemctl
+# Location: /usr/sbin/systemctl
+# /usr/bin/hostnamectl
+# /usr/bin/systemd-detect-virt
+# Author: bgstack15@gmail.com
+# Startdate: 2020-01-10 13:02:14
+# SPDX-License-Identifier: CC-BY-SA-4.0
+# Title:
+# Purpose:
+# Package: systemctl-service-shim
+# History:
+# 2020-05-14 place framework.sh contents inline so as not to depend on it.
+# 2021-01-10 adapted for inclusion in devuan-sanity
+# Usage:
+# Should be mostly like systemctl from systemd.
+# Reference: ftemplate.sh 2019-05-02a ; framework.sh 2018-05-02a
+# man 1 systemctl
+# Improve:
+# add preset command
+# Return 1 if status output is failed
+# Dependencies:
+# req-devuan: moreutils
+# Documentation:
+# Be aware that real systemd systemctl is file /bin/systemctl but
+# this systemdtl is file /usr/sbin/systemctl to prevent a recursive loop
+# in some service scripts that look for /bin/systemctl
+# vim: set sw=3 sts=3 ts=3 et:
+fiversion="2019-05-02a"
+systemctlversion="2021-06-11a"
+
+usage() {
+ ${PAGER:-/usr/bin/less -F} >&2 <<ENDUSAGE
+usage: systemctl [-duV] [-c conffile]
+Provides a systemctl-like interface to sysvinit. Simulates various
+actions on services: start, stop, restart, enable, disable, status,
+mask, unmask, is-enabled, is-active, condrestart.
+version ${systemctlversion}
+ -d debug Show debugging info, including parsed variables.
+ -u usage Show this usage block.
+ -V version Show script version number.
+ -c conf Read in this config file.
+Return values:
+ 0 Normal
+ 1 Queried service is disabled/inactive
+ 2 Count or type of flaglessvals is incorrect
+ 3 Incorrect OS type
+ 4 Unable to find dependency
+ 5 Not run as root or sudo
+ENDUSAGE
+}
+
+# DEFINE FUNCTIONS
+log_to_file() {
+ flecho "${@}" >> "${logfile}"
+}
+
+parseFlag() {
+ flag="$1"
+ hasval=0
+ case ${flag} in
+ # INSERT FLAGS HERE
+ "d" | "debug" | "DEBUG" | "dd" ) setdebug ; ferror "debug level ${debug}" ; __debug_set_by_param=1 ;;
+ "u" | "usage" | "help" | "h" ) usage ; exit 0 ;;
+ "V" | "fcheck" | "version" ) ferror "${scriptfile} version ${systemctlversion}" ; exit 0 ;;
+ "c" | "conf" | "conffile" | "config" ) getval ; conffile="${tempval}" ;;
+ "now" ) export SYSTEMCTL_NOW=1 ;;
+ "full") export SYSTEMCTL_FULL=1 ;;
+ "system") export SYSTEMCTL_SYSTEM=1 ;;
+ esac
+
+ debuglev 10 && { test ${hasval} -eq 1 && ferror "flag: ${flag} = ${tempval}" || ferror "flag: ${flag}" ; }
+}
+
+# INITIALIZE VARIABLES
+# variables set in framework:
+# server scriptdir scriptfile scripttrim
+
+### BEGIN IMPORT OF FRAMEWORK.SH
+fversion="2020-04-24x"
+
+# DEFINE FUNCTIONS
+
+isflag() {
+ # input: $1=word to parse
+ case "$1" in
+ --*) retval=2 ;;
+ -*) retval=1 ;;
+ *) retval=0 ;;
+ esac
+ echo $retval
+}
+
+parseParam() {
+ # determines if --longname or -shortflagS that need individual parsing
+ trimParam=$( printf '%s' "${param}" | sed -n 's/--//p' )
+ _rest=
+ if test -n "$trimParam" ;
+ then
+ parseFlag $trimParam
+ else
+ #splitShortStrings
+ _i=2
+ while test ${_i} -le ${#param} ;
+ do
+ _j=$( expr ${_i} + 1)
+ #_char=$(expr substr "$param" $_i 1)
+ #_rest=$(expr substr "$param" $_j 255)
+ _char=$( printf '%s' "${param}" | cut -c ${_i})
+ _rest=$( printf '%s' "${param}" | cut -c ${_j}-255)
+ parseFlag $_char
+ _i=$( expr ${_i} + 1)
+ done
+ fi
+}
+
+getval() {
+ tempval=
+ if test -n "${_rest}" ;
+ then
+ tempval="${_rest}"
+ hasval=1
+ _i=255 # skip rest of splitShortStrings because found the value!
+ elif test -n "$nextparam" && test $(isflag "$nextparam") -eq 0 ;
+ then
+ tempval="$nextparam"
+ hasval=1 #DNE ; is affected by ftemplate!
+ paramnum=$nextparamnum
+ fi
+}
+
+debuglev() {
+ # call: debuglev 5 && ferror "debug level is at least a five!"
+ # added 2015-11-17
+ localdebug=0 ; localcheck=0 ;
+ fisnum ${debug} && localdebug=${debug}
+ fisnum ${1} && localcheck=${1}
+ test $localdebug -ge $localcheck && return 0 || return 1
+}
+
+debuglevoutput() {
+ # call: commandthatgeneratesstdout | debuglevoutput 8
+ # output: output to standard error prepended with "debug8: " the contents of the pipe
+ ___dlo_threshold="${1}"
+ ___dlo_silent="${2}"
+ if debuglev "${___dlo_threshold}" ;
+ then
+ if test -n "${___dlo_silent}" ;
+ then
+ cat 1>&2
+ else
+ sed -r -e "s/^/debug${___dlo_threshold}: /;" 1>&2
+ fi
+ else
+ cat 1>/dev/null 2>&1
+ fi
+}
+
+fisnum() {
+ # call: fisnum $1 && debug=$1 || debug=10
+ fisnum= ;
+ case $1 in
+ ''|*[!0-9]*) fisnum=1 ;; # invalid
+ *) fisnum=0 ;; # valid number
+ esac
+ return ${fisnum}
+}
+
+fistruthy() {
+ # call: if fistruthy "$val" ; then
+ local _return=
+ case "$( echo "${1}" | tr '[:upper:]' '[:lower:]' )" in
+ yes|1|y|true|always) _return=true ;;
+ esac
+ test -n "${_return}" ; return $?
+}
+
+setval() {
+ # call: setval 0 value1 value2 value3 ... <<EOFOPTIONS
+ # /bin/foo1 --optforfoo1
+ # /usr/bin/foo2 --optforfoo2
+ # EOFOPTIONS
+ # ^ 0 = soft fail, 1 = critical-fail
+ quitonfail="${1}" ; shift
+ _vars="${@}"
+ #echo "_vars=${_vars}"
+ _varcount=0
+ for _word in ${_vars} ; do _varcount=$( expr $_varcount + 1 ) ; eval "_var${_varcount}=${_word}" ; done
+ _usethis=0
+ while read line ;
+ do
+ _varcount=0
+ if test ! "${_usethis}x" = "0x" ; then break ; fi
+ #echo "line=${line}" ;
+ for _word in ${line} ;
+ do
+ _varcount=$( expr $_varcount + 1 )
+ #echo "word ${_varcount}=${_word}" ;
+ case "${_varcount}" in
+ 1)
+ #echo "Testing for existence of file ${_word}"
+ if test -f "${_word}" ;
+ then
+ _usethis=1
+ #echo "${_var1}=${_word}"
+ eval "${_var1}=${_word}"
+ fi
+ ;;
+ *)
+ #echo "just an option: ${_word}"
+ if test "${_usethis}x" = "1x" ;
+ then
+ #eval echo "\${_var${_varcount}}=${_word}"
+ eval eval "\${_var${_varcount}}=${_word}"
+ fi
+ ;;
+ esac
+ done
+ done
+ #eval echo "testfile=\$${_var1}"
+ eval _testfile=\$${_var1}
+ if test ! -f "${_testfile}" ;
+ then
+ case "${quitonfail}" in 1) _failval="critical-fail" ;; *) _failval="fail" ;; esac
+ eval "${_var1}=${_failval}"
+ setvalout=${_failval}
+ else
+ eval setvalout="valid-${_var1}"
+ fi
+}
+
+flecho() {
+ # requires moreutils
+ if echo "${@}" | grep -qiE '.' ;
+ then
+ printf "%s\n" "${@}" | TZ=UTC ts "[%FT%TZ]${USER}@${server}:"
+ else
+ printf '' | TZ=UTC ts "[%FT%TZ]${USER}@${server}"
+ fi
+}
+
+ferror() {
+ # call: ferror "$scriptfile: 2. Something bad happened-- error message 2."
+ echo "$@" 1>&2
+}
+
+setdebug() {
+ # call: setdebug
+ debug=10
+ getval
+ if test $hasval -eq 1 ;
+ then
+ if fisnum ${tempval} ;
+ then
+ debug=${tempval}
+ else
+ #test paramnum -le paramcount && paramnum=$( expr ${paramnum} - 1 )
+ hasval=0
+ fi
+ elif fisnum ${_rest} ;
+ then
+ debug=${_rest}
+ _i=255
+ else
+ test $paramnum -le $paramcount && test -z ${nextparam} && paramnum=$( expr ${paramnum} - 1 )
+ fi
+}
+
+define_if_new() {
+ # call: define_if_new IFW_IN_LOG_FILE "/var/log/messages"
+ eval thisval="\${${1}}"
+ test -z "${thisval}" && eval "$1"=\"$2\"
+}
+
+# INITIALIZE VARIABLES
+server=$( hostname -s )
+thisos="$( uname -s )"
+# get thisflavor and thisflavorversion. Examples: centos, ubuntu, redhat
+if test -f /etc/os-release ;
+then
+ eval thisflavor=$( grep -iE "^\s*ID=" /etc/os-release 2>/dev/null | sed 's/^.*=//;' | tr 'A-Z' 'a-z' )
+ eval thisflavorversion=$( grep -iE "^\s*PRETTY_NAME=" /etc/os-release 2>/dev/null | sed -e 's/^.*=//;' | tr -dc '0-9.' )
+elif test -f /etc/system-release && test $( wc -l < /etc/system-release 2>/dev/null ) -eq 1 ;
+then
+ eval thisflavor=$( awk '{print $1}' < /etc/system-release 2>/dev/null | tr 'A-Z' 'a-z' )
+ eval thisflavorversion=$( </etc/system-release sed -e 's/^.*=//;' 2>/dev/null | tr -dc '0-9.' )
+else
+ if test "${thisos}" = "FreeBSD" ; then
+ thisflavor="$( uname -i )" ; thisflavorversion="$( uname -r )" ;
+ else
+ thisflavor="other"
+ thisflavorversion="unknown"
+ fi
+fi
+case "${thisos}" in FreeBSD) sed=gsed ;; *) sed=sed ;; esac
+
+# if framework is dot sourced then $0 will be "-bash" and screw things up
+case ${0} in
+ "-bash")
+ scriptdir="$( pwd )"
+ scriptfile="dot-sourced" ;;
+ *)
+ scriptdir="$( cd $( dirname ${0} ) ; pwd )"
+ scriptfile="$( basename ${0} | sed 's!/./!/!g;s!\./!!g' )"
+ scripttrim="${scriptfile%%.sh}"
+ ;;
+esac
+
+# SPECIAL RUNTIME-RELATED VARIABLES
+{ test "$USER" = "root" || test "$( stat -c '%u' /proc/$$/exe 2>/dev/null )" = 0 ; } && is_root=1
+test -n "$SUDO_USER" && is_root="sudo"
+
+nullflagcount=0
+validateparams() {
+ # VALIDATE PARAMETERS
+ # scroll through all parameters and check for isflag.
+ # if isflag, get all flags listed. Also grab param#.
+ paramcount=$#
+ thiscount=0 ;thisopt=0 ;freeopt=0 ;
+ varsyet=0
+ paramnum=0
+ debug=0
+ fallopts=
+ while test $paramnum -lt $paramcount ;
+ do
+ paramnum=$( expr ${paramnum} + 1 )
+ eval param=\${$paramnum}
+ nextparamnum=$( expr ${paramnum} + 1 )
+ eval nextparam=\${$nextparamnum}
+ case $param in
+ "-")
+ if test "$varsyet" = "0" ;
+ then
+ # first instance marks beginning of flags and parameters.
+ #Until then it was the names of variables to fill.
+ varsyet=1
+ else
+ nullflagcount=$( expr ${nullflagcount} + 1 ) #useful for separating flags from something else?
+ debuglev 10 && ferror "null flag!" # second instance is null flag.
+ fi
+ ;;
+ esac
+ if test -n "$param" ;
+ then
+ # parameter $param exists.
+ if test $(isflag $param) -gt 0 ;
+ then
+ # IS FLAG
+ parseParam
+ else
+ # IS VALUE
+ if test "$varsyet" = "0" ;
+ then
+ thisopt=$( expr ${thisopt} + 1 )
+ test "${param}" = "DEBUG" && debug=10 && thisopt=$( expr ${thisopt} - 1 ) || \
+ eval "varname${thisopt}=${param}"
+ #varname[${thisopt}]="${param}"
+ debuglev 10 && ferror "var \"${param}\" named"
+ else
+ thiscount=$( expr ${thiscount} + 1 )
+ test $thiscount -gt $thisopt && freeopt=$( expr ${freeopt} + 1 )
+ #eval ${varname[${thiscount}]:-opt${freeopt}}="\"${param}\""
+ eval "thisvarname=\${varname${thiscount}}"
+ test -z "${thisvarname}" && eval "thisvarname=opt${freeopt}"
+ eval "${thisvarname}=\"${param}\""
+ eval fallopts=\"${fallopts} ${param}\"
+ debuglev 10 && ferror "${thisvarname} value: ${param}"
+ fi
+ fi
+ fi
+ done
+ fallopts="${fallopts# }"
+ if debuglev 10 ;
+ then
+ ferror "thiscount=$thiscount"
+ ferror "fallopts=$fallopts"
+ ferror "Framework $fversion"
+ ferror "Finput $fiversion"
+ fi
+}
+### END IMPORT OF FRAMEWORK.SH
+
+define_if_new logfile "/var/log/systemctl.log"
+
+# VALIDATE PARAMETERS
+# objects before the dash are options, which get filled with the optvals
+# to debug flags, use option DEBUG. Variables set in framework: fallopts
+validateparams action - "$@"
+
+# LEARN EX_DEBUG
+test -z "${__debug_set_by_param}" && fisnum "${SYSTEMCTL_DEBUG}" && debug="${SYSTEMCTL_DEBUG}"
+debug=10
+
+# CONFIGURE VARIABLES AFTER PARAMETERS
+
+_trimmed="$( echo "${@}" | tr -d '\r\n' )"
+log_to_file "${0} ${_trimmed}"
+case "${0}" in
+ *hostnamectl|*systemd-detect-virt) exit 0 ;; # always just short-circuit
+esac
+
+# MAIN LOOP
+
+# actions
+actionlist=""
+case "${action}" in
+
+ restart|start|stop|status|reload|condrestart|try-restart|reload-or-try-restart)
+ # re-map a few actions
+ case "${action}" in
+ "reload-or-try-restart") action=restart ;;
+ esac
+ x=1
+ while test ${x:-${thiscount}} -le $(( thiscount - 1 )) && test ${thiscount} -gt 1 ;
+ do
+ eval thisopt="\${opt${x}}"
+ thisopt="$( echo "${thisopt}" | sed -r -e 's/\.service$//;' )"
+ actionstatement="$( printf "%s" "service ${thisopt} ${action};" )"
+ actionlist="${actionlist:+${actionlist} }${actionstatement}"
+ x=$(( x + 1 ))
+ done
+ ;;
+
+ enable|disable|mask|unmask)
+ case "${action}" in
+ mask) action=disable ;;
+ unmask) action=enable ;;
+ esac
+ x=1
+ while test ${x:-${thiscount}} -le $(( thiscount - 1 )) && test ${thiscount} -gt 1 ;
+ do
+ eval thisopt="\${opt${x}}"
+ thisopt="$( echo "${thisopt}" | sed -r -e 's/\.service$//;' )"
+ actionstatement="$( printf "%s" "update-rc.d ${thisopt} ${action};" )"
+ actionlist="${actionlist:+${actionlist} }${actionstatement}"
+ test "${SYSTEMCTL_NOW}" = "1" && {
+ case "${action}" in
+ enable)
+ nowaction=start
+ ;;
+ disable)
+ nowaction=stop
+ ;;
+ esac
+ actionstatement="$( printf "%s" "service ${thisopt} ${nowaction:-stop};" )"
+ actionlist="${actionlist:+${actionlist} }${actionstatement}"
+ }
+ x=$(( x + 1 ))
+ done
+ ;;
+
+ daemon-reload)
+ debuglev 1 && echo "${action} is a NOP."
+ ;;
+
+ list-unit-files)
+ # Future improvement: can consume --full, but I do not care enough to deal with it now.
+ ls -Al /etc/init.d
+ ;;
+
+ is-enabled)
+ currentrunlevel="$( who -r | grep -oE 'run-level\s+[[:digit:]]+' | awk '{print $NF}' )"
+ responsenumber=1
+
+ # loop through each service on the command line
+ x=1
+ while test ${x:-${thiscount}} -le $(( thiscount - 1 )) && test ${thiscount} -gt 1 ;
+ do
+ eval thisopt="\${opt${x}}"
+ thisopt="$( echo "${thisopt}" | sed -r -e 's/\.service$//;' )"
+ #actionstatement="$( printf "%s" "service ${thisopt} ${action};" )"
+ scriptfile="$( find "/etc/rc${currentrunlevel}.d" -mindepth 1 -maxdepth 1 -name "S??${thisopt}" 2>/dev/null )"
+ responsetext="disabled"
+ # if file exists, let us return 0.
+ if test -n "${scriptfile}" ;
+ then
+ debuglev 2 && echo "${scriptfile}"
+ responsenumber=0 # any "enabled" response makes systemctl return 0
+ responsetext="enabled"
+ fi
+ echo "${responsetext:-UNKNOWN}"
+ x=$(( x + 1 ))
+ done
+ exit "${responsenumber}"
+ ;;
+
+ is-active)
+ responsenumber=3
+ x=1
+ while test ${x:-${thiscount}} -le $(( thiscount - 1 )) && test ${thiscount} -gt 1 ;
+ do
+ eval thisopt="\${opt${x}}"
+ thisopt="$( echo "${thisopt}" | sed -r -e 's/\.service$//;' )"
+ #actionstatement="$( printf "%s" "service ${thisopt} ${action};" )"
+ servicestatus="$( service "${thisopt}" status 1>/dev/null 2>&1 ; echo "${?}" )"
+ responsetext="stopped"
+ # if file exists, let us return 0.
+ if test ${servicestatus:-1} -eq 0 ;
+ then
+ responsenumber=0
+ responsetext="active"
+ fi
+ echo "${responsetext:-unknown}"
+ x=$(( x + 1 ))
+ done
+ exit "${responsenumber}"
+ ;;
+
+ *)
+ ferror "Fatal! 2. Unable to understand action ${action}. Aborted."
+ exit 2
+ ;;
+esac
+
+# list of actions
+if test -n "${actionlist}" ;
+then
+ #debuglev 1 && ferror "Full list: ${actionlist}"
+ printf "%s" "${actionlist}" | tr ';' '\n' | while read thisaction ;
+ do
+ log_to_file "ACTION: ${thisaction}"
+ debuglev 5 && ferror "${thisaction}"
+ eval "${thisaction}"
+ done
+fi
+
+# exit cleanly
+:
bgstack15