xref: /openbsd/usr.sbin/ntpd/ntpd.c (revision cecf84d4)
1 /*	$OpenBSD: ntpd.c,v 1.93 2015/03/11 19:38:48 jmc Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  * Copyright (c) 2012 Mike Miller <mmiller@mgm51.com>
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 MIND, USE, DATA OR PROFITS, WHETHER
16  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/resource.h>
22 #include <sys/socket.h>
23 #include <sys/wait.h>
24 #include <sys/un.h>
25 #include <netinet/in.h>
26 #include <errno.h>
27 #include <poll.h>
28 #include <pwd.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <time.h>
34 #include <unistd.h>
35 #include <err.h>
36 
37 #include "ntpd.h"
38 
39 void		sighdlr(int);
40 __dead void	usage(void);
41 int		main(int, char *[]);
42 int		check_child(pid_t, const char *);
43 int		dispatch_imsg(struct ntpd_conf *);
44 int		dispatch_imsg_ctl(struct ntpd_conf *);
45 void		reset_adjtime(void);
46 int		ntpd_adjtime(double);
47 void		ntpd_adjfreq(double, int);
48 void		ntpd_settime(double);
49 void		readfreq(void);
50 int		writefreq(double);
51 void		ctl_main(int, char*[]);
52 const char     *ctl_lookup_option(char *, const char **);
53 void		show_status_msg(struct imsg *);
54 void		show_peer_msg(struct imsg *, int);
55 void		show_sensor_msg(struct imsg *, int);
56 
57 volatile sig_atomic_t	 quit = 0;
58 volatile sig_atomic_t	 reconfig = 0;
59 volatile sig_atomic_t	 sigchld = 0;
60 struct imsgbuf		*ibuf;
61 int			 timeout = INFTIM;
62 
63 const char		*showopt;
64 
65 static const char *ctl_showopt_list[] = {
66 	"peers", "Sensors", "status", "all", NULL
67 };
68 
69 void
70 sighdlr(int sig)
71 {
72 	switch (sig) {
73 	case SIGTERM:
74 	case SIGINT:
75 		quit = 1;
76 		break;
77 	case SIGCHLD:
78 		sigchld = 1;
79 		break;
80 	case SIGHUP:
81 		reconfig = 1;
82 		break;
83 	}
84 }
85 
86 __dead void
87 usage(void)
88 {
89 	extern char *__progname;
90 
91 	if (strcmp(__progname, "ntpctl") == 0)
92 		fprintf(stderr,
93 		    "usage: ntpctl -s all | peers | Sensors | status\n");
94 	else
95 		fprintf(stderr, "usage: %s [-dnSsv] [-f file]\n",
96 		    __progname);
97 	exit(1);
98 }
99 
100 #define POLL_MAX		8
101 #define PFD_PIPE		0
102 
103 int
104 main(int argc, char *argv[])
105 {
106 	struct ntpd_conf	 lconf;
107 	struct pollfd		 pfd[POLL_MAX];
108 	pid_t			 chld_pid = 0, pid;
109 	const char		*conffile;
110 	int			 fd_ctl, ch, nfds;
111 	int			 pipe_chld[2];
112 	struct passwd		*pw;
113 	extern char		*__progname;
114 
115 	if (strcmp(__progname, "ntpctl") == 0) {
116 		ctl_main(argc, argv);
117 		/* NOTREACHED */
118 	}
119 
120 	conffile = CONFFILE;
121 
122 	bzero(&lconf, sizeof(lconf));
123 
124 	log_init(1);		/* log to stderr until daemonized */
125 
126 	while ((ch = getopt(argc, argv, "df:nsSv")) != -1) {
127 		switch (ch) {
128 		case 'd':
129 			lconf.debug = 1;
130 			log_verbose(1);
131 			break;
132 		case 'f':
133 			conffile = optarg;
134 			break;
135 		case 'n':
136 			lconf.noaction = 1;
137 			break;
138 		case 's':
139 			lconf.settime = 1;
140 			break;
141 		case 'S':
142 			lconf.settime = 0;
143 			break;
144 		case 'v':
145 			log_verbose(1);
146 			break;
147 		default:
148 			usage();
149 			/* NOTREACHED */
150 		}
151 	}
152 
153 	argc -= optind;
154 	argv += optind;
155 	if (argc > 0)
156 		usage();
157 
158 	if (parse_config(conffile, &lconf))
159 		exit(1);
160 
161 	if (lconf.noaction) {
162 		fprintf(stderr, "configuration OK\n");
163 		exit(0);
164 	}
165 
166 	if (geteuid())
167 		errx(1, "need root privileges");
168 
169 	if ((pw = getpwnam(NTPD_USER)) == NULL)
170 		errx(1, "unknown user %s", NTPD_USER);
171 
172 	if (setpriority(PRIO_PROCESS, 0, -20) == -1)
173 		warn("can't set priority");
174 
175 	reset_adjtime();
176 	if (!lconf.settime) {
177 		log_init(lconf.debug);
178 		if (!lconf.debug)
179 			if (daemon(1, 0))
180 				fatal("daemon");
181 	} else
182 		timeout = SETTIME_TIMEOUT * 1000;
183 
184 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_chld) == -1)
185 		fatal("socketpair");
186 
187 	if ((fd_ctl = control_init(CTLSOCKET)) == -1)
188 		fatalx("control socket init failed");
189 	if (control_listen(fd_ctl) == -1)
190 		fatalx("control socket listen failed");
191 
192 	signal(SIGCHLD, sighdlr);
193 	/* fork child process */
194 	chld_pid = ntp_main(pipe_chld, fd_ctl, &lconf, pw);
195 
196 	setproctitle("[priv]");
197 	readfreq();
198 
199 	signal(SIGTERM, sighdlr);
200 	signal(SIGINT, sighdlr);
201 	signal(SIGHUP, sighdlr);
202 
203 	close(pipe_chld[1]);
204 
205 	if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
206 		fatal(NULL);
207 	imsg_init(ibuf, pipe_chld[0]);
208 
209 	while (quit == 0) {
210 		pfd[PFD_PIPE].fd = ibuf->fd;
211 		pfd[PFD_PIPE].events = POLLIN;
212 		if (ibuf->w.queued)
213 			pfd[PFD_PIPE].events |= POLLOUT;
214 
215 		if ((nfds = poll(pfd, 1, timeout)) == -1)
216 			if (errno != EINTR) {
217 				log_warn("poll error");
218 				quit = 1;
219 			}
220 
221 		if (nfds == 0 && lconf.settime) {
222 			lconf.settime = 0;
223 			timeout = INFTIM;
224 			log_init(lconf.debug);
225 			log_warnx("no reply received in time, skipping initial "
226 			    "time setting");
227 			if (!lconf.debug)
228 				if (daemon(1, 0))
229 					fatal("daemon");
230 		}
231 
232 		if (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT))
233 			if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) {
234 				log_warn("pipe write error (to child)");
235 				quit = 1;
236 			}
237 
238 		if (nfds > 0 && pfd[PFD_PIPE].revents & POLLIN) {
239 			nfds--;
240 			if (dispatch_imsg(&lconf) == -1)
241 				quit = 1;
242 		}
243 
244 		if (sigchld) {
245 			if (check_child(chld_pid, "child")) {
246 				quit = 1;
247 				chld_pid = 0;
248 			}
249 			sigchld = 0;
250 		}
251 
252 	}
253 
254 	signal(SIGCHLD, SIG_DFL);
255 
256 	if (chld_pid)
257 		kill(chld_pid, SIGTERM);
258 
259 	do {
260 		if ((pid = wait(NULL)) == -1 &&
261 		    errno != EINTR && errno != ECHILD)
262 			fatal("wait");
263 	} while (pid != -1 || (pid == -1 && errno == EINTR));
264 
265 	msgbuf_clear(&ibuf->w);
266 	free(ibuf);
267 	log_info("Terminating");
268 	return (0);
269 }
270 
271 int
272 check_child(pid_t pid, const char *pname)
273 {
274 	int	 status, sig;
275 	char	*signame;
276 
277 	if (waitpid(pid, &status, WNOHANG) > 0) {
278 		if (WIFEXITED(status)) {
279 			log_warnx("Lost child: %s exited", pname);
280 			return (1);
281 		}
282 		if (WIFSIGNALED(status)) {
283 			sig = WTERMSIG(status);
284 			signame = strsignal(sig) ? strsignal(sig) : "unknown";
285 			log_warnx("Lost child: %s terminated; signal %d (%s)",
286 			    pname, sig, signame);
287 			return (1);
288 		}
289 	}
290 
291 	return (0);
292 }
293 
294 int
295 dispatch_imsg(struct ntpd_conf *lconf)
296 {
297 	struct imsg		 imsg;
298 	int			 n;
299 	double			 d;
300 
301 	if ((n = imsg_read(ibuf)) == -1)
302 		return (-1);
303 
304 	if (n == 0) {	/* connection closed */
305 		log_warnx("dispatch_imsg in main: pipe closed");
306 		return (-1);
307 	}
308 
309 	for (;;) {
310 		if ((n = imsg_get(ibuf, &imsg)) == -1)
311 			return (-1);
312 
313 		if (n == 0)
314 			break;
315 
316 		switch (imsg.hdr.type) {
317 		case IMSG_ADJTIME:
318 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
319 				fatalx("invalid IMSG_ADJTIME received");
320 			memcpy(&d, imsg.data, sizeof(d));
321 			n = ntpd_adjtime(d);
322 			imsg_compose(ibuf, IMSG_ADJTIME, 0, 0, -1,
323 			     &n, sizeof(n));
324 			break;
325 		case IMSG_ADJFREQ:
326 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
327 				fatalx("invalid IMSG_ADJFREQ received");
328 			memcpy(&d, imsg.data, sizeof(d));
329 			ntpd_adjfreq(d, 1);
330 			break;
331 		case IMSG_SETTIME:
332 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
333 				fatalx("invalid IMSG_SETTIME received");
334 			if (!lconf->settime)
335 				break;
336 			log_init(lconf->debug);
337 			memcpy(&d, imsg.data, sizeof(d));
338 			ntpd_settime(d);
339 			/* daemonize now */
340 			if (!lconf->debug)
341 				if (daemon(1, 0))
342 					fatal("daemon");
343 			lconf->settime = 0;
344 			timeout = INFTIM;
345 			break;
346 		default:
347 			break;
348 		}
349 		imsg_free(&imsg);
350 	}
351 	return (0);
352 }
353 
354 void
355 reset_adjtime(void)
356 {
357 	struct timeval	tv;
358 
359 	timerclear(&tv);
360 	if (adjtime(&tv, NULL) == -1)
361 		log_warn("reset adjtime failed");
362 }
363 
364 int
365 ntpd_adjtime(double d)
366 {
367 	struct timeval	tv, olddelta;
368 	int		synced = 0;
369 	static int	firstadj = 1;
370 
371 	d += getoffset();
372 	if (d >= (double)LOG_NEGLIGIBLE_ADJTIME / 1000 ||
373 	    d <= -1 * (double)LOG_NEGLIGIBLE_ADJTIME / 1000)
374 		log_info("adjusting local clock by %fs", d);
375 	else
376 		log_debug("adjusting local clock by %fs", d);
377 	d_to_tv(d, &tv);
378 	if (adjtime(&tv, &olddelta) == -1)
379 		log_warn("adjtime failed");
380 	else if (!firstadj && olddelta.tv_sec == 0 && olddelta.tv_usec == 0)
381 		synced = 1;
382 	firstadj = 0;
383 	return (synced);
384 }
385 
386 void
387 ntpd_adjfreq(double relfreq, int wrlog)
388 {
389 	int64_t curfreq;
390 	double ppmfreq;
391 	int r;
392 
393 	if (adjfreq(NULL, &curfreq) == -1) {
394 		log_warn("adjfreq failed");
395 		return;
396 	}
397 
398 	/*
399 	 * adjfreq's unit is ns/s shifted left 32; convert relfreq to
400 	 * that unit before adding. We log values in part per million.
401 	 */
402 	curfreq += relfreq * 1e9 * (1LL << 32);
403 	r = writefreq(curfreq / 1e9 / (1LL << 32));
404 	ppmfreq = relfreq * 1e6;
405 	if (wrlog) {
406 		if (ppmfreq >= LOG_NEGLIGIBLE_ADJFREQ ||
407 		    ppmfreq <= -LOG_NEGLIGIBLE_ADJFREQ)
408 			log_info("adjusting clock frequency by %f to %fppm%s",
409 			    ppmfreq, curfreq / 1e3 / (1LL << 32),
410 			    r ? "" : " (no drift file)");
411 		else
412 			log_debug("adjusting clock frequency by %f to %fppm%s",
413 			    ppmfreq, curfreq / 1e3 / (1LL << 32),
414 			    r ? "" : " (no drift file)");
415 	}
416 
417 	if (adjfreq(&curfreq, NULL) == -1)
418 		log_warn("adjfreq failed");
419 }
420 
421 void
422 ntpd_settime(double d)
423 {
424 	struct timeval	tv, curtime;
425 	char		buf[80];
426 	time_t		tval;
427 
428 	if (gettimeofday(&curtime, NULL) == -1) {
429 		log_warn("gettimeofday");
430 		return;
431 	}
432 	d_to_tv(d, &tv);
433 	curtime.tv_usec += tv.tv_usec + 1000000;
434 	curtime.tv_sec += tv.tv_sec - 1 + (curtime.tv_usec / 1000000);
435 	curtime.tv_usec %= 1000000;
436 
437 	if (settimeofday(&curtime, NULL) == -1) {
438 		log_warn("settimeofday");
439 		return;
440 	}
441 	tval = curtime.tv_sec;
442 	strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
443 	    localtime(&tval));
444 	log_info("set local clock to %s (offset %fs)", buf, d);
445 }
446 
447 void
448 readfreq(void)
449 {
450 	FILE *fp;
451 	int64_t current;
452 	double d;
453 
454 	fp = fopen(DRIFTFILE, "r");
455 	if (fp == NULL) {
456 		/* if the drift file has been deleted by the user, reset */
457 		current = 0;
458 		if (adjfreq(&current, NULL) == -1)
459 			log_warn("adjfreq reset failed");
460 		return;
461 	}
462 
463 	/* if we're adjusting frequency already, don't override */
464 	if (adjfreq(NULL, &current) == -1)
465 		log_warn("adjfreq failed");
466 	else if (current == 0) {
467 		if (fscanf(fp, "%lf", &d) == 1) {
468 			d /= 1e6;	/* scale from ppm */
469 			ntpd_adjfreq(d, 0);
470 		} else
471 			log_warnx("can't read %s", DRIFTFILE);
472 	}
473 	fclose(fp);
474 }
475 
476 int
477 writefreq(double d)
478 {
479 	int r;
480 	FILE *fp;
481 	static int warnonce = 1;
482 
483 	fp = fopen(DRIFTFILE, "w");
484 	if (fp == NULL) {
485 		if (warnonce) {
486 			log_warn("can't open %s", DRIFTFILE);
487 			warnonce = 0;
488 		}
489 		return 0;
490 	}
491 
492 	fprintf(fp, "%.3f\n", d * 1e6);		/* scale to ppm */
493 	r = ferror(fp);
494 	if (fclose(fp) != 0 || r != 0) {
495 		if (warnonce) {
496 			log_warnx("can't write %s", DRIFTFILE);
497 			warnonce = 0;
498 		}
499 		unlink(DRIFTFILE);
500 		return 0;
501 	}
502 	return 1;
503 }
504 
505 void
506 ctl_main(int argc, char *argv[])
507 {
508 	struct sockaddr_un	 sa;
509 	struct imsg		 imsg;
510 	struct imsgbuf		*ibuf_ctl;
511 	int			 fd, n, done, ch, action;
512 	char			*sockname;
513 
514 	sockname = CTLSOCKET;
515 
516 	if (argc < 2) {
517 		usage();
518 		/* NOTREACHED */
519 	}
520 
521 	while ((ch = getopt(argc, argv, "s:")) != -1) {
522 		switch (ch) {
523 		case 's':
524 			showopt = ctl_lookup_option(optarg, ctl_showopt_list);
525 			if (showopt == NULL) {
526 				warnx("Unknown show modifier '%s'", optarg);
527 				usage();
528 			}
529 			break;
530 		default:
531 			usage();
532 			/* NOTREACHED */
533 		}
534 	}
535 
536 	action = -1;
537 	if (showopt != NULL) {
538 		switch (*showopt) {
539 		case 'p':
540 			action = CTL_SHOW_PEERS;
541 			break;
542 		case 's':
543 			action = CTL_SHOW_STATUS;
544 			break;
545 		case 'S':
546 			action = CTL_SHOW_SENSORS;
547 			break;
548 		case 'a':
549 			action = CTL_SHOW_ALL;
550 			break;
551 		}
552 	}
553 	if (action == -1)
554 		usage();
555 		/* NOTREACHED */
556 
557 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
558 		err(1, "ntpctl: socket");
559 
560 	bzero(&sa, sizeof(sa));
561 	sa.sun_family = AF_UNIX;
562 	if (strlcpy(sa.sun_path, sockname, sizeof(sa.sun_path)) >=
563 	    sizeof(sa.sun_path))
564 		errx(1, "ctl socket name too long");
565 	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1)
566 		err(1, "connect: %s", sockname);
567 
568 	if ((ibuf_ctl = malloc(sizeof(struct imsgbuf))) == NULL)
569 		err(1, NULL);
570 	imsg_init(ibuf_ctl, fd);
571 
572 	switch (action) {
573 	case CTL_SHOW_STATUS:
574 		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_STATUS,
575 		    0, 0, -1, NULL, 0);
576 		break;
577 	case CTL_SHOW_PEERS:
578 		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_PEERS,
579 		    0, 0, -1, NULL, 0);
580 		break;
581 	case CTL_SHOW_SENSORS:
582 		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_SENSORS,
583 		    0, 0, -1, NULL, 0);
584 		break;
585 	case CTL_SHOW_ALL:
586 		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_ALL,
587 		    0, 0, -1, NULL, 0);
588 		break;
589 	default:
590 		errx(1, "invalid action");
591 		break; /* NOTREACHED */
592 	}
593 
594 	while (ibuf_ctl->w.queued)
595 		if (msgbuf_write(&ibuf_ctl->w) <= 0 && errno != EAGAIN)
596 			err(1, "ibuf_ctl: msgbuf_write error");
597 
598 	done = 0;
599 	while (!done) {
600 		if ((n = imsg_read(ibuf_ctl)) == -1)
601 			err(1, "ibuf_ctl: imsg_read error");
602 		if (n == 0)
603 			errx(1, "ntpctl: pipe closed");
604 
605 		while (!done) {
606 			if ((n = imsg_get(ibuf_ctl, &imsg)) == -1)
607 				err(1, "ibuf_ctl: imsg_get error");
608 			if (n == 0)
609 				break;
610 
611 			switch (action) {
612 			case CTL_SHOW_STATUS:
613 				show_status_msg(&imsg);
614 				done = 1;
615 				break;
616 			case CTL_SHOW_PEERS:
617 				show_peer_msg(&imsg, 0);
618 				if (imsg.hdr.type ==
619 				    IMSG_CTL_SHOW_PEERS_END)
620 					done = 1;
621 				break;
622 			case CTL_SHOW_SENSORS:
623 				show_sensor_msg(&imsg, 0);
624 				if (imsg.hdr.type ==
625 				    IMSG_CTL_SHOW_SENSORS_END)
626 					done = 1;
627 				break;
628 			case CTL_SHOW_ALL:
629 				switch (imsg.hdr.type) {
630 				case IMSG_CTL_SHOW_STATUS:
631 					show_status_msg(&imsg);
632 					break;
633 				case IMSG_CTL_SHOW_PEERS:
634 					show_peer_msg(&imsg, 1);
635 					break;
636 				case IMSG_CTL_SHOW_SENSORS:
637 					show_sensor_msg(&imsg, 1);
638 					break;
639 				case IMSG_CTL_SHOW_PEERS_END:
640 				case IMSG_CTL_SHOW_SENSORS_END:
641 					/* do nothing */
642 					break;
643 				case IMSG_CTL_SHOW_ALL_END:
644 					done=1;
645 					break;
646 				default:
647 					/* no action taken */
648 					break;
649 				}
650 			default:
651 				/* no action taken */
652 				break;
653 			}
654 			imsg_free(&imsg);
655 		}
656 	}
657 	close(fd);
658 	free(ibuf_ctl);
659 	exit(0);
660 }
661 
662 const char *
663 ctl_lookup_option(char *cmd, const char **list)
664 {
665 	const char *item = NULL;
666 	if (cmd != NULL && *cmd)
667 		for (; *list; list++)
668 			if (!strncmp(cmd, *list, strlen(cmd))) {
669 				if (item == NULL)
670 					item = *list;
671 				else
672 					errx(1, "%s is ambiguous", cmd);
673 			}
674 	return (item);
675 }
676 
677 void
678 show_status_msg(struct imsg *imsg)
679 {
680 	struct ctl_show_status	*cstatus;
681 	double			 clock_offset;
682 	struct timeval		 tv;
683 
684 	if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(struct ctl_show_status))
685 		fatalx("invalid IMSG_CTL_SHOW_STATUS received");
686 
687 	cstatus = (struct ctl_show_status *)imsg->data;
688 
689 	if (cstatus->peercnt > 0)
690 		printf("%d/%d peers valid, ",
691 		    cstatus->valid_peers, cstatus->peercnt);
692 
693 	if (cstatus->sensorcnt > 0)
694 		printf("%d/%d sensors valid, ",
695 		    cstatus->valid_sensors, cstatus->sensorcnt);
696 
697 	if (cstatus->constraint_median) {
698 		tv.tv_sec = cstatus->constraint_median +
699 		    (getmonotime() - cstatus->constraint_last);
700 		tv.tv_usec = 0;
701 		d_to_tv(gettime_from_timeval(&tv) - gettime(), &tv);
702 		printf("constraint offset %llds", (long long)tv.tv_sec);
703 		if (cstatus->constraint_errors)
704 			printf(" (%d errors)",
705 			    cstatus->constraint_errors);
706 		printf(", ");
707 	}
708 
709 	if (cstatus->peercnt + cstatus->sensorcnt == 0)
710 		printf("no peers and no sensors configured\n");
711 
712 	if (cstatus->synced == 1)
713 		printf("clock synced, stratum %u\n", cstatus->stratum);
714 	else {
715 		printf("clock unsynced");
716 		clock_offset = cstatus->clock_offset < 0 ?
717 		    -1.0 * cstatus->clock_offset : cstatus->clock_offset;
718 		if (clock_offset > 5e-7)
719 			printf(", clock offset is %.3fms\n",
720 			    cstatus->clock_offset);
721 		else
722 			printf("\n");
723 	}
724 }
725 
726 void
727 show_peer_msg(struct imsg *imsg, int calledfromshowall)
728 {
729 	struct ctl_show_peer	*cpeer;
730 	int			 cnt;
731 	char			 stratum[3];
732 	static int		 firsttime = 1;
733 
734 	if (imsg->hdr.type == IMSG_CTL_SHOW_PEERS_END) {
735 		if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(cnt))
736 			fatalx("invalid IMSG_CTL_SHOW_PEERS_END received");
737 		memcpy(&cnt, imsg->data, sizeof(cnt));
738 		if (cnt == 0)
739 			printf("no peers configured\n");
740 		return;
741 	}
742 
743 	if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(struct ctl_show_peer))
744 		fatalx("invalid IMSG_CTL_SHOW_PEERS received");
745 
746 	cpeer = (struct ctl_show_peer *)imsg->data;
747 
748 	if (strlen(cpeer->peer_desc) > MAX_DISPLAY_WIDTH - 1)
749 		fatalx("peer_desc is too long");
750 
751 	if (firsttime) {
752 		firsttime = 0;
753 		if (calledfromshowall)
754 			printf("\n");
755 		printf("peer\n   wt tl st  next  poll          "
756 		    "offset       delay      jitter\n");
757 	}
758 
759 	if (cpeer->stratum > 0)
760 		snprintf(stratum, sizeof(stratum), "%2u", cpeer->stratum);
761 	else
762 		strlcpy(stratum, " -", sizeof (stratum));
763 
764 	printf("%s\n %1s %2u %2u %2s %4llds %4llds",
765 	    cpeer->peer_desc, cpeer->syncedto == 1 ? "*" : " ",
766 	    cpeer->weight, cpeer->trustlevel, stratum,
767 	    (long long)cpeer->next, (long long)cpeer->poll);
768 
769 	if (cpeer->trustlevel >= TRUSTLEVEL_BADPEER)
770 		printf("  %12.3fms %9.3fms  %8.3fms\n", cpeer->offset,
771 		    cpeer->delay, cpeer->jitter);
772 	else
773 		printf("             ---- peer not valid ----\n");
774 
775 }
776 
777 void
778 show_sensor_msg(struct imsg *imsg, int calledfromshowall)
779 {
780 	struct ctl_show_sensor	*csensor;
781 	int			 cnt;
782 	static int		 firsttime = 1;
783 
784 	if (imsg->hdr.type == IMSG_CTL_SHOW_SENSORS_END) {
785 		if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(cnt))
786 			fatalx("invalid IMSG_CTL_SHOW_SENSORS_END received");
787 		memcpy(&cnt, imsg->data, sizeof(cnt));
788 		if (cnt == 0)
789 			printf("no sensors configured\n");
790 		return;
791 	}
792 
793 	if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(struct ctl_show_sensor))
794 		fatalx("invalid IMSG_CTL_SHOW_SENSORS received");
795 
796 	csensor = (struct ctl_show_sensor *)imsg->data;
797 
798 	if (strlen(csensor->sensor_desc) > MAX_DISPLAY_WIDTH - 1)
799 		fatalx("sensor_desc is too long");
800 
801 	if (firsttime) {
802 		firsttime = 0;
803 		if (calledfromshowall)
804 			printf("\n");
805 		printf("sensor\n   wt gd st  next  poll          "
806 		    "offset  correction\n");
807 	}
808 
809 	printf("%s\n %1s %2u %2u %2u %4llds %4llds",
810 	    csensor->sensor_desc, csensor->syncedto == 1 ? "*" : " ",
811 	    csensor->weight, csensor->good, csensor->stratum,
812 	    (long long)csensor->next, (long long)csensor->poll);
813 
814 	if (csensor->good == 1)
815 		printf("   %11.3fms %9.3fms\n",
816 		    csensor->offset, csensor->correction);
817 	else
818 		printf("         - sensor not valid -\n");
819 
820 }
821