#!/bin/sh
# {{{ Copyright
# Copyright 2017 David Woodfall <dave@dawoodfall.net>
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Shellcheck note: --exclude=SC1117

# This script allows you to start and stop services in /etc/rc.d/
# }}}
# {{{ Init
init()
{
	trap "cleanup" HUP INT ABRT QUIT SEGV PIPE
	SCRIPT="$(basename "$0")"
	DESC="A sysvinit script controller utility"
	VERSION="1.0.2"
	RCROOT="/etc/rc.d"
	SRVC="$1"
	COM="$2"
	ARG="$3"
	[ "$ARG" = "force" ] && FORCE=1
}
# }}}
# {{{ Do Command
do_command()
{
	if [ -z "$SRVC" ] || [ "$SRVC" = "-h" ]; then
		usage
	fi

	if [ "$SRVC" = "-v" ]; then
		version
	fi

	get_service
	[ -z "$COM" ] && list_opts
	get_opts
	get_args
	[ "$COM" = "chmod" ] && do_chmod

	if ! echo "$OPTS" | grep -q "$COM" && [ -z "$FORCE" ]; then
		echo "Could not find that option for $SERVICE"
		echo -n "Try to $COM it anyway? [yN] "
		read -r

		if [ "$REPLY" = "y" ]; then
			OPTS="$COM"
			FORCE=1
		else
			exit 0
		fi
	fi

	if [ -z "$OPTS" ] && [ -z "$FORCE" ]; then
		echo "Could not find any options for $SERVICE"
		echo -n "Try to $COM it anyway? [yN] "
		read -r

		if [ "$REPLY" = "y" ]; then
			OPTS="$COM"
		else
			exit 0
		fi
	fi

	sh "$SERVICE" "$COM" || error
	if [ ! -x "$SERVICE" ]; then
		error "exec"
	fi
	exit 0
}
# }}}
# {{{ Version
version() {
	printf "%s\n" "$SCRIPT $VERSION - $DESC.
(C) 2018 Dave Woodfall <dave@dawoodfall.net>. All rights reserved."
	exit 0
}
# }}}
# {{{ Usage
usage()
{
printf "%s\n" "$SCRIPT $VERSION - $DESC."
	printf "%s\n" "
Usage:

$SCRIPT <service>                    List service and found commands.
$SCRIPT <service> <command> [force]  start|stop|status etc.. the script.
$SCRIPT <service> <on|off>           Chmod the script to start at boot or not.

Where:

service:      A sysvinit script in /etc/rc.d/ without the preceding 'rc.'.
force:        Force the command even if the option isn't found.

EG for '/etc/rc.d/rc.cups':

$SCRIPT cups
$SCRIPT cups status
$SCRIPT cups start
$SCRIPT cups stop
$SCRIPT cups off

Note that $SCRIPT uses 'sh' to execute the command. This means that you can run
commands without needing the service file to be executable. You will get a
message if the service file isn't executable."
	exit 0
}
# }}}
# {{{ Status
status()
{
	STATUS=$(get_opts "$1")
	[ -n "$STATUS" ] && "$1" status
}
# }}}
# {{{ List Net Interfaces
list_ifaces()
{
	IFACES=$(/sbin/ifconfig -a \
		| grep -E -e "^eth[0-9]+:" -e "^wlan[0-9]+:" -e "^br[0-9]+:" \
		-e "^virbr[0-9]+:" -e "^vmnet[0-9]+:" -e "^vboxnet[0-9]+:" \
		-e "^pan[0-9]+:" -e "^ppp[0-9]+:" \
		| sed 's#:.*##')
}
# }}}
# {{{ Get Options
get_opts()
{
	unset OPTS
	USAGE=$(grep -i usage "$SERVICE")
	OPTS=$(echo "$USAGE" | grep '|' \
		| sed 's#(##g;s#{##g;s#)##g;s#}##g;s#"##g;s#;##g' \
		| awk '{print $NF}' | awk -F'|' '{print $0}')

	if [ "$SRVC" = "inet1" ]; then
		list_ifaces
		OPTS="start stop restart
lo_start lo_stop
"

		for i in $IFACES
		do
			OPTS="${OPTS}${i}_start ${i}_stop ${i}_restart
"
		done
	elif [ "$SRVC" = "qbittorrent-nox" ]; then
		if [ "$UID" = "0" ]; then
			OPTS="Not to be started as root"
		else
			OPTS="start <PORT>|stop|restart <PORT>|status"
		fi
	fi
}
# }}}
# {{{ List options
list_opts()
{
	get_opts
	[ -n "$SERVICE" ] && ls -Fl "$SERVICE" && printf "\n"
	[ -z "$OPTS" ] && OPTS="None found."
	printf "%s\n" "Options:"
	printf "%s\n" "$OPTS"
	exit 0
}
# }}}
# {{{ Do Chmod
do_chmod()
{
	get_args
	chmod "$ARG" "$SERVICE" || exit 1
	[ -x "$SERVICE" ] && echo "Autostart enabled for $SERVICE" \
		|| echo "Autostart disabled for $SERVICE"
	exit 0
}
# }}}
# {{{ Get Args
get_args()
{
	if [ "$COM" = "on" ]; then
		COM="chmod"
		ARG="+x"
	elif [ "$COM" = "off" ]; then
		COM="chmod"
		ARG="-x"
	fi
}
# }}}
# {{{ Get Service Name
get_service()
{
	SERVICE="$RCROOT/rc.$SRVC"

	if [ ! -e "$SERVICE" ]; then
		error "nosuch"
	fi
}
# }}}
# {{{ Error
error() {
	if [ "$1" = "exec" ]; then
		echo "$SERVICE is not executable."
	elif [ "$1" = "unsup" ]; then
		echo "Unsupported command."
	elif [ "$1" = "unrec" ]; then
		echo "Unrecognised command."
	elif [ "$1" = "nosuch" ]; then
		echo "No such file: $SERVICE"
	fi
	exit 1
}
# }}}
# {{{ Cleanup
cleanup() {
	exit "$1"
}
# }}}
# {{{ Start
init "$@"
do_command
# }}}
# vim: colorcolumn=79
