source: bootscripts/lfs/init.d/functions @ 8953f24

clfs-1.2clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since 8953f24 was 8953f24, checked in by Jim Gifford <clfs@…>, 18 years ago

Readded Bootlog to bootscripts

  • Property mode set to 100644
File size: 16.0 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       
124}
125
126boot_mesg_flush()
127{
128        # Reset STRING_LENGTH for next message
129        STRING_LENGTH="0"
130        if [ "$LOGGING" ]; then
131                boot_log "${BOOTMESG}${@}"
132        fi
133}
134
135boot_log()
136{
137        if [ "$LOGGING" ]; then
138                /bin/logger -p local2.info -t bootlog "${@}"
139        else
140                return 0
141        fi
142}
143
144echo_ok()
145{
146        echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${SUCCESS}  OK  ${BRACKET}]"
147        echo -e "${NORMAL}"
148        boot_mesg_flush "[  OK  ]"
149        if [ "$LCD_PROG" ]; then
150                if [ "$LCD_LINES" = "2" ]; then
151                        LCD_OUT2="[  OK  ]"
152                        $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
153                else
154                        LCD_OUT2="${LCD_OUT1:0:12} OK"
155                        $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
156                fi                     
157        fi
158}
159
160echo_failure()
161{
162        echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]"
163        echo -e "${NORMAL}"
164        boot_mesg_flush "[ FAIL ]"
165        if [ "$LCD_PROG" ]; then
166                if [ "$LCD_LINES" = "2" ]; then
167                        LCD_OUT2="[ FAIL  ]"
168                        $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
169                else
170                        LCD_OUT2="${LCD_OUT1:0:10} FAIL"
171                        $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
172                fi
173        fi
174}
175
176echo_warning()
177{
178        echo -n -e "${CURS_UP}${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]"
179        echo -e "${NORMAL}"
180        if [ "$LCD_PROG" ]; then
181                if [ "$LCD_LINES" = "2" ]; then
182                        LCD_OUT2="[ WARN  ]"
183                        $LCD_PROG "$LCD_OUT1" "$LCD_OUT2" > /dev/null 2>&1
184                else
185                        LCD_OUT2="${LCD_OUT1:0:10} WARN"
186                        $LCD_PROG "$LCD_OUT2" > /dev/null 2>&1
187                fi                     
188        fi
189        boot_mesg_flush "[ WARN ]"
190}
191
192print_error_msg()
193{
194        echo_failure
195        # $i is inherited by the rc script
196        boot_log "\n\n${i} failed and exited with a return value of ${error_value}."
197        boot_mesg_flush
198        boot_mesg -n "FAILURE:\n\nYou should not be reading this error message.\n\n" ${FAILURE}
199        boot_mesg -n " It means that an unforeseen error took"
200        boot_mesg -n " place in ${i}, which exited with a return value of"
201        boot_mesg " ${error_value}.\n"
202        boot_mesg_flush
203        boot_mesg -n "If you're able to track this"
204        boot_mesg -n " error down to a bug in one of the files provided by"
205        boot_mesg -n " the CLFS book, please be so kind to inform us at"
206        boot_mesg " clfs-dev@cross-lfs.org.\n"
207        boot_mesg_flush
208        if [ "$INTERACTIVE" ]; then
209                boot_mesg -n "Press Enter to continue..." ${INFO}
210                boot_mesg "" ${NORMAL}
211                if [ "$LCD_PROG" ]; then
212                        sleep 10
213                else
214                        read ENTER
215                fi
216        fi
217}
218
219check_script_status()
220{
221        # $i is inherited by the rc script
222        if [ ! -f ${i} ]; then
223                boot_mesg "${i} is not a valid symlink." ${WARNING}
224                echo_warning
225                continue
226        fi
227
228        if [ ! -x ${i} ]; then
229                boot_mesg "${i} is not executable, skipping." ${WARNING}
230                echo_warning
231                continue
232        fi
233}
234
235evaluate_retval()
236{
237        error_value="${?}"
238
239        if [ ${error_value} = 0 ]; then
240                echo_ok
241        else
242                echo_failure
243        fi
244
245        # This prevents the 'An Unexpected Error Has Occurred' from trivial
246        # errors.
247        return 0
248}
249
250print_status()
251{
252        if [ "${#}" = "0" ]; then
253                echo "Usage: ${0} {success|warning|failure}"
254                return 1
255        fi
256
257#       boot_mesg_flush
258#       echo_warning
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        if [ "${#}" = "0" ]; then
307                echo "Usage: reloadproc [{program}]"
308                exit 1
309        fi
310
311        getpids "${1}"
312
313        if [ -n "${pidlist}" ]; then
314                failure="0"
315                for pid in ${pidlist}
316                do
317                        kill -"${RELOADSIG}" "${pid}" || failure="1"
318                done
319
320                (exit ${failure})
321                evaluate_retval
322
323        else
324                boot_mesg "Process ${1} not running." ${WARNING}
325                echo_warning
326        fi
327}
328
329statusproc()
330{
331        if [ "${#}" = "0" ]
332        then
333                echo "Usage: statusproc {program}"
334                exit 1
335        fi
336
337        getpids "${1}"
338
339        if [ -n "${pidlist}" ]; then
340                echo -e "${INFO}${base} is running with Process"\
341                        "ID(s) ${pidlist}.${NORMAL}"
342        else
343                if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
344                        echo -e "${WARNING}${1} is not running but"\
345                                "/var/run/${base}.pid exists.${NORMAL}"
346                else
347                        if [ -n "${PIDFILE}" -a -e "${PIDFILE}" ]; then
348                                echo -e "${WARNING}${1} is not running"\
349                                        "but ${PIDFILE} exists.${NORMAL}"
350                        else
351                                echo -e "${INFO}${1} is not running.${NORMAL}"
352                        fi
353                fi
354        fi
355}
356
357# The below functions are documented in the LSB-generic 2.1.0
358
359#*******************************************************************************
360# Function - pidofproc [-s] [-p pidfile] pathname
361#
362# Purpose: This function returns one or more pid(s) for a particular daemon
363#
364# Inputs: -p pidfile, use the specified pidfile instead of pidof
365#         pathname, path to the specified program
366#
367# Outputs: return 0 - Success, pid's in stdout
368#          return 1 - Program is dead, pidfile exists
369#          return 2 - Invalid or excessive number of arguments,
370#                     warning in stdout
371#          return 3 - Program is not running
372#
373# Dependencies: pidof, echo, head
374#
375# Todo: Remove dependency on head
376#       This depreciates getpids
377#       Test changes to pidof
378#
379#*******************************************************************************
380pidofproc()
381{
382        local pidfile=""
383        local lpids=""
384        local silent=""
385        pidlist=""
386        while true
387        do
388                case "${1}" in
389                        -p)
390                                pidfile="${2}"
391                                shift 2
392                                ;;
393
394                        -s)
395                                # Added for legacy opperation of getpids
396                                # eliminates several '> /dev/null'
397                                silent="1"
398                                shift 1
399                                ;;
400                        -*)
401                                log_failure_msg "Unknown Option: ${1}"
402                                return 2
403                                ;;
404                        *)
405                                break
406                                ;;
407                esac
408        done
409
410        if [ "${#}" != "1" ]; then
411                shift 1
412                log_failure_msg "Usage: pidofproc [-s] [-p pidfile] pathname"
413                return 2
414        fi
415
416        if [ -n "${pidfile}" ]; then
417                if [ ! -r "${pidfile}" ]; then
418                        return 3 # Program is not running
419                fi
420
421                lpids=`head -n 1 ${pidfile}`
422                for pid in ${lpids}
423                do
424                        if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
425                                kill -0 "${pid}" > /dev/null &&
426                                pidlist="${pidlist} ${pid}"
427                        fi
428                       
429                        if [ "${silent}" -ne "1" ]; then
430                                echo "${pidlist}"
431                        fi
432
433                        test -z "${pidlist}" && 
434                        # Program is dead, pidfile exists
435                        return 1
436                        # else
437                        return 0
438                done
439
440        else
441                pidlist=`pidof -o $$ -o $PPID -x "$1"`
442                if [ "x${silent}" != "x1" ]; then
443                        echo "${pidlist}"
444                fi
445
446                # Get provide correct running status
447                if [ -n "${pidlist}" ]; then
448                        return 0
449                else
450                        return 3
451                fi
452
453        fi
454
455        if [ "$?" != "0" ]; then
456                return 3 # Program is not running
457        fi
458}
459
460# This will ensure compatibility with previous CLFS Bootscripts
461getpids()
462{
463        if [ -z "${PIDFILE}" ]; then
464                pidofproc -s -p "${PIDFILE}" $@
465        else
466                pidofproc -s $@
467        fi
468        base="${1##*/}"
469}
470
471#*******************************************************************************
472# Function - loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]
473#
474# Purpose: This runs the specified program as a daemon
475#
476# Inputs: -f, run the program even if it is already running
477#         -n nicelevel, specifies a nice level. See nice(1).
478#         -p pidfile, uses the specified pidfile
479#         pathname, pathname to the specified program
480#         args, arguments to pass to specified program
481#
482# Outputs: return 0 - Success
483#          return 2 - Invalid of excessive number of arguments,
484#                     warning in stdout
485#          return 4 - Program or service status is unknown
486#
487# Dependencies: nice
488#
489# Todo: LSB says this should be called start_daemon
490#       LSB does not say that it should call evaluate_retval
491#       It checks for PIDFILE, which is deprecated.
492#         Will be removed after BLFS 6.0
493#       loadproc returns 0 if program is already running, not LSB compliant
494#
495#*******************************************************************************
496loadproc()
497{
498        local pidfile=""
499        local forcestart=""
500        local nicelevel="10"
501
502# This will ensure compatibility with previous CLFS Bootscripts
503        if [ -n "${PIDFILE}" ]; then
504                pidfile="${PIDFILE}"
505        fi
506
507  while true
508        do
509                case "${1}" in
510                        -f)
511                                forcestart="1"
512                                shift 1
513                                ;;
514                        -n)
515                                nicelevel="${2}"
516                                shift 2
517                                ;;
518                        -p)
519                                pidfile="${2}"
520                                shift 2
521                                ;;
522                        -*)
523                                log_failure_msg "Unknown Option: ${1}"
524                                return 2 #invalid or excess argument(s)
525                                ;;
526                        *)
527                                break
528                                ;;
529                esac
530        done
531
532        if [ "${#}" = "0" ]; then
533                log_failure_msg "Usage: loadproc [-f] [-n nicelevel] [-p pidfile] pathname [args]"
534                return 2 #invalid or excess argument(s)
535        fi
536
537        if [ -z "${forcestart}" ]; then
538                if [ -z "${pidfile}" ]; then
539                        pidofproc -s "${1}"
540                else
541                        pidofproc -s -p "${pidfile}" "${1}"
542                fi
543
544                case "${?}" in
545                        0)
546                                log_warning_msg "Unable to continue: ${1} is running"
547                                return 0 # 4
548                                ;;
549                        1)
550                                log_warning_msg "Unable to continue: ${pidfile} exists"
551                                return 0 # 4
552                                ;;
553                        3)
554                                ;;
555                        *)
556                                log_failure_msg "Unknown error code from pidofproc: ${?}"
557                                return 4
558                                ;;
559                esac
560        fi
561
562        nice -n "${nicelevel}" "${@}"
563        evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
564        return 0
565}
566
567#*******************************************************************************
568# Function - killproc  [-p pidfile] pathname [signal]
569#
570# Purpose:
571#
572# Inputs: -p pidfile, uses the specified pidfile
573#         pathname, pathname to the specified program
574#         signal, send this signal to pathname
575#
576# Outputs: return 0 - Success
577#          return 2 - Invalid of excessive number of arguments,
578#                     warning in stdout
579#          return 4 - Unknown Status
580#
581# Dependencies: kill
582#
583# Todo: LSB does not say that it should call evaluate_retval
584#       It checks for PIDFILE, which is deprecated.
585#         Will be removed after BLFS 6.0
586#
587#*******************************************************************************
588killproc()
589{
590        local pidfile=""
591        local killsig=""
592        pidlist=""
593
594# This will ensure compatibility with previous CLFS Bootscripts
595        if [ -n "${PIDFILE}" ]; then
596                pidfile="${PIDFILE}"
597        fi
598
599        while true
600        do
601                case "${1}" in
602                        -p)
603                                pidfile="${2}"
604                                shift 2
605                                ;;
606                        -*)
607                                log_failure_msg "Unknown Option: ${1}"
608                                return 2
609                        ;;
610                        *)
611                                break
612                                ;;
613                esac
614        done
615
616        if [ "${#}" = "2" ]; then
617                killsig="${2}"
618        elif [ "${#}" != "1" ]; then
619                shift 2
620                log_failure_msg "Usage: killproc  [-p pidfile] pathname [signal]"
621                return 2
622        fi
623
624        if [ -z "${pidfile}" ]; then
625                pidofproc -s "${1}"
626        else
627                pidofproc -s -p "${pidfile}" "${1}"
628        fi
629
630    # Change....
631    if [ -n "${pidlist}" ]; then
632        for pid in ${pidlist}
633        do
634                kill -${killsig:-TERM} ${pid} 2>/dev/null
635                if [ -z "${killsig}" ]; then
636                        # Wait up to 3 seconds, for ${pid} to terminate
637                        local dtime=${KILLDELAY}
638                        while [ "${dtime}" != "0" ]
639                        do
640                                kill -0 ${pid} 2>/dev/null || break
641                                sleep 1
642                                dtime=$(( ${dtime} - 1))
643                        done
644                        # If ${pid} is still running, kill it
645                        kill -0 ${pid} 2>/dev/null && kill -KILL ${pid} 2>/dev/null
646                fi
647        done
648
649        if [ -z "${killsig}" ]; then
650                pidofproc -s "${1}"
651
652                # Program was terminated
653                if [ "$?" != "0" ]; then
654                        # Pidfile Exists
655                        if [ -f "${pidfile}" ]; then
656                                rm -f "${pidfile}"
657                        fi
658                        echo_ok
659                        return 0
660                else # Program is still running
661                        echo_failure
662                        return 4 # Unknown Status
663                fi
664        else
665                if [ -z "${pidfile}" ]; then
666                        pidofproc -s "${1}"
667                else
668                        pidofproc -s -p "${pidfile}" "${1}"
669                fi
670        fi
671
672        evaluate_retval # This is "Probably" not LSB compliant, but required to be compatible with older bootscripts
673
674    else
675        print_status warning not_running
676    fi
677}
678
679
680#*******************************************************************************
681# Function - log_success_msg "message"
682#
683# Purpose: Print a success message
684#
685# Inputs: $@ - Message
686#
687# Outputs: Text output to screen
688#
689# Dependencies: echo
690#
691# Todo: logging
692#
693#*******************************************************************************
694log_success_msg()
695{
696        echo -n -e "${BOOTMESG_PREFIX}${@}"
697        echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}""  OK  ""${BRACKET}""]""${NORMAL}"
698        return 0
699}
700
701#*******************************************************************************
702# Function - log_failure_msg "message"
703#
704# Purpose: Print a failure message
705#
706# Inputs: $@ - Message
707#
708# Outputs: Text output to screen
709#
710# Dependencies: echo
711#
712# Todo: logging
713#
714#*******************************************************************************
715log_failure_msg() {
716        echo -n -e "${BOOTMESG_PREFIX}${@}"
717        echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
718        return 0
719}
720
721#*******************************************************************************
722# Function - log_warning_msg "message"
723#
724# Purpose: print a warning message
725#
726# Inputs: $@ - Message
727#
728# Outputs: Text output to screen
729#
730# Dependencies: echo
731#
732# Todo: logging
733#
734#*******************************************************************************
735log_warning_msg() {
736        echo -n -e "${BOOTMESG_PREFIX}${@}"
737        echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
738        return 0
739}
740
741# End $rc_base/init.d/functions
Note: See TracBrowser for help on using the repository browser.