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