xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntpd.c (revision f89f6560d453f5e37386cc7938c072d2f528b9fa)
1 /*	$NetBSD: ntpd.c,v 1.9 2015/04/07 17:34:19 christos Exp $	*/
2 
3 /*
4  * ntpd.c - main program for the fixed point NTP daemon
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 # include <config.h>
9 #endif
10 
11 #include "ntp_machine.h"
12 #include "ntpd.h"
13 #include "ntp_io.h"
14 #include "ntp_stdlib.h"
15 #include <ntp_random.h>
16 
17 #include "ntp_config.h"
18 #include "ntp_syslog.h"
19 #include "ntp_assert.h"
20 #include "isc/error.h"
21 #include "isc/strerror.h"
22 #include "isc/formatcheck.h"
23 #include "iosignal.h"
24 
25 #ifdef SIM
26 # include "ntpsim.h"
27 #endif
28 
29 #include "ntp_libopts.h"
30 #include "ntpd-opts.h"
31 
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35 #ifdef HAVE_SYS_STAT_H
36 # include <sys/stat.h>
37 #endif
38 #include <stdio.h>
39 #ifdef HAVE_SYS_PARAM_H
40 # include <sys/param.h>
41 #endif
42 #ifdef HAVE_SYS_SIGNAL_H
43 # include <sys/signal.h>
44 #else
45 # include <signal.h>
46 #endif
47 #ifdef HAVE_SYS_IOCTL_H
48 # include <sys/ioctl.h>
49 #endif /* HAVE_SYS_IOCTL_H */
50 #if defined(HAVE_RTPRIO)
51 # ifdef HAVE_SYS_LOCK_H
52 #  include <sys/lock.h>
53 # endif
54 # include <sys/rtprio.h>
55 #else
56 # ifdef HAVE_PLOCK
57 #  ifdef HAVE_SYS_LOCK_H
58 #	include <sys/lock.h>
59 #  endif
60 # endif
61 #endif
62 #if defined(HAVE_SCHED_SETSCHEDULER)
63 # ifdef HAVE_SCHED_H
64 #  include <sched.h>
65 # else
66 #  ifdef HAVE_SYS_SCHED_H
67 #   include <sys/sched.h>
68 #  endif
69 # endif
70 #endif
71 #if defined(HAVE_SYS_MMAN_H)
72 # include <sys/mman.h>
73 #endif
74 
75 #ifdef HAVE_TERMIOS_H
76 # include <termios.h>
77 #endif
78 
79 #ifdef SYS_DOMAINOS
80 # include <apollo/base.h>
81 #endif /* SYS_DOMAINOS */
82 
83 
84 #include "recvbuff.h"
85 #include "ntp_cmdargs.h"
86 
87 #if 0				/* HMS: I don't think we need this. 961223 */
88 #ifdef LOCK_PROCESS
89 # ifdef SYS_SOLARIS
90 #  include <sys/mman.h>
91 # else
92 #  include <sys/lock.h>
93 # endif
94 #endif
95 #endif
96 
97 #ifdef _AIX
98 # include <ulimit.h>
99 #endif /* _AIX */
100 
101 #ifdef SCO5_CLOCK
102 # include <sys/ci/ciioctl.h>
103 #endif
104 
105 #ifdef HAVE_DROPROOT
106 # include <ctype.h>
107 # include <grp.h>
108 # include <pwd.h>
109 #ifdef HAVE_LINUX_CAPABILITIES
110 # include <sys/capability.h>
111 # include <sys/prctl.h>
112 #endif /* HAVE_LINUX_CAPABILITIES */
113 #if defined(HAVE_PRIV_H) && defined(HAVE_SOLARIS_PRIVS)
114 # include <priv.h>
115 #endif /* HAVE_PRIV_H */
116 #endif /* HAVE_DROPROOT */
117 
118 #if defined (LIBSECCOMP) && (KERN_SECCOMP)
119 /* # include <sys/types.h> */
120 # include <sys/resource.h>
121 # include <seccomp.h>
122 #endif /* LIBSECCOMP and KERN_SECCOMP */
123 
124 #ifdef HAVE_DNSREGISTRATION
125 # include <dns_sd.h>
126 DNSServiceRef mdns;
127 #endif
128 
129 #ifdef HAVE_SETPGRP_0
130 # define ntp_setpgrp(x, y)	setpgrp()
131 #else
132 # define ntp_setpgrp(x, y)	setpgrp(x, y)
133 #endif
134 
135 #ifdef HAVE_SOLARIS_PRIVS
136 # define LOWPRIVS "basic,sys_time,net_privaddr,proc_setid,!proc_info,!proc_session,!proc_exec"
137 static priv_set_t *lowprivs = NULL;
138 static priv_set_t *highprivs = NULL;
139 #endif /* HAVE_SOLARIS_PRIVS */
140 /*
141  * Scheduling priority we run at
142  */
143 #define NTPD_PRIO	(-12)
144 
145 int priority_done = 2;		/* 0 - Set priority */
146 				/* 1 - priority is OK where it is */
147 				/* 2 - Don't set priority */
148 				/* 1 and 2 are pretty much the same */
149 
150 int listen_to_virtual_ips = TRUE;
151 
152 /*
153  * No-fork flag.  If set, we do not become a background daemon.
154  */
155 int nofork;			/* Fork by default */
156 
157 #ifdef HAVE_DNSREGISTRATION
158 /*
159  * mDNS registration flag. If set, we attempt to register with the mDNS system, but only
160  * after we have synched the first time. If the attempt fails, then try again once per
161  * minute for up to 5 times. After all, we may be starting before mDNS.
162  */
163 int mdnsreg = FALSE;
164 int mdnstries = 5;
165 #endif  /* HAVE_DNSREGISTRATION */
166 
167 #ifdef HAVE_DROPROOT
168 int droproot;
169 int root_dropped;
170 char *user;		/* User to switch to */
171 char *group;		/* group to switch to */
172 const char *chrootdir;	/* directory to chroot to */
173 uid_t sw_uid;
174 gid_t sw_gid;
175 char *endp;
176 struct group *gr;
177 struct passwd *pw;
178 #endif /* HAVE_DROPROOT */
179 
180 #ifdef HAVE_WORKING_FORK
181 int	waitsync_fd_to_close = -1;	/* -w/--wait-sync */
182 #endif
183 
184 /*
185  * Initializing flag.  All async routines watch this and only do their
186  * thing when it is clear.
187  */
188 int initializing;
189 
190 /*
191  * Version declaration
192  */
193 extern const char *Version;
194 
195 char const *progname;
196 
197 int was_alarmed;
198 
199 #ifdef DECL_SYSCALL
200 /*
201  * We put this here, since the argument profile is syscall-specific
202  */
203 extern int syscall	(int, ...);
204 #endif /* DECL_SYSCALL */
205 
206 
207 #if !defined(SIM) && defined(SIGDIE1)
208 static	RETSIGTYPE	finish		(int);
209 #endif
210 
211 #if !defined(SIM) && defined(HAVE_WORKING_FORK)
212 static int	wait_child_sync_if	(int, long);
213 #endif
214 
215 #if !defined(SIM) && !defined(SYS_WINNT)
216 # ifdef	DEBUG
217 static	RETSIGTYPE	moredebug	(int);
218 static	RETSIGTYPE	lessdebug	(int);
219 # else	/* !DEBUG follows */
220 static	RETSIGTYPE	no_debug	(int);
221 # endif	/* !DEBUG */
222 #endif	/* !SIM && !SYS_WINNT */
223 
224 int	saved_argc;
225 char **	saved_argv;
226 
227 #ifndef SIM
228 int		ntpdmain		(int, char **);
229 static void	set_process_priority	(void);
230 static void	assertion_failed	(const char *, int,
231 					 isc_assertiontype_t,
232 					 const char *)
233 			__attribute__	((__noreturn__));
234 static void	library_fatal_error	(const char *, int,
235 					 const char *, va_list)
236 					ISC_FORMAT_PRINTF(3, 0);
237 static void	library_unexpected_error(const char *, int,
238 					 const char *, va_list)
239 					ISC_FORMAT_PRINTF(3, 0);
240 #endif	/* !SIM */
241 
242 
243 
244 
245 void
246 parse_cmdline_opts(
247 	int *	pargc,
248 	char ***pargv
249 	)
250 {
251 	static int	parsed;
252 	static int	optct;
253 
254 	if (!parsed)
255 		optct = ntpOptionProcess(&ntpdOptions, *pargc, *pargv);
256 
257 	parsed = 1;
258 
259 	*pargc -= optct;
260 	*pargv += optct;
261 }
262 
263 
264 #ifdef SIM
265 int
266 main(
267 	int argc,
268 	char *argv[]
269 	)
270 {
271 	progname = argv[0];
272 	parse_cmdline_opts(&argc, &argv);
273 #ifdef DEBUG
274 	debug = OPT_VALUE_SET_DEBUG_LEVEL;
275 	DPRINTF(1, ("%s\n", Version));
276 #endif
277 
278 	return ntpsim(argc, argv);
279 }
280 #else	/* !SIM follows */
281 #ifdef NO_MAIN_ALLOWED
282 CALL(ntpd,"ntpd",ntpdmain);
283 #else	/* !NO_MAIN_ALLOWED follows */
284 #ifndef SYS_WINNT
285 int
286 main(
287 	int argc,
288 	char *argv[]
289 	)
290 {
291 	return ntpdmain(argc, argv);
292 }
293 #endif /* !SYS_WINNT */
294 #endif /* !NO_MAIN_ALLOWED */
295 #endif /* !SIM */
296 
297 #ifdef _AIX
298 /*
299  * OK. AIX is different than solaris in how it implements plock().
300  * If you do NOT adjust the stack limit, you will get the MAXIMUM
301  * stack size allocated and PINNED with you program. To check the
302  * value, use ulimit -a.
303  *
304  * To fix this, we create an automatic variable and set our stack limit
305  * to that PLUS 32KB of extra space (we need some headroom).
306  *
307  * This subroutine gets the stack address.
308  *
309  * Grover Davidson and Matt Ladendorf
310  *
311  */
312 static char *
313 get_aix_stack(void)
314 {
315 	char ch;
316 	return (&ch);
317 }
318 
319 /*
320  * Signal handler for SIGDANGER.
321  */
322 static void
323 catch_danger(int signo)
324 {
325 	msyslog(LOG_INFO, "ntpd: setpgid(): %m");
326 	/* Make the system believe we'll free something, but don't do it! */
327 	return;
328 }
329 #endif /* _AIX */
330 
331 /*
332  * Set the process priority
333  */
334 #ifndef SIM
335 static void
336 set_process_priority(void)
337 {
338 
339 # ifdef DEBUG
340 	if (debug > 1)
341 		msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
342 			((priority_done)
343 			 ? "Leave priority alone"
344 			 : "Attempt to set priority"
345 				),
346 			priority_done);
347 # endif /* DEBUG */
348 
349 # if defined(HAVE_SCHED_SETSCHEDULER)
350 	if (!priority_done) {
351 		extern int config_priority_override, config_priority;
352 		int pmax, pmin;
353 		struct sched_param sched;
354 
355 		pmax = sched_get_priority_max(SCHED_FIFO);
356 		sched.sched_priority = pmax;
357 		if ( config_priority_override ) {
358 			pmin = sched_get_priority_min(SCHED_FIFO);
359 			if ( config_priority > pmax )
360 				sched.sched_priority = pmax;
361 			else if ( config_priority < pmin )
362 				sched.sched_priority = pmin;
363 			else
364 				sched.sched_priority = config_priority;
365 		}
366 		if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
367 			msyslog(LOG_ERR, "sched_setscheduler(): %m");
368 		else
369 			++priority_done;
370 	}
371 # endif /* HAVE_SCHED_SETSCHEDULER */
372 # ifdef HAVE_RTPRIO
373 #  ifdef RTP_SET
374 	if (!priority_done) {
375 		struct rtprio srtp;
376 
377 		srtp.type = RTP_PRIO_REALTIME;	/* was: RTP_PRIO_NORMAL */
378 		srtp.prio = 0;		/* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
379 
380 		if (rtprio(RTP_SET, getpid(), &srtp) < 0)
381 			msyslog(LOG_ERR, "rtprio() error: %m");
382 		else
383 			++priority_done;
384 	}
385 #  else	/* !RTP_SET follows */
386 	if (!priority_done) {
387 		if (rtprio(0, 120) < 0)
388 			msyslog(LOG_ERR, "rtprio() error: %m");
389 		else
390 			++priority_done;
391 	}
392 #  endif	/* !RTP_SET */
393 # endif	/* HAVE_RTPRIO */
394 # if defined(NTPD_PRIO) && NTPD_PRIO != 0
395 #  ifdef HAVE_ATT_NICE
396 	if (!priority_done) {
397 		errno = 0;
398 		if (-1 == nice (NTPD_PRIO) && errno != 0)
399 			msyslog(LOG_ERR, "nice() error: %m");
400 		else
401 			++priority_done;
402 	}
403 #  endif	/* HAVE_ATT_NICE */
404 #  ifdef HAVE_BSD_NICE
405 	if (!priority_done) {
406 		if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
407 			msyslog(LOG_ERR, "setpriority() error: %m");
408 		else
409 			++priority_done;
410 	}
411 #  endif	/* HAVE_BSD_NICE */
412 # endif	/* NTPD_PRIO && NTPD_PRIO != 0 */
413 	if (!priority_done)
414 		msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
415 }
416 #endif	/* !SIM */
417 
418 
419 /*
420  * Main program.  Initialize us, disconnect us from the tty if necessary,
421  * and loop waiting for I/O and/or timer expiries.
422  */
423 #ifndef SIM
424 int
425 ntpdmain(
426 	int argc,
427 	char *argv[]
428 	)
429 {
430 	l_fp		now;
431 	struct recvbuf *rbuf;
432 	const char *	logfilename;
433 # ifdef HAVE_UMASK
434 	mode_t		uv;
435 # endif
436 # if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
437 	uid_t		uid;
438 # endif
439 # if defined(HAVE_WORKING_FORK)
440 	long		wait_sync = 0;
441 	int		pipe_fds[2];
442 	int		rc;
443 	int		exit_code;
444 #  ifdef _AIX
445 	struct sigaction sa;
446 #  endif
447 #  if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY)
448 	int		fid;
449 #  endif
450 # endif	/* HAVE_WORKING_FORK*/
451 # ifdef SCO5_CLOCK
452 	int		fd;
453 	int		zero;
454 # endif
455 
456 # ifdef HAVE_UMASK
457 	uv = umask(0);
458 	if (uv)
459 		umask(uv);
460 	else
461 		umask(022);
462 # endif
463 	saved_argc = argc;
464 	saved_argv = argv;
465 	progname = argv[0];
466 	initializing = TRUE;		/* mark that we are initializing */
467 	parse_cmdline_opts(&argc, &argv);
468 # ifdef DEBUG
469 	debug = OPT_VALUE_SET_DEBUG_LEVEL;
470 #  ifdef HAVE_SETLINEBUF
471 	setlinebuf(stdout);
472 #  endif
473 # endif
474 
475 	if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT)
476 # ifdef DEBUG
477 	    || debug
478 # endif
479 	    || HAVE_OPT(SAVECONFIGQUIT))
480 		nofork = TRUE;
481 
482 	init_logging(progname, NLOG_SYNCMASK, TRUE);
483 	/* honor -l/--logfile option to log to a file */
484 	if (HAVE_OPT(LOGFILE)) {
485 		logfilename = OPT_ARG(LOGFILE);
486 		syslogit = FALSE;
487 		change_logfile(logfilename, FALSE);
488 	} else {
489 		logfilename = NULL;
490 		if (nofork)
491 			msyslog_term = TRUE;
492 		if (HAVE_OPT(SAVECONFIGQUIT))
493 			syslogit = FALSE;
494 	}
495 	msyslog(LOG_NOTICE, "%s: Starting", Version);
496 
497 	{
498 		int i;
499 		char buf[1024];	/* Secret knowledge of msyslog buf length */
500 		char *cp = buf;
501 
502 		/* Note that every arg has an initial space character */
503 		snprintf(cp, sizeof(buf), "Command line:");
504 		cp += strlen(cp);
505 
506 		for (i = 0; i < saved_argc ; ++i) {
507 			snprintf(cp, sizeof(buf) - (cp - buf),
508 				" %s", saved_argv[i]);
509 			cp += strlen(cp);
510 		}
511 		msyslog(LOG_INFO, "%s", buf);
512 	}
513 
514 	/*
515 	 * Install trap handlers to log errors and assertion failures.
516 	 * Default handlers print to stderr which doesn't work if detached.
517 	 */
518 	isc_assertion_setcallback(assertion_failed);
519 	isc_error_setfatal(library_fatal_error);
520 	isc_error_setunexpected(library_unexpected_error);
521 
522 	/* MPE lacks the concept of root */
523 # if defined(HAVE_GETUID) && !defined(MPE)
524 	uid = getuid();
525 	if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
526 		msyslog_term = TRUE;
527 		msyslog(LOG_ERR,
528 			"must be run as root, not uid %ld", (long)uid);
529 		exit(1);
530 	}
531 # endif
532 
533 /*
534  * Enable the Multi-Media Timer for Windows?
535  */
536 # ifdef SYS_WINNT
537 	if (HAVE_OPT( MODIFYMMTIMER ))
538 		set_mm_timer(MM_TIMER_HIRES);
539 # endif
540 
541 #ifdef HAVE_DNSREGISTRATION
542 /*
543  * Enable mDNS registrations?
544  */
545 	if (HAVE_OPT( MDNS )) {
546 		mdnsreg = TRUE;
547 	}
548 #endif  /* HAVE_DNSREGISTRATION */
549 
550 	if (HAVE_OPT( NOVIRTUALIPS ))
551 		listen_to_virtual_ips = 0;
552 
553 	/*
554 	 * --interface, listen on specified interfaces
555 	 */
556 	if (HAVE_OPT( INTERFACE )) {
557 		int		ifacect = STACKCT_OPT( INTERFACE );
558 		const char**	ifaces  = STACKLST_OPT( INTERFACE );
559 		sockaddr_u	addr;
560 
561 		while (ifacect-- > 0) {
562 			add_nic_rule(
563 				is_ip_address(*ifaces, AF_UNSPEC, &addr)
564 					? MATCH_IFADDR
565 					: MATCH_IFNAME,
566 				*ifaces, -1, ACTION_LISTEN);
567 			ifaces++;
568 		}
569 	}
570 
571 	if (HAVE_OPT( NICE ))
572 		priority_done = 0;
573 
574 # ifdef HAVE_SCHED_SETSCHEDULER
575 	if (HAVE_OPT( PRIORITY )) {
576 		config_priority = OPT_VALUE_PRIORITY;
577 		config_priority_override = 1;
578 		priority_done = 0;
579 	}
580 # endif
581 
582 # ifdef HAVE_WORKING_FORK
583 	do {					/* 'loop' once */
584 		if (!HAVE_OPT( WAIT_SYNC ))
585 			break;
586 		wait_sync = OPT_VALUE_WAIT_SYNC;
587 		if (wait_sync <= 0) {
588 			wait_sync = 0;
589 			break;
590 		}
591 		/* -w requires a fork() even with debug > 0 */
592 		nofork = FALSE;
593 		if (pipe(pipe_fds)) {
594 			exit_code = (errno) ? errno : -1;
595 			msyslog(LOG_ERR,
596 				"Pipe creation failed for --wait-sync: %m");
597 			exit(exit_code);
598 		}
599 		waitsync_fd_to_close = pipe_fds[1];
600 	} while (0);				/* 'loop' once */
601 # endif	/* HAVE_WORKING_FORK */
602 
603 	init_lib();
604 # ifdef SYS_WINNT
605 	/*
606 	 * Start interpolation thread, must occur before first
607 	 * get_systime()
608 	 */
609 	init_winnt_time();
610 # endif
611 	/*
612 	 * Initialize random generator and public key pair
613 	 */
614 	get_systime(&now);
615 
616 	ntp_srandom((int)(now.l_i * now.l_uf));
617 
618 	/*
619 	 * Detach us from the terminal.  May need an #ifndef GIZMO.
620 	 */
621 	if (!nofork) {
622 
623 # ifdef HAVE_WORKING_FORK
624 		rc = fork();
625 		if (-1 == rc) {
626 			exit_code = (errno) ? errno : -1;
627 			msyslog(LOG_ERR, "fork: %m");
628 			exit(exit_code);
629 		}
630 		if (rc > 0) {
631 			/* parent */
632 			exit_code = wait_child_sync_if(pipe_fds[0],
633 						       wait_sync);
634 			exit(exit_code);
635 		}
636 
637 		/*
638 		 * child/daemon
639 		 * close all open files excepting waitsync_fd_to_close.
640 		 * msyslog() unreliable until after init_logging().
641 		 */
642 		closelog();
643 		if (syslog_file != NULL) {
644 			fclose(syslog_file);
645 			syslog_file = NULL;
646 			syslogit = TRUE;
647 		}
648 		close_all_except(waitsync_fd_to_close);
649 		INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \
650 			&& 2 == dup2(0, 2));
651 
652 		init_logging(progname, 0, TRUE);
653 		/* we lost our logfile (if any) daemonizing */
654 		setup_logfile(logfilename);
655 
656 #  ifdef SYS_DOMAINOS
657 		{
658 			uid_$t puid;
659 			status_$t st;
660 
661 			proc2_$who_am_i(&puid);
662 			proc2_$make_server(&puid, &st);
663 		}
664 #  endif	/* SYS_DOMAINOS */
665 #  ifdef HAVE_SETSID
666 		if (setsid() == (pid_t)-1)
667 			msyslog(LOG_ERR, "setsid(): %m");
668 #  elif defined(HAVE_SETPGID)
669 		if (setpgid(0, 0) == -1)
670 			msyslog(LOG_ERR, "setpgid(): %m");
671 #  else		/* !HAVE_SETSID && !HAVE_SETPGID follows */
672 #   ifdef TIOCNOTTY
673 		fid = open("/dev/tty", 2);
674 		if (fid >= 0) {
675 			ioctl(fid, (u_long)TIOCNOTTY, NULL);
676 			close(fid);
677 		}
678 #   endif	/* TIOCNOTTY */
679 		ntp_setpgrp(0, getpid());
680 #  endif	/* !HAVE_SETSID && !HAVE_SETPGID */
681 #  ifdef _AIX
682 		/* Don't get killed by low-on-memory signal. */
683 		sa.sa_handler = catch_danger;
684 		sigemptyset(&sa.sa_mask);
685 		sa.sa_flags = SA_RESTART;
686 		sigaction(SIGDANGER, &sa, NULL);
687 #  endif	/* _AIX */
688 # endif		/* HAVE_WORKING_FORK */
689 	}
690 
691 # ifdef SCO5_CLOCK
692 	/*
693 	 * SCO OpenServer's system clock offers much more precise timekeeping
694 	 * on the base CPU than the other CPUs (for multiprocessor systems),
695 	 * so we must lock to the base CPU.
696 	 */
697 	fd = open("/dev/at1", O_RDONLY);
698 	if (fd >= 0) {
699 		zero = 0;
700 		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
701 			msyslog(LOG_ERR, "cannot lock to base CPU: %m");
702 		close(fd);
703 	}
704 # endif
705 
706 	/* Setup stack size in preparation for locking pages in memory. */
707 # if defined(HAVE_MLOCKALL)
708 #  ifdef HAVE_SETRLIMIT
709 	ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k");
710 #   ifdef RLIMIT_MEMLOCK
711 	/*
712 	 * The default RLIMIT_MEMLOCK is very low on Linux systems.
713 	 * Unless we increase this limit malloc calls are likely to
714 	 * fail if we drop root privilege.  To be useful the value
715 	 * has to be larger than the largest ntpd resident set size.
716 	 */
717 	ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB");
718 #   endif	/* RLIMIT_MEMLOCK */
719 #  endif	/* HAVE_SETRLIMIT */
720 # else	/* !HAVE_MLOCKALL follows */
721 #  ifdef HAVE_PLOCK
722 #   ifdef PROCLOCK
723 #    ifdef _AIX
724 	/*
725 	 * set the stack limit for AIX for plock().
726 	 * see get_aix_stack() for more info.
727 	 */
728 	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0)
729 		msyslog(LOG_ERR,
730 			"Cannot adjust stack limit for plock: %m");
731 #    endif	/* _AIX */
732 #   endif	/* PROCLOCK */
733 #  endif	/* HAVE_PLOCK */
734 # endif	/* !HAVE_MLOCKALL */
735 
736 	/*
737 	 * Set up signals we pay attention to locally.
738 	 */
739 # ifdef SIGDIE1
740 	signal_no_reset(SIGDIE1, finish);
741 	signal_no_reset(SIGDIE2, finish);
742 	signal_no_reset(SIGDIE3, finish);
743 	signal_no_reset(SIGDIE4, finish);
744 # endif
745 # ifdef SIGBUS
746 	signal_no_reset(SIGBUS, finish);
747 # endif
748 
749 # if !defined(SYS_WINNT) && !defined(VMS)
750 #  ifdef DEBUG
751 	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
752 	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
753 #  else
754 	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
755 	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
756 #  endif	/* DEBUG */
757 # endif	/* !SYS_WINNT && !VMS */
758 
759 	/*
760 	 * Set up signals we should never pay attention to.
761 	 */
762 # ifdef SIGPIPE
763 	signal_no_reset(SIGPIPE, SIG_IGN);
764 # endif
765 
766 	/*
767 	 * Call the init_ routines to initialize the data structures.
768 	 *
769 	 * Exactly what command-line options are we expecting here?
770 	 */
771 	INIT_SSL();
772 	init_auth();
773 	init_util();
774 	init_restrict();
775 	init_mon();
776 	init_timer();
777 	init_request();
778 	init_control();
779 	init_peer();
780 # ifdef REFCLOCK
781 	init_refclock();
782 # endif
783 	set_process_priority();
784 	init_proto();		/* Call at high priority */
785 	init_io();
786 	init_loopfilter();
787 	mon_start(MON_ON);	/* monitor on by default now	  */
788 				/* turn off in config if unwanted */
789 
790 	/*
791 	 * Get the configuration.  This is done in a separate module
792 	 * since this will definitely be different for the gizmo board.
793 	 */
794 	getconfig(argc, argv);
795 
796 	if (do_memlock) {
797 # if defined(HAVE_MLOCKALL)
798 		/*
799 		 * lock the process into memory
800 		 */
801 		if (!HAVE_OPT(SAVECONFIGQUIT) &&
802 		    0 != mlockall(MCL_CURRENT|MCL_FUTURE))
803 			msyslog(LOG_ERR, "mlockall(): %m");
804 # else	/* !HAVE_MLOCKALL follows */
805 #  ifdef HAVE_PLOCK
806 #   ifdef PROCLOCK
807 		/*
808 		 * lock the process into memory
809 		 */
810 		if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK))
811 			msyslog(LOG_ERR, "plock(PROCLOCK): %m");
812 #   else	/* !PROCLOCK follows  */
813 #    ifdef TXTLOCK
814 		/*
815 		 * Lock text into ram
816 		 */
817 		if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK))
818 			msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
819 #    else	/* !TXTLOCK follows */
820 		msyslog(LOG_ERR, "plock() - don't know what to lock!");
821 #    endif	/* !TXTLOCK */
822 #   endif	/* !PROCLOCK */
823 #  endif	/* HAVE_PLOCK */
824 # endif	/* !HAVE_MLOCKALL */
825 	}
826 
827 	loop_config(LOOP_DRIFTINIT, 0);
828 	report_event(EVNT_SYSRESTART, NULL, NULL);
829 	initializing = FALSE;
830 
831 # ifdef HAVE_DROPROOT
832 	if (droproot) {
833 		/* Drop super-user privileges and chroot now if the OS supports this */
834 
835 #  ifdef HAVE_LINUX_CAPABILITIES
836 		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
837 		if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
838 			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
839 			exit(-1);
840 		}
841 #  elif HAVE_SOLARIS_PRIVS
842 		/* Nothing to do here */
843 #  else
844 		/* we need a user to switch to */
845 		if (user == NULL) {
846 			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
847 			exit(-1);
848 		}
849 #  endif	/* HAVE_LINUX_CAPABILITIES || HAVE_SOLARIS_PRIVS */
850 
851 		if (user != NULL) {
852 			if (isdigit((unsigned char)*user)) {
853 				sw_uid = (uid_t)strtoul(user, &endp, 0);
854 				if (*endp != '\0')
855 					goto getuser;
856 
857 				if ((pw = getpwuid(sw_uid)) != NULL) {
858 					free(user);
859 					user = estrdup(pw->pw_name);
860 					sw_gid = pw->pw_gid;
861 				} else {
862 					errno = 0;
863 					msyslog(LOG_ERR, "Cannot find user ID %s", user);
864 					exit (-1);
865 				}
866 
867 			} else {
868 getuser:
869 				errno = 0;
870 				if ((pw = getpwnam(user)) != NULL) {
871 					sw_uid = pw->pw_uid;
872 					sw_gid = pw->pw_gid;
873 				} else {
874 					if (errno)
875 						msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
876 					else
877 						msyslog(LOG_ERR, "Cannot find user `%s'", user);
878 					exit (-1);
879 				}
880 			}
881 		}
882 		if (group != NULL) {
883 			if (isdigit((unsigned char)*group)) {
884 				sw_gid = (gid_t)strtoul(group, &endp, 0);
885 				if (*endp != '\0')
886 					goto getgroup;
887 			} else {
888 getgroup:
889 				if ((gr = getgrnam(group)) != NULL) {
890 					sw_gid = gr->gr_gid;
891 				} else {
892 					errno = 0;
893 					msyslog(LOG_ERR, "Cannot find group `%s'", group);
894 					exit (-1);
895 				}
896 			}
897 		}
898 
899 		if (chrootdir ) {
900 			/* make sure cwd is inside the jail: */
901 			if (chdir(chrootdir)) {
902 				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
903 				exit (-1);
904 			}
905 			if (chroot(chrootdir)) {
906 				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
907 				exit (-1);
908 			}
909 			if (chdir("/")) {
910 				msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
911 				exit (-1);
912 			}
913 		}
914 #  ifdef HAVE_SOLARIS_PRIVS
915 		if ((lowprivs = priv_str_to_set(LOWPRIVS, ",", NULL)) == NULL) {
916 			msyslog(LOG_ERR, "priv_str_to_set() failed:%m");
917 			exit(-1);
918 		}
919 		if ((highprivs = priv_allocset()) == NULL) {
920 			msyslog(LOG_ERR, "priv_allocset() failed:%m");
921 			exit(-1);
922 		}
923 		(void) getppriv(PRIV_PERMITTED, highprivs);
924 		(void) priv_intersect(highprivs, lowprivs);
925 		if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
926 			msyslog(LOG_ERR, "setppriv() failed:%m");
927 			exit(-1);
928 		}
929 #  endif /* HAVE_SOLARIS_PRIVS */
930 		if (user && initgroups(user, sw_gid)) {
931 			msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
932 			exit (-1);
933 		}
934 		if (group && setgid(sw_gid)) {
935 			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
936 			exit (-1);
937 		}
938 		if (group && setegid(sw_gid)) {
939 			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
940 			exit (-1);
941 		}
942 		if (group)
943 			setgroups(1, &sw_gid);
944 		else
945 			initgroups(pw->pw_name, pw->pw_gid);
946 		if (user && setuid(sw_uid)) {
947 			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
948 			exit (-1);
949 		}
950 		if (user && seteuid(sw_uid)) {
951 			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
952 			exit (-1);
953 		}
954 
955 #  if !defined(HAVE_LINUX_CAPABILITIES) && !defined(HAVE_SOLARIS_PRIVS)
956 		/*
957 		 * for now assume that the privilege to bind to privileged ports
958 		 * is associated with running with uid 0 - should be refined on
959 		 * ports that allow binding to NTP_PORT with uid != 0
960 		 */
961 		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
962 #  endif /* !HAVE_LINUX_CAPABILITIES && !HAVE_SOLARIS_PRIVS */
963 
964 		if (disable_dynamic_updates && interface_interval) {
965 			interface_interval = 0;
966 			msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking");
967 		}
968 
969 #  ifdef HAVE_LINUX_CAPABILITIES
970 		{
971 			/*
972 			 *  We may be running under non-root uid now, but we still hold full root privileges!
973 			 *  We drop all of them, except for the crucial one or two: cap_sys_time and
974 			 *  cap_net_bind_service if doing dynamic interface tracking.
975 			 */
976 			cap_t caps;
977 			char *captext;
978 
979 			captext = (0 != interface_interval)
980 				      ? "cap_sys_time,cap_net_bind_service=pe"
981 				      : "cap_sys_time=pe";
982 			caps = cap_from_text(captext);
983 			if (!caps) {
984 				msyslog(LOG_ERR,
985 					"cap_from_text(%s) failed: %m",
986 					captext);
987 				exit(-1);
988 			}
989 			if (-1 == cap_set_proc(caps)) {
990 				msyslog(LOG_ERR,
991 					"cap_set_proc() failed to drop root privs: %m");
992 				exit(-1);
993 			}
994 			cap_free(caps);
995 		}
996 #  endif	/* HAVE_LINUX_CAPABILITIES */
997 #  ifdef HAVE_SOLARIS_PRIVS
998 		if (priv_delset(lowprivs, "proc_setid") == -1) {
999 			msyslog(LOG_ERR, "priv_delset() failed:%m");
1000 			exit(-1);
1001 		}
1002 		if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
1003 			msyslog(LOG_ERR, "setppriv() failed:%m");
1004 			exit(-1);
1005 		}
1006 		priv_freeset(lowprivs);
1007 		priv_freeset(highprivs);
1008 #  endif /* HAVE_SOLARIS_PRIVS */
1009 		root_dropped = TRUE;
1010 		fork_deferred_worker();
1011 	}	/* if (droproot) */
1012 # endif	/* HAVE_DROPROOT */
1013 
1014 /* libssecomp sandboxing */
1015 #if defined (LIBSECCOMP) && (KERN_SECCOMP)
1016 	scmp_filter_ctx ctx;
1017 
1018 	if ((ctx = seccomp_init(SCMP_ACT_KILL)) < 0)
1019 		msyslog(LOG_ERR, "%s: seccomp_init(SCMP_ACT_KILL) failed: %m", __func__);
1020 	else {
1021 		msyslog(LOG_DEBUG, "%s: seccomp_init(SCMP_ACT_KILL) succeeded", __func__);
1022 	}
1023 
1024 #ifdef __x86_64__
1025 int scmp_sc[] = {
1026 	SCMP_SYS(adjtimex),
1027 	SCMP_SYS(bind),
1028 	SCMP_SYS(brk),
1029 	SCMP_SYS(chdir),
1030 	SCMP_SYS(clock_gettime),
1031 	SCMP_SYS(clock_settime),
1032 	SCMP_SYS(close),
1033 	SCMP_SYS(connect),
1034 	SCMP_SYS(exit_group),
1035 	SCMP_SYS(fstat),
1036 	SCMP_SYS(fsync),
1037 	SCMP_SYS(futex),
1038 	SCMP_SYS(getitimer),
1039 	SCMP_SYS(getsockname),
1040 	SCMP_SYS(ioctl),
1041 	SCMP_SYS(lseek),
1042 	SCMP_SYS(madvise),
1043 	SCMP_SYS(mmap),
1044 	SCMP_SYS(munmap),
1045 	SCMP_SYS(open),
1046 	SCMP_SYS(poll),
1047 	SCMP_SYS(read),
1048 	SCMP_SYS(recvmsg),
1049 	SCMP_SYS(rename),
1050 	SCMP_SYS(rt_sigaction),
1051 	SCMP_SYS(rt_sigprocmask),
1052 	SCMP_SYS(rt_sigreturn),
1053 	SCMP_SYS(select),
1054 	SCMP_SYS(sendto),
1055 	SCMP_SYS(setitimer),
1056 	SCMP_SYS(setsid),
1057 	SCMP_SYS(socket),
1058 	SCMP_SYS(stat),
1059 	SCMP_SYS(time),
1060 	SCMP_SYS(write),
1061 };
1062 #endif
1063 #ifdef __i386__
1064 int scmp_sc[] = {
1065 	SCMP_SYS(_newselect),
1066 	SCMP_SYS(adjtimex),
1067 	SCMP_SYS(brk),
1068 	SCMP_SYS(chdir),
1069 	SCMP_SYS(clock_gettime),
1070 	SCMP_SYS(clock_settime),
1071 	SCMP_SYS(close),
1072 	SCMP_SYS(exit_group),
1073 	SCMP_SYS(fsync),
1074 	SCMP_SYS(futex),
1075 	SCMP_SYS(getitimer),
1076 	SCMP_SYS(madvise),
1077 	SCMP_SYS(mmap),
1078 	SCMP_SYS(mmap2),
1079 	SCMP_SYS(munmap),
1080 	SCMP_SYS(open),
1081 	SCMP_SYS(poll),
1082 	SCMP_SYS(read),
1083 	SCMP_SYS(rename),
1084 	SCMP_SYS(rt_sigaction),
1085 	SCMP_SYS(rt_sigprocmask),
1086 	SCMP_SYS(select),
1087 	SCMP_SYS(setitimer),
1088 	SCMP_SYS(setsid),
1089 	SCMP_SYS(sigprocmask),
1090 	SCMP_SYS(sigreturn),
1091 	SCMP_SYS(socketcall),
1092 	SCMP_SYS(stat64),
1093 	SCMP_SYS(time),
1094 	SCMP_SYS(write),
1095 };
1096 #endif
1097 	{
1098 		int i;
1099 
1100 		for (i = 0; i < COUNTOF(scmp_sc); i++) {
1101 			if (seccomp_rule_add(ctx,
1102 			    SCMP_ACT_ALLOW, scmp_sc[i], 0) < 0) {
1103 				msyslog(LOG_ERR,
1104 				    "%s: seccomp_rule_add() failed: %m",
1105 				    __func__);
1106 			}
1107 		}
1108 	}
1109 
1110 	if (seccomp_load(ctx) < 0)
1111 		msyslog(LOG_ERR, "%s: seccomp_load() failed: %m",
1112 		    __func__);
1113 	else {
1114 		msyslog(LOG_DEBUG, "%s: seccomp_load() succeeded", __func__);
1115 	}
1116 #endif /* LIBSECCOMP and KERN_SECCOMP */
1117 
1118 # ifdef HAVE_IO_COMPLETION_PORT
1119 
1120 	for (;;) {
1121 		GetReceivedBuffers();
1122 # else /* normal I/O */
1123 
1124 	BLOCK_IO_AND_ALARM();
1125 	was_alarmed = FALSE;
1126 
1127 	for (;;) {
1128 		if (alarm_flag) {	/* alarmed? */
1129 			was_alarmed = TRUE;
1130 			alarm_flag = FALSE;
1131 		}
1132 
1133 		if (!was_alarmed && !has_full_recv_buffer()) {
1134 			/*
1135 			 * Nothing to do.  Wait for something.
1136 			 */
1137 			io_handler();
1138 		}
1139 
1140 		if (alarm_flag) {	/* alarmed? */
1141 			was_alarmed = TRUE;
1142 			alarm_flag = FALSE;
1143 		}
1144 
1145 		if (was_alarmed) {
1146 			UNBLOCK_IO_AND_ALARM();
1147 			/*
1148 			 * Out here, signals are unblocked.  Call timer routine
1149 			 * to process expiry.
1150 			 */
1151 			timer();
1152 			was_alarmed = FALSE;
1153 			BLOCK_IO_AND_ALARM();
1154 		}
1155 
1156 # endif		/* !HAVE_IO_COMPLETION_PORT */
1157 
1158 # ifdef DEBUG_TIMING
1159 		{
1160 			l_fp pts;
1161 			l_fp tsa, tsb;
1162 			int bufcount = 0;
1163 
1164 			get_systime(&pts);
1165 			tsa = pts;
1166 # endif
1167 			rbuf = get_full_recv_buffer();
1168 			while (rbuf != NULL) {
1169 				if (alarm_flag) {
1170 					was_alarmed = TRUE;
1171 					alarm_flag = FALSE;
1172 				}
1173 				UNBLOCK_IO_AND_ALARM();
1174 
1175 				if (was_alarmed) {
1176 					/* avoid timer starvation during lengthy I/O handling */
1177 					timer();
1178 					was_alarmed = FALSE;
1179 				}
1180 
1181 				/*
1182 				 * Call the data procedure to handle each received
1183 				 * packet.
1184 				 */
1185 				if (rbuf->receiver != NULL) {
1186 # ifdef DEBUG_TIMING
1187 					l_fp dts = pts;
1188 
1189 					L_SUB(&dts, &rbuf->recv_time);
1190 					DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
1191 					collect_timing(rbuf, "buffer processing delay", 1, &dts);
1192 					bufcount++;
1193 # endif
1194 					(*rbuf->receiver)(rbuf);
1195 				} else {
1196 					msyslog(LOG_ERR, "fatal: receive buffer callback NULL");
1197 					abort();
1198 				}
1199 
1200 				BLOCK_IO_AND_ALARM();
1201 				freerecvbuf(rbuf);
1202 				rbuf = get_full_recv_buffer();
1203 			}
1204 # ifdef DEBUG_TIMING
1205 			get_systime(&tsb);
1206 			L_SUB(&tsb, &tsa);
1207 			if (bufcount) {
1208 				collect_timing(NULL, "processing", bufcount, &tsb);
1209 				DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
1210 			}
1211 		}
1212 # endif
1213 
1214 		/*
1215 		 * Go around again
1216 		 */
1217 
1218 # ifdef HAVE_DNSREGISTRATION
1219 		if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
1220 			mdnsreg = current_time;
1221 			msyslog(LOG_INFO, "Attempting to register mDNS");
1222 			if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL,
1223 			    htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
1224 				if (!--mdnstries) {
1225 					msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
1226 				} else {
1227 					msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
1228 				}
1229 			} else {
1230 				msyslog(LOG_INFO, "mDNS service registered.");
1231 				mdnsreg = FALSE;
1232 			}
1233 		}
1234 # endif /* HAVE_DNSREGISTRATION */
1235 
1236 	}
1237 	UNBLOCK_IO_AND_ALARM();
1238 	return 1;
1239 }
1240 #endif	/* !SIM */
1241 
1242 
1243 #if !defined(SIM) && defined(SIGDIE1)
1244 /*
1245  * finish - exit gracefully
1246  */
1247 static RETSIGTYPE
1248 finish(
1249 	int sig
1250 	)
1251 {
1252 	const char *sig_desc;
1253 
1254 	sig_desc = NULL;
1255 #ifdef HAVE_STRSIGNAL
1256 	sig_desc = strsignal(sig);
1257 #endif
1258 	if (sig_desc == NULL)
1259 		sig_desc = "";
1260 	msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname,
1261 		sig, sig_desc);
1262 	/* See Bug 2513 and Bug 2522 re the unlink of PIDFILE */
1263 # ifdef HAVE_DNSREGISTRATION
1264 	if (mdns != NULL)
1265 		DNSServiceRefDeallocate(mdns);
1266 # endif
1267 	peer_cleanup();
1268 	exit(0);
1269 }
1270 #endif	/* !SIM && SIGDIE1 */
1271 
1272 
1273 #ifndef SIM
1274 /*
1275  * wait_child_sync_if - implements parent side of -w/--wait-sync
1276  */
1277 # ifdef HAVE_WORKING_FORK
1278 static int
1279 wait_child_sync_if(
1280 	int	pipe_read_fd,
1281 	long	wait_sync
1282 	)
1283 {
1284 	int	rc;
1285 	int	exit_code;
1286 	time_t	wait_end_time;
1287 	time_t	cur_time;
1288 	time_t	wait_rem;
1289 	fd_set	readset;
1290 	struct timeval wtimeout;
1291 
1292 	if (0 == wait_sync)
1293 		return 0;
1294 
1295 	/* waitsync_fd_to_close used solely by child */
1296 	close(waitsync_fd_to_close);
1297 	wait_end_time = time(NULL) + wait_sync;
1298 	do {
1299 		cur_time = time(NULL);
1300 		wait_rem = (wait_end_time > cur_time)
1301 				? (wait_end_time - cur_time)
1302 				: 0;
1303 		wtimeout.tv_sec = wait_rem;
1304 		wtimeout.tv_usec = 0;
1305 		FD_ZERO(&readset);
1306 		FD_SET(pipe_read_fd, &readset);
1307 		rc = select(pipe_read_fd + 1, &readset, NULL, NULL,
1308 			    &wtimeout);
1309 		if (-1 == rc) {
1310 			if (EINTR == errno)
1311 				continue;
1312 			exit_code = (errno) ? errno : -1;
1313 			msyslog(LOG_ERR,
1314 				"--wait-sync select failed: %m");
1315 			return exit_code;
1316 		}
1317 		if (0 == rc) {
1318 			/*
1319 			 * select() indicated a timeout, but in case
1320 			 * its timeouts are affected by a step of the
1321 			 * system clock, select() again with a zero
1322 			 * timeout to confirm.
1323 			 */
1324 			FD_ZERO(&readset);
1325 			FD_SET(pipe_read_fd, &readset);
1326 			wtimeout.tv_sec = 0;
1327 			wtimeout.tv_usec = 0;
1328 			rc = select(pipe_read_fd + 1, &readset, NULL,
1329 				    NULL, &wtimeout);
1330 			if (0 == rc)	/* select() timeout */
1331 				break;
1332 			else		/* readable */
1333 				return 0;
1334 		} else			/* readable */
1335 			return 0;
1336 	} while (wait_rem > 0);
1337 
1338 	fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n",
1339 		progname, wait_sync);
1340 	return ETIMEDOUT;
1341 }
1342 # endif	/* HAVE_WORKING_FORK */
1343 
1344 
1345 /*
1346  * assertion_failed - Redirect assertion failures to msyslog().
1347  */
1348 static void
1349 assertion_failed(
1350 	const char *file,
1351 	int line,
1352 	isc_assertiontype_t type,
1353 	const char *cond
1354 	)
1355 {
1356 	isc_assertion_setcallback(NULL);    /* Avoid recursion */
1357 
1358 	msyslog(LOG_ERR, "%s:%d: %s(%s) failed",
1359 		file, line, isc_assertion_typetotext(type), cond);
1360 	msyslog(LOG_ERR, "exiting (due to assertion failure)");
1361 
1362 #if defined(DEBUG) && defined(SYS_WINNT)
1363 	if (debug)
1364 		DebugBreak();
1365 #endif
1366 
1367 	abort();
1368 }
1369 
1370 
1371 /*
1372  * library_fatal_error - Handle fatal errors from our libraries.
1373  */
1374 static void
1375 library_fatal_error(
1376 	const char *file,
1377 	int line,
1378 	const char *format,
1379 	va_list args
1380 	)
1381 {
1382 	char errbuf[256];
1383 
1384 	isc_error_setfatal(NULL);  /* Avoid recursion */
1385 
1386 	msyslog(LOG_ERR, "%s:%d: fatal error:", file, line);
1387 	vsnprintf(errbuf, sizeof(errbuf), format, args);
1388 	msyslog(LOG_ERR, "%s", errbuf);
1389 	msyslog(LOG_ERR, "exiting (due to fatal error in library)");
1390 
1391 #if defined(DEBUG) && defined(SYS_WINNT)
1392 	if (debug)
1393 		DebugBreak();
1394 #endif
1395 
1396 	abort();
1397 }
1398 
1399 
1400 /*
1401  * library_unexpected_error - Handle non fatal errors from our libraries.
1402  */
1403 # define MAX_UNEXPECTED_ERRORS 100
1404 int unexpected_error_cnt = 0;
1405 static void
1406 library_unexpected_error(
1407 	const char *file,
1408 	int line,
1409 	const char *format,
1410 	va_list args
1411 	)
1412 {
1413 	char errbuf[256];
1414 
1415 	if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS)
1416 		return;	/* avoid clutter in log */
1417 
1418 	msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line);
1419 	vsnprintf(errbuf, sizeof(errbuf), format, args);
1420 	msyslog(LOG_ERR, "%s", errbuf);
1421 
1422 	if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS)
1423 		msyslog(LOG_ERR, "Too many errors.  Shutting up.");
1424 
1425 }
1426 #endif	/* !SIM */
1427 
1428 #if !defined(SIM) && !defined(SYS_WINNT)
1429 # ifdef DEBUG
1430 
1431 /*
1432  * moredebug - increase debugging verbosity
1433  */
1434 static RETSIGTYPE
1435 moredebug(
1436 	int sig
1437 	)
1438 {
1439 	int saved_errno = errno;
1440 
1441 	if (debug < 255)
1442 	{
1443 		debug++;
1444 		msyslog(LOG_DEBUG, "debug raised to %d", debug);
1445 	}
1446 	errno = saved_errno;
1447 }
1448 
1449 
1450 /*
1451  * lessdebug - decrease debugging verbosity
1452  */
1453 static RETSIGTYPE
1454 lessdebug(
1455 	int sig
1456 	)
1457 {
1458 	int saved_errno = errno;
1459 
1460 	if (debug > 0)
1461 	{
1462 		debug--;
1463 		msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1464 	}
1465 	errno = saved_errno;
1466 }
1467 
1468 # else	/* !DEBUG follows */
1469 
1470 
1471 /*
1472  * no_debug - We don't do the debug here.
1473  */
1474 static RETSIGTYPE
1475 no_debug(
1476 	int sig
1477 	)
1478 {
1479 	int saved_errno = errno;
1480 
1481 	msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1482 	errno = saved_errno;
1483 }
1484 # endif	/* !DEBUG */
1485 #endif	/* !SIM && !SYS_WINNT */
1486