📄 ntpd.c
字号:
/* * ntpd.c - main program for the fixed point NTP daemon */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include "ntp_machine.h"#include "ntpd.h"#include "ntp_io.h"#include "ntp_stdlib.h"#include <ntp_random.h>#ifdef SIM#include "ntpsim.h"#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#include <stdio.h>#ifndef SYS_WINNT# if !defined(VMS) /*wjm*/# ifdef HAVE_SYS_PARAM_H# include <sys/param.h># endif# endif /* VMS */# ifdef HAVE_SYS_SIGNAL_H# include <sys/signal.h># else# include <signal.h># endif# ifdef HAVE_SYS_IOCTL_H# include <sys/ioctl.h># endif /* HAVE_SYS_IOCTL_H */# ifdef HAVE_SYS_RESOURCE_H# include <sys/resource.h># endif /* HAVE_SYS_RESOURCE_H */#else# include <signal.h># include <process.h># include <io.h># include <clockstuff.h>#include "ntp_iocompletionport.h"#endif /* SYS_WINNT */#if defined(HAVE_RTPRIO)# ifdef HAVE_SYS_RESOURCE_H# include <sys/resource.h># endif# ifdef HAVE_SYS_LOCK_H# include <sys/lock.h># endif# include <sys/rtprio.h>#else# ifdef HAVE_PLOCK# ifdef HAVE_SYS_LOCK_H# include <sys/lock.h># endif# endif#endif#if defined(HAVE_SCHED_SETSCHEDULER)# ifdef HAVE_SCHED_H# include <sched.h># else# ifdef HAVE_SYS_SCHED_H# include <sys/sched.h># endif# endif#endif#if defined(HAVE_SYS_MMAN_H)# include <sys/mman.h>#endif#ifdef HAVE_TERMIOS_H# include <termios.h>#endif#ifdef SYS_DOMAINOS# include <apollo/base.h>#endif /* SYS_DOMAINOS */#include "recvbuff.h" #include "ntp_cmdargs.h" #if 0 /* HMS: I don't think we need this. 961223 */#ifdef LOCK_PROCESS# ifdef SYS_SOLARIS# include <sys/mman.h># else# include <sys/lock.h># endif#endif#endif#ifdef _AIX# include <ulimit.h>#endif /* _AIX */#ifdef SCO5_CLOCK# include <sys/ci/ciioctl.h>#endif#ifdef HAVE_DROPROOT# include <ctype.h># include <grp.h># include <pwd.h>#ifdef HAVE_LINUX_CAPABILITIES# include <sys/capability.h># include <sys/prctl.h>#endif#endif/* * Signals we catch for debugging. If not debugging we ignore them. */#define MOREDEBUGSIG SIGUSR1#define LESSDEBUGSIG SIGUSR2/* * Signals which terminate us gracefully. */#ifndef SYS_WINNT# define SIGDIE1 SIGHUP# define SIGDIE3 SIGQUIT# define SIGDIE2 SIGINT# define SIGDIE4 SIGTERM#endif /* SYS_WINNT */#ifdef HAVE_DNSREGISTRATION#include <dns_sd.h>DNSServiceRef mdns;#endif/* * Scheduling priority we run at */#define NTPD_PRIO (-12)int priority_done = 2; /* 0 - Set priority */ /* 1 - priority is OK where it is */ /* 2 - Don't set priority */ /* 1 and 2 are pretty much the same *//* * Debugging flag */volatile int debug;/* * Set the processing not to be in the forground */int forground_process = FALSE;/* * No-fork flag. If set, we do not become a background daemon. */int nofork;#ifdef HAVE_DROPROOTint droproot = 0;char *user = NULL; /* User to switch to */char *group = NULL; /* group to switch to */char *chrootdir = NULL; /* directory to chroot to */int sw_uid;int sw_gid;char *endp; struct group *gr;struct passwd *pw; #endif /* HAVE_DROPROOT *//* * Initializing flag. All async routines watch this and only do their * thing when it is clear. */int initializing;/* * Version declaration */extern const char *Version;int was_alarmed;#ifdef DECL_SYSCALL/* * We put this here, since the argument profile is syscall-specific */extern int syscall P((int, ...));#endif /* DECL_SYSCALL */#ifdef SIGDIE2static RETSIGTYPE finish P((int));#endif /* SIGDIE2 */#ifdef DEBUG#ifndef SYS_WINNTstatic RETSIGTYPE moredebug P((int));static RETSIGTYPE lessdebug P((int));#endif#else /* not DEBUG */static RETSIGTYPE no_debug P((int));#endif /* not DEBUG */int ntpdmain P((int, char **));static void set_process_priority P((void));static void init_logging P((char *));/* * Initialize the logging */voidinit_logging(char *name){ char *cp; /* * Logging. This may actually work on the gizmo board. Find a name * to log with by using the basename */ cp = strrchr(name, '/'); if (cp == 0) cp = name; else cp++;#if !defined(VMS)# ifndef LOG_DAEMON openlog(cp, LOG_PID);# else /* LOG_DAEMON */# ifndef LOG_NTP# define LOG_NTP LOG_DAEMON# endif openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);# ifdef DEBUG if (debug) setlogmask(LOG_UPTO(LOG_DEBUG)); else# endif /* DEBUG */ setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */# endif /* LOG_DAEMON */#endif /* !SYS_WINNT && !VMS */ NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */ msyslog(LOG_NOTICE, "%s", Version);}#ifdef SIMintmain( int argc, char *argv[] ){ return ntpsim(argc, argv);}#else /* SIM */#ifdef NO_MAIN_ALLOWEDCALL(ntpd,"ntpd",ntpdmain);#else#ifndef SYS_WINNTintmain( int argc, char *argv[] ){ return ntpdmain(argc, argv);}#endif /* SYS_WINNT */#endif /* NO_MAIN_ALLOWED */#endif /* SIM */#ifdef _AIX/* * OK. AIX is different than solaris in how it implements plock(). * If you do NOT adjust the stack limit, you will get the MAXIMUM * stack size allocated and PINNED with you program. To check the * value, use ulimit -a. * * To fix this, we create an automatic variable and set our stack limit * to that PLUS 32KB of extra space (we need some headroom). * * This subroutine gets the stack address. * * Grover Davidson and Matt Ladendorf * */static char *get_aix_stack(void){ char ch; return (&ch);}/* * Signal handler for SIGDANGER. */static voidcatch_danger(int signo){ msyslog(LOG_INFO, "ntpd: setpgid(): %m"); /* Make the system believe we'll free something, but don't do it! */ return;}#endif /* _AIX *//* * Set the process priority */static voidset_process_priority(void){#ifdef DEBUG if (debug > 1) msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>", ((priority_done) ? "Leave priority alone" : "Attempt to set priority" ), priority_done);#endif /* DEBUG */#ifdef SYS_WINNT priority_done += NT_set_process_priority();#endif#if defined(HAVE_SCHED_SETSCHEDULER) if (!priority_done) { extern int config_priority_override, config_priority; int pmax, pmin; struct sched_param sched; pmax = sched_get_priority_max(SCHED_FIFO); sched.sched_priority = pmax; if ( config_priority_override ) { pmin = sched_get_priority_min(SCHED_FIFO); if ( config_priority > pmax ) sched.sched_priority = pmax; else if ( config_priority < pmin ) sched.sched_priority = pmin; else sched.sched_priority = config_priority; } if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) msyslog(LOG_ERR, "sched_setscheduler(): %m"); else ++priority_done; }#endif /* HAVE_SCHED_SETSCHEDULER */#if defined(HAVE_RTPRIO)# ifdef RTP_SET if (!priority_done) { struct rtprio srtp; srtp.type = RTP_PRIO_REALTIME; /* was: RTP_PRIO_NORMAL */ srtp.prio = 0; /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */ if (rtprio(RTP_SET, getpid(), &srtp) < 0) msyslog(LOG_ERR, "rtprio() error: %m"); else ++priority_done; }# else /* not RTP_SET */ if (!priority_done) { if (rtprio(0, 120) < 0) msyslog(LOG_ERR, "rtprio() error: %m"); else ++priority_done; }# endif /* not RTP_SET */#endif /* HAVE_RTPRIO */#if defined(NTPD_PRIO) && NTPD_PRIO != 0# ifdef HAVE_ATT_NICE if (!priority_done) { errno = 0; if (-1 == nice (NTPD_PRIO) && errno != 0) msyslog(LOG_ERR, "nice() error: %m"); else ++priority_done; }# endif /* HAVE_ATT_NICE */# ifdef HAVE_BSD_NICE if (!priority_done) { if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO)) msyslog(LOG_ERR, "setpriority() error: %m"); else ++priority_done; }# endif /* HAVE_BSD_NICE */#endif /* NTPD_PRIO && NTPD_PRIO != 0 */ if (!priority_done) msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");}/* * Main program. Initialize us, disconnect us from the tty if necessary, * and loop waiting for I/O and/or timer expiries. */intntpdmain( int argc, char *argv[] ){ l_fp now; struct recvbuf *rbuflist; struct recvbuf *rbuf;#ifdef _AIX /* HMS: ifdef SIGDANGER? */ struct sigaction sa;#endif initializing = 1; /* mark that we are initializing */ debug = 0; /* no debugging by default */ nofork = 0; /* will fork by default */ init_logging(argv[0]); /* Open the log file */#ifdef HAVE_UMASK { mode_t uv; uv = umask(0); if(uv) (void) umask(uv); else (void) umask(022); }#endif#if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ { uid_t uid; uid = getuid(); if (uid) { msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid); exit(1); } }#endif#ifdef OPENSSL if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) { msyslog(LOG_ERR, "ntpd: OpenSSL version mismatch. Built against %lx, you have %lx\n", OPENSSL_VERSION_NUMBER, SSLeay()); exit(1); }#endif#ifdef SYS_WINNT /* * Initialize the time structures and variables */ init_winnt_time();#endif getstartup(argc, argv); /* startup configuration, may set debug */ if (debug) printf("%s\n", Version); /* * Initialize random generator and public key pair */ get_systime(&now); ntp_srandom((int)(now.l_i * now.l_uf));#ifdef HAVE_DNSREGISTRATION msyslog(LOG_INFO, "Attemping to register mDNS\n"); if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) { msyslog(LOG_ERR, "Unable to register mDNS\n"); }#endif#if !defined(VMS)# ifndef NODETACH /* * Detach us from the terminal. May need an #ifndef GIZMO. */# ifdef DEBUG if (!debug && !nofork)# else /* DEBUG */ if (!nofork)# endif /* DEBUG */ {# ifndef SYS_WINNT# ifdef HAVE_DAEMON daemon(0, 0);# else /* not HAVE_DAEMON */ if (fork()) /* HMS: What about a -1? */ exit(0); {#if !defined(F_CLOSEM) u_long s; int max_fd;#endif /* not F_CLOSEM */#if defined(F_CLOSEM) /* * From 'Writing Reliable AIX Daemons,' SG24-4946-00, * by Eric Agar (saves us from doing 32767 system * calls) */ if (fcntl(0, F_CLOSEM, 0) == -1) msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");#else /* not F_CLOSEM */# if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) max_fd = sysconf(_SC_OPEN_MAX);# else /* HAVE_SYSCONF && _SC_OPEN_MAX */ max_fd = getdtablesize();# endif /* HAVE_SYSCONF && _SC_OPEN_MAX */ for (s = 0; s < max_fd; s++) (void) close((int)s);#endif /* not F_CLOSEM */ (void) open("/", 0); (void) dup2(0, 1); (void) dup2(0, 2);#ifdef SYS_DOMAINOS { uid_$t puid; status_$t st; proc2_$who_am_i(&puid);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -