xref: /freebsd/usr.sbin/service/service.sh (revision b37f6c9805edb4b89f0a8c2b78f78a3dcfc0647b)
1#!/bin/sh
2
3# $FreeBSD$
4
5# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6#
7#  Copyright (c) 2009 Douglas Barton
8#  All rights reserved.
9#
10#  Redistribution and use in source and binary forms, with or without
11#  modification, are permitted provided that the following conditions
12#  are met:
13#  1. Redistributions of source code must retain the above copyright
14#     notice, this list of conditions and the following disclaimer.
15#  2. Redistributions in binary form must reproduce the above copyright
16#     notice, this list of conditions and the following disclaimer in the
17#     documentation and/or other materials provided with the distribution.
18#
19#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22#  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29#  SUCH DAMAGE.
30
31. /etc/rc.subr
32load_rc_config 'XXX'
33
34usage () {
35	echo ''
36	echo 'Usage:'
37	echo "${0##*/} [-j <jail name or id>] -e"
38	echo "${0##*/} [-j <jail name or id>] -R"
39	echo "${0##*/} [-j <jail name or id>] [-v] -l | -r"
40	echo "${0##*/} [-j <jail name or id>] [-v] <rc.d script> start|stop|etc."
41	echo "${0##*/} -h"
42	echo ''
43	echo "-j	Perform actions within the named jail"
44	echo '-e	Show services that are enabled'
45	echo "-R	Stop and start enabled $local_startup services"
46	echo "-l	List all scripts in /etc/rc.d and $local_startup"
47	echo '-r	Show the results of boot time rcorder'
48	echo '-v	Verbose'
49	echo ''
50}
51
52accepted_argstr='jehlrRv'
53
54# Only deal with the -j option here. If found, JAIL is set and the opt and
55# arg are shifted out. OPTIND is left untouched. We strip the -j option out
56# here because we'll be proxying this invocation through to the jail via
57# jls(8) instead of handling it ourselves.
58while getopts ${accepted_argstr} COMMAND_LINE_ARGUMENT ; do
59	case "${COMMAND_LINE_ARGUMENT}" in
60	j)	JAIL="$2" ; shift ; shift ;;
61	esac
62done
63
64# If -j was provided, then we pass everthing along to the jexec command
65# and execute `service` within the named JAIL. Provided that the jail
66# actually exists, as checked by `jls`.
67# We do this so that if the jail does exist, we can then return the exit
68# code of `jexec` and it should be the exit code of whatever ran in the jail.
69# There is a race condition here in that the jail might exist at `jls` time
70# and be gone by `jexec` time, but it shouldn't be a big deal.
71if [ -n "$JAIL" ]; then
72	/usr/sbin/jls -j "$JAIL" 2>/dev/null >/dev/null
73	if [ $? -ne 0 ]; then
74		echo "Jail '$JAIL' does not exist."
75		exit 1
76	fi
77
78	/usr/sbin/jexec -l "$JAIL" /usr/sbin/service $*
79	exit $?
80fi
81
82OPTIND=1
83while getopts ${accepted_argstr} COMMAND_LINE_ARGUMENT ; do
84	case "${COMMAND_LINE_ARGUMENT}" in
85	e)	ENABLED=eopt ;;
86	h)	usage ; exit 0 ;;
87	l)	LIST=lopt ;;
88	r)	RCORDER=ropt ;;
89	R)	RESTART=Ropt ;;
90	v)	VERBOSE=vopt ;;
91	*)	usage ; exit 1 ;;
92	esac
93done
94shift $(( $OPTIND - 1 ))
95
96if [ -n "$RESTART" ]; then
97	skip="-s nostart"
98	if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
99		skip="$skip -s nojail"
100	fi
101	[ -n "$local_startup" ] && find_local_scripts_new
102	files=`rcorder ${skip} ${local_rc} 2>/dev/null`
103
104	for file in `reverse_list ${files}`; do
105		if grep -q ^rcvar $file; then
106			eval `grep ^name= $file`
107			eval `grep ^rcvar $file`
108			if [ -n "$rcvar" ]; then
109				load_rc_config_var ${name} ${rcvar}
110			fi
111			checkyesno $rcvar 2>/dev/null && run_rc_script ${file} stop
112		fi
113	done
114	for file in $files; do
115		if grep -q ^rcvar $file; then
116			eval `grep ^name= $file`
117			eval `grep ^rcvar $file`
118			checkyesno $rcvar 2>/dev/null && run_rc_script ${file} start
119		fi
120	done
121
122	exit 0
123fi
124
125if [ -n "$ENABLED" -o -n "$RCORDER" ]; then
126	# Copied from /etc/rc
127	skip="-s nostart"
128	if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
129		skip="$skip -s nojail"
130	fi
131	[ -n "$local_startup" ] && find_local_scripts_new
132	files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
133fi
134
135if [ -n "$ENABLED" ]; then
136	for file in $files; do
137		if grep -q ^rcvar $file; then
138			eval `grep ^name= $file`
139			eval `grep ^rcvar $file`
140			if [ -n "$rcvar" ]; then
141				load_rc_config_var ${name} ${rcvar}
142			fi
143			checkyesno $rcvar 2>/dev/null && echo $file
144		fi
145	done
146	exit 0
147fi
148
149if [ -n "$LIST" ]; then
150	for dir in /etc/rc.d $local_startup; do
151		[ -n "$VERBOSE" ] && echo "From ${dir}:"
152		[ -d ${dir} ] && /bin/ls -1 ${dir}
153	done
154	exit 0
155fi
156
157if [ -n "$RCORDER" ]; then
158	for file in $files; do
159		echo $file
160		if [ -n "$VERBOSE" ]; then
161			case "$file" in
162			*/${early_late_divider})
163				echo '========= Early/Late Divider =========' ;;
164			esac
165		fi
166	done
167	exit 0
168fi
169
170if [ $# -gt 1 ]; then
171	script=$1
172	shift
173else
174	usage
175	exit 1
176fi
177
178cd /
179for dir in /etc/rc.d $local_startup; do
180	if [ -x "$dir/$script" ]; then
181		[ -n "$VERBOSE" ] && echo "$script is located in $dir"
182		exec env -i HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin $dir/$script $*
183	fi
184done
185
186# If the script was not found
187echo "$script does not exist in /etc/rc.d or the local startup"
188echo "directories (${local_startup}), or is not executable"
189exit 1
190