Let us add some meat onto the bones of the previous script and make it more complex and featureful. The default methods can do a good job for us, but we may need some of their aspects tweaked. Now we will learn how to tune the default methods to our needs.
#!/bin/sh
. /etc/rc.subr
name=mumbled
rcvar=mumbled_enable
command="/usr/sbin/${name}"
command_args="mock arguments > /dev/null 2>&1"
pidfile="/var/run/${name}.pid"
required_files="/etc/${name}.conf /usr/share/misc/${name}.rules"
sig_reload="USR1"
start_precmd="${name}_prestart"
stop_postcmd="echo Bye-bye"
extra_commands="reload plugh xyzzy"
plugh_cmd="mumbled_plugh"
xyzzy_cmd="echo 'Nothing happens.'"
mumbled_prestart()
{
	if checkyesno mumbled_smart; then
		rc_flags="-o smart ${rc_flags}"
	fi
	case "$mumbled_mode" in
	foo)
		rc_flags="-frotz ${rc_flags}"
		;;
	bar)
		rc_flags="-baz ${rc_flags}"
		;;
	*)
		warn "Invalid value for mumbled_mode"
		return 1
		;;
	esac
	run_rc_command xyzzy
	return 0
}
mumbled_plugh()
{
	echo 'A hollow voice says "plugh".'
}
load_rc_config $name
run_rc_command "$1"

Note: Never include dashed options, like
-Xor--foo, in command_args. The contents of command_args will appear at the end of the final command line, hence they are likely to follow arguments present in ${name}_flags; but most commands will not recognize dashed options after ordinary arguments. A better way of passing additional options to $command is to add them to the beginning of ${name}_flags. Another way is to modify rc_flags as shown later.

Note: In fact, rc.subr(8) will also use the pidfile to see if the daemon is already running before starting it. This check can be skipped by using the
faststartargument.

Note: The default method from rc.subr(8) can be forced to skip the prerequisite checks by using
forcestartas the argument to the script.

SIGHUP by default. Another signal is 	 sent to stop the daemon
process; the default is 	 SIGTERM, but this can be
changed by 	 setting sig_stop appropriately.Note: The signal names should be specified to rc.subr(8) without the SIG prefix, as it is shown in the example. The FreeBSD version of kill(1) can recognize the SIG prefix, but the versions from other OS types may not.


Note: Overriding a default method with a custom argument_cmd still does not prevent us from making use of argument_precmd or argument_postcmd if we need to. In particular, the former is good for checking custom, sophisticated conditions that should be met before performing the command itself. Using argument_precmd along with argument_cmd lets us logically separate the checks from the action.
Do not forget that you can cram any valid sh(1) expressions into the methods, pre-, and post-commands you define. Just invoking a function that makes the real job is a good style in most cases, but never let style limit your understanding of what is going on behind the curtain.

Note: The
reloadcommand is special. On the one hand, it has a preset method in rc.subr(8). On the other hand,reloadis not offered by default. The reason is that not all daemons use the same reload mechanism and some have nothing to reload at all. So we need to ask explicitly that the builtin functionality be provided. We can do so via extra_commands.What do we get from the default method for
reload? Quite often daemons reload their configuration upon reception of a signal — typically,SIGHUP. Therefore rc.subr(8) attempts to reload the daemon by sending a signal to it. The signal is preset toSIGHUPbut can be customized via sig_reload if necessary.


plugh and xyzzy. We 	 saw them
listed in extra_commands, and now 	 it is time to provide
methods for them. The method for 	 xyzzy is just inlined
while that for 	 plugh is implemented as the 	 mumbled_plugh function.Non-standard commands are not invoked during startup or shutdown. Usually they are for the system admin's convenience. They can also be used from other subsystems, e.g., devd(8) if specified in devd.conf(5).
The full list of available commands can be found in the usage line printed by rc.subr(8) when the script is invoked without arguments. For example, here is the usage line from the script under study:
# /etc/rc.d/mumbled Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll)


checkyesno 	 is provided by
rc.subr(8). It takes a
variable name 	 as its argument and returns a zero exit code if and only 	 if the
variable is set to YES, or 	 TRUE,
or ON, or 	 1, case insensitive; a
non-zero exit 	 code is returned otherwise. In the latter case, the 	 function
tests the variable for being set to 	 NO, FALSE, 	 OFF, or 0, case 	 insensitive; it prints a warning message if the
variable 	 contains anything else, i.e., junk.Keep in mind that for sh(1) a zero exit code means true and a non-zero exit code means false.
Important: The
checkyesnofunction takes a variable name. Do not pass the expanded value of a variable to it; it will not work as expected.The following is the correct usage of
checkyesno:if checkyesno mumbled_enable; then foo fiOn the contrary, calling
checkyesnoas shown below will not work — at least not as expected:if checkyesno "${mumbled_enable}"; then foo fi


debug, 	 info, warn, and 	 err. The latter
function then exits 	 the script with the code specified.
Note: However, rc.subr(8) can be instructed from the command line to ignore those exit codes and invoke all commands anyway by prefixing an argument with force, as in
forcestart.