source: bootscripts/lfs/init.d/functions @ c6e88663

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

Added: LCD Support to bootscripts

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