rc.subr revision 119170
1195534Sscottl# $NetBSD: rc.subr,v 1.49 2002/05/21 12:31:01 lukem Exp $ 2195534Sscottl# $FreeBSD: head/etc/rc.subr 119170 2003-08-20 06:50:34Z mtm $ 3195534Sscottl# 4195534Sscottl# Copyright (c) 1997-2002 The NetBSD Foundation, Inc. 5195534Sscottl# All rights reserved. 6195534Sscottl# 7195534Sscottl# This code is derived from software contributed to The NetBSD Foundation 8195534Sscottl# by Luke Mewburn. 9195534Sscottl# 10195534Sscottl# Redistribution and use in source and binary forms, with or without 11195534Sscottl# modification, are permitted provided that the following conditions 12195534Sscottl# are met: 13195534Sscottl# 1. Redistributions of source code must retain the above copyright 14195534Sscottl# notice, this list of conditions and the following disclaimer. 15195534Sscottl# 2. Redistributions in binary form must reproduce the above copyright 16195534Sscottl# notice, this list of conditions and the following disclaimer in the 17195534Sscottl# documentation and/or other materials provided with the distribution. 18195534Sscottl# 3. All advertising materials mentioning features or use of this software 19195534Sscottl# must display the following acknowledgement: 20195534Sscottl# This product includes software developed by the NetBSD 21195534Sscottl# Foundation, Inc. and its contributors. 22195534Sscottl# 4. Neither the name of The NetBSD Foundation nor the names of its 23195534Sscottl# contributors may be used to endorse or promote products derived 24195534Sscottl# from this software without specific prior written permission. 25195534Sscottl# 26195534Sscottl# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27195534Sscottl# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28195534Sscottl# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29195534Sscottl# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30195534Sscottl# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31195534Sscottl# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32195534Sscottl# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33195534Sscottl# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34195534Sscottl# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35195534Sscottl# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36195534Sscottl# POSSIBILITY OF SUCH DAMAGE. 37195534Sscottl# 38195534Sscottl# rc.subr 39195534Sscottl# functions used by various rc scripts 40195534Sscottl# 41195534Sscottl 42195534Sscottl# 43195534Sscottl# Operating System dependent/independent variables 44195534Sscottl# 45195534Sscottl 46195534SscottlSYSCTL="/sbin/sysctl" 47195534SscottlSYSCTL_N="${SYSCTL} -n" 48195534SscottlCMD_OSTYPE="${SYSCTL_N} kern.ostype" 49195534SscottlOSTYPE=`${CMD_OSTYPE}` 50195534Sscottl 51195534Sscottlcase ${OSTYPE} in 52195534SscottlFreeBSD) 53195534Sscottl SYSCTL_W="${SYSCTL}" 54195534Sscottl ;; 55195534SscottlNetBSD) 56195534Sscottl SYSCTL_W="${SYSCTL} -w" 57195534Sscottl ;; 58195534Sscottlesac 59195534Sscottl 60195534Sscottl# 61195534Sscottl# functions 62195534Sscottl# --------- 63195534Sscottl 64195534Sscottl# 65195534Sscottl# set_rcvar base_var 66195534Sscottl# Set the variable name enabling a specific service. 67195534Sscottl# FreeBSD uses ${service}_enable, while NetBSD uses 68195534Sscottl# just the name of the service. For example: 69195534Sscottl# FreeBSD: sendmail_enable="YES" 70195534Sscottl# NetBSD : sendmail="YES" 71216088Sken# $1 - if $name is not the base to work of off, specify 72195534Sscottl# a different one 73195534Sscottl# 74208911Smjacobset_rcvar() 75195534Sscottl{ 76195534Sscottl if [ -z "$1" ]; then 77195534Sscottl base_var=${name} 78195534Sscottl else 79195534Sscottl base_var="$1" 80195534Sscottl fi 81195534Sscottl 82195534Sscottl case ${OSTYPE} in 83195534Sscottl FreeBSD) 84195534Sscottl echo ${base_var}_enable 85195534Sscottl ;; 86195534Sscottl NetBSD) 87195534Sscottl echo ${base_var} 88208911Smjacob ;; 89208911Smjacob *) 90208911Smjacob echo 'XXX' 91208911Smjacob ;; 92208911Smjacob esac 93208911Smjacob} 94208911Smjacob 95208911Smjacob# 96208911Smjacob# force_depend script 97208911Smjacob# Force a service to start. Intended for use by services 98208911Smjacob# to resolve dependency issues. It is assumed the caller 99208911Smjacob# has check to make sure this call is necessary 100208911Smjacob# $1 - filename of script, in /etc/rc.d, to run 101208911Smjacob# 102208911Smjacobforce_depend() 103195534Sscottl{ 104195534Sscottl _depend="$1" 105195534Sscottl 106195534Sscottl info "${name} depends on ${_depend}, which will be forced to start." 107195534Sscottl if ! /etc/rc.d/${_depend} forcestart ; then 108195534Sscottl warn "Unable to force ${_depend}. It may already be running." 109195534Sscottl return 1 110195534Sscottl fi 111195534Sscottl return 0 112195534Sscottl} 113195534Sscottl 114195534Sscottl# 115195534Sscottl# checkyesno var 116195534Sscottl# Test $1 variable, and warn if not set to YES or NO. 117195534Sscottl# Return 0 if it's "yes" (et al), nonzero otherwise. 118195534Sscottl# 119195534Sscottlcheckyesno() 120195534Sscottl{ 121195534Sscottl eval _value=\$${1} 122195534Sscottl debug "checkyesno: $1 is set to $_value." 123195534Sscottl case $_value in 124195534Sscottl 125198708Smav # "yes", "true", "on", or "1" 126198708Smav [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 127195534Sscottl return 0 128195534Sscottl ;; 129195534Sscottl 130195534Sscottl # "no", "false", "off", or "0" 131195534Sscottl [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) 132195534Sscottl return 1 133195534Sscottl ;; 134195534Sscottl *) 135208911Smjacob warn "\$${1} is not set properly - see rc.conf(5)." 136195534Sscottl return 1 137216088Sken ;; 138216088Sken esac 139216088Sken} 140195534Sscottl 141195534Sscottl# reverse_list list 142195534Sscottl# print the list in reverse order 143195534Sscottl# 144236613Smavreverse_list() 145195534Sscottl{ 146195534Sscottl _revlist= 147195534Sscottl for _revfile in $*; do 148195534Sscottl _revlist="$_revfile $_revlist" 149195534Sscottl done 150195534Sscottl echo $_revlist 151195534Sscottl} 152208911Smjacob 153195534Sscottl# 154216088Sken# mount_critical_filesystems type 155216088Sken# Go through the list of critical filesystems as provided in 156216088Sken# the rc.conf(5) variable $critical_filesystems_${type}, checking 157195534Sscottl# each one to see if it is mounted, and if it is not, mounting it. 158195534Sscottl# 159195534Sscottlmount_critical_filesystems() 160195534Sscottl{ 161236613Smav eval _fslist=\$critical_filesystems_${1} 162195534Sscottl for _fs in $_fslist; do 163195534Sscottl mount | ( 164195534Sscottl _ismounted=no 165195534Sscottl while read what _on on _type type; do 166195534Sscottl if [ $on = $_fs ]; then 167195534Sscottl _ismounted=yes 168195534Sscottl fi 169236613Smav done 170195534Sscottl if [ $_ismounted = no ]; then 171195534Sscottl mount $_fs >/dev/null 2>&1 172195534Sscottl fi 173195534Sscottl ) 174195534Sscottl done 175195534Sscottl} 176195534Sscottl 177195534Sscottl# 178195534Sscottl# check_pidfile pidfile procname [interpreter] 179195534Sscottl# Parses the first line of pidfile for a PID, and ensures 180195534Sscottl# that the process is running and matches procname. 181195534Sscottl# Prints the matching PID upon success, nothing otherwise. 182195534Sscottl# interpreter is optional; see _find_processes() for details. 183195534Sscottl# 184195534Sscottlcheck_pidfile() 185195534Sscottl{ 186195534Sscottl _pidfile=$1 187195534Sscottl _procname=$2 188195534Sscottl _interpreter=$3 189195534Sscottl if [ -z "$_pidfile" -o -z "$_procname" ]; then 190195534Sscottl err 3 'USAGE: check_pidfile pidfile procname [interpreter]' 191195534Sscottl fi 192195534Sscottl if [ ! -f $_pidfile ]; then 193195534Sscottl debug "pid file {$_pidfile): not readable." 194195534Sscottl return 195195534Sscottl fi 196195534Sscottl read _pid _junk < $_pidfile 197195534Sscottl if [ -z "$_pid" ]; then 198195534Sscottl debug "pid file {$_pidfile): no pid in file." 199195534Sscottl return 200195534Sscottl fi 201195534Sscottl _find_processes $_procname ${_interpreter:-.} '-p '"$_pid" 202195534Sscottl} 203195534Sscottl 204195534Sscottl# 205195534Sscottl# check_process procname [interpreter] 206195534Sscottl# Ensures that a process (or processes) named procname is running. 207195534Sscottl# Prints a list of matching PIDs. 208195534Sscottl# interpreter is optional; see _find_processes() for details. 209195534Sscottl# 210195534Sscottlcheck_process() 211195534Sscottl{ 212195534Sscottl _procname=$1 213195534Sscottl _interpreter=$2 214195534Sscottl if [ -z "$_procname" ]; then 215195534Sscottl err 3 'USAGE: check_process procname [interpreter]' 216195534Sscottl fi 217195534Sscottl _find_processes $_procname ${_interpreter:-.} '-ax' 218195534Sscottl} 219195534Sscottl 220195534Sscottl# 221195534Sscottl# _find_processes procname interpreter psargs 222195534Sscottl# Search for procname in the output of ps generated by psargs. 223195534Sscottl# Prints the PIDs of any matching processes, space separated. 224195534Sscottl# 225195534Sscottl# If interpreter == ".", check the following variations of procname 226195534Sscottl# against the first word of each command: 227195534Sscottl# procname 228195534Sscottl# `basename procname` 229195534Sscottl# `basename procname` + ":" 230195534Sscottl# "(" + `basename procname` + ")" 231195534Sscottl# 232195534Sscottl# If interpreter != ".", read the first line of procname, remove the 233195534Sscottl# leading #!, normalise whitespace, append procname, and attempt to 234195534Sscottl# match that against each command, either as is, or with extra words 235195534Sscottl# at the end. 236195534Sscottl# 237195534Sscottl_find_processes() 238195534Sscottl{ 239195534Sscottl if [ $# -ne 3 ]; then 240195534Sscottl err 3 'USAGE: _find_processes procname interpreter psargs' 241195534Sscottl fi 242195534Sscottl _procname=$1 243195534Sscottl _interpreter=$2 244195534Sscottl _psargs=$3 245195534Sscottl 246195534Sscottl _pref= 247195534Sscottl if [ $_interpreter != "." ]; then # an interpreted script 248195534Sscottl read _interp < $_procname # read interpreter name 249195534Sscottl _interp=${_interp#\#!} # strip #! 250195534Sscottl set -- $_interp 251195534Sscottl if [ $_interpreter != $1 ]; then 252195534Sscottl warn "\$command_interpreter $_interpreter != $1" 253195534Sscottl fi 254195534Sscottl _interp="$* $_procname" # cleanup spaces, add _procname 255195534Sscottl _fp_args='_argv' 256195534Sscottl _fp_match='case "$_argv" in 257195534Sscottl ${_interp}|"${_interp} "*)' 258195534Sscottl else # a normal daemon 259195534Sscottl _procnamebn=${_procname##*/} 260195534Sscottl _fp_args='_arg0 _argv' 261195534Sscottl _fp_match='case "$_arg0" in 262195534Sscottl $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})")' 263195534Sscottl fi 264195534Sscottl 265195534Sscottl _proccheck=' 266195534Sscottl ps -o "pid,command" '"$_psargs"' | 267195534Sscottl while read _npid '"$_fp_args"'; do 268195534Sscottl case "$_npid" in 269195534Sscottl PID) 270195534Sscottl continue ;; 271195534Sscottl esac ; '"$_fp_match"' 272195534Sscottl echo -n "$_pref$_npid" ; 273195534Sscottl _pref=" " 274195534Sscottl ;; 275195534Sscottl esac 276195534Sscottl done' 277195534Sscottl 278195534Sscottl# debug "in _find_processes: proccheck is ($_proccheck)." 279195534Sscottl eval $_proccheck 280195534Sscottl} 281195534Sscottl 282195534Sscottl# 283195534Sscottl# wait_for_pids pid [pid ...] 284195534Sscottl# spins until none of the pids exist 285195534Sscottl# 286195534Sscottlwait_for_pids() 287195534Sscottl{ 288195534Sscottl _list=$* 289195534Sscottl if [ -z "$_list" ]; then 290195534Sscottl return 291195534Sscottl fi 292195534Sscottl _prefix= 293195534Sscottl while true; do 294195534Sscottl _nlist=""; 295195534Sscottl for _j in $_list; do 296195534Sscottl if kill -0 $_j 2>/dev/null; then 297195534Sscottl _nlist="${_nlist}${_nlist:+ }$_j" 298195534Sscottl fi 299195534Sscottl done 300231745Sgibbs if [ -z "$_nlist" ]; then 301231745Sgibbs break 302231745Sgibbs fi 303231745Sgibbs _list=$_nlist 304231745Sgibbs echo -n ${_prefix:-"Waiting for PIDS: "}$_list 305231745Sgibbs _prefix=", " 306231745Sgibbs sleep 2 307231745Sgibbs done 308195534Sscottl if [ -n "$_prefix" ]; then 309195534Sscottl echo "." 310195534Sscottl fi 311195534Sscottl} 312195534Sscottl 313195534Sscottl# 314195534Sscottl# run_rc_command argument 315195534Sscottl# Search for argument in the list of supported commands, which is: 316195534Sscottl# "start stop restart rcvar status poll ${extra_commands}" 317195534Sscottl# If there's a match, run ${argument}_cmd or the default method 318195534Sscottl# (see below). 319195534Sscottl# 320195534Sscottl# If argument has a given prefix, then change the operation as follows: 321195534Sscottl# Prefix Operation 322195534Sscottl# ------ --------- 323195534Sscottl# fast Skip the pid check, and set rc_fast=yes 324195534Sscottl# force Set ${rcvar} to YES, and set rc_force=yes 325195534Sscottl# 326195534Sscottl# The following globals are used: 327195534Sscottl# 328195534Sscottl# Name Needed Purpose 329195534Sscottl# ---- ------ ------- 330195534Sscottl# name y Name of script. 331195534Sscottl# 332195534Sscottl# command n Full path to command. 333195534Sscottl# Not needed if ${rc_arg}_cmd is set for 334195534Sscottl# each keyword. 335195534Sscottl# 336195534Sscottl# command_args n Optional args/shell directives for command. 337195534Sscottl# 338195534Sscottl# command_interpreter n If not empty, command is interpreted, so 339195534Sscottl# call check_{pidfile,process}() appropriately. 340195534Sscottl# 341195534Sscottl# extra_commands n List of extra commands supported. 342195534Sscottl# 343195534Sscottl# pidfile n If set, use check_pidfile $pidfile $command, 344195534Sscottl# otherwise use check_process $command. 345195534Sscottl# In either case, only check if $command is set. 346195534Sscottl# 347195534Sscottl# procname n Process name to check for instead of $command. 348195534Sscottl# 349195534Sscottl# rcvar n This is checked with checkyesno to determine 350195534Sscottl# if the action should be run. 351195534Sscottl# 352195534Sscottl# ${name}_chroot n Directory to chroot to before running ${command} 353195534Sscottl# Requires /usr to be mounted. 354195534Sscottl# 355195534Sscottl# ${name}_chdir n Directory to cd to before running ${command} 356195534Sscottl# (if not using ${name}_chroot). 357195534Sscottl# 358195534Sscottl# ${name}_flags n Arguments to call ${command} with. 359195534Sscottl# NOTE: $flags from the parent environment 360195534Sscottl# can be used to override this. 361195534Sscottl# 362195534Sscottl# ${name}_nice n Nice level to run ${command} at. 363195534Sscottl# 364195534Sscottl# ${name}_user n User to run ${command} as, using su(1) if not 365195534Sscottl# using ${name}_chroot. 366195534Sscottl# Requires /usr to be mounted. 367195534Sscottl# 368195534Sscottl# ${name}_group n Group to run chrooted ${command} as. 369195534Sscottl# Requires /usr to be mounted. 370195534Sscottl# 371195534Sscottl# ${name}_groups n Comma separated list of supplementary groups 372195534Sscottl# to run the chrooted ${command} with. 373195534Sscottl# Requires /usr to be mounted. 374195534Sscottl# 375195534Sscottl# ${rc_arg}_cmd n If set, use this as the method when invoked; 376195534Sscottl# Otherwise, use default command (see below) 377195534Sscottl# 378195534Sscottl# ${rc_arg}_precmd n If set, run just before performing the 379195534Sscottl# ${rc_arg}_cmd method in the default 380195534Sscottl# operation (i.e, after checking for required 381195534Sscottl# bits and process (non)existence). 382195534Sscottl# If this completes with a non-zero exit code, 383195534Sscottl# don't run ${rc_arg}_cmd. 384195534Sscottl# 385195534Sscottl# ${rc_arg}_postcmd n If set, run just after performing the 386195534Sscottl# ${rc_arg}_cmd method, if that method 387195534Sscottl# returned a zero exit code. 388195534Sscottl# 389195534Sscottl# required_dirs n If set, check for the existence of the given 390195534Sscottl# directories before running the default 391195534Sscottl# (re)start command. 392195534Sscottl# 393195534Sscottl# required_files n If set, check for the readability of the given 394195534Sscottl# files before running the default (re)start 395195534Sscottl# command. 396195534Sscottl# 397195534Sscottl# required_vars n If set, perform checkyesno on each of the 398195534Sscottl# listed variables before running the default 399195534Sscottl# (re)start command. 400195534Sscottl# 401195534Sscottl# Default behaviour for a given argument, if no override method is 402195534Sscottl# provided: 403195534Sscottl# 404195534Sscottl# Argument Default behaviour 405195534Sscottl# -------- ----------------- 406195534Sscottl# start if !running && checkyesno ${rcvar} 407195534Sscottl# ${command} 408195534Sscottl# 409195534Sscottl# stop if ${pidfile} 410195534Sscottl# rc_pid=$(check_pidfile $pidfile $command) 411195534Sscottl# else 412195534Sscottl# rc_pid=$(check_process $command) 413195534Sscottl# kill $sig_stop $rc_pid 414195534Sscottl# wait_for_pids $rc_pid 415195534Sscottl# ($sig_stop defaults to TERM.) 416195534Sscottl# 417195534Sscottl# reload Similar to stop, except use $sig_reload instead, 418195534Sscottl# and doesn't wait_for_pids. 419195534Sscottl# $sig_reload defaults to HUP. 420195534Sscottl# 421195534Sscottl# restart Run `stop' then `start'. 422195534Sscottl# 423195534Sscottl# status Show if ${command} is running, etc. 424195534Sscottl# 425195534Sscottl# poll Wait for ${command} to exit. 426195534Sscottl# 427195534Sscottl# rcvar Display what rc.conf variable is used (if any). 428195534Sscottl# 429195534Sscottl# Variables available to methods, and after run_rc_command() has 430195534Sscottl# completed: 431195534Sscottl# 432195534Sscottl# Variable Purpose 433195534Sscottl# -------- ------- 434195534Sscottl# rc_arg Argument to command, after fast/force processing 435195534Sscottl# performed 436195534Sscottl# 437195534Sscottl# rc_flags Flags to start the default command with. 438195534Sscottl# Defaults to ${name}_flags, unless overridden 439195534Sscottl# by $flags from the environment. 440195534Sscottl# This variable may be changed by the precmd method. 441195534Sscottl# 442195534Sscottl# rc_pid PID of command (if appropriate) 443195534Sscottl# 444195534Sscottl# rc_fast Not empty if "fast" was provided (q.v.) 445195534Sscottl# 446195534Sscottl# rc_force Not empty if "force" was provided (q.v.) 447195534Sscottl# 448195534Sscottl# 449195534Sscottlrun_rc_command() 450195534Sscottl{ 451195534Sscottl _return=0 452195534Sscottl rc_arg=$1 453195534Sscottl if [ -z "$name" ]; then 454195534Sscottl err 3 'run_rc_command: $name is not set.' 455195534Sscottl fi 456195534Sscottl 457195534Sscottl case "$rc_arg" in 458195534Sscottl fast*) # "fast" prefix; don't check pid 459195534Sscottl rc_arg=${rc_arg#fast} 460195534Sscottl rc_fast=yes 461195534Sscottl ;; 462195534Sscottl force*) # "force prefix; always start 463195534Sscottl rc_arg=${rc_arg#force} 464195534Sscottl rc_force=yes 465195534Sscottl if [ -n "${rcvar}" ]; then 466195534Sscottl eval ${rcvar}=YES 467195534Sscottl fi 468195534Sscottl ;; 469195534Sscottl esac 470195534Sscottl 471195534Sscottl eval _overide_command=\$${name}_program 472195534Sscottl if [ -n "$_overide_command" ]; then 473195534Sscottl command=$_overide_command 474195534Sscottl fi 475195534Sscottl 476195534Sscottl _keywords="start stop restart rcvar $extra_commands" 477195534Sscottl rc_pid= 478216088Sken _pidcmd= 479195534Sscottl _procname=${procname:-${command}} 480195534Sscottl 481195534Sscottl # setup pid check command if not fast 482195534Sscottl if [ -z "$rc_fast" -a -n "$_procname" ]; then 483195534Sscottl if [ -n "$pidfile" ]; then 484195534Sscottl _pidcmd='rc_pid=$(check_pidfile '"$pidfile $_procname $command_interpreter"')' 485195534Sscottl else 486195534Sscottl _pidcmd='rc_pid=$(check_process '"$_procname $command_interpreter"')' 487195534Sscottl fi 488195534Sscottl if [ -n "$_pidcmd" ]; then 489195534Sscottl _keywords="${_keywords} status poll" 490195534Sscottl fi 491195534Sscottl fi 492195534Sscottl 493195534Sscottl if [ -z "$rc_arg" ]; then 494195534Sscottl rc_usage "$_keywords" 495195534Sscottl fi 496195534Sscottl 497195534Sscottl if [ -n "$flags" ]; then # allow override from environment 498195534Sscottl rc_flags=$flags 499195534Sscottl else 500195534Sscottl eval rc_flags=\$${name}_flags 501195534Sscottl fi 502195534Sscottl eval _chdir=\$${name}_chdir _chroot=\$${name}_chroot \ 503195534Sscottl _nice=\$${name}_nice _user=\$${name}_user \ 504195534Sscottl _group=\$${name}_group _groups=\$${name}_groups 505195534Sscottl 506195534Sscottl if [ -n "$_user" ]; then # unset $_user if running as that user 507195534Sscottl if [ "$_user" = "$(id -un)" ]; then 508195534Sscottl unset _user 509195534Sscottl fi 510195534Sscottl fi 511195534Sscottl 512195534Sscottl # if ${rcvar} is set, and $1 is not 513195534Sscottl # "rcvar", then run 514195534Sscottl # checkyesno ${rcvar} 515195534Sscottl # and return if that failed 516195534Sscottl # 517195534Sscottl if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then 518195534Sscottl if ! checkyesno ${rcvar}; then 519195534Sscottl return 0 520195534Sscottl fi 521195534Sscottl fi 522195534Sscottl 523195534Sscottl eval $_pidcmd # determine the pid if necessary 524195534Sscottl 525195534Sscottl for _elem in $_keywords; do 526195534Sscottl if [ "$_elem" != "$rc_arg" ]; then 527195534Sscottl continue 528195534Sscottl fi 529195534Sscottl 530195534Sscottl # if there's a custom ${XXX_cmd}, 531195534Sscottl # run that instead of the default 532195534Sscottl # 533195534Sscottl eval _cmd=\$${rc_arg}_cmd _precmd=\$${rc_arg}_precmd \ 534195534Sscottl _postcmd=\$${rc_arg}_postcmd 535195534Sscottl if [ -n "$_cmd" ]; then 536195534Sscottl # if the precmd failed and force 537195534Sscottl # isn't set, exit 538195534Sscottl # 539195534Sscottl if [ -n "$_precmd" ]; then 540236283Seadler debug "run_rc_command: evaluating ${_precmd}()." 541236283Seadler eval $_precmd 542236283Seadler _return=$? 543236283Seadler [ $_return -ne 0 ] && [ -z "$rc_force" ] && 544195534Sscottl return 1 545195534Sscottl fi 546195534Sscottl 547195534Sscottl if [ -n "$_cmd" ]; then 548195534Sscottl debug "run_rc_command: evaluating ${_cmd}()." 549195534Sscottl eval $_cmd 550195534Sscottl _return=$? 551195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && 552195534Sscottl return 1 553195534Sscottl fi 554195534Sscottl 555195534Sscottl if [ -n "$_postcmd" ]; then 556195534Sscottl debug "run_rc_command: evaluating ${_postcmd}()." 557195534Sscottl eval $_postcmd 558195534Sscottl _return=$? 559195534Sscottl fi 560195534Sscottl return $_return 561195534Sscottl fi 562195534Sscottl 563195534Sscottl case "$rc_arg" in # default operations... 564208911Smjacob 565208911Smjacob status) 566208911Smjacob if [ -n "$rc_pid" ]; then 567208911Smjacob echo "${name} is running as pid $rc_pid." 568195534Sscottl else 569195534Sscottl echo "${name} is not running." 570195534Sscottl return 1 571195534Sscottl fi 572195534Sscottl ;; 573195534Sscottl 574195534Sscottl start) 575195534Sscottl if [ -n "$rc_pid" ]; then 576195534Sscottl echo "${name} already running? (pid=$rc_pid)." 577195534Sscottl exit 1 578195534Sscottl fi 579195534Sscottl 580256843Smav if [ ! -x $command ]; then 581195534Sscottl info "run_rc_command: cannot run ($command)." 582195534Sscottl return 0 583195534Sscottl fi 584195534Sscottl 585195534Sscottl # check for required variables, 586195534Sscottl # directories, and files 587195534Sscottl # 588195534Sscottl for _f in $required_vars; do 589204220Smav if ! checkyesno $_f; then 590195534Sscottl warn "\$${_f} is not set." 591195534Sscottl if [ -z "$rc_force" ]; then 592195534Sscottl return 1 593195534Sscottl fi 594195534Sscottl fi 595204220Smav done 596195534Sscottl for _f in $required_dirs; do 597195534Sscottl if [ ! -d "${_f}/." ]; then 598195534Sscottl warn "${_f} is not a directory." 599195534Sscottl if [ -z "$rc_force" ]; then 600195534Sscottl return 1 601195534Sscottl fi 602195534Sscottl fi 603195534Sscottl done 604195534Sscottl for _f in $required_files; do 605195534Sscottl if [ ! -r "${_f}" ]; then 606195534Sscottl warn "${_f} is not readable." 607195534Sscottl if [ -z "$rc_force" ]; then 608195534Sscottl return 1 609195534Sscottl fi 610195534Sscottl fi 611195534Sscottl done 612195534Sscottl 613195534Sscottl # if the precmd failed and force 614195534Sscottl # isn't set, exit 615195534Sscottl # 616195534Sscottl if [ -n "${_precmd}" ]; then 617195534Sscottl debug "run_rc_command: evaluating ${_precmd}()." 618195534Sscottl eval $_precmd 619195534Sscottl _return=$? 620195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && 621195534Sscottl return 1 622195534Sscottl fi 623195534Sscottl 624195534Sscottl # setup the command to run, and run it 625195534Sscottl # 626195534Sscottl echo "Starting ${name}." 627195534Sscottl if [ -n "$_chroot" ]; then 628195534Sscottl _doit="\ 629195534Sscottl${_nice:+nice -n $_nice }\ 630195534Sscottlchroot ${_user:+-u $_user }${_group:+-g $_group }${_groups:+-G $_groups }\ 631195534Sscottl$_chroot $command $rc_flags $command_args" 632195534Sscottl else 633195534Sscottl _doit="\ 634195534Sscottl${_chdir:+cd $_chdir; }\ 635195534Sscottl${_nice:+nice -n $_nice }\ 636195534Sscottl$command $rc_flags $command_args" 637195534Sscottl if [ -n "$_user" ]; then 638195534Sscottl _doit="su -m $_user -c 'sh -c \"$_doit\"'" 639195534Sscottl fi 640195534Sscottl fi 641236613Smav 642256843Smav # if the cmd failed and force 643195534Sscottl # isn't set, exit 644195534Sscottl # 645195534Sscottl debug "run_rc_command: _doit: $_doit" 646195534Sscottl eval $_doit 647195534Sscottl _return=$? 648195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 649195534Sscottl 650195534Sscottl # finally, run postcmd 651195534Sscottl # 652195534Sscottl if [ -n "${_postcmd}" ]; then 653195534Sscottl debug "run_rc_command: evaluating ${_postcmd}()." 654195534Sscottl eval $_postcmd 655195534Sscottl fi 656195534Sscottl ;; 657195534Sscottl 658195534Sscottl stop) 659195534Sscottl if [ -z "$rc_pid" ]; then 660195534Sscottl if [ -n "$pidfile" ]; then 661195534Sscottl echo \ 662195534Sscottl "${name} not running? (check $pidfile)." 663195534Sscottl else 664195534Sscottl echo "${name} not running?" 665203108Smav fi 666195534Sscottl exit 1 667195534Sscottl fi 668195534Sscottl 669195534Sscottl # if the precmd failed and force 670195534Sscottl # isn't set, exit 671195534Sscottl # 672195534Sscottl if [ -n "$_precmd" ]; then 673195534Sscottl eval $_precmd 674195534Sscottl _return=$? 675195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && 676195534Sscottl return 1 677195534Sscottl fi 678195534Sscottl 679195534Sscottl # send the signal to stop 680195534Sscottl # 681195534Sscottl echo "Stopping ${name}." 682195534Sscottl _doit="kill -${sig_stop:-TERM} $rc_pid" 683195534Sscottl if [ -n "$_user" ]; then 684195534Sscottl _doit="su -m $_user -c 'sh -c \"$_doit\"'" 685195534Sscottl fi 686195534Sscottl 687195534Sscottl # if the stop cmd failed and force 688195534Sscottl # isn't set, exit 689195534Sscottl # 690195534Sscottl eval $_doit 691195534Sscottl _return=$? 692195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 693195534Sscottl 694195534Sscottl # wait for the command to exit, 695195534Sscottl # and run postcmd. 696195534Sscottl wait_for_pids $rc_pid 697195534Sscottl if [ -n "$_postcmd" ]; then 698195534Sscottl eval $_postcmd 699195534Sscottl _return=$? 700195534Sscottl fi 701195534Sscottl ;; 702195534Sscottl 703203108Smav reload) 704195534Sscottl if [ -z "$rc_pid" ]; then 705195534Sscottl if [ -n "$pidfile" ]; then 706195534Sscottl echo \ 707195534Sscottl "${name} not running? (check $pidfile)." 708195534Sscottl else 709195534Sscottl echo "${name} not running?" 710195534Sscottl fi 711195534Sscottl exit 1 712195534Sscottl fi 713195534Sscottl echo "Reloading ${name} config files." 714195534Sscottl if [ -n "$_precmd" ]; then 715195534Sscottl eval $_precmd 716195534Sscottl _return=$? 717208911Smjacob [ $_return -ne 0 ] && [ -z "$rc_force" ] && 718195534Sscottl return 1 719195534Sscottl fi 720195534Sscottl _doit="kill -${sig_reload:-HUP} $rc_pid" 721195534Sscottl if [ -n "$_user" ]; then 722195534Sscottl _doit="su -m $_user -c 'sh -c \"$_doit\"'" 723195534Sscottl fi 724195534Sscottl eval $_doit 725236814Smav _return=$? 726195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && return 1 727195534Sscottl if [ -n "$_postcmd" ]; then 728195534Sscottl eval $_postcmd 729195534Sscottl _return=$? 730195534Sscottl fi 731195534Sscottl ;; 732195534Sscottl 733195534Sscottl restart) 734195534Sscottl if [ -n "$_precmd" ]; then 735195534Sscottl eval $_precmd 736195534Sscottl _return=$? 737195534Sscottl [ $_return -ne 0 ] && [ -z "$rc_force" ] && 738195534Sscottl return 1 739195534Sscottl fi 740195534Sscottl # prevent restart being called more 741195534Sscottl # than once by any given script 742195534Sscottl # 743195534Sscottl if [ -n "$_rc_restart_done" ]; then 744195534Sscottl return 0 745195534Sscottl fi 746195534Sscottl _rc_restart_done=YES 747195534Sscottl 748195534Sscottl ( $0 ${rc_force:+force}stop ) 749195534Sscottl $0 ${rc_force:+force}start 750195534Sscottl 751195534Sscottl if [ -n "$_postcmd" ]; then 752195534Sscottl eval $_postcmd 753195534Sscottl _return=$? 754195534Sscottl fi 755195534Sscottl ;; 756195534Sscottl 757195534Sscottl poll) 758195534Sscottl if [ -n "$rc_pid" ]; then 759195534Sscottl wait_for_pids $rc_pid 760195534Sscottl fi 761195534Sscottl ;; 762195534Sscottl 763195534Sscottl rcvar) 764195534Sscottl echo "# $name" 765195534Sscottl if [ -n "$rcvar" ]; then 766195534Sscottl if checkyesno ${rcvar}; then 767195534Sscottl echo "\$${rcvar}=YES" 768195534Sscottl else 769195534Sscottl echo "\$${rcvar}=NO" 770195534Sscottl fi 771195534Sscottl fi 772195534Sscottl ;; 773195534Sscottl 774195534Sscottl *) 775195534Sscottl rc_usage "$_keywords" 776195534Sscottl ;; 777195534Sscottl 778195534Sscottl esac 779195534Sscottl return $_return 780195534Sscottl done 781195534Sscottl 782195534Sscottl echo 1>&2 "$0: unknown directive '$rc_arg'." 783195534Sscottl rc_usage "$_keywords" 784195534Sscottl exit 1 785195534Sscottl} 786195534Sscottl 787195534Sscottl# 788195534Sscottl# run_rc_script file arg 789195534Sscottl# Start the script `file' with `arg', and correctly handle the 790195534Sscottl# return value from the script. If `file' ends with `.sh', it's 791195534Sscottl# sourced into the current environment. If `file' appears to be 792195534Sscottl# a backup or scratch file, ignore it. Otherwise if it's 793195534Sscottl# executable run as a child process. 794195534Sscottl# 795195534Sscottlrun_rc_script() 796195534Sscottl{ 797195534Sscottl _file=$1 798195534Sscottl _arg=$2 799195534Sscottl if [ -z "$_file" -o -z "$_arg" ]; then 800195534Sscottl err 3 'USAGE: run_rc_script file arg' 801195534Sscottl fi 802195534Sscottl 803195534Sscottl trap "echo 'Reboot interrupted'; exit 1" 3 804195534Sscottl 805195534Sscottl unset name command command_args command_interpreter \ 806208911Smjacob extra_commands pidfile procname \ 807208911Smjacob rcvar required_dirs required_files required_vars 808208911Smjacob eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd 809208911Smjacob 810208911Smjacob case "$_file" in 811208911Smjacob *.sh) # run in current shell 812208911Smjacob set $_arg ; . $_file 813208911Smjacob ;; 814208911Smjacob *[~#]|*.OLD|*.orig) # scratch file; skip 815208911Smjacob warn "Ignoring scratch file $_file" 816208911Smjacob ;; 817208911Smjacob *) # run in subshell 818208911Smjacob if [ -x $_file ]; then 819208911Smjacob if [ -n "$rc_fast_and_loose" ]; then 820216088Sken set $_arg ; . $_file 821216088Sken else 822208911Smjacob ( trap "echo 'Reboot interrupted'; exit 1" 3 823208911Smjacob set $_arg ; . $_file ) 824208911Smjacob fi 825208911Smjacob fi 826208911Smjacob ;; 827208911Smjacob esac 828208911Smjacob} 829195534Sscottl 830195534Sscottl# 831195534Sscottl# load_rc_config 832195534Sscottl# Source in the configuration file for a given command. 833195534Sscottl# 834195534Sscottlload_rc_config() 835195534Sscottl{ 836195534Sscottl _command=$1 837195534Sscottl if [ -z "$_command" ]; then 838195534Sscottl err 3 'USAGE: load_rc_config command' 839195534Sscottl fi 840195534Sscottl 841195534Sscottl if [ -z "$_rc_conf_loaded" ]; then 842195534Sscottl if [ -r /etc/defaults/rc.conf ]; then 843195534Sscottl debug "Sourcing /etc/defaults/rc.conf" 844195534Sscottl . /etc/defaults/rc.conf 845195534Sscottl source_rc_confs 846195534Sscottl elif [ -r /etc/rc.conf ]; then 847195534Sscottl debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." 848195534Sscottl . /etc/rc.conf 849195534Sscottl fi 850195534Sscottl _rc_conf_loaded=YES 851195534Sscottl fi 852195534Sscottl if [ -f /etc/rc.conf.d/"$_command" ]; then 853195534Sscottl debug "Sourcing /etc/rc.conf.d/${_command}" 854216088Sken . /etc/rc.conf.d/"$_command" 855195534Sscottl fi 856195534Sscottl 857216088Sken # XXX - Deprecated variable name support 858195534Sscottl # 859216088Sken case ${OSTYPE} in 860195534Sscottl FreeBSD) 861195534Sscottl [ -n "$portmap_enable" ] && rpcbind_enable="$portmap_enable" 862216088Sken [ -n "$portmap_program" ] && rpcbind_program="$portmap_program" 863195534Sscottl [ -n "$portmap_flags" ] && rpcbind_flags="$portmap_flags" 864216088Sken [ -n "$single_mountd_enable" ] && mountd_enable="$single_mountd_enable" 865216088Sken [ -n "$xntpd_enable" ] && ntpd_enable="$xntpd_enable" 866195534Sscottl [ -n "$xntpd_program" ] && ntpd_program="$xntpd_program" 867195534Sscottl [ -n "$xntpd_flags" ] && ntpd_flags="$xntpd_flags" 868195534Sscottl [ -n "$dhcp_program" ] && dhclient_program="$dhcp_program" 869195534Sscottl [ -n "$dhcp_flags" ] && dhclient_flags="$dhcp_flags" 870195534Sscottl ;; 871195534Sscottl esac 872195534Sscottl 873195534Sscottl} 874195534Sscottl 875195534Sscottl# 876195534Sscottl# rc_usage commands 877195534Sscottl# Print a usage string for $0, with `commands' being a list of 878195534Sscottl# valid commands. 879195534Sscottl# 880195534Sscottlrc_usage() 881195534Sscottl{ 882195534Sscottl echo -n 1>&2 "Usage: $0 [fast|force](" 883195534Sscottl 884195534Sscottl _sep= 885195534Sscottl for _elem in $*; do 886195534Sscottl echo -n 1>&2 "$_sep$_elem" 887250025Smav _sep="|" 888195534Sscottl done 889195534Sscottl echo 1>&2 ")" 890195534Sscottl exit 1 891216088Sken} 892195534Sscottl 893216088Sken# 894216088Sken# err exitval message 895216088Sken# Display message to stderr and log to the syslog, and exit with exitval. 896249937Ssmh# 897216088Skenerr() 898216088Sken{ 899216088Sken exitval=$1 900216088Sken shift 901216088Sken 902216088Sken if [ -x /usr/bin/logger ]; then 903216088Sken logger "$0: ERROR: $*" 904216088Sken fi 905216088Sken echo 1>&2 "$0: ERROR: $*" 906216088Sken exit $exitval 907216088Sken} 908216088Sken 909216088Sken# 910216088Sken# warn message 911216088Sken# Display message to stderr and log to the syslog. 912216088Sken# 913216088Skenwarn() 914216088Sken{ 915216088Sken if [ -x /usr/bin/logger ]; then 916216088Sken logger "$0: WARNING: $*" 917216088Sken fi 918250025Smav echo 1>&2 "$0: WARNING: $*" 919216088Sken} 920216088Sken 921216088Sken# 922216088Sken# info message 923216088Sken# Display informational message to stdout and log to syslog. 924195534Sscottl# 925195534Sscottlinfo() 926195534Sscottl{ 927195534Sscottl case ${rc_info} in 928195534Sscottl [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 929195685Semaste if [ -x /usr/bin/logger ]; then 930195685Semaste logger "$0: INFO: $*" 931195685Semaste fi 932195685Semaste echo "$0: INFO: $*" 933195685Semaste ;; 934195534Sscottl esac 935249937Ssmh} 936216088Sken 937216088Sken# 938216088Sken# debug message 939195534Sscottl# If debugging is enabled in rc.conf output message to stderr. 940195534Sscottl# BEWARE that you don't call any subroutine that itself calls this 941195534Sscottl# function. 942195534Sscottl# 943195534Sscottldebug() 944195534Sscottl{ 945195534Sscottl case ${rc_debug} in 946195534Sscottl [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 947195534Sscottl if [ -x /usr/bin/logger ]; then 948195534Sscottl logger "$0: INFO: $*" 949195534Sscottl fi 950195534Sscottl echo 1>&2 "$0: DEBUG: $*" 951195534Sscottl ;; 952195534Sscottl esac 953195534Sscottl} 954195534Sscottl 955195534Sscottl# 956195534Sscottl# backup_file action file cur backup 957195534Sscottl# Make a backup copy of `file' into `cur', and save the previous 958250025Smav# version of `cur' as `backup' or use rcs for archiving. 959195534Sscottl# 960195534Sscottl# This routine checks the value of the backup_uses_rcs variable, 961195534Sscottl# which can be either YES or NO. 962195534Sscottl# 963236613Smav# The `action' keyword can be one of the following: 964195534Sscottl# 965249466Smav# add `file' is now being backed up (and is possibly 966195534Sscottl# being reentered into the backups system). `cur' 967195534Sscottl# is created and RCS files, if necessary, are 968195534Sscottl# created as well. 969195534Sscottl# 970195534Sscottl# update `file' has changed and needs to be backed up. 971195534Sscottl# If `cur' exists, it is copied to to `back' or 972195534Sscottl# checked into RCS (if the repository file is old), 973195534Sscottl# and then `file' is copied to `cur'. Another RCS 974203108Smav# check in done here if RCS is being used. 975195534Sscottl# 976195534Sscottl# remove `file' is no longer being tracked by the backups 977195534Sscottl# system. If RCS is not being used, `cur' is moved 978252382Sscottl# to `back', otherwise an empty file is checked in, 979195534Sscottl# and then `cur' is removed. 980195534Sscottl# 981195534Sscottl# 982195534Sscottlbackup_file() 983195534Sscottl{ 984195534Sscottl _action=$1 985195534Sscottl _file=$2 986195534Sscottl _cur=$3 987195534Sscottl _back=$4 988195534Sscottl 989195534Sscottl if checkyesno backup_uses_rcs; then 990195534Sscottl _msg0="backup archive" 991195534Sscottl _msg1="update" 992195534Sscottl 993195534Sscottl # ensure that history file is not locked 994195534Sscottl if [ -f $_cur,v ]; then 995195534Sscottl rcs -q -u -U -M $_cur 996203108Smav fi 997195534Sscottl 998195534Sscottl # ensure after switching to rcs that the 999195534Sscottl # current backup is not lost 1000252382Sscottl if [ -f $_cur ]; then 1001195534Sscottl # no archive, or current newer than archive 1002195534Sscottl if [ ! -f $_cur,v -o $_cur -nt $_cur,v ]; then 1003195534Sscottl ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1004195534Sscottl rcs -q -kb -U $_cur 1005195534Sscottl co -q -f -u $_cur 1006195534Sscottl fi 1007195534Sscottl fi 1008195534Sscottl 1009195534Sscottl case $_action in 1010195534Sscottl add|update) 1011195534Sscottl cp -p $_file $_cur 1012195534Sscottl ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1013195534Sscottl rcs -q -kb -U $_cur 1014195534Sscottl co -q -f -u $_cur 1015195534Sscottl chown root:wheel $_cur $_cur,v 1016195534Sscottl ;; 1017195534Sscottl remove) 1018195534Sscottl cp /dev/null $_cur 1019195534Sscottl ci -q -f -u -t-"$_msg0" -m"$_msg1" $_cur 1020195534Sscottl rcs -q -kb -U $_cur 1021195534Sscottl chown root:wheel $_cur $_cur,v 1022195534Sscottl rm $_cur 1023195534Sscottl ;; 1024195534Sscottl esac 1025195534Sscottl else 1026195534Sscottl case $_action in 1027195534Sscottl add|update) 1028195534Sscottl if [ -f $_cur ]; then 1029195534Sscottl cp -p $_cur $_back 1030195534Sscottl fi 1031195534Sscottl cp -p $_file $_cur 1032195534Sscottl chown root:wheel $_cur 1033195534Sscottl ;; 1034195534Sscottl remove) 1035195534Sscottl mv -f $_cur $_back 1036195534Sscottl ;; 1037195534Sscottl esac 1038195534Sscottl fi 1039195534Sscottl} 1040195534Sscottl 1041195534Sscottl# devfs_link dir src link 1042195534Sscottl# Make a symbolic link 'link' to src in chroot/dev. 1043195534Sscottl# Returns 0 on sucess. 1044236613Smav# 1045195534Sscottldevfs_link() 1046195534Sscottl{ 1047195534Sscottl local dir src link _me 1048195534Sscottl dir="$1" 1049195534Sscottl src="$2" 1050195534Sscottl link="$3" 1051195534Sscottl _me="devfs_link" 1052195534Sscottl 1053195534Sscottl if [ -z "$dir" -o -z "$src" -o -z "$link" ]; then 1054195534Sscottl warn "devfs_link(): requires three arguments." 1055195534Sscottl return 1 1056195534Sscottl fi 1057195534Sscottl if [ -z "$dir" ]; then 1058195534Sscottl warn "$_me: the directory ($dir) does not exist" 1059195534Sscottl return 1 1060195534Sscottl fi 1061195534Sscottl cd ${chroot}/dev 1062195534Sscottl if ! ln -sf $src $link ; then 1063195534Sscottl warn "$_me: unable to link $link --> $src in $dir" 1064236613Smav return 1 1065195534Sscottl fi 1066195534Sscottl return 0 1067195534Sscottl} 1068195534Sscottl 1069195534Sscottl# devfs_rulesets_from_file file 1070195534Sscottl# Reads a set of devfs commands from file, and creates 1071195534Sscottl# the specified rulesets with their rules. Returns non-zero 1072236613Smav# if there was an error. 1073195534Sscottl# 1074195534Sscottldevfs_rulesets_from_file() 1075195534Sscottl{ 1076195534Sscottl local file _err _me 1077195534Sscottl file="$1" 1078195534Sscottl _me="devfs_rulesets_from_file" 1079252382Sscottl _err=0 1080195534Sscottl 1081195534Sscottl if [ -z "$file" ]; then 1082236613Smav warn "$_me: you must specify a file" 1083195534Sscottl return 1 1084195534Sscottl fi 1085195534Sscottl if [ ! -e "$file" ]; then 1086195534Sscottl debug "$_me: no such file ($file)" 1087195534Sscottl return 0 1088195534Sscottl fi 1089195534Sscottl debug "reading rulesets from file ($file)" 1090195534Sscottl { while read line 1091216088Sken do 1092216088Sken case $line in 1093195534Sscottl \#*) 1094195534Sscottl continue 1095195534Sscottl ;; 1096195534Sscottl \[*\]*) 1097195534Sscottl rulenum=`expr "$line" : "\[.*=\([0-9]*\)\]"` 1098195534Sscottl if [ -z "$rulenum" ]; then 1099195534Sscottl warn "$_me: cannot extract rule number ($line)" 1100195534Sscottl _err=1 1101195534Sscottl break 1102195534Sscottl fi 1103195534Sscottl rulename=`expr "$line" : "\[\(.*\)=[0-9]*\]"` 1104195534Sscottl if [ -z "$rulename" ]; then 1105195534Sscottl warn "$_me: cannot extract rule name ($line)" 1106195534Sscottl _err=1 1107195534Sscottl break; 1108195534Sscottl fi 1109252382Sscottl eval $rulename=\$rulenum 1110195534Sscottl debug "found ruleset: $rulename=$rulenum" 1111195534Sscottl if ! /sbin/devfs rule -s $rulenum delset ; then 1112249466Smav _err=1 1113249466Smav break 1114249466Smav fi 1115249466Smav ;; 1116195534Sscottl *) 1117249466Smav rulecmd="${line%%"\#*"}" 1118195534Sscottl # evaluate the command incase it includes 1119195534Sscottl # other rules 1120195534Sscottl if [ -n "$rulecmd" ]; then 1121195534Sscottl debug "adding rule ($rulecmd)" 1122195534Sscottl if ! eval /sbin/devfs rule -s $rulenum $rulecmd 1123195534Sscottl then 1124195534Sscottl _err=1 1125195534Sscottl break 1126195534Sscottl fi 1127249466Smav fi 1128195534Sscottl ;; 1129195534Sscottl esac 1130195534Sscottl if [ $_err -ne 0 ]; then 1131195534Sscottl debug "error in $_me" 1132252382Sscottl break 1133195534Sscottl fi 1134195534Sscottl done } < $file 1135195534Sscottl return $_err 1136195534Sscottl} 1137195534Sscottl 1138195534Sscottl# devfs_init_rulesets 1139195534Sscottl# Initializes rulesets from configuration files. Returns 1140195534Sscottl# non-zero if there was an error. 1141208911Smjacob# 1142195534Sscottldevfs_init_rulesets() 1143195534Sscottl{ 1144195534Sscottl local file _me 1145195534Sscottl _me="devfs_init_rulesets" 1146195534Sscottl 1147195534Sscottl # Go through this only once 1148195534Sscottl if [ -n "$devfs_rulesets_init" ]; then 1149195534Sscottl debug "$_me: devfs rulesets already initialized" 1150195534Sscottl return 1151195534Sscottl fi 1152195534Sscottl for file in $devfs_rulesets ; do 1153195534Sscottl devfs_rulesets_from_file $file || return 1 1154195534Sscottl done 1155195534Sscottl devfs_rulesets_init=1 1156195534Sscottl debug "$_me: devfs rulesets initialized" 1157195534Sscottl return 0 1158195534Sscottl} 1159195534Sscottl 1160195534Sscottl# devfs_set_ruleset ruleset [dir] 1161195534Sscottl# Sets the default ruleset of dir to ruleset. The ruleset arguement 1162249466Smav# must be a ruleset name as specified in devfs.rules(5) file. 1163195534Sscottl# Returns non-zero if it could not set it successfully. 1164195534Sscottl# 1165195534Sscottldevfs_set_ruleset() 1166195534Sscottl{ 1167195534Sscottl local devdir rs _me 1168208911Smjacob [ -n "$1" ] && eval rs=\$$1 || rs= 1169208911Smjacob [ -n "$2" ] && devdir="-m "$2"" || devdir= 1170208911Smjacob _me="devfs_set_ruleset" 1171208911Smjacob 1172208911Smjacob if [ -z "$rs" ]; then 1173208911Smjacob warn "$_me: you must specify a ruleset number" 1174208911Smjacob return 1 1175208911Smjacob fi 1176208911Smjacob debug "$_me: setting ruleset ($rs) on mount-point (${devdir#-m })" 1177208911Smjacob if ! /sbin/devfs $devdir ruleset $rs ; then 1178208911Smjacob warn "$_me: unable to set ruleset $rs to ${devdir#-m }" 1179208911Smjacob return 1 1180208911Smjacob fi 1181208911Smjacob return 0 1182195534Sscottl} 1183208911Smjacob 1184216088Sken# devfs_apply_ruleset ruleset [dir] 1185195534Sscottl# Apply ruleset number $ruleset to the devfs mountpoint $dir. 1186198748Smav# The ruleset argument must be a ruleset name as specified 1187198748Smav# in a devfs.rules(5) file. Returns 0 on success or non-zero 1188198748Smav# if it could not apply the ruleset. 1189198748Smav# 1190195534Sscottldevfs_apply_ruleset() 1191195534Sscottl{ 1192249466Smav local devdir rs _me 1193208911Smjacob [ -n "$1" ] && eval rs=\$$1 || rs= 1194208911Smjacob [ -n "$2" ] && devdir="-m "$2"" || devdir= 1195208911Smjacob _me="devfs_apply_ruleset" 1196208911Smjacob 1197208911Smjacob if [ -z "$rs" ]; then 1198208911Smjacob warn "$_me: you must specify a ruleset" 1199208911Smjacob return 1 1200208911Smjacob fi 1201208911Smjacob debug "$_me: applying ruleset ($rs) to mount-point (${devdir#-m })" 1202208911Smjacob if ! /sbin/devfs $devdir rule -s $rs applyset ; then 1203208911Smjacob warn "$_me: unable to apply ruleset $rs to ${devdir#-m }" 1204208911Smjacob return 1 1205208911Smjacob fi 1206208911Smjacob return 0 1207249466Smav} 1208195534Sscottl 1209195534Sscottl# devfs_domount dir [ruleset] 1210195534Sscottl# Mount devfs on dir. If ruleset is specified it is set 1211195534Sscottl# on the mount-point. It must also be a ruleset name as specified 1212195534Sscottl# in a devfs.rules(5) file. Returns 0 on success. 1213195534Sscottl# 1214249466Smavdevfs_domount() 1215195534Sscottl{ 1216195534Sscottl local devdir rs _me 1217195534Sscottl devdir="$1" 1218195534Sscottl [ -n "$2" ] && rs=$2 || rs= 1219195534Sscottl _me="devfs_domount()" 1220195534Sscottl 1221195534Sscottl if [ -z "$devdir" ]; then 1222195534Sscottl warn "$_me: you must specify a mount-point" 1223195534Sscottl return 1 1224195534Sscottl fi 1225195534Sscottl debug "$_me: mount-point is ($devdir), ruleset is ($rs)" 1226195534Sscottl if ! mount -t devfs dev "$devdir" ; then 1227195534Sscottl warn "$_me: Unable to mount devfs on $devdir" 1228195534Sscottl return 1 1229195534Sscottl fi 1230195534Sscottl if [ -n "$rs" ]; then 1231195534Sscottl devfs_init_rulesets 1232195534Sscottl devfs_set_ruleset $rs $devdir 1233236613Smav fi 1234195534Sscottl return 0 1235195534Sscottl} 1236195534Sscottl 1237195534Sscottl# devfs_mount_jail dir [ruleset] 1238208911Smjacob# Mounts a devfs file system appropriate for jails 1239208911Smjacob# on the directory dir. If ruleset is specified, the ruleset 1240208911Smjacob# it names will be used instead. If present, ruleset must 1241208911Smjacob# be the name of a ruleset as defined in a devfs.rules(5) file. 1242208911Smjacob# This function returns non-zero if an error occurs. 1243208911Smjacob# 1244208911Smjacobdevfs_mount_jail() 1245208911Smjacob{ 1246208911Smjacob local jdev rs _me 1247208911Smjacob jdev="$1" 1248208911Smjacob [ -n "$2" ] && rs=$2 || rs="devfsrules_jail" 1249208911Smjacob _me="devfs_mount_jail" 1250252382Sscottl 1251208911Smjacob devfs_init_rulesets 1252208911Smjacob if ! devfs_domount "$jdev" $rs ; then 1253208911Smjacob warn "$_me: devfs was not mounted on $jdev" 1254208911Smjacob return 1 1255249466Smav fi 1256208911Smjacob return 0 1257208911Smjacob} 1258208911Smjacob