diff options
Diffstat (limited to 'ntpd/ntp_util.c')
-rw-r--r-- | ntpd/ntp_util.c | 249 |
1 files changed, 134 insertions, 115 deletions
diff --git a/ntpd/ntp_util.c b/ntpd/ntp_util.c index 62a997e43aad..e7b374fc346f 100644 --- a/ntpd/ntp_util.c +++ b/ntpd/ntp_util.c @@ -13,7 +13,6 @@ #include "ntp_assert.h" #include "ntp_calendar.h" #include "ntp_leapsec.h" -#include "lib_strbuf.h" #include <stdio.h> #include <ctype.h> @@ -63,7 +62,6 @@ char *stats_drift_file; /* frequency file name */ static char *stats_temp_file; /* temp frequency file name */ static double wander_resid; /* last frequency update */ double wander_threshold = 1e-7; /* initial frequency threshold */ -static unsigned int cmdargs_seen = 0; /* stat options seen from command line */ /* * Statistics file stuff @@ -183,7 +181,7 @@ init_util(void) void write_stats(void) { - FILE *fp; + FILE *fp = NULL; #ifdef DOSYNCTODR struct timeval tv; #if !defined(VMS) @@ -267,12 +265,10 @@ write_stats(void) * the frequncy file. This minimizes the file writes to * nonvolaile storage. */ -#ifdef DEBUG - if (debug) - printf("write_stats: frequency %.6lf thresh %.6lf, freq %.6lf\n", + DPRINTF(1, ("write_stats: frequency %.6f thresh %.6f, freq %.6f\n", (prev_drift_comp - drift_comp) * 1e6, wander_resid * - 1e6, drift_comp * 1e6); -#endif + 1e6, drift_comp * 1e6)); + if (fabs(prev_drift_comp - drift_comp) < wander_resid) { wander_resid *= 0.5; return; @@ -284,7 +280,7 @@ write_stats(void) stats_temp_file); return; } - fprintf(fp, "%.3f\n", drift_comp * 1e6); + fprintf(fp, "%.6f\n", drift_comp * 1e6); (void)fclose(fp); /* atomic */ #ifdef SYS_WINNT @@ -326,29 +322,38 @@ write_stats(void) /* - * stats_config - configure the stats operation + * If an option was given on the command line make sure it takes + * precedence over the configuration file, as command-line options + * are processed first. Similarly, if an option is given in the + * configuration file, do not allow it to be overridden with runtime + * configuration. Done by simply remembering an option was already + * seen. */ static int allow_config( - unsigned int option, - int/*BOOL*/ cmdopt) + u_int option, + int/*BOOL*/ cmdopt + ) { - /* If an option was given on the command line, make sure it - * persists and is not later changed by a corresponding option - * from the config file. Done by simply remembering an option was - * already seen from the command line. - * - * BTW, if we ever define stats options beyond 31, this needs a - * fix. Until then, simply assume the shift will not overflow. - */ - unsigned int mask = 1u << option; - int retv = cmdopt || !(cmdargs_seen & mask); - if (cmdopt) - cmdargs_seen |= mask; + static u_int seen = 0; /* stat options previously set */ + u_int mask; + int retv; + + if (cmdopt) { + DEBUG_REQUIRE(option < sizeof(mask) * 8); + mask = 1u << option; + retv = !(seen & mask); + seen |= mask; + } else { + retv = FALSE; + } return retv; } +/* + * stats_config - configure the stats operation + */ void stats_config( int item, @@ -356,12 +361,13 @@ stats_config( int optflag ) { - FILE *fp; + FILE *fp = NULL; const char *value; size_t len; double old_drift; l_fp now; time_t ttnow; + char dirsep_or_nul; #ifndef VMS static const char temp_ext[] = ".TEMP"; #else @@ -415,137 +421,131 @@ stats_config( switch (item) { - /* - * Open and read frequency file. - */ + /* + * Open and read frequency file. + */ case STATS_FREQ_FILE: - if (!allow_config(STATS_FREQ_FILE, optflag)) + if (!allow_config(STATS_FREQ_FILE, optflag)) { break; - - if (!value || (len = strlen(value)) == 0) - { + } + if (!value || 0 == (len = strlen(value))) { free(stats_drift_file); free(stats_temp_file); - stats_drift_file = stats_temp_file = NULL; - } - else - { - stats_drift_file = erealloc(stats_drift_file, len + 1); + stats_drift_file = stats_temp_file = NULL; + } else { + stats_drift_file = erealloc(stats_drift_file, + 1 + len); stats_temp_file = erealloc(stats_temp_file, - len + sizeof(".TEMP")); - memcpy(stats_drift_file, value, (size_t)(len+1)); - memcpy(stats_temp_file, value, (size_t)len); - memcpy(stats_temp_file + len, temp_ext, sizeof(temp_ext)); + len + sizeof(temp_ext)); + memcpy(stats_drift_file, value, 1 + len); + memcpy(stats_temp_file, value, len); + memcpy(stats_temp_file + len, temp_ext, + sizeof(temp_ext)); } - + /* * Open drift file and read frequency. If the file is * missing or contains errors, tell the loop to reset. */ if (NULL == stats_drift_file) { - loop_config(LOOP_NOFREQ, 0.0); - prev_drift_comp = 0.0; + goto nofreq; } else if ((fp = fopen(stats_drift_file, "r")) == NULL) { - if (errno != ENOENT) + if (errno != ENOENT) { msyslog(LOG_WARNING, - "cannot read frequency file %s: %s", - stats_drift_file, strerror(errno)); + "cannot read frequency file %s: %m", + stats_drift_file); + } + goto nofreq; } else if (fscanf(fp, "%lf", &old_drift) != 1) { msyslog(LOG_ERR, "format error frequency file %s", stats_drift_file); - fclose(fp); + nofreq: + prev_drift_comp = 0.0; + loop_config(LOOP_NOFREQ, prev_drift_comp); } else { loop_config(LOOP_FREQ, old_drift); prev_drift_comp = drift_comp; msyslog(LOG_INFO, - "initial drift restored to %f", + "initial drift restored to %.6f", old_drift); + } + if (NULL != fp) { fclose(fp); } break; - /* - * Specify statistics directory. - */ + /* + * Specify statistics directory. + */ case STATS_STATSDIR: - if (!allow_config(STATS_STATSDIR, optflag)) + if (!allow_config(STATS_STATSDIR, optflag)) { break; - - /* - 1 since value may be missing the DIR_SEP. */ - if (strlen(value) >= sizeof(statsdir) - 1) { + } + /* - 2 since value may be missing the DIR_SEP. */ + len = strlen(value); + if (len > sizeof(statsdir) - 2) { msyslog(LOG_ERR, - "statsdir too long (>%d, sigh)", - (int)sizeof(statsdir) - 2); + "statsdir %s too long (>%u)", value, + (u_int)sizeof(statsdir) - 2); + break; + } + /* Add a DIR_SEP unless we already have one. */ + if (0 == len || DIR_SEP == value[len - 1]) { + dirsep_or_nul = '\0'; } else { - int add_dir_sep; - size_t value_l; - - /* Add a DIR_SEP unless we already have one. */ - value_l = strlen(value); - if (0 == value_l) - add_dir_sep = FALSE; - else - add_dir_sep = (DIR_SEP != - value[value_l - 1]); - - if (add_dir_sep) - snprintf(statsdir, sizeof(statsdir), - "%s%c", value, DIR_SEP); - else - snprintf(statsdir, sizeof(statsdir), - "%s", value); - filegen_statsdir(); + dirsep_or_nul = DIR_SEP; } + snprintf(statsdir, sizeof(statsdir), "%s%c", + value, dirsep_or_nul); + filegen_statsdir(); break; - /* - * Open pid file. - */ + /* + * Write pid file. + */ case STATS_PID_FILE: - if (!allow_config(STATS_PID_FILE, optflag)) + if (!allow_config(STATS_PID_FILE, optflag)) { break; - + } if ((fp = fopen(value, "w")) == NULL) { - msyslog(LOG_ERR, "pid file %s: %m", - value); + msyslog(LOG_ERR, "pid file %s: %m", value); break; } - fprintf(fp, "%d", (int)getpid()); + fprintf(fp, "%ld", (long)getpid()); fclose(fp); break; /* * Read leapseconds file. * - * Note: Currently a leap file without SHA1 signature is - * accepted, but if there is a signature line, the signature - * must be valid or the file is rejected. + * By default a leap file without SHA1 signature is accepted, + * but if there is a signature line, the signature must be + * valid or the leapfile line in ntp.conf must have ignorehash. */ case STATS_LEAP_FILE: - if (!value || (len = strlen(value)) == 0) + if (NULL == value || 0 == (len = strlen(value))) { break; - + } leapfile_name = erealloc(leapfile_name, len + 1); memcpy(leapfile_name, value, len + 1); chck_leaphash = optflag; if (leapsec_load_file( leapfile_name, &leapfile_stat, - TRUE, TRUE, chck_leaphash)) - { + TRUE, TRUE, chck_leaphash)) { leap_signature_t lsig; get_systime(&now); time(&ttnow); leapsec_getsig(&lsig); mprintf_event(EVNT_TAI, NULL, - "%d leap %s %s %s", + "%d leap %s expire%s %s", lsig.taiof, fstostr(lsig.ttime), leapsec_expired(now.l_ui, NULL) - ? "expired" - : "expires", + ? "d" + : "s", fstostr(lsig.etime)); have_leapfile = TRUE; @@ -579,31 +579,32 @@ stats_config( */ void record_peer_stats( - sockaddr_u *addr, - int status, - double offset, /* offset */ - double delay, /* delay */ - double dispersion, /* dispersion */ - double jitter /* jitter */ + sockaddr_u * addr, + int status, + double offset, + double delay, + double dispersion, + double jitter ) { - l_fp now; - u_long day; + l_fp now; + u_long day; - if (!stats_control) + if (!stats_control) { return; - + } get_systime(&now); filegen_setup(&peerstats, now.l_ui); + if (NULL == peerstats.fp) { + return; + } day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; - if (peerstats.fp != NULL) { - fprintf(peerstats.fp, - "%lu %s %s %x %.9f %.9f %.9f %.9f\n", day, - ulfptoa(&now, 3), stoa(addr), status, offset, - delay, dispersion, jitter); - fflush(peerstats.fp); - } + fprintf(peerstats.fp, + "%lu %s %s %x %.9f %.9f %.9f %.9f\n", day, + ulfptoa(&now, 3), stoa(addr), status, offset, + delay, dispersion, jitter); + fflush(peerstats.fp); } @@ -934,13 +935,14 @@ record_timing_stats( * * Note: This loads a new leapfile on the fly. Currently a leap file * without SHA1 signature is accepted, but if there is a signature line, - * the signature must be valid or the file is rejected. + * the signature must be valid unless the ntp.conf leapfile line specified + * ignorehash. */ void check_leap_file( - int is_daily_check, - uint32_t ntptime , - const time_t *systime + int is_daily_check, + uint32_t ntptime, + const time_t * systime ) { /* just do nothing if there is no leap file */ @@ -1097,3 +1099,20 @@ ntpd_time_stepped(void) win_time_stepped(); #endif } + + +#ifdef DEBUG +void +append_flagstr( + char * flagstr, + size_t sz, + const char * text +) +{ + if ('\0' != flagstr[0]) { + strlcat(flagstr, ",", sz); + } + /* bail if we ran out of room */ + INSIST(strlcat(flagstr, text, sz) < sz); +} +#endif /* DEBUG */ |