aboutsummaryrefslogtreecommitdiff
path: root/ntpd/ntp_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/ntp_util.c')
-rw-r--r--ntpd/ntp_util.c249
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 */