blob: 96f01892f8d57e5ddc5e1da1724afcc06ba6104c [file] [log] [blame]
xf.li86118912025-03-19 20:07:27 -07001# /lib/lsb/init-functions for Debian -*- shell-script -*-
2#
3#Copyright (c) 2002-08 Chris Lawrence
4#All rights reserved.
5#
6#Redistribution and use in source and binary forms, with or without
7#modification, are permitted provided that the following conditions
8#are met:
9#1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11#2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#3. Neither the name of the author nor the names of other contributors
15# may be used to endorse or promote products derived from this software
16# without specific prior written permission.
17#
18#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21#ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
22#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23#CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24#SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25#BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27#OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28#EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30start_daemon () {
31 local force nice pidfile exec i args
32 force=0
33 nice=0
34 pidfile=/dev/null
35
36 OPTIND=1
37 while getopts fn:p: opt ; do
38 case "$opt" in
39 f) force=1;;
40 n) nice="$OPTARG";;
41 p) pidfile="$OPTARG";;
42 esac
43 done
44
45 shift $(($OPTIND - 1))
46 if [ "$1" = '--' ]; then
47 shift
48 fi
49
50 exec="$1"; shift
51
52 args="--start --nicelevel $nice --quiet --oknodo"
53 if [ $force = 1 ]; then
54 /sbin/start-stop-daemon $args --chdir "$PWD" --startas $exec --pidfile /dev/null -- "$@"
55 elif [ $pidfile ]; then
56 /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec --oknodo --pidfile "$pidfile" -- "$@"
57 else
58 /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec -- "$@"
59 fi
60}
61
62pidofproc () {
63 local pidfile line i pids= status specified pid
64 pidfile=
65 specified=
66
67 OPTIND=1
68 while getopts p: opt ; do
69 case "$opt" in
70 p) pidfile="$OPTARG"; specified=1;;
71 esac
72 done
73 shift $(($OPTIND - 1))
74
75 base=${1##*/}
76 if [ ! "$specified" ]; then
77 pidfile="/var/run/$base.pid"
78 fi
79
80 if [ -n "${pidfile:-}" -a -r "$pidfile" ]; then
81 read pid < "$pidfile"
82 if [ -n "${pid:-}" ]; then
83 if $(kill -0 "${pid:-}" 2> /dev/null); then
84 echo "$pid"
85 return 0
86 elif ps "${pid:-}" >/dev/null 2>&1; then
87 echo "$pid"
88 return 0 # program is running, but not owned by this user
89 else
90 return 1 # program is dead and /var/run pid file exists
91 fi
92 fi
93 fi
94 if [ "$specified" = 1 ]; then
95 if [ -e "$pidfile" -a ! -r "$pidfile" ]; then
96 return 4 # pidfile exists, but unreadable, return unknown
97 else
98 return 3 # pidfile specified, but contains no PID to test
99 fi
100 fi
101 if [ -x /bin/pidof ]; then
102 status="0"
103 /bin/pidof -o %PPID -x $1 || status="$?"
104 if [ "$status" = 1 ]; then
105 return 3 # program is not running
106 fi
107 return 0
108 fi
109 return 4 # Unable to determine status
110}
111
112# start-stop-daemon uses the same algorithm as "pidofproc" above.
113killproc () {
114 local pidfile sig status base i name_param is_term_sig
115 pidfile=
116 name_param=
117 is_term_sig=no
118
119 OPTIND=1
120 while getopts p: opt ; do
121 case "$opt" in
122 p) pidfile="$OPTARG";;
123 esac
124 done
125 shift $(($OPTIND - 1))
126
127 base=${1##*/}
128 if [ ! $pidfile ]; then
129 name_param="--name $base --pidfile /var/run/$base.pid"
130 else
131 name_param="--pidfile $pidfile"
132 fi
133
134 sig=$(echo ${2:-} | sed -e 's/^-\(.*\)/\1/')
135 sig=$(echo $sig | sed -e 's/^SIG\(.*\)/\1/')
136 if [ -z "$sig" -o "$sig" = 15 -o "$sig" = TERM ]; then
137 is_term_sig=yes
138 fi
139 status=0
140 if [ ! "$is_term_sig" = yes ]; then
141 if [ -n "$sig" ]; then
142 /sbin/start-stop-daemon --stop --signal "$sig" --quiet $name_param || status="$?"
143 else
144 /sbin/start-stop-daemon --stop --quiet $name_param || status="$?"
145 fi
146 else
147 /sbin/start-stop-daemon --stop --quiet --oknodo $name_param || status="$?"
148 fi
149 if [ "$status" = 1 ]; then
150 if [ -n "$sig" ]; then
151 return 0
152 fi
153 return 3 # program is not running
154 fi
155
156 if [ "$status" = 0 -a "$is_term_sig" = yes -a "$pidfile" ]; then
157 pidofproc -p "$pidfile" "$1" >/dev/null || rm -f "$pidfile"
158 fi
159 return 0
160}
161
162# Return LSB status
163status_of_proc () {
164 local pidfile daemon name status
165
166 pidfile=
167 OPTIND=1
168 while getopts p: opt ; do
169 case "$opt" in
170 p) pidfile="$OPTARG";;
171 esac
172 done
173 shift $(($OPTIND - 1))
174
175 if [ -n "$pidfile" ]; then
176 pidfile="-p $pidfile"
177 fi
178 daemon="$1"
179 name="$2"
180
181 status="0"
182 pidofproc $pidfile $daemon >/dev/null || status="$?"
183 if [ "$status" = 0 ]; then
184 log_success_msg "$name is running"
185 return 0
186 elif [ "$status" = 4 ]; then
187 log_failure_msg "could not access PID file for $name"
188 return $status
189 else
190 log_failure_msg "$name is not running"
191 return $status
192 fi
193}
194
195log_use_fancy_output () {
196 TPUT=/usr/bin/tput
197 EXPR=/usr/bin/expr
198 if [ -t 1 ] && [ "x${TERM:-}" != "x" ] && [ "x${TERM:-}" != "xdumb" ] && [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1 && $TPUT setaf 1 >/dev/null 2>&1; then
199 [ -z $FANCYTTY ] && FANCYTTY=1 || true
200 else
201 FANCYTTY=0
202 fi
203 case "$FANCYTTY" in
204 1|Y|yes|true) true;;
205 *) false;;
206 esac
207}
208
209log_success_msg () {
210 if [ -n "${1:-}" ]; then
211 log_begin_msg $@
212 fi
213 log_end_msg 0
214}
215
216log_failure_msg () {
217 if [ -n "${1:-}" ]; then
218 log_begin_msg $@ "..."
219 fi
220 log_end_msg 1 || true
221}
222
223log_warning_msg () {
224 if [ -n "${1:-}" ]; then
225 log_begin_msg $@ "..."
226 fi
227 log_end_msg 255 || true
228}
229
230#
231# NON-LSB HELPER FUNCTIONS
232#
233# int get_lsb_header_val (char *scriptpathname, char *key)
234get_lsb_header_val () {
235 if [ ! -f "$1" ] || [ -z "${2:-}" ]; then
236 return 1
237 fi
238 LSB_S="### BEGIN INIT INFO"
239 LSB_E="### END INIT INFO"
240 sed -n "/$LSB_S/,/$LSB_E/ s/# $2: \(.*\)/\1/p" $1
241}
242
243# int log_begin_message (char *message)
244log_begin_msg () {
245 if [ -z "${1:-}" ]; then
246 return 1
247 fi
248 echo -n "$@"
249}
250
251# Sample usage:
252# log_daemon_msg "Starting GNOME Login Manager" "gdm"
253#
254# On Debian, would output "Starting GNOME Login Manager: gdm"
255# On Ubuntu, would output " * Starting GNOME Login Manager..."
256#
257# If the second argument is omitted, logging suitable for use with
258# log_progress_msg() is used:
259#
260# log_daemon_msg "Starting remote filesystem services"
261#
262# On Debian, would output "Starting remote filesystem services:"
263# On Ubuntu, would output " * Starting remote filesystem services..."
264
265log_daemon_msg () {
266 if [ -z "${1:-}" ]; then
267 return 1
268 fi
269 log_daemon_msg_pre "$@"
270
271 if [ -z "${2:-}" ]; then
272 echo -n "$1:"
273 return
274 fi
275
276 echo -n "$1: $2"
277 log_daemon_msg_post "$@"
278}
279
280# #319739
281#
282# Per policy docs:
283#
284# log_daemon_msg "Starting remote file system services"
285# log_progress_msg "nfsd"; start-stop-daemon --start --quiet nfsd
286# log_progress_msg "mountd"; start-stop-daemon --start --quiet mountd
287# log_progress_msg "ugidd"; start-stop-daemon --start --quiet ugidd
288# log_end_msg 0
289#
290# You could also do something fancy with log_end_msg here based on the
291# return values of start-stop-daemon; this is left as an exercise for
292# the reader...
293#
294# On Ubuntu, one would expect log_progress_msg to be a no-op.
295log_progress_msg () {
296 if [ -z "${1:-}" ]; then
297 return 1
298 fi
299 echo -n " $@"
300}
301
302
303# int log_end_message (int exitstatus)
304log_end_msg () {
305 # If no arguments were passed, return
306 if [ -z "${1:-}" ]; then
307 return 1
308 fi
309
310 retval=$1
311
312 log_end_msg_pre "$@"
313
314 # Only do the fancy stuff if we have an appropriate terminal
315 # and if /usr is already mounted
316 if log_use_fancy_output; then
317 RED=`$TPUT setaf 1`
318 YELLOW=`$TPUT setaf 3`
319 NORMAL=`$TPUT op`
320 else
321 RED=''
322 YELLOW=''
323 NORMAL=''
324 fi
325
326 if [ $1 -eq 0 ]; then
327 echo "."
328 elif [ $1 -eq 255 ]; then
329 /bin/echo -e " ${YELLOW}(warning).${NORMAL}"
330 else
331 /bin/echo -e " ${RED}failed!${NORMAL}"
332 fi
333 log_end_msg_post "$@"
334 return $retval
335}
336
337log_action_msg () {
338 echo "$@."
339}
340
341log_action_begin_msg () {
342 echo -n "$@..."
343}
344
345log_action_cont_msg () {
346 echo -n "$@..."
347}
348
349log_action_end_msg () {
350 log_action_end_msg_pre "$@"
351 if [ -z "${2:-}" ]; then
352 end="."
353 else
354 end=" ($2)."
355 fi
356
357 if [ $1 -eq 0 ]; then
358 echo "done${end}"
359 else
360 if log_use_fancy_output; then
361 RED=`$TPUT setaf 1`
362 NORMAL=`$TPUT op`
363 /bin/echo -e "${RED}failed${end}${NORMAL}"
364 else
365 echo "failed${end}"
366 fi
367 fi
368 log_action_end_msg_post "$@"
369}
370
371# Hooks for /etc/lsb-base-logging.sh
372log_daemon_msg_pre () { :; }
373log_daemon_msg_post () { :; }
374log_end_msg_pre () { :; }
375log_end_msg_post () { :; }
376log_action_end_msg_pre () { :; }
377log_action_end_msg_post () { :; }
378
379FANCYTTY=
380[ -e /etc/lsb-base-logging.sh ] && . /etc/lsb-base-logging.sh || true