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