source: bootscripts/clfs/init.d/functions@ c4b9677

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since c4b9677 was d66bf46, checked in by Jim Gifford <clfs@…>, 18 years ago

Update bootscripts to follow our standards

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