rc.subr revision 114272
1# $NetBSD: rc.subr,v 1.49 2002/05/21 12:31:01 lukem Exp $ 2# $FreeBSD: head/etc/rc.subr 114272 2003-04-30 03:03:47Z mtm $ 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 46SYSCTL="/sbin/sysctl" 47SYSCTL_N="${SYSCTL} -n" 48CMD_OSTYPE="${SYSCTL_N} kern.ostype" 49OSTYPE=`${CMD_OSTYPE}` 50 51case ${OSTYPE} in 52FreeBSD) 53 SYSCTL_W="${SYSCTL}" 54 ;; 55NetBSD) 56 SYSCTL_W="${SYSCTL} -w" 57 ;; 58esac 59 60# 61# functions 62# --------- 63 64# 65# set_rcvar base_var 66# Set the variable name enabling a specific service. 67# FreeBSD uses ${service}_enable, while NetBSD uses 68# just the name of the service. For example: 69# FreeBSD: sendmail_enable="YES" 70# NetBSD : sendmail="YES" 71# $1 - if $name is not the base to work of off, specify 72# a different one 73# 74set_rcvar() 75{ 76 if [ -z "$1" ]; then 77 base_var=${name} 78 else 79 base_var="$1" 80 fi 81 82 case ${OSTYPE} in 83 FreeBSD) 84 echo ${base_var}_enable 85 ;; 86 NetBSD) 87 echo ${base_var} 88 ;; 89 *) 90 echo 'XXX' 91 ;; 92 esac 93} 94 95# 96# force_depend script 97# Force a service to start. Intended for use by services 98# to resolve dependency issues. It is assumed the caller 99# has check to make sure this call is necessary 100# $1 - filename of script, in /etc/rc.d, to run 101# 102force_depend() 103{ 104 _depend="$1" 105 106 info "${name} depends on ${_depend}, which will be forced to start." 107 if ! /etc/rc.d/${_depend} forcestart ; then 108 warn "Unable to force ${_depend}. It may already be running." 109 return 1 110 fi 111 return 0 112} 113 114# 115# checkyesno var 116# Test $1 variable, and warn if not set to YES or NO. 117# Return 0 if it's "yes" (et al), nonzero otherwise. 118# 119checkyesno() 120{ 121 eval _value=\$${1} 122 debug "checkyesno: $1 is set to $_value." 123 case $_value in 124 125 # "yes", "true", "on", or "1" 126 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 127 return 0 128 ;; 129 130 # "no", "false", "off", or "0" 131 [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) 132 return 1 133 ;; 134 *) 135 warn "\$${1} is not set properly - see rc.conf(5)." 136 return 1 137 ;; 138 esac 139} 140 141# reverse_list list 142# print the list in reverse order 143# 144reverse_list() 145{ 146 _revlist= 147 for _revfile in $*; do 148 _revlist="$_revfile $_revlist" 149 done 150 echo $_revlist 151} 152 153# 154# mount_critical_filesystems type 155# Go through the list of critical filesystems as provided in 156# the rc.conf(5) variable $critical_filesystems_${type}, checking 157# each one to see if it is mounted, and if it is not, mounting it. 158# 159mount_critical_filesystems() 160{ 161 eval _fslist=\$critical_filesystems_${1} 162 for _fs in $_fslist; do 163 mount | ( 164 _ismounted=no 165 while read what _on on _type type; do 166 if [ $on = $_fs ]; then 167 _ismounted=yes 168 fi 169 done 170 if [ $_ismounted = no ]; then 171 mount $_fs >/dev/null 2>&1 172 fi 173 ) 174 done 175} 176 177# 178# check_pidfile pidfile procname [interpreter] 179# Parses the first line of pidfile for a PID, and ensures 180# that the process is running and matches procname. 181# Prints the matching PID upon success, nothing otherwise. 182# interpreter is optional; see _find_processes() for details. 183# 184check_pidfile() 185{ 186 _pidfile=$1 187 _procname=$2 188 _interpreter=$3 189 if [ -z "$_pidfile" -o -z "$_procname" ]; then 190 err 3 'USAGE: check_pidfile pidfile procname [interpreter]' 191 fi 192 if [ ! -f $_pidfile ]; then 193 debug "pid file {$_pidfile): not readable." 194 return 195 fi 196 read _pid _junk < $_pidfile 197 if [ -z "$_pid" ]; then 198 debug "pid file {$_pidfile): no pid in file." 199 return 200 fi 201 _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" 202} 203 204# 205# check_process procname [interpreter] 206# Ensures that a process (or processes) named procname is running. 207# Prints a list of matching PIDs. 208# interpreter is optional; see _find_processes() for details. 209# 210check_process() 211{ 212 _procname=$1 213 _interpreter=$2 214 if [ -z "$_procname" ]; then 215 err 3 'USAGE: check_process procname [interpreter]' 216 fi 217 _find_processes $_procname ${_interpreter:-.} '-ax' 218} 219 220# 221# _find_processes procname interpreter psargs 222# Search for procname in the output of ps generated by psargs. 223# Prints the PIDs of any matching processes, space separated. 224# 225# If interpreter == ".", check the following variations of procname 226# against the first word of each command: 227# procname 228# `basename procname` 229# `basename procname` + ":" 230# "(" + `basename procname` + ")" 231# 232# If interpreter != ".", read the first line of procname, remove the 233# leading #!, normalise whitespace, append procname, and attempt to 234# match that against each command, either as is, or with extra words 235# at the end. 236# 237_find_processes() 238{ 239 if [ $# -ne 3 ]; then 240 err 3 'USAGE: _find_processes procname interpreter psargs' 241 fi 242 _procname=$1 243 _interpreter=$2 244 _psargs=$3 245 246 _pref= 247 if [ $_interpreter != "." ]; then # an interpreted script 248 read _interp < $_procname # read interpreter name 249 _interp=${_interp#\#!} # strip #! 250 set -- $_interp 251 if [ $_interpreter != $1 ]; then 252 warn "\$command_interpreter $_interpreter != $1" 253 fi 254 _interp="$* $_procname" # cleanup spaces, add _procname 255 _fp_args='_argv' 256 _fp_match='case "$_argv" in 257 ${_interp}|"${_interp} "*)' 258 else # a normal daemon 259 _procnamebn=${_procname##*/} 260 _fp_args='_arg0 _argv' 261 _fp_match='case "$_arg0" in 262 $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})")' 263 fi 264 265 _proccheck=' 266 ps -o "pid,command" '"$_psargs"' | 267 while read _npid '"$_fp_args"'; do 268 case "$_npid" in 269 PID) 270 continue ;; 271 esac ; '"$_fp_match"' 272 echo -n "$_pref$_npid" ; 273 _pref=" " 274 ;; 275 esac 276 done' 277 278# debug "in _find_processes: proccheck is ($_proccheck)." 279 eval $_proccheck 280} 281 282# 283# wait_for_pids pid [pid ...] 284# spins until none of the pids exist 285# 286wait_for_pids() 287{ 288 _list=$* 289 if [ -z "$_list" ]; then 290 return 291 fi 292 _prefix= 293 while true; do 294 _nlist=""; 295 for _j in $_list; do 296 if kill -0 $_j 2>/dev/null; then 297 _nlist="${_nlist}${_nlist:+ }$_j" 298 fi 299 done 300 if [ -z "$_nlist" ]; then 301 break 302 fi 303 _list=$_nlist 304 echo -n ${_prefix:-"Waiting for PIDS: "}$_list 305 _prefix=", " 306 sleep 2 307 done 308 if [ -n "$_prefix" ]; then 309 echo "." 310 fi 311} 312 313# 314# run_rc_command argument 315# Search for argument in the list of supported commands, which is: 316# "start stop restart rcvar status poll ${extra_commands}" 317# If there's a match, run ${argument}_cmd or the default method 318# (see below). 319# 320# If argument has a given prefix, then change the operation as follows: 321# Prefix Operation 322# ------ --------- 323# fast Skip the pid check, and set rc_fast=yes 324# force Set ${rcvar} to YES, and set rc_force=yes 325# 326# The following globals are used: 327# 328# Name Needed Purpose 329# ---- ------ ------- 330# name y Name of script. 331# 332# command n Full path to command. 333# Not needed if ${rc_arg}_cmd is set for 334# each keyword. 335# 336# command_args n Optional args/shell directives for command. 337# 338# command_interpreter n If not empty, command is interpreted, so 339# call check_{pidfile,process}() appropriately. 340# 341# extra_commands n List of extra commands supported. 342# 343# pidfile n If set, use check_pidfile $pidfile $command, 344# otherwise use check_process $command. 345# In either case, only check if $command is set. 346# 347# procname n Process name to check for instead of $command. 348# 349# rcvar n This is checked with checkyesno to determine 350# if the action should be run. 351# 352# ${name}_chroot n Directory to chroot to before running ${command} 353# Requires /usr to be mounted. 354# 355# ${name}_chdir n Directory to cd to before running ${command} 356# (if not using ${name}_chroot). 357# 358# ${name}_flags n Arguments to call ${command} with. 359# NOTE: $flags from the parent environment 360# can be used to override this. 361# 362# ${name}_nice n Nice level to run ${command} at. 363# 364# ${name}_user n User to run ${command} as, using su(1) if not 365# using ${name}_chroot. 366# Requires /usr to be mounted. 367# 368# ${name}_group n Group to run chrooted ${command} as. 369# Requires /usr to be mounted. 370# 371# ${name}_groups n Comma separated list of supplementary groups 372# to run the chrooted ${command} with. 373# Requires /usr to be mounted. 374# 375# ${rc_arg}_cmd n If set, use this as the method when invoked; 376# Otherwise, use default command (see below) 377# 378# ${rc_arg}_precmd n If set, run just before performing the 379# ${rc_arg}_cmd method in the default 380# operation (i.e, after checking for required 381# bits and process (non)existence). 382# If this completes with a non-zero exit code, 383# don't run ${rc_arg}_cmd. 384# 385# ${rc_arg}_postcmd n If set, run just after performing the 386# ${rc_arg}_cmd method, if that method 387# returned a zero exit code. 388# 389# required_dirs n If set, check for the existence of the given 390# directories before running the default 391# (re)start command. 392# 393# required_files n If set, check for the readability of the given 394# files before running the default (re)start 395# command. 396# 397# required_vars n If set, perform checkyesno on each of the 398# listed variables before running the default 399# (re)start command. 400# 401# Default behaviour for a given argument, if no override method is 402# provided: 403# 404# Argument Default behaviour 405# -------- ----------------- 406# start if !running && checkyesno ${rcvar} 407# ${command} 408# 409# stop if ${pidfile} 410# rc_pid=$(check_pidfile $pidfile $command) 411# else 412# rc_pid=$(check_process $command) 413# kill $sig_stop $rc_pid 414# wait_for_pids $rc_pid 415# ($sig_stop defaults to TERM.) 416# 417# reload Similar to stop, except use $sig_reload instead, 418# and doesn't wait_for_pids. 419# $sig_reload defaults to HUP. 420# 421# restart Run `stop' then `start'. 422# 423# status Show if ${command} is running, etc. 424# 425# poll Wait for ${command} to exit. 426# 427# rcvar Display what rc.conf variable is used (if any). 428# 429# Variables available to methods, and after run_rc_command() has 430# completed: 431# 432# Variable Purpose 433# -------- ------- 434# rc_arg Argument to command, after fast/force processing 435# performed 436# 437# rc_flags Flags to start the default command with. 438# Defaults to ${name}_flags, unless overridden 439# by $flags from the environment. 440# This variable may be changed by the precmd method. 441# 442# rc_pid PID of command (if appropriate) 443# 444# rc_fast Not empty if "fast" was provided (q.v.) 445# 446# rc_force Not empty if "force" was provided (q.v.) 447# 448# 449run_rc_command() 450{ 451 rc_arg=$1 452 if [ -z "$name" ]; then 453 err 3 'run_rc_command: $name is not set.' 454 fi 455 456 case "$rc_arg" in 457 fast*) # "fast" prefix; don't check pid 458 rc_arg=${rc_arg#fast} 459 rc_fast=yes 460 ;; 461 force*) # "force prefix; always start 462 rc_arg=${rc_arg#force} 463 rc_force=yes 464 if [ -n "${rcvar}" ]; then 465 eval ${rcvar}=YES 466 fi 467 ;; 468 esac 469 470 eval _overide_command=\$${name}_program 471 if [ -n "$_overide_command" ]; then 472 command=$_overide_command 473 fi 474 475 _keywords="start stop restart rcvar $extra_commands" 476 rc_pid= 477 _pidcmd= 478 _procname=${procname:-${command}} 479 480 # setup pid check command if not fast 481 if [ -z "$rc_fast" -a -n "$_procname" ]; then 482 if [ -n "$pidfile" ]; then 483 _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' 484 else 485 _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' 486 fi 487 if [ -n "$_pidcmd" ]; then 488 _keywords="${_keywords} status poll" 489 fi 490 fi 491 492 if [ -z "$rc_arg" ]; then 493 rc_usage "$_keywords" 494 fi 495 496 if [ -n "$flags" ]; then # allow override from environment 497 rc_flags=$flags 498 else 499 eval rc_flags=\$${name}_flags 500 fi 501 eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ 502 _nice=\$${name}_nice _user=\$${name}_user \ 503 _group=\$${name}_group _groups=\$${name}_groups 504 505 if [ -n "$_user" ]; then # unset $_user if running as that user 506 if [ "$_user" = "$(id -un)" ]; then 507 unset _user 508 fi 509 fi 510 511 # if ${rcvar} is set, and $1 is not 512 # "rcvar", then run 513 # checkyesno ${rcvar} 514 # and return if that failed 515 # 516 if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then 517 if ! checkyesno ${rcvar}; then 518 return 0 519 fi 520 fi 521 522 eval $_pidcmd # determine the pid if necessary 523 524 for _elem in $_keywords; do 525 if [ "$_elem" != "$rc_arg" ]; then 526 continue 527 fi 528 529 # if there's a custom ${XXX_cmd}, 530 # run that instead of the default 531 # 532 eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \ 533 _postcmd=\$${rc_arg}_postcmd 534 if [ -n "$_cmd" ]; then 535 # if the precmd failed and force 536 # isn't set, exit 537 # 538 [ -n "$_precmd" ] && 539 debug "run_rc_command: evaluating ${_precmd}()." 540 if ! eval $_precmd && [ -z "$rc_force" ]; then 541 return 1 542 fi 543 544 [ -n "$_cmd" ] && 545 debug "run_rc_command: evaluating ${_cmd}()." 546 if ! eval $_cmd && [ -z "$rc_force" ]; then 547 return 1 548 fi 549 550 [ -n "$_postcmd" ] && 551 debug "run_rc_command: evaluating ${_postcmd}()." 552 eval $_postcmd 553 return 0 554 fi 555 556 case "$rc_arg" in # default operations... 557 558 status) 559 if [ -n "$rc_pid" ]; then 560 echo "${name} is running as pid $rc_pid." 561 else 562 echo "${name} is not running." 563 return 1 564 fi 565 ;; 566 567 start) 568 if [ -n "$rc_pid" ]; then 569 echo "${name} already running? (pid=$rc_pid)." 570 exit 1 571 fi 572 573 if [ ! -x $command ]; then 574 info "run_rc_command: cannot run ($command)." 575 return 0 576 fi 577 578 # check for required variables, 579 # directories, and files 580 # 581 for _f in $required_vars; do 582 if ! checkyesno $_f; then 583 warn "\$${_f} is not set." 584 if [ -z "$rc_force" ]; then 585 return 1 586 fi 587 fi 588 done 589 for _f in $required_dirs; do 590 if [ ! -d "${_f}/." ]; then 591 warn "${_f} is not a directory." 592 if [ -z "$rc_force" ]; then 593 return 1 594 fi 595 fi 596 done 597 for _f in $required_files; do 598 if [ ! -r "${_f}" ]; then 599 warn "${_f} is not readable." 600 if [ -z "$rc_force" ]; then 601 return 1 602 fi 603 fi 604 done 605 606 # if the precmd failed and force 607 # isn't set, exit 608 # 609 [ -n "${_precmd}" ] && 610 debug "run_rc_command: evaluating ${_precmd}()." 611 if ! eval $_precmd && [ -z "$rc_force" ]; then 612 return 1 613 fi 614 615 # setup the command to run, and run it 616 # 617 echo "Starting ${name}." 618 if [ -n "$_chroot" ]; then 619 _doit="\ 620${_nice:+nice -n $_nice }\ 621chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ 622$_chroot $command $rc_flags $command_args" 623 else 624 _doit="\ 625${_chdir:+cd $_chdir; }\ 626${_nice:+nice -n $_nice }\ 627$command $rc_flags $command_args" 628 if [ -n "$_user" ]; then 629 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 630 fi 631 fi 632 633 # if the cmd failed and force 634 # isn't set, exit 635 # 636 debug "run_rc_command: _doit: $_doit" 637 if ! eval $_doit && [ -z "$rc_force" ]; then 638 return 1 639 fi 640 641 # finally, run postcmd 642 # 643 [ -n "${_postcmd}" ] && 644 debug "run_rc_command: evaluating ${_postcmd}()." 645 eval $_postcmd 646 ;; 647 648 stop) 649 if [ -z "$rc_pid" ]; then 650 if [ -n "$pidfile" ]; then 651 echo \ 652 "${name} not running? (check $pidfile)." 653 else 654 echo "${name} not running?" 655 fi 656 exit 1 657 fi 658 659 # if the precmd failed and force 660 # isn't set, exit 661 # 662 if ! eval $_precmd && [ -z "$rc_force" ]; then 663 return 1 664 fi 665 666 # send the signal to stop 667 # 668 echo "Stopping ${name}." 669 _doit="kill -${sig_stop:-TERM} $rc_pid" 670 if [ -n "$_user" ]; then 671 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 672 fi 673 674 # if the stop cmd failed and force 675 # isn't set, exit 676 # 677 if ! eval $_doit && [ -z "$rc_force" ]; then 678 return 1 679 fi 680 681 # wait for the command to exit, 682 # and run postcmd. 683 wait_for_pids $rc_pid 684 eval $_postcmd 685 ;; 686 687 reload) 688 if [ -z "$rc_pid" ]; then 689 if [ -n "$pidfile" ]; then 690 echo \ 691 "${name} not running? (check $pidfile)." 692 else 693 echo "${name} not running?" 694 fi 695 exit 1 696 fi 697 echo "Reloading ${name} config files." 698 if ! eval $_precmd && [ -z "$rc_force" ]; then 699 return 1 700 fi 701 _doit="kill -${sig_reload:-HUP} $rc_pid" 702 if [ -n "$_user" ]; then 703 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 704 fi 705 if ! eval $_doit && [ -z "$rc_force" ]; then 706 return 1 707 fi 708 eval $_postcmd 709 ;; 710 711 restart) 712 if ! eval $_precmd && [ -z "$rc_force" ]; then 713 return 1 714 fi 715 # prevent restart being called more 716 # than once by any given script 717 # 718 if [ -n "$_rc_restart_done" ]; then 719 return 0 720 fi 721 _rc_restart_done=YES 722 723 ( $0 ${rc_force:+force}stop ) 724 $0 ${rc_force:+force}start 725 726 eval $_postcmd 727 ;; 728 729 poll) 730 if [ -n "$rc_pid" ]; then 731 wait_for_pids $rc_pid 732 fi 733 ;; 734 735 rcvar) 736 echo "# $name" 737 if [ -n "$rcvar" ]; then 738 if checkyesno ${rcvar}; then 739 echo "\$${rcvar}=YES" 740 else 741 echo "\$${rcvar}=NO" 742 fi 743 fi 744 ;; 745 746 *) 747 rc_usage "$_keywords" 748 ;; 749 750 esac 751 return 0 752 done 753 754 echo 1>&2 "$0: unknown directive '$rc_arg'." 755 rc_usage "$_keywords" 756 exit 1 757} 758 759# 760# run_rc_script file arg 761# Start the script `file' with `arg', and correctly handle the 762# return value from the script. If `file' ends with `.sh', it's 763# sourced into the current environment. If `file' appears to be 764# a backup or scratch file, ignore it. Otherwise if it's 765# executable run as a child process. 766# 767run_rc_script() 768{ 769 _file=$1 770 _arg=$2 771 if [ -z "$_file" -o -z "$_arg" ]; then 772 err 3 'USAGE: run_rc_script file arg' 773 fi 774 775 trap "echo 'Reboot interrupted'; exit 1" 3 776 777 unset name command command_args command_interpreter \ 778 extra_commands pidfile procname \ 779 rcvar required_dirs required_files required_vars 780 eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd 781 782 case "$_file" in 783 *.sh) # run in current shell 784 set $_arg ; . $_file 785 ;; 786 *[~#]|*.OLD|*.orig) # scratch file; skip 787 warn "Ignoring scratch file $_file" 788 ;; 789 *) # run in subshell 790 if [ -x $_file ]; then 791 if [ -n "$rc_fast_and_loose" ]; then 792 set $_arg ; . $_file 793 else 794 ( trap "echo 'Reboot interrupted'; exit 1" 3 795 set $_arg ; . $_file ) 796 fi 797 fi 798 ;; 799 esac 800} 801 802# 803# load_rc_config 804# Source in the configuration file for a given command. 805# 806load_rc_config() 807{ 808 _command=$1 809 if [ -z "$_command" ]; then 810 err 3 'USAGE: load_rc_config command' 811 fi 812 813 if [ -z "$_rc_conf_loaded" ]; then 814 if [ -r /etc/defaults/rc.conf ]; then 815 debug "Sourcing /etc/defaults/rc.conf" 816 . /etc/defaults/rc.conf 817 source_rc_confs 818 elif [ -r /etc/rc.conf ]; then 819 debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." 820 . /etc/rc.conf 821 fi 822 _rc_conf_loaded=YES 823 fi 824 if [ -f /etc/rc.conf.d/"$_command" ]; then 825 debug "Sourcing /etc/rc.conf.d/${_command}" 826 . /etc/rc.conf.d/"$_command" 827 fi 828 829 # XXX - Deprecated variable name support 830 # 831 case ${OSTYPE} in 832 FreeBSD) 833 [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable" 834 [ -n "$portmap_program" ] && rpcbind_program="$portmap_program" 835 [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags" 836 [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable" 837 [ -n "$xntpd_enable" ] && ntpd_enable="$xntpd_enable" 838 [ -n "$xntpd_program" ] && ntpd_program="$xntpd_program" 839 [ -n "$xntpd_flags" ] && ntpd_flags="$xntpd_flags" 840 ;; 841 esac 842 843} 844 845# 846# rc_usage commands 847# Print a usage string for $0, with `commands' being a list of 848# valid commands. 849# 850rc_usage() 851{ 852 echo -n 1>&2 "Usage: $0 [fast|force](" 853 854 _sep= 855 for _elem in $*; do 856 echo -n 1>&2 "$_sep$_elem" 857 _sep="|" 858 done 859 echo 1>&2 ")" 860 exit 1 861} 862 863# 864# err exitval message 865# Display message to stderr and log to the syslog, and exit with exitval. 866# 867err() 868{ 869 exitval=$1 870 shift 871 872 if [ -x /usr/bin/logger ]; then 873 logger "$0: ERROR: $*" 874 fi 875 echo 1>&2 "$0: ERROR: $*" 876 exit $exitval 877} 878 879# 880# warn message 881# Display message to stderr and log to the syslog. 882# 883warn() 884{ 885 if [ -x /usr/bin/logger ]; then 886 logger "$0: WARNING: $*" 887 fi 888 echo 1>&2 "$0: WARNING: $*" 889} 890 891# 892# info message 893# Display informational message to stdout and log to syslog. 894# 895info() 896{ 897 if [ -x /usr/bin/logger ]; then 898 logger "$0: INFO: $*" 899 fi 900 echo "$0: INFO: $*" 901} 902 903# 904# debug message 905# If debugging is enabled in rc.conf output message to stderr. 906# BEWARE that you don't call any subroutine that itself calls this 907# function. 908# 909debug() 910{ 911 case ${rc_debug} in 912 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 913 if [ -x /usr/bin/logger ]; then 914 logger "$0: INFO: $*" 915 fi 916 echo 1>&2 "$0: DEBUG: $*" 917 ;; 918 esac 919} 920 921# 922# backup_file action file cur backup 923# Make a backup copy of `file' into `cur', and save the previous 924# version of `cur' as `backup' or use rcs for archiving. 925# 926# This routine checks the value of the backup_uses_rcs variable, 927# which can be either YES or NO. 928# 929# The `action' keyword can be one of the following: 930# 931# add `file' is now being backed up (and is possibly 932# being reentered into the backups system). `cur' 933# is created and RCS files, if necessary, are 934# created as well. 935# 936# update `file' has changed and needs to be backed up. 937# If `cur' exists, it is copied to to `back' or 938# checked into RCS (if the repository file is old), 939# and then `file' is copied to `cur'. Another RCS 940# check in done here if RCS is being used. 941# 942# remove `file' is no longer being tracked by the backups 943# system. If RCS is not being used, `cur' is moved 944# to `back', otherwise an empty file is checked in, 945# and then `cur' is removed. 946# 947# 948backup_file() 949{ 950 _action=$1 951 _file=$2 952 _cur=$3 953 _back=$4 954 955 if checkyesno backup_uses_rcs; then 956 _msg0="backup archive" 957 _msg1="update" 958 959 # ensure that history file is not locked 960 if [ -f $_cur,v ]; then 961 rcs -q -u -U -M $_cur 962 fi 963 964 # ensure after switching to rcs that the 965 # current backup is not lost 966 if [ -f $_cur ]; then 967 # no archive, or current newer than archive 968 if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then 969 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 970 rcs -q -kb -U $_cur 971 co -q -f -u $_cur 972 fi 973 fi 974 975 case $_action in 976 add|update) 977 cp -p $_file $_cur 978 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 979 rcs -q -kb -U $_cur 980 co -q -f -u $_cur 981 chown root:wheel $_cur $_cur,v 982 ;; 983 remove) 984 cp /dev/null $_cur 985 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 986 rcs -q -kb -U $_cur 987 chown root:wheel $_cur $_cur,v 988 rm $_cur 989 ;; 990 esac 991 else 992 case $_action in 993 add|update) 994 if [ -f $_cur ]; then 995 cp -p $_cur $_back 996 fi 997 cp -p $_file $_cur 998 chown root:wheel $_cur 999 ;; 1000 remove) 1001 mv -f $_cur $_back 1002 ;; 1003 esac 1004 fi 1005} 1006