📄 ntptimeset.c
字号:
* to throttle things */ for(k = 0;k < MAXXMITCOUNT;k++) { register int i, oldi; register u_long oldxtime; /* * We want to send a packet out for a server that has an * expired event time. However to be mellow about this, we only * use one expired event timer and to avoid starvation we use * the one with the oldest last transmit time. */ oldi = -1; oldxtime = 0; for (i = 0; i < sys_numservers; i++) { if (sys_servers[i]->event_time <= current_time) { if (oldi < 0 || oldxtime > sys_servers[i]->last_xmit) { oldxtime = sys_servers[i]->last_xmit; oldi = i; } } } if (oldi >= 0) transmit(sys_servers[oldi]); else break; /* no expired event */ } /* end of transmit loop */}#ifndef SYS_WINNT/* * alarming - record the occurance of an alarm interrupt */static RETSIGTYPEalarming( int sig )#elsevoid CALLBACK alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)#endif /* SYS_WINNT */{ alarm_flag++;}/* * init_alarm - set up the timer interrupt */static voidinit_alarm(void){#ifndef SYS_WINNT# ifndef HAVE_TIMER_SETTIME struct itimerval itimer;# else struct itimerspec ntpdate_itimer;# endif#else TIMECAPS tc; UINT wTimerRes, wTimerID;# endif /* SYS_WINNT */#if defined SYS_CYGWIN32 || defined SYS_WINNT HANDLE hToken; TOKEN_PRIVILEGES tkp; DWORD dwUser = 0;#endif /* SYS_WINNT */ alarm_flag = 0;#ifndef SYS_WINNT# if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) alarm_flag = 0; /* this code was put in as setitimer() is non existant this us the * POSIX "equivalents" setup - casey */ /* ntpdate_timerid is global - so we can kill timer later */ if (timer_create (CLOCK_REALTIME, NULL, &ntpdate_timerid) ==# ifdef SYS_VXWORKS ERROR# else -1# endif ) { fprintf (stderr, "init_alarm(): timer_create (...) FAILED\n"); return; } /* TIMER_HZ = (5) * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) * seconds from now and they continue on every 1/TIMER_HZ seconds. */ (void) signal_no_reset(SIGALRM, alarming); ntpdate_itimer.it_interval.tv_sec = ntpdate_itimer.it_value.tv_sec = 0; ntpdate_itimer.it_interval.tv_nsec = 1000000000/TIMER_HZ; ntpdate_itimer.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1); timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &ntpdate_itimer, NULL);# else /* * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) * seconds from now and they continue on every 1/TIMER_HZ seconds. */ (void) signal_no_reset(SIGALRM, alarming); itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0; itimer.it_interval.tv_usec = 1000000/TIMER_HZ; itimer.it_value.tv_usec = 1000000/(TIMER_HZ<<1); setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);# endif#if defined SYS_CYGWIN32 /* * Get previleges needed for fiddling with the clock */ /* get the current process token handle */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { msyslog(LOG_ERR, "OpenProcessToken failed: %m"); exit(1); } /* get the LUID for system-time privilege. */ LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; /* one privilege to set */ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; /* get set-time privilege for this process. */ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); /* cannot test return value of AdjustTokenPrivileges. */ if (GetLastError() != ERROR_SUCCESS) msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");#endif#else /* SYS_WINNT */ _tzset(); /* * Get previleges needed for fiddling with the clock */ /* get the current process token handle */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { msyslog(LOG_ERR, "OpenProcessToken failed: %m"); exit(1); } /* get the LUID for system-time privilege. */ LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; /* one privilege to set */ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; /* get set-time privilege for this process. */ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); /* cannot test return value of AdjustTokenPrivileges. */ if (GetLastError() != ERROR_SUCCESS) msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); /* * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds * Under Win/NT, expiry of timer interval leads to invocation * of a callback function (on a different thread) rather than * generating an alarm signal */ /* determine max and min resolution supported */ if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { msyslog(LOG_ERR, "timeGetDevCaps failed: %m"); exit(1); } wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax); /* establish the minimum timer resolution that we'll use */ timeBeginPeriod(wTimerRes); /* start the timer event */ wTimerID = timeSetEvent( (UINT) (1000/TIMER_HZ), /* Delay */ wTimerRes, /* Resolution */ (LPTIMECALLBACK) alarming, /* Callback function */ (DWORD) dwUser, /* User data */ TIME_PERIODIC); /* Event type (periodic) */ if (wTimerID == 0) { msyslog(LOG_ERR, "timeSetEvent failed: %m"); exit(1); }#endif /* SYS_WINNT */}/* * init_io - initialize I/O data and open socket */static voidinit_io(void){#ifdef SYS_WINNT WORD wVersionRequested; WSADATA wsaData; init_transmitbuff();#endif /* SYS_WINNT */ /* * Init buffer free list and stat counters */ init_recvbuff(sys_numservers + 2);#if defined(HAVE_SIGNALED_IO) set_signal();#endif#ifdef SYS_WINNT wVersionRequested = MAKEWORD(1,1); if (WSAStartup(wVersionRequested, &wsaData)) { msyslog(LOG_ERR, "No useable winsock.dll: %m"); exit(1); }#endif /* SYS_WINNT */ BLOCKIO(); /* create a datagram (UDP) socket */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { msyslog(LOG_ERR, "socket() failed: %m"); exit(1); /*NOTREACHED*/ } /* * bind the socket to the NTP port */ if (!debug && set_time && !unpriv_port) { struct sockaddr_in addr; memset((char *)&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = htons(NTP_PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {#ifndef SYS_WINNT if (errno == EADDRINUSE)#else if (WSAGetLastError() == WSAEADDRINUSE)#endif msyslog(LOG_ERR, "the NTP socket is in use, exiting"); else msyslog(LOG_ERR, "bind() fails: %m"); exit(1); } } FD_ZERO(&fdmask); FD_SET(fd, &fdmask); /* * set non-blocking, */#ifdef USE_FIONBIO /* in vxWorks we use FIONBIO, but the others are defined for old systems, so * all hell breaks loose if we leave them defined */#undef O_NONBLOCK#undef FNDELAY#undef O_NDELAY#endif#if defined(O_NONBLOCK) /* POSIX */ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m"); exit(1); /*NOTREACHED*/ }#elif defined(FNDELAY) if (fcntl(fd, F_SETFL, FNDELAY) < 0) { msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m"); exit(1); /*NOTREACHED*/ }#elif defined(O_NDELAY) /* generally the same as FNDELAY */ if (fcntl(fd, F_SETFL, O_NDELAY) < 0) { msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m"); exit(1); /*NOTREACHED*/ }#elif defined(FIONBIO) if (# if defined(VMS) (ioctl(fd,FIONBIO,&1) < 0)# elif defined(SYS_WINNT) (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)# else (ioctl(fd,FIONBIO,&on) < 0)# endif ) { msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m"); exit(1); /*NOTREACHED*/ }#elif defined(FIOSNBIO) if (ioctl(fd,FIOSNBIO,&on) < 0) { msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m"); exit(1); /*NOTREACHED*/ }#else# include "Bletch: Need non-blocking I/O!"#endif#ifdef HAVE_SIGNALED_IO init_socket_sig(fd);#endif /* not HAVE_SIGNALED_IO */ UNBLOCKIO();}/* * sendpkt - send a packet to the specified destination */static intsendpkt( struct sockaddr_in *dest, struct pkt *pkt, int len ){ int cc; static int horriblecnt = 0;#ifdef SYS_WINNT DWORD err;#endif /* SYS_WINNT */ total_xmit++; /* count it */ if (horrible) { if (++horriblecnt > HORRIBLEOK) { if (debug > 3) printf("dropping send (%s)\n", ntoa(dest)); if (horriblecnt >= HORRIBLEOK+horrible) horriblecnt = 0; return 0; } } cc = sendto(fd, (char *)pkt, (size_t)len, 0, (struct sockaddr *)dest, sizeof(struct sockaddr_in));#ifndef SYS_WINNT if (cc == -1) { if (errno != EWOULDBLOCK && errno != ENOBUFS)#else if (cc == SOCKET_ERROR) { err = WSAGetLastError(); if (err != WSAEWOULDBLOCK && err != WSAENOBUFS)#endif /* SYS_WINNT */ msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest)); return -1; } return 0;}/* * input_handler - receive packets asynchronously */voidinput_handler(l_fp *xts){ register int n; register struct recvbuf *rb; struct timeval tvzero; int fromlen; fd_set fds; l_fp ts; ts = *xts; /* we ignore xts, but make the compiler happy */ /* * Do a poll to see if we have data */ for (;;) { fds = fdmask; tvzero.tv_sec = tvzero.tv_usec = 0; n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero); /* * If nothing to do, just return. If an error occurred, * complain and return. If we've got some, freeze a * timestamp. */ if (n == 0) return; else if (n == -1) { if (errno != EINTR) { msyslog(LOG_ERR, "select() error: %m"); } return; } get_systime(&ts); /* * Get a buffer and read the frame. If we * haven't got a buffer, or this is received * on the wild card socket, just dump the packet. */ if (initializing || free_recvbuffs == 0) { char buf[100];#ifndef SYS_WINNT (void) read(fd, buf, sizeof buf);#else /* NT's _read does not operate on nonblocking sockets * either recvfrom or ReadFile() has to be used here. * ReadFile is used in [ntpd]ntp_intres() and ntpdc, * just to be different use recvfrom() here */ recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)0, NULL);#endif /* SYS_WINNT */ continue; } rb = get_free_recv_buffer(); fromlen = sizeof(struct sockaddr_in); rb->recv_length = recvfrom(fd, (char *)&rb->recv_pkt, sizeof(rb->recv_pkt), 0, (struct sockaddr *)&rb->srcadr, &fromlen); if (rb->recv_length == -1) { freerecvbuf(rb); continue; } /* * Got one. Mark how and when it got here, * put it on the full list. */ rb->recv_time = ts; add_full_recv_buffer(rb); total_recv++; /* count it */ }}/* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c *//* * printserver - print detail information for a server */static voidprintserver( register struct server *pp, FILE *fp ){ register int i; char junk[5]; char *str; if (!debug) { (void) fprintf(fp, "%-15s %d/%d %03o v%d s%d offset %9s delay %s disp %s\n", ntoa(&pp->srcadr), pp->xmtcnt,pp->rcvcnt,pp->reach, pp->version,pp->stratum, lfptoa(&pp->offset, 6), ufptoa(pp->delay, 5), ufptoa(pp->dispersion, 4)); return; } (void) fprintf(fp, "server %s, port %d\n", ntoa(&pp->srcadr), ntohs(pp->srcadr.sin_port)); (void) fprintf(fp, "stratum %d, precision %d, leap %c%c, trust %03o\n", pp->stratum, pp->precision, pp->leap & 0x2 ? '1' : '0', pp->leap & 0x1 ? '1' : '0', pp->trust); if (pp->stratum == 1) { junk[4] = 0; memmove(junk, (char *)&pp->refid, 4); str = junk; } else { str = numtoa(pp->refid); } (void) fprintf(fp, "refid [%s], delay %s, dispersion %s\n", str, fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5)); (void) fprintf(fp, "transmitted %d, received %d, reachable %03o\n", pp->xmtcnt, pp->rcvcnt, pp->reach); (void) fprintf(fp, "reference time: %s\n", prettydate(&pp->reftime)); (void) fprintf(fp, "originate timestamp: %s\n", prettydate(&pp->org)); (void) fprintf(fp, "transmit timestamp: %s\n", prettydate(&pp->xmt)); (void) fprintf(fp, "filter delay: "); for (i = 0; i < NTP_SHIFT; i++) { (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5)); if (i == (NTP_SHIFT>>1)-1) (void) fprintf(fp, "\n "); } (void) fprintf(fp, "\n"); (void) fprintf(fp, "filter offset:"); for (i = 0; i < PEER_SHIFT; i++) { (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6)); if (i == (PEER_SHIFT>>1)-1) (void) fprintf(fp, "\n "); } (void) fprintf(fp, "\n"); (void) fprintf(fp, "delay %s, dispersion %s\n", fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5)); (void) fprintf(fp, "offset %s\n\n", lfptoa(&pp->offset, 6));}#if !defined(HAVE_VSPRINTF)intvsprintf( char *str, const char *fmt, va_list ap ){ FILE f; int len; f._flag = _IOWRT+_IOSTRG; f._ptr = str; f._cnt = 32767; len = _doprnt(fmt, ap, &f); *f._ptr = 0; return (len);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -