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