xref: /netbsd/usr.sbin/service/service (revision 51a0772d)
1226f7e91Sast#!/bin/sh
2*51a0772dSkre#    $NetBSD: service,v 1.9 2023/03/14 06:19:35 kre Exp $
3226f7e91Sast#    service -- run or list system services
4226f7e91Sast#
5226f7e91Sast#  Taken from FreeBSD: releng/10.1/usr.sbin/service/service.sh 268098
6226f7e91Sast#  Modified for NetBSD by Adrian Steinmann in March, 2015
7226f7e91Sast#
8226f7e91Sast#  Copyright (c) 2009 Douglas Barton
9226f7e91Sast#  All rights reserved.
10226f7e91Sast#
11226f7e91Sast#  Redistribution and use in source and binary forms, with or without
12226f7e91Sast#  modification, are permitted provided that the following conditions
13226f7e91Sast#  are met:
14226f7e91Sast#  1. Redistributions of source code must retain the above copyright
15226f7e91Sast#     notice, this list of conditions and the following disclaimer.
16226f7e91Sast#  2. Redistributions in binary form must reproduce the above copyright
17226f7e91Sast#     notice, this list of conditions and the following disclaimer in the
18226f7e91Sast#     documentation and/or other materials provided with the distribution.
19226f7e91Sast#
20226f7e91Sast#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21226f7e91Sast#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22226f7e91Sast#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23226f7e91Sast#  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24226f7e91Sast#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25226f7e91Sast#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26226f7e91Sast#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27226f7e91Sast#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28226f7e91Sast#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29226f7e91Sast#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30226f7e91Sast#  SUCH DAMAGE.
31226f7e91Sast
32226f7e91Sastexport PATH=/sbin:/bin:/usr/sbin:/usr/bin
33226f7e91Sast
34226f7e91Sastusage ()
35226f7e91Sast{
3613ae0c2bSapb    local me="${0##*/}"
37*51a0772dSkre
38*51a0772dSkre    exec >&2
39*51a0772dSkre
40*51a0772dSkre    printf 'Usage:\t%s -l [-v]\n' "${me}"
41*51a0772dSkre    printf '\t%s\n'							   \
42*51a0772dSkre	"       List all scripts in rc order"				   \
43*51a0772dSkre	"   -v: Prepend the value of rc_directories to the output"	   \
44*51a0772dSkre	"${me} -e [-v]"							   \
45*51a0772dSkre	"       Print names of all enabled scripts"			   \
46*51a0772dSkre	"   -v: Include the value of rc_directories (to stderr)"	   \
47*51a0772dSkre	"${me} -e [-v] rc_script_name [rc_script_name...]"		   \
48*51a0772dSkre	"       Print path names of any given scripts which are enabled"   \
49*51a0772dSkre	"   -v: Include the value of rc_directories (to stderr)"	   \
50*51a0772dSkre	"${me} [-v] rc_script_name action"				   \
51*51a0772dSkre	"       Run rc_script_name to perform the action specified"	   \
52*51a0772dSkre	"   -v: Verbose (mention in which directory script was found)"
53*51a0772dSkre    printf 'rc_directories is currently set to: %s\n' "${rc_directories}"
54*51a0772dSkre    exit 2
55226f7e91Sast}
56226f7e91Sast
5700458d6aSast# list all files in rc_directories with absolute pathnames
58*51a0772dSkre# (don't use ls(1) so we get the pathnames, without using non-std options)
5900458d6aSast_rc_files()
60226f7e91Sast{
61*51a0772dSkre    local _d _f IFS
62*51a0772dSkre
63*51a0772dSkre    IFS=$'\n'
64*51a0772dSkre    rcorder -s nostart ${rc_rcorder_flags} $(
65*51a0772dSkre	for _d in ${rc_directories}
66*51a0772dSkre	do
67*51a0772dSkre	    if [ -d "$_d" ]
68*51a0772dSkre	    then
69*51a0772dSkre		for _f in "$_d"/*
70*51a0772dSkre		do
71*51a0772dSkre		    if [ -f "$_f" ] && [ -x "$_f" ]
72*51a0772dSkre		    then
73*51a0772dSkre			printf '%s\n' "$_f"
74*51a0772dSkre		    fi
75e7b575edSast		done
7600458d6aSast	    fi
77*51a0772dSkre	done
78*51a0772dSkre    )
79226f7e91Sast    return 0
80226f7e91Sast}
81226f7e91Sast
82*51a0772dSkre_rc_dirs()
83*51a0772dSkre{
84*51a0772dSkre    if "${VERBOSE}"
85*51a0772dSkre    then
86*51a0772dSkre	printf 'rc_directories is %s\n' "${rc_directories}"
87*51a0772dSkre    fi
88*51a0772dSkre}
89*51a0772dSkre
90*51a0772dSkreENABLED=false
91*51a0772dSkreLIST=false
92*51a0772dSkreVERBOSE=false
93*51a0772dSkre
94*51a0772dSkrewhile getopts elv o
95*51a0772dSkredo
9613ae0c2bSapb    case "$o" in
97*51a0772dSkre	e) ENABLED=true	;;
98*51a0772dSkre	l) LIST=true	;;
99*51a0772dSkre	v) VERBOSE=true	;;
100c706eb5fSast	*) usage	;;
101226f7e91Sast    esac
102226f7e91Sastdone
103*51a0772dSkreshift $(( OPTIND - 1 ))
104c706eb5fSast
105*51a0772dSkreif "${ENABLED}" && "${LIST}"
106226f7e91Sastthen
107*51a0772dSkre    usage
108226f7e91Sastfi
109*51a0772dSkre
110*51a0772dSkreif ! [ -f /etc/rc.subr ]
111*51a0772dSkrethen
112*51a0772dSkre	printf >&2 '%s: The rc system seems to be missing /etc/rc.subr\n' \
113*51a0772dSkre	    "${0##*/}"
114*51a0772dSkre	exit 3
115*51a0772dSkrefi
116*51a0772dSkre
117*51a0772dSkreif command . /etc/rc.subr
118*51a0772dSkrethen
119*51a0772dSkre	load_rc_config :
120*51a0772dSkreelse
121*51a0772dSkre	printf >&2 '%s: Problems running /etc/rc.subr.   Aborting\n'  "${0##*/}"
122*51a0772dSkre	exit 3
123*51a0772dSkrefi
124*51a0772dSkre
125*51a0772dSkreif "${ENABLED}"
126*51a0772dSkrethen
127*51a0772dSkre    _rc_dirs >&2
128*51a0772dSkre    case $# in
129*51a0772dSkre    0)	flt=cat;;
130*51a0772dSkre    *)
131*51a0772dSkre	IFS='|'
132*51a0772dSkre	flt="egrep '/(${*})\$'"
133*51a0772dSkre	;;
134*51a0772dSkre    esac
135*51a0772dSkre    if ( set +o pipefail ) 2>/dev/null
136*51a0772dSkre    then
137*51a0772dSkre	# If this option exists, disable it.
138*51a0772dSkre	set +o pipefail
139*51a0772dSkre    fi
140*51a0772dSkre    IFS=
141*51a0772dSkre    _rc_files | eval "$flt" |
142*51a0772dSkre    {
143*51a0772dSkre	found=false
144*51a0772dSkre	while read file
145226f7e91Sast	do
146*51a0772dSkre	    if grep -q '^rcvar=' "$file"
147*51a0772dSkre	    then
148*51a0772dSkre		unset name rcvar
149*51a0772dSkre		eval "$( sed -n < "$file" -e '/^name=/p' -e '/^rcvar=/p' )"
150*51a0772dSkre		if [ -n "${rcvar}" ]
151*51a0772dSkre		then
152*51a0772dSkre		    load_rc_config "${rcvar}"
153*51a0772dSkre		    if checkyesno "${rcvar}" 2>/dev/null
154*51a0772dSkre		    then
155*51a0772dSkre			printf '%s\n' "${file}"
156*51a0772dSkre			found=true
157226f7e91Sast		    fi
15800458d6aSast		fi
159*51a0772dSkre	    else
160*51a0772dSkre		# pseudo scripts like LOGIN DAEMON ... have no rcvar,
161*51a0772dSkre		# but aren't intended to be run either, those contain
162*51a0772dSkre		# no lower case letters in their names.
163*51a0772dSkre		#
164*51a0772dSkre		# Other scripts without an rcvar are always enabled
165*51a0772dSkre		#
166*51a0772dSkre		# So require at least one lower case letter in the name
167*51a0772dSkre		# in order to run a script without an rcvar, and include
168*51a0772dSkre		# them in the list of enabled scripts.
169*51a0772dSkre
170*51a0772dSkre		case "${file##*/}" in
171*51a0772dSkre		*[:lower:]*) printf '%s\n' "${file}"; found=true;;
172*51a0772dSkre		esac
173*51a0772dSkre	    fi
174226f7e91Sast	done
175*51a0772dSkre	"$found"
176*51a0772dSkre    }
177*51a0772dSkre    exit "$?"
178226f7e91Sastfi
179226f7e91Sast
180*51a0772dSkreif "${LIST}"
181*51a0772dSkrethen
182*51a0772dSkre    _rc_dirs
18300458d6aSast    _rc_files
184226f7e91Sast    exit 0
185226f7e91Sastfi
186226f7e91Sast
187*51a0772dSkreif [ "$#" -ne 2 ]
188*51a0772dSkrethen
189226f7e91Sast    usage
190226f7e91Sastfi
191226f7e91Sast
192*51a0772dSkrescript=$1
193*51a0772dSkrearg=$2
194*51a0772dSkre
195*51a0772dSkrefor dir in ${rc_directories}
196*51a0772dSkredo
197*51a0772dSkre    if [ -x "${dir}/${script}" ]
198*51a0772dSkre    then
199*51a0772dSkre	if "${VERBOSE}"
200*51a0772dSkre	then
201*51a0772dSkre	    printf >&2 '%s script is located in %s\n' "${script}" "${dir}"
202*51a0772dSkre	fi
203*51a0772dSkre
204226f7e91Sast	# run as in /etc/rc
205226f7e91Sast	cd /
206226f7e91Sast	umask 022
207226f7e91Sast	exec env -i \
208226f7e91Sast	    HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin \
20913ae0c2bSapb		"${dir}/${script}" "${arg}"
210*51a0772dSkre	printf >&2 'Failed to exec %s (status %d)\n' \
211*51a0772dSkre		"${dir}/${script} ${arg}" "$?"
212*51a0772dSkre	exit 126
213226f7e91Sast    fi
214226f7e91Sastdone
215226f7e91Sast
216*51a0772dSkreprintf >&2 '%s does not exist in%s\n' "${script}" "${rc_directories}"
217226f7e91Sastexit 1
218