File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ntpd / ntpd.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 2 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>