# Shell functions for the rc-scripts in /etc/init.d/ # Reference material on init scripts: # * Linux Standards Base Core Specification 4.0: http://refspecs.freestandards.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html # optional environment variables: # # name default description # ============= ============= ============= # DAEMON default for some other variables # DAEMON_LONG_NAME ${DAEMON} full name of daemon to display in start/stop messages # CONF_NAME ${DAEMON} config is in /mod/etc/conf/${CONF_NAME}.cfg # CONF_ENABLED ${DAEMON}_ENABLED variablename with starttype of daemon (yes,no,inetd) in .cfg-file # DAEMON_CONFIG /mod/etc/${DAEMON}.conf modlib_config will generate this file # DAEMON_BIN ${DAEMON} other binary name than $DAEMON # DAEMON_ENV additional environment settings # DAEMON_CHECK daemon(s) to check with pidof for running-status # PID_FILE /var/run/${DAEMON_BIN}.pid pid-file for DAEMON export PATH=/mod/sbin:/mod/bin:/mod/usr/sbin:/mod/usr/bin:/sbin:/bin:/usr/sbin:/usr/bin export LD_LIBRARY_PATH=/mod/lib:/mod/usr/lib : ${DAEMON_LONG_NAME:=$DAEMON} : ${CONF_NAME:=$DAEMON} : ${CONF_ENABLED:=${DAEMON}_ENABLED} : ${DAEMON_CONFIG:=/mod/etc/${DAEMON}.conf} : ${DAEMON_BIN:=$DAEMON} : ${PID_FILE:=/var/run/${DAEMON_BIN}.pid} # config: # dummy function if "config" is not defined in parent-script config() { :; } # stop_pre: # dummy function if "stop_pre" is not defined in parent-script stop_pre() { :; } # stop_post: # dummy function if "stop_post" is not defined in parent-script # parameter $1: return-value of stop(), 0=sucessfully stop_post() { :; } # modlib_addgroup: # check for group name, create group if not found. # No check is done for a change in the optional arguments! # $1: group name # $2-n: optional arguments for addgroup modlib_addgroup() { local group=$1 shift if grep -q "^$group:" /etc/group; then return 0 fi echo -n "Looking for group '$group' ... " if addgroup "$@" "$group"; then echo -n "created - now saving to data buffer ... " modusers save && echo "done." || echo "failed." else echo "not created - error occurred" fi } # modlib_adduser: # check for user name, create user if not found. # No check is done for a change in the optional arguments! # $1: user name # $2-n: optional arguments for adduser modlib_adduser() { local user=$1 shift if grep -q "^$user:" /etc/passwd; then return 0 fi echo -n "Looking for user '$user' ... " local msg=$(adduser "$@" "$user" 2>&1) if [ $? -eq 0 ]; then echo -n "created - now saving to data buffer ... " modusers save && echo "done." || echo "failed." else echo "not created - error occurred: $msg" exit 1 fi } # modlib_check_running # checks if the daemon is currently running. # return values: # 0: running # 3: stopped # 5: inetd # use CONF_ENABLED for other variablename with manual/automatic/inetd in .cfg-file modlib_check_running() { [ -n "$FORCE_STATUS" ] && return $FORCE_STATUS if [ -x /etc/init.d/rc.inetd ]; then [ "$(eval echo \$$(echo ${CONF_ENABLED} | tr [:lower:]- [:upper:]_))" == "inetd" ] && return 5 fi if [ -n "$DAEMON_CHECK" ]; then for DAEMON_single in $DAEMON_CHECK; do pidof $DAEMON_single >/dev/null 2>&1 || return 3 done return 0 fi local fn=$PID_FILE [ ! -s "$fn" ] && return 3 if kill -0 $(cat "$fn") 2> /dev/null; then return 0 else rm -f "$fn" return 3 fi } # modlib_config # creates /mod/etc/$DAEMON.conf # parameters: # $1 (optional): overwrites the $DAEMON part in input filenames # $2 (optional): overwrites output path+filename, default is $DAEMON_CONFIG (=/mod/etc/${DAEMON}.conf) modlib_config() { local in_files=${1-$DAEMON} local out_file=${2-$DAEMON_CONFIG} ( if [ -x "/tmp/flash/${in_files}_conf" ]; then /tmp/flash/${in_files}_conf elif [ -x "/tmp/flash/${DAEMON}/${in_files}_conf" ]; then /tmp/flash/${DAEMON}/${in_files}_conf else /mod/etc/default.${DAEMON}/${in_files}_conf fi cat /tmp/flash/${in_files}.extra /tmp/flash/${DAEMON}/${in_files}.extra 2>/dev/null ) > $out_file } # modlib_startdaemon # starts the binary with a clean environment # "$@": commandline to execute # if available runs "config" of rc.$DAEMON # use $DAEMON_BIN for other binary name than $DAEMON # use $DAEMON_ENV for additional environment settings modlib_startdaemon() { echo -n "Starting ${DAEMON_LONG_NAME} ... " config if [ ! -x "$(which $1)" ]; then echo "could not execute $1, failed." exit 1 fi env - PATH="$PATH" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" $DAEMON_ENV "$@" 1>&2 local rv=$? if [ $rv -ne 0 ]; then echo 'failed.' exit $rv fi # even daemons without pid-support creates a .pid file: local fn=$PID_FILE if [ ! -s "$fn" ]; then local dp=$(pidof -s "$DAEMON_BIN") if [ $? -ne 0 ]; then echo 'failed.' exit 1 fi [ -n "$dp" ] && echo "$dp" > $fn fi echo 'done.' } # modlib_start # decide if daemon is started in inetd mode # function "start" has to be defined in the calling script # $1: value for DAEMON_ENABLED # returns: 0=success or 1=error modlib_start() { local DAEMON_ENABLED=$1 if [ "$DAEMON_ENABLED" == "no" ]; then echo "${DAEMON_LONG_NAME} is disabled." 1>&2 exit 1 fi if [ "$DAEMON_ENABLED" == "inetd" -a ! -x /etc/init.d/rc.inetd ]; then echo "WARNING: ${DAEMON_LONG_NAME} could not find inetd." 1>&2 fi modlib_check_running case $? in 0) echo "Starting ${DAEMON_LONG_NAME} ... already running." ;; 3) start return $? ;; 5) config /etc/init.d/rc.inetd config $DAEMON ;; *) echo "${DAEMON_LONG_NAME} start prohibited, status is uncertain!" 1>&2 ;; esac return 1 } # modlib_force_start # forces start of the daemon modlib_force_start() { if [ -x /etc/init.d/rc.inetd ]; then config /etc/init.d/rc.inetd config $DAEMON fi modlib_start } # stop # could be overwritten in parent script stop() { local retval=0 case "$1" in 0) local id=$(cat "$PID_FILE" 2>/dev/null) local cnt=9 while [ $cnt -ge 0 ] && kill -0 $id 2>/dev/null; do kill $id 2>/dev/null local retval=$? sleep 1 let cnt-- done if kill -0 $id 2>/dev/null; then kill -9 $id 2>/dev/null local retval=$? sleep 1 kill -0 $id 2>/dev/null || local retval=0 fi ;; 5) killall $DAEMON_BIN 2>/dev/null ;; esac return $retval } # modlib_stop # stops the daemon # kills daemon with "stop" of rc.$DAEMON if available modlib_stop() { local fn=$PID_FILE local id=$(cat "$fn" 2>/dev/null) echo -n "Stopping ${DAEMON_LONG_NAME} ... " modlib_check_running case $? in 0) stop_pre stop 0 local retval=$? stop_post $retval if ! kill -0 $id 2>/dev/null && [ "$retval" -eq 0 ]; then rm -f "$fn" echo 'done.' else echo 'failed.' return $retval fi ;; 3) echo 'not running.' ;; 5) stop 5 echo 'inetd instances killed, done.' ;; *) echo 'status unknown, failed.' return 1 ;; esac return 0 } # modlib_force_stop # forces stop of the daemon modlib_force_stop() { echo -n "Stopping ${DAEMON_LONG_NAME} forced ... " FORCE_STATUS="0" modlib_stop >/dev/null if [ -e /etc/default.$DAEMON/*.inetd ]; then FORCE_STATUS="5" modlib_stop >/dev/null fi FORCE_STATUS="" echo 'done.' } # modlib_restart # restarts the daemon modlib_restart() { modlib_stop modlib_start } # modlib_force_restart # forces restart of the daemon modlib_force_restart() { modlib_force_stop modlib_force_start } # reload # could be overwritten in parent script reload() { local retval=1 case "$1" in 0) kill -HUP $(cat "$PID_FILE") 2> /dev/null local retval=$? ;; 5) killall -HUP $DAEMON_BIN 2>/dev/null 1>&2 local retval=0 ;; esac return $retval } # modlib_reload # reloads the daemon with SIGHUP # if available runs "config" of rc.$DAEMON # reloads daemon with "reload" of rc.$DAEMON if available modlib_reload() { local fn=$PID_FILE echo -n "Reloading ${DAEMON_LONG_NAME} ... " modlib_check_running case $? in 0) config reload 0 local retval=$? if [ $retval -eq 0 ]; then echo 'done.' return 0 else rm -f "$fn" echo 'failed.' return $retval fi ;; 3) echo 'not running.' ;; 5) config reload 5 echo 'inetd.' ;; *) echo 'status unknown, failed.' return 1 ;; esac return 0 } # modlib_status # checks if the daemon is running # return values: # 0: running # 3: stopped # 5: inetd # : unknown modlib_status() { modlib_check_running retval=$? case $retval in 0) echo 'running' ;; 3) echo 'stopped' ;; 5) echo 'inetd' ;; *) echo 'unknown' ;; esac return $retval } # modlib_loadconfig # loads the configuration modlib_loadconfig() { local CONF_FILE="/mod/etc/conf/${1-$CONF_NAME}.cfg" if [ ! -r "$CONF_FILE" ]; then echo "Error [${DAEMON_LONG_NAME}]: not configured." 1>&2 exit 1 fi . "$CONF_FILE" } # for each parameter passed creates symlink httpd-$parameter pointing to httpd modlib_add_httpd_symlink() { local HTTPD=$(which httpd) while [[ "$1" != "" ]]; do ln -sfn "$HTTPD" "/mod$HTTPD-$1" shift done } # load config [ -n "$DAEMON" ] && modlib_loadconfig