#!/bin/sh
#    $NetBSD: service,v 1.10 2024/07/26 18:54:49 jakllsch Exp $
#    service -- run or list system services
#
#  Taken from FreeBSD: releng/10.1/usr.sbin/service/service.sh 268098
#  Modified for NetBSD by Adrian Steinmann in March, 2015
#
#  Copyright (c) 2009 Douglas Barton
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.

export PATH=/sbin:/bin:/usr/sbin:/usr/bin

usage ()
{
    local me="${0##*/}"

    exec >&2

    printf 'Usage:\t%s -l [-v]\n' "${me}"
    printf '\t%s\n'							   \
	"       List all scripts in rc order"				   \
	"   -v: Prepend the value of rc_directories to the output"	   \
	"${me} -e [-v]"							   \
	"       Print names of all enabled scripts"			   \
	"   -v: Include the value of rc_directories (to stderr)"	   \
	"${me} -e [-v] rc_script_name [rc_script_name...]"		   \
	"       Print path names of any given scripts which are enabled"   \
	"   -v: Include the value of rc_directories (to stderr)"	   \
	"${me} [-v] rc_script_name action"				   \
	"       Run rc_script_name to perform the action specified"	   \
	"   -v: Verbose (mention in which directory script was found)"
    printf 'rc_directories is currently set to: %s\n' "${rc_directories}"
    exit 2
}

# list all files in rc_directories with absolute pathnames
# (don't use ls(1) so we get the pathnames, without using non-std options)
_rc_files()
{
    local _d _f IFS

    IFS=$'\n'
    rcorder -s nostart ${rc_rcorder_flags} $(
	for _d in ${rc_directories}
	do
	    if [ -d "$_d" ]
	    then
		for _f in "$_d"/*
		do
		    if [ -f "$_f" ] && [ -x "$_f" ]
		    then
			printf '%s\n' "$_f"
		    fi
		done
	    fi
	done
    )
    return 0
}

_rc_dirs()
{
    if "${VERBOSE}"
    then
	printf 'rc_directories is %s\n' "${rc_directories}"
    fi
}

ENABLED=false
LIST=false
VERBOSE=false

while getopts elv o
do
    case "$o" in
	e) ENABLED=true	;;
	l) LIST=true	;;
	v) VERBOSE=true	;;
	*) usage	;;
    esac
done
shift $(( OPTIND - 1 ))

if "${ENABLED}" && "${LIST}"
then
    usage
fi

if ! [ -f /etc/rc.subr ]
then
	printf >&2 '%s: The rc system seems to be missing /etc/rc.subr\n' \
	    "${0##*/}"
	exit 3
fi

if command . /etc/rc.subr
then
	load_rc_config :
else
	printf >&2 '%s: Problems running /etc/rc.subr.   Aborting\n'  "${0##*/}"
	exit 3
fi

if "${ENABLED}"
then
    _rc_dirs >&2
    case $# in
    0)	flt=cat;;
    *)
	IFS='|'
	flt="egrep '/(${*})\$'"
	;;
    esac
    if ( set +o pipefail ) 2>/dev/null
    then
	# If this option exists, disable it.
	set +o pipefail
    fi
    IFS=
    _rc_files | eval "$flt" |
    {
	found=false
	while read file
	do
	    if grep -q '^rcvar=' "$file"
	    then
		unset name rcvar
		eval "$( sed -n < "$file" -e '/^name=/p' -e '/^rcvar=/p' )"
		if [ -n "${rcvar}" ]
		then
		    load_rc_config "${rcvar}"
		    if checkyesno "${rcvar}" 2>/dev/null
		    then		
			printf '%s\n' "${file}"
			found=true
		    fi
		fi
	    else
		# pseudo scripts like LOGIN DAEMON ... have no rcvar,
		# but aren't intended to be run either, those contain
		# no lower case letters in their names.
		#
		# Other scripts without an rcvar are always enabled
		#
		# So require at least one lower case letter in the name
		# in order to run a script without an rcvar, and include
		# them in the list of enabled scripts.

		case "${file##*/}" in
		*[:lower:]*) printf '%s\n' "${file}"; found=true;;
		esac
	    fi
	done
	"$found"
    }
    exit "$?"
fi

if "${LIST}"
then
    _rc_dirs
    _rc_files
    exit 0
fi

if [ "$#" -ne 2 ]
then
    usage
fi

script=$1
arg=$2

for dir in ${rc_directories}
do
    if [ -x "${dir}/${script}" ]
    then
	if "${VERBOSE}"
	then
	    printf >&2 '%s script is located in %s\n' "${script}" "${dir}"
	fi

	# run as in /etc/rc
	cd /
	umask 022
	exec env -i \
	    HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin \
		"${dir}/${script}" "${arg}"
	printf >&2 'Failed to exec %s (status %d)\n' \
		"${dir}/${script} ${arg}" "$?"
	exit 126
    fi
done

printf >&2 '%s does not exist in %s\n' "${script}" "${rc_directories}"
exit 1
