#!/bin/bash # rc # By Jason Pearce - jason.pearce@linux.org # Modified by Gerard Beekmans - gerard@linuxfromscratch.org # print_error_msg based on ideas by Simon Perreault - # nomis80@videotron.ca # Source functions library source /etc/rc.d/init.d/functions # If you uncomment the debug variable below none of the scripts will be # executed, just the script name and parameters will be echo'ed to the # screen so you can see how the scripts are called by rc. #debug="echo" # If the return value of the scripts executed in each runlevel (start or stop) # is not 0 (success) or 1 (warning), something went wrong with error checking # inside the script. The print_error_msg function will be called and the # message plus the return value of the K script will be printed to the screen. # Prints an error message when an unforeseen error occurred that wasn't # trapped for some reason by error checking. print_error_msg() { ${FAILURE} echo " Error in subscript \"${1}\" (${2})" echo -en "${NORMAL}" echo " Press a key to continue..." read } # Start script or program. startup() { ${debug} "$@" } check_script_status() { if [ ! -f $1 ]; then echo "$1 is not a valid symlink" return ${EXIT_CODE_FAILURE} fi if [ ! -x $1 ]; then echo "$1 is not executable, skipping" return ${EXIT_CODE_FAILURE} fi return ${EXIT_CODE_SUCCESS} } # Configure for displaying only relevant messages to console /bin/dmesg -n ${LOGLEVEL} # Ignore CTRL-C only in this shell, so we can interrupt subprocesses. trap ":" INT QUIT TSTP runlevel=${1} # If no runlevel was passed as an argument, we won't change runlevels. if [ "${runlevel}" == "" ]; then echo "Usage: ${0} " >&2 exit ${EXIT_CODE_FAILURE} fi # PREVLEVEL is set by init # If PREVLEVEL is not set it means that there is no previous runlevel and # we'll set previous to N. previous=${PREVLEVEL} if [ "${previous}" = "" ]; then previous="N" fi # Is there an rc directory for the new runlevel? if [ ! -d /etc/rc.d/rc${runlevel}.d ]; then echo "/etc/rc.d/rc${runlevel}.d directory does not exist" exit ${EXIT_CODE_FAILURE} fi # First, attempt to stop all services started by previous runlevel, # and killed in this runlevel (K* scripts # If so, first collect all the K* scripts in the new run level. if [ ${previous} != N ]; then for kill_script in $(ls /etc/rc.d/rc${runlevel}.d/K* 2> /dev/null); do check_script_status ${kill_script} if [ ${?} != ${EXIT_CODE_SUCCESS} ]; then continue fi # "suffix" will contain the script name without the leading Kxx. suffix="${kill_script##*/K[0-9][0-9]}" # If there is a S script in the previous runlevel corresponding # to this K script, determine what it's full path is. previous_start="/etc/rc.d/rc${previous}.d/S[0-9][0-9]${suffix}" # If no start script was found in the previous run level it could # be that something was started in rcsysinit.d (sysinit level) so we'll # determine the path for that possibility as well. sysinit_start="/etc/rc.d/rcsysinit.d/S[0-9][0-9]${suffix}" # Stop the service if there is a start script in the previous run # level or in the sysinit level. Otherwise, don't execute this K # script because the service is not active. if [ "${runlevel}" != "0" -a "${runlevel}" != "6" ]; then if [ ! -f ${previous_start} -a ! -f ${sysinit_start} ]; then echo "Warning: script ${kill_script} cannot be stopped because it was not started" echo "in the previous runlevel" continue fi fi startup ${kill_script} stop retval=${?} if [ ${retval} -ne ${EXIT_CODE_SUCCESS} -a ${retval} -ne ${EXIT_CODE_WARNING} ]; then print_error_msg ${kill_script} ${retval} fi done fi # Now run the START scripts for this runlevel. for start_script in $(ls /etc/rc.d/rc${runlevel}.d/S* 2> /dev/null); do if [ "${previous}" != "N" ]; then # "suffix" will contain the script name without the leading Sxx. suffix=${start_script#/etc/rc.d/rc${runlevel}.d/S[0-9][0-9]} # If there is a K script in the current runlevel corresponding # to this S script, determine what it's full path is. current_stop=/etc/rc.d/rc${runlevel}.d/K[0-9][0-9]${suffix} # If there is a S script in the previous runlevel corresponding # to this S script, determine what it's full path is. previous_start=/etc/rc.d/rc${previous}.d/S[0-9][0-9]${suffix} if [ -f ${previous_start} -a ! -f ${current_stop} ]; then # If the service was started in the previous level and was not stopped # in this runlevel, then we don't have to re-start it. continue fi fi check_script_status ${start_script} if [ ${?} != ${EXIT_CODE_SUCCESS} ]; then continue fi # If the service was not started in the previous level, or if we just # stopped it in this runlevel, then we need to start or restart it. case ${runlevel} in 0|6) startup ${start_script} stop ;; *) startup ${start_script} start ;; esac retval=${?} if [ ${retval} -ne ${EXIT_CODE_SUCCESS} -a ${retval} -ne ${EXIT_CODE_WARNING} ]; then print_error_msg ${start_script} ${retval} fi done exit ${EXIT_CODE_SUCCESS}