xref: /freebsd/contrib/ntp/ntpd/ntpd.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
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 
14 #ifdef SIM
15 #include "ntpsim.h"
16 #endif
17 
18 #ifdef HAVE_UNISTD_H
19 # include <unistd.h>
20 #endif
21 #ifdef HAVE_SYS_STAT_H
22 # include <sys/stat.h>
23 #endif
24 #include <stdio.h>
25 #ifndef SYS_WINNT
26 # if !defined(VMS)	/*wjm*/
27 #  ifdef HAVE_SYS_PARAM_H
28 #   include <sys/param.h>
29 #  endif
30 # endif /* VMS */
31 # ifdef HAVE_SYS_SIGNAL_H
32 #  include <sys/signal.h>
33 # else
34 #  include <signal.h>
35 # endif
36 # ifdef HAVE_SYS_IOCTL_H
37 #  include <sys/ioctl.h>
38 # endif /* HAVE_SYS_IOCTL_H */
39 # ifdef HAVE_SYS_RESOURCE_H
40 #  include <sys/resource.h>
41 # endif /* HAVE_SYS_RESOURCE_H */
42 #else
43 # include <signal.h>
44 # include <process.h>
45 # include <io.h>
46 # include "../libntp/log.h"
47 # include <clockstuff.h>
48 # include <crtdbg.h>
49 #endif /* SYS_WINNT */
50 #if defined(HAVE_RTPRIO)
51 # ifdef HAVE_SYS_RESOURCE_H
52 #  include <sys/resource.h>
53 # endif
54 # ifdef HAVE_SYS_LOCK_H
55 #  include <sys/lock.h>
56 # endif
57 # include <sys/rtprio.h>
58 #else
59 # ifdef HAVE_PLOCK
60 #  ifdef HAVE_SYS_LOCK_H
61 #	include <sys/lock.h>
62 #  endif
63 # endif
64 #endif
65 #if defined(HAVE_SCHED_SETSCHEDULER)
66 # ifdef HAVE_SCHED_H
67 #  include <sched.h>
68 # else
69 #  ifdef HAVE_SYS_SCHED_H
70 #   include <sys/sched.h>
71 #  endif
72 # endif
73 #endif
74 #if defined(HAVE_SYS_MMAN_H)
75 # include <sys/mman.h>
76 #endif
77 
78 #ifdef HAVE_TERMIOS_H
79 # include <termios.h>
80 #endif
81 
82 #ifdef SYS_DOMAINOS
83 # include <apollo/base.h>
84 #endif /* SYS_DOMAINOS */
85 
86 #include "recvbuff.h"
87 #include "ntp_cmdargs.h"
88 
89 #if 0				/* HMS: I don't think we need this. 961223 */
90 #ifdef LOCK_PROCESS
91 # ifdef SYS_SOLARIS
92 #  include <sys/mman.h>
93 # else
94 #  include <sys/lock.h>
95 # endif
96 #endif
97 #endif
98 
99 #ifdef _AIX
100 # include <ulimit.h>
101 #endif /* _AIX */
102 
103 #ifdef SCO5_CLOCK
104 # include <sys/ci/ciioctl.h>
105 #endif
106 
107 #ifdef HAVE_CLOCKCTL
108 # include <ctype.h>
109 # include <grp.h>
110 # include <pwd.h>
111 #endif
112 
113 /*
114  * Signals we catch for debugging.	If not debugging we ignore them.
115  */
116 #define MOREDEBUGSIG	SIGUSR1
117 #define LESSDEBUGSIG	SIGUSR2
118 
119 /*
120  * Signals which terminate us gracefully.
121  */
122 #ifndef SYS_WINNT
123 # define SIGDIE1 	SIGHUP
124 # define SIGDIE3 	SIGQUIT
125 # define SIGDIE2 	SIGINT
126 # define SIGDIE4 	SIGTERM
127 #endif /* SYS_WINNT */
128 
129 #if defined SYS_WINNT
130 /* handles for various threads, process, and objects */
131 HANDLE ResolverThreadHandle = NULL;
132 /* variables used to inform the Service Control Manager of our current state */
133 BOOL NoWinService = FALSE;
134 SERVICE_STATUS ssStatus;
135 SERVICE_STATUS_HANDLE	sshStatusHandle;
136 HANDLE WaitHandles[3] = { NULL, NULL, NULL };
137 char szMsgPath[255];
138 static BOOL WINAPI OnConsoleEvent(DWORD dwCtrlType);
139 BOOL init_randfile();
140 #endif /* SYS_WINNT */
141 
142 /*
143  * Scheduling priority we run at
144  */
145 #define NTPD_PRIO	(-12)
146 
147 int priority_done = 2;		/* 0 - Set priority */
148 				/* 1 - priority is OK where it is */
149 				/* 2 - Don't set priority */
150 				/* 1 and 2 are pretty much the same */
151 
152 /*
153  * Debugging flag
154  */
155 volatile int debug;
156 
157 /*
158  * Set the processing not to be in the forground
159  */
160 int forground_process = FALSE;
161 
162 /*
163  * No-fork flag.  If set, we do not become a background daemon.
164  */
165 int nofork;
166 
167 #ifdef HAVE_CLOCKCTL
168 char *user = NULL;		/* User to switch to */
169 char *group = NULL;		/* group to switch to */
170 char *chrootdir = NULL;		/* directory to chroot to */
171 int sw_uid;
172 int sw_gid;
173 char *endp;
174 struct group *gr;
175 struct passwd *pw;
176 #endif /* HAVE_CLOCKCTL */
177 
178 /*
179  * Initializing flag.  All async routines watch this and only do their
180  * thing when it is clear.
181  */
182 int initializing;
183 
184 /*
185  * Version declaration
186  */
187 extern const char *Version;
188 
189 int was_alarmed;
190 
191 #ifdef DECL_SYSCALL
192 /*
193  * We put this here, since the argument profile is syscall-specific
194  */
195 extern int syscall	P((int, ...));
196 #endif /* DECL_SYSCALL */
197 
198 
199 #ifdef	SIGDIE2
200 static	RETSIGTYPE	finish		P((int));
201 #endif	/* SIGDIE2 */
202 
203 #ifdef	DEBUG
204 #ifndef SYS_WINNT
205 static	RETSIGTYPE	moredebug	P((int));
206 static	RETSIGTYPE	lessdebug	P((int));
207 #endif
208 #else /* not DEBUG */
209 static	RETSIGTYPE	no_debug	P((int));
210 #endif	/* not DEBUG */
211 
212 int 		ntpdmain		P((int, char **));
213 static void	set_process_priority	P((void));
214 
215 #ifdef SIM
216 int
217 main(
218 	int argc,
219 	char *argv[]
220 	)
221 {
222 	return ntpsim(argc, argv);
223 }
224 #else /* SIM */
225 #ifdef NO_MAIN_ALLOWED
226 CALL(ntpd,"ntpd",ntpdmain);
227 #else
228 int
229 main(
230 	int argc,
231 	char *argv[]
232 	)
233 {
234 	return ntpdmain(argc, argv);
235 }
236 #endif
237 #endif /* SIM */
238 
239 #ifdef _AIX
240 /*
241  * OK. AIX is different than solaris in how it implements plock().
242  * If you do NOT adjust the stack limit, you will get the MAXIMUM
243  * stack size allocated and PINNED with you program. To check the
244  * value, use ulimit -a.
245  *
246  * To fix this, we create an automatic variable and set our stack limit
247  * to that PLUS 32KB of extra space (we need some headroom).
248  *
249  * This subroutine gets the stack address.
250  *
251  * Grover Davidson and Matt Ladendorf
252  *
253  */
254 static char *
255 get_aix_stack(void)
256 {
257 	char ch;
258 	return (&ch);
259 }
260 
261 /*
262  * Signal handler for SIGDANGER.
263  */
264 static void
265 catch_danger(int signo)
266 {
267 	msyslog(LOG_INFO, "ntpd: setpgid(): %m");
268 	/* Make the system believe we'll free something, but don't do it! */
269 	return;
270 }
271 #endif /* _AIX */
272 
273 /*
274  * Set the process priority
275  */
276 static void
277 set_process_priority(void)
278 {
279 
280 #ifdef DEBUG
281 	if (debug > 1)
282 		msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
283 			((priority_done)
284 			 ? "Leave priority alone"
285 			 : "Attempt to set priority"
286 				),
287 			priority_done);
288 #endif /* DEBUG */
289 
290 #ifdef SYS_WINNT
291 	priority_done += NT_set_process_priority();
292 #endif
293 
294 #if defined(HAVE_SCHED_SETSCHEDULER)
295 	if (!priority_done) {
296 		extern int config_priority_override, config_priority;
297 		int pmax, pmin;
298 		struct sched_param sched;
299 
300 		pmax = sched_get_priority_max(SCHED_FIFO);
301 		sched.sched_priority = pmax;
302 		if ( config_priority_override ) {
303 			pmin = sched_get_priority_min(SCHED_FIFO);
304 			if ( config_priority > pmax )
305 				sched.sched_priority = pmax;
306 			else if ( config_priority < pmin )
307 				sched.sched_priority = pmin;
308 			else
309 				sched.sched_priority = config_priority;
310 		}
311 		if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
312 			msyslog(LOG_ERR, "sched_setscheduler(): %m");
313 		else
314 			++priority_done;
315 	}
316 #endif /* HAVE_SCHED_SETSCHEDULER */
317 #if defined(HAVE_RTPRIO)
318 # ifdef RTP_SET
319 	if (!priority_done) {
320 		struct rtprio srtp;
321 
322 		srtp.type = RTP_PRIO_REALTIME;	/* was: RTP_PRIO_NORMAL */
323 		srtp.prio = 0;		/* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
324 
325 		if (rtprio(RTP_SET, getpid(), &srtp) < 0)
326 			msyslog(LOG_ERR, "rtprio() error: %m");
327 		else
328 			++priority_done;
329 	}
330 # else /* not RTP_SET */
331 	if (!priority_done) {
332 		if (rtprio(0, 120) < 0)
333 			msyslog(LOG_ERR, "rtprio() error: %m");
334 		else
335 			++priority_done;
336 	}
337 # endif /* not RTP_SET */
338 #endif  /* HAVE_RTPRIO */
339 #if defined(NTPD_PRIO) && NTPD_PRIO != 0
340 # ifdef HAVE_ATT_NICE
341 	if (!priority_done) {
342 		errno = 0;
343 		if (-1 == nice (NTPD_PRIO) && errno != 0)
344 			msyslog(LOG_ERR, "nice() error: %m");
345 		else
346 			++priority_done;
347 	}
348 # endif /* HAVE_ATT_NICE */
349 # ifdef HAVE_BSD_NICE
350 	if (!priority_done) {
351 		if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
352 			msyslog(LOG_ERR, "setpriority() error: %m");
353 		else
354 			++priority_done;
355 	}
356 # endif /* HAVE_BSD_NICE */
357 #endif /* NTPD_PRIO && NTPD_PRIO != 0 */
358 	if (!priority_done)
359 		msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
360 }
361 
362 
363 /*
364  * Main program.  Initialize us, disconnect us from the tty if necessary,
365  * and loop waiting for I/O and/or timer expiries.
366  */
367 int
368 ntpdmain(
369 	int argc,
370 	char *argv[]
371 	)
372 {
373 	l_fp now;
374 	char *cp;
375 	struct recvbuf *rbuflist;
376 	struct recvbuf *rbuf;
377 #ifdef _AIX			/* HMS: ifdef SIGDANGER? */
378 	struct sigaction sa;
379 #endif
380 
381 	initializing = 1;		/* mark that we are initializing */
382 	debug = 0;			/* no debugging by default */
383 	nofork = 0;			/* will fork by default */
384 
385 #ifdef HAVE_UMASK
386 	{
387 		mode_t uv;
388 
389 		uv = umask(0);
390 		if(uv)
391 			(void) umask(uv);
392 		else
393 			(void) umask(022);
394 	}
395 #endif
396 
397 #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
398 	{
399 		uid_t uid;
400 
401 		uid = getuid();
402 		if (uid)
403 		{
404 			msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
405 			exit(1);
406 		}
407 	}
408 #endif
409 
410 #ifdef SYS_WINNT
411 	/* Set the Event-ID message-file name. */
412 	if (!GetModuleFileName(NULL, szMsgPath, sizeof(szMsgPath))) {
413 		msyslog(LOG_ERR, "GetModuleFileName(PGM_EXE_FILE) failed: %m\n");
414 		exit(1);
415 	}
416 	addSourceToRegistry("NTP", szMsgPath);
417 #endif
418 	getstartup(argc, argv); /* startup configuration, may set debug */
419 
420 	if (debug)
421 	    printf("%s\n", Version);
422 
423 	/*
424 	 * Initialize random generator and public key pair
425 	 */
426 #ifdef SYS_WINNT
427 	/* Initialize random file before OpenSSL checks */
428 	if(!init_randfile())
429 		msyslog(LOG_ERR, "Unable to initialize .rnd file\n");
430 #endif
431 	get_systime(&now);
432 	SRANDOM((int)(now.l_i * now.l_uf));
433 
434 #if !defined(VMS)
435 # ifndef NODETACH
436 	/*
437 	 * Detach us from the terminal.  May need an #ifndef GIZMO.
438 	 */
439 #  ifdef DEBUG
440 	if (!debug && !nofork)
441 #  else /* DEBUG */
442 	if (!nofork)
443 #  endif /* DEBUG */
444 	{
445 #  ifndef SYS_WINNT
446 #   ifdef HAVE_DAEMON
447 		daemon(0, 0);
448 #   else /* not HAVE_DAEMON */
449 		if (fork())	/* HMS: What about a -1? */
450 			exit(0);
451 
452 		{
453 #if !defined(F_CLOSEM)
454 			u_long s;
455 			int max_fd;
456 #endif /* not F_CLOSEM */
457 
458 #if defined(F_CLOSEM)
459 			/*
460 			 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
461 			 * by Eric Agar (saves us from doing 32767 system
462 			 * calls)
463 			 */
464 			if (fcntl(0, F_CLOSEM, 0) == -1)
465 			    msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
466 #else  /* not F_CLOSEM */
467 
468 # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
469 			max_fd = sysconf(_SC_OPEN_MAX);
470 # else /* HAVE_SYSCONF && _SC_OPEN_MAX */
471 			max_fd = getdtablesize();
472 # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
473 			for (s = 0; s < max_fd; s++)
474 				(void) close((int)s);
475 #endif /* not F_CLOSEM */
476 			(void) open("/", 0);
477 			(void) dup2(0, 1);
478 			(void) dup2(0, 2);
479 #ifdef SYS_DOMAINOS
480 			{
481 				uid_$t puid;
482 				status_$t st;
483 
484 				proc2_$who_am_i(&puid);
485 				proc2_$make_server(&puid, &st);
486 			}
487 #endif /* SYS_DOMAINOS */
488 #if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
489 # ifdef HAVE_SETSID
490 			if (setsid() == (pid_t)-1)
491 				msyslog(LOG_ERR, "ntpd: setsid(): %m");
492 # else
493 			if (setpgid(0, 0) == -1)
494 				msyslog(LOG_ERR, "ntpd: setpgid(): %m");
495 # endif
496 #else /* HAVE_SETPGID || HAVE_SETSID */
497 			{
498 # if defined(TIOCNOTTY)
499 				int fid;
500 
501 				fid = open("/dev/tty", 2);
502 				if (fid >= 0)
503 				{
504 					(void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
505 					(void) close(fid);
506 				}
507 # endif /* defined(TIOCNOTTY) */
508 # ifdef HAVE_SETPGRP_0
509 				(void) setpgrp();
510 # else /* HAVE_SETPGRP_0 */
511 				(void) setpgrp(0, getpid());
512 # endif /* HAVE_SETPGRP_0 */
513 			}
514 #endif /* HAVE_SETPGID || HAVE_SETSID */
515 #ifdef _AIX
516 			/* Don't get killed by low-on-memory signal. */
517 			sa.sa_handler = catch_danger;
518 			sigemptyset(&sa.sa_mask);
519 			sa.sa_flags = SA_RESTART;
520 
521 			(void) sigaction(SIGDANGER, &sa, NULL);
522 #endif /* _AIX */
523 		}
524 #   endif /* not HAVE_DAEMON */
525 #  else /* SYS_WINNT */
526 
527 		{
528 			if (NoWinService == FALSE) {
529 				SERVICE_TABLE_ENTRY dispatchTable[] = {
530 				{ TEXT("NetworkTimeProtocol"), (LPSERVICE_MAIN_FUNCTION)service_main },
531 				{ NULL, NULL }
532 				};
533 
534 				/* daemonize */
535 				if (!StartServiceCtrlDispatcher(dispatchTable))
536 				{
537 					msyslog(LOG_ERR, "StartServiceCtrlDispatcher: %m");
538 					ExitProcess(2);
539 				}
540 			}
541 			else {
542 				service_main(argc, argv);
543 				return 0;
544 			}
545 		}
546 #  endif /* SYS_WINNT */
547 	}
548 # endif /* NODETACH */
549 # if defined(SYS_WINNT) && !defined(NODETACH)
550 	else
551 		service_main(argc, argv);
552 	return 0;	/* must return a value */
553 } /* end main */
554 
555 /*
556  * If this runs as a service under NT, the main thread will block at
557  * StartServiceCtrlDispatcher() and another thread will be started by the
558  * Service Control Dispatcher which will begin execution at the routine
559  * specified in that call (viz. service_main)
560  */
561 void
562 service_main(
563 	DWORD argc,
564 	LPTSTR *argv
565 	)
566 {
567 	char *cp;
568 	struct recvbuf *rbuflist;
569 	struct recvbuf *rbuf;
570 
571 	if(!debug && NoWinService == FALSE)
572 	{
573 		/* register our service control handler */
574 		sshStatusHandle = RegisterServiceCtrlHandler( TEXT("NetworkTimeProtocol"),
575 							(LPHANDLER_FUNCTION)service_ctrl);
576 		if(sshStatusHandle == 0)
577 		{
578 			msyslog(LOG_ERR, "RegisterServiceCtrlHandler failed: %m");
579 			return;
580 		}
581 
582 		/* report pending status to Service Control Manager */
583 		ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
584 		ssStatus.dwCurrentState = SERVICE_START_PENDING;
585 		ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
586 		ssStatus.dwWin32ExitCode = NO_ERROR;
587 		ssStatus.dwServiceSpecificExitCode = 0;
588 		ssStatus.dwCheckPoint = 1;
589 		ssStatus.dwWaitHint = 5000;
590 		if (!SetServiceStatus(sshStatusHandle, &ssStatus))
591 		{
592 			msyslog(LOG_ERR, "SetServiceStatus: %m");
593 			ssStatus.dwCurrentState = SERVICE_STOPPED;
594 			SetServiceStatus(sshStatusHandle, &ssStatus);
595 			return;
596 		}
597 
598 	}  /* debug */
599 # endif /* defined(SYS_WINNT) && !defined(NODETACH) */
600 #endif /* VMS */
601 
602 	/*
603 	 * Logging.  This may actually work on the gizmo board.  Find a name
604 	 * to log with by using the basename of argv[0]
605 	 */
606 	cp = strrchr(argv[0], '/');
607 	if (cp == 0)
608 		cp = argv[0];
609 	else
610 		cp++;
611 
612 	debug = 0; /* will be immediately re-initialized 8-( */
613 	getstartup(argc, argv); /* startup configuration, catch logfile this time */
614 
615 #if !defined(VMS)
616 
617 # ifndef LOG_DAEMON
618 	openlog(cp, LOG_PID);
619 # else /* LOG_DAEMON */
620 
621 #  ifndef LOG_NTP
622 #	define	LOG_NTP LOG_DAEMON
623 #  endif
624 	openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);
625 #  ifdef DEBUG
626 	if (debug)
627 		setlogmask(LOG_UPTO(LOG_DEBUG));
628 	else
629 #  endif /* DEBUG */
630 		setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
631 # endif /* LOG_DAEMON */
632 #endif	/* !SYS_WINNT && !VMS */
633 
634 	NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
635 		msyslog(LOG_NOTICE, "%s", Version);
636 
637 #ifdef SYS_WINNT
638 	/* GMS 1/18/1997
639 	 * TODO: lock the process in memory using SetProcessWorkingSetSize() and VirtualLock() functions
640 	 *
641 	 process_handle = GetCurrentProcess();
642 	 if (SetProcessWorkingSetSize(process_handle, 2097152 , 4194304 ) == TRUE) {
643 	 if (VirtualLock(0 , 4194304) == FALSE)
644 	 msyslog(LOG_ERR, "VirtualLock() failed: %m");
645 	 } else {
646 	 msyslog(LOG_ERR, "SetProcessWorkingSetSize() failed: %m");
647 	 }
648 	*/
649 #endif /* SYS_WINNT */
650 
651 #ifdef SCO5_CLOCK
652 	/*
653 	 * SCO OpenServer's system clock offers much more precise timekeeping
654 	 * on the base CPU than the other CPUs (for multiprocessor systems),
655 	 * so we must lock to the base CPU.
656 	 */
657 	{
658 	    int fd = open("/dev/at1", O_RDONLY);
659 	    if (fd >= 0) {
660 		int zero = 0;
661 		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
662 		    msyslog(LOG_ERR, "cannot lock to base CPU: %m\n");
663 		close( fd );
664 	    } /* else ...
665 	       *   If we can't open the device, this probably just isn't
666 	       *   a multiprocessor system, so we're A-OK.
667 	       */
668 	}
669 #endif
670 
671 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
672 # ifdef HAVE_SETRLIMIT
673 	/*
674 	 * Set the stack limit to something smaller, so that we don't lock a lot
675 	 * of unused stack memory.
676 	 */
677 	{
678 	    struct rlimit rl;
679 
680 	    if (getrlimit(RLIMIT_STACK, &rl) != -1
681 		&& (rl.rlim_cur = 20 * 4096) < rl.rlim_max)
682 	    {
683 		    if (setrlimit(RLIMIT_STACK, &rl) == -1)
684 		    {
685 			    msyslog(LOG_ERR,
686 				"Cannot adjust stack limit for mlockall: %m");
687 		    }
688 	    }
689 	}
690 # endif /* HAVE_SETRLIMIT */
691 	/*
692 	 * lock the process into memory
693 	 */
694 	if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
695 		msyslog(LOG_ERR, "mlockall(): %m");
696 #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
697 # ifdef HAVE_PLOCK
698 #  ifdef PROCLOCK
699 #   ifdef _AIX
700 	/*
701 	 * set the stack limit for AIX for plock().
702 	 * see get_aix_stack for more info.
703 	 */
704 	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
705 	{
706 		msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
707 	}
708 #   endif /* _AIX */
709 	/*
710 	 * lock the process into memory
711 	 */
712 	if (plock(PROCLOCK) < 0)
713 		msyslog(LOG_ERR, "plock(PROCLOCK): %m");
714 #  else /* not PROCLOCK */
715 #   ifdef TXTLOCK
716 	/*
717 	 * Lock text into ram
718 	 */
719 	if (plock(TXTLOCK) < 0)
720 		msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
721 #   else /* not TXTLOCK */
722 	msyslog(LOG_ERR, "plock() - don't know what to lock!");
723 #   endif /* not TXTLOCK */
724 #  endif /* not PROCLOCK */
725 # endif /* HAVE_PLOCK */
726 #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
727 
728 	/*
729 	 * Set up signals we pay attention to locally.
730 	 */
731 #ifdef SIGDIE1
732 	(void) signal_no_reset(SIGDIE1, finish);
733 #endif	/* SIGDIE1 */
734 #ifdef SIGDIE2
735 	(void) signal_no_reset(SIGDIE2, finish);
736 #endif	/* SIGDIE2 */
737 #ifdef SIGDIE3
738 	(void) signal_no_reset(SIGDIE3, finish);
739 #endif	/* SIGDIE3 */
740 #ifdef SIGDIE4
741 	(void) signal_no_reset(SIGDIE4, finish);
742 #endif	/* SIGDIE4 */
743 
744 #ifdef SIGBUS
745 	(void) signal_no_reset(SIGBUS, finish);
746 #endif /* SIGBUS */
747 
748 #if !defined(SYS_WINNT) && !defined(VMS)
749 # ifdef DEBUG
750 	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
751 	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
752 # else
753 	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
754 	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
755 # endif /* DEBUG */
756 #endif /* !SYS_WINNT && !VMS */
757 
758 	/*
759 	 * Set up signals we should never pay attention to.
760 	 */
761 #if defined SIGPIPE
762 	(void) signal_no_reset(SIGPIPE, SIG_IGN);
763 #endif	/* SIGPIPE */
764 
765 #if defined SYS_WINNT
766 	if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) {
767 		msyslog(LOG_ERR, "Can't set console control handler: %m");
768 	}
769 #endif
770 
771 	/*
772 	 * Call the init_ routines to initialize the data structures.
773 	 */
774 #if defined (HAVE_IO_COMPLETION_PORT)
775 	init_io_completion_port();
776 	init_winnt_time();
777 #endif
778 	init_auth();
779 	init_util();
780 	init_restrict();
781 	init_mon();
782 	init_timer();
783 	init_lib();
784 	init_random();
785 	init_request();
786 	init_control();
787 	init_peer();
788 #ifdef REFCLOCK
789 	init_refclock();
790 #endif
791 	set_process_priority();
792 	init_proto();		/* Call at high priority */
793 	init_io();
794 	init_loopfilter();
795 	mon_start(MON_ON);	/* monitor on by default now	  */
796 				/* turn off in config if unwanted */
797 
798 	/*
799 	 * Get configuration.  This (including argument list parsing) is
800 	 * done in a separate module since this will definitely be different
801 	 * for the gizmo board. While at it, save the host name for later
802 	 * along with the length. The crypto needs this.
803 	 */
804 #ifdef DEBUG
805 	debug = 0;
806 #endif
807 	getconfig(argc, argv);
808 #ifdef OPENSSL
809 	crypto_setup();
810 #endif /* OPENSSL */
811 	initializing = 0;
812 
813 #if defined(SYS_WINNT) && !defined(NODETACH)
814 # if defined(DEBUG)
815 	if(!debug)
816 	{
817 # endif
818 		if (NoWinService == FALSE) {
819 		/* report to the service control manager that the service is running */
820 			ssStatus.dwCurrentState = SERVICE_RUNNING;
821 			ssStatus.dwWin32ExitCode = NO_ERROR;
822 			if (!SetServiceStatus(sshStatusHandle, &ssStatus))
823 			{
824 				msyslog(LOG_ERR, "SetServiceStatus: %m");
825 				if (ResolverThreadHandle != NULL)
826 					CloseHandle(ResolverThreadHandle);
827 				ssStatus.dwCurrentState = SERVICE_STOPPED;
828 				SetServiceStatus(sshStatusHandle, &ssStatus);
829 				return;
830 			}
831 		}
832 # if defined(DEBUG)
833 	}
834 # endif
835 #endif
836 
837 #ifdef HAVE_CLOCKCTL
838 	/*
839 	 * Drop super-user privileges and chroot now if the OS supports
840 	 * non root clock control (only NetBSD for now).
841 	 */
842 	if (user != NULL) {
843 	        if (isdigit((unsigned char)*user)) {
844 	                sw_uid = (uid_t)strtoul(user, &endp, 0);
845 	                if (*endp != '\0')
846 	                        goto getuser;
847 	        } else {
848 getuser:
849 	                if ((pw = getpwnam(user)) != NULL) {
850 	                        sw_uid = pw->pw_uid;
851 	                } else {
852 	                        errno = 0;
853 	                        msyslog(LOG_ERR, "Cannot find user `%s'", user);
854 									exit (-1);
855 	                }
856 	        }
857 	}
858 	if (group != NULL) {
859 	        if (isdigit((unsigned char)*group)) {
860 	                sw_gid = (gid_t)strtoul(group, &endp, 0);
861 	                if (*endp != '\0')
862 	                        goto getgroup;
863 	        } else {
864 getgroup:
865 	                if ((gr = getgrnam(group)) != NULL) {
866 	                        sw_gid = pw->pw_gid;
867 	                } else {
868 	                        errno = 0;
869 	                        msyslog(LOG_ERR, "Cannot find group `%s'", group);
870 									exit (-1);
871 	                }
872 	        }
873 	}
874 	if (chrootdir && chroot(chrootdir)) {
875 		msyslog(LOG_ERR, "Cannot chroot to `%s': %m", chrootdir);
876 		exit (-1);
877 	}
878 	if (group && setgid(sw_gid)) {
879 		msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
880 		exit (-1);
881 	}
882 	if (group && setegid(sw_gid)) {
883 		msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
884 		exit (-1);
885 	}
886 	if (user && setuid(sw_uid)) {
887 		msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
888 		exit (-1);
889 	}
890 	if (user && seteuid(sw_uid)) {
891 		msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
892 		exit (-1);
893 	}
894 #endif
895 	/*
896 	 * Report that we're up to any trappers
897 	 */
898 	report_event(EVNT_SYSRESTART, (struct peer *)0);
899 
900 	/*
901 	 * Use select() on all on all input fd's for unlimited
902 	 * time.  select() will terminate on SIGALARM or on the
903 	 * reception of input.	Using select() means we can't do
904 	 * robust signal handling and we get a potential race
905 	 * between checking for alarms and doing the select().
906 	 * Mostly harmless, I think.
907 	 */
908 	/* On VMS, I suspect that select() can't be interrupted
909 	 * by a "signal" either, so I take the easy way out and
910 	 * have select() time out after one second.
911 	 * System clock updates really aren't time-critical,
912 	 * and - lacking a hardware reference clock - I have
913 	 * yet to learn about anything else that is.
914 	 */
915 #if defined(HAVE_IO_COMPLETION_PORT)
916 		WaitHandles[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* exit reques */
917 		WaitHandles[1] = get_timer_handle();
918 		WaitHandles[2] = get_io_event();
919 
920 		for (;;) {
921 			DWORD Index = WaitForMultipleObjectsEx(sizeof(WaitHandles)/sizeof(WaitHandles[0]), WaitHandles, FALSE, 1000, TRUE);
922 			switch (Index) {
923 				case WAIT_OBJECT_0 + 0 : /* exit request */
924 					exit(0);
925 				break;
926 
927 				case WAIT_OBJECT_0 + 1 : /* timer */
928 					timer();
929 				break;
930 
931 				case WAIT_OBJECT_0 + 2 : /* Io event */
932 # ifdef DEBUG
933 					if ( debug > 3 )
934 					{
935 						printf( "IoEvent occurred\n" );
936 					}
937 # endif
938 				break;
939 
940 				case WAIT_IO_COMPLETION : /* loop */
941 				case WAIT_TIMEOUT :
942 				break;
943 				case WAIT_FAILED:
944 					msyslog(LOG_ERR, "ntpdc: WaitForMultipleObjectsEx Failed: Error: %m");
945 					break;
946 
947 				/* For now do nothing if not expected */
948 				default:
949 					break;
950 
951 			} /* switch */
952 			rbuflist = getrecvbufs();	/* get received buffers */
953 
954 #else /* normal I/O */
955 
956 	was_alarmed = 0;
957 	rbuflist = (struct recvbuf *)0;
958 	for (;;)
959 	{
960 # if !defined(HAVE_SIGNALED_IO)
961 		extern fd_set activefds;
962 		extern int maxactivefd;
963 
964 		fd_set rdfdes;
965 		int nfound;
966 # elif defined(HAVE_SIGNALED_IO)
967 		block_io_and_alarm();
968 # endif
969 
970 		rbuflist = getrecvbufs();	/* get received buffers */
971 		if (alarm_flag) 	/* alarmed? */
972 		{
973 			was_alarmed = 1;
974 			alarm_flag = 0;
975 		}
976 
977 		if (!was_alarmed && rbuflist == (struct recvbuf *)0)
978 		{
979 			/*
980 			 * Nothing to do.  Wait for something.
981 			 */
982 # ifndef HAVE_SIGNALED_IO
983 			rdfdes = activefds;
984 #  if defined(VMS) || defined(SYS_VXWORKS)
985 			/* make select() wake up after one second */
986 			{
987 				struct timeval t1;
988 
989 				t1.tv_sec = 1; t1.tv_usec = 0;
990 				nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
991 						(fd_set *)0, &t1);
992 			}
993 #  else
994 			nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
995 					(fd_set *)0, (struct timeval *)0);
996 #  endif /* VMS */
997 			if (nfound > 0)
998 			{
999 				l_fp ts;
1000 
1001 				get_systime(&ts);
1002 
1003 				(void)input_handler(&ts);
1004 			}
1005 			else if (nfound == -1 && errno != EINTR)
1006 				msyslog(LOG_ERR, "select() error: %m");
1007 #  ifdef DEBUG
1008 			else if (debug > 2)
1009 				msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
1010 #  endif /* DEBUG */
1011 # else /* HAVE_SIGNALED_IO */
1012 
1013 			wait_for_signal();
1014 # endif /* HAVE_SIGNALED_IO */
1015 			if (alarm_flag) 	/* alarmed? */
1016 			{
1017 				was_alarmed = 1;
1018 				alarm_flag = 0;
1019 			}
1020 			rbuflist = getrecvbufs();  /* get received buffers */
1021 		}
1022 # ifdef HAVE_SIGNALED_IO
1023 		unblock_io_and_alarm();
1024 # endif /* HAVE_SIGNALED_IO */
1025 
1026 		/*
1027 		 * Out here, signals are unblocked.  Call timer routine
1028 		 * to process expiry.
1029 		 */
1030 		if (was_alarmed)
1031 		{
1032 			timer();
1033 			was_alarmed = 0;
1034 		}
1035 
1036 #endif /* HAVE_IO_COMPLETION_PORT */
1037 		/*
1038 		 * Call the data procedure to handle each received
1039 		 * packet.
1040 		 */
1041 		while (rbuflist != (struct recvbuf *)0)
1042 		{
1043 			rbuf = rbuflist;
1044 			rbuflist = rbuf->next;
1045 			(rbuf->receiver)(rbuf);
1046 			freerecvbuf(rbuf);
1047 		}
1048 #if defined DEBUG && defined SYS_WINNT
1049 		if (debug > 4)
1050 		    printf("getrecvbufs: %ld handler interrupts, %ld frames\n",
1051 			   handler_calls, handler_pkts);
1052 #endif
1053 
1054 		/*
1055 		 * Go around again
1056 		 */
1057 	}
1058 #ifndef SYS_WINNT
1059 	exit(1); /* unreachable */
1060 #endif
1061 #ifndef SYS_WINNT
1062 	return 1;		/* DEC OSF cc braindamage */
1063 #endif
1064 }
1065 
1066 
1067 #ifdef SIGDIE2
1068 /*
1069  * finish - exit gracefully
1070  */
1071 static RETSIGTYPE
1072 finish(
1073 	int sig
1074 	)
1075 {
1076 
1077 	msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
1078 
1079 	switch (sig)
1080 	{
1081 # ifdef SIGBUS
1082 		case SIGBUS:
1083 		printf("\nfinish(SIGBUS)\n");
1084 		exit(0);
1085 # endif
1086 		case 0: 		/* Should never happen... */
1087 		return;
1088 		default:
1089 		exit(0);
1090 	}
1091 }
1092 #endif	/* SIGDIE2 */
1093 
1094 
1095 #ifdef DEBUG
1096 #ifndef SYS_WINNT
1097 /*
1098  * moredebug - increase debugging verbosity
1099  */
1100 static RETSIGTYPE
1101 moredebug(
1102 	int sig
1103 	)
1104 {
1105 	int saved_errno = errno;
1106 
1107 	if (debug < 255)
1108 	{
1109 		debug++;
1110 		msyslog(LOG_DEBUG, "debug raised to %d", debug);
1111 	}
1112 	errno = saved_errno;
1113 }
1114 
1115 /*
1116  * lessdebug - decrease debugging verbosity
1117  */
1118 static RETSIGTYPE
1119 lessdebug(
1120 	int sig
1121 	)
1122 {
1123 	int saved_errno = errno;
1124 
1125 	if (debug > 0)
1126 	{
1127 		debug--;
1128 		msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1129 	}
1130 	errno = saved_errno;
1131 }
1132 #endif
1133 #else /* not DEBUG */
1134 #ifndef SYS_WINNT/*
1135  * no_debug - We don't do the debug here.
1136  */
1137 static RETSIGTYPE
1138 no_debug(
1139 	int sig
1140 	)
1141 {
1142 	int saved_errno = errno;
1143 
1144 	msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1145 	errno = saved_errno;
1146 }
1147 #endif  /* not SYS_WINNT */
1148 #endif	/* not DEBUG */
1149 
1150 #ifdef SYS_WINNT
1151 /* service_ctrl - control handler for NTP service
1152  * signals the service_main routine of start/stop requests
1153  * from the control panel or other applications making
1154  * win32API calls
1155  */
1156 void
1157 service_ctrl(
1158 	DWORD dwCtrlCode
1159 	)
1160 {
1161 	DWORD  dwState = SERVICE_RUNNING;
1162 
1163 	/* Handle the requested control code */
1164 	switch(dwCtrlCode)
1165 	{
1166 		case SERVICE_CONTROL_PAUSE:
1167 		/* see no reason to support this */
1168 		break;
1169 
1170 		case SERVICE_CONTROL_CONTINUE:
1171 		/* see no reason to support this */
1172 		break;
1173 
1174 		case SERVICE_CONTROL_STOP:
1175 			dwState = SERVICE_STOP_PENDING;
1176 			/*
1177 			 * Report the status, specifying the checkpoint and waithint,
1178 			 *	before setting the termination event.
1179 			 */
1180 			ssStatus.dwCurrentState = dwState;
1181 			ssStatus.dwWin32ExitCode = NO_ERROR;
1182 			ssStatus.dwWaitHint = 3000;
1183 			if (!SetServiceStatus(sshStatusHandle, &ssStatus))
1184 			{
1185 				msyslog(LOG_ERR, "SetServiceStatus: %m");
1186 			}
1187 			if (WaitHandles[0] != NULL) {
1188 				SetEvent(WaitHandles[0]);
1189 			}
1190 		return;
1191 
1192 		case SERVICE_CONTROL_INTERROGATE:
1193 		/* Update the service status */
1194 		break;
1195 
1196 		default:
1197 		/* invalid control code */
1198 		break;
1199 
1200 	}
1201 
1202 	ssStatus.dwCurrentState = dwState;
1203 	ssStatus.dwWin32ExitCode = NO_ERROR;
1204 	if (!SetServiceStatus(sshStatusHandle, &ssStatus))
1205 	{
1206 		msyslog(LOG_ERR, "SetServiceStatus: %m");
1207 	}
1208 }
1209 
1210 static BOOL WINAPI
1211 OnConsoleEvent(
1212 	DWORD dwCtrlType
1213 	)
1214 {
1215 	switch (dwCtrlType) {
1216 		case CTRL_BREAK_EVENT :
1217 			if (debug > 0) {
1218 				debug <<= 1;
1219 			}
1220 			else {
1221 				debug = 1;
1222 			}
1223 			if (debug > 8) {
1224 				debug = 0;
1225 			}
1226 			printf("debug level %d\n", debug);
1227 		break ;
1228 
1229 		case CTRL_C_EVENT  :
1230 		case CTRL_CLOSE_EVENT :
1231 		case CTRL_SHUTDOWN_EVENT :
1232 			if (WaitHandles[0] != NULL) {
1233 				SetEvent(WaitHandles[0]);
1234 			}
1235 		break;
1236 
1237 		default :
1238 			return FALSE;
1239 
1240 
1241 	}
1242 	return TRUE;;
1243 }
1244 
1245 
1246 /*
1247  *  NT version of exit() - all calls to exit() should be routed to
1248  *  this function.
1249  */
1250 void
1251 service_exit(
1252 	int status
1253 	)
1254 {
1255 	if (!debug) { /* did not become a service, simply exit */
1256 		/* service mode, need to have the service_main routine
1257 		 * register with the service control manager that the
1258 		 * service has stopped running, before exiting
1259 		 */
1260 		ssStatus.dwCurrentState = SERVICE_STOPPED;
1261 		SetServiceStatus(sshStatusHandle, &ssStatus);
1262 
1263 	}
1264 	uninit_io_completion_port();
1265 	reset_winnt_time();
1266 
1267 # if defined _MSC_VER
1268 	_CrtDumpMemoryLeaks();
1269 # endif
1270 #undef exit
1271 	exit(status);
1272 }
1273 
1274 #endif /* SYS_WINNT */
1275