Here is patch 1 of 2.  Roger

diff -rup nut-2.7.4.orig/clients/upsmon.c nut-2.7.4.dev/clients/upsmon.c
--- nut-2.7.4.orig/clients/upsmon.c     2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/clients/upsmon.c      2016-07-01 09:46:21.567766415 +0200
@@ -525,6 +525,18 @@ static int get_var(utype_t *ups, const c
                numq = 2;
        }

+       /* Subcommands for polling SIGUSR1, SIGUSR2  RP */
+       if (strcmp(var, "SIGUSR1") == 0) {
+               query[0] = "SIGUSR1";
+               query[1] = ups->upsname;
+               numq = 2;
+       }
+       if (strcmp(var, "SIGUSR2") == 0) {
+               query[0] = "SIGUSR2";
+               query[1] = ups->upsname;
+               numq = 2;
+       }
+
        if (!strcmp(var, "status")) {
                query[0] = "VAR";
                query[1] = ups->upsname;
@@ -1518,7 +1530,25 @@ static void pollups(utype_t *ups)
        if (get_var(ups, "status", status, sizeof(status)) == 0) {
                clear_alarm();
                parse_status(ups, status);
-               return;
+               /* All is well, continue to poll SIGUSR1 RP */
+      set_alarm();
+               if (get_var(ups, "SIGUSR1", status, sizeof(status)) == 0) {
+                       clear_alarm();
+                       if ( ! (strcmp(status,"0") == 0)) {  /* See K&R p.53 */
+                               /* We have a SIGUSR1 */
+            do_notify(ups, NOTIFY_SIGUSR1);
+                       }
+                       /* All is well, continue to poll SIGUSR2 RP */
+                       set_alarm();
+                       if (get_var(ups, "SIGUSR2", status, sizeof(status)) == 
0) {
+                               clear_alarm();
+                               if ( ! (strcmp(status,"0") == 0)) {
+                                       /* We have a SIGUSR2 */
+                                       do_notify(ups, NOTIFY_SIGUSR2);
+                               }
+                       }
+                       return;
+               }
        }

        /* fallthrough: no communications */
diff -rup nut-2.7.4.orig/clients/upsmon.h nut-2.7.4.dev/clients/upsmon.h
--- nut-2.7.4.orig/clients/upsmon.h     2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/clients/upsmon.h      2016-06-20 11:24:20.494863128 +0200
@@ -68,13 +68,15 @@ typedef struct {
 #define NOTIFY_ONLINE  0       /* UPS went on-line                     */
 #define NOTIFY_ONBATT  1       /* UPS went on battery                  */
 #define NOTIFY_LOWBATT 2       /* UPS went to low battery              */
-#define NOTIFY_FSD     3       /* Master upsmon set FSD flag           */
+#define NOTIFY_FSD     3       /* Master upsmon set FSD flag           */
 #define NOTIFY_COMMOK  4       /* Communication established            */
 #define NOTIFY_COMMBAD 5       /* Communication lost                   */
 #define NOTIFY_SHUTDOWN        6       /* System shutdown in progress          
*/
 #define NOTIFY_REPLBATT        7       /* UPS battery needs to be replaced     
*/
 #define NOTIFY_NOCOMM  8       /* UPS hasn't been contacted in awhile  */
 #define NOTIFY_NOPARENT        9       /* privileged parent process died       
*/
+#define NOTIFY_SIGUSR1 10      /* Server received SIGUSR1 RP */
+#define NOTIFY_SIGUSR2 11      /* Server received SIGUSR2 RP */

 /* notify flag values */

@@ -97,13 +99,15 @@ struct {
        { NOTIFY_ONLINE,   "ONLINE",   NULL, "UPS %s on line power", 
NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_ONBATT,   "ONBATT",   NULL, "UPS %s on battery", NOTIFY_SYSLOG 
| NOTIFY_WALL },
        { NOTIFY_LOWBATT,  "LOWBATT",  NULL, "UPS %s battery is low", 
NOTIFY_SYSLOG | NOTIFY_WALL },
-       { NOTIFY_FSD,      "FSD",      NULL, "UPS %s: forced shutdown in 
progress", NOTIFY_SYSLOG | NOTIFY_WALL },
+       { NOTIFY_FSD,       "FSD",      NULL, "UPS %s: forced shutdown in 
progress", NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_COMMOK,   "COMMOK",   NULL, "Communications with UPS %s 
established", NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_COMMBAD,  "COMMBAD",  NULL, "Communications with UPS %s lost", 
NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_SHUTDOWN, "SHUTDOWN", NULL, "Auto logout and shutdown 
proceeding", NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_REPLBATT, "REPLBATT", NULL, "UPS %s battery needs to be 
replaced", NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_NOCOMM,   "NOCOMM",   NULL, "UPS %s is unavailable", 
NOTIFY_SYSLOG | NOTIFY_WALL },
        { NOTIFY_NOPARENT, "NOPARENT", NULL, "upsmon parent process died - shutdown 
impossible", NOTIFY_SYSLOG | NOTIFY_WALL },
+       { NOTIFY_SIGUSR1,  "SIGUSR1",  NULL, "UPS % received SIGUSR1", 
NOTIFY_SYSLOG },  /* No default wall for SIGUSR1 RP */
+       { NOTIFY_SIGUSR2,  "SIGUSR2",  NULL, "UPS % received SIGUSR2", 
NOTIFY_SYSLOG },  /* No default wall for SIGUSR2 RP */
        { 0, NULL, NULL, NULL, 0 }
 };

diff -rup nut-2.7.4.orig/clients/upssched.c nut-2.7.4.dev/clients/upssched.c
--- nut-2.7.4.orig/clients/upssched.c   2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/clients/upssched.c    2016-06-30 16:56:32.911812443 +0200
@@ -686,6 +686,10 @@ static void sendcmd(const char *cmd, con
        if (!arg1)
                return;

+ if (verbose > 1) { /* Detailed trace of timer actions RP */ + upslogx(LOG_NOTICE, "%s: cmd=%s, arg1=%s, arg2=%s", __func__, cmd, arg1, arg2);
+       }
+
        /* build the request */
        snprintf(buf, sizeof(buf), "%s \"%s\"",
                cmd, pconf_encode(arg1, enc, sizeof(enc)));
@@ -902,6 +906,8 @@ int main(int argc, char **argv)
 {
        const char      *prog = xbasename(argv[0]);

+       /* Please keep this very useful trace of upssched activity.  RP)
+      0 = no trace, 1 = trace, 2 = detailed trace. */
        verbose = 1;            /* TODO: remove when done testing */

        /* normally we don't have stderr, so get this going to syslog early */
diff -rup nut-2.7.4.orig/common/common.c nut-2.7.4.dev/common/common.c
--- nut-2.7.4.orig/common/common.c      2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/common/common.c       2016-07-01 09:51:14.779883781 +0200
@@ -407,10 +407,25 @@ void upslogx(int priority, const char *f
 void upsdebug_with_errno(int level, const char *fmt, ...)
 {
        va_list va;
- - if (nut_debug_level < level)
-               return;
+       /* Sysadmin may use "echo n > /etc/ups/NUT_DEBUG_LEVEL" to set debug 
level n. RP */
+       char    fn[SMALLBUF];
+   FILE *fp;
+   int   ndl;   /* 0 through 4 */
+
+       snprintf(fn, sizeof(fn), "%s/NUT_DEBUG_LEVEL", confpath());  /* E.g. 
/etc/ups/NUT_DEBUG_LEVEL RP */
+   fp = fopen(fn, "r");
+       if (!fp) {
+               ndl = 0;     /* Ignore errors */
+       } else {
+      if (fscanf(fp, "%d", &ndl) != 1) {
+         ndl = 0;  /* Ignore errors */
+      }
+               fclose(fp);
+       }

+       if (nut_debug_level < level && ndl < level) {
+               return;
+   }
        va_start(va, fmt);
        vupslog(LOG_DEBUG, fmt, va, 1);
        va_end(va);
@@ -419,10 +434,25 @@ void upsdebug_with_errno(int level, cons
 void upsdebugx(int level, const char *fmt, ...)
 {
        va_list va;
- - if (nut_debug_level < level)
-               return;
+       /* Sysadmin may use "echo n > /etc/ups/NUT_DEBUG_LEVEL" to set debug 
level n. RP */
+       char    fn[SMALLBUF];
+   FILE *fp;
+   int   ndl;   /* 0 through 4 */
+
+       snprintf(fn, sizeof(fn), "%s/NUT_DEBUG_LEVEL", confpath());  /* E.g. 
/etc/ups/NUT_DEBUG_LEVEL RP */
+   fp = fopen(fn, "r");
+       if (!fp) {
+               ndl = 0;     /* Ignore errors */
+       } else {
+      if (fscanf(fp, "%d", &ndl) != 1) {
+         ndl = 0;  /* Ignore errors */
+      }
+               fclose(fp);
+       }

+       if (nut_debug_level < level && ndl < level) {
+               return;
+       }
        va_start(va, fmt);
        vupslog(LOG_DEBUG, fmt, va, 0);
        va_end(va);
diff -rup nut-2.7.4.orig/server/netget.c nut-2.7.4.dev/server/netget.c
--- nut-2.7.4.orig/server/netget.c      2016-03-08 13:01:11.000000000 +0100
+++ nut-2.7.4.dev/server/netget.c       2016-06-29 15:36:45.829340912 +0200
@@ -44,6 +44,51 @@ static void get_numlogins(nut_ctype_t *c
        sendback(client, "NUMLOGINS %s %d\n", upsname, ups->numlogins);
 }

+/* The SIGUSR1 and SIGUSR2 signals to the UPS's are received and remembered
+   by the server on behalf of the UPS's.  RP */
+static void get_sigusr1(nut_ctype_t *client, const char *upsname)
+{
+       upstype_t       *ups;
+
+       ups = get_ups_ptr(upsname);
+
+       if (!ups) {
+               send_err(client, NUT_ERR_UNKNOWN_UPS);
+               return;
+       }
+
+       if (!ups_available(ups, client))
+               return;
+
+       sendback(client, "SIGUSR1 %s %d\n", upsname, ups->sigusr1);
+   if (ups->sigusr1 > 0) {
+               --(ups->sigusr1);     /* If still >0 further user signals await 
a GET */
+               upsdebugx(1, "%s: UPS %s, sigusr1 down to %d", __func__, 
ups->name, ups->sigusr1);
+       }
+}
+
+static void get_sigusr2(nut_ctype_t *client, const char *upsname)
+{
+       upstype_t       *ups;
+
+       ups = get_ups_ptr(upsname);
+
+       if (!ups) {
+               send_err(client, NUT_ERR_UNKNOWN_UPS);
+               return;
+       }
+
+       if (!ups_available(ups, client))
+               return;
+
+       sendback(client, "SIGUSR2 %s %d\n", upsname, ups->sigusr2);
+
+   if (ups->sigusr2 > 0) {
+               --(ups->sigusr2);     /* If still >0 further user signals await 
a GET */
+               upsdebugx(1, "%s: UPS %s, sigusr2 down to %d", __func__, 
ups->name, ups->sigusr2);
+       }
+}
+
 static void get_upsdesc(nut_ctype_t *client, const char *upsname)
 {
        const   upstype_t       *ups;
@@ -229,6 +274,18 @@ void net_get(nut_ctype_t *client, int nu
                return;
        }

+       /* GET SIGUSR1 UPS  RP */
+       if (!strcasecmp(arg[0], "SIGUSR1")) {
+               get_sigusr1(client, arg[1]);
+               return;
+       }
+
+       /* GET SIGUSR2 UPS  RP */
+       if (!strcasecmp(arg[0], "SIGUSR2")) {
+               get_sigusr2(client, arg[1]);
+               return;
+       }
+
        /* GET UPSDESC UPS */
        if (!strcasecmp(arg[0], "UPSDESC")) {
                get_upsdesc(client, arg[1]);
diff -rup nut-2.7.4.orig/server/upsd.c nut-2.7.4.dev/server/upsd.c
--- nut-2.7.4.orig/server/upsd.c        2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/server/upsd.c 2016-07-01 09:56:59.589903339 +0200
@@ -848,6 +848,32 @@ static void set_exit_flag(int sig)
        exit_flag = sig;
 }

+static void sigusr1_handler(int sig)
+{
+ /* SIGUSR1 signals are passed on to every known UPS RP */ + upstype_t *u;
+
+       for (u = firstups; u; u = u->next) {
+               if ( u->sigusr1 < MAX_SIGUSR1 ) {
+                       (u->sigusr1)++;
+                       upsdebugx(1, "%s: UPS %s, sigusr1 up to %d", __func__, 
u->name, u->sigusr1);
+               }
+       }
+}
+
+static void sigusr2_handler(int sig)
+{
+ /* SIGUSR2 signals are passed on to every known UPS RP */ + upstype_t *u;
+
+       for (u = firstups; u; u = u->next) {
+               if ( u->sigusr2 < MAX_SIGUSR2 ) {
+                       (u->sigusr2)++;
+                       upsdebugx(1, "%s: UPS %s, sigusr2 up to %d", __func__, 
u->name, u->sigusr2);
+               }
+       }
+}
+
 static void setup_signals(void)
 {
        struct sigaction        sa;
@@ -869,6 +895,12 @@ static void setup_signals(void)
        /* handle reloading */
        sa.sa_handler = set_reload_flag;
        sigaction(SIGHUP, &sa, NULL);
+
+       /* Handle user signals. RP */
+       sa.sa_handler = sigusr1_handler;
+       sigaction(SIGUSR1, &sa, NULL);
+       sa.sa_handler = sigusr2_handler;
+       sigaction(SIGUSR2, &sa, NULL);
 }

 void check_perms(const char *fn)
diff -rup nut-2.7.4.orig/server/upsd.h nut-2.7.4.dev/server/upsd.h
--- nut-2.7.4.orig/server/upsd.h        2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/server/upsd.h 2016-06-16 12:28:07.066830712 +0200
@@ -80,6 +80,11 @@ extern nut_ctype_t   *firstclient;
 #define SIGCMD_STOP    SIGTERM
 #define SIGCMD_RELOAD  SIGHUP

+/* How many user signals may be sent in a burst? RP */
+
+#define MAX_SIGUSR1 1       /* Safe */
+#define MAX_SIGUSR2 8       /* Experimental */
+
 /* awkward way to make a string out of a numeric constant */

 #define string_const_aux(x)    #x
diff -rup nut-2.7.4.orig/server/upstype.h nut-2.7.4.dev/server/upstype.h
--- nut-2.7.4.orig/server/upstype.h     2015-12-29 13:08:34.000000000 +0100
+++ nut-2.7.4.dev/server/upstype.h      2016-06-23 16:35:18.940499226 +0200
@@ -46,6 +46,9 @@ typedef struct upstype_s {
        PCONF_CTX_t             sock_ctx;
        struct st_tree_s        *inforoot;
        struct cmdlist_s        *cmdlist;
+ + int sigusr1; /* Each UPS receives the SIGUSR1 sent to server. RP */
+       int   sigusr2;  /* Each UPS receives the SIGUSR2 sent to server. RP */

        int     numlogins;
        int     fsd;            /* forced shutdown in effect? */

_______________________________________________
Nut-upsdev mailing list
Nut-upsdev@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev

Reply via email to