#!/bin/bash # Begin $rc_base/init.d/functions - Run Level Control Functions # Based on functions script from LFS-3.1 and earlier. # Rewritten by Gerard Beekmans - gerard@linuxfromscratch.org # With code based on Matthias Benkmann's simpleinit-msb @ # http://winterdrache.de/linux/newboot/index.html # Modified slightly for SourceMage GNU linux # SGL-script-version=20020923 umask 022 export PATH="/bin:/usr/bin:/sbin:/usr/sbin" KILLDELAY=3 COLUMNS=$(stty size) COLUMNS=${COLUMNS##* } COL=$[ $COLUMNS - 10 ] WCOL=$[ $COLUMNS - 30 ] SET_COL="builtin echo -en \\033[${COL}G" SET_WCOL="builtin echo -en \\033[${WCOL}G" CURS_UP="builtin echo -en \\033[A" NORMAL="builtin echo -en \\033[0;39m" SUCCESS="builtin echo -en \\033[1;32m" WARNING="builtin echo -en \\033[1;33m" FAILURE="builtin echo -en \\033[1;31m" SCRIPTC="builtin echo -en \\033[1;37m" # log the messages hack echo() { if ! [[ -t 1 ]]; then builtin echo "$@" else INITSTORE="$INITSTORE$(builtin echo "$@")" # correct for bash's insane strip trailing newline mumbo jumbo on command substitutions TRAILINGNL=$(( $(builtin echo "$@" | ( i=0; while read LINE; do i=$((++i)); done; builtin echo $i)) - $(builtin echo "$(builtin echo "$@")" | ( i=0; while read LINE; do i=$((++i)); done; builtin echo $i)) )) local i for ((i=0; i <= $TRAILINGNL; i++)); do INITSTORE="$INITSTORE " done # if it's more than one line, dump the line out and save the last line that doesn't have a newline at the end yet. if [ "`builtin echo "$INITSTORE" | ( i=0; while read LINE; do i=$((++i)); done; builtin echo $i)`" -gt 1 ]; then print_status message fi fi } export -f echo export INITSTORE print_error_msg() { echo $FAILURE echo "You should not be reading this error message. It means" echo "that an unforseen error took place in $i," echo "which exited with a return value of $error_value" echo echo "If you're able to track this error down to a bug in one" echo "of the files provided by SourceMage GNU Linux, please" echo "be so kind to inform us at http://www.sourcemage.org" $NORMAL echo echo echo "Press Enter to continue..." read } evaluate_retval() { local exit_value=$? if [ $exit_value = 0 ] ; then print_status success else print_status failure fi return $exit_value } logger_func() { [ -e /bin/logger ] && /bin/logger $* || { [ -e /usr/bin/logger ] && /usr/bin/logger $* } true } export -f logger_func print_status() { if [ $# = 0 ] ; then echo "Usage: $0 {success|warning|failure|message}" return 1 fi case "$1" in success) COLORCODE="$SUCCESS" ;; warning) COLORCODE="$WARNING" ;; failure) COLORCODE="$FAILURE" ;; message) ;; # null esac local SCRIPT="$(builtin echo $0 | sed -e 's!/.*/!!')" local SCRIPTW="$($SCRIPTC)$SCRIPT$($NORMAL)" local line builtin echo "$INITSTORE" | while read line; do [ -n "$line" -o "$1" != "message" ] && if [ -n "$SYSLOG_INIT" ]; then logger_func -p user.info -t init.d -- "$SCRIPT: $@: $line" fi && builtin echo -n "$SCRIPTW" && if [ ! "$1" = "message" ]; then builtin echo -n ": " && $COLORCODE && builtin echo -n "$@" && $NORMAL fi && if [ -n "$line" ]; then builtin echo -n ": $line" fi if [ -n "$line" -o "$1" != "message" ]; then builtin echo -ne "\eE" # PARALLEL fi done if [ "$1" = "message" ]; then INITSTORE="$line" else INITSTORE= fi } export -f print_status getpids() { local base=${1##*/} pidlist=$(builtin echo $(for i in $(pidof -o $$ -o $PPID -o '%PPID' -x $base); do awk -v i=$i '!/\/etc\/init[.]d/ {print i}' < /proc/$i/cmdline; done)) } loadproc() { if [ $# = 0 ] ; then echo "Usage: loadproc {program}" exit 1 fi getpids $1 if [ -z "$pidlist" ] ; then ( unset -f echo ; "$@" ; ) evaluate_retval else $SET_WCOL print_status warning running fi } killproc() { if [ $# = 0 ] ; then echo "Usage: killproc {program} [signal]" exit 1 fi if [ -z "$2" ] ; then signal=TERM fallback=KILL else signal=${2##-} signal=${signal##SIG} fallback="" fi getpids $1 if [ -n "$pidlist" ] ; then failure=0 for pid in $pidlist ; do kill -$signal $pid 2>/dev/null for ((i=0; $i<5000; i=$i+1)) ; do : ; done for ((i=0; $i<$KILLDELAY; i=$i+1)) ; do kill -0 $pid 2>/dev/null || break sleep 1 done if [ -n "$fallback" ] ; then kill -$fallback $pid 2>/dev/null ; fi for ((i=0; $i<$KILLDELAY; i=$i+1)) ; do kill -0 $pid 2>/dev/null || break sleep 1 done kill -0 $pid 2>/dev/null && failure=1 done base=${1##*/} if [ $failure = 0 ] ; then rm -f /var/run/$base.pid ; fi (exit $failure) evaluate_retval else $SET_WCOL print_status warning not_running exit 0 fi } reloadproc() { if [ $# = 0 ] ; then echo "Usage: reloadproc {program} [signal]" exit 1 fi if [ -z "$2" ] ; then signal=HUP else signal=${2##-} signal=${signal##SIG} fi getpids $1 if [ -n "$pidlist" ] ; then failure=0 for pid in $pidlist ; do kill -$signal $pid || failure=1 done (exit $failure) evaluate_retval else $SET_WCOL print_status warning not_running fi } statusproc() { if [ $# = 0 ] ; then echo "Usage: statusproc {program}" exit 1 fi local base=${1##*/} getpids $1 if [ -n "$pidlist" ] ; then echo "$base is running with Process ID(s) $pidlist" else if [ -s /var/run/$base.pid ] ; then echo "$1 is not running but /var/run/$base.pid exists" return 1 else echo "$1 is not running" fi fi } required_executable() { test -x $1 || { $FAILURE echo "Required program $1 doesn't appear to be installed" $NORMAL exit 5 } } optional_executable() { test -x $1 || { $WARNING echo "Optional program $1 doesn't appear to be installed" $NORMAL return 1 } return 0 } # End $rc_base/init.d/functions .