PageRenderTime 100ms CodeModel.GetById 60ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/ntp/ntpd/ntpd.c

https://bitbucket.org/freebsd/freebsd-head/
C | 1220 lines | 892 code | 133 blank | 195 comment | 162 complexity | 0d0f452ba6b65e085f41100c844a2f72 MD5 | raw file
   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#ifdef SIM
  16# include "ntpsim.h"
  17# include "ntpdsim-opts.h"
  18#else
  19# include "ntpd-opts.h"
  20#endif
  21
  22#ifdef HAVE_UNISTD_H
  23# include <unistd.h>
  24#endif
  25#ifdef HAVE_SYS_STAT_H
  26# include <sys/stat.h>
  27#endif
  28#include <stdio.h>
  29#if !defined(VMS)	/*wjm*/
  30# ifdef HAVE_SYS_PARAM_H
  31#  include <sys/param.h>
  32# endif
  33#endif /* VMS */
  34#ifdef HAVE_SYS_SIGNAL_H
  35# include <sys/signal.h>
  36#else
  37# include <signal.h>
  38#endif
  39#ifdef HAVE_SYS_IOCTL_H
  40# include <sys/ioctl.h>
  41#endif /* HAVE_SYS_IOCTL_H */
  42#ifdef HAVE_SYS_RESOURCE_H
  43# include <sys/resource.h>
  44#endif /* HAVE_SYS_RESOURCE_H */
  45#if defined(HAVE_RTPRIO)
  46# ifdef HAVE_SYS_RESOURCE_H
  47#  include <sys/resource.h>
  48# endif
  49# ifdef HAVE_SYS_LOCK_H
  50#  include <sys/lock.h>
  51# endif
  52# include <sys/rtprio.h>
  53#else
  54# ifdef HAVE_PLOCK
  55#  ifdef HAVE_SYS_LOCK_H
  56#	include <sys/lock.h>
  57#  endif
  58# endif
  59#endif
  60#if defined(HAVE_SCHED_SETSCHEDULER)
  61# ifdef HAVE_SCHED_H
  62#  include <sched.h>
  63# else
  64#  ifdef HAVE_SYS_SCHED_H
  65#   include <sys/sched.h>
  66#  endif
  67# endif
  68#endif
  69#if defined(HAVE_SYS_MMAN_H)
  70# include <sys/mman.h>
  71#endif
  72
  73#ifdef HAVE_TERMIOS_H
  74# include <termios.h>
  75#endif
  76
  77#ifdef SYS_DOMAINOS
  78# include <apollo/base.h>
  79#endif /* SYS_DOMAINOS */
  80
  81#include "recvbuff.h"  
  82#include "ntp_cmdargs.h"  
  83
  84#if 0				/* HMS: I don't think we need this. 961223 */
  85#ifdef LOCK_PROCESS
  86# ifdef SYS_SOLARIS
  87#  include <sys/mman.h>
  88# else
  89#  include <sys/lock.h>
  90# endif
  91#endif
  92#endif
  93
  94#ifdef _AIX
  95# include <ulimit.h>
  96#endif /* _AIX */
  97
  98#ifdef SCO5_CLOCK
  99# include <sys/ci/ciioctl.h>
 100#endif
 101
 102#ifdef HAVE_DROPROOT
 103# include <ctype.h>
 104# include <grp.h>
 105# include <pwd.h>
 106#ifdef HAVE_LINUX_CAPABILITIES
 107# include <sys/capability.h>
 108# include <sys/prctl.h>
 109#endif
 110#endif
 111
 112/*
 113 * Signals we catch for debugging.	If not debugging we ignore them.
 114 */
 115#define MOREDEBUGSIG	SIGUSR1
 116#define LESSDEBUGSIG	SIGUSR2
 117
 118/*
 119 * Signals which terminate us gracefully.
 120 */
 121#ifndef SYS_WINNT
 122# define SIGDIE1 	SIGHUP
 123# define SIGDIE3 	SIGQUIT
 124# define SIGDIE2 	SIGINT
 125# define SIGDIE4 	SIGTERM
 126#endif /* SYS_WINNT */
 127
 128#ifdef HAVE_DNSREGISTRATION
 129#include <dns_sd.h>
 130DNSServiceRef mdns;
 131#endif
 132
 133/*
 134 * Scheduling priority we run at
 135 */
 136#define NTPD_PRIO	(-12)
 137
 138int priority_done = 2;		/* 0 - Set priority */
 139				/* 1 - priority is OK where it is */
 140				/* 2 - Don't set priority */
 141				/* 1 and 2 are pretty much the same */
 142
 143#ifdef DEBUG
 144/*
 145 * Debugging flag
 146 */
 147volatile int debug = 0;		/* No debugging by default */
 148#endif
 149
 150int	listen_to_virtual_ips = 1;
 151const char *specific_interface = NULL;        /* interface name or IP address to bind to */
 152
 153/*
 154 * No-fork flag.  If set, we do not become a background daemon.
 155 */
 156int nofork = 0;			/* Fork by default */
 157
 158#ifdef HAVE_DROPROOT
 159int droproot = 0;
 160char *user = NULL;		/* User to switch to */
 161char *group = NULL;		/* group to switch to */
 162char *chrootdir = NULL;		/* directory to chroot to */
 163int sw_uid;
 164int sw_gid;
 165char *endp;  
 166struct group *gr;
 167struct passwd *pw; 
 168#endif /* HAVE_DROPROOT */
 169
 170/*
 171 * Initializing flag.  All async routines watch this and only do their
 172 * thing when it is clear.
 173 */
 174int initializing;
 175
 176/*
 177 * Version declaration
 178 */
 179extern const char *Version;
 180
 181char const *progname;
 182
 183int was_alarmed;
 184
 185#ifdef DECL_SYSCALL
 186/*
 187 * We put this here, since the argument profile is syscall-specific
 188 */
 189extern int syscall	P((int, ...));
 190#endif /* DECL_SYSCALL */
 191
 192
 193#ifdef	SIGDIE2
 194static	RETSIGTYPE	finish		P((int));
 195#endif	/* SIGDIE2 */
 196
 197#ifdef	DEBUG
 198#ifndef SYS_WINNT
 199static	RETSIGTYPE	moredebug	P((int));
 200static	RETSIGTYPE	lessdebug	P((int));
 201#endif
 202#else /* not DEBUG */
 203static	RETSIGTYPE	no_debug	P((int));
 204#endif	/* not DEBUG */
 205
 206int 		ntpdmain		P((int, char **));
 207static void	set_process_priority	P((void));
 208static void	init_logging		P((char const *));
 209static void	setup_logfile		P((void));
 210
 211/*
 212 * Initialize the logging
 213 */
 214void
 215init_logging(char const *name)
 216{
 217	const char *cp;
 218
 219	/*
 220	 * Logging.  This may actually work on the gizmo board.  Find a name
 221	 * to log with by using the basename
 222	 */
 223	cp = strrchr(name, '/');
 224	if (cp == 0)
 225		cp = name;
 226	else
 227		cp++;
 228
 229#if !defined(VMS)
 230
 231# ifndef LOG_DAEMON
 232	openlog(cp, LOG_PID);
 233# else /* LOG_DAEMON */
 234
 235#  ifndef LOG_NTP
 236#	define	LOG_NTP LOG_DAEMON
 237#  endif
 238	openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);
 239#  ifdef DEBUG
 240	if (debug)
 241		setlogmask(LOG_UPTO(LOG_DEBUG));
 242	else
 243#  endif /* DEBUG */
 244		setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
 245# endif /* LOG_DAEMON */
 246#endif	/* !SYS_WINNT && !VMS */
 247
 248	NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
 249		msyslog(LOG_NOTICE, "%s", Version);
 250}
 251
 252
 253/*
 254 * See if we should redirect the logfile
 255 */
 256
 257void
 258setup_logfile(
 259	void
 260	)
 261{
 262	if (HAVE_OPT( LOGFILE )) {
 263		const char *my_optarg = OPT_ARG( LOGFILE );
 264		FILE *new_file;
 265
 266		if(strcmp(my_optarg, "stderr") == 0)
 267			new_file = stderr;
 268		else if(strcmp(my_optarg, "stdout") == 0)
 269			new_file = stdout;
 270		else
 271			new_file = fopen(my_optarg, "a");
 272		if (new_file != NULL) {
 273			NLOG(NLOG_SYSINFO)
 274				msyslog(LOG_NOTICE, "logging to file %s", my_optarg);
 275			if (syslog_file != NULL &&
 276				fileno(syslog_file) != fileno(new_file))
 277				(void)fclose(syslog_file);
 278
 279			syslog_file = new_file;
 280			syslogit = 0;
 281		}
 282		else
 283			msyslog(LOG_ERR,
 284				"Cannot open log file %s",
 285				my_optarg);
 286	}
 287}
 288
 289#ifdef SIM
 290int
 291main(
 292	int argc,
 293	char *argv[]
 294	)
 295{
 296	return ntpsim(argc, argv);
 297}
 298#else /* SIM */
 299#ifdef NO_MAIN_ALLOWED
 300CALL(ntpd,"ntpd",ntpdmain);
 301#else
 302#ifndef SYS_WINNT
 303int
 304main(
 305	int argc,
 306	char *argv[]
 307	)
 308{
 309	return ntpdmain(argc, argv);
 310}
 311#endif /* SYS_WINNT */
 312#endif /* NO_MAIN_ALLOWED */
 313#endif /* SIM */
 314
 315#ifdef _AIX
 316/*
 317 * OK. AIX is different than solaris in how it implements plock().
 318 * If you do NOT adjust the stack limit, you will get the MAXIMUM
 319 * stack size allocated and PINNED with you program. To check the 
 320 * value, use ulimit -a. 
 321 *
 322 * To fix this, we create an automatic variable and set our stack limit 
 323 * to that PLUS 32KB of extra space (we need some headroom).
 324 *
 325 * This subroutine gets the stack address.
 326 *
 327 * Grover Davidson and Matt Ladendorf
 328 *
 329 */
 330static char *
 331get_aix_stack(void)
 332{
 333	char ch;
 334	return (&ch);
 335}
 336
 337/*
 338 * Signal handler for SIGDANGER.
 339 */
 340static void
 341catch_danger(int signo)
 342{
 343	msyslog(LOG_INFO, "ntpd: setpgid(): %m");
 344	/* Make the system believe we'll free something, but don't do it! */
 345	return;
 346}
 347#endif /* _AIX */
 348
 349/*
 350 * Set the process priority
 351 */
 352static void
 353set_process_priority(void)
 354{
 355
 356#ifdef DEBUG
 357	if (debug > 1)
 358		msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
 359			((priority_done)
 360			 ? "Leave priority alone"
 361			 : "Attempt to set priority"
 362				),
 363			priority_done);
 364#endif /* DEBUG */
 365
 366#ifdef SYS_WINNT
 367	priority_done += NT_set_process_priority();
 368#endif
 369
 370#if defined(HAVE_SCHED_SETSCHEDULER)
 371	if (!priority_done) {
 372		extern int config_priority_override, config_priority;
 373		int pmax, pmin;
 374		struct sched_param sched;
 375
 376		pmax = sched_get_priority_max(SCHED_FIFO);
 377		sched.sched_priority = pmax;
 378		if ( config_priority_override ) {
 379			pmin = sched_get_priority_min(SCHED_FIFO);
 380			if ( config_priority > pmax )
 381				sched.sched_priority = pmax;
 382			else if ( config_priority < pmin )
 383				sched.sched_priority = pmin;
 384			else
 385				sched.sched_priority = config_priority;
 386		}
 387		if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
 388			msyslog(LOG_ERR, "sched_setscheduler(): %m");
 389		else
 390			++priority_done;
 391	}
 392#endif /* HAVE_SCHED_SETSCHEDULER */
 393#if defined(HAVE_RTPRIO)
 394# ifdef RTP_SET
 395	if (!priority_done) {
 396		struct rtprio srtp;
 397
 398		srtp.type = RTP_PRIO_REALTIME;	/* was: RTP_PRIO_NORMAL */
 399		srtp.prio = 0;		/* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
 400
 401		if (rtprio(RTP_SET, getpid(), &srtp) < 0)
 402			msyslog(LOG_ERR, "rtprio() error: %m");
 403		else
 404			++priority_done;
 405	}
 406# else /* not RTP_SET */
 407	if (!priority_done) {
 408		if (rtprio(0, 120) < 0)
 409			msyslog(LOG_ERR, "rtprio() error: %m");
 410		else
 411			++priority_done;
 412	}
 413# endif /* not RTP_SET */
 414#endif  /* HAVE_RTPRIO */
 415#if defined(NTPD_PRIO) && NTPD_PRIO != 0
 416# ifdef HAVE_ATT_NICE
 417	if (!priority_done) {
 418		errno = 0;
 419		if (-1 == nice (NTPD_PRIO) && errno != 0)
 420			msyslog(LOG_ERR, "nice() error: %m");
 421		else
 422			++priority_done;
 423	}
 424# endif /* HAVE_ATT_NICE */
 425# ifdef HAVE_BSD_NICE
 426	if (!priority_done) {
 427		if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
 428			msyslog(LOG_ERR, "setpriority() error: %m");
 429		else
 430			++priority_done;
 431	}
 432# endif /* HAVE_BSD_NICE */
 433#endif /* NTPD_PRIO && NTPD_PRIO != 0 */
 434	if (!priority_done)
 435		msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
 436}
 437
 438
 439/*
 440 * Main program.  Initialize us, disconnect us from the tty if necessary,
 441 * and loop waiting for I/O and/or timer expiries.
 442 */
 443int
 444ntpdmain(
 445	int argc,
 446	char *argv[]
 447	)
 448{
 449	l_fp now;
 450	struct recvbuf *rbuf;
 451#ifdef _AIX			/* HMS: ifdef SIGDANGER? */
 452	struct sigaction sa;
 453#endif
 454
 455	progname = argv[0];
 456
 457	initializing = 1;		/* mark that we are initializing */
 458
 459	{
 460		int optct = optionProcess(
 461#ifdef SIM
 462					  &ntpdsimOptions
 463#else
 464					  &ntpdOptions
 465#endif
 466					  , argc, argv);
 467		argc -= optct;
 468		argv += optct;
 469	}
 470
 471	/* HMS: is this lame? Should we process -l first? */
 472
 473	init_logging(progname);		/* Open the log file */
 474
 475#ifdef HAVE_UMASK
 476	{
 477		mode_t uv;
 478
 479		uv = umask(0);
 480		if(uv)
 481			(void) umask(uv);
 482		else
 483			(void) umask(022);
 484	}
 485#endif
 486
 487#if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
 488	{
 489		uid_t uid;
 490
 491		uid = getuid();
 492		if (uid)
 493		{
 494			msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
 495			printf("must be run as root, not uid %ld", (long)uid);
 496			exit(1);
 497		}
 498	}
 499#endif
 500
 501#ifdef OPENSSL
 502	if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) {
 503		msyslog(LOG_ERR,
 504		    "ntpd: OpenSSL version mismatch. Built against %lx, you have %lx\n",
 505		    OPENSSL_VERSION_NUMBER, SSLeay());
 506		exit(1);
 507	}
 508#endif
 509
 510	/* getstartup(argc, argv); / * startup configuration, may set debug */
 511
 512#ifdef DEBUG
 513	debug = DESC(DEBUG_LEVEL).optOccCt;
 514	if (debug)
 515	    printf("%s\n", Version);
 516#endif
 517
 518/*
 519 * Enable the Multi-Media Timer for Windows?
 520 */
 521#ifdef SYS_WINNT
 522	if (HAVE_OPT( MODIFYMMTIMER ))
 523		set_mm_timer(MM_TIMER_HIRES);
 524#endif
 525
 526	if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT ))
 527		nofork = 1;
 528
 529	if (HAVE_OPT( NOVIRTUALIPS ))
 530		listen_to_virtual_ips = 0;
 531
 532	if (HAVE_OPT( INTERFACE )) {
 533#if 0
 534		int	ifacect = STACKCT_OPT( INTERFACE );
 535		char**	ifaces  = STACKLST_OPT( INTERFACE );
 536
 537		/* malloc space for the array of names */
 538		while (ifacect-- > 0) {
 539			next_iface = *ifaces++;
 540		}
 541#else
 542		specific_interface = OPT_ARG( INTERFACE );
 543#endif
 544	}
 545
 546	if (HAVE_OPT( NICE ))
 547		priority_done = 0;
 548
 549#if defined(HAVE_SCHED_SETSCHEDULER)
 550	if (HAVE_OPT( PRIORITY )) {
 551		config_priority = OPT_VALUE_PRIORITY;
 552		config_priority_override = 1;
 553		priority_done = 0;
 554	}
 555#endif
 556
 557#ifdef SYS_WINNT
 558	/*
 559	 * Initialize the time structures and variables
 560	 */
 561	init_winnt_time();
 562#endif
 563
 564	setup_logfile();
 565
 566	/*
 567	 * Initialize random generator and public key pair
 568	 */
 569	get_systime(&now);
 570
 571	ntp_srandom((int)(now.l_i * now.l_uf));
 572
 573#ifdef HAVE_DNSREGISTRATION
 574	/* HMS: does this have to happen this early? */
 575	msyslog(LOG_INFO, "Attemping to register mDNS");
 576	if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
 577		msyslog(LOG_ERR, "Unable to register mDNS");
 578	}
 579#endif
 580
 581#if !defined(VMS)
 582# ifndef NODETACH
 583	/*
 584	 * Detach us from the terminal.  May need an #ifndef GIZMO.
 585	 */
 586	if (
 587#  ifdef DEBUG
 588	    !debug &&
 589#  endif /* DEBUG */
 590	    !nofork)
 591	{
 592#  ifndef SYS_WINNT
 593#   ifdef HAVE_DAEMON
 594		daemon(0, 0);
 595#   else /* not HAVE_DAEMON */
 596		if (fork())	/* HMS: What about a -1? */
 597			exit(0);
 598
 599		{
 600#if !defined(F_CLOSEM)
 601			u_long s;
 602			int max_fd;
 603#endif /* not F_CLOSEM */
 604
 605#if defined(F_CLOSEM)
 606			/*
 607			 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
 608			 * by Eric Agar (saves us from doing 32767 system
 609			 * calls)
 610			 */
 611			if (fcntl(0, F_CLOSEM, 0) == -1)
 612			    msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
 613#else  /* not F_CLOSEM */
 614
 615# if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
 616			max_fd = sysconf(_SC_OPEN_MAX);
 617# else /* HAVE_SYSCONF && _SC_OPEN_MAX */
 618			max_fd = getdtablesize();
 619# endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
 620			for (s = 0; s < max_fd; s++)
 621				(void) close((int)s);
 622#endif /* not F_CLOSEM */
 623			(void) open("/", 0);
 624			(void) dup2(0, 1);
 625			(void) dup2(0, 2);
 626#ifdef SYS_DOMAINOS
 627			{
 628				uid_$t puid;
 629				status_$t st;
 630
 631				proc2_$who_am_i(&puid);
 632				proc2_$make_server(&puid, &st);
 633			}
 634#endif /* SYS_DOMAINOS */
 635#if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
 636# ifdef HAVE_SETSID
 637			if (setsid() == (pid_t)-1)
 638				msyslog(LOG_ERR, "ntpd: setsid(): %m");
 639# else
 640			if (setpgid(0, 0) == -1)
 641				msyslog(LOG_ERR, "ntpd: setpgid(): %m");
 642# endif
 643#else /* HAVE_SETPGID || HAVE_SETSID */
 644			{
 645# if defined(TIOCNOTTY)
 646				int fid;
 647
 648				fid = open("/dev/tty", 2);
 649				if (fid >= 0)
 650				{
 651					(void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
 652					(void) close(fid);
 653				}
 654# endif /* defined(TIOCNOTTY) */
 655# ifdef HAVE_SETPGRP_0
 656				(void) setpgrp();
 657# else /* HAVE_SETPGRP_0 */
 658				(void) setpgrp(0, getpid());
 659# endif /* HAVE_SETPGRP_0 */
 660			}
 661#endif /* HAVE_SETPGID || HAVE_SETSID */
 662#ifdef _AIX
 663			/* Don't get killed by low-on-memory signal. */
 664			sa.sa_handler = catch_danger;
 665			sigemptyset(&sa.sa_mask);
 666			sa.sa_flags = SA_RESTART;
 667
 668			(void) sigaction(SIGDANGER, &sa, NULL);
 669#endif /* _AIX */
 670		}
 671#   endif /* not HAVE_DAEMON */
 672#  endif /* SYS_WINNT */
 673	}
 674# endif /* NODETACH */
 675#endif /* VMS */
 676
 677	setup_logfile();	/* We lost any redirect when we daemonized */
 678
 679#ifdef SCO5_CLOCK
 680	/*
 681	 * SCO OpenServer's system clock offers much more precise timekeeping
 682	 * on the base CPU than the other CPUs (for multiprocessor systems),
 683	 * so we must lock to the base CPU.
 684	 */
 685	{
 686	    int fd = open("/dev/at1", O_RDONLY);
 687	    if (fd >= 0) {
 688		int zero = 0;
 689		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
 690		    msyslog(LOG_ERR, "cannot lock to base CPU: %m");
 691		close( fd );
 692	    } /* else ...
 693	       *   If we can't open the device, this probably just isn't
 694	       *   a multiprocessor system, so we're A-OK.
 695	       */
 696	}
 697#endif
 698
 699#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
 700# ifdef HAVE_SETRLIMIT
 701	/*
 702	 * Set the stack limit to something smaller, so that we don't lock a lot
 703	 * of unused stack memory.
 704	 */
 705	{
 706	    struct rlimit rl;
 707
 708	    /* HMS: must make the rlim_cur amount configurable */
 709	    if (getrlimit(RLIMIT_STACK, &rl) != -1
 710		&& (rl.rlim_cur = 50 * 4096) < rl.rlim_max)
 711	    {
 712		    if (setrlimit(RLIMIT_STACK, &rl) == -1)
 713		    {
 714			    msyslog(LOG_ERR,
 715				"Cannot adjust stack limit for mlockall: %m");
 716		    }
 717	    }
 718#  ifdef RLIMIT_MEMLOCK
 719	    /*
 720	     * The default RLIMIT_MEMLOCK is very low on Linux systems.
 721	     * Unless we increase this limit malloc calls are likely to
 722	     * fail if we drop root privlege.  To be useful the value
 723	     * has to be larger than the largest ntpd resident set size.
 724	     */
 725	    rl.rlim_cur = rl.rlim_max = 32*1024*1024;
 726	    if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) {
 727	    	msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
 728	    }
 729#  endif /* RLIMIT_MEMLOCK */
 730	}
 731# endif /* HAVE_SETRLIMIT */
 732	/*
 733	 * lock the process into memory
 734	 */
 735	if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
 736		msyslog(LOG_ERR, "mlockall(): %m");
 737#else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
 738# ifdef HAVE_PLOCK
 739#  ifdef PROCLOCK
 740#   ifdef _AIX
 741	/* 
 742	 * set the stack limit for AIX for plock().
 743	 * see get_aix_stack() for more info.
 744	 */
 745	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
 746	{
 747		msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
 748	}
 749#   endif /* _AIX */
 750	/*
 751	 * lock the process into memory
 752	 */
 753	if (plock(PROCLOCK) < 0)
 754		msyslog(LOG_ERR, "plock(PROCLOCK): %m");
 755#  else /* not PROCLOCK */
 756#   ifdef TXTLOCK
 757	/*
 758	 * Lock text into ram
 759	 */
 760	if (plock(TXTLOCK) < 0)
 761		msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
 762#   else /* not TXTLOCK */
 763	msyslog(LOG_ERR, "plock() - don't know what to lock!");
 764#   endif /* not TXTLOCK */
 765#  endif /* not PROCLOCK */
 766# endif /* HAVE_PLOCK */
 767#endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
 768
 769	/*
 770	 * Set up signals we pay attention to locally.
 771	 */
 772#ifdef SIGDIE1
 773	(void) signal_no_reset(SIGDIE1, finish);
 774#endif	/* SIGDIE1 */
 775#ifdef SIGDIE2
 776	(void) signal_no_reset(SIGDIE2, finish);
 777#endif	/* SIGDIE2 */
 778#ifdef SIGDIE3
 779	(void) signal_no_reset(SIGDIE3, finish);
 780#endif	/* SIGDIE3 */
 781#ifdef SIGDIE4
 782	(void) signal_no_reset(SIGDIE4, finish);
 783#endif	/* SIGDIE4 */
 784
 785#ifdef SIGBUS
 786	(void) signal_no_reset(SIGBUS, finish);
 787#endif /* SIGBUS */
 788
 789#if !defined(SYS_WINNT) && !defined(VMS)
 790# ifdef DEBUG
 791	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
 792	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
 793# else
 794	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
 795	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
 796# endif /* DEBUG */
 797#endif /* !SYS_WINNT && !VMS */
 798
 799	/*
 800	 * Set up signals we should never pay attention to.
 801	 */
 802#if defined SIGPIPE
 803	(void) signal_no_reset(SIGPIPE, SIG_IGN);
 804#endif	/* SIGPIPE */
 805
 806	/*
 807	 * Call the init_ routines to initialize the data structures.
 808	 *
 809	 * Exactly what command-line options are we expecting here?
 810	 */
 811	init_auth();
 812	init_util();
 813	init_restrict();
 814	init_mon();
 815	init_timer();
 816	init_lib();
 817	init_request();
 818	init_control();
 819	init_peer();
 820#ifdef REFCLOCK
 821	init_refclock();
 822#endif
 823	set_process_priority();
 824	init_proto();		/* Call at high priority */
 825	init_io();
 826	init_loopfilter();
 827	mon_start(MON_ON);	/* monitor on by default now	  */
 828				/* turn off in config if unwanted */
 829
 830	/*
 831	 * Get the configuration.  This is done in a separate module
 832	 * since this will definitely be different for the gizmo board.
 833	 */
 834
 835	getconfig(argc, argv);
 836
 837	loop_config(LOOP_DRIFTCOMP, old_drift / 1e6);
 838#ifdef OPENSSL
 839	crypto_setup();
 840#endif /* OPENSSL */
 841	initializing = 0;
 842
 843#ifdef HAVE_DROPROOT
 844	if( droproot ) {
 845		/* Drop super-user privileges and chroot now if the OS supports this */
 846
 847#ifdef HAVE_LINUX_CAPABILITIES
 848		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
 849		if( prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1 ) {
 850			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
 851			exit(-1);
 852		}
 853#else
 854		/* we need a user to switch to */
 855		if( user == NULL ) {
 856			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
 857			exit(-1);
 858		}
 859#endif /* HAVE_LINUX_CAPABILITIES */
 860	
 861		if (user != NULL) {
 862			if (isdigit((unsigned char)*user)) {
 863				sw_uid = (uid_t)strtoul(user, &endp, 0);
 864				if (*endp != '\0') 
 865					goto getuser;
 866			} else {
 867getuser:	
 868				if ((pw = getpwnam(user)) != NULL) {
 869					sw_uid = pw->pw_uid;
 870				} else {
 871					errno = 0;
 872					msyslog(LOG_ERR, "Cannot find user `%s'", user);
 873					exit (-1);
 874				}
 875			}
 876		}
 877		if (group != NULL) {
 878			if (isdigit((unsigned char)*group)) {
 879				sw_gid = (gid_t)strtoul(group, &endp, 0);
 880				if (*endp != '\0') 
 881					goto getgroup;
 882			} else {
 883getgroup:	
 884				if ((gr = getgrnam(group)) != NULL) {
 885					sw_gid = gr->gr_gid;
 886				} else {
 887					errno = 0;
 888					msyslog(LOG_ERR, "Cannot find group `%s'", group);
 889					exit (-1);
 890				}
 891			}
 892		}
 893		
 894		if( chrootdir ) {
 895			/* make sure cwd is inside the jail: */
 896			if( chdir(chrootdir) ) {
 897				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
 898				exit (-1);
 899			}
 900			if( chroot(chrootdir) ) {
 901				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
 902				exit (-1);
 903			}
 904		}
 905		if (group && setgid(sw_gid)) {
 906			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
 907			exit (-1);
 908		}
 909		if (group && setegid(sw_gid)) {
 910			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
 911			exit (-1);
 912		}
 913		if (user && setuid(sw_uid)) {
 914			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
 915			exit (-1);
 916		}
 917		if (user && seteuid(sw_uid)) {
 918			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
 919			exit (-1);
 920		}
 921	
 922#ifndef HAVE_LINUX_CAPABILITIES
 923		/*
 924		 * for now assume that the privilege to bind to privileged ports
 925		 * is associated with running with uid 0 - should be refined on
 926		 * ports that allow binding to NTP_PORT with uid != 0
 927		 */
 928		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
 929#endif
 930
 931		if (disable_dynamic_updates && interface_interval) {
 932			interface_interval = 0;
 933			msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking");
 934		}
 935
 936#ifdef HAVE_LINUX_CAPABILITIES
 937		do {
 938			/*
 939			 *  We may be running under non-root uid now, but we still hold full root privileges!
 940			 *  We drop all of them, except for the crucial one or two: cap_sys_time and
 941			 *  cap_net_bind_service if doing dynamic interface tracking.
 942			 */
 943			cap_t caps;
 944			char *captext = interface_interval ?
 945			       	"cap_sys_time,cap_net_bind_service=ipe" :
 946			       	"cap_sys_time=ipe";
 947			if( ! ( caps = cap_from_text( captext ) ) ) {
 948				msyslog( LOG_ERR, "cap_from_text() failed: %m" );
 949				exit(-1);
 950			}
 951			if( cap_set_proc( caps ) == -1 ) {
 952				msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" );
 953				exit(-1);
 954			}
 955			cap_free( caps );
 956		} while(0);
 957#endif /* HAVE_LINUX_CAPABILITIES */
 958
 959	}    /* if( droproot ) */
 960#endif /* HAVE_DROPROOT */
 961	
 962	/*
 963	 * Report that we're up to any trappers
 964	 */
 965	report_event(EVNT_SYSRESTART, (struct peer *)0);
 966
 967	/*
 968	 * Use select() on all on all input fd's for unlimited
 969	 * time.  select() will terminate on SIGALARM or on the
 970	 * reception of input.	Using select() means we can't do
 971	 * robust signal handling and we get a potential race
 972	 * between checking for alarms and doing the select().
 973	 * Mostly harmless, I think.
 974	 */
 975	/* On VMS, I suspect that select() can't be interrupted
 976	 * by a "signal" either, so I take the easy way out and
 977	 * have select() time out after one second.
 978	 * System clock updates really aren't time-critical,
 979	 * and - lacking a hardware reference clock - I have
 980	 * yet to learn about anything else that is.
 981	 */
 982#if defined(HAVE_IO_COMPLETION_PORT)
 983
 984	for (;;) {
 985		GetReceivedBuffers();
 986#else /* normal I/O */
 987
 988	BLOCK_IO_AND_ALARM();
 989	was_alarmed = 0;
 990	for (;;)
 991	{
 992# if !defined(HAVE_SIGNALED_IO) 
 993		extern fd_set activefds;
 994		extern int maxactivefd;
 995
 996		fd_set rdfdes;
 997		int nfound;
 998# endif
 999
1000		if (alarm_flag) 	/* alarmed? */
1001		{
1002			was_alarmed = 1;
1003			alarm_flag = 0;
1004		}
1005
1006		if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE)
1007		{
1008			/*
1009			 * Nothing to do.  Wait for something.
1010			 */
1011# ifndef HAVE_SIGNALED_IO
1012			rdfdes = activefds;
1013#  if defined(VMS) || defined(SYS_VXWORKS)
1014			/* make select() wake up after one second */
1015			{
1016				struct timeval t1;
1017
1018				t1.tv_sec = 1; t1.tv_usec = 0;
1019				nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1020						(fd_set *)0, &t1);
1021			}
1022#  else
1023			nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1024					(fd_set *)0, (struct timeval *)0);
1025#  endif /* VMS */
1026			if (nfound > 0)
1027			{
1028				l_fp ts;
1029
1030				get_systime(&ts);
1031
1032				(void)input_handler(&ts);
1033			}
1034			else if (nfound == -1 && errno != EINTR)
1035				netsyslog(LOG_ERR, "select() error: %m");
1036#  ifdef DEBUG
1037			else if (debug > 5)
1038				netsyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
1039#  endif /* DEBUG */
1040# else /* HAVE_SIGNALED_IO */
1041                        
1042			wait_for_signal();
1043# endif /* HAVE_SIGNALED_IO */
1044			if (alarm_flag) 	/* alarmed? */
1045			{
1046				was_alarmed = 1;
1047				alarm_flag = 0;
1048			}
1049		}
1050
1051		if (was_alarmed)
1052		{
1053			UNBLOCK_IO_AND_ALARM();
1054			/*
1055			 * Out here, signals are unblocked.  Call timer routine
1056			 * to process expiry.
1057			 */
1058			timer();
1059			was_alarmed = 0;
1060                        BLOCK_IO_AND_ALARM();
1061		}
1062
1063#endif /* HAVE_IO_COMPLETION_PORT */
1064
1065#ifdef DEBUG_TIMING
1066		{
1067			l_fp pts;
1068			l_fp tsa, tsb;
1069			int bufcount = 0;
1070			
1071			get_systime(&pts);
1072			tsa = pts;
1073#endif
1074			rbuf = get_full_recv_buffer();
1075			while (rbuf != NULL)
1076			{
1077				if (alarm_flag)
1078				{
1079					was_alarmed = 1;
1080					alarm_flag = 0;
1081				}
1082				UNBLOCK_IO_AND_ALARM();
1083
1084				if (was_alarmed)
1085				{	/* avoid timer starvation during lengthy I/O handling */
1086					timer();
1087					was_alarmed = 0;
1088				}
1089
1090				/*
1091				 * Call the data procedure to handle each received
1092				 * packet.
1093				 */
1094				if (rbuf->receiver != NULL)	/* This should always be true */
1095				{
1096#ifdef DEBUG_TIMING
1097					l_fp dts = pts;
1098
1099					L_SUB(&dts, &rbuf->recv_time);
1100					DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
1101					collect_timing(rbuf, "buffer processing delay", 1, &dts);
1102					bufcount++;
1103#endif
1104					(rbuf->receiver)(rbuf);
1105				} else {
1106					msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING");
1107					abort();
1108				}
1109
1110				BLOCK_IO_AND_ALARM();
1111				freerecvbuf(rbuf);
1112				rbuf = get_full_recv_buffer();
1113			}
1114#ifdef DEBUG_TIMING
1115			get_systime(&tsb);
1116			L_SUB(&tsb, &tsa);
1117			if (bufcount) {
1118				collect_timing(NULL, "processing", bufcount, &tsb);
1119				DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
1120			}
1121		}
1122#endif
1123
1124		/*
1125		 * Go around again
1126		 */
1127	}
1128	UNBLOCK_IO_AND_ALARM();
1129	return 1;
1130}
1131
1132
1133#ifdef SIGDIE2
1134/*
1135 * finish - exit gracefully
1136 */
1137static RETSIGTYPE
1138finish(
1139	int sig
1140	)
1141{
1142
1143	msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
1144	write_stats();
1145#ifdef HAVE_DNSREGISTRATION
1146	if (mdns != NULL)
1147	DNSServiceRefDeallocate(mdns);
1148#endif
1149
1150	switch (sig)
1151	{
1152# ifdef SIGBUS
1153		case SIGBUS:
1154		printf("\nfinish(SIGBUS)\n");
1155		exit(0);
1156# endif
1157		case 0: 		/* Should never happen... */
1158		return;
1159		default:
1160		exit(0);
1161	}
1162}
1163#endif	/* SIGDIE2 */
1164
1165
1166#ifdef DEBUG
1167#ifndef SYS_WINNT
1168/*
1169 * moredebug - increase debugging verbosity
1170 */
1171static RETSIGTYPE
1172moredebug(
1173	int sig
1174	)
1175{
1176	int saved_errno = errno;
1177
1178	if (debug < 255)
1179	{
1180		debug++;
1181		msyslog(LOG_DEBUG, "debug raised to %d", debug);
1182	}
1183	errno = saved_errno;
1184}
1185
1186/*
1187 * lessdebug - decrease debugging verbosity
1188 */
1189static RETSIGTYPE
1190lessdebug(
1191	int sig
1192	)
1193{
1194	int saved_errno = errno;
1195
1196	if (debug > 0)
1197	{
1198		debug--;
1199		msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1200	}
1201	errno = saved_errno;
1202}
1203#endif
1204#else /* not DEBUG */
1205#ifndef SYS_WINNT
1206/*
1207 * no_debug - We don't do the debug here.
1208 */
1209static RETSIGTYPE
1210no_debug(
1211	int sig
1212	)
1213{
1214	int saved_errno = errno;
1215
1216	msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1217	errno = saved_errno;
1218}
1219#endif  /* not SYS_WINNT */
1220#endif	/* not DEBUG */