📄 ntpd.c
字号:
proc2_$make_server(&puid, &st); }#endif /* SYS_DOMAINOS */#if defined(HAVE_SETPGID) || defined(HAVE_SETSID)# ifdef HAVE_SETSID if (setsid() == (pid_t)-1) msyslog(LOG_ERR, "ntpd: setsid(): %m");# else if (setpgid(0, 0) == -1) msyslog(LOG_ERR, "ntpd: setpgid(): %m");# endif#else /* HAVE_SETPGID || HAVE_SETSID */ {# if defined(TIOCNOTTY) int fid; fid = open("/dev/tty", 2); if (fid >= 0) { (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0); (void) close(fid); }# endif /* defined(TIOCNOTTY) */# ifdef HAVE_SETPGRP_0 (void) setpgrp();# else /* HAVE_SETPGRP_0 */ (void) setpgrp(0, getpid());# endif /* HAVE_SETPGRP_0 */ }#endif /* HAVE_SETPGID || HAVE_SETSID */#ifdef _AIX /* Don't get killed by low-on-memory signal. */ sa.sa_handler = catch_danger; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; (void) sigaction(SIGDANGER, &sa, NULL);#endif /* _AIX */ }# endif /* not HAVE_DAEMON */# endif /* SYS_WINNT */ }# endif /* NODETACH */#endif /* VMS */ debug = 0; /* will be immediately re-initialized 8-( */ getstartup(argc, argv); /* startup configuration, catch logfile this time */#ifdef SCO5_CLOCK /* * SCO OpenServer's system clock offers much more precise timekeeping * on the base CPU than the other CPUs (for multiprocessor systems), * so we must lock to the base CPU. */ { int fd = open("/dev/at1", O_RDONLY); if (fd >= 0) { int zero = 0; if (ioctl(fd, ACPU_LOCK, &zero) < 0) msyslog(LOG_ERR, "cannot lock to base CPU: %m\n"); close( fd ); } /* else ... * If we can't open the device, this probably just isn't * a multiprocessor system, so we're A-OK. */ }#endif#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)# ifdef HAVE_SETRLIMIT /* * Set the stack limit to something smaller, so that we don't lock a lot * of unused stack memory. */ { struct rlimit rl; if (getrlimit(RLIMIT_STACK, &rl) != -1 && (rl.rlim_cur = 50 * 4096) < rl.rlim_max) { if (setrlimit(RLIMIT_STACK, &rl) == -1) { msyslog(LOG_ERR, "Cannot adjust stack limit for mlockall: %m"); } }# ifdef RLIMIT_MEMLOCK /* * The default RLIMIT_MEMLOCK is very low on Linux systems. * Unless we increase this limit malloc calls are likely to * fail if we drop root privlege. To be useful the value * has to be larger than the largest ntpd resident set size. */ rl.rlim_cur = rl.rlim_max = 32*1024*1024; if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) { msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m"); }# endif /* RLIMIT_MEMLOCK */ }# endif /* HAVE_SETRLIMIT */ /* * lock the process into memory */ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) msyslog(LOG_ERR, "mlockall(): %m");#else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */# ifdef HAVE_PLOCK# ifdef PROCLOCK# ifdef _AIX /* * set the stack limit for AIX for plock(). * see get_aix_stack for more info. */ if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0) { msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m"); }# endif /* _AIX */ /* * lock the process into memory */ if (plock(PROCLOCK) < 0) msyslog(LOG_ERR, "plock(PROCLOCK): %m");# else /* not PROCLOCK */# ifdef TXTLOCK /* * Lock text into ram */ if (plock(TXTLOCK) < 0) msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");# else /* not TXTLOCK */ msyslog(LOG_ERR, "plock() - don't know what to lock!");# endif /* not TXTLOCK */# endif /* not PROCLOCK */# endif /* HAVE_PLOCK */#endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ /* * Set up signals we pay attention to locally. */#ifdef SIGDIE1 (void) signal_no_reset(SIGDIE1, finish);#endif /* SIGDIE1 */#ifdef SIGDIE2 (void) signal_no_reset(SIGDIE2, finish);#endif /* SIGDIE2 */#ifdef SIGDIE3 (void) signal_no_reset(SIGDIE3, finish);#endif /* SIGDIE3 */#ifdef SIGDIE4 (void) signal_no_reset(SIGDIE4, finish);#endif /* SIGDIE4 */#ifdef SIGBUS (void) signal_no_reset(SIGBUS, finish);#endif /* SIGBUS */#if !defined(SYS_WINNT) && !defined(VMS)# ifdef DEBUG (void) signal_no_reset(MOREDEBUGSIG, moredebug); (void) signal_no_reset(LESSDEBUGSIG, lessdebug);# else (void) signal_no_reset(MOREDEBUGSIG, no_debug); (void) signal_no_reset(LESSDEBUGSIG, no_debug);# endif /* DEBUG */#endif /* !SYS_WINNT && !VMS */ /* * Set up signals we should never pay attention to. */#if defined SIGPIPE (void) signal_no_reset(SIGPIPE, SIG_IGN);#endif /* SIGPIPE */ /* * Call the init_ routines to initialize the data structures. */ init_auth(); init_util(); init_restrict(); init_mon(); init_timer();#if defined (HAVE_IO_COMPLETION_PORT) init_io_completion_port();#endif init_lib(); init_request(); init_control(); init_peer();#ifdef REFCLOCK init_refclock();#endif set_process_priority(); init_proto(); /* Call at high priority */ init_io(); init_loopfilter(); mon_start(MON_ON); /* monitor on by default now */ /* turn off in config if unwanted */ /* * Get configuration. This (including argument list parsing) is * done in a separate module since this will definitely be different * for the gizmo board. While at it, save the host name for later * along with the length. The crypto needs this. */#ifdef DEBUG debug = 0;#endif getconfig(argc, argv); loop_config(LOOP_DRIFTCOMP, old_drift / 1e6);#ifdef OPENSSL crypto_setup();#endif /* OPENSSL */ initializing = 0;#ifdef HAVE_DROPROOT if( droproot ) { /* Drop super-user privileges and chroot now if the OS supports this */#ifdef HAVE_LINUX_CAPABILITIES /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */ if( prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1 ) { msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" ); exit(-1); }#else /* we need a user to switch to */ if( user == NULL ) { msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" ); exit(-1); }#endif /* HAVE_LINUX_CAPABILITIES */ if (user != NULL) { if (isdigit((unsigned char)*user)) { sw_uid = (uid_t)strtoul(user, &endp, 0); if (*endp != '\0') goto getuser; } else {getuser: if ((pw = getpwnam(user)) != NULL) { sw_uid = pw->pw_uid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find user `%s'", user); exit (-1); } } } if (group != NULL) { if (isdigit((unsigned char)*group)) { sw_gid = (gid_t)strtoul(group, &endp, 0); if (*endp != '\0') goto getgroup; } else {getgroup: if ((gr = getgrnam(group)) != NULL) { sw_gid = gr->gr_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find group `%s'", group); exit (-1); } } } if( chrootdir ) { /* make sure cwd is inside the jail: */ if( chdir(chrootdir) ) { msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir); exit (-1); } if( chroot(chrootdir) ) { msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir); exit (-1); } } if (group && setgid(sw_gid)) { msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group); exit (-1); } if (group && setegid(sw_gid)) { msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group); exit (-1); } if (user && setuid(sw_uid)) { msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user); exit (-1); } if (user && seteuid(sw_uid)) { msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user); exit (-1); } #ifdef HAVE_LINUX_CAPABILITIES do { /* We may be running under non-root uid now, but we still hold full root privileges! * We drop all of them, except for the crucial one: cap_sys_time: */ cap_t caps; if( ! ( caps = cap_from_text( "cap_sys_time=ipe" ) ) ) { msyslog( LOG_ERR, "cap_from_text() failed: %m" ); exit(-1); } if( cap_set_proc( caps ) == -1 ) { msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" ); exit(-1); } cap_free( caps ); } while(0);#endif /* HAVE_LINUX_CAPABILITIES */ } /* if( droproot ) */#endif /* HAVE_DROPROOT */ /* * Report that we're up to any trappers */ report_event(EVNT_SYSRESTART, (struct peer *)0); /* * Use select() on all on all input fd's for unlimited * time. select() will terminate on SIGALARM or on the * reception of input. Using select() means we can't do * robust signal handling and we get a potential race * between checking for alarms and doing the select(). * Mostly harmless, I think. */ /* On VMS, I suspect that select() can't be interrupted * by a "signal" either, so I take the easy way out and * have select() time out after one second. * System clock updates really aren't time-critical, * and - lacking a hardware reference clock - I have * yet to learn about anything else that is. */#if defined(HAVE_IO_COMPLETION_PORT) for (;;) { rbuflist = GetReceivedBuffers();#else /* normal I/O */ was_alarmed = 0; rbuflist = (struct recvbuf *)0; for (;;) {# if !defined(HAVE_SIGNALED_IO) extern fd_set activefds; extern int maxactivefd; fd_set rdfdes; int nfound;# elif defined(HAVE_SIGNALED_IO) block_io_and_alarm();# endif rbuflist = getrecvbufs(); /* get received buffers */ if (alarm_flag) /* alarmed? */ { was_alarmed = 1; alarm_flag = 0; } if (!was_alarmed && rbuflist == (struct recvbuf *)0) { /* * Nothing to do. Wait for something. */# ifndef HAVE_SIGNALED_IO rdfdes = activefds;# if defined(VMS) || defined(SYS_VXWORKS) /* make select() wake up after one second */ { struct timeval t1; t1.tv_sec = 1; t1.tv_usec = 0; nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, &t1); }# else nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, (struct timeval *)0);# endif /* VMS */ if (nfound > 0) { l_fp ts; get_systime(&ts); (void)input_handler(&ts); } else if (nfound == -1 && errno != EINTR) netsyslog(LOG_ERR, "select() error: %m");# ifdef DEBUG else if (debug > 5) netsyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);# endif /* DEBUG */# else /* HAVE_SIGNALED_IO */ wait_for_signal();# endif /* HAVE_SIGNALED_IO */ if (alarm_flag) /* alarmed? */ { was_alarmed = 1; alarm_flag = 0; } rbuflist = getrecvbufs(); /* get received buffers */ }# ifdef HAVE_SIGNALED_IO unblock_io_and_alarm();# endif /* HAVE_SIGNALED_IO */ /* * Out here, signals are unblocked. Call timer routine * to process expiry. */ if (was_alarmed) { timer(); was_alarmed = 0; }#endif /* HAVE_IO_COMPLETION_PORT */ /* * Call the data procedure to handle each received * packet. */ while (rbuflist != (struct recvbuf *)0) { rbuf = rbuflist; rbuflist = rbuf->next; (rbuf->receiver)(rbuf); freerecvbuf(rbuf); }#if defined DEBUG && defined SYS_WINNT if (debug > 4) printf("getrecvbufs: %ld handler interrupts, %ld frames\n", handler_calls, handler_pkts);#endif /* * Go around again */ } return 1;}#ifdef SIGDIE2/* * finish - exit gracefully */static RETSIGTYPEfinish( int sig ){ msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);#ifdef HAVE_DNSREGISTRATION if (mdns != NULL) DNSServiceRefDeallocate(mdns);#endif switch (sig) {# ifdef SIGBUS case SIGBUS: printf("\nfinish(SIGBUS)\n"); exit(0);# endif case 0: /* Should never happen... */ return; default: exit(0); }}#endif /* SIGDIE2 */#ifdef DEBUG#ifndef SYS_WINNT/* * moredebug - increase debugging verbosity */static RETSIGTYPEmoredebug( int sig ){ int saved_errno = errno; if (debug < 255) { debug++; msyslog(LOG_DEBUG, "debug raised to %d", debug); } errno = saved_errno;}/* * lessdebug - decrease debugging verbosity */static RETSIGTYPElessdebug( int sig ){ int saved_errno = errno; if (debug > 0) { debug--; msyslog(LOG_DEBUG, "debug lowered to %d", debug); } errno = saved_errno;}#endif#else /* not DEBUG */#ifndef SYS_WINNT/* * no_debug - We don't do the debug here. */static RETSIGTYPEno_debug( int sig ){ int saved_errno = errno; msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig); errno = saved_errno;}#endif /* not SYS_WINNT */#endif /* not DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -