55 2008 Arjen de Korte <[email protected] > 66 2012-2017 Arnaud Quette <[email protected] > 77 2020-2025 Jim Klimov <[email protected] > 8+ 2025 desertwitch <[email protected] > 89
910 This program is free software; you can redistribute it and/or modify
1011 it under the terms of the GNU General Public License as published by
5051 static OVERLAPPED connect_overlapped ;
5152 static char * pipename = NULL ;
5253#endif /* WIN32 */
53- static int stale = 1 , alarm_active = 0 , alarm_status = 0 , ignorelb = 0 ;
54+ static int stale = 1 , alarm_active = 0 , alarm_status = 0 , ignorelb = 0 ,
55+ alarm_legacy_status = 0 ;
5456 static char status_buf [ST_MAX_VALUE_LEN ], alarm_buf [ST_MAX_VALUE_LEN ],
5557 buzzmode_buf [ST_MAX_VALUE_LEN ];
5658 static conn_t * connhead = NULL ;
@@ -1766,12 +1768,12 @@ int dstate_is_stale(void)
17661768/* clean out the temp space for a new pass */
17671769void status_init (void )
17681770{
1769- if (dstate_getinfo ("driver.flag.ignorelb" )) {
1770- ignorelb = 1 ;
1771- }
1771+ /* This does not normally change in driver run-time, but can in tests */
1772+ ignorelb = (dstate_getinfo ("driver.flag.ignorelb" ) ? 1 : 0 );
17721773
17731774 memset (status_buf , 0 , sizeof (status_buf ));
17741775 alarm_status = 0 ;
1776+ alarm_legacy_status = 0 ;
17751777}
17761778
17771779/* check if a status element has been set, return 0 if not, 1 if yes
@@ -1795,17 +1797,23 @@ static int status_set_callback(char *tgt, size_t tgtsize, const char *token)
17951797 }
17961798
17971799 if (!strcasecmp (token , "ALARM" )) {
1798- /* Drivers really should not raise alarms this way,
1799- * but for the sake of third-party forks, we handle
1800- * the possibility...
1800+ /* Drivers should not do this anymore, but we continue
1801+ * to support it. The upsmon notifiers do not care where
1802+ * alarm tokens get set and legacy drivers may still use
1803+ * this older method. The only real limitations are that
1804+ * the alarm state is very tightly coupled to the UPS
1805+ * status, and the ups.alarm variables do not get published
1806+ * in a controlled manner. Rather, these are very dependent
1807+ * on the (legacy) driver, and alarm notifications via upsmon
1808+ * will show placeholder "n/a" if all values are missing.
1809+ * The status token is ignored to prepend it to other tokens
1810+ * later, within the status_commit() function.
1811+ * For more information, see this discussion:
1812+ * https://github.com/networkupstools/nut/pull/2931#issuecomment-2841705269
18011813 */
1802- upsdebugx (2 , "%s: (almost) ignoring ALARM set as a status" , __func__ );
1803- if (!alarm_status && !alarm_active && strlen (alarm_buf ) == 0 ) {
1804- alarm_init (); /* no-op currently, but better be proper about it */
1805- alarm_set ("[N/A]" );
1806- }
1807- alarm_status ++ ;
1808- return 0 ;
1814+ upsdebugx (6 , "%s: caller set ALARM as a status, this is deprecated - please fix the NUT driver code" , __func__ );
1815+ alarm_legacy_status = 1 ;
1816+ return 0 ; /* ignore it */
18091817 }
18101818
18111819 /* Proceed adding the token */
@@ -1848,36 +1856,15 @@ void status_commit(void)
18481856 break ;
18491857 }
18501858
1851- /* NOTE: Not sure if any clients rely on ALARM being first if raised,
1852- * but note that if someone also uses status_set("ALARM") we can end
1853- * up with a "[N/A]" alarm value injected (if no other alarm was set)
1854- * and only add the token here so it remains first.
1855- *
1856- * NOTE: alarm_commit() must be executed before status_commit() for
1857- * this report to work!
1858- * * If a driver only called status_set("ALARM") and did not bother
1859- * with alarm_commit(), the "ups.alarm" value queries would have
1860- * returned NULL if not for the "sloppy driver" fix below, although
1861- * the "ups.status" value would report an ALARM token.
1862- * * If a driver properly used alarm_init() and alarm_set(), but then
1863- * called status_commit() before alarm_commit(), the "ups.status"
1864- * value would not know to report an ALARM token, as before.
1865- * * If a driver used both status_set("ALARM") and alarm_set() later,
1866- * the injected "[N/A]" value of the alarm (if that's its complete
1867- * value) would be overwritten by the explicitly assigned contents,
1868- * and an explicit alarm_commit() would be required for proper
1869- * reporting from a non-sloppy driver.
1870- */
1871-
1872- if (!alarm_active && alarm_status && !strcmp (alarm_buf , "[N/A]" )) {
1873- upsdebugx (2 , "%s: Assume sloppy driver coding that ignored alarm methods and used status_set(\"ALARM\") instead: commit the injected N/A ups.alarm value" , __func__ );
1874- alarm_commit ();
1875- }
1876-
1877- if (alarm_active ) {
1878- dstate_setinfo ("ups.status" , "ALARM %s" , status_buf );
1859+ if (alarm_active || alarm_legacy_status ) {
1860+ if (* status_buf != '\0' ) {
1861+ dstate_setinfo ("ups.status" , "ALARM %s" , status_buf );
1862+ } else {
1863+ dstate_setinfo ("ups.status" , "ALARM" );
1864+ }
18791865 } else {
18801866 dstate_setinfo ("ups.status" , "%s" , status_buf );
1867+ alarm_legacy_status = 0 ; /* just to be sure */
18811868 }
18821869}
18831870
0 commit comments