source: bootscripts-standard/clfs/init.d/functions@ 7df280d

Last change on this file since 7df280d was 7df280d, checked in by Joe Ciccone <jciccone@…>, 17 years ago

Change /bin/sh to /bin/bash in the bootscripts because the bootscripts use bashisms. Having ash linked to sh will cause errors. Thanks to Bigdassaved for providing the diff and Copper for bring up the issue.

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