#!/bin/sh -e
#
# s6 compatibility script of:
#
# service, Debian/SysVinit (/etc/init.d) service control wrapper.
#
# Why this file exists: Debian's /usr/sbin/service takes the systemctl branch
# only when it detects systemd (a readable /run/systemd/system). Under s6 that
# directory does not exist, so the original falls back to SERVICEDIR=/etc/init.d
# and runs the init script directly. For a service we supervise that is a
# disaster: "service postfix start" runs "postfix start", which leaves a
# "master -w" behind with PPID 1 -- a process no s6-supervise owns, holding
# master.pid, so every master s6 starts afterwards dies on it. s6-svstat then
# reads "up (pid ...) 0 seconds" at every glance while the port stays open, and
# nothing in the s6 log says why (postfix writes its diagnosis to syslog).
# Measured on dns-1 (2026-09-22) and reproduced in a container (2026-09-23).
#
# Debian's own debconf template for postfix recommends exactly the command that
# causes it: "- Running 'service postfix start'." -- in ten languages.
#
# So this script maps to svctl instead, with the same rule as our invoke-rc.d:
# no fallback to /etc/init.d, ever. A service s6 does not know is reported and
# the script exits 0, because a maintainer script must not fail over it.
#
# Difference to invoke-rc.d, on purpose: "start" here is "svctl start <name>",
# not "svctl apply". invoke-rc.d is called by maintainer scripts, where Debian's
# meaning is "bring the system to its configured state"; service is typed by a
# person who means "start this one now", and a silent success on a disabled unit
# would be a lie.

self="${0##*/}"

usage() {
  >&2 echo "Usage: ${self} <service> {start|stop|restart|try-restart|reload|force-reload|status}"
  >&2 echo "       ${self} --status-all"
  >&2 echo "  ${self} -> svctl (s6); /etc/init.d is never used."
}

case "$1" in
  --help|-h|help)
    usage
    exit 0
    ;;
  --status-all)
    for svc in $(svctl listall 2>/dev/null); do
      state='?'
      if svctl isup "$svc" >/dev/null 2>&1; then state='+'; else state='-'; fi
      echo " [ ${state} ]  ${svc}"
    done
    exit 0
    ;;
  --version)
    echo "${self} (s6 compatibility script, init-system-helpers-s6)"
    exit 0
    ;;
esac

# Debian's service accepts both "service <name> <action>" and, for historical
# reasons, "service <action> <name>" is NOT accepted -- keep it strict.
if [ $# -lt 2 ]; then
  usage
  exit 1
fi

svc="$1"
action="$2"
shift 2

# Strip a trailing .service, the way people type it after years of systemd.
svc="${svc%.service}"

if ! svctl listall 2>/dev/null | grep -q "^${svc}$"; then
  >&2 echo "${self}: service ${svc} is unknown to s6; /etc/init.d is not used here."
  exit 0
fi

case "$action" in
  start)
    svctl start "$svc"
    ;;
  stop)
    svctl stop "$svc"
    ;;
  restart|try-restart)
    svctl restart "$svc"
    ;;
  reload|force-reload)
    svctl reload "$svc"
    ;;
  status)
    svctl isenabled "$svc"
    svctl isup "$svc"
    ;;
  *)
    >&2 echo "${self}: unknown action ${action} for ${svc}."
    usage
    exit 1
    ;;
esac
