#!/bin/sh
# service - start, stop and enable Arctic services
#
#   service list                 show every service and its state
#   service status <name>        is it running?
#   service start|stop|restart <name>
#   service enable|disable <name>
#
# A service is a script in /etc/rc.d taking start/stop/status. Enabling one
# creates a marker in /etc/arctic/services, which rc.boot reads in order.
# shellcheck shell=sh disable=SC2039

set -u
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
. /etc/arctic/rc.lib 2>/dev/null || { _R= ; _B= ; _MINT= ; _RED= ; _GREY= ; _SNOW= ; _AMB= ; _TEAL= ; }

RCD=/etc/rc.d
ENA=/etc/arctic/services

need_root() { [ "$(id -u)" = "0" ] || { echo "Must be run as root." >&2; exit 1; }; }

exists() { [ -x "$RCD/$1" ]; }
enabled() { [ -e "$ENA/$1" ]; }

running() {
	# The service script knows best; ask it first.
	if exists "$1" && "$RCD/$1" status >/dev/null 2>&1; then return 0; fi
	# Then a pidfile. Deliberately no name-based lookup: comm is the script's
	# own name for an interpreted service script, so matching on it always hits.
	[ -f "/run/$1.pid" ] && kill -0 "$(cat "/run/$1.pid")" 2>/dev/null
}

case "${1:-list}" in
list|ls)
	printf '\n  %s%-18s %-10s %s%s\n' "$_B" "SERVICE" "ENABLED" "STATE" "$_R"
	for f in "$RCD"/*; do
		[ -x "$f" ] || continue
		n=$(basename "$f")
		if enabled "$n"; then e="${_MINT}yes${_R}"; else e="${_GREY}no${_R} "; fi
		if running "$n"; then s="${_MINT}running${_R}"; else s="${_GREY}stopped${_R}"; fi
		printf '  %s%-18s%s %-19s %s\n' "$_SNOW" "$n" "$_R" "$e" "$s"
	done
	printf '\n' ;;
status)
	n=${2:?usage: service status <name>}
	exists "$n" || { echo "no such service: $n" >&2; exit 1; }
	if running "$n"; then
		printf '  %s%s%s is %srunning%s%s\n' "$_SNOW" "$n" "$_R" "$_MINT" "$_R" \
			"$(enabled "$n" && printf ' (enabled)' || printf ' (not enabled at boot)')"
	else
		printf '  %s%s%s is %sstopped%s\n' "$_SNOW" "$n" "$_R" "$_GREY" "$_R"
		exit 3
	fi ;;
start)
	need_root
	n=${2:?usage: service start <name>}
	exists "$n" || { echo "no such service: $n" >&2; exit 1; }
	begin "starting $n"; "$RCD/$n" start >/dev/null 2>&1 && good || { bad; exit 1; } ;;
stop)
	need_root
	n=${2:?usage: service stop <name>}
	exists "$n" || { echo "no such service: $n" >&2; exit 1; }
	begin "stopping $n"; "$RCD/$n" stop >/dev/null 2>&1 && good || { bad; exit 1; } ;;
restart)
	need_root
	n=${2:?usage: service restart <name>}
	exists "$n" || { echo "no such service: $n" >&2; exit 1; }
	begin "restarting $n"
	"$RCD/$n" stop >/dev/null 2>&1
	sleep 1
	"$RCD/$n" start >/dev/null 2>&1 && good || { bad; exit 1; } ;;
enable)
	need_root
	n=${2:?usage: service enable <name>}
	exists "$n" || { echo "no such service: $n" >&2; exit 1; }
	mkdir -p "$ENA"; : >"$ENA/$n"
	printf '  %s%s%s will start at boot\n' "$_SNOW" "$n" "$_R" ;;
disable)
	need_root
	n=${2:?usage: service disable <name>}
	rm -f "$ENA/$n"
	printf '  %s%s%s will no longer start at boot\n' "$_SNOW" "$n" "$_R" ;;
*)
	sed -n '2,10p' "$0" | sed 's/^# \?//'
	exit 1 ;;
esac
