LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File upsd.init of Package nut (Project DISCONTINUED:openSUSE:10.3:Update)

#! /bin/sh
# Copyright (c) 1995-2006  SUSE / Novell Inc.
# All rights reserved.
#
# Author: Frank Lemser
#	  Wolfgang Rosenauer, 2000-2003
#	  Arjen de Korte, 2006
#	  Stanislav Brabec, 2006
# Please send feedback to http://www.suse.de/feedback/
#
# /etc/init.d/upsd
#   and its symbolic link
# /(usr/)sbin/rcupsd
#
#    This program is free software; you can redistribute it and/or modify 
#    it under the terms of the GNU General Public License as published by 
#    the Free Software Foundation; either version 2 of the License, or 
#    (at your option) any later version. 
# 
#    This program is distributed in the hope that it will be useful, 
#    but WITHOUT ANY WARRANTY; without even the implied warranty of 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
#    GNU General Public License for more details. 
# 
#    You should have received a copy of the GNU General Public License 
#    along with this program; if not, write to the Free Software 
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# System startup script for NUT UPS daemon
#
# LSB compatible service control script; see http://www.linuxbase.org/spec/
# 
### BEGIN INIT INFO
# Provides:          ups
# Required-Start:    $network $syslog $remote_fs
# Should-Start:      $time ypbind sendmail
# Required-Stop:     $network $syslog $remote_fs
# Should-Stop:       $time ypbind sendmail
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: UPS monitoring software (remote/local)
# Description:       Network UPS Tools provides remote or local
#	monitoring of UPS.
### END INIT INFO
#
# Note on runlevels:
# 0 - halt/poweroff 			6 - reboot
# 1 - single user			2 - multiuser without network exported
# 3 - multiuser w/ network (text mode)  5 - multiuser w/ network and X11 (xdm)
# 

DRIVER_BIN=/usr/lib/ups/driver
DRIVER_RUN=/var/lib/ups

# Location of upsd.pid file:
UPSD_PID=${DRIVER_RUN}/upsd.pid

# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
UPSD_BIN=/usr/sbin/upsd
UPSMON_BIN=/usr/sbin/upsmon
UPSDRVCTL_BIN=$DRIVER_BIN/upsdrvctl
test -x $UPSD_BIN || { echo "$UPSD_BIN not installed"; 
	if [ "$1" = "stop" ]; then exit 0;
	else exit 5; fi; }
test -x $UPSMON_BIN || { echo "$UPSMON_BIN not installed"; 
	if [ "$1" = "stop" ]; then exit 0;
	else exit 5; fi; }
test -x $UPSDRVCTL_BIN || { echo "$UPSDRVCTL_BIN not installed"; 
	if [ "$1" = "stop" ]; then exit 0;
	else exit 5; fi; }

# Check for existence of needed config files
UPS_CONFIG=/etc/ups/ups.conf
UPSD_CONFIG=/etc/ups/upsd.conf
UPSMON_CONFIG=/etc/ups/upsmon.conf
test -r $UPS_CONFIG    || { echo "$UPS_CONFIG not existing";
	if [ "$1" = "stop" ]; then exit 0; else exit 6; fi;
}
test -r $UPSD_CONFIG   || { echo "$UPSD_CONFIG not existing";
	if [ "$1" = "stop" ]; then exit 0; else exit 6; fi;
}
test -r $UPSMON_CONFIG || { echo "$UPSMON_CONFIG not existing";
	if [ "$1" = "stop" ]; then exit 0; else exit 6; fi;
}
# verify, that we have at least a configured monitor
grep -q '^MONITOR' $UPSMON_CONFIG || {
	echo "$UPSMON_CONFIG not configured";
	if [ "$1" = "stop" ]; then exit 0; else exit 6; fi;
}
# verify, that user configured ups.conf.
if grep -q '^[[:space:]][[:space:]]*driver[[:space:]]*=[[:space:]]*undefined' $UPS_CONFIG ; then
	echo "$UPS_CONFIG not configured, see /usr/share/doc/packages/nut/README.SUSE";
	if [ "$1" = "stop" ]; then exit 0; else exit 6; fi;
fi

# Preconfigured user ID of UPS devices.
UPSD_USER="@UPSD_USER@"

# Owner of UPS port devices (empty to skip device check):
UPS_OWNER="$UPSD_USER:root"

# If this file exists, power is failing.
POWERDOWNFLAG=$(sed -n 's/^POWERDOWNFLAG[[:space:]]*//p' </etc/ups/upsmon.conf)

# Shell functions sourced from /etc/rc.status:
#      rc_check         check and set local and overall rc status
#      rc_status        check and set local and overall rc status
#      rc_status -v     be verbose in local rc status and clear it afterwards
#      rc_status -v -r  ditto and clear both the local and overall rc status
#      rc_status -s     display "skipped" and exit with status 3
#      rc_status -u     display "unused" and exit with status 3
#      rc_failed        set local and overall rc status to failed
#      rc_failed <num>  set local and overall rc status to <num>
#      rc_reset         clear both the local and overall rc status
#      rc_exit          exit appropriate to overall rc status
#      rc_active        checks whether a service is activated by symlinks
. /etc/rc.status

# Reset status of this service
rc_reset

# Return values acc. to LSB for all commands but status:
# 0	  - success
# 1       - generic or unspecified error
# 2       - invalid or excess argument(s)
# 3       - unimplemented feature (e.g. "reload")
# 4       - user had insufficient privileges
# 5       - program is not installed
# 6       - program is not configured
# 7       - program is not running
# 8--199  - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
# 
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signaling is not supported) are
# considered a success.

case "$1" in
    start)
	test -n "$POWERDOWNFLAG" && rm -f "$POWERDOWNFLAG"
	if grep -q '^\[' $UPS_CONFIG ; then
	    # Read current user in the config:
	    USER=$(sed -n 's/^[[:space:]]*user[[:space:]]*=[[:space:]]*//p' < $UPS_CONFIG)
	    if test -n "$USER" ; then
		UPS_OWNER="$USER:root"
		UPSD_USER="$USER"
	    fi

	    if test -n "$UPS_OWNER" ; then
		PORTS=$(sed -n 's/^[[:space:]][[:space:]]*port[[:space:]]*=[[:space:]]*//p' < $UPS_CONFIG)
		## Change permissions of undetectable ports (for detectable ports it's done by udev).
		for PORT in $PORTS ; do
		    if test -L "$PORT" ; then
			PORT=$(readlink -f $PORT)
		    fi
		    case "$PORT" in
		    /dev/ttyS* )
			chown $UPS_OWNER $PORT || { rc_failed ; rc_status -v ; rc_exit ; }
			;;
		    esac
		done
	    fi

	    echo -n "Starting NUT UPS drivers "
	    # Do not start upsdrvctl more times.
	    if ! test -f /var/run/upsdrvctl ; then
		## Start daemon with startproc(8). If this fails
		## the return value is set appropriately by startproc.
		$UPSDRVCTL_BIN start >/dev/null 2>&1 || rc_failed
		# Remember status and be verbose
		rc_status -v || rc_exit
		touch /var/run/upsdrvctl
	    else
		rc_status -s ; rc_reset
	    fi

	    echo -n "Starting NUT UPS server "
	    ## Start daemon with startproc(8). If this fails
	    ## the return value is set appropriately by startproc.
	    startproc -q -p $UPSD_PID $UPSD_BIN ${UPSD_USER:+-u $UPSD_USER} || {
		rc=$?
		$UPSDRVCTL_BIN stop >/dev/null 2>&1
		rc_failed $rc
            }
	    # Remember status and be verbose
	    rc_status -v || rc_exit
	fi

	echo -n "Starting NUT UPS monitor "
	## Start daemon with startproc(8). If this fails
	## the return value is set appropriately by startproc.
	/sbin/startproc -q $UPSMON_BIN

	# Remember status and be verbose
	rc_status -v
	;;
    stop)
	echo -n "Shutting down NUT UPS monitor "
	## Stop daemon with killproc(8) and if this fails
	## killproc sets the return value according to LSB.
	/sbin/killproc -TERM $UPSMON_BIN
	# Remember status and be verbose
	rc_status -v

	echo -n "Shutting down NUT UPS server "
	## Stop daemon with killproc(8) and if this fails
	## killproc sets the return value according to LSB.
	killproc -TERM -p $UPSD_PID $UPSD_BIN
	# Remember status and be verbose
	rc_status -v

	# NOTE: Command should return OK, if no drivers are running.
	# WARNING: There is no chance to stop daemons after ups.conf change!
	# (except of some sort of find for pid's in ${DRIVER_RUN} dir )
	echo -n "Shutting down NUT UPS drivers"
	$UPSDRVCTL_BIN stop >/dev/null 2>&1 || :
	# Remember status and be verbose
	FAILED=true
	for (( n=0 ; n<10 ; n++ )) ; do
	    if ! pgrep >/dev/null -f /usr/lib/ups/driver ; then
		echo -n " "
		FAILED=false
		break
	    fi
	    sleep 1
	    echo -n "."
	done
	if $FAILED ; then
	    # Try again with pkill. Maybe configuration was changed.
	    # Drivers are not properly terminated after configuration
	    # change.
	    for (( n=0 ; n<10 ; n++ )) ; do
		if ! pkill -TERM >/dev/null -f /usr/lib/ups/driver ; then
		    echo -n " "
		    FAILED=false
		    break
		fi
		sleep 1
		echo -n "."
	    done
	fi
	if $FAILED ; then
	    rc_failed
	fi
	rm -f /var/run/upsdrvctl
	rc_status -v
	;;
    try-restart|condrestart)
	## Do a restart only if the service was active before.
	## Note: try-restart is now part of LSB (as of 1.9).
	## RH has a similar command named condrestart.
	if test "$1" = "condrestart"; then
		echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
	fi
	$0 status
	if test $? = 0; then
		$0 restart
	else
		rc_reset	# Not running is not a failure.
	fi
	# Remember status and be quiet
	rc_status
	;;
    restart)
	## Stop the service and regardless of whether it was
	## running or not, start it again.
	$0 stop
	$0 start

	# Remember status and be quiet
	rc_status
	;;
    force-reload)
	## Signal the daemon to reload its config. Most daemons
	## do this on signal 1 (SIGHUP).
	echo -n "Reload service NUT UPS "
	## if it supports it:
	$UPSDRVCTL_BIN stop >/dev/null 2>&1 || :
	$UPSDRVCTL_BIN start >/dev/null 2>&1 || :
	/sbin/killproc -HUP -p $UPSD_PID $UPSD_BIN
	/sbin/killproc -HUP $UPSMON_BIN
	rc_status -v
	;;
    reload)
	## Signal the daemon to reload its config. Most daemons
	## do this on signal 1 (SIGHUP).
	# WARNING: upsdrvctl does not support reload!
	# Use force-reload unstead.
	echo -n "Reload service NUT UPS (excluding upsdrvctl) "
	## if it supports it:
	/sbin/killproc -HUP -p $UPSD_PID $UPSD_BIN
	/sbin/killproc -HUP $UPSMON_BIN
	rc_status -v
	;;
    status)
	## Check status with checkproc(8), if process is running
	## checkproc will return with exit status 0.

	# Return value is slightly different for the status command:
	# 0 - service up and running
	# 1 - service dead, but /var/run/  pid  file exists
	# 2 - service dead, but /var/lock/ lock file exists
	# 3 - service not running (unused)
	# 4 - service status unknown :-(
	# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
	
	# NOTE: checkproc returns LSB compliant status values.
	# NOTE: rc_status knows that we called this init script with
	# "status" option and adapts its messages accordingly.

	echo -n "Checking for service NUT UPS server "
	/sbin/checkproc -p $UPSD_PID $UPSD_BIN
	# show & reset status - we need the status from monitor for
	# try-restart in case that only the monitor is running.
	rc_status -v -r

	echo -n "Checking for service NUT UPS monitor "
	/sbin/checkproc $UPSMON_BIN
	rc_status -v
	;;
    probe)
	## Optional: Probe for the necessity of a reload, print out the
	## argument to this init script which is required for a reload.
	## Note: probe is not (yet) part of LSB (as of 1.9)
	if test -f $UPSD_PID && test $UPS_CONFIG -nt $UPSD_PID ; then
		echo reload
	elif test -f $UPSD_PID && test $UPSD_CONFIG -nt $UPSD_PID ; then
		echo reload
	elif test -f $UPSD_PID && test /etc/ups/upsd.users -nt $UPSD_PID ; then
		echo reload
	elif  test -f /var/run/upsmon.pid && test $UPS_CONFIG -nt /var/run/upsmon.pid ; then
		echo reload
	elif  test -f /var/run/upsmon.pid && test $UPSMON_CONFIG -nt /var/run/upsmon.pid ; then
		echo reload
	elif  test -f /var/run/upsmon.pid && test /etc/ups/upsd.users -nt /var/run/upsmon.pid ; then
		echo reload
	fi
	;;
    powerdown)
	## Special command: Instruct UPS to shutdown.
	sync &
	if grep -q '^\[' $UPS_CONFIG ; then
	    echo -n "Instructing UPS to powerdown "
	    $UPSDRVCTL_BIN shutdown >/dev/null 2>&1 || rc_failed
	    rc_check
	else
	    echo "No local UPS defined, skipping powerdown "
	fi
	rc_status -v
	;;
    try-powerdown)
	## Special command: Instruct UPS to shutdown, if halt is running
	## and power is failing. Otherwise silently quit.
	if test "$RUNLEVEL" = "0" -a -n "$POWERDOWNFLAG" -a -f "$POWERDOWNFLAG" ; then
	    exec $0 powerdown
	fi
	;;
    *)
	echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe|powerdown|try-powerdown}"
	exit 1
	;;
esac
rc_exit