Changed checkfs to auto reboot after correctable fsck fixes.
[people/pmueller/ipfire-2.x.git] / src / initscripts / init.d / functions
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
18 umask 022
19 export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
20
21 # Signal sent to running processes to refresh their configuration
22 RELOADSIG="HUP"
23
24 # Number of seconds between STOPSIG and FALLBACK when stopping processes
25 KILLDELAY="10"
26
27 ## Screen Dimensions
28 # Find current screen size
29 if [ -z "${COLUMNS}" ]; then
30 COLUMNS=$(stty size)
31 COLUMNS=${COLUMNS##* }
32 fi
33
34 # When using remote connections, such as a serial port, stty size returns 0
35 if [ "${COLUMNS}" = "0" ]; then
36 COLUMNS=80
37 fi
38
39 ## Measurements for positioning result messages
40 COL=$((${COLUMNS} - 8))
41 WCOL=$((${COL} - 2))
42
43 ## Set Cursor Position Commands, used via echo -e
44 SET_COL="\\033[${COL}G" # at the $COL char
45 SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
46 CURS_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
56 NORMAL="\\033[0;39m" # Standard console grey
57 SUCCESS="\\033[1;32m" # Success is green
58 WARNING="\\033[1;33m" # Warnings are yellow
59 FAILURE="\\033[1;31m" # Failures are red
60 INFO="\\033[1;36m" # Information is light cyan
61 BRACKET="\\033[1;34m" # Brackets are blue
62
63 STRING_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 #*******************************************************************************
80 boot_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
111 boot_mesg_flush()
112 {
113 # Reset STRING_LENGTH for next message
114 STRING_LENGTH="0"
115 }
116
117 boot_log()
118 {
119 # Left in for backwards compatibility
120 echo -n ""
121 }
122
123 echo_ok()
124 {
125 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]"
126 echo -e "${NORMAL}"
127 boot_mesg_flush
128 }
129
130 echo_failure()
131 {
132 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
133 echo -e "${NORMAL}"
134 boot_mesg_flush
135 }
136
137 echo_warning()
138 {
139 echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
140 echo -e "${NORMAL}"
141 boot_mesg_flush
142 }
143
144 print_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"
155 boot_mesg -n " ipfire, please be so kind to inform us at"
156 boot_mesg " info@ipfire.org.\n"
157 boot_mesg_flush
158 boot_mesg -n "Press Enter to continue or wait a minute..." ${INFO}
159 boot_mesg "" ${NORMAL}
160 read -t 60 ENTER
161 }
162
163 check_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
179 evaluate_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
194 print_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
245 reloadproc()
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
270 statusproc()
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 #*******************************************************************************
321 pidofproc()
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
402 getpids()
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 #*******************************************************************************
437 loadproc()
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 #*******************************************************************************
529 killproc()
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 #*******************************************************************************
635 log_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 #*******************************************************************************
656 log_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 #*******************************************************************************
676 log_warning_msg() {
677 echo -n -e "${BOOTMESG_PREFIX}${@}"
678 echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
679 return 0
680 }
681
682 run_subdir() {
683 DIR=$1
684 for i in $(ls -v ${DIR}* 2> /dev/null); do
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 ;;
692 U) ${i} up ;;
693 D) ${i} down ;;
694 *) ${i} ;;
695 esac
696 done
697 }
698
699 # End $rc_base/init.d/functions