#!/bin/sh

###########################################################################
#
# A convenient wrapper for the /etc/init.d avreg init scripts.
#
# This script is a modified version of the /sbin/service utility found on
# Red Hat/Fedora systems (licensed GPLv2+).
#
# Copyright (C) 2006 Red Hat, Inc. All rights reserved.
# Copyright (C) 2008 Canonical Ltd.
#   * August 2008 - Dustin Kirkland <kirkland@canonical.com>
# Copyright (C) 2013 Michael Stapelberg <stapelberg@debian.org>
# Copyright (C) 2016 Andrey Nikitin <support@avreg.net>

# 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# On Debian GNU/Linux systems, the complete text of the GNU General
# Public License can be found in `/usr/share/common-licenses/GPL-2'.
###########################################################################


ME=`basename $0`
USAGE="Usage: $ME start|stop|status|restart|reload [ avreg-profile-name ]"
CONFDIR='/etc/avreg'
PROFILEDIR="${CONFDIR}/profiles"
SYSTEMD_SERVICE='avreg'
UPSTART_SERVICE='avreg'
SERVICE='avreg'
SYSV_OPTIONS=
ACTION=
SERVICEDIR="/etc/init.d"
PROFILE=
is_systemd=
options=

if [ $# -eq 0 -o -z "${1%-*}" -o "$1" = '-h' -o "$1" = '--help' ]; then
    echo "${USAGE}" >&2
    exit 1
fi

if [ -d /run/systemd/system ]; then
    is_systemd=1
fi

cd /

ACTION="${1}"
shift
if [ $# -gt 0 ]; then
    PROFILE="${1}"
fi

if [ -n "${PROFILE}" ]; then
    if [ -f "${PROFILEDIR}/${PROFILE}" -o -f "${PROFILEDIR}/${PROFILE}.conf" ]; then
       SYSTEMD_SERVICE="avregd@$PROFILE"
       UPSTART_SERVICE='avreg-worker'
       SYSV_OPTIONS="${PROFILE}"
    else
       echo "cmdline error: unrecognized avreg profile \"${PROFILE}\"" 1>&2
       exit 1
    fi
fi

# Operate against system upstart, not session
unset UPSTART_SESSION
if [ -r "/etc/init/${UPSTART_SERVICE}.conf" ] && which initctl >/dev/null \
    && initctl version 2>/dev/null | grep -q upstart \
    && initctl status ${UPSTART_SERVICE} 2>/dev/null 1>/dev/null
then
    if [ -n "${PROFILE}" ]; then
        options="PROFILE=${PROFILE}"
    fi

    # Upstart configuration exists for this job and we're running on upstart
    case "${ACTION}" in
        start|stop|status|reload)
            # Action is a valid upstart action
            exec ${ACTION} ${UPSTART_SERVICE} ${options}
            ;;
        restart|force-reload)
            # Map restart to the usual sysvinit behavior.
            # Map force-reload to restart as per Debian policy 9.3.2,
            # since there is no way to know if "reload" is supported
            stop ${UPSTART_SERVICE} ${options} || :
            exec start ${UPSTART_SERVICE} ${options}
            ;;
    esac
fi

run_via_sysvinit() {
   # Otherwise, use the traditional sysvinit
   if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
      exec env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" ${ACTION} ${SYSV_OPTIONS}
   else
      echo "${SERVICE}: unrecognized service" >&2
      exit 1
   fi
}

update_openrc_started_symlinks() {
   # maintain the symlinks of /run/openrc/started so that
   # rc-status works with the service command as well
   if [ -d /run/openrc/started ] ; then
      case "${ACTION}" in
      start)
         if [ ! -h /run/openrc/started/$SERVICE ] ; then
            ln -s $SERVICEDIR/$SERVICE /run/openrc/started/$SERVICE || true
         fi
      ;;
      stop)
         rm /run/openrc/started/$SERVICE || true
      ;;
      esac
   fi
}

# When this machine is running systemd, standard service calls are turned into
# systemctl calls.
if [ -n "$is_systemd" ]
then
   UNIT="${SYSTEMD_SERVICE}.service"
   # avoid deadlocks during bootup and shutdown from units/hooks
   # which call "invoke-rc.d service reload" and similar, since
   # the synchronous wait plus systemd's normal behaviour of
   # transactionally processing all dependencies first easily
   # causes dependency loops
   if ! OUT=$(systemctl is-system-running 2>/dev/null) && [ "$OUT" != "degraded" ]; then
       sctl_args="--job-mode=ignore-dependencies"
   fi

   case "${ACTION}" in
      restart|status)
         exec systemctl $sctl_args ${ACTION} ${UNIT}
      ;;
      start|stop)
         # Follow the principle of least surprise for SysV people:
         # When running "service foo stop" and foo happens to be a service that
         # has one or more .socket files, we also stop the .socket units.
         # Users who need more control will use systemctl directly.
         for unit in $(systemctl list-unit-files --full --type=socket 2>/dev/null | sed -ne 's/\.socket\s*[a-z]*\s*$/.socket/p'); do
             if [ "$(systemctl -p Triggers show $unit)" = "Triggers=${UNIT}" ]; then
                systemctl $sctl_args ${ACTION} $unit
             fi
         done
         exec systemctl $sctl_args ${ACTION} ${UNIT}
      ;;
      reload)
         _canreload="$(systemctl -p CanReload show ${UNIT} 2>/dev/null)"
         if [ "$_canreload" = "CanReload=no" ]; then
            # The reload action falls back to the sysv init script just in case
            # the systemd service file does not (yet) support reload for a
            # specific service.
            run_via_sysvinit
         else
            exec systemctl $sctl_args reload "${UNIT}"
         fi
         ;;
      force-stop)
         exec systemctl --signal=KILL kill "${UNIT}"
         ;;
      force-reload)
         _canreload="$(systemctl -p CanReload show ${UNIT} 2>/dev/null)"
         if [ "$_canreload" = "CanReload=no" ]; then
            exec systemctl $sctl_args restart "${UNIT}"
         else
            exec systemctl $sctl_args reload "${UNIT}"
         fi
         ;;
      *)
         # We try to run non-standard actions by running
         # the init script directly.
         run_via_sysvinit
         ;;
   esac
fi

update_openrc_started_symlinks
run_via_sysvinit
