#!/bin/sh # /etc/init.d/nutwrapper.sh ### BEGIN INIT INFO # Provides: nutwrapper # Required-Start: apcupsd $network $remote_fs $syslog # Required-Stop: apcupsd $network $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Nut server wrapper for apcupsd # Description: Nut server emulator service for apcupsd ### END INIT INFO # Do NOT "set -e" # This script provides service for Nut server emulator(on apcupsd) created by Martin (Machtl) Lang. # Script is used for automatic starting after boot or manual stop/start/reload/restart of the service. # For activation of the service you should run "sudo systemctl daemon-reload" after you copy the script # to "/etc/init.d" directory. # For installation of the service to the boot sequence you should run: # "sudo update-rc.d /etc/init.d/nutwrapper.sh defaults" # For manual control of the service you can use: # "sudo /etc/init.d/nutwrapper.sh status/start/stop/reload/restart" # or "sudo service nutwrapper status/start/stop/reload/restart" # or "sudo systemctl status/start/stop/reload/restart nutwrapper" # The credit & our thanks for creating this emulator belong to Martin Lang # For more details about this project please visit https://www.reddit.com/r/homelab/comments/ar0h9l/apcupsd_nut_wrapper_script_apcupsd_and_nut_on_the/ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin DESC="Nut server wrapper for apcupsd" NAME=nutwrapper USERNAME=root PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME.sh LOGFILE=/root/$NAME.log WSCRIPTNAME=/usr/local/bin/usvnutwrapper.sh DAEMON=/usr/bin/tcpserver DAEMON_ARGS="-q -HR" # General options for tcpserver DAEMON_ARGS="$DAEMON_ARGS -c 10" # Maximal number of NUT clients DAEMON_ARGS="$DAEMON_ARGS 0.0.0.0" # TCP service internal address DAEMON_ARGS="$DAEMON_ARGS 3493" # TCP service port for NUT clients DAEMON_ARGS="$DAEMON_ARGS $WSCRIPTNAME" # NUT wrapper main script name # Load the VERBOSE setting and other rcS variables [ -f "/lib/init/vars.sh" ] || exit 1 . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. [ -f "/lib/lsb/init-functions" ] || exit 1 . /lib/lsb/init-functions pidof_daemon() { # if there is actually a nutwrapper process whose pid is in PIDFILE, # print it and return 0. if [ -e "$PIDFILE" ]; then if pidof "$DAEMON" | tr ' ' '\n' | grep -w $(cat $PIDFILE); then return 0 fi fi return 1 } # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started # Exit if apcupsd package is not installed if [ ! $(command -v "apcupsd") ]; then log_failure_msg "Please check that package apcupsd is installed." return 2 fi # Exit if tcpserver is not installed if [ ! $(command -v "$DAEMON") ]; then log_failure_msg "Please check that tcpserver is installed." return 2 fi # Exit if main wrapper script is not installed if [ ! -f "$WSCRIPTNAME" ]; then log_failure_msg "Please check that wrapper script $WSCRIPTNAME is installed." return 2 fi start-stop-daemon --chuid $USERNAME --start --quiet --make-pidfile --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --background --no-close --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred PID=$(pidof_daemon) || true if [ "${PID}" ]; then CHILD_PIDS=$(ps -o pid= --ppid "${PID}") fi start-stop-daemon --stop --quiet --retry=TERM/2/KILL/5 --remove-pidfile --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be needed by services started subsequently. A last resort is # to sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/2/KILL/5 --exec $DAEMON # Kill the remaining child processess of the daemon PID if any if [ "${CHILD_PIDS}" ]; then for chpid in ${CHILD_PIDS}; do kill -9 $chpid > /dev/null 2>&1; done fi # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; reload) [ "$VERBOSE" != no ] && log_daemon_msg "Reloading $DESC" "$NAME" PID=$(pidof_daemon) || true if [ "${PID}" ]; then # Kill the child processess of the daemon PID if any # They will be re-started automatically # But don't kill the daemon process PID kill -9 $(ps -o pid= --ppid "${PID}") > /dev/null 2>&1 log_end_msg 0 else log_end_msg 1 fi ;; restart) [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload}" >&2 exit 3 ;; esac :