[BACK]Return to rc.subr CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / etc

Annotation of src/etc/rc.subr, Revision 1.88

1.88    ! apb         1: # $NetBSD: rc.subr,v 1.87 2011/06/09 14:52:01 christos Exp $
1.11      lukem       2: #
1.88    ! apb         3: # Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
1.11      lukem       4: # All rights reserved.
                      5: #
                      6: # This code is derived from software contributed to The NetBSD Foundation
                      7: # by Luke Mewburn.
                      8: #
                      9: # Redistribution and use in source and binary forms, with or without
                     10: # modification, are permitted provided that the following conditions
                     11: # are met:
                     12: # 1. Redistributions of source code must retain the above copyright
                     13: #    notice, this list of conditions and the following disclaimer.
                     14: # 2. Redistributions in binary form must reproduce the above copyright
                     15: #    notice, this list of conditions and the following disclaimer in the
                     16: #    documentation and/or other materials provided with the distribution.
                     17: #
                     18: # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     19: # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     20: # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     21: # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     22: # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     23: # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     24: # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     25: # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     26: # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     27: # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     28: # POSSIBILITY OF SUCH DAMAGE.
                     29: #
                     30: # rc.subr
                     31: #      functions used by various rc scripts
                     32: #
                     33:
1.62      jmmv       34: : ${rcvar_manpage:='rc.conf(5)'}
1.69      apb        35: : ${RC_PID:=$$} ; export RC_PID
1.78      apb        36: nl='
                     37: ' # a literal newline
1.62      jmmv       38:
1.11      lukem      39: #
                     40: #      functions
                     41: #      ---------
1.1       cjs        42:
1.5       lukem      43: #
1.11      lukem      44: # checkyesno var
1.5       lukem      45: #      Test $1 variable, and warn if not set to YES or NO.
1.11      lukem      46: #      Return 0 if it's "yes" (et al), nonzero otherwise.
1.5       lukem      47: #
1.11      lukem      48: checkyesno()
                     49: {
                     50:        eval _value=\$${1}
                     51:        case $_value in
1.4       lukem      52:
                     53:                #       "yes", "true", "on", or "1"
                     54:        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
                     55:                return 0
1.3       lukem      56:                ;;
1.4       lukem      57:
                     58:                #       "no", "false", "off", or "0"
                     59:        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
                     60:                return 1
1.3       lukem      61:                ;;
                     62:        *)
1.62      jmmv       63:                warn "\$${1} is not set properly - see ${rcvar_manpage}."
1.4       lukem      64:                return 1
1.3       lukem      65:                ;;
                     66:        esac
1.38      lukem      67: }
                     68:
1.65      lukem      69: #
1.78      apb        70: # yesno_to_truefalse var
                     71: #      Convert the value of a variable from any of the values
                     72: #      understood by checkyesno() to "true" or "false".
                     73: #
                     74: yesno_to_truefalse()
                     75: {
                     76:        local var=$1
                     77:        if checkyesno $var; then
                     78:                eval $var=true
                     79:                return 0
                     80:        else
                     81:                eval $var=false
                     82:                return 1
                     83:        fi
                     84: }
                     85:
                     86: #
1.38      lukem      87: # reverse_list list
                     88: #      print the list in reverse order
                     89: #
                     90: reverse_list()
                     91: {
                     92:        _revlist=
1.56      christos   93:        for _revfile; do
1.38      lukem      94:                _revlist="$_revfile $_revlist"
                     95:        done
                     96:        echo $_revlist
1.6       mellon     97: }
                     98:
                     99: #
1.69      apb       100: # If booting directly to multiuser, send SIGTERM to
                    101: # the parent (/etc/rc) to abort the boot.
                    102: # Otherwise just exit.
                    103: #
                    104: stop_boot()
                    105: {
                    106:        if [ "$autoboot" = yes ]; then
                    107:                echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
                    108:                kill -TERM ${RC_PID}
                    109:        fi
                    110:        exit 1
                    111: }
                    112:
                    113: #
1.47      lukem     114: # mount_critical_filesystems type
                    115: #      Go through the list of critical filesystems as provided in
                    116: #      the rc.conf(5) variable $critical_filesystems_${type}, checking
                    117: #      each one to see if it is mounted, and if it is not, mounting it.
1.79      apb       118: #      It's not an error if file systems prefixed with "OPTIONAL:"
                    119: #      are not mentioned in /etc/fstab.
1.6       mellon    120: #
1.11      lukem     121: mount_critical_filesystems()
                    122: {
1.47      lukem     123:        eval _fslist=\$critical_filesystems_${1}
1.79      apb       124:        _mountcrit_es=0
1.17      lukem     125:        for _fs in $_fslist; do
1.79      apb       126:                _optional=false
                    127:                case "$_fs" in
                    128:                OPTIONAL:*)
                    129:                        _optional=true
                    130:                        _fs="${_fs#*:}"
                    131:                        ;;
                    132:                esac
                    133:                _ismounted=false
                    134:                # look for a line like "${fs} on * type *"
                    135:                # or "* on ${fs} type *" in the output from mount.
                    136:                case "${nl}$( mount )${nl}" in
                    137:                *" on ${_fs} type "*)
                    138:                        _ismounted=true
                    139:                        ;;
                    140:                *"${nl}${_fs} on "*)
                    141:                        _ismounted=true
                    142:                        ;;
                    143:                esac
                    144:                if $_ismounted; then
                    145:                        print_rc_metadata \
                    146:                        "note:File system ${_fs} was already mounted"
                    147:                else
                    148:                        _mount_output=$( mount $_fs 2>&1 )
                    149:                        _mount_es=$?
                    150:                        case "$_mount_output" in
                    151:                        *"${nl}"*)
                    152:                                # multiple lines can't be good,
                    153:                                # not even if $_optional is true
                    154:                                ;;
                    155:                        *'unknown special file or file system'*)
                    156:                                if $_optional; then
                    157:                                        # ignore this error
                    158:                                        print_rc_metadata \
                    159:                        "note:Optional file system ${_fs} is not present"
                    160:                                        _mount_es=0
                    161:                                        _mount_output=""
1.6       mellon    162:                                fi
1.79      apb       163:                                ;;
                    164:                        esac
                    165:                        if [ -n "$_mount_output" ]; then
                    166:                                printf >&2 "%s\n" "$_mount_output"
                    167:                        fi
                    168:                        if [ "$_mount_es" != 0 ]; then
                    169:                                _mountcrit_es="$_mount_es"
1.6       mellon    170:                        fi
1.79      apb       171:                fi
1.6       mellon    172:        done
1.79      apb       173:        return $_mountcrit_es
1.7       cjs       174: }
                    175:
1.11      lukem     176: #
1.45      lukem     177: # check_pidfile pidfile procname [interpreter]
                    178: #      Parses the first line of pidfile for a PID, and ensures
1.11      lukem     179: #      that the process is running and matches procname.
1.45      lukem     180: #      Prints the matching PID upon success, nothing otherwise.
                    181: #      interpreter is optional; see _find_processes() for details.
1.11      lukem     182: #
                    183: check_pidfile()
                    184: {
                    185:        _pidfile=$1
                    186:        _procname=$2
1.45      lukem     187:        _interpreter=$3
1.11      lukem     188:        if [ -z "$_pidfile" -o -z "$_procname" ]; then
1.45      lukem     189:                err 3 'USAGE: check_pidfile pidfile procname [interpreter]'
1.11      lukem     190:        fi
                    191:        if [ ! -f $_pidfile ]; then
                    192:                return
                    193:        fi
                    194:        read _pid _junk < $_pidfile
                    195:        if [ -z "$_pid" ]; then
                    196:                return
                    197:        fi
1.45      lukem     198:        _find_processes $_procname ${_interpreter:-.} '-p '"$_pid"
1.11      lukem     199: }
                    200:
                    201: #
1.45      lukem     202: # check_process procname [interpreter]
1.11      lukem     203: #      Ensures that a process (or processes) named procname is running.
1.45      lukem     204: #      Prints a list of matching PIDs.
                    205: #      interpreter is optional; see _find_processes() for details.
1.11      lukem     206: #
                    207: check_process()
                    208: {
                    209:        _procname=$1
1.45      lukem     210:        _interpreter=$2
1.11      lukem     211:        if [ -z "$_procname" ]; then
1.45      lukem     212:                err 3 'USAGE: check_process procname [interpreter]'
                    213:        fi
                    214:        _find_processes $_procname ${_interpreter:-.} '-ax'
                    215: }
                    216:
1.46      lukem     217: #
1.45      lukem     218: # _find_processes procname interpreter psargs
                    219: #      Search for procname in the output of ps generated by psargs.
                    220: #      Prints the PIDs of any matching processes, space separated.
                    221: #
                    222: #      If interpreter == ".", check the following variations of procname
                    223: #      against the first word of each command:
                    224: #              procname
                    225: #              `basename procname`
                    226: #              `basename procname` + ":"
                    227: #              "(" + `basename procname` + ")"
                    228: #
                    229: #      If interpreter != ".", read the first line of procname, remove the
                    230: #      leading #!, normalise whitespace, append procname, and attempt to
                    231: #      match that against each command, either as is, or with extra words
1.73      dholland  232: #      at the end.  As an alternative, to deal with interpreted daemons
1.66      he        233: #      using perl, the basename of the interpreter plus a colon is also
                    234: #      tried as the prefix to procname.
1.45      lukem     235: #
                    236: _find_processes()
                    237: {
                    238:        if [ $# -ne 3 ]; then
                    239:                err 3 'USAGE: _find_processes procname interpreter psargs'
1.11      lukem     240:        fi
1.45      lukem     241:        _procname=$1
                    242:        _interpreter=$2
                    243:        _psargs=$3
                    244:
1.11      lukem     245:        _pref=
1.68      hubertf   246:        _procnamebn=${_procname##*/}
1.45      lukem     247:        if [ $_interpreter != "." ]; then       # an interpreted script
1.67      elad      248:                read _interp < ${_chroot:-}/$_procname  # read interpreter name
1.45      lukem     249:                _interp=${_interp#\#!}          # strip #!
                    250:                set -- $_interp
1.87      christos  251:                if [ $1 = "/usr/bin/env" ]; then
                    252:                        shift
                    253:                        set -- $(type $1)
                    254:                        shift $(($# - 1))
                    255:                        _interp="${1##*/} $_procname"
                    256:                else
                    257:                        _interp="$* $_procname"
                    258:                fi
1.45      lukem     259:                if [ $_interpreter != $1 ]; then
                    260:                        warn "\$command_interpreter $_interpreter != $1"
                    261:                fi
1.66      he        262:                _interpbn=${1##*/}
1.45      lukem     263:                _fp_args='_argv'
                    264:                _fp_match='case "$_argv" in
1.68      hubertf   265:                    ${_interp}|"${_interp} "*|"${_interpbn}: "*${_procnamebn}*)'
1.45      lukem     266:        else                                    # a normal daemon
                    267:                _fp_args='_arg0 _argv'
                    268:                _fp_match='case "$_arg0" in
                    269:                    $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})")'
                    270:        fi
                    271:
                    272:        _proccheck='
1.46      lukem     273:                ps -o "pid,command" '"$_psargs"' |
1.45      lukem     274:                while read _npid '"$_fp_args"'; do
                    275:                        case "$_npid" in
                    276:                            PID)
                    277:                                continue ;;
                    278:                        esac ; '"$_fp_match"'
                    279:                                echo -n "$_pref$_npid" ;
                    280:                                _pref=" "
                    281:                                ;;
                    282:                        esac
                    283:                done'
                    284:
                    285: #echo 1>&2 "proccheck is :$_proccheck:"
                    286:        eval $_proccheck
1.11      lukem     287: }
                    288:
                    289: #
1.33      lukem     290: # wait_for_pids pid [pid ...]
1.35      lukem     291: #      spins until none of the pids exist
1.33      lukem     292: #
                    293: wait_for_pids()
                    294: {
1.56      christos  295:        _list="$@"
1.33      lukem     296:        if [ -z "$_list" ]; then
                    297:                return
                    298:        fi
1.35      lukem     299:        _prefix=
                    300:        while true; do
1.33      lukem     301:                _nlist="";
                    302:                for _j in $_list; do
                    303:                        if kill -0 $_j 2>/dev/null; then
                    304:                                _nlist="${_nlist}${_nlist:+ }$_j"
                    305:                        fi
                    306:                done
                    307:                if [ -z "$_nlist" ]; then
                    308:                        break
                    309:                fi
                    310:                _list=$_nlist
1.35      lukem     311:                echo -n ${_prefix:-"Waiting for PIDS: "}$_list
                    312:                _prefix=", "
                    313:                sleep 2
1.33      lukem     314:        done
1.35      lukem     315:        if [ -n "$_prefix" ]; then
                    316:                echo "."
                    317:        fi
1.33      lukem     318: }
                    319:
                    320: #
1.81      jmmv      321: # run_rc_command argument [parameters]
1.46      lukem     322: #      Search for argument in the list of supported commands, which is:
1.33      lukem     323: #              "start stop restart rcvar status poll ${extra_commands}"
1.46      lukem     324: #      If there's a match, run ${argument}_cmd or the default method
1.81      jmmv      325: #      (see below), and pass the optional list of parameters to it.
1.11      lukem     326: #
1.46      lukem     327: #      If argument has a given prefix, then change the operation as follows:
                    328: #              Prefix  Operation
1.11      lukem     329: #              ------  ---------
1.48      lukem     330: #              fast    Skip the pid check, and set rc_fast=yes
                    331: #              force   Set ${rcvar} to YES, and set rc_force=yes
1.61      lukem     332: #              one     Set ${rcvar} to YES
1.11      lukem     333: #
                    334: #      The following globals are used:
1.24      lukem     335: #
1.46      lukem     336: #      Name            Needed  Purpose
                    337: #      ----            ------  -------
1.11      lukem     338: #      name            y       Name of script.
1.24      lukem     339: #
1.11      lukem     340: #      command         n       Full path to command.
1.46      lukem     341: #                              Not needed if ${rc_arg}_cmd is set for
1.11      lukem     342: #                              each keyword.
1.24      lukem     343: #
1.11      lukem     344: #      command_args    n       Optional args/shell directives for command.
1.24      lukem     345: #
1.45      lukem     346: #      command_interpreter n   If not empty, command is interpreted, so
                    347: #                              call check_{pidfile,process}() appropriately.
                    348: #
1.16      lukem     349: #      extra_commands  n       List of extra commands supported.
1.24      lukem     350: #
1.42      lukem     351: #      pidfile         n       If set, use check_pidfile $pidfile $command,
                    352: #                              otherwise use check_process $command.
                    353: #                              In either case, only check if $command is set.
                    354: #
                    355: #      procname        n       Process name to check for instead of $command.
1.24      lukem     356: #
                    357: #      rcvar           n       This is checked with checkyesno to determine
                    358: #                              if the action should be run.
                    359: #
1.22      lukem     360: #      ${name}_chroot  n       Directory to chroot to before running ${command}
1.42      lukem     361: #                              Requires /usr to be mounted.
1.24      lukem     362: #
1.22      lukem     363: #      ${name}_chdir   n       Directory to cd to before running ${command}
                    364: #                              (if not using ${name}_chroot).
1.24      lukem     365: #
1.11      lukem     366: #      ${name}_flags   n       Arguments to call ${command} with.
1.24      lukem     367: #                              NOTE:   $flags from the parent environment
                    368: #                                      can be used to override this.
                    369: #
1.72      he        370: #      ${name}_env     n       Additional environment variable settings
                    371: #                              for running ${command}
                    372: #
1.23      lukem     373: #      ${name}_nice    n       Nice level to run ${command} at.
1.24      lukem     374: #
1.22      lukem     375: #      ${name}_user    n       User to run ${command} as, using su(1) if not
                    376: #                              using ${name}_chroot.
1.42      lukem     377: #                              Requires /usr to be mounted.
1.24      lukem     378: #
1.22      lukem     379: #      ${name}_group   n       Group to run chrooted ${command} as.
1.42      lukem     380: #                              Requires /usr to be mounted.
1.24      lukem     381: #
1.32      lukem     382: #      ${name}_groups  n       Comma separated list of supplementary groups
                    383: #                              to run the chrooted ${command} with.
1.42      lukem     384: #                              Requires /usr to be mounted.
1.24      lukem     385: #
1.46      lukem     386: #      ${rc_arg}_cmd   n       If set, use this as the method when invoked;
1.11      lukem     387: #                              Otherwise, use default command (see below)
1.24      lukem     388: #
1.46      lukem     389: #      ${rc_arg}_precmd n      If set, run just before performing the
                    390: #                              ${rc_arg}_cmd method in the default
                    391: #                              operation (i.e, after checking for required
                    392: #                              bits and process (non)existence).
1.11      lukem     393: #                              If this completes with a non-zero exit code,
1.46      lukem     394: #                              don't run ${rc_arg}_cmd.
1.24      lukem     395: #
1.46      lukem     396: #      ${rc_arg}_postcmd n     If set, run just after performing the
                    397: #                              ${rc_arg}_cmd method, if that method
1.43      lukem     398: #                              returned a zero exit code.
                    399: #
1.11      lukem     400: #      required_dirs   n       If set, check for the existence of the given
                    401: #                              directories before running the default
                    402: #                              (re)start command.
1.24      lukem     403: #
1.11      lukem     404: #      required_files  n       If set, check for the readability of the given
                    405: #                              files before running the default (re)start
                    406: #                              command.
1.24      lukem     407: #
1.11      lukem     408: #      required_vars   n       If set, perform checkyesno on each of the
                    409: #                              listed variables before running the default
                    410: #                              (re)start command.
                    411: #
1.46      lukem     412: #      Default behaviour for a given argument, if no override method is
                    413: #      provided:
1.24      lukem     414: #
1.46      lukem     415: #      Argument        Default behaviour
                    416: #      --------        -----------------
1.11      lukem     417: #      start           if !running && checkyesno ${rcvar}
                    418: #                              ${command}
1.24      lukem     419: #
1.11      lukem     420: #      stop            if ${pidfile}
1.46      lukem     421: #                              rc_pid=$(check_pidfile $pidfile $command)
1.11      lukem     422: #                      else
1.46      lukem     423: #                              rc_pid=$(check_process $command)
                    424: #                      kill $sig_stop $rc_pid
                    425: #                      wait_for_pids $rc_pid
1.35      lukem     426: #                      ($sig_stop defaults to TERM.)
1.24      lukem     427: #
1.35      lukem     428: #      reload          Similar to stop, except use $sig_reload instead,
                    429: #                      and doesn't wait_for_pids.
1.11      lukem     430: #                      $sig_reload defaults to HUP.
1.24      lukem     431: #
1.11      lukem     432: #      restart         Run `stop' then `start'.
                    433: #
1.33      lukem     434: #      status          Show if ${command} is running, etc.
                    435: #
                    436: #      poll            Wait for ${command} to exit.
                    437: #
                    438: #      rcvar           Display what rc.conf variable is used (if any).
                    439: #
1.46      lukem     440: #      Variables available to methods, and after run_rc_command() has
                    441: #      completed:
                    442: #
                    443: #      Variable        Purpose
                    444: #      --------        -------
1.61      lukem     445: #      rc_arg          Argument to command, after fast/force/one processing
1.46      lukem     446: #                      performed
                    447: #
                    448: #      rc_flags        Flags to start the default command with.
                    449: #                      Defaults to ${name}_flags, unless overridden
                    450: #                      by $flags from the environment.
                    451: #                      This variable may be changed by the precmd method.
                    452: #
                    453: #      rc_pid          PID of command (if appropriate)
                    454: #
                    455: #      rc_fast         Not empty if "fast" was provided (q.v.)
                    456: #
                    457: #      rc_force        Not empty if "force" was provided (q.v.)
1.33      lukem     458: #
1.24      lukem     459: #
1.11      lukem     460: run_rc_command()
                    461: {
1.46      lukem     462:        rc_arg=$1
1.24      lukem     463:        if [ -z "$name" ]; then
1.30      lukem     464:                err 3 'run_rc_command: $name is not set.'
1.11      lukem     465:        fi
                    466:
1.61      lukem     467:        _rc_prefix=
1.46      lukem     468:        case "$rc_arg" in
1.24      lukem     469:        fast*)                          # "fast" prefix; don't check pid
1.46      lukem     470:                rc_arg=${rc_arg#fast}
1.48      lukem     471:                rc_fast=yes
1.11      lukem     472:                ;;
1.61      lukem     473:        force*)                         # "force" prefix; always run
1.48      lukem     474:                rc_force=yes
1.61      lukem     475:                _rc_prefix=force
                    476:                rc_arg=${rc_arg#${_rc_prefix}}
                    477:                if [ -n "${rcvar}" ]; then
                    478:                        eval ${rcvar}=YES
                    479:                fi
                    480:                ;;
                    481:        one*)                           # "one" prefix; set ${rcvar}=yes
                    482:                _rc_prefix=one
                    483:                rc_arg=${rc_arg#${_rc_prefix}}
1.29      lukem     484:                if [ -n "${rcvar}" ]; then
                    485:                        eval ${rcvar}=YES
                    486:                fi
1.11      lukem     487:                ;;
                    488:        esac
                    489:
1.75      reed      490:        _keywords="start stop restart rcvar"
                    491:        if [ -n "$extra_commands" ]; then
                    492:                _keywords="${_keywords} ${extra_commands}"
                    493:        fi
1.46      lukem     494:        rc_pid=
1.11      lukem     495:        _pidcmd=
1.42      lukem     496:        _procname=${procname:-${command}}
                    497:
1.24      lukem     498:                                        # setup pid check command if not fast
1.46      lukem     499:        if [ -z "$rc_fast" -a -n "$_procname" ]; then
1.11      lukem     500:                if [ -n "$pidfile" ]; then
1.46      lukem     501:                        _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')'
1.42      lukem     502:                else
1.46      lukem     503:                        _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')'
1.11      lukem     504:                fi
                    505:                if [ -n "$_pidcmd" ]; then
1.33      lukem     506:                        _keywords="${_keywords} status poll"
1.11      lukem     507:                fi
                    508:        fi
                    509:
1.46      lukem     510:        if [ -z "$rc_arg" ]; then
1.11      lukem     511:                rc_usage "$_keywords"
                    512:        fi
1.81      jmmv      513:        shift   # remove $rc_arg from the positional parameters
1.11      lukem     514:
1.17      lukem     515:        if [ -n "$flags" ]; then        # allow override from environment
1.46      lukem     516:                rc_flags=$flags
1.11      lukem     517:        else
1.46      lukem     518:                eval rc_flags=\$${name}_flags
1.11      lukem     519:        fi
1.30      lukem     520:        eval _chdir=\$${name}_chdir     _chroot=\$${name}_chroot \
                    521:            _nice=\$${name}_nice        _user=\$${name}_user \
1.72      he        522:            _group=\$${name}_group      _groups=\$${name}_groups \
                    523:            _env=\"\$${name}_env\"
1.11      lukem     524:
1.42      lukem     525:        if [ -n "$_user" ]; then        # unset $_user if running as that user
                    526:                if [ "$_user" = "$(id -un)" ]; then
                    527:                        unset _user
                    528:                fi
                    529:        fi
                    530:
1.29      lukem     531:                                        # if ${rcvar} is set, and $1 is not
1.40      lukem     532:                                        # "rcvar", then run
1.29      lukem     533:                                        #       checkyesno ${rcvar}
1.74      salo      534:                                        # and return if that failed or warn
                    535:                                        # user and exit when interactive
1.24      lukem     536:                                        #
1.46      lukem     537:        if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then
1.24      lukem     538:                if ! checkyesno ${rcvar}; then
1.74      salo      539:                                        # check whether interactive or not
                    540:                        if [ -n "$_run_rc_script" ]; then
                    541:                                return 0
                    542:                        fi
                    543:                        for _elem in $_keywords; do
                    544:                                if [ "$_elem" = "$rc_arg" ]; then
1.88    ! apb       545:                                        cat 1>&2 <<EOF
        !           546: \$${rcvar} is not enabled - see ${rcvar_manpage}.
        !           547: Use the following if you wish to perform the operation:
        !           548:   $0 one${rc_arg}
        !           549: EOF
1.74      salo      550:                                        exit 1
                    551:                                fi
                    552:                        done
                    553:                        echo 1>&2 "$0: unknown directive '$rc_arg'."
                    554:                        rc_usage "$_keywords"
1.24      lukem     555:                fi
                    556:        fi
                    557:
                    558:        eval $_pidcmd                   # determine the pid if necessary
1.11      lukem     559:
                    560:        for _elem in $_keywords; do
1.46      lukem     561:                if [ "$_elem" != "$rc_arg" ]; then
1.11      lukem     562:                        continue
                    563:                fi
                    564:
1.24      lukem     565:                                        # if there's a custom ${XXX_cmd},
                    566:                                        # run that instead of the default
                    567:                                        #
1.46      lukem     568:                eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \
                    569:                    _postcmd=\$${rc_arg}_postcmd
1.11      lukem     570:                if [ -n "$_cmd" ]; then
1.24      lukem     571:                                        # if the precmd failed and force
                    572:                                        # isn't set, exit
                    573:                                        #
1.46      lukem     574:                        if ! eval $_precmd && [ -z "$rc_force" ]; then
1.24      lukem     575:                                return 1
                    576:                        fi
                    577:
1.81      jmmv      578:                        if ! eval $_cmd \"\${@}\" && [ -z "$rc_force" ]; then
1.44      lukem     579:                                return 1
                    580:                        fi
                    581:                        eval $_postcmd
1.11      lukem     582:                        return 0
                    583:                fi
                    584:
1.81      jmmv      585:                if [ ${#} -gt 0 ]; then
                    586:                        err 1 "the $rc_arg command does not take any parameters"
                    587:                fi
                    588:
1.46      lukem     589:                case "$rc_arg" in       # default operations...
1.11      lukem     590:
                    591:                status)
1.46      lukem     592:                        if [ -n "$rc_pid" ]; then
                    593:                                echo "${name} is running as pid $rc_pid."
1.11      lukem     594:                        else
                    595:                                echo "${name} is not running."
1.28      lukem     596:                                return 1
1.11      lukem     597:                        fi
                    598:                        ;;
                    599:
                    600:                start)
1.46      lukem     601:                        if [ -n "$rc_pid" ]; then
1.63      lukem     602:                                echo 1>&2 "${name} already running? (pid=$rc_pid)."
1.11      lukem     603:                                exit 1
                    604:                        fi
                    605:
1.57      lukem     606:                        if [ ! -x ${_chroot}${command} ]; then
1.11      lukem     607:                                return 0
                    608:                        fi
                    609:
1.24      lukem     610:                                        # check for required variables,
                    611:                                        # directories, and files
                    612:                                        #
1.11      lukem     613:                        for _f in $required_vars; do
                    614:                                if ! checkyesno $_f; then
1.65      lukem     615:                                        warn "\$${_f} is not enabled."
1.46      lukem     616:                                        if [ -z "$rc_force" ]; then
1.24      lukem     617:                                                return 1
                    618:                                        fi
1.11      lukem     619:                                fi
                    620:                        done
                    621:                        for _f in $required_dirs; do
                    622:                                if [ ! -d "${_f}/." ]; then
1.25      lukem     623:                                        warn "${_f} is not a directory."
1.46      lukem     624:                                        if [ -z "$rc_force" ]; then
1.24      lukem     625:                                                return 1
                    626:                                        fi
1.11      lukem     627:                                fi
                    628:                        done
                    629:                        for _f in $required_files; do
                    630:                                if [ ! -r "${_f}" ]; then
1.25      lukem     631:                                        warn "${_f} is not readable."
1.46      lukem     632:                                        if [ -z "$rc_force" ]; then
1.24      lukem     633:                                                return 1
                    634:                                        fi
1.11      lukem     635:                                fi
                    636:                        done
                    637:
1.24      lukem     638:                                        # if the precmd failed and force
                    639:                                        # isn't set, exit
                    640:                                        #
1.46      lukem     641:                        if ! eval $_precmd && [ -z "$rc_force" ]; then
1.24      lukem     642:                                return 1
                    643:                        fi
                    644:
                    645:                                        # setup the command to run, and run it
1.29      lukem     646:                                        #
1.11      lukem     647:                        echo "Starting ${name}."
1.22      lukem     648:                        if [ -n "$_chroot" ]; then
                    649:                                _doit="\
1.72      he        650: ${_env:+env $_env }\
1.23      lukem     651: ${_nice:+nice -n $_nice }\
1.22      lukem     652: chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\
1.46      lukem     653: $_chroot $command $rc_flags $command_args"
1.22      lukem     654:                        else
                    655:                                _doit="\
1.18      lukem     656: ${_chdir:+cd $_chdir; }\
1.72      he        657: ${_env:+env $_env }\
1.18      lukem     658: ${_nice:+nice -n $_nice }\
1.46      lukem     659: $command $rc_flags $command_args"
1.34      lukem     660:                                if [ -n "$_user" ]; then
                    661:                                    _doit="su -m $_user -c 'sh -c \"$_doit\"'"
                    662:                                fi
1.22      lukem     663:                        fi
1.43      lukem     664:
                    665:                                        # if the cmd failed and force
                    666:                                        # isn't set, exit
                    667:                                        #
1.46      lukem     668:                        if ! eval $_doit && [ -z "$rc_force" ]; then
1.43      lukem     669:                                return 1
                    670:                        fi
                    671:
                    672:                                        # finally, run postcmd
                    673:                                        #
                    674:                        eval $_postcmd
1.11      lukem     675:                        ;;
                    676:
                    677:                stop)
1.46      lukem     678:                        if [ -z "$rc_pid" ]; then
1.24      lukem     679:                                if [ -n "$pidfile" ]; then
1.63      lukem     680:                                        echo 1>&2 \
1.24      lukem     681:                                    "${name} not running? (check $pidfile)."
                    682:                                else
1.63      lukem     683:                                        echo 1>&2 "${name} not running?"
1.11      lukem     684:                                fi
1.24      lukem     685:                                exit 1
1.11      lukem     686:                        fi
                    687:
1.43      lukem     688:                                        # if the precmd failed and force
                    689:                                        # isn't set, exit
                    690:                                        #
1.46      lukem     691:                        if ! eval $_precmd && [ -z "$rc_force" ]; then
1.24      lukem     692:                                return 1
                    693:                        fi
1.43      lukem     694:
                    695:                                        # send the signal to stop
                    696:                                        #
1.11      lukem     697:                        echo "Stopping ${name}."
1.46      lukem     698:                        _doit="kill -${sig_stop:-TERM} $rc_pid"
1.34      lukem     699:                        if [ -n "$_user" ]; then
                    700:                                _doit="su -m $_user -c 'sh -c \"$_doit\"'"
                    701:                        fi
1.43      lukem     702:
                    703:                                        # if the stop cmd failed and force
                    704:                                        # isn't set, exit
                    705:                                        #
1.46      lukem     706:                        if ! eval $_doit && [ -z "$rc_force" ]; then
1.43      lukem     707:                                return 1
                    708:                        fi
                    709:
                    710:                                        # wait for the command to exit,
                    711:                                        # and run postcmd.
1.46      lukem     712:                        wait_for_pids $rc_pid
1.43      lukem     713:                        eval $_postcmd
1.11      lukem     714:                        ;;
                    715:
                    716:                reload)
1.46      lukem     717:                        if [ -z "$rc_pid" ]; then
1.24      lukem     718:                                if [ -n "$pidfile" ]; then
1.63      lukem     719:                                        echo 1>&2 \
1.11      lukem     720:                                    "${name} not running? (check $pidfile)."
1.24      lukem     721:                                else
1.63      lukem     722:                                        echo 1>&2 "${name} not running?"
1.11      lukem     723:                                fi
1.24      lukem     724:                                exit 1
1.11      lukem     725:                        fi
                    726:                        echo "Reloading ${name} config files."
1.46      lukem     727:                        if ! eval $_precmd && [ -z "$rc_force" ]; then
1.24      lukem     728:                                return 1
                    729:                        fi
1.46      lukem     730:                        _doit="kill -${sig_reload:-HUP} $rc_pid"
1.34      lukem     731:                        if [ -n "$_user" ]; then
                    732:                                _doit="su -m $_user -c 'sh -c \"$_doit\"'"
                    733:                        fi
1.46      lukem     734:                        if ! eval $_doit && [ -z "$rc_force" ]; then
1.43      lukem     735:                                return 1
                    736:                        fi
                    737:                        eval $_postcmd
1.11      lukem     738:                        ;;
                    739:
                    740:                restart)
1.46      lukem     741:                        if ! eval $_precmd && [ -z "$rc_force" ]; then
1.24      lukem     742:                                return 1
1.11      lukem     743:                        fi
1.29      lukem     744:                                        # prevent restart being called more
                    745:                                        # than once by any given script
                    746:                                        #
1.53      lukem     747:                        if ${_rc_restart_done:-false}; then
1.29      lukem     748:                                return 0
                    749:                        fi
1.53      lukem     750:                        _rc_restart_done=true
1.33      lukem     751:
1.61      lukem     752:                        ( $0 ${_rc_prefix}stop )
                    753:                        $0 ${_rc_prefix}start
1.11      lukem     754:
1.43      lukem     755:                        eval $_postcmd
1.33      lukem     756:                        ;;
                    757:
                    758:                poll)
1.46      lukem     759:                        if [ -n "$rc_pid" ]; then
                    760:                                wait_for_pids $rc_pid
1.33      lukem     761:                        fi
1.11      lukem     762:                        ;;
                    763:
                    764:                rcvar)
                    765:                        echo "# $name"
1.24      lukem     766:                        if [ -n "$rcvar" ]; then
                    767:                                if checkyesno ${rcvar}; then
                    768:                                        echo "\$${rcvar}=YES"
                    769:                                else
                    770:                                        echo "\$${rcvar}=NO"
                    771:                                fi
1.11      lukem     772:                        fi
                    773:                        ;;
                    774:
                    775:                *)
                    776:                        rc_usage "$_keywords"
                    777:                        ;;
                    778:
                    779:                esac
                    780:                return 0
                    781:        done
                    782:
1.46      lukem     783:        echo 1>&2 "$0: unknown directive '$rc_arg'."
1.11      lukem     784:        rc_usage "$_keywords"
                    785:        exit 1
                    786: }
                    787:
                    788: #
                    789: # run_rc_script file arg
                    790: #      Start the script `file' with `arg', and correctly handle the
1.17      lukem     791: #      return value from the script.  If `file' ends with `.sh', it's
1.37      lukem     792: #      sourced into the current environment.  If `file' appears to be
                    793: #      a backup or scratch file, ignore it.  Otherwise if it's
                    794: #      executable run as a child process.
1.17      lukem     795: #
1.78      apb       796: #      If `file' contains "KEYWORD: interactive" and if we are
                    797: #      running inside /etc/rc with postprocessing (as signified by
                    798: #      _rc_postprocessor_fd being defined) then the script's stdout
                    799: #      and stderr are redirected to $_rc_original_stdout_fd and
                    800: #      $_rc_original_stderr_fd, so the output will be displayed on the
                    801: #      console but not intercepted by /etc/rc's postprocessor.
                    802: #
1.11      lukem     803: run_rc_script()
                    804: {
                    805:        _file=$1
                    806:        _arg=$2
                    807:        if [ -z "$_file" -o -z "$_arg" ]; then
                    808:                err 3 'USAGE: run_rc_script file arg'
                    809:        fi
                    810:
1.74      salo      811:        _run_rc_script=true
                    812:
1.45      lukem     813:        unset   name command command_args command_interpreter \
                    814:                extra_commands pidfile procname \
1.42      lukem     815:                rcvar required_dirs required_files required_vars
1.43      lukem     816:        eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd
1.39      lukem     817:
1.78      apb       818:        _must_redirect=false
1.80      apb       819:        if [ -n "${_rc_postprocessor_fd}" ] \
1.78      apb       820:            && _has_rcorder_keyword interactive $_file
                    821:        then
                    822:                _must_redirect=true
                    823:        fi
                    824:
1.39      lukem     825:        case "$_file" in
                    826:        *.sh)                           # run in current shell
1.78      apb       827:                if $_must_redirect; then
                    828:                        print_rc_metadata \
                    829:                            "note:Output from ${_file} is not logged"
1.80      apb       830:                        no_rc_postprocess eval \
                    831:                            'set $_arg ; . $_file'
1.78      apb       832:                else
                    833:                        set $_arg ; . $_file
                    834:                fi
1.39      lukem     835:                ;;
1.60      lukem     836:        *[~#]|*.OLD|*.orig|*,v)         # scratch file; skip
1.39      lukem     837:                warn "Ignoring scratch file $_file"
                    838:                ;;
                    839:        *)                              # run in subshell
1.78      apb       840:                if [ -x $_file ] && $_must_redirect; then
                    841:                        print_rc_metadata \
                    842:                            "note:Output from ${_file} is not logged"
                    843:                        if [ -n "$rc_fast_and_loose" ]; then
1.80      apb       844:                                no_rc_postprocess eval \
                    845:                                    'set $_arg ; . $_file'
1.78      apb       846:                        else
1.80      apb       847:                                no_rc_postprocess eval \
                    848:                                    '( set $_arg ; . $_file )'
1.78      apb       849:                        fi
                    850:                elif [ -x $_file ]; then
1.39      lukem     851:                        if [ -n "$rc_fast_and_loose" ]; then
                    852:                                set $_arg ; . $_file
                    853:                        else
1.37      lukem     854:                                ( set $_arg ; . $_file )
                    855:                        fi
1.78      apb       856:                else
                    857:                        warn "Ignoring non-executable file $_file"
1.39      lukem     858:                fi
                    859:                ;;
                    860:        esac
1.11      lukem     861: }
1.19      lukem     862:
                    863: #
1.65      lukem     864: # load_rc_config command
1.19      lukem     865: #      Source in the configuration file for a given command.
                    866: #
                    867: load_rc_config()
                    868: {
                    869:        _command=$1
                    870:        if [ -z "$_command" ]; then
                    871:                err 3 'USAGE: load_rc_config command'
                    872:        fi
                    873:
1.54      lukem     874:        if ${_rc_conf_loaded:-false}; then
                    875:                :
                    876:        else
1.30      lukem     877:                . /etc/rc.conf
1.53      lukem     878:                _rc_conf_loaded=true
1.30      lukem     879:        fi
1.20      fvdl      880:        if [ -f /etc/rc.conf.d/"$_command" ]; then
                    881:                . /etc/rc.conf.d/"$_command"
                    882:        fi
1.19      lukem     883: }
                    884:
1.65      lukem     885: #
                    886: # load_rc_config_var cmd var
                    887: #      Read the rc.conf(5) var for cmd and set in the
                    888: #      current shell, using load_rc_config in a subshell to prevent
                    889: #      unwanted side effects from other variable assignments.
                    890: #
                    891: load_rc_config_var()
                    892: {
                    893:        if [ $# -ne 2 ]; then
                    894:                err 3 'USAGE: load_rc_config_var cmd var'
                    895:        fi
                    896:        eval $(eval '(
                    897:                load_rc_config '$1' >/dev/null;
1.77      apb       898:                if [ -n "${'$2'}" -o "${'$2'-UNSET}" != "UNSET" ]; then
1.65      lukem     899:                        echo '$2'=\'\''${'$2'}\'\'';
                    900:                fi
                    901:        )' )
                    902: }
1.11      lukem     903:
                    904: #
                    905: # rc_usage commands
                    906: #      Print a usage string for $0, with `commands' being a list of
                    907: #      valid commands.
                    908: #
                    909: rc_usage()
                    910: {
1.61      lukem     911:        echo -n 1>&2 "Usage: $0 [fast|force|one]("
1.11      lukem     912:
                    913:        _sep=
1.56      christos  914:        for _elem; do
1.11      lukem     915:                echo -n 1>&2 "$_sep$_elem"
                    916:                _sep="|"
                    917:        done
                    918:        echo 1>&2 ")"
                    919:        exit 1
                    920: }
                    921:
                    922: #
                    923: # err exitval message
                    924: #      Display message to stderr and log to the syslog, and exit with exitval.
                    925: #
                    926: err()
                    927: {
                    928:        exitval=$1
                    929:        shift
                    930:
1.51      grant     931:        if [ -x /usr/bin/logger ]; then
                    932:                logger "$0: ERROR: $*"
                    933:        fi
1.21      lukem     934:        echo 1>&2 "$0: ERROR: $*"
1.11      lukem     935:        exit $exitval
                    936: }
                    937:
                    938: #
                    939: # warn message
                    940: #      Display message to stderr and log to the syslog.
                    941: #
                    942: warn()
                    943: {
1.51      grant     944:        if [ -x /usr/bin/logger ]; then
                    945:                logger "$0: WARNING: $*"
                    946:        fi
1.21      lukem     947:        echo 1>&2 "$0: WARNING: $*"
1.31      atatat    948: }
                    949:
                    950: #
                    951: # backup_file action file cur backup
                    952: #      Make a backup copy of `file' into `cur', and save the previous
                    953: #      version of `cur' as `backup' or use rcs for archiving.
                    954: #
                    955: #      This routine checks the value of the backup_uses_rcs variable,
                    956: #      which can be either YES or NO.
                    957: #
                    958: #      The `action' keyword can be one of the following:
                    959: #
                    960: #      add             `file' is now being backed up (and is possibly
                    961: #                      being reentered into the backups system).  `cur'
                    962: #                      is created and RCS files, if necessary, are
                    963: #                      created as well.
                    964: #
                    965: #      update          `file' has changed and needs to be backed up.
                    966: #                      If `cur' exists, it is copied to to `back' or
                    967: #                      checked into RCS (if the repository file is old),
                    968: #                      and then `file' is copied to `cur'.  Another RCS
                    969: #                      check in done here if RCS is being used.
                    970: #
                    971: #      remove          `file' is no longer being tracked by the backups
                    972: #                      system.  If RCS is not being used, `cur' is moved
                    973: #                      to `back', otherwise an empty file is checked in,
                    974: #                      and then `cur' is removed.
                    975: #
                    976: #
                    977: backup_file()
                    978: {
                    979:        _action=$1
                    980:        _file=$2
                    981:        _cur=$3
                    982:        _back=$4
                    983:
                    984:        if checkyesno backup_uses_rcs; then
                    985:                _msg0="backup archive"
                    986:                _msg1="update"
                    987:
1.36      atatat    988:                # ensure that history file is not locked
                    989:                if [ -f $_cur,v ]; then
                    990:                        rcs -q -u -U -M $_cur
                    991:                fi
                    992:
1.31      atatat    993:                # ensure after switching to rcs that the
                    994:                # current backup is not lost
                    995:                if [ -f $_cur ]; then
                    996:                        # no archive, or current newer than archive
                    997:                        if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then
1.36      atatat    998:                                ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
                    999:                                rcs -q -kb -U $_cur
1.49      lukem    1000:                                co -q -f -u $_cur
1.31      atatat   1001:                        fi
                   1002:                fi
                   1003:
                   1004:                case $_action in
                   1005:                add|update)
                   1006:                        cp -p $_file $_cur
1.36      atatat   1007:                        ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
                   1008:                        rcs -q -kb -U $_cur
1.49      lukem    1009:                        co -q -f -u $_cur
1.31      atatat   1010:                        chown root:wheel $_cur $_cur,v
                   1011:                        ;;
                   1012:                remove)
                   1013:                        cp /dev/null $_cur
1.36      atatat   1014:                        ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
                   1015:                        rcs -q -kb -U $_cur
1.31      atatat   1016:                        chown root:wheel $_cur $_cur,v
                   1017:                        rm $_cur
                   1018:                        ;;
                   1019:                esac
                   1020:        else
                   1021:                case $_action in
                   1022:                add|update)
                   1023:                        if [ -f $_cur ]; then
                   1024:                                cp -p $_cur $_back
                   1025:                        fi
                   1026:                        cp -p $_file $_cur
                   1027:                        chown root:wheel $_cur
                   1028:                        ;;
                   1029:                remove)
                   1030:                        mv -f $_cur $_back
                   1031:                        ;;
                   1032:                esac
                   1033:        fi
1.1       cjs      1034: }
1.64      mycroft  1035:
1.76      christos 1036: #
                   1037: # handle_fsck_error fsck_exit_code
                   1038: #      Take action depending on the return code from fsck.
                   1039: #
                   1040: handle_fsck_error()
                   1041: {
                   1042:        case $1 in
                   1043:        0)      # OK
                   1044:                return
                   1045:                ;;
                   1046:        2)      # Needs re-run, still fs errors
                   1047:                echo "File system still has errors; re-run fsck manually!"
                   1048:                ;;
                   1049:        4)      # Root modified
                   1050:                echo "Root filesystem was modified, rebooting ..."
                   1051:                reboot -n
                   1052:                echo "Reboot failed; help!"
                   1053:                ;;
                   1054:        8)      # Check failed
                   1055:                echo "Automatic file system check failed; help!"
                   1056:                ;;
                   1057:        12)     # Got signal
                   1058:                echo "Boot interrupted."
                   1059:                ;;
                   1060:        *)
                   1061:                echo "Unknown error $1; help!"
                   1062:                ;;
                   1063:        esac
                   1064:        stop_boot
                   1065: }
                   1066:
1.78      apb      1067: #
                   1068: # _has_rcorder_keyword word file
                   1069: #      Check whether a file contains a "# KEYWORD:" comment with a
                   1070: #      specified keyword in the style used by rcorder(8).
                   1071: #
                   1072: _has_rcorder_keyword()
                   1073: {
                   1074:        local word="$1"
                   1075:        local file="$2"
                   1076:        local line
                   1077:
                   1078:        [ -r "$file" ] || return 1
                   1079:        while read line; do
                   1080:                case "${line} " in
                   1081:                "# KEYWORD:"*[\ \       ]"${word}"[\ \  ]*)
                   1082:                        return 0
                   1083:                        ;;
                   1084:                "#"*)
                   1085:                        continue
                   1086:                        ;;
                   1087:                *[A-Za-z0-9]*)
                   1088:                        # give up at the first non-empty non-comment line
                   1089:                        return 1
                   1090:                        ;;
                   1091:                esac
                   1092:        done <"$file"
                   1093:        return 1
                   1094: }
                   1095:
                   1096: #
                   1097: # print_rc_metadata string
                   1098: #      Print the specified string in such a way that the post-processor
                   1099: #      inside /etc/rc will treat it as meta-data.
                   1100: #
                   1101: #      If we are not running inside /etc/rc, do nothing.
                   1102: #
                   1103: #      For public use by any rc.d script, the string must begin with
                   1104: #      "note:", followed by arbitrary text.  The intent is that the text
                   1105: #      will appear in a log file but not on the console.
                   1106: #
                   1107: #      For private use within /etc/rc, the string must contain a
                   1108: #      keyword recognised by the rc_postprocess_metadata() function
                   1109: #      defined in /etc/rc, followed by a colon, followed by one or more
                   1110: #      colon-separated arguments associated with the keyword.
                   1111: #
                   1112: print_rc_metadata()
                   1113: {
                   1114:        # _rc_postprocessor fd, if defined, is the fd to which we must
                   1115:        # print, prefixing the output with $_rc_metadata_prefix.
                   1116:        #
                   1117:        if [ -n "$_rc_postprocessor_fd" ]; then
1.88    ! apb      1118:                command printf "%s%s\n" "$rc_metadata_prefix" "$1" \
1.78      apb      1119:                        >&${_rc_postprocessor_fd}
                   1120:        fi
                   1121: }
                   1122:
                   1123: #
1.88    ! apb      1124: # _flush_rc_output
        !          1125: #      Arrange for output to be flushed, if we are running
        !          1126: #      inside /etc/rc with postprocessing.
        !          1127: #
        !          1128: _flush_rc_output()
        !          1129: {
        !          1130:        print_rc_metadata "nop"
        !          1131: }
        !          1132:
        !          1133: #
        !          1134: # print_rc_normal [-n] string
1.78      apb      1135: #      Print the specified string in such way that it is treated as
                   1136: #      normal output, regardless of whether or not we are running
                   1137: #      inside /etc/rc with post-processing.
                   1138: #
1.88    ! apb      1139: #      If "-n" is specified in $1, then the string in $2 is printed
        !          1140: #      without a newline; otherwise, the string in $1 is printed
        !          1141: #      with a newline.
        !          1142: #
        !          1143: #      Intended use cases include:
        !          1144: #
        !          1145: #      o   An rc.d script can use ``print_rc_normal -n'' to print a
        !          1146: #          partial line in such a way that it appears immediately
        !          1147: #          instead of being buffered by rc(8)'s post-processor.
        !          1148: #
        !          1149: #      o   An rc.d script that is run via the no_rc_postprocess
        !          1150: #          function (so most of its output is invisible to rc(8)'s
        !          1151: #          post-processor) can use print_rc_normal to force some of its
        !          1152: #          output to be seen by the post-processor.
        !          1153: #
1.78      apb      1154: #
                   1155: print_rc_normal()
                   1156: {
                   1157:        # If _rc_postprocessor_fd is defined, then it is the fd
1.88    ! apb      1158:        # to which we must print; otherwise print to stdout.
1.78      apb      1159:        #
1.88    ! apb      1160:        local fd="${_rc_postprocessor_fd:-1}"
        !          1161:        case "$1" in
        !          1162:        "-n")
        !          1163:                command printf "%s" "$2" >&${fd}
        !          1164:                _flush_rc_output
        !          1165:                ;;
        !          1166:        *)
        !          1167:                command printf "%s\n" "$1" >&${fd}
        !          1168:                ;;
        !          1169:        esac
1.78      apb      1170: }
                   1171:
                   1172: #
                   1173: # no_rc_postprocess cmd...
                   1174: #      Execute the specified command in such a way that its output
                   1175: #      bypasses the post-processor that handles the output from
                   1176: #      most commands that are run inside /etc/rc.  If we are not
                   1177: #      inside /etc/rc, then just execute the command without special
                   1178: #      treatment.
                   1179: #
                   1180: #      The intent is that interactive commands can be run via
                   1181: #      no_rc_postprocess(), and their output will apear immediately
                   1182: #      on the console instead of being hidden or delayed by the
                   1183: #      post-processor.  An unfortunate consequence of the output
                   1184: #      bypassing the post-processor is that the output will not be
                   1185: #      logged.
                   1186: #
                   1187: no_rc_postprocess()
                   1188: {
                   1189:        if [ -n "${_rc_postprocessor_fd}" ]; then
                   1190:                "$@" >&${_rc_original_stdout_fd} 2>&${_rc_original_stderr_fd}
                   1191:        else
                   1192:                "$@"
                   1193:        fi
                   1194: }
                   1195:
                   1196: #
                   1197: # twiddle
                   1198: #      On each call, print a different one of "/", "-", "\\", "|",
                   1199: #      followed by a backspace.  The most recently printed value is
                   1200: #      saved in $_twiddle_state.
                   1201: #
                   1202: #      Output is to /dev/tty, so this function may be useful even inside
                   1203: #      a script whose output is redirected.
                   1204: #
                   1205: twiddle()
                   1206: {
                   1207:        case "$_twiddle_state" in
                   1208:        '/')    _next='-' ;;
                   1209:        '-')    _next='\' ;;
                   1210:        '\')    _next='|' ;;
                   1211:        *)      _next='/' ;;
                   1212:        esac
1.88    ! apb      1213:        command printf "%s\b" "$_next" >/dev/tty
1.78      apb      1214:        _twiddle_state="$_next"
                   1215: }
                   1216:
1.82      christos 1217: #
                   1218: # human_exit_code
                   1219: #      Print the a human version of the exit code.
                   1220: #
                   1221: human_exit_code()
                   1222: {
1.83      christos 1223:        if [ "$1" -lt 127 ]
1.82      christos 1224:        then
                   1225:                echo "exited with code $1"
1.85      christos 1226:        elif [ "$(expr $1 % 256)" -eq 127 ]
1.82      christos 1227:        then
1.84      christos 1228:                # This cannot really happen because the shell will not
                   1229:                # pass stopped job status out and the exit code is limited
                   1230:                # to 8 bits. This code is here just for completeness.
1.82      christos 1231:                echo "stopped with signal $(expr $1 / 256)"
                   1232:        else
                   1233:                echo "terminated with signal $(expr $1 - 128)"
                   1234:        fi
                   1235: }
1.86      apb      1236:
                   1237: #
                   1238: # collapse_backslash_newline
                   1239: #      Copy input to output, collapsing <backslash><newline>
                   1240: #      to nothing, but leaving other backslashes alone.
                   1241: #
                   1242: collapse_backslash_newline()
                   1243: {
                   1244:        local line
                   1245:        while read -r line ; do
                   1246:                case "$line" in
                   1247:                *\\)
                   1248:                        # print it, without the backslash or newline
1.88    ! apb      1249:                        command printf "%s" "${line%?}"
1.86      apb      1250:                        ;;
                   1251:                *)
                   1252:                        # print it, with a newline
1.88    ! apb      1253:                        command printf "%s\n" "${line}"
1.86      apb      1254:                        ;;
                   1255:                esac
                   1256:        done
                   1257: }
1.82      christos 1258:
1.88    ! apb      1259: # Override the normal "echo" and "printf" commands, so that
        !          1260: # partial lines printed by rc.d scripts appear immediately,
        !          1261: # instead of being buffered by rc(8)'s post-processor.
        !          1262: #
        !          1263: # Naive use of the echo or printf commands from rc.d scripts,
        !          1264: # elsewhere in rc.subr, or anything else that sources rc.subr,
        !          1265: # will call these functions.  To call the real echo and printf
        !          1266: # commands, use "command echo" or "command printf".
        !          1267: #
        !          1268: echo()
        !          1269: {
        !          1270:        command echo "$@"
        !          1271:        case "$1" in
        !          1272:        '-n')   _flush_rc_output ;;
        !          1273:        esac
        !          1274: }
        !          1275: printf()
        !          1276: {
        !          1277:        command printf "$@"
        !          1278:        case "$1" in
        !          1279:        *'\n')  : ;;
        !          1280:        *)      _flush_rc_output ;;
        !          1281:        esac
        !          1282: }
        !          1283:
1.64      mycroft  1284: _rc_subr_loaded=:

CVSweb <webmaster@jp.NetBSD.org>