]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/initscripts/init.d/functions
Merge branch 'master' into next
[people/pmueller/ipfire-2.x.git] / src / initscripts / init.d / functions
CommitLineData
73d9a908
MT
1#!/bin/sh
2########################################################################
3# Begin $rc_base/init.d/functions
4#
5# Description : Run Level Control Functions
6#
7# Authors : Gerard Beekmans - gerard@linuxfromscratch.org
8#
9# Version : 00.00
10#
11# Notes : With code based on Matthias Benkmann's simpleinit-msb
12# http://winterdrache.de/linux/newboot/index.html
13#
14########################################################################
15
16## Environmental setup
17# Setup default values for environment
18umask 022
19export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
20
21# Signal sent to running processes to refresh their configuration
22RELOADSIG="HUP"
23
24# Number of seconds between STOPSIG and FALLBACK when stopping processes
cb1fb691 25KILLDELAY="10"
73d9a908
MT
26
27## Screen Dimensions
28# Find current screen size
29if [ -z "${COLUMNS}" ]; then
30 COLUMNS=$(stty size)
31 COLUMNS=${COLUMNS##* }
32fi
33
34# When using remote connections, such as a serial port, stty size returns 0
35if [ "${COLUMNS}" = "0" ]; then
36 COLUMNS=80
37fi
38
39## Measurements for positioning result messages
40COL=$((${COLUMNS} - 8))
41WCOL=$((${COL} - 2))
42
43## Set Cursor Position Commands, used via echo -e
44SET_COL="\\033[${COL}G" # at the $COL char
45SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
46CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
47
48## Set color commands, used via echo -e
49# Please consult `man console_codes for more information
50# under the "ECMA-48 Set Graphics Rendition" section
51#
52# Warning: when switching from a 8bit to a 9bit font,
53# the linux console will reinterpret the bold (1;) to
54# the top 256 glyphs of the 9bit font. This does
55# not affect framebuffer consoles
56NORMAL="\\033[0;39m" # Standard console grey
57SUCCESS="\\033[1;32m" # Success is green
58WARNING="\\033[1;33m" # Warnings are yellow
59FAILURE="\\033[1;31m" # Failures are red
60INFO="\\033[1;36m" # Information is light cyan
61BRACKET="\\033[1;34m" # Brackets are blue
62
63STRING_LENGTH="0" # the length of the current message
64
65#*******************************************************************************
66# Function - boot_mesg()
67#
68# Purpose: Sending information from bootup scripts to the console
69#
70# Inputs: $1 is the message
71# $2 is the colorcode for the console
72#
73# Outputs: Standard Output
74#
75# Dependencies: - sed for parsing strings.
76# - grep for counting string length.
77#
78# Todo:
79#*******************************************************************************
80boot_mesg()
81{
82 local ECHOPARM=""
83
84 while true
85 do
86 case "${1}" in
87 -n)
88 ECHOPARM=" -n "
89 shift 1
90 ;;
91 -*)
92 echo "Unknown Option: ${1}"
93 return 1
94 ;;
95 *)
96 break
97 ;;
98 esac
99 done
100
101 ## Figure out the length of what is to be printed to be used
102 ## for warning messges.
103 STRING_LENGTH="`echo "${1}" | sed \
104 -e 's,.,.,g' -e 'l 1' | grep -c \$`"
105
106 # Print the message to the screen
107 echo ${ECHOPARM} -e "${2}${1}"
108
109}
110
111boot_mesg_flush()
112{
113 # Reset STRING_LENGTH for next message
114 STRING_LENGTH="0"
115}
116
117boot_log()
118{
119 # Left in for backwards compatibility
120 echo -n ""
121}
122
123echo_ok()
124{
125 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]"
126 echo -e "${NORMAL}"
127 boot_mesg_flush
128}
129
130echo_failure()
131{
132 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
133 echo -e "${NORMAL}"
134 boot_mesg_flush
135}
136
137echo_warning()
138{
139 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
140 echo -e "${NORMAL}"
141 boot_mesg_flush
142}
143
144print_error_msg()
145{
146 echo_failure
147 # $i is inherited by the rc script
148 boot_mesg -n "FAILURE:\n\nYou should not be reading this error message.\n\n" ${FAILURE}
149 boot_mesg -n " It means that an unforeseen error took"
150 boot_mesg -n " place in ${i}, which exited with a return value of"
151 boot_mesg " ${error_value}.\n"
152 boot_mesg_flush
153 boot_mesg -n "If you're able to track this"
154 boot_mesg -n " error down to a bug in one of the files provided by"
4601019b
MT
155 boot_mesg -n " ipfire, please be so kind to inform us at"
156 boot_mesg " info@ipfire.org.\n"
73d9a908 157 boot_mesg_flush
e147d1e6 158 boot_mesg -n "Press Enter to continue or wait a minute..." ${INFO}
73d9a908 159 boot_mesg "" ${NORMAL}
e147d1e6 160 read -t 60 ENTER
73d9a908
MT
161}
162
163check_script_status()
164{
165 # $i is inherited by the rc script
166 if [ ! -f ${i} ]; then
167 boot_mesg "${i} is not a valid symlink." ${WARNING}
168 echo_warning
169 continue
170 fi
171
172 if [ ! -x ${i} ]; then
173 boot_mesg "${i} is not executable, skipping." ${WARNING}
174 echo_warning
175 continue
176 fi
177}
178
179evaluate_retval()
180{
181 error_value="${?}"
182
183 if [ ${error_value} = 0 ]; then
184 echo_ok
185 else
186 echo_failure
187 fi
188
189 # This prevents the 'An Unexpected Error Has Occurred' from trivial
190 # errors.
191 return 0
192}
193
194print_status()
195{
196 if [ "${#}" = "0" ]; then
197 echo "Usage: ${0} {success|warning|failure}"
198 return 1
199 fi
200
201 case "${1}" in
202
203 success)
204 echo_ok
205 ;;
206
207 warning)
208 # Leave this extra case in because old scripts
209 # may call it this way.
210 case "${2}" in
211 running)
212 echo -e -n "${CURS_UP}"
213 echo -e -n "\\033[${STRING_LENGTH}G "
214 boot_mesg "Already running." ${WARNING}
215 echo_warning
216 ;;
217 not_running)
218 echo -e -n "${CURS_UP}"
219 echo -e -n "\\033[${STRING_LENGTH}G "
220 boot_mesg "Not running." ${WARNING}
221 echo_warning
222 ;;
223 not_available)
224 echo -e -n "${CURS_UP}"
225 echo -e -n "\\033[${STRING_LENGTH}G "
226 boot_mesg "Not available." ${WARNING}
227 echo_warning
228 ;;
229 *)
230 # This is how it is supposed to
231 # be called
232 echo_warning
233 ;;
234 esac
235 ;;
236
237 failure)
238 echo_failure
239 ;;
240
241 esac
242
243}
244
245reloadproc()
246{
247 if [ "${#}" = "0" ]; then
248 echo "Usage: reloadproc [{program}]"
249 exit 1
250 fi
251
252 getpids "${1}"
253
254 if [ -n "${pidlist}" ]; then
255 failure="0"
256 for pid in ${pidlist}
257 do
258 kill -"${RELOADSIG}" "${pid}" || failure="1"
259 done
260
261 (exit ${failure})
262 evaluate_retval
263
264 else
265 boot_mesg "Process ${1} not running." ${WARNING}
266 echo_warning
267 fi
268}
269
270statusproc()
271{
272 if [ "${#}" = "0" ]
273 then
274 echo "Usage: statusproc {program}"
275 exit 1
276 fi
277
278 getpids "${1}"
279
280 if [ -n "${pidlist}" ]; then
281 echo -e "${INFO}${base} is running with Process"\
282 "ID(s) ${pidlist}.${NORMAL}"
283 else
284 if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
285 echo -e "${WARNING}${1} is not running but"\
286 "/var/run/${base}.pid exists.${NORMAL}"
287 else
288 if [ -n "${PIDFILE}" -a -e "${PIDFILE}" ]; then
289 echo -e "${WARNING}${1} is not running"\
290 "but ${PIDFILE} exists.${NORMAL}"
291 else
292 echo -e "${INFO}${1} is not running.${NORMAL}"
293 fi
294 fi
295 fi
296}
297
298# The below functions are documented in the LSB-generic 2.1.0
299
300#*******************************************************************************
301# Function - pidofproc [-s] [-p pidfile] pathname
302#
303# Purpose: This function returns one or more pid(s) for a particular daemon
304#
305# Inputs: -p pidfile, use the specified pidfile instead of pidof
306# pathname, path to the specified program
307#
308# Outputs: return 0 - Success, pid's in stdout
309# return 1 - Program is dead, pidfile exists
310# return 2 - Invalid or excessive number of arguments,
311# warning in stdout
312# return 3 - Program is not running
313#
314# Dependencies: pidof, echo, head
315#
316# Todo: Remove dependency on head
317# This depreciates getpids
318# Test changes to pidof
319#
320#*******************************************************************************
321pidofproc()
322{
323 local pidfile=""
324 local lpids=""
325 local silent=""
326 pidlist=""
327 while true
328 do
329 case "${1}" in
330 -p)
331 pidfile="${2}"
332 shift 2
333 ;;
334
335 -s)
336 # Added for legacy opperation of getpids
337 # eliminates several '> /dev/null'
338 silent="1"
339 shift 1
340 ;;
341 -*)
342 log_failure_msg "Unknown Option: ${1}"
343 return 2
344 ;;
345 *)
346 break
347 ;;
348 esac
349 done
350
351 if [ "${#}" != "1" ]; then
352 shift 1
353 log_failure_msg "Usage: pidofproc [-s] [-p pidfile] pathname"
354 return 2
355 fi
356
357 if [ -n "${pidfile}" ]; then
358 if [ ! -r "${pidfile}" ]; then
359 return 3 # Program is not running
360 fi
361
362 lpids=`head -n 1 ${pidfile}`
363 for pid in ${lpids}
364 do
365 if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
366 kill -0 "${pid}" > /dev/null &&
367 pidlist="${pidlist} ${pid}"
368 fi
369
370 if [ "${silent}" -ne "1" ]; then
371 echo "${pidlist}"
372 fi
373
374 test -z "${pidlist}" &&
375 # Program is dead, pidfile exists
376 return 1
377 # else
378 return 0
379 done
380
381 else
382 pidlist=`pidof -o $$ -o $PPID -x "$1"`
383 if [ "x${silent}" != "x1" ]; then
384 echo "${pidlist}"
385 fi
386
387 # Get provide correct running status
388 if [ -n "${pidlist}" ]; then
389 return 0
390 else
391 return 3
392 fi
393
394 fi
395
396 if [ "$?" != "0" ]; then
397 return 3 # Program is not running
398 fi
399}
400
401# This will ensure compatibility with previous LFS Bootscripts
402getpids()
403{
404 if [ -z "${PIDFILE}" ]; then
405 pidofproc -s -p "${PIDFILE}" $@
406 else
407 pidofproc -s $@
408 fi
409 base="${1##*/}"
410}
411
412#*******************************************************************************
413# Function - loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]
414#
415# Purpose: This runs the specified program as a daemon
416#
417# Inputs: -f, run the program even if it is already running
418# -n nicelevel, specifies a nice level. See nice(1).
419# -p pidfile, uses the specified pidfile
420# pathname, pathname to the specified program
421# args, arguments to pass to specified program
422#
423# Outputs: return 0 - Success
424# return 2 - Invalid of excessive number of arguments,
425# warning in stdout
426# return 4 - Program or service status is unknown
427#
428# Dependencies: nice
429#
430# Todo: LSB says this should be called start_daemon
431# LSB does not say that it should call evaluate_retval
432# It checks for PIDFILE, which is deprecated.
433# Will be removed after BLFS 6.0
434# loadproc returns 0 if program is already running, not LSB compliant
435#
436#*******************************************************************************
437loadproc()
438{
439 local pidfile=""
440 local forcestart=""
441 local nicelevel="10"
442
443# This will ensure compatibility with previous LFS Bootscripts
444 if [ -n "${PIDFILE}" ]; then
445 pidfile="${PIDFILE}"
446 fi
447
448 while true
449 do
450 case "${1}" in
451 -f)
452 forcestart="1"
453 shift 1
454 ;;
455 -n)
456 nicelevel="${2}"
457 shift 2
458 ;;
459 -p)
460 pidfile="${2}"
461 shift 2
462 ;;
463 -*)
464 log_failure_msg "Unknown Option: ${1}"
465 return 2 #invalid or excess argument(s)
466 ;;
467 *)
468 break
469 ;;
470 esac
471 done
472
473 if [ "${#}" = "0" ]; then
474 log_failure_msg "Usage: loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]"
475 return 2 #invalid or excess argument(s)
476 fi
477
478 if [ -z "${forcestart}" ]; then
479 if [ -z "${pidfile}" ]; then
480 pidofproc -s "${1}"
481 else
482 pidofproc -s -p "${pidfile}" "${1}"
483 fi
484
485 case "${?}" in
486 0)
487 log_warning_msg "Unable to continue: ${1} is running"
488 return 0 # 4
489 ;;
490 1)
491 log_warning_msg "Unable to continue: ${pidfile} exists"
492 return 0 # 4
493 ;;
494 3)
495 ;;
496 *)
497 log_failure_msg "Unknown error code from pidofproc: ${?}"
498 return 4
499 ;;
500 esac
501 fi
502
503 nice -n "${nicelevel}" "${@}"
504 evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
505 return 0
506}
507
508#*******************************************************************************
509# Function - killproc [-p pidfile] pathname [signal]
510#
511# Purpose:
512#
513# Inputs: -p pidfile, uses the specified pidfile
514# pathname, pathname to the specified program
515# signal, send this signal to pathname
516#
517# Outputs: return 0 - Success
518# return 2 - Invalid of excessive number of arguments,
519# warning in stdout
520# return 4 - Unknown Status
521#
522# Dependencies: kill
523#
524# Todo: LSB does not say that it should call evaluate_retval
525# It checks for PIDFILE, which is deprecated.
526# Will be removed after BLFS 6.0
527#
528#*******************************************************************************
529killproc()
530{
531 local pidfile=""
532 local killsig=""
533 pidlist=""
534
535# This will ensure compatibility with previous LFS Bootscripts
536 if [ -n "${PIDFILE}" ]; then
537 pidfile="${PIDFILE}"
538 fi
539
540 while true
541 do
542 case "${1}" in
543 -p)
544 pidfile="${2}"
545 shift 2
546 ;;
547 -*)
548 log_failure_msg "Unknown Option: ${1}"
549 return 2
550 ;;
551 *)
552 break
553 ;;
554 esac
555 done
556
557 if [ "${#}" = "2" ]; then
558 killsig="${2}"
559 elif [ "${#}" != "1" ]; then
560 shift 2
561 log_failure_msg "Usage: killproc [-p pidfile] pathname [signal]"
562 return 2
563 fi
564
565 if [ -z "${pidfile}" ]; then
566 pidofproc -s "${1}"
567 else
568 pidofproc -s -p "${pidfile}" "${1}"
569 fi
570
571 # Change....
572 if [ -n "${pidlist}" ]; then
573 for pid in ${pidlist}
574 do
575 kill -${killsig:-TERM} ${pid} 2>/dev/null
576 if [ -z "${killsig}" ]; then
577 # Wait up to 3 seconds, for ${pid} to terminate
578 local dtime=${KILLDELAY}
579 while [ "${dtime}" != "0" ]
580 do
581 kill -0 ${pid} 2>/dev/null || break
582 sleep 1
583 dtime=$(( ${dtime} - 1))
584 done
585 # If ${pid} is still running, kill it
586 kill -0 ${pid} 2>/dev/null && kill -KILL ${pid} 2>/dev/null
587 fi
588 done
589
590 if [ -z "${killsig}" ]; then
591 pidofproc -s "${1}"
592
593 # Program was terminated
594 if [ "$?" != "0" ]; then
595 # Pidfile Exists
596 if [ -f "${pidfile}" ]; then
597 rm -f "${pidfile}"
598 fi
599 echo_ok
600 return 0
601 else # Program is still running
602 echo_failure
603 return 4 # Unknown Status
604 fi
605 else
606 if [ -z "${pidfile}" ]; then
607 pidofproc -s "${1}"
608 else
609 pidofproc -s -p "${pidfile}" "${1}"
610 fi
611 fi
612
613 evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
614
615 else
616 print_status warning not_running
617 fi
618}
619
620
621#*******************************************************************************
622# Function - log_success_msg "message"
623#
624# Purpose: Print a success message
625#
626# Inputs: $@ - Message
627#
628# Outputs: Text output to screen
629#
630# Dependencies: echo
631#
632# Todo: logging
633#
634#*******************************************************************************
635log_success_msg()
636{
637 echo -n -e "${BOOTMESG_PREFIX}${@}"
638 echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}"" OK ""${BRACKET}""]""${NORMAL}"
639 return 0
640}
641
642#*******************************************************************************
643# Function - log_failure_msg "message"
644#
645# Purpose: Print a failure message
646#
647# Inputs: $@ - Message
648#
649# Outputs: Text output to screen
650#
651# Dependencies: echo
652#
653# Todo: logging
654#
655#*******************************************************************************
656log_failure_msg() {
657 echo -n -e "${BOOTMESG_PREFIX}${@}"
658 echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
659 return 0
660}
661
662#*******************************************************************************
663# Function - log_warning_msg "message"
664#
665# Purpose: print a warning message
666#
667# Inputs: $@ - Message
668#
669# Outputs: Text output to screen
670#
671# Dependencies: echo
672#
673# Todo: logging
674#
675#*******************************************************************************
676log_warning_msg() {
677 echo -n -e "${BOOTMESG_PREFIX}${@}"
678 echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
679 return 0
680}
681
0e42072a 682run_subdir() {
905fbf3e
MT
683 DIR=$1
684 for i in $(ls -v ${DIR}* 2> /dev/null); do
0e42072a
MT
685 check_script_status
686 OUT=$(echo $(basename ${i}) | awk -F- '{ print $2 }')
687 case "$OUT" in
688 S) ${i} start ;;
689 K) ${i} stop ;;
690 RS) ${i} restart ;;
691 RL) ${i} reload ;;
ebca0d9a 692 U) ${i} up ;;
905fbf3e 693 D) ${i} down ;;
0e42072a
MT
694 *) ${i} ;;
695 esac
696 done
378cbbe0
MT
697}
698
73d9a908 699# End $rc_base/init.d/functions