Bug Summary

File:kern/tty_endrun.c
Warning:line 343, column 10
Although the value stored to 'tfom' is used in the enclosing expression, the value is never actually read from 'tfom'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tty_endrun.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/kern/tty_endrun.c
1/* $OpenBSD: tty_endrun.c,v 1.8 2018/02/19 08:59:52 mpi Exp $ */
2
3/*
4 * Copyright (c) 2008 Marc Balmer <mbalmer@openbsd.org>
5 * Copyright (c) 2009 Kevin Steves <stevesk@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20/*
21 * A tty line discipline to decode the EndRun Technologies native
22 * time-of-day message.
23 * http://www.endruntechnologies.com/
24 */
25
26/*
27 * EndRun Format:
28 *
29 * T YYYY DDD HH:MM:SS zZZ m<CR><LF>
30 *
31 * T is the Time Figure of Merit (TFOM) character (described below).
32 * This is the on-time character, transmitted during the first
33 * millisecond of each second.
34 *
35 * YYYY is the year
36 * DDD is the day-of-year
37 * : is the colon character (0x3A)
38 * HH is the hour of the day
39 * MM is the minute of the hour
40 * SS is the second of the minute
41 * z is the sign of the offset to UTC, + implies time is ahead of UTC.
42 * ZZ is the magnitude of the offset to UTC in units of half-hours.
43 * Non-zero only when the Timemode is Local.
44 * m is the Timemode character and is one of:
45 * G = GPS
46 * L = Local
47 * U = UTC
48 * <CR> is the ASCII carriage return character (0x0D)
49 * <LF> is the ASCII line feed character (0x0A)
50 */
51
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/malloc.h>
55#include <sys/sensors.h>
56#include <sys/tty.h>
57#include <sys/conf.h>
58#include <sys/time.h>
59
60#ifdef ENDRUN_DEBUG
61#define DPRINTFN(n, x) do { if (endrundebug > (n)) printf x; } while (0)
62int endrundebug = 0;
63#else
64#define DPRINTFN(n, x)
65#endif
66#define DPRINTF(x) DPRINTFN(0, x)
67
68void endrunattach(int);
69
70#define ENDRUNLEN27 27 /* strlen("6 2009 018 20:41:17 +00 U\r\n") */
71#define NUMFLDS6 6
72#ifdef ENDRUN_DEBUG
73#define TRUSTTIME(10 * 60) 30
74#else
75#define TRUSTTIME(10 * 60) (10 * 60) /* 10 minutes */
76#endif
77
78int endrun_count, endrun_nxid;
79
80struct endrun {
81 char cbuf[ENDRUNLEN27]; /* receive buffer */
82 struct ksensor time; /* the timedelta sensor */
83 struct ksensor signal; /* signal status */
84 struct ksensordev timedev;
85 struct timespec ts; /* current timestamp */
86 struct timespec lts; /* timestamp of last TFOM */
87 struct timeout endrun_tout; /* invalidate sensor */
88 int64_t gap; /* gap between two sentences */
89 int64_t last; /* last time rcvd */
90#define SYNC_SCAN1 1 /* scanning for '\n' */
91#define SYNC_EOL2 2 /* '\n' seen, next char TFOM */
92 int sync;
93 int pos; /* position in rcv buffer */
94 int no_pps; /* no PPS although requested */
95#ifdef ENDRUN_DEBUG
96 char tfom;
97#endif
98};
99
100/* EndRun decoding */
101void endrun_scan(struct endrun *, struct tty *);
102void endrun_decode(struct endrun *, struct tty *, char *fld[], int fldcnt);
103
104/* date and time conversion */
105int endrun_atoi(char *s, int len);
106int endrun_date_to_nano(char *s1, char *s2, int64_t *nano);
107int endrun_time_to_nano(char *s, int64_t *nano);
108int endrun_offset_to_nano(char *s, int64_t *nano);
109
110/* degrade the timedelta sensor */
111void endrun_timeout(void *);
112
113void
114endrunattach(int dummy)
115{
116}
117
118int
119endrunopen(dev_t dev, struct tty *tp, struct proc *p)
120{
121 struct endrun *np;
122 int error;
123
124 DPRINTF(("endrunopen\n"));
125 if (tp->t_line == ENDRUNDISC9)
126 return ENODEV19;
127 if ((error = suser(p)) != 0)
128 return error;
129 np = malloc(sizeof(struct endrun), M_DEVBUF2, M_WAITOK0x0001|M_ZERO0x0008);
130 snprintf(np->timedev.xname, sizeof(np->timedev.xname), "endrun%d",
131 endrun_nxid++);
132 endrun_count++;
133 np->time.status = SENSOR_S_UNKNOWN;
134 np->time.type = SENSOR_TIMEDELTA;
135#ifndef ENDRUN_DEBUG
136 np->time.flags = SENSOR_FINVALID0x0001;
137#endif
138 sensor_attach(&np->timedev, &np->time);
139
140 np->signal.type = SENSOR_PERCENT;
141 np->signal.status = SENSOR_S_UNKNOWN;
142 np->signal.value = 100000LL;
143 strlcpy(np->signal.desc, "Signal", sizeof(np->signal.desc));
144 sensor_attach(&np->timedev, &np->signal);
145
146 np->sync = SYNC_SCAN1;
147#ifdef ENDRUN_DEBUG
148 np->tfom = '0';
149#endif
150 tp->t_sc = (caddr_t)np;
151
152 error = linesw[TTYDISC0].l_open(dev, tp, p);
153 if (error) {
154 free(np, M_DEVBUF2, sizeof(*np));
155 tp->t_sc = NULL((void *)0);
156 } else {
157 sensordev_install(&np->timedev);
158 timeout_set(&np->endrun_tout, endrun_timeout, np);
159 }
160
161 return error;
162}
163
164int
165endrunclose(struct tty *tp, int flags, struct proc *p)
166{
167 struct endrun *np = (struct endrun *)tp->t_sc;
168
169 DPRINTF(("endrunclose\n"));
170 tp->t_line = TTYDISC0; /* switch back to termios */
171 timeout_del(&np->endrun_tout);
172 sensordev_deinstall(&np->timedev);
173 free(np, M_DEVBUF2, sizeof(*np));
174 tp->t_sc = NULL((void *)0);
175 endrun_count--;
176 if (endrun_count == 0)
177 endrun_nxid = 0;
178 return linesw[TTYDISC0].l_close(tp, flags, p);
179}
180
181/* collect EndRun sentence from tty */
182int
183endruninput(int c, struct tty *tp)
184{
185 struct endrun *np = (struct endrun *)tp->t_sc;
186 struct timespec ts;
187 int64_t gap;
188 long tmin, tmax;
189
190 if (np->sync == SYNC_EOL2) {
191 nanotime(&ts);
192 np->pos = 0;
193 np->sync = SYNC_SCAN1;
194 np->cbuf[np->pos++] = c; /* TFOM char */
195
196 gap = (ts.tv_sec * 1000000000LL + ts.tv_nsec) -
197 (np->lts.tv_sec * 1000000000LL + np->lts.tv_nsec);
198
199 np->lts.tv_sec = ts.tv_sec;
200 np->lts.tv_nsec = ts.tv_nsec;
201
202 if (gap <= np->gap)
203 goto nogap;
204
205 np->ts.tv_sec = ts.tv_sec;
206 np->ts.tv_nsec = ts.tv_nsec;
207 np->gap = gap;
208
209 /*
210 * If a tty timestamp is available, make sure its value is
211 * reasonable by comparing against the timestamp just taken.
212 * If they differ by more than 2 seconds, assume no PPS signal
213 * is present, note the fact, and keep using the timestamp
214 * value. When this happens, the sensor state is set to
215 * CRITICAL later when the EndRun sentence is decoded.
216 */
217 if (tp->t_flags & (TS_TSTAMPDCDSET0x10000 | TS_TSTAMPDCDCLR0x20000 |
218 TS_TSTAMPCTSSET0x40000 | TS_TSTAMPCTSCLR0x80000)) {
219 tmax = lmax(np->ts.tv_sec, tp->t_tv.tv_sec);
220 tmin = lmin(np->ts.tv_sec, tp->t_tv.tv_sec);
221 if (tmax - tmin > 1)
222 np->no_pps = 1;
223 else {
224 np->ts.tv_sec = tp->t_tv.tv_sec;
225 np->ts.tv_nsec = tp->t_tv.tv_usec *
226 1000L;
227 np->no_pps = 0;
228 }
229 }
230 } else if (c == '\n') {
231 if (np->pos == ENDRUNLEN27 - 1) {
232 /* don't copy '\n' into cbuf */
233 np->cbuf[np->pos] = '\0';
234 endrun_scan(np, tp);
235 }
236 np->sync = SYNC_EOL2;
237 } else {
238 if (np->pos < ENDRUNLEN27 - 1)
239 np->cbuf[np->pos++] = c;
240 }
241
242nogap:
243 /* pass data to termios */
244 return linesw[TTYDISC0].l_rint(c, tp);
245}
246
247/* Scan the EndRun sentence just received */
248void
249endrun_scan(struct endrun *np, struct tty *tp)
250{
251 int fldcnt = 0, n;
252 char *fld[NUMFLDS6], *cs;
253
254 DPRINTFN(1, ("%s\n", np->cbuf));
255 /* split into fields */
256 fld[fldcnt++] = &np->cbuf[0];
257 for (cs = NULL((void *)0), n = 0; n < np->pos && cs == NULL((void *)0); n++) {
258 switch (np->cbuf[n]) {
259 case '\r':
260 np->cbuf[n] = '\0';
261 cs = &np->cbuf[n + 1];
262 break;
263 case ' ':
264 if (fldcnt < NUMFLDS6) {
265 np->cbuf[n] = '\0';
266 fld[fldcnt++] = &np->cbuf[n + 1];
267 } else {
268 DPRINTF(("endrun: nr of fields in sentence "
269 "exceeds expected: %d\n", NUMFLDS));
270 return;
271 }
272 break;
273 }
274 }
275 endrun_decode(np, tp, fld, fldcnt);
276}
277
278/* Decode the time string */
279void
280endrun_decode(struct endrun *np, struct tty *tp, char *fld[], int fldcnt)
281{
282 int64_t date_nano, time_nano, offset_nano, endrun_now;
283 char tfom;
284 int jumped = 0;
285
286 if (fldcnt != NUMFLDS6) {
287 DPRINTF(("endrun: field count mismatch, %d\n", fldcnt));
288 return;
289 }
290 if (endrun_time_to_nano(fld[3], &time_nano) == -1) {
291 DPRINTF(("endrun: illegal time, %s\n", fld[3]));
292 return;
293 }
294 if (endrun_date_to_nano(fld[1], fld[2], &date_nano) == -1) {
295 DPRINTF(("endrun: illegal date, %s %s\n", fld[1], fld[2]));
296 return;
297 }
298 offset_nano = 0;
299 /* only parse offset when timemode is local */
300 if (fld[5][0] == 'L' &&
301 endrun_offset_to_nano(fld[4], &offset_nano) == -1) {
302 DPRINTF(("endrun: illegal offset, %s\n", fld[4]));
303 return;
304 }
305
306 endrun_now = date_nano + time_nano + offset_nano;
307 if (endrun_now <= np->last) {
308 DPRINTF(("endrun: time not monotonically increasing "
309 "last %lld now %lld\n",
310 (long long)np->last, (long long)endrun_now));
311 jumped = 1;
312 }
313 np->last = endrun_now;
314 np->gap = 0LL;
315#ifdef ENDRUN_DEBUG
316 if (np->time.status == SENSOR_S_UNKNOWN) {
317 np->time.status = SENSOR_S_OK;
318 timeout_add_sec(&np->endrun_tout, TRUSTTIME(10 * 60));
319 }
320#endif
321
322 np->time.value = np->ts.tv_sec * 1000000000LL +
323 np->ts.tv_nsec - endrun_now;
324 np->time.tv.tv_sec = np->ts.tv_sec;
325 np->time.tv.tv_usec = np->ts.tv_nsec / 1000L;
326 if (np->time.status == SENSOR_S_UNKNOWN) {
327 np->time.status = SENSOR_S_OK;
328 np->time.flags &= ~SENSOR_FINVALID0x0001;
329 strlcpy(np->time.desc, "EndRun", sizeof(np->time.desc));
330 }
331 /*
332 * Only update the timeout if the clock reports the time as valid.
333 *
334 * Time Figure Of Merit (TFOM) values:
335 *
336 * 6 - time error is < 100 us
337 * 7 - time error is < 1 ms
338 * 8 - time error is < 10 ms
339 * 9 - time error is > 10 ms,
340 * unsynchronized state if never locked to CDMA
341 */
342
343 switch (tfom = fld[0][0]) {
Although the value stored to 'tfom' is used in the enclosing expression, the value is never actually read from 'tfom'
344 case '6':
345 case '7':
346 case '8':
347 np->time.status = SENSOR_S_OK;
348 np->signal.status = SENSOR_S_OK;
349 break;
350 case '9':
351 np->signal.status = SENSOR_S_WARN;
352 break;
353 default:
354 DPRINTF(("endrun: invalid TFOM: '%c'\n", tfom));
355 np->signal.status = SENSOR_S_CRIT;
356 break;
357 }
358
359#ifdef ENDRUN_DEBUG
360 if (np->tfom != tfom) {
361 DPRINTF(("endrun: TFOM changed from %c to %c\n",
362 np->tfom, tfom));
363 np->tfom = tfom;
364 }
365#endif
366 if (jumped)
367 np->time.status = SENSOR_S_WARN;
368 if (np->time.status == SENSOR_S_OK)
369 timeout_add_sec(&np->endrun_tout, TRUSTTIME(10 * 60));
370
371 /*
372 * If tty timestamping is requested, but no PPS signal is present, set
373 * the sensor state to CRITICAL.
374 */
375 if (np->no_pps)
376 np->time.status = SENSOR_S_CRIT;
377}
378
379int
380endrun_atoi(char *s, int len)
381{
382 int n;
383 char *p;
384
385 /* make sure the input contains only numbers */
386 for (n = 0, p = s; n < len && *p && *p >= '0' && *p <= '9'; n++, p++)
387 ;
388 if (n != len || *p != '\0')
389 return -1;
390
391 for (n = 0; *s; s++)
392 n = n * 10 + *s - '0';
393
394 return n;
395}
396
397/*
398 * Convert date fields from EndRun to nanoseconds since the epoch.
399 * The year string must be of the form YYYY .
400 * The day of year string must be of the form DDD .
401 * Return 0 on success, -1 if illegal characters are encountered.
402 */
403int
404endrun_date_to_nano(char *y, char *doy, int64_t *nano)
405{
406 struct clock_ymdhms clock;
407 time_t secs;
408 int n, i;
409 int year_days = 365;
410 int month_days[] = {
411 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
412 };
413
414#define FEBRUARY2 2
415
416#define LEAPYEAR(x)((x) % 4 == 0 && (x) % 100 != 0) || (x) % 400 == 0 \
417 ((x) % 4 == 0 && \
418 (x) % 100 != 0) || \
419 (x) % 400 == 0
420
421 if ((n = endrun_atoi(y, 4)) == -1)
422 return -1;
423 clock.dt_year = n;
424
425 if (LEAPYEAR(n)((n) % 4 == 0 && (n) % 100 != 0) || (n) % 400 == 0) {
426 month_days[FEBRUARY2]++;
427 year_days++;
428 }
429
430 if ((n = endrun_atoi(doy, 3)) == -1 || n == 0 || n > year_days)
431 return -1;
432
433 /* convert day of year to month, day */
434 for (i = 1; n > month_days[i]; i++) {
435 n -= month_days[i];
436 }
437 clock.dt_mon = i;
438 clock.dt_day = n;
439
440 DPRINTFN(1, ("mm/dd %d/%d\n", i, n));
441
442 clock.dt_hour = clock.dt_min = clock.dt_sec = 0;
443
444 secs = clock_ymdhms_to_secs(&clock);
445 *nano = secs * 1000000000LL;
446 return 0;
447}
448
449/*
450 * Convert time field from EndRun to nanoseconds since midnight.
451 * The string must be of the form HH:MM:SS .
452 * Return 0 on success, -1 if illegal characters are encountered.
453 */
454int
455endrun_time_to_nano(char *s, int64_t *nano)
456{
457 struct clock_ymdhms clock;
458 time_t secs;
459 int n;
460
461 if (s[2] != ':' || s[5] != ':')
462 return -1;
463
464 s[2] = '\0';
465 s[5] = '\0';
466
467 if ((n = endrun_atoi(&s[0], 2)) == -1 || n > 23)
468 return -1;
469 clock.dt_hour = n;
470 if ((n = endrun_atoi(&s[3], 2)) == -1 || n > 59)
471 return -1;
472 clock.dt_min = n;
473 if ((n = endrun_atoi(&s[6], 2)) == -1 || n > 60)
474 return -1;
475 clock.dt_sec = n;
476
477 DPRINTFN(1, ("hh:mm:ss %d:%d:%d\n", (int)clock.dt_hour,
478 (int)clock.dt_min,
479 (int)clock.dt_sec));
480 secs = clock.dt_hour * 3600
481 + clock.dt_min * 60
482 + clock.dt_sec;
483
484 DPRINTFN(1, ("secs %lu\n", (unsigned long)secs));
485
486 *nano = secs * 1000000000LL;
487 return 0;
488}
489
490int
491endrun_offset_to_nano(char *s, int64_t *nano)
492{
493 time_t secs;
494 int n;
495
496 if (!(s[0] == '+' || s[0] == '-'))
497 return -1;
498
499 if ((n = endrun_atoi(&s[1], 2)) == -1)
500 return -1;
501 secs = n * 30 * 60;
502
503 *nano = secs * 1000000000LL;
504 if (s[0] == '+')
505 *nano = -*nano;
506
507 DPRINTFN(1, ("offset secs %lu nanosecs %lld\n",
508 (unsigned long)secs, (long long)*nano));
509
510 return 0;
511}
512
513/*
514 * Degrade the sensor state if we received no EndRun string for more than
515 * TRUSTTIME seconds.
516 */
517void
518endrun_timeout(void *xnp)
519{
520 struct endrun *np = xnp;
521
522 if (np->time.status == SENSOR_S_OK) {
523 np->time.status = SENSOR_S_WARN;
524 /*
525 * further degrade in TRUSTTIME seconds if no new valid EndRun
526 * strings are received.
527 */
528 timeout_add_sec(&np->endrun_tout, TRUSTTIME(10 * 60));
529 } else
530 np->time.status = SENSOR_S_CRIT;
531}