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