rc.subr revision 106643
1# $NetBSD: rc.subr,v 1.49 2002/05/21 12:31:01 lukem Exp $ 2# $FreeBSD: head/etc/rc.subr 106643 2002-11-08 17:06:15Z gordon $ 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 debug "run_rc_command: using XXX_cmd functions." 536 # if the precmd failed and force 537 # isn't set, exit 538 # 539 if ! eval $_precmd && [ -z "$rc_force" ]; then 540 return 1 541 fi 542 543 if ! eval $_cmd && [ -z "$rc_force" ]; then 544 return 1 545 fi 546 eval $_postcmd 547 return 0 548 fi 549 550 case "$rc_arg" in # default operations... 551 552 status) 553 if [ -n "$rc_pid" ]; then 554 echo "${name} is running as pid $rc_pid." 555 else 556 echo "${name} is not running." 557 return 1 558 fi 559 ;; 560 561 start) 562 if [ -n "$rc_pid" ]; then 563 echo "${name} already running? (pid=$rc_pid)." 564 exit 1 565 fi 566 567 if [ ! -x $command ]; then 568 info "run_rc_command: cannot run ($command)." 569 return 0 570 fi 571 572 # check for required variables, 573 # directories, and files 574 # 575 for _f in $required_vars; do 576 if ! checkyesno $_f; then 577 warn "\$${_f} is not set." 578 if [ -z "$rc_force" ]; then 579 return 1 580 fi 581 fi 582 done 583 for _f in $required_dirs; do 584 if [ ! -d "${_f}/." ]; then 585 warn "${_f} is not a directory." 586 if [ -z "$rc_force" ]; then 587 return 1 588 fi 589 fi 590 done 591 for _f in $required_files; do 592 if [ ! -r "${_f}" ]; then 593 warn "${_f} is not readable." 594 if [ -z "$rc_force" ]; then 595 return 1 596 fi 597 fi 598 done 599 600 # if the precmd failed and force 601 # isn't set, exit 602 # 603 if ! eval $_precmd && [ -z "$rc_force" ]; then 604 return 1 605 fi 606 607 # setup the command to run, and run it 608 # 609 echo "Starting ${name}." 610 if [ -n "$_chroot" ]; then 611 _doit="\ 612${_nice:+nice -n $_nice }\ 613chroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ 614$_chroot $command $rc_flags $command_args" 615 else 616 _doit="\ 617${_chdir:+cd $_chdir; }\ 618${_nice:+nice -n $_nice }\ 619$command $rc_flags $command_args" 620 if [ -n "$_user" ]; then 621 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 622 fi 623 fi 624 625 # if the cmd failed and force 626 # isn't set, exit 627 # 628 debug "run_rc_command: _doit: $_doit" 629 if ! eval $_doit && [ -z "$rc_force" ]; then 630 return 1 631 fi 632 633 # finally, run postcmd 634 # 635 eval $_postcmd 636 ;; 637 638 stop) 639 if [ -z "$rc_pid" ]; then 640 if [ -n "$pidfile" ]; then 641 echo \ 642 "${name} not running? (check $pidfile)." 643 else 644 echo "${name} not running?" 645 fi 646 exit 1 647 fi 648 649 # if the precmd failed and force 650 # isn't set, exit 651 # 652 if ! eval $_precmd && [ -z "$rc_force" ]; then 653 return 1 654 fi 655 656 # send the signal to stop 657 # 658 echo "Stopping ${name}." 659 _doit="kill -${sig_stop:-TERM} $rc_pid" 660 if [ -n "$_user" ]; then 661 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 662 fi 663 664 # if the stop cmd failed and force 665 # isn't set, exit 666 # 667 if ! eval $_doit && [ -z "$rc_force" ]; then 668 return 1 669 fi 670 671 # wait for the command to exit, 672 # and run postcmd. 673 wait_for_pids $rc_pid 674 eval $_postcmd 675 ;; 676 677 reload) 678 if [ -z "$rc_pid" ]; then 679 if [ -n "$pidfile" ]; then 680 echo \ 681 "${name} not running? (check $pidfile)." 682 else 683 echo "${name} not running?" 684 fi 685 exit 1 686 fi 687 echo "Reloading ${name} config files." 688 if ! eval $_precmd && [ -z "$rc_force" ]; then 689 return 1 690 fi 691 _doit="kill -${sig_reload:-HUP} $rc_pid" 692 if [ -n "$_user" ]; then 693 _doit="su -m $_user -c 'sh -c \"$_doit\"'" 694 fi 695 if ! eval $_doit && [ -z "$rc_force" ]; then 696 return 1 697 fi 698 eval $_postcmd 699 ;; 700 701 restart) 702 if ! eval $_precmd && [ -z "$rc_force" ]; then 703 return 1 704 fi 705 # prevent restart being called more 706 # than once by any given script 707 # 708 if [ -n "$_rc_restart_done" ]; then 709 return 0 710 fi 711 _rc_restart_done=YES 712 713 ( $0 ${rc_force:+force}stop ) 714 $0 ${rc_force:+force}start 715 716 eval $_postcmd 717 ;; 718 719 poll) 720 if [ -n "$rc_pid" ]; then 721 wait_for_pids $rc_pid 722 fi 723 ;; 724 725 rcvar) 726 echo "# $name" 727 if [ -n "$rcvar" ]; then 728 if checkyesno ${rcvar}; then 729 echo "\$${rcvar}=YES" 730 else 731 echo "\$${rcvar}=NO" 732 fi 733 fi 734 ;; 735 736 *) 737 rc_usage "$_keywords" 738 ;; 739 740 esac 741 return 0 742 done 743 744 echo 1>&2 "$0: unknown directive '$rc_arg'." 745 rc_usage "$_keywords" 746 exit 1 747} 748 749# 750# run_rc_script file arg 751# Start the script `file' with `arg', and correctly handle the 752# return value from the script. If `file' ends with `.sh', it's 753# sourced into the current environment. If `file' appears to be 754# a backup or scratch file, ignore it. Otherwise if it's 755# executable run as a child process. 756# 757run_rc_script() 758{ 759 _file=$1 760 _arg=$2 761 if [ -z "$_file" -o -z "$_arg" ]; then 762 err 3 'USAGE: run_rc_script file arg' 763 fi 764 765 trap "echo 'Reboot interrupted'; exit 1" 3 766 767 unset name command command_args command_interpreter \ 768 extra_commands pidfile procname \ 769 rcvar required_dirs required_files required_vars 770 eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd 771 772 case "$_file" in 773 *.sh) # run in current shell 774 set $_arg ; . $_file 775 ;; 776 *[~#]|*.OLD|*.orig) # scratch file; skip 777 warn "Ignoring scratch file $_file" 778 ;; 779 *) # run in subshell 780 if [ -x $_file ]; then 781 if [ -n "$rc_fast_and_loose" ]; then 782 set $_arg ; . $_file 783 else 784 ( trap "echo 'Reboot interrupted'; exit 1" 3 785 set $_arg ; . $_file ) 786 fi 787 fi 788 ;; 789 esac 790} 791 792# 793# load_rc_config 794# Source in the configuration file for a given command. 795# 796load_rc_config() 797{ 798 _command=$1 799 if [ -z "$_command" ]; then 800 err 3 'USAGE: load_rc_config command' 801 fi 802 803 if [ -z "$_rc_conf_loaded" ]; then 804 if [ -r /etc/defaults/rc.conf ]; then 805 debug "Sourcing /etc/defaults/rc.conf" 806 . /etc/defaults/rc.conf 807 source_rc_confs 808 elif [ -r /etc/rc.conf ]; then 809 debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." 810 . /etc/rc.conf 811 fi 812 _rc_conf_loaded=YES 813 fi 814 if [ -f /etc/rc.conf.d/"$_command" ]; then 815 debug "Sourcing /etc/rc.conf.d/${_command}" 816 . /etc/rc.conf.d/"$_command" 817 fi 818 819 # XXX - Deprecated variable name support 820 # 821 case ${OSTYPE} in 822 FreeBSD) 823 [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable" 824 [ -n "$portmap_program" ] && rpcbind_program="$portmap_program" 825 [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags" 826 [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable" 827 [ -n "$xntpd_enable" ] && ntpd_enable="$xntpd_enable" 828 [ -n "$xntpd_program" ] && ntpd_program="$xntpd_program" 829 [ -n "$xntpd_flags" ] && ntpd_flags="$xntpd_flags" 830 ;; 831 esac 832 833} 834 835# 836# rc_usage commands 837# Print a usage string for $0, with `commands' being a list of 838# valid commands. 839# 840rc_usage() 841{ 842 echo -n 1>&2 "Usage: $0 [fast|force](" 843 844 _sep= 845 for _elem in $*; do 846 echo -n 1>&2 "$_sep$_elem" 847 _sep="|" 848 done 849 echo 1>&2 ")" 850 exit 1 851} 852 853# 854# err exitval message 855# Display message to stderr and log to the syslog, and exit with exitval. 856# 857err() 858{ 859 exitval=$1 860 shift 861 862 if [ -x /usr/bin/logger ]; then 863 logger "$0: ERROR: $*" 864 fi 865 echo 1>&2 "$0: ERROR: $*" 866 exit $exitval 867} 868 869# 870# warn message 871# Display message to stderr and log to the syslog. 872# 873warn() 874{ 875 if [ -x /usr/bin/logger ]; then 876 logger "$0: WARNING: $*" 877 fi 878 echo 1>&2 "$0: WARNING: $*" 879} 880 881# 882# info message 883# Display informational message to stdout and log to syslog. 884# 885info() 886{ 887 if [ -x /usr/bin/logger ]; then 888 logger "$0: INFO: $*" 889 fi 890 echo "$0: INFO: $*" 891} 892 893# 894# debug message 895# If debugging is enabled in rc.conf output message to stderr. 896# BEWARE that you don't call any subroutine that itself calls this 897# function. 898# 899debug() 900{ 901 case ${rc_debug} in 902 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 903 echo 1>&2 "$0: DEBUG: $*" 904 return 905 ;; 906 esac 907} 908 909# 910# backup_file action file cur backup 911# Make a backup copy of `file' into `cur', and save the previous 912# version of `cur' as `backup' or use rcs for archiving. 913# 914# This routine checks the value of the backup_uses_rcs variable, 915# which can be either YES or NO. 916# 917# The `action' keyword can be one of the following: 918# 919# add `file' is now being backed up (and is possibly 920# being reentered into the backups system). `cur' 921# is created and RCS files, if necessary, are 922# created as well. 923# 924# update `file' has changed and needs to be backed up. 925# If `cur' exists, it is copied to to `back' or 926# checked into RCS (if the repository file is old), 927# and then `file' is copied to `cur'. Another RCS 928# check in done here if RCS is being used. 929# 930# remove `file' is no longer being tracked by the backups 931# system. If RCS is not being used, `cur' is moved 932# to `back', otherwise an empty file is checked in, 933# and then `cur' is removed. 934# 935# 936backup_file() 937{ 938 _action=$1 939 _file=$2 940 _cur=$3 941 _back=$4 942 943 if checkyesno backup_uses_rcs; then 944 _msg0="backup archive" 945 _msg1="update" 946 947 # ensure that history file is not locked 948 if [ -f $_cur,v ]; then 949 rcs -q -u -U -M $_cur 950 fi 951 952 # ensure after switching to rcs that the 953 # current backup is not lost 954 if [ -f $_cur ]; then 955 # no archive, or current newer than archive 956 if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then 957 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 958 rcs -q -kb -U $_cur 959 co -q -f -u $_cur 960 fi 961 fi 962 963 case $_action in 964 add|update) 965 cp -p $_file $_cur 966 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 967 rcs -q -kb -U $_cur 968 co -q -f -u $_cur 969 chown root:wheel $_cur $_cur,v 970 ;; 971 remove) 972 cp /dev/null $_cur 973 ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 974 rcs -q -kb -U $_cur 975 chown root:wheel $_cur $_cur,v 976 rm $_cur 977 ;; 978 esac 979 else 980 case $_action in 981 add|update) 982 if [ -f $_cur ]; then 983 cp -p $_cur $_back 984 fi 985 cp -p $_file $_cur 986 chown root:wheel $_cur 987 ;; 988 remove) 989 mv -f $_cur $_back 990 ;; 991 esac 992 fi 993} 994