xref: /dragonfly/etc/rc.subr (revision 52a8809727a06d0e9569683ae6425c6052056155)
1# $NetBSD: rc.subr,v 1.49 2002/05/21 12:31:01 lukem Exp $
2# $FreeBSD: head/etc/rc.subr 275359 2014-12-01 12:17:42Z des $
3#
4# Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# This code is derived from software contributed to The NetBSD Foundation
8# by Luke Mewburn.
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions
12# are met:
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18# 3. All advertising materials mentioning features or use of this software
19#    must display the following acknowledgement:
20#        This product includes software developed by the NetBSD
21#        Foundation, Inc. and its contributors.
22# 4. Neither the name of The NetBSD Foundation nor the names of its
23#    contributors may be used to endorse or promote products derived
24#    from this software without specific prior written permission.
25#
26# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36# POSSIBILITY OF SUCH DAMAGE.
37#
38# rc.subr
39#         functions used by various rc scripts
40#
41
42: ${RC_PID:=$$}; export RC_PID
43
44#
45#         Operating System dependent/independent variables
46#
47
48if [ -z "$_file" ]; then
49          _file="$0"
50fi
51provide_list=`rcorder -p $_file`
52
53if [ -n "${_rc_subr_loaded}" ]; then
54          return
55fi
56
57_rc_subr_loaded="YES"
58
59SYSCTL="/sbin/sysctl"
60SYSCTL_N="${SYSCTL} -n"
61SYSCTL_W="${SYSCTL}"
62CMD_OSTYPE="${SYSCTL_N} kern.ostype"
63OSTYPE=`${CMD_OSTYPE}`
64
65RC_RUNNING=0
66RC_FAILED=1
67RC_DISABLED=2
68RC_IRRELEVANT=3
69RC_CONFIGURED=4
70RC_STOPPED=5
71
72#
73#         functions
74#         ---------
75
76# list_vars pattern
77#         List vars matching pattern.
78#
79list_vars()
80{
81          set | { while read LINE; do
82                    var="${LINE%%=*}"
83                    case "$var" in
84                    "$LINE"|*[!a-zA-Z0-9_]*) continue ;;
85                    $1) echo $var
86                    esac
87          done; }
88}
89
90# set_rcvar base_var
91#         Set the variable name enabling a specific service.
92#         FreeBSD uses ${service}_enable, while NetBSD uses
93#         just the name of the service. For example:
94#         FreeBSD: sendmail_enable="YES"
95#         NetBSD : sendmail="YES"
96#         $1 - if $name is not the base to work of off, specify
97#              a different one
98#
99set_rcvar()
100{
101          if [ -z "$1" ]; then
102                    base_var=${name}
103          else
104                    base_var="$1"
105          fi
106
107          echo ${base_var}
108}
109
110# set_provide_list
111#
112#         $1        should be $rc_arg (start, stop, restart, reload, etc)
113#         $2        return value $RC_*
114#
115#         Set the rcng_* variables associated with elements in provide_list
116#         based on $1 and $2.
117#
118#         Returns non-zero when early termination should occur, in which
119#         case the caller should return with a value of $? - 1
120#
121set_provide_list()
122{
123    # Remember, plret is set to the early termination return code + 1,
124    # or 0 if we want to continue the operation.
125    #
126    for i in $provide_list; do
127          case $1$2 in
128          start$RC_RUNNING|restart$RC_RUNNING)
129              varsym -s rcng_$i=running
130              ;;
131          start$RC_FAILED|restart$RC_FAILED)
132              varsym -s rcng_$i=failed
133              ;;
134          start$RC_DISABLED|restart$RC_DISABLED|reload$RC_DISABLED)
135              varsym -s rcng_$i=disabled
136              ;;
137          start$RC_IRRELEVANT|restart$RC_IRRELEVANT|reload$RC_IRRELEVANT)
138              varsym -s rcng_$i=irrelevant
139              ;;
140          start$RC_CONFIGURED|restart$RC_CONFIGURED)
141              varsym -s rcng_$i=configured
142              ;;
143          stop$RC_DISABLED)
144              varsym -s rcng_$i=disabled
145              ;;
146          stop$RC_IRRELEVANT)
147              varsym -s rcng_$i=irrelevant
148              ;;
149          stop*)
150              varsym -s rcng_$i=stopped
151              ;;
152          *)
153              ;;
154          esac
155    done
156}
157
158# check_early_term
159#         $1        should be $rc_arg (start, stop, restart, reload, etc)
160#         $2        return value $RC_*
161#         $3        $rc_force "" not to force, "anything" to force.
162#
163# The return code is 0 if early termination is not to occur, non-zero if
164# it is to occur.  When early termination is to occur the caller should
165# return check_early_term()'s return code - 1.    That is, early termination
166# can occur with or without an error.
167#
168# The provide list will be adjusted when early termination occurs.
169#
170check_early_term()
171{
172    case $2 in
173    $RC_RUNNING)
174          return 0
175          ;;
176    $RC_FAILED)
177          set_provide_list $1 $2
178          [ -z "$3" ] || return 0
179          return 2
180          ;;
181    $RC_DISABLED)
182          set_provide_list $1 $2
183          [ -z "$3" ] || return 0
184          return 1
185          ;;
186    $RC_IRRELEVANT)
187          set_provide_list $1 $2
188          [ -z "$3" ] || return 0
189          return 1
190          ;;
191    $RC_CONFIGURED)
192          return 0
193          ;;
194    $RC_STOPPED)
195          return 0
196          ;;
197    esac
198    set_provide_list $1 $2
199    [ -z "$3" ] || return 0
200    return 2
201}
202
203# adjust_return_code $1
204#
205#         Convert the return code to an exit code of 0 (success) or 1 (failure)
206#
207adjust_return_code()
208{
209    if [ $1 = $RC_FAILED ]; then
210          return 1
211    fi
212    return 0
213}
214
215#
216# force_depend script
217#         Force a service to start. Intended for use by services
218#         to resolve dependency issues. It is assumed the caller
219#         has check to make sure this call is necessary
220#         $1 - filename of script, in /etc/rc.d, to run
221#
222force_depend()
223{
224          _depend="$1"
225
226          info "${name} depends on ${_depend}, which will be forced to start."
227          if ! /etc/rc.d/${_depend} forcestart ; then
228                    warn "Unable to force ${_depend}. It may already be running."
229                    return 1
230          fi
231          return 0
232}
233
234#
235# checkyesno var
236#         Test $1 variable, and warn if not set to YES or NO.
237#         Return 0 if it's "yes" (et al), nonzero otherwise.
238#
239checkyesno()
240{
241          # try foo
242          eval _value=\$${1%_enable}
243          # try foo_enable
244          if [ -z $_value ]
245          then
246                    eval _value=\$${1%_enable}_enable;
247          fi
248          debug "checkyesno: $1 is set to $_value."
249          case $_value in
250
251                    #         "yes", "true", "on", or "1"
252          [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
253                    return 0
254                    ;;
255
256                    #         "no", "false", "off", or "0"
257          [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
258                    return 1
259                    ;;
260          *)
261                    warn "\$${1} is not set properly - see rc.conf(5)."
262                    return 1
263                    ;;
264          esac
265}
266
267#
268# reverse_list list
269#         print the list in reverse order
270#
271reverse_list()
272{
273          _revlist=
274          for _revfile in $*; do
275                    _revlist="$_revfile $_revlist"
276          done
277          echo $_revlist
278}
279
280#
281# stop_boot always
282#         If booting directly to multiuser or $always is true,
283#         send SIGTERM to the parent (/etc/rc) to abort the boot.
284#         Otherwise just exit.
285#
286stop_boot()
287{
288          local always
289
290          case $1 in
291                    #         "yes", "true", "on", or "1"
292        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
293                    always=true
294                    ;;
295          *)
296                    always=false
297                    ;;
298          esac
299          if [ "$autoboot" = yes -o "$always" = true ]; then
300                    echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!"
301                    kill -TERM ${RC_PID}
302          fi
303          exit 1
304}
305
306#
307# mount_critical_filesystems type
308#         Go through the list of critical filesystems as provided in
309#         the rc.conf(5) variable $critical_filesystems_${type}, checking
310#         each one to see if it is mounted, and if it is not, mounting it.
311#
312mount_critical_filesystems()
313{
314          eval _fslist=\$critical_filesystems_${1}
315          for _fs in $_fslist; do
316                    mount | (
317                              _ismounted=no
318                              while read what _on on _type type; do
319                                        if [ $on = $_fs ]; then
320                                                  _ismounted=yes
321                                        fi
322                              done
323                              if [ $_ismounted = no ]; then
324                                        mount $_fs >/dev/null 2>&1
325                              fi
326                    )
327          done
328}
329
330#
331# check_pidfile pidfile procname [interpreter]
332#         Parses the first line of pidfile for a PID, and ensures
333#         that the process is running and matches procname.
334#         Prints the matching PID upon success, nothing otherwise.
335#         interpreter is optional; see _find_processes() for details.
336#
337check_pidfile()
338{
339          _pidfile=$1
340          _procname=$2
341          _interpreter=$3
342          if [ -z "$_pidfile" -o -z "$_procname" ]; then
343                    err 3 'USAGE: check_pidfile pidfile procname [interpreter]'
344          fi
345          if [ ! -f $_pidfile ]; then
346                    debug "pid file {$_pidfile): not readable."
347                    return
348          fi
349          read _pid _junk < $_pidfile
350          if [ -z "$_pid" ]; then
351                    debug "pid file {$_pidfile): no pid in file."
352                    return
353          fi
354          _find_processes $_procname ${_interpreter:-.} '-p '"$_pid"
355}
356
357#
358# check_process procname [interpreter]
359#         Ensures that a process (or processes) named procname is running.
360#         Prints a list of matching PIDs.
361#         interpreter is optional; see _find_processes() for details.
362#
363check_process()
364{
365          _procname=$1
366          _interpreter=$2
367          if [ -z "$_procname" ]; then
368                    err 3 'USAGE: check_process procname [interpreter]'
369          fi
370          _find_processes $_procname ${_interpreter:-.} '-ax'
371}
372
373#
374# _find_processes procname interpreter psargs
375#         Search for procname in the output of ps generated by psargs.
376#         Prints the PIDs of any matching processes, space separated.
377#
378#         If interpreter == ".", check the following variations of procname
379#         against the first word of each command:
380#                   procname
381#                   `basename procname`
382#                   `basename procname` + ":"
383#                   "(" + `basename procname` + ")"
384#
385#         If interpreter != ".", read the first line of procname, remove the
386#         leading #!, normalise whitespace, append procname, and attempt to
387#         match that against each command, either as is, or with extra words
388#         at the end.
389#
390_find_processes()
391{
392          if [ $# -ne 3 ]; then
393                    err 3 'USAGE: _find_processes procname interpreter psargs'
394          fi
395          _procname=$1
396          _interpreter=$2
397          _psargs=$3
398
399          _pref=
400          if [ $_interpreter != "." ]; then       # an interpreted script
401                    read _interp < $_procname     # read interpreter name
402                    _interp=${_interp#\#!}                  # strip #!
403                    set -- $_interp
404                    if [ $_interpreter != $1 ]; then
405                              warn "\$command_interpreter $_interpreter != $1"
406                    fi
407                    _interp="$* $_procname"                 # cleanup spaces, add _procname
408                    _interpbn="$1"                          # the interpreter binary
409                    _fp_args='_argv'
410                    _fp_match='case "$_argv" in
411                        "${_interpbn##*/}: "$_procname*|${_interp}|"${_interp} "*)'
412          else                                              # a normal daemon
413                    _procnamebn=${_procname##*/}
414                    _fp_args='_arg0 _argv'
415                    _fp_match='case "$_arg0" in
416                        $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})")'
417          fi
418
419          _proccheck='
420                    ps -o "pid,command" '"$_psargs"' |
421                    while read _npid '"$_fp_args"'; do
422                              case "$_npid" in
423                                  PID)
424                                        continue ;;
425                              esac ; '"$_fp_match"'
426                                        echo -n "$_pref$_npid" ;
427                                        _pref=" "
428                                        ;;
429                              esac
430                    done'
431
432#         debug "in _find_processes: proccheck is ($_proccheck)."
433          eval $_proccheck
434}
435
436#
437# wait_for_pids pid [pid ...]
438#         spins until none of the pids exist
439#
440wait_for_pids()
441{
442          _list=$*
443          if [ -z "$_list" ]; then
444                    return
445          fi
446          _prefix=
447          while true; do
448                    _nlist="";
449                    for _j in $_list; do
450                              if kill -0 $_j 2>/dev/null; then
451                                        _nlist="${_nlist}${_nlist:+ }$_j"
452                              fi
453                    done
454                    if [ -z "$_nlist" ]; then
455                              break
456                    fi
457                    _list=$_nlist
458                    echo -n ${_prefix:-"Waiting for PIDS: "}$_list
459                    _prefix=", "
460                    sleep 2
461          done
462          if [ -n "$_prefix" ]; then
463                    echo "."
464          fi
465}
466
467#
468# get_pidfile_from_conf string file
469#
470#         Takes a string to search for in the specified file.
471#         Ignores lines with traditional comment characters.
472#
473# Example:
474#
475# if get_pidfile_from_conf string file; then
476#         pidfile="$_pidfile_from_conf"
477# else
478#         pidfile='appropriate default'
479# fi
480#
481get_pidfile_from_conf()
482{
483          if [ -z "$1" -o -z "$2" ]; then
484                    err 3 "USAGE: get_pidfile_from_conf string file ($name)"
485          fi
486
487          local string file line
488
489          string="$1" ; file="$2"
490
491          if [ ! -s "$file" ]; then
492                    err 3 "get_pidfile_from_conf: $file does not exist ($name)"
493          fi
494
495          while read line; do
496                    case "$line" in
497                    *[#\;]*${string}*)  continue ;;
498                    *${string}*)                  break ;;
499                    esac
500          done < $file
501
502          if [ -n "$line" ]; then
503                    line=${line#*/}
504                    _pidfile_from_conf="/${line%%[\"\;]*}"
505          else
506                    return 1
507          fi
508}
509
510#
511# check_startmsgs
512#         If rc_quiet is set (usually as a result of using faststart at
513#         boot time) check if rc_startmsgs is enabled.
514#
515check_startmsgs()
516{
517          if [ -n "$rc_quiet" ]; then
518                    checkyesno rc_startmsgs
519          else
520                    return 0
521          fi
522}
523
524#
525# run_rc_command argument
526#         Search for argument in the list of supported commands, which is:
527#                   "start stop restart rcvar status poll ${extra_commands}"
528#         If there's a match, run ${argument}_cmd or the default method
529#         (see below).
530#
531#         If argument has a given prefix, then change the operation as follows:
532#                   Prefix    Operation
533#                   ------    ---------
534#                   fast      Skip the pid check, and set rc_fast=yes, rc_quiet=yes
535#                   force     Set ${rcvar} to YES, and set rc_force=yes
536#                   one       Set ${rcvar} to YES
537#                   quiet     Don't output some diagnostics, and set rc_quiet=yes
538#
539#         The following globals are used:
540#
541#         Name                Needed    Purpose
542#         ----                ------    -------
543#         provide_list        (gen)     list of keywords provided by current rcng file
544#
545#         name                y         Name of script.
546#
547#         command             n         Full path to command.
548#                                       Not needed if ${rc_arg}_cmd is set for
549#                                       each keyword.
550#
551#         command_args        n         Optional args/shell directives for command.
552#
553#         command_interpreter n         If not empty, command is interpreted, so
554#                                       call check_{pidfile,process}() appropriately.
555#
556#         extra_commands      n         List of extra commands supported.
557#
558#         pidfile             n         If set, use check_pidfile $pidfile $command,
559#                                       otherwise use check_process $command.
560#                                       In either case, only check if $command is set.
561#
562#         procname  n         Process name to check for instead of $command.
563#
564#         rcvar               n         This is checked with checkyesno to determine
565#                                       if the action should be run.
566#
567#         ${name}_chroot      n         Directory to chroot to before running ${command}
568#                                       Requires /usr to be mounted.
569#
570#         ${name}_chdir       n         Directory to cd to before running ${command}
571#                                       (if not using ${name}_chroot).
572#
573#         ${name}_flags       n         Arguments to call ${command} with.
574#                                       NOTE:     $flags from the parent environment
575#                                                 can be used to override this.
576#
577#         ${name}_env         n         Environment variables to run ${command} with.
578#
579#         ${name}_nice        n         Nice level to run ${command} at.
580#
581#         ${name}_user        n         User to run ${command} as, using su(1) if not
582#                                       using ${name}_chroot.
583#                                       Requires /usr to be mounted.
584#
585#         ${name}_group       n         Group to run chrooted ${command} as.
586#                                       Requires /usr to be mounted.
587#
588#         ${name}_groups      n         Comma separated list of supplementary groups
589#                                       to run the chrooted ${command} with.
590#                                       Requires /usr to be mounted.
591#
592#         ${name}_prepend     n         Command added before ${command}.
593#
594#         ${rc_arg}_cmd       n         If set, use this as the method when invoked;
595#                                       Otherwise, use default command (see below)
596#
597#         ${rc_arg}_precmd n  If set, run just before performing the
598#                                       ${rc_arg}_cmd method in the default
599#                                       operation (i.e, after checking for required
600#                                       bits and process (non)existence).
601#                                       If this completes with a non-zero exit code,
602#                                       don't run ${rc_arg}_cmd.
603#
604#         ${rc_arg}_postcmd n If set, run just after performing the
605#                                       ${rc_arg}_cmd method, if that method
606#                                       returned a zero exit code.
607#
608#         required_dirs       n         If set, check for the existence of the given
609#                                       directories before running the default
610#                                       (re)start command.
611#
612#         required_files      n         If set, check for the readability of the given
613#                                       files before running the default (re)start
614#                                       command.
615#
616#         required_modules n  If set, ensure the given kernel modules are
617#                                       loaded before running a (re)start command.
618#                                       The check and possible loads are actually
619#                                       done after start_precmd so that the modules
620#                                       aren't loaded in vain, should the precmd
621#                                       return a non-zero status to indicate an error.
622#                                       If a word in the list looks like "foo:bar",
623#                                       "foo" is the KLD file name and "bar" is the
624#                                       module name.  If a word looks like "foo~bar",
625#                                       "foo" is the KLD file name and "bar" is a
626#                                       egrep(1) pattern matching the module name.
627#                                       Otherwise the module name is assumed to be
628#                                       the same as the KLD file name, which is most
629#                                       common.  See load_kld().
630#
631#         required_vars       n         If set, perform checkyesno on each of the
632#                                       listed variables before running the default
633#                                       (re)start command.
634#
635#         Default behaviour for a given argument, if no override method is
636#         provided:
637#
638#         Argument  Default behaviour
639#         --------  -----------------
640#         start               if !running && checkyesno ${rcvar}
641#                                       ${command}
642#
643#         stop                if ${pidfile}
644#                                       rc_pid=$(check_pidfile $pidfile $command)
645#                             else
646#                                       rc_pid=$(check_process $command)
647#                             kill $sig_stop $rc_pid
648#                             wait_for_pids $rc_pid
649#                             ($sig_stop defaults to TERM.)
650#
651#         reload              Similar to stop, except use $sig_reload instead,
652#                             and doesn't wait_for_pids.
653#                             $sig_reload defaults to HUP.
654#
655#         restart             Run `stop' then `start'.
656#
657#         status              Show if ${command} is running, etc.
658#
659#         poll                Wait for ${command} to exit.
660#
661#         rcvar               Display what rc.conf variable is used (if any).
662#
663#         Variables available to methods, and after run_rc_command() has
664#         completed:
665#
666#         Variable  Purpose
667#         --------  -------
668#         rc_arg              Argument to command, after fast/force/one processing
669#                             performed
670#
671#         rc_flags  Flags to start the default command with.
672#                             Defaults to ${name}_flags, unless overridden
673#                             by $flags from the environment.
674#                             This variable may be changed by the precmd method.
675#
676#         rc_pid              PID of command (if appropriate)
677#
678#         rc_fast             Not empty if "fast" was provided (q.v.)
679#
680#         rc_force  Not empty if "force" was provided (q.v.)
681#
682#         rc_quiet  Not empty if "quiet" was provided
683#
684#
685dummy_rc_command()
686{
687          rc_arg=$1
688
689          case "$rc_arg" in
690          fast*)                                  # "fast" prefix; don't check pid
691                    rc_arg=${rc_arg#fast}
692                    ;;
693          force*)                                 # "force" prefix; always start
694                    rc_arg=${rc_arg#force}
695                    ;;
696          one*)                                   # "one" prefix; set ${rcvar}=yes
697                    rc_arg=${rc_arg#one}
698                    ;;
699          esac
700          set_provide_list $rc_arg $RC_CONFIGURED
701          return 0
702}
703
704run_rc_command()
705{
706          _return=0
707          rc_arg=$1
708          if [ -z "$name" ]; then
709                    err 3 'run_rc_command: $name is not set.'
710          fi
711
712          # Don't repeat the first argument when passing additional command-
713          # line arguments to the command subroutines.
714          #
715          shift 1
716          rc_extra_args="$*"
717
718          case "$rc_arg" in
719          fast*)                                  # "fast" prefix; don't check pid
720                    rc_arg=${rc_arg#fast}
721                    rc_fast=yes
722                    rc_quiet=yes
723                    ;;
724          force*)                                 # "force" prefix; always start
725                    rc_arg=${rc_arg#force}
726                    rc_force=yes
727                    if [ -n "${rcvar}" ]; then
728                              eval ${rcvar}=YES
729                    fi
730                    ;;
731          one*)                                   # "one" prefix; set ${rcvar}=yes
732                    rc_arg=${rc_arg#one}
733                    if [ -n "${rcvar}" ]; then
734                              eval ${rcvar}=YES
735                    fi
736                    ;;
737          quiet*)                                 # "quiet" prefix; omit some messages
738                    _rc_prefix=quiet
739                    rc_arg=${rc_arg#${_rc_prefix}}
740                    rc_quiet=yes
741                    ;;
742          esac
743
744          eval _override_command=\$${name}_program
745          if [ -n "$_override_command" ]; then
746                    command=$_override_command
747          fi
748
749          _keywords="start stop restart rcvar $extra_commands"
750          rc_pid=
751          _pidcmd=
752          _procname=${procname:-${command}}
753
754                                                  # setup pid check command if not fast
755          if [ -z "$rc_fast" -a -n "$_procname" ]; then
756                    if [ -n "$pidfile" ]; then
757                              _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')'
758                    else
759                              _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')'
760                    fi
761                    if [ -n "$_pidcmd" ]; then
762                              _keywords="${_keywords} status poll"
763                    fi
764          fi
765
766          if [ -z "$rc_arg" ]; then
767                    rc_usage "$_keywords"
768          fi
769
770          if [ -n "$flags" ]; then      # allow override from environment
771                    rc_flags=$flags
772          else
773                    eval rc_flags=\$${name}_flags
774          fi
775          eval _chdir=\$${name}_chdir   _chroot=\$${name}_chroot \
776              _nice=\$${name}_nice      _user=\$${name}_user \
777              _group=\$${name}_group    _groups=\$${name}_groups \
778              _env=\$${name}_env                  _prepend=\$${name}_prepend
779
780          if [ -n "$_user" ]; then      # unset $_user if running as that user
781                    if [ "$_user" = "$(id -un)" ]; then
782                              unset _user
783                    fi
784          fi
785
786                                                  # if ${rcvar} is set, and $1 is not
787                                                  # "rcvar", then run
788                                                  #         checkyesno ${rcvar}
789                                                  # and return if that failed
790                                                  #
791          if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then
792                    if ! checkyesno ${rcvar}; then
793                              set_provide_list $rc_arg $RC_DISABLED
794                              return 0
795                    fi
796          fi
797
798          eval $_pidcmd                           # determine the pid if necessary
799
800          for _elem in $_keywords; do
801                    if [ "$_elem" != "$rc_arg" ]; then
802                              continue
803                    fi
804
805                                                  # if there's a custom ${XXX_cmd},
806                                                  # run that instead of the default
807                                                  #
808                    eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \
809                        _postcmd=\$${rc_arg}_postcmd
810                    if [ -n "$_cmd" ]; then
811                                                  # if the precmd failed and force
812                                                  # isn't set, exit
813                                                  #
814                              if [ -n "$_precmd" ]; then
815                                        debug "run_rc_command: evaluating ${_precmd}()."
816                                        eval $_precmd $rc_extra_args
817
818                                        _return=$?
819                                        check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
820                              fi
821
822                              if [ -n "$_cmd" ]; then
823                                        debug "run_rc_command: evaluating ${_cmd}()."
824                                        eval $_cmd $rc_extra_args
825                                        _return=$?
826                                        check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
827                              fi
828
829                              if [ -n "$_postcmd" ]; then
830                                        debug "run_rc_command: evaluating ${_postcmd}()."
831                                        eval $_postcmd $rc_extra_args
832                                        _return=$?
833                                        check_early_term $rc_arg $_return "" || return $(($?-1))
834                              fi
835                              set_provide_list $rc_arg $_return
836                              adjust_return_code $_return
837                              return $?
838                    fi
839
840                    case "$rc_arg" in   # default operations...
841
842                    status)
843                              if [ -n "$rc_pid" ]; then
844                                        echo "${name} is running as pid $rc_pid."
845                              else
846                                        echo "${name} is not running."
847                                        return 1
848                              fi
849                              ;;
850
851                    start)
852                              if [ -n "$rc_pid" ]; then
853                                        if [ -z "$rc_quiet" ]; then
854                                                  echo "${name} already running? (pid=$rc_pid)."
855                                        fi
856                                        exit 1
857                              fi
858
859                              if [ ! -x $command ]; then
860                                        info "run_rc_command: cannot run ($command)."
861                                        set_provide_list $rc_arg $RC_FAILED
862                                        adjust_return_code $RC_FAILED
863                                        return $?
864                              fi
865
866                                                  # check for required variables,
867                                                  # directories, and files
868                                                  #
869                              for _f in $required_vars; do
870                                        if ! checkyesno $_f; then
871                                                  warn "\$${_f} is not set."
872                                                  if [ -z "$rc_force" ]; then
873                                                            set_provide_list $rc_arg $RC_FAILED
874                                                            adjust_return_code $RC_FAILED
875                                                            return $?
876                                                  fi
877                                        fi
878                              done
879                              for _f in $required_dirs; do
880                                        if [ ! -d "${_f}/." ]; then
881                                                  warn "${_f} is not a directory."
882                                                  if [ -z "$rc_force" ]; then
883                                                            set_provide_list $rc_arg $RC_FAILED
884                                                            adjust_return_code $RC_FAILED
885                                                            return $?
886                                                  fi
887                                        fi
888                              done
889                              for _f in $required_files; do
890                                        if [ ! -r "${_f}" ]; then
891                                                  warn "${_f} is not readable."
892                                                  if [ -z "$rc_force" ]; then
893                                                            set_provide_list $rc_arg $RC_FAILED
894                                                            adjust_return_code $RC_FAILED
895                                                            return $?
896                                                  fi
897                                        fi
898                              done
899                              for _f in $required_modules; do
900                                        case "${_f}" in
901                                        *~*)      _args="-e ${_f#*~} ${_f%%~*}" ;;
902                                        *:*)      _args="-m ${_f#*:} ${_f%%:*}" ;;
903                                        *)        _args="${_f}" ;;
904                                        esac
905                                        if ! load_kld ${_args}; then
906                                                  if [ -z "$rc_force" ]; then
907                                                            set_provide_list $rc_arg $RC_FAILED
908                                                            adjust_return_code $RC_FAILED
909                                                            return $?
910                                                  fi
911                                        fi
912                              done
913
914                                                  # if the precmd failed and force
915                                                  # isn't set, exit
916                                                  #
917                              if [ -n "${_precmd}" ]; then
918                                        debug "run_rc_command: evaluating ${_precmd}()."
919                                        eval $_precmd
920                                        _return=$?
921                                        check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
922                              fi
923
924                                                  # setup the command to run, and run it
925                                                  #
926                              echo "Starting ${name}."
927                              if [ -n "$_chroot" ]; then
928                                        _doit="\
929${_nice:+nice -n $_nice }\
930${_env:+env $_env }\
931chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\
932$_chroot $command $rc_flags $command_args"
933                              else
934                                        _doit="\
935${_chdir:+cd $_chdir; }\
936${_nice:+nice -n $_nice }\
937${_env:+env $_env }\
938$command $rc_flags $command_args"
939                                        if [ -n "$_user" ]; then
940                                            _doit="su -m $_user -c 'sh -c \"$_doit\"'"
941                                        fi
942                                        if [ -n "$_prepend" ]; then
943                                                  _doit="$_prepend $_doit"
944                                        fi
945                              fi
946
947                                                  # if the cmd failed and force
948                                                  # isn't set, exit
949                                                  #
950                              debug "run_rc_command: _doit: $_doit"
951                              eval $_doit
952                              _return=$?
953                              check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
954                                                  # finally, run postcmd
955                                                  #
956                              if [ -n "${_postcmd}" ]; then
957                                        debug "run_rc_command: evaluating ${_postcmd}()."
958                                        eval $_postcmd
959                              fi
960                              ;;
961
962                    stop)
963                              if [ -z "$rc_pid" ]; then
964                                        if [ -n "$pidfile" ]; then
965                                                  echo \
966                                            "${name} not running? (check $pidfile)."
967                                        else
968                                                  echo "${name} not running?"
969                                        fi
970                                        set_provide_list $rc_arg $RC_STOPPED
971                                        exit 1
972                              fi
973
974                                                  # if the precmd failed and force
975                                                  # isn't set, exit
976                                                  #
977                              if [ -n "$_precmd" ]; then
978                                        eval $_precmd
979                                        _return=$?
980                                        check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
981                              fi
982
983                                                  # send the signal to stop
984                                                  #
985                              echo "Stopping ${name}."
986                              _doit="kill -${sig_stop:-TERM} $rc_pid"
987                              if [ -n "$_user" ]; then
988                                        _doit="su -m $_user -c 'sh -c \"$_doit\"'"
989                              fi
990
991                                                  # if the stop cmd failed and force
992                                                  # isn't set, exit
993                                                  #
994                              eval $_doit
995                              _return=$?
996                              check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
997                                                  # wait for the command to exit,
998                                                  # and run postcmd.
999                              sleep 0.1
1000                              wait_for_pids $rc_pid
1001                              if [ -n "$_postcmd" ]; then
1002                                        eval $_postcmd
1003                                        _return=$?
1004                              fi
1005                              ;;
1006
1007                    reload)
1008                              if [ -z "$rc_pid" ]; then
1009                                        if [ -n "$pidfile" ]; then
1010                                                  echo \
1011                                            "${name} not running? (check $pidfile)."
1012                                        else
1013                                                  echo "${name} not running?"
1014                                        fi
1015                                        set_provide_list $rc_arg $RC_FAILED
1016                                        exit 1
1017                              fi
1018                              echo "Reloading ${name} config files."
1019                              if [ -n "$_precmd" ]; then
1020                                        eval $_precmd
1021                                        _return=$?
1022                                        check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
1023                              fi
1024                              _doit="kill -${sig_reload:-HUP} $rc_pid"
1025                              if [ -n "$_user" ]; then
1026                                        _doit="su -m $_user -c 'sh -c \"$_doit\"'"
1027                              fi
1028                              eval $_doit
1029                              _return=$?
1030                              check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
1031                              if [ -n "$_postcmd" ]; then
1032                                        eval $_postcmd
1033                                        _return=$?
1034                              fi
1035                              ;;
1036
1037                    restart)
1038                              if [ -n "$_precmd" ]; then
1039                                        eval $_precmd $rc_extra_args
1040                                        _return=$?
1041                                        check_early_term $rc_arg $_return "$rc_force" || return $(($?-1))
1042                              fi
1043                                                  # prevent restart being called more
1044                                                  # than once by any given script
1045                                                  #
1046                              if [ -n "$_rc_restart_done" ]; then
1047                                        return 0
1048                              fi
1049                              _rc_restart_done=YES
1050
1051                              ( $0 ${rc_force:+force}stop $rc_extra_args )
1052                              $0 ${rc_force:+force}start $rc_extra_args
1053                              _return=$?
1054
1055                              if [ -n "$_postcmd" ]; then
1056                                        eval $_postcmd $rc_extra_args
1057                                        adjust_return_code $?
1058                                        _return=$?
1059                              fi
1060                              # Do not set_provide_list(), the start command above
1061                              # will have done it for us and we do not know the
1062                              # actual RC code to base a setting on here.
1063                              #
1064                              return $_return
1065                              ;;
1066
1067                    poll)
1068                              if [ -n "$rc_pid" ]; then
1069                                        wait_for_pids $rc_pid
1070                              fi
1071                              ;;
1072
1073                    rcvar)
1074                              echo "# $name"
1075                              if [ -n "$rcvar" ]; then
1076                                        if checkyesno ${rcvar}; then
1077                                                  echo "\$${rcvar}=YES"
1078                                        else
1079                                                  echo "\$${rcvar}=NO"
1080                                        fi
1081                              fi
1082                              ;;
1083
1084                    *)
1085                              rc_usage "$_keywords"
1086                              ;;
1087
1088                    esac
1089                    set_provide_list $rc_arg $_return
1090                    adjust_return_code $_return
1091                    return $?
1092          done
1093
1094          echo 1>&2 "$0: unknown directive '$rc_arg'."
1095          rc_usage "$_keywords"
1096          exit 1
1097}
1098
1099#
1100# Helper functions for run_rc_command: common code.
1101# They use such global variables besides the exported rc_* ones:
1102#
1103#         name             R/W
1104#         ------------------
1105#         _precmd             R
1106#         _postcmd  R
1107#         _return             W
1108#
1109_run_rc_precmd()
1110{
1111          check_required_before "$rc_arg" || return 1
1112
1113          if [ -n "$_precmd" ]; then
1114                    debug "run_rc_command: ${rc_arg}_precmd: $_precmd $rc_extra_args"
1115                    eval "$_precmd $rc_extra_args"
1116                    _return=$?
1117
1118                    # If precmd failed and force isn't set, request exit.
1119                    if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then
1120                              return 1
1121                    fi
1122          fi
1123
1124          check_required_after "$rc_arg" || return 1
1125
1126          return 0
1127}
1128
1129_run_rc_postcmd()
1130{
1131          if [ -n "$_postcmd" ]; then
1132                    debug "run_rc_command: ${rc_arg}_postcmd: $_postcmd $rc_extra_args"
1133                    eval "$_postcmd $rc_extra_args"
1134                    _return=$?
1135          fi
1136          return 0
1137}
1138
1139_run_rc_doit()
1140{
1141          debug "run_rc_command: doit: $*"
1142          eval "$@"
1143          _return=$?
1144
1145          # If command failed and force isn't set, request exit.
1146          if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then
1147                    return 1
1148          fi
1149
1150          return 0
1151}
1152
1153_run_rc_notrunning()
1154{
1155          local _pidmsg
1156
1157          if [ -n "$pidfile" ]; then
1158                    _pidmsg=" (check $pidfile)."
1159          else
1160                    _pidmsg=
1161          fi
1162          echo 1>&2 "${name} not running?${_pidmsg}"
1163}
1164
1165_run_rc_killcmd()
1166{
1167          local _cmd
1168
1169          _cmd="kill -$1 $rc_pid"
1170          if [ -n "$_user" ]; then
1171                    _cmd="su -m ${_user} -c 'sh -c \"${_cmd}\"'"
1172          fi
1173          echo "$_cmd"
1174}
1175
1176#
1177# run_rc_script file arg
1178#         Start the script `file' with `arg', and correctly handle the
1179#         return value from the script.  If `file' ends with `.sh', it's
1180#         sourced into the current environment.  If `file' appears to be
1181#         a backup or scratch file, ignore it.  Otherwise if it's
1182#         executable run as a child process.
1183#
1184run_rc_script()
1185{
1186          _file=$1
1187          _arg=$2
1188          if [ -z "$_file" -o -z "$_arg" ]; then
1189                    err 3 'USAGE: run_rc_script file arg'
1190          fi
1191
1192          trap "echo 'Reboot interrupted'; exit 1" 3
1193
1194          unset     name command command_args command_interpreter \
1195                    extra_commands pidfile procname \
1196                    rcvar required_dirs required_files required_vars
1197          eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd
1198
1199          case "$_file" in
1200          *.sh)                                   # run in current shell
1201                    set $_arg ; . $_file
1202                    ;;
1203          *[~#]|*.OLD|*.orig)           # scratch file; skip
1204                    warn "Ignoring scratch file $_file"
1205                    ;;
1206          *)                                      # run in subshell
1207                    if [ -x $_file ]; then
1208                              if [ -n "$rc_fast_and_loose" ]; then
1209                                        set $_arg ; . $_file
1210                              else
1211                                        ( trap "echo 'Reboot interrupted'; exit 1" 3
1212                                          set $_arg ; . $_file )
1213                              fi
1214                    fi
1215                    ;;
1216          esac
1217}
1218
1219# Code common to scripts that need to load a kernel module
1220# if it isn't in the kernel yet. Syntax:
1221#   load_kld [-e regex] [-m module] file
1222# where -e or -m chooses the way to check if the module
1223# is already loaded:
1224#   regex is egrep'd in the output from `kldstat -v',
1225#   module is passed to `kldstat -m'.
1226# The default way is as though `-m file' were specified.
1227load_kld()
1228{
1229          local _loaded _mod _opt _re
1230
1231          while getopts "e:m:" _opt; do
1232                    case "$_opt" in
1233                    e) _re="$OPTARG" ;;
1234                    m) _mod="$OPTARG" ;;
1235                    *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;;
1236                    esac
1237          done
1238          shift $(($OPTIND - 1))
1239          if [ $# -ne 1 ]; then
1240                    err 3 'USAGE: load_kld [-e regex] [-m module] file'
1241          fi
1242          _mod=${_mod:-$1}
1243          _loaded=false
1244          if [ -n "$_re" ]; then
1245                    if kldstat -v | egrep -q -e "$_re"; then
1246                              _loaded=true
1247                    fi
1248          else
1249                    if kldstat -q -m "$_mod"; then
1250                              _loaded=true
1251                    fi
1252          fi
1253          if ! $_loaded; then
1254                    if ! kldload "$1"; then
1255                              warn "Unable to load kernel module $1"
1256                              return 1
1257                    else
1258                              info "$1 kernel module loaded."
1259                    fi
1260          else
1261                    debug "load_kld: $1 kernel module already loaded."
1262          fi
1263          return 0
1264}
1265
1266
1267# ltr str src dst
1268#         Change every $src in $str to $dst.
1269#         Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor
1270#         awk(1).
1271ltr()
1272{
1273          local _str _src _dst _out _com
1274          _str=$1
1275          _src=$2
1276          _dst=$3
1277          _out=""
1278
1279          IFS=${_src}
1280          for _com in ${_str}; do
1281                    if [ -z "${_out}" ]; then
1282                              _out="${_com}"
1283                    else
1284                              _out="${_out}${_dst}${_com}"
1285                    fi
1286          done
1287          echo "${_out}"
1288}
1289
1290#
1291# load_rc_config
1292#         Source in the configuration file for a given command.
1293#
1294load_rc_config()
1295{
1296          _command=$1
1297          if [ -z "$_command" ]; then
1298                    err 3 'USAGE: load_rc_config command'
1299          fi
1300
1301          if [ -z "$_rc_conf_loaded" ]; then
1302                    if [ -r /etc/defaults/rc.conf ]; then
1303                              debug "Sourcing /etc/defaults/rc.conf"
1304                              . /etc/defaults/rc.conf
1305                              source_rc_confs
1306                    elif [ -r /etc/rc.conf ]; then
1307                              debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)."
1308                              . /etc/rc.conf
1309                    fi
1310                    _rc_conf_loaded=YES
1311          fi
1312          if [ -f /etc/rc.conf.d/"$_command" ]; then
1313                    debug "Sourcing /etc/rc.conf.d/${_command}"
1314                    . /etc/rc.conf.d/"$_command"
1315          fi
1316
1317          # XXX - Deprecated variable name support
1318          #
1319          [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable"
1320          [ -n "$portmap_program" ] && rpcbind_program="$portmap_program"
1321          [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags"
1322          [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable"
1323
1324}
1325
1326#
1327# rc_usage commands
1328#         Print a usage string for $0, with `commands' being a list of
1329#         valid commands.
1330#
1331rc_usage()
1332{
1333          echo -n 1>&2 "Usage: $0 [fast|force|one|quiet]("
1334
1335          _sep=
1336          for _elem in $*; do
1337                    echo -n 1>&2 "$_sep$_elem"
1338                    _sep="|"
1339          done
1340          echo 1>&2 ")"
1341          exit 1
1342}
1343
1344#
1345# err exitval message
1346#         Display message to stderr and log to the syslog, and exit with exitval.
1347#
1348err()
1349{
1350          exitval=$1
1351          shift
1352
1353          if [ -x /usr/bin/logger ]; then
1354                    logger "$0: ERROR: $*"
1355          fi
1356          echo 1>&2 "$0: ERROR: $*"
1357          exit $exitval
1358}
1359
1360#
1361# warn message
1362#         Display message to stderr and log to the syslog.
1363#
1364warn()
1365{
1366          if [ -x /usr/bin/logger ]; then
1367                    logger "$0: WARNING: $*"
1368          fi
1369          echo 1>&2 "$0: WARNING: $*"
1370}
1371
1372#
1373# info message
1374#         Display informational message to stdout and log to syslog.
1375#
1376info()
1377{
1378          case ${rc_info} in
1379          [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
1380                    if [ -x /usr/bin/logger ]; then
1381                              logger "$0: INFO: $*"
1382                    fi
1383                    echo "$0: INFO: $*"
1384                    ;;
1385          esac
1386}
1387
1388#
1389# debug message
1390#         If debugging is enabled in rc.conf output message to stderr.
1391#         BEWARE that you don't call any subroutine that itself calls this
1392#         function.
1393#
1394debug()
1395{
1396          case ${rc_debug} in
1397          [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
1398                    if [ -x /usr/bin/logger ]; then
1399                              logger "$0: INFO: $*"
1400                    fi
1401          echo 1>&2 "$0: DEBUG: $*"
1402                    ;;
1403          esac
1404}
1405
1406#
1407# backup_file action file cur backup
1408#         Make a backup copy of `file' into `cur', and save the previous
1409#         version of `cur' as `backup' or use rcs for archiving.
1410#
1411#         This routine checks the value of the backup_uses_rcs variable,
1412#         which can be either YES or NO.
1413#
1414#         The `action' keyword can be one of the following:
1415#
1416#         add                 `file' is now being backed up (and is possibly
1417#                             being reentered into the backups system).  `cur'
1418#                             is created and RCS files, if necessary, are
1419#                             created as well.
1420#
1421#         update              `file' has changed and needs to be backed up.
1422#                             If `cur' exists, it is copied to to `back' or
1423#                             checked into RCS (if the repository file is old),
1424#                             and then `file' is copied to `cur'.  Another RCS
1425#                             check in done here if RCS is being used.
1426#
1427#         remove              `file' is no longer being tracked by the backups
1428#                             system.  If RCS is not being used, `cur' is moved
1429#                             to `back', otherwise an empty file is checked in,
1430#                             and then `cur' is removed.
1431#
1432#
1433backup_file()
1434{
1435          _action=$1
1436          _cpfile=$2
1437          _cur=$3
1438          _back=$4
1439
1440          if checkyesno backup_uses_rcs; then
1441                    _msg0="backup archive"
1442                    _msg1="update"
1443
1444                    # ensure that history file is not locked
1445                    if [ -f $_cur,v ]; then
1446                              rcs -q -u -U -M $_cur
1447                    fi
1448
1449                    # ensure after switching to rcs that the
1450                    # current backup is not lost
1451                    if [ -f $_cur ]; then
1452                              # no archive, or current newer than archive
1453                              if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then
1454                                        ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
1455                                        rcs -q -kb -U $_cur
1456                                        co -q -f -u $_cur
1457                              fi
1458                    fi
1459
1460                    case $_action in
1461                    add|update)
1462                              cp -p $_cpfile $_cur
1463                              ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
1464                              rcs -q -kb -U $_cur
1465                              co -q -f -u $_cur
1466                              chown root:wheel $_cur $_cur,v
1467                              ;;
1468                    remove)
1469                              cp /dev/null $_cur
1470                              ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur
1471                              rcs -q -kb -U $_cur
1472                              chown root:wheel $_cur $_cur,v
1473                              rm $_cur
1474                              ;;
1475                    esac
1476          else
1477                    case $_action in
1478                    add|update)
1479                              if [ -f $_cur ]; then
1480                                        cp -p $_cur $_back
1481                              fi
1482                              cp -p $_cpfile $_cur
1483                              chown root:wheel $_cur
1484                              ;;
1485                    remove)
1486                              mv -f $_cur $_back
1487                              ;;
1488                    esac
1489          fi
1490}
1491
1492# devfs_mount_jail dir
1493# Mounts a devfs file system appropriate for jails
1494# on the directory dir.
1495# This function returns non-zero if an error occurs.
1496#
1497devfs_mount_jail()
1498{
1499          local jdev _me
1500          jdev="$1"
1501          _me="devfs_mount_jail"
1502
1503          if ! devfs_domount "$jdev" $rs; then
1504                    warn "$_me: devfs was not mounted on $jdev"
1505                    return 1
1506          fi
1507          return 0
1508}
1509
1510# devfs_domount dir
1511# Mount devfs on dir.
1512# Returns 0 on success.
1513#
1514devfs_domount()
1515{
1516          local devdir _me
1517          devdir="$1"
1518          _me="devfs_domount()"
1519
1520          if [ -z "$devdir" ]; then
1521                    warn "$_me: you must specify a mount-point"
1522                    return 1
1523          fi
1524
1525          debug "$_me: mount-point is ($devdir)"
1526          if ! mount -t devfs devfs "$devdir"; then
1527                    warn "$_me: Unable to mount devfs on $devdir"
1528                    return 1
1529          fi
1530
1531return 0
1532}
1533
1534# Find scripts in local_startup directories.
1535find_local_scripts() {
1536          local_rc=''
1537          for dir in ${local_startup}; do
1538                    if [ -d "${dir}" ]; then
1539                              for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do
1540                                        case "$file" in
1541                                        *.sample) ;;
1542                                        *)        if [ -x "$file" ]; then
1543                                                            local_rc="${local_rc} ${file}"
1544                                                  fi
1545                                                  ;;
1546                                        esac
1547                              done
1548                    fi
1549          done
1550}
1551