Made listener_print be CONST
[freeradius.git] / scripts / radwatch.in
index a3bd101..fd2bb65 100644 (file)
 #  reading the file doc/supervise-radiusd.txt
 
 #
+#  This simplifies the script, and avoids most issues with (say)
+#  Debian re-naming "radiusd" to "freeradius".
+#
+name=radiusd
+
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 sbindir=@sbindir@
 localstatedir=@localstatedir@
 logdir=@logdir@
-rundir=${localstatedir}/run/radiusd
+rundir=${localstatedir}/run/${name}
 sysconfdir=@sysconfdir@
-pid_file=${rundir}/radiusd.pid
-log_file=${logdir}/radiusd_safe.log
+pid_file=${rundir}/${name}.pid
+log_file=${logdir}/${name}_safe.log
 
-RADIUSD=$sbindir/radiusd
+#
+#  Figure out what arguments to pass tail
+#
+tail="tail -n "
+echo foo | ${tail}1 > /dev/null 2>&1
+if test "$?" != "0"
+then
+    tail="tail -"
+fi
+
+RADIUSD=$sbindir/${name}
 RADDBDIR=${sysconfdir}/raddb
 
 #
+#  If you want to send email, define this field to be an email address.
+#  This part of the functionality hasn't been well tested, so please
+#  test it before putting it into production.
+#
+#  It also presumes that you have a functioning mail system on
+#  the maching running RADIUS.  You will need to check that the
+#  "mail" command exists, and sends mail to the address below, e.g.:
+#
+#     echo test | mail -s "Testing" $MAILTO
+#
+#  If you receive the message, then enable MAILTO.  Otherwise, fix
+#  your mail system so that it delivers mail.
+#
+MAILTO=
+
+#
 #  Allow "radiusd_safe -X" for testing the radiusd_safe functionality.
 #
 ARGS="$@"
@@ -49,12 +80,6 @@ ARGS="$@"
 test -f $RADIUSD || exit 0
 test -f $RADDBDIR/radiusd.conf || exit 0
 
-#
-#  This simplifies the script, and avoids most issues with (say)
-#  Debian re-naming "radiusd" to "freeradius".
-#
-name=`basename $RADIUSD`
-
 ulimit -c unlimited
 
 #
@@ -89,15 +114,20 @@ then
 fi
 
 started=0
+restarts=0
+last_email=0
+now=0
+
+#
+#  Save our PID.
+#
+echo $$ > ${rundir}/${name}_safe.pid
 
 #
 #  Loop forever, or until we're told to exit via a signal.
 #
 while :
 do
-    mysig=
-    trap 'mysig=yes' HUP TERM INT QUIT TSTP
-
     #
     #  The first time around, just start the server.
     #  After that, see if we are re-starting in the same second
@@ -108,14 +138,63 @@ do
     #  This helps prevent CPU spikes when something goes catastrophically
     #  wrong, and the server re-starts continuously.  (e.g. disk full, etc.)
     #
+    now_s=`date +'%a %b %e %H:%M:%S %Y'`
     if test "$started" != "0"
     then
-       if test "$started" = `date +"%s"`
+       #  Send mail when the server starts
+       if test "$MAILTO" != ""
        then
+           # don't print minutes and seconds: cheap way
+           # of sending email only once an hour.
+           now=`date +'%a %b %e %H %Y'`
+           restarts=`expr $restarts + 1`
+
+           # send email the first time it restarts
+           if test "$last_email" = "0"
+           then
+                   cat |  mail -s "ERROR - $name died, restarting.." $MAILTO <<EOF
+$name has restarted unexpectedly at $now
+
+See $log_file for details.  Last 20 lines are:
+
+----------------------------------------------------------------------
+`${tail}20 $log_file`
+EOF
+               last_email="$now"
+               restarts=0
+           else
+               #  Send email only once every hour (or so)
+               if test "$now" != "$last_email"
+               then
+                   cat |  mail -s "ERROR - $name died, restarting.." $MAILTO <<EOF
+$name has restarted $restarts times since last email at $last_email
+
+See $log_file for details.  Last 100 lines are:
+
+----------------------------------------------------------------------
+`${tail}100 $log_file`
+EOF
+                   last_email="$now"
+                   restarts=0
+               fi
+           fi
+       fi
+
+       if test "$started" = "$now_s"
+       then
+           #  Allow us to be killed
+           trap - HUP INT QUIT TERM TSTP
            sleep 1
        fi
     fi
-    started=`date +"%s"`
+    started="$now_s"
+
+    mysig=
+    trap 'mysig=1' HUP
+    trap 'mysig=2' INT
+    trap 'mysig=3' QUIT
+    trap 'mysig=15' TERM
+    trap 'mysig=18' TSTP
 
     eval "$RADIUSD -f $ARGS < /dev/null >> $log_file 2>&1 &"
     PID=$!
@@ -134,7 +213,22 @@ do
     #
     wait $PID
     code=$?
-    
+
+    #
+    #  On *BSD and Linux, sending *us* a signal results in "wait" returning
+    #  with 128+sig.  On Solaris, it results in "wait" returning with "0".
+    #
+    #  If this happens, we reset our expectations here so that the code
+    #  below will work correctly.
+    #
+    if test "$code" = "0"
+    then
+       if test "$mysig" != ""
+       then
+           code=`expr $mysig + 128`
+       fi
+    fi
+
     case "$code" in
        0)
            echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited normally.  Exiting" | tee -a $log_file
@@ -158,10 +252,10 @@ do
                #
                #  Was the signal sent to us, or to the child process?
                #
-               if test "$mysig" = "yes"
+               if test "$mysig" != ""
                then
                    echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: Caught signal $sig: Signalling $name to exit." | tee -a $log_file
-                   kill -`expr $code - 128` $PID
+                   kill -$sig $PID
                    break
                else
                    echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly on signal $sig.  Restarting it." | tee -a $log_file
@@ -171,5 +265,5 @@ do
     esac
 done
 
-rm -f $pid_file
+rm -f $pid_file ${rundir}/${name}_safe.pid
 exit 0