#! /bin/sh # # init.sh - a sample init control script for smail # #ident "@(#)smail/util:RELEASE-3_2_0_121:init.sh,v 1.12 2005/01/14 05:22:25 woods Exp" # PROVIDE: mail # REQUIRE: LOGIN # KEYWORD: shutdown # This script is designed primarily for the NetBSD system startup # scripts (/etc/rc et al), but has basic compatability to work on other # systems (including older NetBSD systems) with no additional outside # support functionality. # # It is easily tailored to support any basic daemon which writes its # PID to a file specified by $pidfile. # # The following globals are used to tailor it: # # name needed function # ---- ------ -------- # name y Name of script. # # command n Full path to command. # Not needed if ${arg}_cmd is set for # each keyword. # # command_args n Optional parameters for command # (used after ${name}_flags). # # extra_commands n List of extra commands supported. # # pidfile n If set, use check_pidfile $pidfile, else if # $command is set, use check_process $command. # # rcvar n This is checked with checkyesno to determine # if the action should be run. # # sig_reload n signal to send for the "reload" command. (def=1) # # sig_stop n signal to send for the "stop" command. (def=15) # # ${name}_chdir n Directory to cd to before running ${command} # # ${name}_flags n Arguments to call ${command} with. # # NOTE: $flags from the environment # can be used to override this. # # ${_arg}_cmd n If set, use this as the action when invoked; # $_arg is available for the action to use. # Otherwise, use default command (see below) # # ${_arg}_precmd n If set, run just before performing the main # action in the default command (i.e, after # checking for required bits and process # (non)existance). # # If this completes with a non-zero exit code, # don't run ${_arg}_cmd. # # required_dirs n If set, check for the existence of the given # directories before running the default # (re)start command. # # required_files n If set, check for the readability of the given # files before running the default (re)start # command. # # required_vars n If set, perform checkyesno on each of the # listed variables before running the default # (re)start command. #### start of local configuration section #### command="/usr/local/sbin/sendmail" conf_file="/usr/local/etc/smail/config" aliases_file="/etc/aliases" forcepaths_file="/usr/local/etc/smail/forcepaths" forcesmtp_file="/usr/local/etc/smail/forcesmtp" paths_file="/usr/local/etc/smail/paths" rewrite_file="/usr/local/etc/smail/rewrite" pidfile="/var/run/smail.pid" #### end of local configuration section #### #### start of package-specific section #### name="smail" rcvar="smail" : ${smail_flags:="-bd -q15m"} # default settings -- override in /etc/rc.conf #required_files="${conf_file} ${aliases_file} ${forcepaths_file} ${forcesmtp_file} ${paths_file} ${rewrite_file}" required_files="${aliases_file} ${rewrite_file}" sig_reload="1" smail_status_precmd() { ${command} -bp -s } status_precmd="smail_status_precmd" #### end of package-specific section -- the rest is 100% generic #### # is this NetBSD (1.4V|1.5) [2000/03/13] or newer? # if [ -f /etc/rc.subr -a -f /etc/rc.conf -a -d /etc/rc.d -a -f /etc/rc.d/DAEMON ]; then . /etc/rc.subr # some older versions need this enabled... # extra_commands="${extra_commands} reload" # is this NetBSD 1.4Z [2000/05/13] or newer? # if type load_rc_config > /dev/null 2>&1 ; then load_rc_config ${name} else . /etc/rc.conf if [ -f /etc/rc.conf.d/${name} ]; then . /etc/rc.conf.d/${name} fi fi run_rc_command "$1" # if not then it must be old NetBSD, Solaris, Linux, etc... # else if [ -f /etc/rc.subr ] ; then . /etc/rc.subr # NetBSD-1.3 has older checkyesno variant fi # don't override any warn function already provided in /etc/rc.subr # if expr "$(type warn)" : '.* is a shell function$' >/dev/null 2>&1 ; then : else warn () { if expr "$(type logger)" : '.* is .*/logger$' >/dev/null 2>&1 ; then logger -s -p daemon.warning -t rc "$0: WARNING: $*" else echo "$0: WARNING: $*" 1>&2 fi } fi # XXX we may not have/want to be so paranoid of overriding 'checkyesno'... # if expr "$(type checkyesno)" : '.* is a shell function$' >/dev/null 2>&1 ; then : else # Test contents of $1, as a variable, for on or off values; # and warn if not set appropriately. # checkyesno () { eval _value=\${${1}} case ${_value} in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0 ;; [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1 ;; *) _rcconf="" if [ -f /etc/rc.conf ]; then _rcconf="in /etc/rc.conf" fi warn "\${${1}} is not configured properly${_rcconf}." return 1 ;; esac } fi # wait_for_pids pid [pid ...] # spins until none of the pids exist # wait_for_pids() { _list=$* if [ -z "$_list" ]; then return fi _prefix= while true; do _nlist=""; for _j in $_list; do if kill -0 $_j 2>/dev/null; then _nlist="${_nlist}${_nlist:+ }$_j" fi done if [ -z "$_nlist" ]; then break fi _list=$_nlist echo -n ${_prefix:-"Waiting for PIDS: "}$_list _prefix=", " sleep 2 done if [ -n "$_prefix" ]; then echo "." fi } _arg=${1} # On systems without an /etc/rc.conf the default action must # be to start the daemon.... # if [ -f /etc/rc.conf ] ; then . /etc/rc.conf else eval ${rcvar}="YES" # strictly maybe the rule should also be if $0 ends in ".sh"? # case ${_arg} in "") _arg="start" ;; esac fi _rc_force_run="" case ${_arg} in force*) _arg=${_arg#force} _rc_force_run=YES eval ${rcvar}="YES" ;; esac if [ -n "${rcvar}" -a "${_arg}" != "rcvar" -a "${_arg}" != "status" ]; then if ! checkyesno ${rcvar}; then exit 0 fi fi # eval $foo when $foo is unset returns true so we can blindly # "eval $_precmd" and check for failures without having to set # it to true... # eval _precmd=\$${cmd}_precmd eval _cmd=\$${_arg}_cmd # handle custom FOO_cmd setting... # if [ -n "$_cmd" ]; then if ! eval $_precmd && [ -z "$_rc_force_run" ]; then exit 1 fi eval $_cmd exit 0 fi if [ -n "$flags" ]; then # allow override from environment $flags _flags=$flags else eval _flags=\$${name}_flags fi eval _chdir=\$${name}_chdir case ${_arg} in start) if [ ! -x $command ]; then exit 0 fi if [ -s ${pidfile} ] ; then read _pid _junk < ${pidfile} if kill -0 ${_pid}; then warn "${name} is already running as ${_pid}!" exit 0 fi fi for _f in $required_vars; do if ! checkyesno $_f; then warn "\$${_f} is not set." if [ -z "$_rc_force_run" ]; then exit 1 fi fi done for _f in $required_dirs; do if [ ! -d "${_f}/." ]; then warn "${_f} is not a directory." if [ -z "$_rc_force_run" ]; then exit 1 fi fi done for _f in $required_files; do if [ ! -r "${_f}" ]; then warn "${_f} is not readable." if [ -z "$_rc_force_run" ]; then exit 1 fi fi done # # run the precmd and if it fails, and force, isn't # set, then error out # if ! eval $_precmd && [ -z "$_rc_force_run" ]; then exit 1 fi if [ -n "$_chdir" ] ; then cd $_chdir fi eval ${command} \${${name}_flags} ${command_args} && eval echo "${name} started using '${command} ${command_args} \${${name}_flags}'." ;; stop) if [ -s ${pidfile} ] ; then if ! eval $_precmd && [ -z "$_rc_force_run" ]; then exit 1 fi read _pid _junk < ${pidfile} kill -${sig_stop:-15} ${_pid} && echo "Stopping ${name}." wait_for_pids ${_pid} rm -f ${pidfile} elif checkyesno ${rcvar}; then warn " (${pidfile} does not exist; not stopping ${name})" fi ;; status) if [ -s ${pidfile} ] ; then if ! eval $_precmd && [ -z "$_rc_force_run" ]; then exit 1 fi read _pid _junk < ${pidfile} if [ -n "${_pid}" ]; then # -p and -l are nearly universal these days.... ps -p ${_pid} -l fi elif checkyesno ${rcvar}; then warn "${pidfile} does not exist." fi ;; reload) if [ -s ${pidfile} ] ; then if ! eval $_precmd && [ -z "$_rc_force_run" ]; then exit 1 fi read _pid _junk < ${pidfile} kill -${sig_reload:-1} ${_pid} elif checkyesno ${rcvar}; then warn "${pidfile} does not exist; not reloading ${name}." fi ;; restart) if ! eval $_precmd && [ -z "$_rc_force_run" ]; then exit 1 fi # prevent restart being called more # than once by any given script # if [ -n "$_rc_restart_done" ]; then exit 0 fi _rc_restart_done=YES ( $0 ${_rc_force_run:+force}stop ) $0 ${_rc_force_run:+force}start ;; rcvar) echo "# $name" if [ -n "$rcvar" ]; then if checkyesno ${rcvar}; then echo "\$${rcvar}=YES" else echo "\$${rcvar}=NO" fi fi ;; *) echo "Usage: $0 {start|stop|restart|status|reload|rcvar}" 1>&2 exit 1 ;; esac fi exit 0