2424#include "state.h"
2525#include "desc.h"
2626#include "neterr.h"
27+ #include "nut_stdint.h"
2728
2829#include "netget.h"
2930
@@ -138,6 +139,19 @@ static void get_type(nut_ctype_t *client, const char *upsname, const char *var)
138139
139140 snprintf (buf , sizeof (buf ), "TYPE %s %s" , upsname , var );
140141
142+ if (node -> flags & ST_FLAG_IMMUTABLE ) {
143+ #if defined DEBUG && DEBUG
144+ /* Properly exposing this needs also an update to
145+ * docs/net-protocol.txt (promote the paragraph
146+ * provided as a note currently) and to the NUT RFC
147+ * https://www.rfc-editor.org/info/rfc9271
148+ */
149+ snprintfcat (buf , sizeof (buf ), " IMMUTABLE" );
150+ #endif
151+ upsdebugx (3 , "%s: UPS[%s] variable %s is IMMUTABLE" ,
152+ __func__ , upsname , var );
153+ }
154+
141155 if (node -> flags & ST_FLAG_RW )
142156 snprintfcat (buf , sizeof (buf ), " RW" );
143157
@@ -162,6 +176,66 @@ static void get_type(nut_ctype_t *client, const char *upsname, const char *var)
162176 __func__ , upsname , var );
163177 }
164178
179+ /* Sanity-check current contents */
180+ if (node -> val && * (node -> val )) {
181+ double d ;
182+ long l ;
183+ int ok = 1 ;
184+ size_t len = strlen (node -> val );
185+
186+ errno = 0 ;
187+ if (!str_to_double_strict (node -> val , & d , 10 )) {
188+ upsdebugx (3 , "%s: UPS[%s] variable %s is flagged a NUMBER but not (exclusively) a double: %s" ,
189+ __func__ , upsname , var , node -> val );
190+ upsdebug_with_errno (4 , "%s: val=%f len=%" PRIuSIZE ,
191+ __func__ , d , len );
192+ ok = 0 ;
193+ }
194+
195+ if (!ok ) {
196+ /* did not parse as a float... range issues or NaN? */
197+ errno = 0 ;
198+ ok = 1 ;
199+ if (!str_to_long_strict (node -> val , & l , 10 )) {
200+ upsdebugx (3 , "%s: UPS[%s] variable %s is flagged a NUMBER but not (exclusively) a long int: %s" ,
201+ __func__ , upsname , var , node -> val );
202+ upsdebug_with_errno (4 , "%s: val=%ld len=%" PRIuSIZE ,
203+ __func__ , l , len );
204+ ok = 0 ;
205+ }
206+ }
207+
208+ #if defined DEBUG && DEBUG
209+ /* Need to figure out an "aux" value here (length of current
210+ * string at least?) and propagate the flag into where netset
211+ * would see it. Maybe this sanity-check should move into the
212+ * core state.c logic, so dstate setting would already remember
213+ * the defaulted flag (and maybe set another to clarify it is
214+ * a guess). Currently that code does not concern itself with
215+ * sanity-checks, it seems!
216+ */
217+ if (!ok && !(node -> flags & ST_FLAG_NUMBER )) {
218+ upsdebugx (3 , "%s: assuming UPS[%s] variable %s is a STRING after all, by contents; "
219+ "value='%s' len='%" PRIuSIZE "' aux='%ld'" ,
220+ __func__ , upsname , var , node -> val , len , node -> aux );
221+
222+ sendback (client , "%s STRING:%ld\n" , buf , node -> aux );
223+ return ;
224+ }
225+ #endif
226+
227+ if (!ok ) {
228+ /* FIXME: Should this return an error?
229+ * Value was explicitly flagged as a NUMBER but is not by content.
230+ * Note that state_addinfo() does not sanity-check; but
231+ * netset.c::set_var() does though (for protocol clients).
232+ */
233+ upslogx (LOG_WARNING , "%s: UPS[%s] variable %s is flagged as a NUMBER but is not "
234+ "by contents (please report as a bug to NUT project)): %s" ,
235+ __func__ , upsname , var , node -> val );
236+ }
237+ }
238+
165239 sendback (client , "%s NUMBER\n" , buf );
166240}
167241
0 commit comments