diff options
Diffstat (limited to 'contrib/ntp/ntpd/ntpd.c')
-rw-r--r-- | contrib/ntp/ntpd/ntpd.c | 1274 |
1 files changed, 0 insertions, 1274 deletions
diff --git a/contrib/ntp/ntpd/ntpd.c b/contrib/ntp/ntpd/ntpd.c deleted file mode 100644 index 0b05253..0000000 --- a/contrib/ntp/ntpd/ntpd.c +++ /dev/null @@ -1,1274 +0,0 @@ -/* - * 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" - -#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 "../libntp/log.h" -# include <clockstuff.h> -# include <crtdbg.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_CLOCKCTL -# include <ctype.h> -# include <grp.h> -# include <pwd.h> -#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 */ - -#if defined SYS_WINNT -/* handles for various threads, process, and objects */ -HANDLE ResolverThreadHandle = NULL; -/* variables used to inform the Service Control Manager of our current state */ -BOOL NoWinService = FALSE; -SERVICE_STATUS ssStatus; -SERVICE_STATUS_HANDLE sshStatusHandle; -HANDLE WaitHandles[3] = { NULL, NULL, NULL }; -char szMsgPath[255]; -static BOOL WINAPI OnConsoleEvent(DWORD dwCtrlType); -BOOL init_randfile(); -#endif /* SYS_WINNT */ - -/* - * 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_CLOCKCTL -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_CLOCKCTL */ - -/* - * 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 SIGDIE2 -static RETSIGTYPE finish P((int)); -#endif /* SIGDIE2 */ - -#ifdef DEBUG -#ifndef SYS_WINNT -static 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)); - -#ifdef SIM -int -main( - int argc, - char *argv[] - ) -{ - return ntpsim(argc, argv); -} -#else /* SIM */ -#ifdef NO_MAIN_ALLOWED -CALL(ntpd,"ntpd",ntpdmain); -#else -int -main( - int argc, - char *argv[] - ) -{ - return ntpdmain(argc, argv); -} -#endif -#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 void -catch_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 void -set_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. - */ -int -ntpdmain( - int argc, - char *argv[] - ) -{ - l_fp now; - char *cp; - 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 */ - -#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 SYS_WINNT - /* Set the Event-ID message-file name. */ - if (!GetModuleFileName(NULL, szMsgPath, sizeof(szMsgPath))) { - msyslog(LOG_ERR, "GetModuleFileName(PGM_EXE_FILE) failed: %m\n"); - exit(1); - } - addSourceToRegistry("NTP", szMsgPath); -#endif - getstartup(argc, argv); /* startup configuration, may set debug */ - - if (debug) - printf("%s\n", Version); - - /* - * Initialize random generator and public key pair - */ -#ifdef SYS_WINNT - /* Initialize random file before OpenSSL checks */ - if(!init_randfile()) - msyslog(LOG_ERR, "Unable to initialize .rnd file\n"); -#endif - get_systime(&now); - SRANDOM((int)(now.l_i * now.l_uf)); - -#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); - 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 */ -# else /* SYS_WINNT */ - - { - if (NoWinService == FALSE) { - SERVICE_TABLE_ENTRY dispatchTable[] = { - { TEXT("NetworkTimeProtocol"), (LPSERVICE_MAIN_FUNCTION)service_main }, - { NULL, NULL } - }; - - /* daemonize */ - if (!StartServiceCtrlDispatcher(dispatchTable)) - { - msyslog(LOG_ERR, "StartServiceCtrlDispatcher: %m"); - ExitProcess(2); - } - } - else { - service_main(argc, argv); - return 0; - } - } -# endif /* SYS_WINNT */ - } -# endif /* NODETACH */ -# if defined(SYS_WINNT) && !defined(NODETACH) - else - service_main(argc, argv); - return 0; /* must return a value */ -} /* end main */ - -/* - * If this runs as a service under NT, the main thread will block at - * StartServiceCtrlDispatcher() and another thread will be started by the - * Service Control Dispatcher which will begin execution at the routine - * specified in that call (viz. service_main) - */ -void -service_main( - DWORD argc, - LPTSTR *argv - ) -{ - char *cp; - struct recvbuf *rbuflist; - struct recvbuf *rbuf; - - if(!debug && NoWinService == FALSE) - { - /* register our service control handler */ - sshStatusHandle = RegisterServiceCtrlHandler( TEXT("NetworkTimeProtocol"), - (LPHANDLER_FUNCTION)service_ctrl); - if(sshStatusHandle == 0) - { - msyslog(LOG_ERR, "RegisterServiceCtrlHandler failed: %m"); - return; - } - - /* report pending status to Service Control Manager */ - ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - ssStatus.dwCurrentState = SERVICE_START_PENDING; - ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - ssStatus.dwWin32ExitCode = NO_ERROR; - ssStatus.dwServiceSpecificExitCode = 0; - ssStatus.dwCheckPoint = 1; - ssStatus.dwWaitHint = 5000; - if (!SetServiceStatus(sshStatusHandle, &ssStatus)) - { - msyslog(LOG_ERR, "SetServiceStatus: %m"); - ssStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(sshStatusHandle, &ssStatus); - return; - } - - } /* debug */ -# endif /* defined(SYS_WINNT) && !defined(NODETACH) */ -#endif /* VMS */ - - /* - * Logging. This may actually work on the gizmo board. Find a name - * to log with by using the basename of argv[0] - */ - cp = strrchr(argv[0], '/'); - if (cp == 0) - cp = argv[0]; - else - cp++; - - debug = 0; /* will be immediately re-initialized 8-( */ - getstartup(argc, argv); /* startup configuration, catch logfile this time */ - -#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 SYS_WINNT - /* GMS 1/18/1997 - * TODO: lock the process in memory using SetProcessWorkingSetSize() and VirtualLock() functions - * - process_handle = GetCurrentProcess(); - if (SetProcessWorkingSetSize(process_handle, 2097152 , 4194304 ) == TRUE) { - if (VirtualLock(0 , 4194304) == FALSE) - msyslog(LOG_ERR, "VirtualLock() failed: %m"); - } else { - msyslog(LOG_ERR, "SetProcessWorkingSetSize() failed: %m"); - } - */ -#endif /* SYS_WINNT */ - -#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 = 20 * 4096) < rl.rlim_max) - { - if (setrlimit(RLIMIT_STACK, &rl) == -1) - { - msyslog(LOG_ERR, - "Cannot adjust stack limit for mlockall: %m"); - } - } - } -# 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 */ - -#if defined SYS_WINNT - if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) { - msyslog(LOG_ERR, "Can't set console control handler: %m"); - } -#endif - - /* - * Call the init_ routines to initialize the data structures. - */ -#if defined (HAVE_IO_COMPLETION_PORT) - init_io_completion_port(); - init_winnt_time(); -#endif - init_auth(); - init_util(); - init_restrict(); - init_mon(); - init_timer(); - init_lib(); - init_random(); - 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); -#ifdef OPENSSL - crypto_setup(); -#endif /* OPENSSL */ - initializing = 0; - -#if defined(SYS_WINNT) && !defined(NODETACH) -# if defined(DEBUG) - if(!debug) - { -# endif - if (NoWinService == FALSE) { - /* report to the service control manager that the service is running */ - ssStatus.dwCurrentState = SERVICE_RUNNING; - ssStatus.dwWin32ExitCode = NO_ERROR; - if (!SetServiceStatus(sshStatusHandle, &ssStatus)) - { - msyslog(LOG_ERR, "SetServiceStatus: %m"); - if (ResolverThreadHandle != NULL) - CloseHandle(ResolverThreadHandle); - ssStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(sshStatusHandle, &ssStatus); - return; - } - } -# if defined(DEBUG) - } -# endif -#endif - -#ifdef HAVE_CLOCKCTL - /* - * Drop super-user privileges and chroot now if the OS supports - * non root clock control (only NetBSD for now). - */ - 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 = pw->pw_gid; - } else { - errno = 0; - msyslog(LOG_ERR, "Cannot find group `%s'", group); - exit (-1); - } - } - } - if (chrootdir && 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); - } -#endif - /* - * 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) - WaitHandles[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* exit reques */ - WaitHandles[1] = get_timer_handle(); - WaitHandles[2] = get_io_event(); - - for (;;) { - DWORD Index = WaitForMultipleObjectsEx(sizeof(WaitHandles)/sizeof(WaitHandles[0]), WaitHandles, FALSE, 1000, TRUE); - switch (Index) { - case WAIT_OBJECT_0 + 0 : /* exit request */ - exit(0); - break; - - case WAIT_OBJECT_0 + 1 : /* timer */ - timer(); - break; - - case WAIT_OBJECT_0 + 2 : /* Io event */ -# ifdef DEBUG - if ( debug > 3 ) - { - printf( "IoEvent occurred\n" ); - } -# endif - break; - - case WAIT_IO_COMPLETION : /* loop */ - case WAIT_TIMEOUT : - break; - case WAIT_FAILED: - msyslog(LOG_ERR, "ntpdc: WaitForMultipleObjectsEx Failed: Error: %m"); - break; - - /* For now do nothing if not expected */ - default: - break; - - } /* switch */ - rbuflist = getrecvbufs(); /* get received buffers */ - -#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) - msyslog(LOG_ERR, "select() error: %m"); -# ifdef DEBUG - else if (debug > 2) - msyslog(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 - */ - } -#ifndef SYS_WINNT - exit(1); /* unreachable */ -#endif -#ifndef SYS_WINNT - return 1; /* DEC OSF cc braindamage */ -#endif -} - - -#ifdef SIGDIE2 -/* - * finish - exit gracefully - */ -static RETSIGTYPE -finish( - int sig - ) -{ - - msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig); - - 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 RETSIGTYPE -moredebug( - 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 RETSIGTYPE -lessdebug( - 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 RETSIGTYPE -no_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 */ - -#ifdef SYS_WINNT -/* service_ctrl - control handler for NTP service - * signals the service_main routine of start/stop requests - * from the control panel or other applications making - * win32API calls - */ -void -service_ctrl( - DWORD dwCtrlCode - ) -{ - DWORD dwState = SERVICE_RUNNING; - - /* Handle the requested control code */ - switch(dwCtrlCode) - { - case SERVICE_CONTROL_PAUSE: - /* see no reason to support this */ - break; - - case SERVICE_CONTROL_CONTINUE: - /* see no reason to support this */ - break; - - case SERVICE_CONTROL_STOP: - dwState = SERVICE_STOP_PENDING; - /* - * Report the status, specifying the checkpoint and waithint, - * before setting the termination event. - */ - ssStatus.dwCurrentState = dwState; - ssStatus.dwWin32ExitCode = NO_ERROR; - ssStatus.dwWaitHint = 3000; - if (!SetServiceStatus(sshStatusHandle, &ssStatus)) - { - msyslog(LOG_ERR, "SetServiceStatus: %m"); - } - if (WaitHandles[0] != NULL) { - SetEvent(WaitHandles[0]); - } - return; - - case SERVICE_CONTROL_INTERROGATE: - /* Update the service status */ - break; - - default: - /* invalid control code */ - break; - - } - - ssStatus.dwCurrentState = dwState; - ssStatus.dwWin32ExitCode = NO_ERROR; - if (!SetServiceStatus(sshStatusHandle, &ssStatus)) - { - msyslog(LOG_ERR, "SetServiceStatus: %m"); - } -} - -static BOOL WINAPI -OnConsoleEvent( - DWORD dwCtrlType - ) -{ - switch (dwCtrlType) { - case CTRL_BREAK_EVENT : - if (debug > 0) { - debug <<= 1; - } - else { - debug = 1; - } - if (debug > 8) { - debug = 0; - } - printf("debug level %d\n", debug); - break ; - - case CTRL_C_EVENT : - case CTRL_CLOSE_EVENT : - case CTRL_SHUTDOWN_EVENT : - if (WaitHandles[0] != NULL) { - SetEvent(WaitHandles[0]); - } - break; - - default : - return FALSE; - - - } - return TRUE;; -} - - -/* - * NT version of exit() - all calls to exit() should be routed to - * this function. - */ -void -service_exit( - int status - ) -{ - if (!debug) { /* did not become a service, simply exit */ - /* service mode, need to have the service_main routine - * register with the service control manager that the - * service has stopped running, before exiting - */ - ssStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(sshStatusHandle, &ssStatus); - - } - uninit_io_completion_port(); - reset_winnt_time(); - -# if defined _MSC_VER - _CrtDumpMemoryLeaks(); -# endif -#undef exit - exit(status); -} - -#endif /* SYS_WINNT */ |