source: bootscripts/lfs/init.d/functions @ 2676abb

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

Fixed LCD when it's not available.

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