rc.subr revision 178776
1164640Sflz# $NetBSD: rc.subr,v 1.67 2006/10/07 11:25:15 elad Exp $ 298186Sgordon# $FreeBSD: head/etc/rc.subr 178776 2008-05-05 15:52:54Z maxim $ 378344Sobrien# 4157473Sflz# Copyright (c) 1997-2004 The NetBSD Foundation, Inc. 578344Sobrien# All rights reserved. 678344Sobrien# 778344Sobrien# This code is derived from software contributed to The NetBSD Foundation 878344Sobrien# by Luke Mewburn. 978344Sobrien# 1078344Sobrien# Redistribution and use in source and binary forms, with or without 1178344Sobrien# modification, are permitted provided that the following conditions 1278344Sobrien# are met: 1378344Sobrien# 1. Redistributions of source code must retain the above copyright 1478344Sobrien# notice, this list of conditions and the following disclaimer. 1578344Sobrien# 2. Redistributions in binary form must reproduce the above copyright 1678344Sobrien# notice, this list of conditions and the following disclaimer in the 1778344Sobrien# documentation and/or other materials provided with the distribution. 1878344Sobrien# 3. All advertising materials mentioning features or use of this software 1978344Sobrien# must display the following acknowledgement: 2078344Sobrien# This product includes software developed by the NetBSD 2178344Sobrien# Foundation, Inc. and its contributors. 2278344Sobrien# 4. Neither the name of The NetBSD Foundation nor the names of its 2378344Sobrien# contributors may be used to endorse or promote products derived 2478344Sobrien# from this software without specific prior written permission. 2578344Sobrien# 2678344Sobrien# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2778344Sobrien# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2878344Sobrien# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2978344Sobrien# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 3078344Sobrien# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3178344Sobrien# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3278344Sobrien# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3378344Sobrien# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3478344Sobrien# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3578344Sobrien# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3678344Sobrien# POSSIBILITY OF SUCH DAMAGE. 3778344Sobrien# 3878344Sobrien# rc.subr 3978344Sobrien# functions used by various rc scripts 4078344Sobrien# 4178344Sobrien 42157473Sflz: ${rcvar_manpage:='rc.conf(5)'} 43169668Smtm: ${RC_PID:=$$}; export RC_PID 44157473Sflz 4578344Sobrien# 4698186Sgordon# Operating System dependent/independent variables 4798186Sgordon# 4898186Sgordon 49131550Scpercivaif [ -z "${_rc_subr_loaded}" ]; then 50131550Scperciva 51131550Scperciva_rc_subr_loaded="YES" 52131550Scperciva 5398186SgordonSYSCTL="/sbin/sysctl" 5498186SgordonSYSCTL_N="${SYSCTL} -n" 5598186SgordonCMD_OSTYPE="${SYSCTL_N} kern.ostype" 56103018SgordonOSTYPE=`${CMD_OSTYPE}` 57124832SmtmID="/usr/bin/id" 58124832SmtmIDCMD="if [ -x $ID ]; then $ID -un; fi" 59161435SyarPS="/bin/ps -ww" 60161435SyarJID=`$PS -p $$ -o jid=` 6198186Sgordon 62103018Sgordoncase ${OSTYPE} in 6398186SgordonFreeBSD) 6498186Sgordon SYSCTL_W="${SYSCTL}" 6598186Sgordon ;; 6698186SgordonNetBSD) 6798186Sgordon SYSCTL_W="${SYSCTL} -w" 6898186Sgordon ;; 6998186Sgordonesac 7098186Sgordon 7198186Sgordon# 7278344Sobrien# functions 7378344Sobrien# --------- 7478344Sobrien 75197144Shrs# 7678344Sobrien# set_rcvar base_var 77197144Shrs# Set the variable name enabling a specific service. 78197144Shrs# FreeBSD uses ${service}_enable, while NetBSD uses 7998186Sgordon# just the name of the service. For example: 80197144Shrs# FreeBSD: sendmail_enable="YES" 81197144Shrs# NetBSD : sendmail="YES" 82197144Shrs# $1 - if $name is not the base to work of off, specify 83197144Shrs# a different one 84197144Shrs# 85197144Shrsset_rcvar() 86197144Shrs{ 87197144Shrs if [ -z "$1" ]; then 88197144Shrs base_var=${name} 8998186Sgordon else 9098186Sgordon base_var="$1" 91197144Shrs fi 92197144Shrs 93197144Shrs case ${OSTYPE} in 9498186Sgordon FreeBSD) 95197144Shrs echo ${base_var}_enable 96197144Shrs ;; 9798186Sgordon NetBSD) 9898186Sgordon echo ${base_var} 99197144Shrs ;; 100197144Shrs *) 101197144Shrs echo 'XXX' 102197144Shrs ;; 103197144Shrs esac 104197144Shrs} 105197144Shrs 106197144Shrs# 107197144Shrs# force_depend script 108197144Shrs# Force a service to start. Intended for use by services 109197144Shrs# to resolve dependency issues. It is assumed the caller 110197144Shrs# has check to make sure this call is necessary 111197144Shrs# $1 - filename of script, in /etc/rc.d, to run 11298186Sgordon# 11398186Sgordonforce_depend() 11498186Sgordon{ 11598186Sgordon _depend="$1" 116197144Shrs 117197144Shrs info "${name} depends on ${_depend}, which will be forced to start." 118197144Shrs if ! /etc/rc.d/${_depend} forcestart; then 11998186Sgordon warn "Unable to force ${_depend}. It may already be running." 120197144Shrs return 1 121197144Shrs fi 122197144Shrs return 0 123197144Shrs} 124197144Shrs 125197144Shrs# 126197144Shrs# checkyesno var 127197144Shrs# Test $1 variable, and warn if not set to YES or NO. 128197144Shrs# Return 0 if it's "yes" (et al), nonzero otherwise. 129197144Shrs# 130197144Shrscheckyesno() 131197144Shrs{ 132197144Shrs eval _value=\$${1} 13398186Sgordon debug "checkyesno: $1 is set to $_value." 13498186Sgordon case $_value in 13598186Sgordon 13698186Sgordon # "yes", "true", "on", or "1" 13798186Sgordon [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 13898186Sgordon return 0 13998186Sgordon ;; 14098186Sgordon 14198186Sgordon # "no", "false", "off", or "0" 14298186Sgordon [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) 14398186Sgordon return 1 144146490Sschweikh ;; 14598186Sgordon *) 14698186Sgordon warn "\$${1} is not set properly - see ${rcvar_manpage}." 14798186Sgordon return 1 14898186Sgordon ;; 14998186Sgordon esac 15098186Sgordon} 15198186Sgordon 15278344Sobrien# 15378344Sobrien# reverse_list list 15478344Sobrien# print the list in reverse order 15578344Sobrien# 15678344Sobrienreverse_list() 15778344Sobrien{ 15878344Sobrien _revlist= 15998186Sgordon for _revfile; do 16078344Sobrien _revlist="$_revfile $_revlist" 16178344Sobrien done 16278344Sobrien echo $_revlist 16378344Sobrien} 16478344Sobrien 16578344Sobrien# stop_boot always 16678344Sobrien# If booting directly to multiuser or $always is enabled, 16778344Sobrien# send SIGTERM to the parent (/etc/rc) to abort the boot. 16878344Sobrien# Otherwise just exit. 16978344Sobrien# 17078344Sobrienstop_boot() 17178344Sobrien{ 172157473Sflz local always 17378344Sobrien 17478344Sobrien case $1 in 17578344Sobrien # "yes", "true", "on", or "1" 17678344Sobrien [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 17778344Sobrien always=true 178157473Sflz ;; 17998186Sgordon *) 18098186Sgordon always=false 18178344Sobrien ;; 18298186Sgordon esac 18398186Sgordon if [ "$autoboot" = yes -o "$always" = true ]; then 18498186Sgordon echo "ERROR: ABORTING BOOT (sending SIGTERM to parent)!" 185126286Smtm kill -TERM ${RC_PID} 18698186Sgordon fi 18798186Sgordon exit 1 18898186Sgordon} 18998186Sgordon 19098186Sgordon# 191169668Smtm# mount_critical_filesystems type 192169668Smtm# Go through the list of critical filesystems as provided in 193169668Smtm# the rc.conf(5) variable $critical_filesystems_${type}, checking 194169668Smtm# each one to see if it is mounted, and if it is not, mounting it. 19578344Sobrien# 196169668Smtmmount_critical_filesystems() 197169668Smtm{ 198169668Smtm eval _fslist=\$critical_filesystems_${1} 199169668Smtm for _fs in $_fslist; do 200178776Smaxim mount | ( 201178776Smaxim _ismounted=false 202178770Smtm while read what _on on _type type; do 203169668Smtm if [ $on = $_fs ]; then 204178770Smtm _ismounted=true 205178770Smtm fi 206169668Smtm done 207178770Smtm if $_ismounted; then 208178775Smaxim : 209169668Smtm else 210169668Smtm mount $_fs >/dev/null 2>&1 211169668Smtm fi 212169668Smtm ) 213169668Smtm done 214169668Smtm} 215169668Smtm 216169668Smtm# 21798186Sgordon# check_pidfile pidfile procname [interpreter] 21898186Sgordon# Parses the first line of pidfile for a PID, and ensures 21998186Sgordon# that the process is running and matches procname. 22098186Sgordon# Prints the matching PID upon success, nothing otherwise. 22198186Sgordon# interpreter is optional; see _find_processes() for details. 22278344Sobrien# 22378344Sobriencheck_pidfile() 22498186Sgordon{ 22578344Sobrien _pidfile=$1 22678344Sobrien _procname=$2 227126285Smtm _interpreter=$3 22878344Sobrien if [ -z "$_pidfile" -o -z "$_procname" ]; then 22978344Sobrien err 3 'USAGE: check_pidfile pidfile procname [interpreter]' 230126285Smtm fi 23178344Sobrien if [ ! -f $_pidfile ]; then 23278344Sobrien debug "pid file ($_pidfile): not readable." 233126285Smtm return 234126285Smtm fi 235126285Smtm read _pid _junk < $_pidfile 23678344Sobrien if [ -z "$_pid" ]; then 23778344Sobrien debug "pid file ($_pidfile): no pid in file." 23898186Sgordon return 23978344Sobrien fi 24078344Sobrien _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" 24178344Sobrien} 24278344Sobrien 24398186Sgordon# 24498186Sgordon# check_process procname [interpreter] 24578344Sobrien# Ensures that a process (or processes) named procname is running. 24698186Sgordon# Prints a list of matching PIDs. 24798186Sgordon# interpreter is optional; see _find_processes() for details. 24878344Sobrien# 24978344Sobriencheck_process() 25078344Sobrien{ 25178344Sobrien _procname=$1 25278344Sobrien _interpreter=$2 25398186Sgordon if [ -z "$_procname" ]; then 25478344Sobrien err 3 'USAGE: check_process procname [interpreter]' 25598186Sgordon fi 25678344Sobrien _find_processes $_procname ${_interpreter:-.} '-ax' 25778344Sobrien} 258131061Smtm 25978344Sobrien# 26078344Sobrien# _find_processes procname interpreter psargs 26178344Sobrien# Search for procname in the output of ps generated by psargs. 26278344Sobrien# Prints the PIDs of any matching processes, space separated. 263139949Skeramida# 26478344Sobrien# If interpreter == ".", check the following variations of procname 26578344Sobrien# against the first word of each command: 26698186Sgordon# procname 26778344Sobrien# `basename procname` 26878344Sobrien# `basename procname` + ":" 26978344Sobrien# "(" + `basename procname` + ")" 27098186Sgordon# "[" + `basename procname` + "]" 27178344Sobrien# 27298186Sgordon# If interpreter != ".", read the first line of procname, remove the 27398186Sgordon# leading #!, normalise whitespace, append procname, and attempt to 27478344Sobrien# match that against each command, either as is, or with extra words 27578344Sobrien# at the end. As an alternative, to deal with interpreted daemons 27678344Sobrien# using perl, the basename of the interpreter plus a colon is also 27778344Sobrien# tried as the prefix to procname. 27898186Sgordon# 27978344Sobrien_find_processes() 28098186Sgordon{ 28178344Sobrien if [ $# -ne 3 ]; then 28298186Sgordon err 3 'USAGE: _find_processes procname interpreter psargs' 28398186Sgordon fi 28498186Sgordon _procname=$1 28598186Sgordon _interpreter=$2 28698186Sgordon _psargs=$3 28798186Sgordon 28898186Sgordon _pref= 28998186Sgordon if [ $_interpreter != "." ]; then # an interpreted script 29098186Sgordon _script=${_chroot}${_chroot:+"/"}$_procname 29198186Sgordon if [ -r $_script ]; then 29298186Sgordon read _interp < $_script # read interpreter name 29398186Sgordon case "$_interp" in 29498186Sgordon \#!*) 29598186Sgordon _interp=${_interp#\#!} # strip #! 296155719Sceri set -- $_interp 29798186Sgordon case $1 in 29898186Sgordon */bin/env) 29998186Sgordon shift # drop env to get real name 30098186Sgordon ;; 301157841Sflz esac 302157841Sflz if [ $_interpreter != $1 ]; then 303157841Sflz warn "\$command_interpreter $_interpreter != $1" 30498186Sgordon fi 30598186Sgordon ;; 30698186Sgordon *) 30798186Sgordon warn "no shebang line in $_script" 30898186Sgordon set -- $_interpreter 30998186Sgordon ;; 31098186Sgordon esac 31198186Sgordon else 31298186Sgordon warn "cannot read shebang line from $_script" 31398186Sgordon set -- $_interpreter 31478344Sobrien fi 31598186Sgordon _interp="$* $_procname" # cleanup spaces, add _procname 316170282Syar _interpbn=${1##*/} 317170282Syar _fp_args='_argv' 318170282Syar _fp_match='case "$_argv" in 319170282Syar ${_interp}|"${_interp} "*|"${_interpbn}: ${_procname}"*)' 320170282Syar else # a normal daemon 321170282Syar _procnamebn=${_procname##*/} 322170282Syar _fp_args='_arg0 _argv' 323170282Syar _fp_match='case "$_arg0" in 324170282Syar $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' 325170282Syar fi 326170282Syar 327170282Syar _proccheck="\ 328170282Syar $PS 2>/dev/null -o pid= -o jid= -o command= $_psargs"' | 329170282Syar while read _npid _jid '"$_fp_args"'; do 330170282Syar '"$_fp_match"' 331170282Syar if [ "$JID" -eq "$_jid" ]; 332170282Syar then echo -n "$_pref$_npid"; 333170282Syar _pref=" "; 334170282Syar fi 335170282Syar ;; 336170282Syar esac 337170282Syar done' 338170282Syar 339170282Syar# debug "in _find_processes: proccheck is ($_proccheck)." 34078344Sobrien eval $_proccheck 34198186Sgordon} 342157841Sflz 34398186Sgordon# 34498186Sgordon# wait_for_pids pid [pid ...] 345157841Sflz# spins until none of the pids exist 34698186Sgordon# 34798186Sgordonwait_for_pids() 34898186Sgordon{ 34998186Sgordon _list="$@" 350151426Sjhb if [ -z "$_list" ]; then 35198186Sgordon return 35298186Sgordon fi 353161435Syar _prefix= 354161436Syar while true; do 355157657Sflz _nlist=""; 356161436Syar for _j in $_list; do 357157657Sflz if kill -0 $_j 2>/dev/null; then 358157657Sflz _nlist="${_nlist}${_nlist:+ }$_j" 359157657Sflz fi 360157657Sflz done 36198186Sgordon if [ -z "$_nlist" ]; then 36298186Sgordon break 36398186Sgordon fi 36498186Sgordon _list=$_nlist 365114272Smtm echo -n ${_prefix:-"Waiting for PIDS: "}$_list 36698186Sgordon _prefix=", " 36798186Sgordon sleep 2 36898186Sgordon done 36998186Sgordon if [ -n "$_prefix" ]; then 37098186Sgordon echo "." 37198186Sgordon fi 37298186Sgordon} 37398186Sgordon 37498186Sgordon# 375126286Smtm# run_rc_command argument 37698186Sgordon# Search for argument in the list of supported commands, which is: 37798186Sgordon# "start stop restart rcvar status poll ${extra_commands}" 37898186Sgordon# If there's a match, run ${argument}_cmd or the default method 37998186Sgordon# (see below). 38098186Sgordon# 38198186Sgordon# If argument has a given prefix, then change the operation as follows: 38298186Sgordon# Prefix Operation 38398186Sgordon# ------ --------- 38498186Sgordon# fast Skip the pid check, and set rc_fast=yes, rc_quiet=yes 38598186Sgordon# force Set ${rcvar} to YES, and set rc_force=yes 38698186Sgordon# one Set ${rcvar} to YES 38798186Sgordon# quiet Don't output some diagnostics, and set rc_quiet=yes 38898186Sgordon# 38978344Sobrien# The following globals are used: 39098186Sgordon# 39198186Sgordon# Name Needed Purpose 39298186Sgordon# ---- ------ ------- 39398186Sgordon# name y Name of script. 39478344Sobrien# 39598186Sgordon# command n Full path to command. 39698186Sgordon# Not needed if ${rc_arg}_cmd is set for 39798186Sgordon# each keyword. 39878344Sobrien# 39978344Sobrien# command_args n Optional args/shell directives for command. 40078344Sobrien# 401197947Sdougb# command_interpreter n If not empty, command is interpreted, so 402197947Sdougb# call check_{pidfile,process}() appropriately. 403197947Sdougb# 404197947Sdougb# extra_commands n List of extra commands supported. 405197947Sdougb# 406197947Sdougb# pidfile n If set, use check_pidfile $pidfile $command, 407197947Sdougb# otherwise use check_process $command. 408197947Sdougb# In either case, only check if $command is set. 409197947Sdougb# 410197947Sdougb# procname n Process name to check for instead of $command. 411197947Sdougb# 412197947Sdougb# rcvar n This is checked with checkyesno to determine 413197947Sdougb# if the action should be run. 414197947Sdougb# 41598186Sgordon# ${name}_program n Full path to command. 41698186Sgordon# Meant to be used in /etc/rc.conf to override 41798186Sgordon# ${command}. 41898186Sgordon# 41998186Sgordon# ${name}_chroot n Directory to chroot to before running ${command} 42078344Sobrien# Requires /usr to be mounted. 42198186Sgordon# 42298186Sgordon# ${name}_chdir n Directory to cd to before running ${command} 42378344Sobrien# (if not using ${name}_chroot). 424175676Smtm# 42598186Sgordon# ${name}_flags n Arguments to call ${command} with. 426126303Smtm# NOTE: $flags from the parent environment 427175676Smtm# can be used to override this. 42878344Sobrien# 42978344Sobrien# ${name}_nice n Nice level to run ${command} at. 43078344Sobrien# 43198186Sgordon# ${name}_user n User to run ${command} as, using su(1) if not 43298186Sgordon# using ${name}_chroot. 43378344Sobrien# Requires /usr to be mounted. 43478344Sobrien# 43578344Sobrien# ${name}_group n Group to run chrooted ${command} as. 43698186Sgordon# Requires /usr to be mounted. 43778344Sobrien# 43878344Sobrien# ${name}_groups n Comma separated list of supplementary groups 43978344Sobrien# to run the chrooted ${command} with. 44078344Sobrien# Requires /usr to be mounted. 44198186Sgordon# 44298186Sgordon# ${rc_arg}_cmd n If set, use this as the method when invoked; 44398186Sgordon# Otherwise, use default command (see below) 444197144Shrs# 445197144Shrs# ${rc_arg}_precmd n If set, run just before performing the 44678344Sobrien# ${rc_arg}_cmd method in the default 44778344Sobrien# operation (i.e, after checking for required 44898186Sgordon# bits and process (non)existence). 44998186Sgordon# If this completes with a non-zero exit code, 45098186Sgordon# don't run ${rc_arg}_cmd. 45178344Sobrien# 45298186Sgordon# ${rc_arg}_postcmd n If set, run just after performing the 45398186Sgordon# ${rc_arg}_cmd method, if that method 45478344Sobrien# returned a zero exit code. 45578344Sobrien# 45678344Sobrien# required_dirs n If set, check for the existence of the given 457157653Sflz# directories before running a (re)start command. 458157653Sflz# 459157653Sflz# required_files n If set, check for the readability of the given 460157653Sflz# files before running a (re)start command. 46178344Sobrien# 46298186Sgordon# required_modules n If set, ensure the given kernel modules are 46378344Sobrien# loaded before running a (re)start command. 46478344Sobrien# The check and possible loads are actually 46578344Sobrien# done after start_precmd so that the modules 46678344Sobrien# aren't loaded in vain, should the precmd 46778344Sobrien# return a non-zero status to indicate a error. 46878344Sobrien# If a word in the list looks like "foo:bar", 46978344Sobrien# "foo" is the KLD file name and "bar" is the 47078344Sobrien# module name. If a word looks like "foo~bar", 47178344Sobrien# "foo" is the KLD file name and "bar" is a 47278344Sobrien# egrep(1) pattern matching the module name. 47378344Sobrien# Otherwise the module name is assumed to be 47478344Sobrien# the same as the KLD file name, which is most 47598186Sgordon# common. See load_kld(). 47678344Sobrien# 47778344Sobrien# required_vars n If set, perform checkyesno on each of the 47898186Sgordon# listed variables before running the default 47978344Sobrien# (re)start command. 48098186Sgordon# 48198186Sgordon# Default behaviour for a given argument, if no override method is 48298186Sgordon# provided: 48378344Sobrien# 48498186Sgordon# Argument Default behaviour 48578344Sobrien# -------- ----------------- 48678344Sobrien# start if !running && checkyesno ${rcvar} 48798186Sgordon# ${command} 48898186Sgordon# 48998186Sgordon# stop if ${pidfile} 49098186Sgordon# rc_pid=$(check_pidfile $pidfile $command) 49178344Sobrien# else 49298186Sgordon# rc_pid=$(check_process $command) 49378344Sobrien# kill $sig_stop $rc_pid 49498186Sgordon# wait_for_pids $rc_pid 49598186Sgordon# ($sig_stop defaults to TERM.) 49698186Sgordon# 49798186Sgordon# reload Similar to stop, except use $sig_reload instead, 49878344Sobrien# and doesn't wait_for_pids. 499165565Syar# $sig_reload defaults to HUP. 50078344Sobrien# Note that `reload' isn't provided by default, 50178344Sobrien# it should be enabled via $extra_commands. 502165565Syar# 50378344Sobrien# restart Run `stop' then `start'. 504165565Syar# 505165565Syar# status Show if ${command} is running, etc. 506165565Syar# 507165565Syar# poll Wait for ${command} to exit. 508165565Syar# 509165565Syar# rcvar Display what rc.conf variable is used (if any). 510165565Syar# 511165565Syar# Variables available to methods, and after run_rc_command() has 512165565Syar# completed: 513165565Syar# 514165565Syar# Variable Purpose 515165565Syar# -------- ------- 516165565Syar# rc_arg Argument to command, after fast/force/one processing 517165565Syar# performed 518165565Syar# 51978344Sobrien# rc_flags Flags to start the default command with. 52078344Sobrien# Defaults to ${name}_flags, unless overridden 52178344Sobrien# by $flags from the environment. 52278344Sobrien# This variable may be changed by the precmd method. 52398186Sgordon# 52498186Sgordon# rc_pid PID of command (if appropriate) 52578344Sobrien# 52698186Sgordon# rc_fast Not empty if "fast" was provided (q.v.) 52798186Sgordon# 52878344Sobrien# rc_force Not empty if "force" was provided (q.v.) 52978344Sobrien# 53078344Sobrien# rc_quiet Not empty if "quiet" was provided 53178344Sobrien# 53298186Sgordon# 53378344Sobrienrun_rc_command() 53498186Sgordon{ 53598186Sgordon _return=0 53698186Sgordon rc_arg=$1 53798186Sgordon if [ -z "$name" ]; then 53878344Sobrien err 3 'run_rc_command: $name is not set.' 53998186Sgordon fi 54098186Sgordon 54178344Sobrien # Don't repeat the first argument when passing additional command- 542151685Syar # line arguments to the command subroutines. 543151685Syar # 54478344Sobrien shift 1 54578344Sobrien rc_extra_args="$*" 54678344Sobrien 54798186Sgordon _rc_prefix= 54878344Sobrien case "$rc_arg" in 54998186Sgordon fast*) # "fast" prefix; don't check pid 55098186Sgordon rc_arg=${rc_arg#fast} 55198186Sgordon rc_fast=yes 55298186Sgordon rc_quiet=yes 55398186Sgordon ;; 55498186Sgordon force*) # "force prefix; always run 55598186Sgordon rc_force=yes 55698186Sgordon _rc_prefix=force 55798186Sgordon rc_arg=${rc_arg#${_rc_prefix}} 558126303Smtm if [ -n "${rcvar}" ]; then 55998186Sgordon eval ${rcvar}=YES 56098186Sgordon fi 56198186Sgordon ;; 56298186Sgordon one*) # "one" prefix; set ${rcvar}=yes 56398186Sgordon _rc_prefix=one 56498186Sgordon rc_arg=${rc_arg#${_rc_prefix}} 56598186Sgordon if [ -n "${rcvar}" ]; then 56698186Sgordon eval ${rcvar}=YES 56798186Sgordon fi 56898186Sgordon ;; 56998186Sgordon quiet*) # "quiet" prefix; omit some messages 57098186Sgordon _rc_prefix=quiet 57198186Sgordon rc_arg=${rc_arg#${_rc_prefix}} 572175676Smtm rc_quiet=yes 57398186Sgordon ;; 574175676Smtm esac 57578344Sobrien 57678344Sobrien eval _override_command=\$${name}_program 577116097Smtm command=${command:+${_override_command:-$command}} 57898186Sgordon 57978344Sobrien _keywords="start stop restart rcvar $extra_commands" 58098186Sgordon rc_pid= 58178344Sobrien _pidcmd= 58278344Sobrien _procname=${procname:-${command}} 583132892Smtm 584132892Smtm # setup pid check command 585132892Smtm if [ -n "$_procname" ]; then 586132892Smtm if [ -n "$pidfile" ]; then 587132892Smtm _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' 588132892Smtm else 589126303Smtm _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' 59098186Sgordon fi 59178344Sobrien if [ -n "$_pidcmd" ]; then 59298186Sgordon _keywords="${_keywords} status poll" 59398186Sgordon fi 594175676Smtm fi 59578344Sobrien 596198216Sed if [ -z "$rc_arg" ]; then 59798186Sgordon rc_usage $_keywords 598126303Smtm fi 599126303Smtm 60078344Sobrien if [ -n "$flags" ]; then # allow override from environment 60178344Sobrien rc_flags=$flags 60278344Sobrien else 60378344Sobrien eval rc_flags=\$${name}_flags 604126303Smtm fi 605126303Smtm eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ 606126303Smtm _nice=\$${name}_nice _user=\$${name}_user \ 607126303Smtm _group=\$${name}_group _groups=\$${name}_groups 608126303Smtm 609126303Smtm if [ -n "$_user" ]; then # unset $_user if running as that user 610126303Smtm if [ "$_user" = "$(eval $IDCMD)" ]; then 611175676Smtm unset _user 612175676Smtm fi 613175676Smtm fi 614175676Smtm 615175676Smtm # if ${rcvar} is set, and $1 is not 61678344Sobrien # "rcvar", then run 61778344Sobrien # checkyesno ${rcvar} 618161530Sflz # and return if that failed 619198162Sdougb # 620161530Sflz if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then 62178344Sobrien if ! checkyesno ${rcvar}; then 62298186Sgordon if [ -n "${rc_quiet}" ]; then 62378344Sobrien return 0 62498186Sgordon fi 62598186Sgordon echo -n "Cannot '${rc_arg}' $name. Set ${rcvar} to " 626131135Smtm echo -n "YES in /etc/rc.conf or use 'one${rc_arg}' " 627131135Smtm echo "instead of '${rc_arg}'." 62878344Sobrien return 0 62998186Sgordon fi 63098186Sgordon fi 63198186Sgordon 63278344Sobrien eval $_pidcmd # determine the pid if necessary 63378344Sobrien 63498186Sgordon for _elem in $_keywords; do 63578344Sobrien if [ "$_elem" != "$rc_arg" ]; then 63678344Sobrien continue 63778344Sobrien fi 63898186Sgordon # if there's a custom ${XXX_cmd}, 639150796Syar # run that instead of the default 64078344Sobrien # 64178344Sobrien eval _cmd=\$${rc_arg}_cmd \ 64278344Sobrien _precmd=\$${rc_arg}_precmd \ 64398186Sgordon _postcmd=\$${rc_arg}_postcmd 64478344Sobrien 64598186Sgordon if [ -n "$_cmd" ]; then 64678344Sobrien _run_rc_precmd || return 1 64798186Sgordon _run_rc_doit "$_cmd $rc_extra_args" || return 1 64898186Sgordon _run_rc_postcmd 64998186Sgordon return $_return 65078344Sobrien fi 65198186Sgordon 652124832Smtm case "$rc_arg" in # default operations... 65398186Sgordon 65498186Sgordon status) 65598186Sgordon _run_rc_precmd || return 1 65698186Sgordon if [ -n "$rc_pid" ]; then 657179870Smtm echo "${name} is running as pid $rc_pid." 658179870Smtm else 659179870Smtm echo "${name} is not running." 660179870Smtm return 1 661179870Smtm fi 662179870Smtm _run_rc_postcmd 66378344Sobrien ;; 66498186Sgordon 66578344Sobrien start) 66678344Sobrien if [ -z "$rc_fast" -a -n "$rc_pid" ]; then 66778344Sobrien echo 1>&2 "${name} already running? (pid=$rc_pid)." 668179870Smtm return 1 669179870Smtm fi 670179870Smtm 671179870Smtm if [ ! -x ${_chroot}${_chroot:+"/"}${command} ]; then 672179870Smtm warn "run_rc_command: cannot run $command" 673179870Smtm return 1 674179870Smtm fi 675179870Smtm 676175676Smtm _run_rc_precmd || return 1 677175676Smtm 67878344Sobrien # setup the full command to run 67978344Sobrien # 68078344Sobrien echo "Starting ${name}." 68178344Sobrien if [ -n "$_chroot" ]; then 68278344Sobrien _doit="\ 683165565Syar${_nice:+nice -n $_nice }\ 684165565Syarchroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ 685165565Syar$_chroot $command $rc_flags $command_args" 686165565Syar else 68778344Sobrien _doit="\ 688165565Syar${_chdir:+cd $_chdir && }\ 689165565Syar$command $rc_flags $command_args" 690165565Syar if [ -n "$_user" ]; then 691116097Smtm _doit="su -m $_user -c 'sh -c \"$_doit\"'" 69278344Sobrien fi 69378344Sobrien if [ -n "$_nice" ]; then 69498186Sgordon if [ -z "$_user" ]; then 69578344Sobrien _doit="sh -c \"$_doit\"" 69678344Sobrien fi 697165565Syar _doit="nice -n $_nice $_doit" 69898186Sgordon fi 69998186Sgordon fi 70078344Sobrien 70178344Sobrien # run the full command 70278344Sobrien # 70378344Sobrien _run_rc_doit "$_doit" || return 1 704165565Syar 70578344Sobrien # finally, run postcmd 70678344Sobrien # 70778344Sobrien _run_rc_postcmd 708131135Smtm ;; 709157473Sflz 710153152Syar stop) 71178344Sobrien if [ -z "$rc_pid" ]; then 71278344Sobrien [ -n "$rc_fast" ] && return 0 713167413Syar _run_rc_notrunning 714160667Syar return 1 715153152Syar fi 71678344Sobrien 71778344Sobrien _run_rc_precmd || return 1 718179946Smtm 719179946Smtm # send the signal to stop 720179946Smtm # 721179946Smtm echo "Stopping ${name}." 72278344Sobrien _doit=$(_run_rc_killcmd "${sig_stop:-TERM}") 723160668Syar _run_rc_doit "$_doit" || return 1 72478344Sobrien 725197947Sdougb # wait for the command to exit, 72678344Sobrien # and run postcmd. 72778344Sobrien wait_for_pids $rc_pid 72878344Sobrien 72978344Sobrien _run_rc_postcmd 73098186Sgordon ;; 73178344Sobrien 73278344Sobrien reload) 733161396Syar if [ -z "$rc_pid" ]; then 73498186Sgordon _run_rc_notrunning 73598186Sgordon return 1 73698186Sgordon fi 73798186Sgordon 738161396Syar _run_rc_precmd || return 1 739161396Syar 740161396Syar _doit=$(_run_rc_killcmd "${sig_reload:-HUP}") 741161396Syar _run_rc_doit "$_doit" || return 1 742161396Syar 743161396Syar _run_rc_postcmd 74478344Sobrien ;; 74598186Sgordon 746165565Syar restart) 74798186Sgordon # prevent restart being called more 748179946Smtm # than once by any given script 749179946Smtm # 750179946Smtm if ${_rc_restart_done:-false}; then 751179946Smtm return 0 75298186Sgordon fi 75398186Sgordon _rc_restart_done=true 75498186Sgordon 755165565Syar _run_rc_precmd || return 1 75678344Sobrien 75778344Sobrien # run those in a subshell to keep global variables 75878344Sobrien ( run_rc_command ${_rc_prefix}stop $rc_extra_args ) 75998186Sgordon ( run_rc_command ${_rc_prefix}start $rc_extra_args ) 760153152Syar _return=$? 761165565Syar [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 762153152Syar 76378344Sobrien _run_rc_postcmd 76478344Sobrien ;; 765165565Syar 76698186Sgordon poll) 76798186Sgordon _run_rc_precmd || return 1 76898186Sgordon if [ -n "$rc_pid" ]; then 76978344Sobrien wait_for_pids $rc_pid 770165565Syar fi 771165565Syar _run_rc_postcmd 77298186Sgordon ;; 77398186Sgordon 77498186Sgordon rcvar) 77598186Sgordon echo "# $name" 776165565Syar if [ -n "$rcvar" ]; then 777165565Syar if checkyesno ${rcvar}; then 77878344Sobrien echo "${rcvar}=YES" 77978344Sobrien else 78078344Sobrien echo "${rcvar}=NO" 78198186Sgordon fi 782165565Syar fi 783153152Syar ;; 78478344Sobrien 785165565Syar *) 786165565Syar rc_usage $_keywords 787165565Syar ;; 788165565Syar 789165565Syar esac 790165565Syar return $_return 791165565Syar done 79278344Sobrien 79378344Sobrien echo 1>&2 "$0: unknown directive '$rc_arg'." 79478344Sobrien rc_usage $_keywords 79578344Sobrien # not reached 79678344Sobrien} 79778344Sobrien 798126285Smtm# 79978344Sobrien# Helper functions for run_rc_command: common code. 80078344Sobrien# They use such global variables besides the exported rc_* ones: 801126285Smtm# 80278344Sobrien# name R/W 803165565Syar# ------------------ 804165565Syar# _precmd R 805165565Syar# _postcmd R 806152519Syar# _return W 807165565Syar# 808165565Syar_run_rc_precmd() 809165565Syar{ 81098186Sgordon check_required_before "$rc_arg" || return 1 811165565Syar 81278344Sobrien if [ -n "$_precmd" ]; then 81378344Sobrien debug "run_rc_command: ${rc_arg}_precmd: $_precmd $rc_extra_args" 81498186Sgordon eval "$_precmd $rc_extra_args" 815165565Syar _return=$? 81698186Sgordon 81798186Sgordon # If precmd failed and force isn't set, request exit. 81898186Sgordon if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then 819165565Syar return 1 82098186Sgordon fi 82198186Sgordon fi 82278344Sobrien 823197144Shrs check_required_after "$rc_arg" || return 1 824197144Shrs 825197144Shrs return 0 826197144Shrs} 827197144Shrs 828197144Shrs_run_rc_postcmd() 829197144Shrs{ 830197144Shrs if [ -n "$_postcmd" ]; then 831197144Shrs debug "run_rc_command: ${rc_arg}_postcmd: $_postcmd $rc_extra_args" 832197144Shrs eval "$_postcmd $rc_extra_args" 833197144Shrs _return=$? 834197144Shrs fi 835197144Shrs return 0 836197144Shrs} 837197144Shrs 838197144Shrs_run_rc_doit() 839197144Shrs{ 840197144Shrs debug "run_rc_command: doit: $*" 841197144Shrs eval "$@" 84278344Sobrien _return=$? 843197144Shrs 844197144Shrs # If command failed and force isn't set, request exit. 845197144Shrs if [ $_return -ne 0 ] && [ -z "$rc_force" ]; then 846197144Shrs return 1 847197144Shrs fi 848197144Shrs 849197144Shrs return 0 850197144Shrs} 851197144Shrs 852197144Shrs_run_rc_notrunning() 853197144Shrs{ 854197144Shrs local _pidmsg 855197144Shrs 856197144Shrs if [ -n "$pidfile" ]; then 857197144Shrs _pidmsg=" (check $pidfile)." 858197144Shrs else 859197144Shrs _pidmsg= 860197144Shrs fi 861197144Shrs echo 1>&2 "${name} not running?${_pidmsg}" 862197144Shrs} 863197144Shrs 864197144Shrs_run_rc_killcmd() 865197144Shrs{ 86678344Sobrien local _cmd 86778344Sobrien 86878344Sobrien _cmd="kill -$1 $rc_pid" 869150796Syar if [ -n "$_user" ]; then 87078344Sobrien _cmd="su -m ${_user} -c 'sh -c \"${_cmd}\"'" 87178344Sobrien fi 87278344Sobrien echo "$_cmd" 873116097Smtm} 87478344Sobrien 87578344Sobrien# 87698186Sgordon# run_rc_script file arg 877150796Syar# Start the script `file' with `arg', and correctly handle the 878153152Syar# return value from the script. If `file' ends with `.sh', it's 87978344Sobrien# sourced into the current environment. If `file' appears to be 88078344Sobrien# a backup or scratch file, ignore it. Otherwise if it's 88178344Sobrien# executable run as a child process. 882165565Syar# 883165565Syarrun_rc_script() 884165565Syar{ 885165565Syar _file=$1 886165565Syar _arg=$2 887165565Syar if [ -z "$_file" -o -z "$_arg" ]; then 888165565Syar err 3 'USAGE: run_rc_script file arg' 889165565Syar fi 890165565Syar 891165565Syar unset name command command_args command_interpreter \ 892165565Syar extra_commands pidfile procname \ 893165565Syar rcvar required_dirs required_files required_vars 894165565Syar eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd 895165565Syar 896165565Syar case "$_file" in 897165565Syar /etc/rc.d/*.sh) # run in current shell 898165565Syar set $_arg; . $_file 899165565Syar ;; 900165565Syar *[~#]|*.OLD|*.bak|*.orig|*,v) # scratch file; skip 901165565Syar warn "Ignoring scratch file $_file" 902165565Syar ;; 903165565Syar *) # run in subshell 904165565Syar if [ -x $_file ]; then 905165565Syar if [ -n "$rc_fast_and_loose" ]; then 906165565Syar set $_arg; . $_file 907165565Syar else 908165565Syar ( trap "echo Script $_file interrupted; kill -QUIT $$" 3 909165565Syar trap "echo Script $_file interrupted; exit 1" 2 910165565Syar set $_arg; . $_file ) 911165565Syar fi 912165565Syar fi 913165565Syar ;; 914165565Syar esac 915165565Syar} 916165565Syar 917165565Syar# 918165565Syar# load_rc_config name 919165565Syar# Source in the configuration file for a given name. 920165565Syar# 921165565Syarload_rc_config() 922165565Syar{ 923165565Syar _name=$1 924165565Syar if [ -z "$_name" ]; then 925165565Syar err 3 'USAGE: load_rc_config name' 926165565Syar fi 927165565Syar 928165565Syar if ${_rc_conf_loaded:-false}; then 929165565Syar : 930165565Syar else 931165565Syar if [ -r /etc/defaults/rc.conf ]; then 932165565Syar debug "Sourcing /etc/defaults/rc.conf" 933165565Syar . /etc/defaults/rc.conf 934165565Syar source_rc_confs 935165565Syar elif [ -r /etc/rc.conf ]; then 936165565Syar debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." 937165565Syar . /etc/rc.conf 938165565Syar fi 939165565Syar _rc_conf_loaded=true 940165565Syar fi 941165565Syar if [ -f /etc/rc.conf.d/"$_name" ]; then 942165565Syar debug "Sourcing /etc/rc.conf.d/${_name}" 943165565Syar . /etc/rc.conf.d/"$_name" 944165565Syar fi 945165565Syar} 946165565Syar 947165565Syar# 948165565Syar# load_rc_config_var name var 949165565Syar# Read the rc.conf(5) var for name and set in the 950165565Syar# current shell, using load_rc_config in a subshell to prevent 951165565Syar# unwanted side effects from other variable assignments. 952165565Syar# 953165565Syarload_rc_config_var() 954165565Syar{ 955165565Syar if [ $# -ne 2 ]; then 956165565Syar err 3 'USAGE: load_rc_config_var name var' 957165565Syar fi 958165565Syar eval $(eval '( 95978344Sobrien load_rc_config '$1' >/dev/null; 96078344Sobrien if [ -n "${'$2'}" -o "${'$2'-UNSET}" != "UNSET" ]; then 96178344Sobrien echo '$2'=\'\''${'$2'}\'\''; 96298186Sgordon fi 96398186Sgordon )' ) 96498186Sgordon} 96578344Sobrien 96678344Sobrien# 96778344Sobrien# rc_usage commands 96878344Sobrien# Print a usage string for $0, with `commands' being a list of 96978344Sobrien# valid commands. 97078344Sobrien# 97178344Sobrienrc_usage() 97278344Sobrien{ 97378344Sobrien echo -n 1>&2 "Usage: $0 [fast|force|one](" 97498186Sgordon 97598186Sgordon _sep= 976197144Shrs for _elem; do 977197144Shrs echo -n 1>&2 "$_sep$_elem" 97898186Sgordon _sep="|" 97998186Sgordon done 98078344Sobrien echo 1>&2 ")" 981193118Sdougb exit 1 982193118Sdougb} 98378344Sobrien 984153105Sdougb# 98598186Sgordon# err exitval message 98698186Sgordon# Display message to stderr and log to the syslog, and exit with exitval. 98778344Sobrien# 98898186Sgordonerr() 98998186Sgordon{ 990146490Sschweikh exitval=$1 99198186Sgordon shift 992130161Smtm 993130161Smtm if [ -x /usr/bin/logger ]; then 994184317Sthompsa logger "$0: ERROR: $*" 995146490Sschweikh fi 99698186Sgordon echo 1>&2 "$0: ERROR: $*" 99798186Sgordon exit $exitval 99878344Sobrien} 99978344Sobrien 100078344Sobrien# 100178344Sobrien# warn message 100278344Sobrien# Display message to stderr and log to the syslog. 1003157653Sflz# 1004157653Sflzwarn() 100578344Sobrien{ 100678344Sobrien if [ -x /usr/bin/logger ]; then 100778344Sobrien logger "$0: WARNING: $*" 1008197144Shrs fi 1009157653Sflz echo 1>&2 "$0: WARNING: $*" 1010157653Sflz} 1011157653Sflz 101278344Sobrien# 101378344Sobrien# info message 1014126285Smtm# Display informational message to stdout and log to syslog. 1015126285Smtm# 1016126285Smtminfo() 101798186Sgordon{ 101898186Sgordon case ${rc_info} in 101998186Sgordon [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 102098186Sgordon if [ -x /usr/bin/logger ]; then 102198186Sgordon logger "$0: INFO: $*" 102298186Sgordon fi 102398186Sgordon echo "$0: INFO: $*" 102498186Sgordon ;; 1025126285Smtm esac 102698186Sgordon} 1027161530Sflz 1028157653Sflz# 1029161530Sflz# debug message 1030157653Sflz# If debugging is enabled in rc.conf output message to stderr. 1031179872Smtm# BEWARE that you don't call any subroutine that itself calls this 1032179872Smtm# function. 1033179872Smtm# 1034179872Smtmdebug() 1035197144Shrs{ 1036197144Shrs case ${rc_debug} in 1037197144Shrs [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 1038197144Shrs if [ -x /usr/bin/logger ]; then 1039197144Shrs logger "$0: DEBUG: $*" 1040197144Shrs fi 1041197144Shrs echo 1>&2 "$0: DEBUG: $*" 1042197144Shrs ;; 1043197144Shrs esac 1044197144Shrs} 1045197144Shrs 1046197144Shrs# 1047197144Shrs# backup_file action file cur backup 1048197144Shrs# Make a backup copy of `file' into `cur', and save the previous 1049197144Shrs# version of `cur' as `backup' or use rcs for archiving. 1050197144Shrs# 1051197144Shrs# This routine checks the value of the backup_uses_rcs variable, 1052197144Shrs# which can be either YES or NO. 1053197144Shrs# 1054197144Shrs# The `action' keyword can be one of the following: 1055197144Shrs# 1056197144Shrs# add `file' is now being backed up (and is possibly 1057197144Shrs# being reentered into the backups system). `cur' 1058197144Shrs# is created and RCS files, if necessary, are 1059197144Shrs# created as well. 1060197144Shrs# 1061197144Shrs# update `file' has changed and needs to be backed up. 1062197144Shrs# If `cur' exists, it is copied to to `back' or 1063197144Shrs# checked into RCS (if the repository file is old), 1064197144Shrs# and then `file' is copied to `cur'. Another RCS 106578344Sobrien# check in done here if RCS is being used. 1066157473Sflz# 1067157473Sflz# remove `file' is no longer being tracked by the backups 1068157653Sflz# system. If RCS is not being used, `cur' is moved 1069157653Sflz# to `back', otherwise an empty file is checked in, 1070157473Sflz# and then `cur' is removed. 1071157473Sflz# 1072157473Sflz# 1073157473Sflzbackup_file() 1074157473Sflz{ 1075157473Sflz _action=$1 1076157653Sflz _file=$2 1077157473Sflz _cur=$3 1078157473Sflz _back=$4 1079157473Sflz 1080157473Sflz if checkyesno backup_uses_rcs; then 1081157473Sflz _msg0="backup archive" 1082157473Sflz _msg1="update" 1083157473Sflz 1084157473Sflz # ensure that history file is not locked 108578344Sobrien if [ -f $_cur,v ]; then 108678344Sobrien rcs -q -u -U -M $_cur 108778344Sobrien fi 108878344Sobrien 108978344Sobrien # ensure after switching to rcs that the 109078344Sobrien # current backup is not lost 109178344Sobrien if [ -f $_cur ]; then 109278344Sobrien # no archive, or current newer than archive 1093126303Smtm if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then 109478344Sobrien ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 109578344Sobrien rcs -q -kb -U $_cur 1096126286Smtm co -q -f -u $_cur 109778344Sobrien fi 109878344Sobrien fi 109978344Sobrien 110078344Sobrien case $_action in 110178344Sobrien add|update) 110278344Sobrien cp -p $_file $_cur 110378344Sobrien ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 110478344Sobrien rcs -q -kb -U $_cur 110578344Sobrien co -q -f -u $_cur 110678344Sobrien chown root:wheel $_cur $_cur,v 110778344Sobrien ;; 110878344Sobrien remove) 110978344Sobrien cp /dev/null $_cur 111078344Sobrien ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 111178344Sobrien rcs -q -kb -U $_cur 111278344Sobrien chown root:wheel $_cur $_cur,v 1113106643Sgordon rm $_cur 1114106643Sgordon ;; 1115106643Sgordon esac 1116106643Sgordon else 111778344Sobrien case $_action in 111878344Sobrien add|update) 111978344Sobrien if [ -f $_cur ]; then 112078344Sobrien cp -p $_cur $_back 112178344Sobrien fi 112278344Sobrien cp -p $_file $_cur 112378344Sobrien chown root:wheel $_cur 112478344Sobrien ;; 112578344Sobrien remove) 1126106643Sgordon mv -f $_cur $_back 1127106643Sgordon ;; 1128106643Sgordon esac 1129106643Sgordon fi 113078344Sobrien} 113198186Sgordon 113298186Sgordon# make_symlink src link 113398186Sgordon# Make a symbolic link 'link' to src from basedir. If the 113498186Sgordon# directory in which link is to be created does not exist 113598186Sgordon# a warning will be displayed and an error will be returned. 113698186Sgordon# Returns 0 on sucess, 1 otherwise. 113798186Sgordon# 1138119170Smtmmake_symlink() 1139119170Smtm{ 1140119170Smtm local src link linkdir _me 1141119170Smtm src="$1" 1142119170Smtm link="$2" 1143119170Smtm linkdir="`dirname $link`" 1144119170Smtm _me="make_symlink()" 1145119170Smtm 114698186Sgordon if [ -z "$src" -o -z "$link" ]; then 114798186Sgordon warn "$_me: requires two arguments." 114898186Sgordon return 1 114998186Sgordon fi 1150106643Sgordon if [ ! -d "$linkdir" ]; then 115198186Sgordon warn "$_me: the directory $linkdir does not exist." 115298186Sgordon return 1 115398186Sgordon fi 115498186Sgordon if ! ln -sf $src $link; then 115598186Sgordon warn "$_me: unable to make a symbolic link from $link to $src" 115698186Sgordon return 1 115798186Sgordon fi 1158106700Sgordon return 0 1159162947Syar} 1160106700Sgordon 1161146490Sschweikh# devfs_rulesets_from_file file 116298186Sgordon# Reads a set of devfs commands from file, and creates 116398186Sgordon# the specified rulesets with their rules. Returns non-zero 116498186Sgordon# if there was an error. 116598186Sgordon# 116698186Sgordondevfs_rulesets_from_file() 116798186Sgordon{ 116898186Sgordon local file _err _me 116998186Sgordon file="$1" 117098186Sgordon _me="devfs_rulesets_from_file" 117198186Sgordon _err=0 117298186Sgordon 117398186Sgordon if [ -z "$file" ]; then 117498186Sgordon warn "$_me: you must specify a file" 117598186Sgordon return 1 117698186Sgordon fi 117798186Sgordon if [ ! -e "$file" ]; then 117898186Sgordon debug "$_me: no such file ($file)" 117998186Sgordon return 0 118098186Sgordon fi 118198186Sgordon debug "reading rulesets from file ($file)" 118298186Sgordon { while read line 118398186Sgordon do 118498186Sgordon case $line in 118598186Sgordon \#*) 118698186Sgordon continue 118798186Sgordon ;; 118898186Sgordon \[*\]*) 118998186Sgordon rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` 119098186Sgordon if [ -z "$rulenum" ]; then 119198186Sgordon warn "$_me: cannot extract rule number ($line)" 119298186Sgordon _err=1 119398186Sgordon break 119498186Sgordon fi 119598186Sgordon rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` 119698186Sgordon if [ -z "$rulename" ]; then 119798186Sgordon warn "$_me: cannot extract rule name ($line)" 119898186Sgordon _err=1 119998186Sgordon break; 120098186Sgordon fi 120198186Sgordon eval $rulename=\$rulenum 120298186Sgordon debug "found ruleset: $rulename=$rulenum" 120398186Sgordon if ! /sbin/devfs rule -s $rulenum delset; then 120498186Sgordon _err=1 120598186Sgordon break 120698186Sgordon fi 120798186Sgordon ;; 120898186Sgordon *) 120998186Sgordon rulecmd="${line%%"\#*"}" 121098186Sgordon # evaluate the command incase it includes 121198186Sgordon # other rules 121298186Sgordon if [ -n "$rulecmd" ]; then 121398186Sgordon debug "adding rule ($rulecmd)" 121498186Sgordon if ! eval /sbin/devfs rule -s $rulenum $rulecmd 121598186Sgordon then 121698186Sgordon _err=1 121798186Sgordon break 121898186Sgordon fi 121998186Sgordon fi 122098186Sgordon ;; 122198186Sgordon esac 122298186Sgordon if [ $_err -ne 0 ]; then 122398186Sgordon debug "error in $_me" 122498186Sgordon break 122598186Sgordon fi 122698186Sgordon done } < $file 122798186Sgordon return $_err 122898186Sgordon} 122998186Sgordon 123098186Sgordon# devfs_init_rulesets 123198186Sgordon# Initializes rulesets from configuration files. Returns 123298186Sgordon# non-zero if there was an error. 123398186Sgordon# 123498186Sgordondevfs_init_rulesets() 123598186Sgordon{ 123698186Sgordon local file _me 123798186Sgordon _me="devfs_init_rulesets" 123898186Sgordon 123998186Sgordon # Go through this only once 124098186Sgordon if [ -n "$devfs_rulesets_init" ]; then 124198186Sgordon debug "$_me: devfs rulesets already initialized" 124298186Sgordon return 124398186Sgordon fi 124498186Sgordon for file in $devfs_rulesets; do 124598186Sgordon devfs_rulesets_from_file $file || return 1 124698186Sgordon done 124798186Sgordon devfs_rulesets_init=1 124898186Sgordon debug "$_me: devfs rulesets initialized" 124998186Sgordon return 0 125098186Sgordon} 1251119166Smtm 1252123344Smtm# devfs_set_ruleset ruleset [dir] 1253123344Smtm# Sets the default ruleset of dir to ruleset. The ruleset argument 1254123344Smtm# must be a ruleset name as specified in devfs.rules(5) file. 1255123344Smtm# Returns non-zero if it could not set it successfully. 1256123344Smtm# 1257119166Smtmdevfs_set_ruleset() 1258123344Smtm{ 1259119166Smtm local devdir rs _me 1260123344Smtm [ -n "$1" ] && eval rs=\$$1 || rs= 1261123344Smtm [ -n "$2" ] && devdir="-m "$2"" || devdir= 1262123344Smtm _me="devfs_set_ruleset" 1263123344Smtm 1264123344Smtm if [ -z "$rs" ]; then 1265119166Smtm warn "$_me: you must specify a ruleset number" 1266123344Smtm return 1 1267123344Smtm fi 1268119166Smtm debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" 1269119166Smtm if ! /sbin/devfs $devdir ruleset $rs; then 1270123344Smtm warn "$_me: unable to set ruleset $rs to ${devdir#-m }" 1271160667Syar return 1 1272119166Smtm fi 1273119166Smtm return 0 1274146490Sschweikh} 1275123344Smtm 1276119166Smtm# devfs_apply_ruleset ruleset [dir] 1277119166Smtm# Apply ruleset number $ruleset to the devfs mountpoint $dir. 1278119166Smtm# The ruleset argument must be a ruleset name as specified 1279119166Smtm# in a devfs.rules(5) file. Returns 0 on success or non-zero 1280119166Smtm# if it could not apply the ruleset. 1281119166Smtm# 1282119166Smtmdevfs_apply_ruleset() 1283119166Smtm{ 1284119166Smtm local devdir rs _me 1285119166Smtm [ -n "$1" ] && eval rs=\$$1 || rs= 1286119166Smtm [ -n "$2" ] && devdir="-m "$2"" || devdir= 1287119166Smtm _me="devfs_apply_ruleset" 1288119166Smtm 1289119166Smtm if [ -z "$rs" ]; then 1290119166Smtm warn "$_me: you must specify a ruleset" 1291119166Smtm return 1 1292119166Smtm fi 1293119166Smtm debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })" 1294119166Smtm if ! /sbin/devfs $devdir rule -s $rs applyset; then 1295119166Smtm warn "$_me: unable to apply ruleset $rs to ${devdir#-m }" 1296119166Smtm return 1 1297119166Smtm fi 1298119166Smtm return 0 1299119166Smtm} 1300119166Smtm 1301119166Smtm# devfs_domount dir [ruleset] 1302119166Smtm# Mount devfs on dir. If ruleset is specified it is set 1303119166Smtm# on the mount-point. It must also be a ruleset name as specified 1304119166Smtm# in a devfs.rules(5) file. Returns 0 on success. 1305119166Smtm# 1306119166Smtmdevfs_domount() 1307119166Smtm{ 1308119166Smtm local devdir rs _me 1309119166Smtm devdir="$1" 1310119166Smtm [ -n "$2" ] && rs=$2 || rs= 1311119166Smtm _me="devfs_domount()" 1312119166Smtm 1313119166Smtm if [ -z "$devdir" ]; then 1314119166Smtm warn "$_me: you must specify a mount-point" 1315119166Smtm return 1 1316119166Smtm fi 1317119166Smtm debug "$_me: mount-point is ($devdir), ruleset is ($rs)" 1318119166Smtm if ! mount -t devfs dev "$devdir"; then 1319119166Smtm warn "$_me: Unable to mount devfs on $devdir" 1320119166Smtm return 1 1321119166Smtm fi 1322119166Smtm if [ -n "$rs" ]; then 1323146490Sschweikh devfs_init_rulesets 1324119166Smtm devfs_set_ruleset $rs $devdir 1325119166Smtm devfs -m $devdir rule applyset 1326119166Smtm fi 1327119166Smtm return 0 1328119166Smtm} 1329119166Smtm 1330119166Smtm# devfs_mount_jail dir [ruleset] 1331119166Smtm# Mounts a devfs file system appropriate for jails 1332119166Smtm# on the directory dir. If ruleset is specified, the ruleset 1333119166Smtm# it names will be used instead. If present, ruleset must 1334119166Smtm# be the name of a ruleset as defined in a devfs.rules(5) file. 1335119166Smtm# This function returns non-zero if an error occurs. 1336119166Smtm# 1337119166Smtmdevfs_mount_jail() 1338119166Smtm{ 1339119166Smtm local jdev rs _me 1340119166Smtm jdev="$1" 1341119166Smtm [ -n "$2" ] && rs=$2 || rs="devfsrules_jail" 1342119166Smtm _me="devfs_mount_jail" 1343119166Smtm 1344119166Smtm devfs_init_rulesets 1345119166Smtm if ! devfs_domount "$jdev" $rs; then 1346119166Smtm warn "$_me: devfs was not mounted on $jdev" 1347119166Smtm return 1 1348119166Smtm fi 1349119166Smtm return 0 1350119166Smtm} 1351119166Smtm 1352119166Smtm# Provide a function for normalizing the mounting of memory 1353119166Smtm# filesystems. This should allow the rest of the code here to remain 1354119166Smtm# as close as possible between 5-current and 4-stable. 1355119166Smtm# $1 = size 1356119166Smtm# $2 = mount point 1357119166Smtm# $3 = (optional) extra mdmfs flags 1358119166Smtmmount_md() 1359119166Smtm{ 1360119166Smtm if [ -n "$3" ]; then 1361119166Smtm flags="$3" 1362119166Smtm fi 1363119166Smtm /sbin/mdmfs $flags -s $1 md $2 1364146490Sschweikh} 1365119166Smtm 1366119166Smtm# Code common to scripts that need to load a kernel module 1367119166Smtm# if it isn't in the kernel yet. Syntax: 1368119166Smtm# load_kld [-e regex] [-m module] file 1369119166Smtm# where -e or -m chooses the way to check if the module 1370119166Smtm# is already loaded: 1371119166Smtm# regex is egrep'd in the output from `kldstat -v', 1372119166Smtm# module is passed to `kldstat -m'. 1373151619Smaxim# The default way is as though `-m file' were specified. 1374119166Smtmload_kld() 1375119166Smtm{ 1376119166Smtm local _loaded _mod _opt _re 1377119166Smtm 1378119166Smtm while getopts "e:m:" _opt; do 1379119166Smtm case "$_opt" in 1380119166Smtm e) _re="$OPTARG" ;; 1381119166Smtm m) _mod="$OPTARG" ;; 1382119166Smtm *) err 3 'USAGE: load_kld [-e regex] [-m module] file' ;; 1383119166Smtm esac 1384119166Smtm done 1385119166Smtm shift $(($OPTIND - 1)) 1386119166Smtm if [ $# -ne 1 ]; then 1387119166Smtm err 3 'USAGE: load_kld [-e regex] [-m module] file' 1388119166Smtm fi 1389146490Sschweikh _mod=${_mod:-$1} 1390119166Smtm _loaded=false 1391119166Smtm if [ -n "$_re" ]; then 1392119166Smtm if kldstat -v | egrep -q -e "$_re"; then 1393119166Smtm _loaded=true 1394119166Smtm fi 1395119166Smtm else 1396119166Smtm if kldstat -q -m "$_mod"; then 1397119166Smtm _loaded=true 1398119166Smtm fi 1399119166Smtm fi 1400119166Smtm if ! $_loaded; then 1401119166Smtm if ! kldload "$1"; then 1402119166Smtm warn "Unable to load kernel module $1" 1403119166Smtm return 1 1404119166Smtm else 1405119166Smtm info "$1 kernel module loaded." 1406119166Smtm fi 1407119166Smtm else 1408119166Smtm debug "load_kld: $1 kernel module already loaded." 1409119166Smtm fi 1410119166Smtm return 0 1411119166Smtm} 1412119166Smtm 1413119166Smtm# ltr str src dst 1414146490Sschweikh# Change every $src in $str to $dst. 1415119166Smtm# Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor 1416119166Smtm# awk(1). 1417119166Smtmltr() 1418119166Smtm{ 1419119166Smtm local _str _src _dst _out _com 1420119166Smtm _str=$1 1421119166Smtm _src=$2 1422119166Smtm _dst=$3 1423119166Smtm _out="" 1424119166Smtm 1425119166Smtm IFS=${_src} 1426119166Smtm for _com in ${_str}; do 1427119166Smtm if [ -z "${_out}" ]; then 1428119166Smtm _out="${_com}" 1429119166Smtm else 1430119166Smtm _out="${_out}${_dst}${_com}" 1431119166Smtm fi 1432119166Smtm done 1433119166Smtm echo "${_out}" 1434119166Smtm} 1435119166Smtm 1436119166Smtm# Creates a list of providers for GELI encryption. 1437119166Smtmgeli_make_list() 1438146490Sschweikh{ 1439119166Smtm local devices devices2 1440119166Smtm local provider mountpoint type options rest 1441119166Smtm 1442119166Smtm # Create list of GELI providers from fstab. 1443119166Smtm while read provider mountpoint type options rest ; do 1444119166Smtm case ":${options}" in 1445124797Scperciva :*noauto*) 1446119166Smtm noauto=yes 1447119166Smtm ;; 1448119166Smtm *) 1449119166Smtm noauto=no 1450119166Smtm ;; 1451119166Smtm esac 1452119166Smtm 1453119166Smtm case ":${provider}" in 1454119166Smtm :#*) 1455119166Smtm continue 1456119166Smtm ;; 1457119166Smtm *.eli) 1458119166Smtm # Skip swap devices. 1459119166Smtm if [ "${type}" = "swap" -o "${options}" = "sw" -o "${noauto}" = "yes" ]; then 1460119166Smtm continue 1461119166Smtm fi 1462119166Smtm devices="${devices} ${provider}" 1463119166Smtm ;; 1464119166Smtm esac 1465146490Sschweikh done < /etc/fstab 1466119166Smtm 1467119166Smtm # Append providers from geli_devices. 1468119166Smtm devices="${devices} ${geli_devices}" 1469119166Smtm 1470119166Smtm for provider in ${devices}; do 1471127345Sbrooks provider=${provider%.eli} 1472127345Sbrooks provider=${provider#/dev/} 1473127345Sbrooks devices2="${devices2} ${provider}" 1474127345Sbrooks done 1475127345Sbrooks 1476127345Sbrooks echo ${devices2} 1477137451Skeramida} 1478146490Sschweikh 1479146490Sschweikh# Find scripts in local_startup directories that use the old syntax 1480127345Sbrooks# 1481137451Skeramidafind_local_scripts_old () { 1482127345Sbrooks zlist='' 1483149421Syar slist='' 1484127345Sbrooks for dir in ${local_startup}; do 1485131550Scperciva if [ -d "${dir}" ]; then 1486159828Syar for file in ${dir}/[0-9]*.sh; do 1487159828Syar grep '^# PROVIDE:' $file >/dev/null 2>&1 && 1488160666Syar continue 1489159828Syar zlist="$zlist $file" 1490159828Syar done 1491160666Syar for file in ${dir}/[^0-9]*.sh; do 1492160666Syar grep '^# PROVIDE:' $file >/dev/null 2>&1 && 1493160666Syar continue 1494159828Syar slist="$slist $file" 1495159828Syar done 1496159828Syar fi 1497159828Syar done 1498159828Syar} 1499159828Syar 1500159828Syarfind_local_scripts_new () { 1501159828Syar local_rc='' 1502160666Syar for dir in ${local_startup}; do 1503159828Syar if [ -d "${dir}" ]; then 1504159828Syar for file in `grep -l '^# PROVIDE:' ${dir}/* 2>/dev/null`; do 1505159828Syar case "$file" in 1506160666Syar *.sample) ;; 1507160666Syar *) if [ -x "$file" ]; then 1508160666Syar local_rc="${local_rc} ${file}" 1509159828Syar fi 1510159828Syar ;; 1511159828Syar esac 1512159828Syar done 1513159828Syar fi 1514159828Syar done 1515159828Syar} 1516159828Syar 1517159828Syar# check_required_{before|after} command 1518159828Syar# Check for things required by the command before and after its precmd, 1519159828Syar# respectively. The two separate functions are needed because some 1520159828Syar# conditions should prevent precmd from being run while other things 1521159828Syar# depend on precmd having already been run. 1522159828Syar# 1523159828Syarcheck_required_before() 1524160666Syar{ 1525160666Syar local _f 1526159828Syar 1527160666Syar case "$1" in 1528160666Syar start) 1529159828Syar for _f in $required_vars; do 1530159828Syar if ! checkyesno $_f; then 1531159828Syar warn "\$${_f} is not enabled." 1532159828Syar if [ -z "$rc_force" ]; then 1533149049Spjd return 1 1534149049Spjd fi 1535149049Spjd fi 1536149049Spjd done 1537149049Spjd 1538149049Spjd for _f in $required_dirs; do 1539149049Spjd if [ ! -d "${_f}/." ]; then 1540149049Spjd warn "${_f} is not a directory." 1541149049Spjd if [ -z "$rc_force" ]; then 1542149049Spjd return 1 1543149049Spjd fi 1544149049Spjd fi 1545149049Spjd done 1546149049Spjd 1547149049Spjd for _f in $required_files; do 1548149049Spjd if [ ! -r "${_f}" ]; then 1549149049Spjd warn "${_f} is not readable." 1550149049Spjd if [ -z "$rc_force" ]; then 1551149049Spjd return 1 1552149049Spjd fi 1553149049Spjd fi 1554149049Spjd done 1555149049Spjd ;; 1556149050Spjd esac 1557149050Spjd 1558149050Spjd return 0 1559149050Spjd} 1560149050Spjd 1561149050Spjdcheck_required_after() 1562149050Spjd{ 1563149050Spjd local _f _args 1564155570Sflz 1565155570Sflz case "$1" in 1566155570Sflz start) 1567155570Sflz for _f in $required_modules; do 1568155570Sflz case "${_f}" in 1569155570Sflz *~*) _args="-e ${_f#*~} ${_f%%~*}" ;; 1570155570Sflz *:*) _args="-m ${_f#*:} ${_f%%:*}" ;; 1571155570Sflz *) _args="${_f}" ;; 1572155570Sflz esac 1573149050Spjd if ! load_kld ${_args}; then 1574149050Spjd if [ -z "$rc_force" ]; then 1575149050Spjd return 1 1576149050Spjd fi 1577149050Spjd fi 1578149050Spjd done 1579155570Sflz ;; 1580149050Spjd esac 1581149050Spjd 1582149050Spjd return 0 1583149050Spjd} 1584149050Spjd 1585149050Spjdfi 1586149050Spjd 1587149050Spjd_rc_subr_loaded=: 1588149050Spjd