📄 ntp_util.c
字号:
/* * ntp_util.c - stuff I didn't have any other place for */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include "ntpd.h"#include "ntp_io.h"#include "ntp_unixtime.h"#include "ntp_filegen.h"#include "ntp_if.h"#include "ntp_stdlib.h"#include <stdio.h>#include <ctype.h>#include <sys/types.h>#ifdef HAVE_SYS_IOCTL_H# include <sys/ioctl.h>#endif#ifdef HAVE_IEEEFP_H# include <ieeefp.h>#endif#ifdef HAVE_MATH_H# include <math.h>#endif#ifdef DOSYNCTODR# if !defined(VMS)# include <sys/resource.h># endif /* VMS */#endif#if defined(VMS)# include <descrip.h>#endif /* VMS *//* * This contains odds and ends. Right now the only thing you'll find * in here is the hourly stats printer and some code to support * rereading the keys file, but I may eventually put other things in * here such as code to do something with the leap bits. *//* * Name of the keys file */static char *key_file_name;/* * The name of the drift_comp file and the temporary. */static char *stats_drift_file;static char *stats_temp_file;/* * Statistics file stuff */#ifndef NTP_VAR# ifndef SYS_WINNT# define NTP_VAR "/var/NTP/" /* NOTE the trailing '/' */# else# define NTP_VAR "c:\\var\\ntp\\" /* NOTE the trailing '\\' */# endif /* SYS_WINNT */#endif#ifndef MAXPATHLEN# define MAXPATHLEN 256#endifstatic char statsdir[MAXPATHLEN] = NTP_VAR;static FILEGEN peerstats;static FILEGEN loopstats;static FILEGEN clockstats;static FILEGEN rawstats;static FILEGEN sysstats;#ifdef OPENSSLstatic FILEGEN cryptostats;#endif /* OPENSSL *//* * This controls whether stats are written to the fileset. Provided * so that ntpdc can turn off stats when the file system fills up. */int stats_control;/* * Initial frequency offset later passed to the loopfilter. */double old_drift;/* * init_util - initialize the utilities */voidinit_util(void){ stats_drift_file = 0; stats_temp_file = 0; key_file_name = 0; filegen_register(&statsdir[0], "peerstats", &peerstats); filegen_register(&statsdir[0], "loopstats", &loopstats); filegen_register(&statsdir[0], "clockstats", &clockstats); filegen_register(&statsdir[0], "rawstats", &rawstats); filegen_register(&statsdir[0], "sysstats", &sysstats);#ifdef OPENSSL filegen_register(&statsdir[0], "cryptostats", &cryptostats);#endif /* OPENSSL */}/* * hourly_stats - print some interesting stats */voidhourly_stats(void){ FILE *fp;#ifdef DOSYNCTODR struct timeval tv;#if !defined(VMS) int prio_set;#endif#ifdef HAVE_GETCLOCK struct timespec ts;#endif int o_prio; /* * Sometimes having a Sun can be a drag. * * The kernel variable dosynctodr controls whether the system's * soft clock is kept in sync with the battery clock. If it * is zero, then the soft clock is not synced, and the battery * clock is simply left to rot. That means that when the system * reboots, the battery clock (which has probably gone wacky) * sets the soft clock. That means ntpd starts off with a very * confused idea of what time it is. It then takes a large * amount of time to figure out just how wacky the battery clock * has made things drift, etc, etc. The solution is to make the * battery clock sync up to system time. The way to do THAT is * to simply set the time of day to the current time of day, but * as quickly as possible. This may, or may not be a sensible * thing to do. * * CAVEAT: settimeofday() steps the sun clock by about 800 us, * so setting DOSYNCTODR seems a bad idea in the * case of us resolution */#if !defined(VMS) /* (prr) getpriority returns -1 on error, but -1 is also a valid * return value (!), so instead we have to zero errno before the * call and check it for non-zero afterwards. */ errno = 0; prio_set = 0; o_prio = getpriority(PRIO_PROCESS,0); /* Save setting */ /* * (prr) if getpriority succeeded, call setpriority to raise * scheduling priority as high as possible. If that succeeds * as well, set the prio_set flag so we remember to reset * priority to its previous value below. Note that on Solaris * 2.6 (and beyond?), both getpriority and setpriority will fail * with ESRCH, because sched_setscheduler (called from main) put * us in the real-time scheduling class which setpriority * doesn't know about. Being in the real-time class is better * than anything setpriority can do, anyhow, so this error is * silently ignored. */ if ((errno == 0) && (setpriority(PRIO_PROCESS,0,-20) == 0)) prio_set = 1; /* overdrive */#endif /* VMS */#ifdef HAVE_GETCLOCK (void) getclock(TIMEOFDAY, &ts); tv.tv_sec = ts.tv_sec; tv.tv_usec = ts.tv_nsec / 1000;#else /* not HAVE_GETCLOCK */ GETTIMEOFDAY(&tv,(struct timezone *)NULL);#endif /* not HAVE_GETCLOCK */ if (ntp_set_tod(&tv,(struct timezone *)NULL) != 0) { msyslog(LOG_ERR, "can't sync battery time: %m"); }#if !defined(VMS) if (prio_set) setpriority(PRIO_PROCESS, 0, o_prio); /* downshift */#endif /* VMS */#endif /* DOSYNCTODR */ NLOG(NLOG_SYSSTATIST) msyslog(LOG_INFO, "offset %.6f sec freq %.3f ppm error %.6f poll %d", last_offset, drift_comp * 1e6, sys_jitter, sys_poll); record_sys_stats(); if (stats_drift_file != 0) { if ((fp = fopen(stats_temp_file, "w")) == NULL) { msyslog(LOG_ERR, "can't open %s: %m", stats_temp_file); return; } fprintf(fp, "%.3f\n", drift_comp * 1e6); (void)fclose(fp); /* atomic */#ifdef SYS_WINNT (void) _unlink(stats_drift_file); /* rename semantics differ under NT */#endif /* SYS_WINNT */#ifndef NO_RENAME (void) rename(stats_temp_file, stats_drift_file);#else /* we have no rename NFS of ftp in use */ if ((fp = fopen(stats_drift_file, "w")) == NULL) { msyslog(LOG_ERR, "can't open %s: %m", stats_drift_file); return; }#endif#if defined(VMS) /* PURGE */ { $DESCRIPTOR(oldvers,";-1"); struct dsc$descriptor driftdsc = { strlen(stats_drift_file),0,0,stats_drift_file }; while(lib$delete_file(&oldvers,&driftdsc) & 1) ; }#endif }}/* * stats_config - configure the stats operation */voidstats_config( int item, char *invalue /* only one type so far */ ){ FILE *fp; char *value; int len; /* * Expand environment strings under Windows NT, since the * command interpreter doesn't do this, the program must. */#ifdef SYS_WINNT char newvalue[MAX_PATH], parameter[MAX_PATH]; if (!ExpandEnvironmentStrings(invalue, newvalue, MAX_PATH)) { switch(item) { case STATS_FREQ_FILE: strcpy(parameter,"STATS_FREQ_FILE"); break; case STATS_STATSDIR: strcpy(parameter,"STATS_STATSDIR"); break; case STATS_PID_FILE: strcpy(parameter,"STATS_PID_FILE"); break; default: strcpy(parameter,"UNKNOWN"); break; } value = invalue; msyslog(LOG_ERR, "ExpandEnvironmentStrings(%s) failed: %m\n", parameter); } else { value = newvalue; }#else value = invalue;#endif /* SYS_WINNT */ switch(item) { case STATS_FREQ_FILE: if (stats_drift_file != 0) { (void) free(stats_drift_file); (void) free(stats_temp_file); stats_drift_file = 0; stats_temp_file = 0; } if (value == 0 || (len = strlen(value)) == 0) break; stats_drift_file = (char*)emalloc((u_int)(len + 1));#if !defined(VMS) stats_temp_file = (char*)emalloc((u_int)(len + sizeof(".TEMP")));#else stats_temp_file = (char*)emalloc((u_int)(len + sizeof("-TEMP")));#endif /* VMS */ memmove(stats_drift_file, value, (unsigned)(len+1)); memmove(stats_temp_file, value, (unsigned)len);#if !defined(VMS) memmove(stats_temp_file + len, ".TEMP", sizeof(".TEMP"));#else memmove(stats_temp_file + len, "-TEMP", sizeof("-TEMP"));#endif /* VMS */ /* * Open drift file and read frequency. If the file is * missing or contains errors, tell the loop to reset. */ if ((fp = fopen(stats_drift_file, "r")) == NULL) { old_drift = 1e9; break; } if (fscanf(fp, "%lf", &old_drift) != 1) { msyslog(LOG_ERR, "Frequency format error in %s", stats_drift_file); old_drift = 1e9; break; } fclose(fp); msyslog(LOG_INFO, "frequency initialized %.3f PPM from %s", old_drift, stats_drift_file); break; case STATS_STATSDIR: if (strlen(value) >= sizeof(statsdir)) { msyslog(LOG_ERR, "value for statsdir too long (>%d, sigh)", (int)sizeof(statsdir)-1); } else { l_fp now; get_systime(&now); strcpy(statsdir,value); if(peerstats.prefix == &statsdir[0] && peerstats.fp != NULL) { fclose(peerstats.fp); peerstats.fp = NULL; filegen_setup(&peerstats, now.l_ui); } if(loopstats.prefix == &statsdir[0] && loopstats.fp != NULL) { fclose(loopstats.fp); loopstats.fp = NULL; filegen_setup(&loopstats, now.l_ui); } if(clockstats.prefix == &statsdir[0] && clockstats.fp != NULL) { fclose(clockstats.fp); clockstats.fp = NULL; filegen_setup(&clockstats, now.l_ui); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -