Combine only sources whose distance is shorter than distance of the selected source multiplied by the value of combinelimit and their estimated frequencies are close to the frequency of the selected source. Add outlyer status for sources which are selectable, but not included in the combining. The status is displayed as '-' in the chronyc sources output.
1885 lines
43 KiB
C
1885 lines
43 KiB
C
/*
|
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
|
|
|
**********************************************************************
|
|
* Copyright (C) Richard P. Curnow 1997-2003
|
|
* Copyright (C) Miroslav Lichvar 2009-2012
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
**********************************************************************
|
|
|
|
=======================================================================
|
|
|
|
Module that reads and processes the configuration file.
|
|
|
|
1999-12-19 Kalle Olavi Niemitalo <tosi@stekt.oulu.fi>
|
|
|
|
* conf.c: Added a new configuration setting "acquisitionport" and
|
|
a function CNF_GetAcquisitionPort to read its value.
|
|
(acquisition_port): New variable.
|
|
(parse_port): Delegate most work to new function parse_some_port.
|
|
(parse_acquisitionport): New function.
|
|
(commands): Added "acquisitionport".
|
|
(CNF_GetAcquisitionPort): New function.
|
|
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "sysincl.h"
|
|
|
|
#include "conf.h"
|
|
#include "ntp_sources.h"
|
|
#include "ntp_core.h"
|
|
#include "refclock.h"
|
|
#include "cmdmon.h"
|
|
#include "srcparams.h"
|
|
#include "logging.h"
|
|
#include "nameserv.h"
|
|
#include "memory.h"
|
|
#include "acquire.h"
|
|
#include "cmdparse.h"
|
|
#include "broadcast.h"
|
|
#include "util.h"
|
|
|
|
/* ================================================== */
|
|
/* Forward prototypes */
|
|
|
|
static void parse_acquisitionport(char *);
|
|
static void parse_allow(char *);
|
|
static void parse_bindaddress(char *);
|
|
static void parse_bindcmdaddress(char *);
|
|
static void parse_broadcast(char *);
|
|
static void parse_clientloglimit(char *);
|
|
static void parse_cmdallow(char *);
|
|
static void parse_cmddeny(char *);
|
|
static void parse_cmdport(char *);
|
|
static void parse_combinelimit(char *);
|
|
static void parse_commandkey(char *);
|
|
static void parse_corrtimeratio(char *);
|
|
static void parse_deny(char *);
|
|
static void parse_driftfile(char *);
|
|
static void parse_dumpdir(char *);
|
|
static void parse_dumponexit(char *);
|
|
static void parse_fallbackdrift(char *);
|
|
static void parse_generatecommandkey(char *);
|
|
static void parse_include(char *);
|
|
static void parse_initstepslew(char *);
|
|
static void parse_keyfile(char *);
|
|
static void parse_leapsectz(char *);
|
|
static void parse_linux_freq_scale(char *);
|
|
static void parse_linux_hz(char *);
|
|
static void parse_local(char *);
|
|
static void parse_lockall(char *);
|
|
static void parse_log(char *);
|
|
static void parse_logbanner(char *);
|
|
static void parse_logchange(char *);
|
|
static void parse_logdir(char *);
|
|
static void parse_mailonchange(char *);
|
|
static void parse_makestep(char *);
|
|
static void parse_manual(char *);
|
|
static void parse_maxchange(char *);
|
|
static void parse_maxclockerror(char *);
|
|
static void parse_maxupdateskew(char *);
|
|
static void parse_noclientlog(char *);
|
|
static void parse_peer(char *);
|
|
static void parse_pidfile(char *);
|
|
static void parse_port(char *);
|
|
static void parse_refclock(char *);
|
|
static void parse_reselectdist(char *);
|
|
static void parse_rtcdevice(char *);
|
|
static void parse_rtcfile(char *);
|
|
static void parse_rtconutc(char *);
|
|
static void parse_rtcsync(char *);
|
|
static void parse_sched_priority(char *);
|
|
static void parse_server(char *);
|
|
static void parse_stratumweight(char *);
|
|
static void parse_tempcomp(char *);
|
|
static void parse_user(char *);
|
|
|
|
/* ================================================== */
|
|
/* Configuration variables */
|
|
|
|
static int restarted = 0;
|
|
static int generate_command_key = 0;
|
|
static char *rtc_device = "/dev/rtc";
|
|
static int acquisition_port = 0; /* 0 means let kernel choose port */
|
|
static int ntp_port = 123;
|
|
static char *keys_file = NULL;
|
|
static char *drift_file = NULL;
|
|
static char *rtc_file = NULL;
|
|
static unsigned long command_key_id;
|
|
static double max_update_skew = 1000.0;
|
|
static double correction_time_ratio = 1.0;
|
|
static double max_clock_error = 1.0; /* in ppm */
|
|
|
|
static double reselect_distance = 1e-4;
|
|
static double stratum_weight = 1.0;
|
|
static double combine_limit = 3.0;
|
|
|
|
static int cmd_port = DEFAULT_CANDM_PORT;
|
|
|
|
static int do_log_measurements = 0;
|
|
static int do_log_statistics = 0;
|
|
static int do_log_tracking = 0;
|
|
static int do_log_rtc = 0;
|
|
static int do_log_refclocks = 0;
|
|
static int do_log_tempcomp = 0;
|
|
static int do_dump_on_exit = 0;
|
|
static int log_banner = 32;
|
|
static char *logdir = ".";
|
|
static char *dumpdir = ".";
|
|
|
|
static int enable_local=0;
|
|
static int local_stratum;
|
|
|
|
static int do_init_stepslew = 0;
|
|
static int n_init_srcs;
|
|
|
|
/* Threshold (in seconds) - if absolute value of initial error is less
|
|
than this, slew instead of stepping */
|
|
static double init_slew_threshold;
|
|
#define MAX_INIT_SRCS 8
|
|
static IPAddr init_srcs_ip[MAX_INIT_SRCS];
|
|
|
|
static int enable_manual=0;
|
|
|
|
/* Flag set if the RTC runs UTC (default is it runs local time
|
|
incl. daylight saving). */
|
|
static int rtc_on_utc = 0;
|
|
|
|
/* Flag set if the RTC should be automatically synchronised by kernel */
|
|
static int rtc_sync = 0;
|
|
|
|
/* Limit and threshold for clock stepping */
|
|
static int make_step_limit = 0;
|
|
static double make_step_threshold = 0.0;
|
|
|
|
/* Number of updates before offset checking, number of ignored updates
|
|
before exiting and the maximum allowed offset */
|
|
static int max_offset_delay = -1;
|
|
static int max_offset_ignore;
|
|
static double max_offset;
|
|
|
|
/* Flag set if we should log to syslog when a time adjustment
|
|
exceeding the threshold is initiated */
|
|
static int do_log_change = 0;
|
|
static double log_change_threshold = 0.0;
|
|
|
|
static char *mail_user_on_change = NULL;
|
|
static double mail_change_threshold = 0.0;
|
|
|
|
/* Flag indicating that we don't want to log clients, e.g. to save
|
|
memory */
|
|
static int no_client_log = 0;
|
|
|
|
/* Limit memory allocated for the clients log */
|
|
static unsigned long client_log_limit = 524288;
|
|
|
|
/* Minimum and maximum fallback drift intervals */
|
|
static int fb_drift_min = 0;
|
|
static int fb_drift_max = 0;
|
|
|
|
/* IP addresses for binding the NTP socket to. UNSPEC family means INADDR_ANY
|
|
will be used */
|
|
static IPAddr bind_address4, bind_address6;
|
|
|
|
/* IP addresses for binding the command socket to. UNSPEC family means
|
|
use the value of bind_address */
|
|
static IPAddr bind_cmd_address4, bind_cmd_address6;
|
|
|
|
/* Filename to use for storing pid of running chronyd, to prevent multiple
|
|
* chronyds being started. */
|
|
static char *pidfile = "/var/run/chronyd.pid";
|
|
|
|
/* Temperature sensor, update interval and compensation coefficients */
|
|
static char *tempcomp_file = NULL;
|
|
static double tempcomp_interval;
|
|
static double tempcomp_T0, tempcomp_k0, tempcomp_k1, tempcomp_k2;
|
|
|
|
/* Boolean for whether the Linux HZ value has been overridden, and the
|
|
* new value. */
|
|
static int set_linux_hz = 0;
|
|
static int linux_hz;
|
|
|
|
/* Boolean for whether the Linux frequency scaling value (i.e. the one that's
|
|
* approx (1<<SHIFT_HZ)/HZ) has been overridden, and the new value. */
|
|
static int set_linux_freq_scale = 0;
|
|
static double linux_freq_scale;
|
|
|
|
static int sched_priority = 0;
|
|
static int lock_memory = 0;
|
|
|
|
/* Name of a system timezone containing leap seconds occuring at midnight */
|
|
static char *leapsec_tz = NULL;
|
|
|
|
/* Name of the user to which will be dropped root privileges. */
|
|
static char *user = NULL;
|
|
|
|
typedef struct {
|
|
NTP_Source_Type type;
|
|
CPS_NTP_Source params;
|
|
} NTP_Source;
|
|
|
|
#define MAX_NTP_SOURCES 64
|
|
|
|
static NTP_Source ntp_sources[MAX_NTP_SOURCES];
|
|
static int n_ntp_sources = 0;
|
|
|
|
#define MAX_RCL_SOURCES 8
|
|
|
|
static RefclockParameters refclock_sources[MAX_RCL_SOURCES];
|
|
static int n_refclock_sources = 0;
|
|
|
|
typedef struct _AllowDeny {
|
|
struct _AllowDeny *next;
|
|
struct _AllowDeny *prev;
|
|
IPAddr ip;
|
|
int subnet_bits;
|
|
int all; /* 1 to override existing more specific defns */
|
|
int allow; /* 0 for deny, 1 for allow */
|
|
} AllowDeny;
|
|
|
|
static AllowDeny ntp_auth_list = {&ntp_auth_list, &ntp_auth_list};
|
|
static AllowDeny cmd_auth_list = {&cmd_auth_list, &cmd_auth_list};
|
|
|
|
typedef struct {
|
|
/* Both in host (not necessarily network) order */
|
|
IPAddr addr;
|
|
unsigned short port;
|
|
int interval;
|
|
} NTP_Broadcast_Destination;
|
|
|
|
static NTP_Broadcast_Destination *broadcasts = NULL;
|
|
static int max_broadcasts = 0;
|
|
static int n_broadcasts = 0;
|
|
|
|
/* ================================================== */
|
|
|
|
/* The line number in the configuration file being processed */
|
|
static int line_number;
|
|
static const char *processed_file;
|
|
static const char *processed_command;
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
command_parse_error(void)
|
|
{
|
|
LOG_FATAL(LOGF_Configure, "Could not parse %s directive at line %d in file %s",
|
|
processed_command, line_number, processed_file);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
other_parse_error(const char *message)
|
|
{
|
|
LOG_FATAL(LOGF_Configure, "%s at line %d in file %s",
|
|
message, line_number, processed_file);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
check_number_of_args(char *line, int num)
|
|
{
|
|
/* The line is normalized, between arguments is just one space */
|
|
if (*line == ' ')
|
|
line++;
|
|
if (*line)
|
|
num--;
|
|
for (; *line; line++) {
|
|
if (*line == ' ')
|
|
num--;
|
|
}
|
|
if (num) {
|
|
LOG_FATAL(LOGF_Configure, "%s arguments for %s directive at line %d in file %s",
|
|
num > 0 ? "Missing" : "Too many",
|
|
processed_command, line_number, processed_file);
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_SetRestarted(int r)
|
|
{
|
|
restarted = r;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
/* Read the configuration file */
|
|
void
|
|
CNF_ReadFile(const char *filename)
|
|
{
|
|
FILE *in;
|
|
char line[2048];
|
|
char *p, *command;
|
|
const char *prev_processed_file;
|
|
int prev_line_number;
|
|
|
|
in = fopen(filename, "r");
|
|
if (!in) {
|
|
LOG_FATAL(LOGF_Configure, "Could not open configuration file %s", filename);
|
|
} else {
|
|
/* Save current line number in case this is an included file */
|
|
prev_line_number = line_number;
|
|
prev_processed_file = processed_file;
|
|
|
|
line_number = 0;
|
|
processed_file = filename;
|
|
|
|
/* Success */
|
|
while (fgets(line, sizeof(line), in)) {
|
|
line_number++;
|
|
|
|
/* Remove extra white-space and comments */
|
|
CPS_NormalizeLine(line);
|
|
|
|
/* Skip blank lines */
|
|
if (!*line)
|
|
continue;
|
|
|
|
/* We have a real line, now try to match commands */
|
|
processed_command = command = line;
|
|
p = CPS_SplitWord(line);
|
|
|
|
if (!strcasecmp(command, "acquisitionport")) {
|
|
parse_acquisitionport(p);
|
|
} else if (!strcasecmp(command, "allow")) {
|
|
parse_allow(p);
|
|
} else if (!strcasecmp(command, "bindaddress")) {
|
|
parse_bindaddress(p);
|
|
} else if (!strcasecmp(command, "bindcmdaddress")) {
|
|
parse_bindcmdaddress(p);
|
|
} else if (!strcasecmp(command, "broadcast")) {
|
|
parse_broadcast(p);
|
|
} else if (!strcasecmp(command, "clientloglimit")) {
|
|
parse_clientloglimit(p);
|
|
} else if (!strcasecmp(command, "cmdallow")) {
|
|
parse_cmdallow(p);
|
|
} else if (!strcasecmp(command, "cmddeny")) {
|
|
parse_cmddeny(p);
|
|
} else if (!strcasecmp(command, "cmdport")) {
|
|
parse_cmdport(p);
|
|
} else if (!strcasecmp(command, "combinelimit")) {
|
|
parse_combinelimit(p);
|
|
} else if (!strcasecmp(command, "commandkey")) {
|
|
parse_commandkey(p);
|
|
} else if (!strcasecmp(command, "corrtimeratio")) {
|
|
parse_corrtimeratio(p);
|
|
} else if (!strcasecmp(command, "deny")) {
|
|
parse_deny(p);
|
|
} else if (!strcasecmp(command, "driftfile")) {
|
|
parse_driftfile(p);
|
|
} else if (!strcasecmp(command, "dumpdir")) {
|
|
parse_dumpdir(p);
|
|
} else if (!strcasecmp(command, "dumponexit")) {
|
|
parse_dumponexit(p);
|
|
} else if (!strcasecmp(command, "fallbackdrift")) {
|
|
parse_fallbackdrift(p);
|
|
} else if (!strcasecmp(command, "generatecommandkey")) {
|
|
parse_generatecommandkey(p);
|
|
} else if (!strcasecmp(command, "include")) {
|
|
parse_include(p);
|
|
} else if (!strcasecmp(command, "initstepslew")) {
|
|
parse_initstepslew(p);
|
|
} else if (!strcasecmp(command, "keyfile")) {
|
|
parse_keyfile(p);
|
|
} else if (!strcasecmp(command, "leapsectz")) {
|
|
parse_leapsectz(p);
|
|
} else if (!strcasecmp(command, "linux_freq_scale")) {
|
|
parse_linux_freq_scale(p);
|
|
} else if (!strcasecmp(command, "linux_hz")) {
|
|
parse_linux_hz(p);
|
|
} else if (!strcasecmp(command, "local")) {
|
|
parse_local(p);
|
|
} else if (!strcasecmp(command, "lock_all")) {
|
|
parse_lockall(p);
|
|
} else if (!strcasecmp(command, "log")) {
|
|
parse_log(p);
|
|
} else if (!strcasecmp(command, "logbanner")) {
|
|
parse_logbanner(p);
|
|
} else if (!strcasecmp(command, "logchange")) {
|
|
parse_logchange(p);
|
|
} else if (!strcasecmp(command, "logdir")) {
|
|
parse_logdir(p);
|
|
} else if (!strcasecmp(command, "mailonchange")) {
|
|
parse_mailonchange(p);
|
|
} else if (!strcasecmp(command, "makestep")) {
|
|
parse_makestep(p);
|
|
} else if (!strcasecmp(command, "manual")) {
|
|
parse_manual(p);
|
|
} else if (!strcasecmp(command, "maxchange")) {
|
|
parse_maxchange(p);
|
|
} else if (!strcasecmp(command, "maxclockerror")) {
|
|
parse_maxclockerror(p);
|
|
} else if (!strcasecmp(command, "maxupdateskew")) {
|
|
parse_maxupdateskew(p);
|
|
} else if (!strcasecmp(command, "noclientlog")) {
|
|
parse_noclientlog(p);
|
|
} else if (!strcasecmp(command, "peer")) {
|
|
parse_peer(p);
|
|
} else if (!strcasecmp(command, "pidfile")) {
|
|
parse_pidfile(p);
|
|
} else if (!strcasecmp(command, "port")) {
|
|
parse_port(p);
|
|
} else if (!strcasecmp(command, "refclock")) {
|
|
parse_refclock(p);
|
|
} else if (!strcasecmp(command, "reselectdist")) {
|
|
parse_reselectdist(p);
|
|
} else if (!strcasecmp(command, "rtcdevice")) {
|
|
parse_rtcdevice(p);
|
|
} else if (!strcasecmp(command, "rtcfile")) {
|
|
parse_rtcfile(p);
|
|
} else if (!strcasecmp(command, "rtconutc")) {
|
|
parse_rtconutc(p);
|
|
} else if (!strcasecmp(command, "rtcsync")) {
|
|
parse_rtcsync(p);
|
|
} else if (!strcasecmp(command, "sched_priority")) {
|
|
parse_sched_priority(p);
|
|
} else if (!strcasecmp(command, "server")) {
|
|
parse_server(p);
|
|
} else if (!strcasecmp(command, "stratumweight")) {
|
|
parse_stratumweight(p);
|
|
} else if (!strcasecmp(command, "tempcomp")) {
|
|
parse_tempcomp(p);
|
|
} else if (!strcasecmp(command, "user")) {
|
|
parse_user(p);
|
|
} else {
|
|
other_parse_error("Invalid command");
|
|
}
|
|
}
|
|
|
|
line_number = prev_line_number;
|
|
processed_file = prev_processed_file;
|
|
fclose(in);
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_source(char *line, NTP_Source_Type type)
|
|
{
|
|
CPS_Status status;
|
|
|
|
if (n_ntp_sources >= MAX_NTP_SOURCES)
|
|
return;
|
|
|
|
ntp_sources[n_ntp_sources].type = type;
|
|
status = CPS_ParseNTPSourceAdd(line, &ntp_sources[n_ntp_sources].params);
|
|
|
|
switch (status) {
|
|
case CPS_Success:
|
|
n_ntp_sources++;
|
|
break;
|
|
case CPS_BadOption:
|
|
other_parse_error("Invalid server/peer parameter");
|
|
break;
|
|
case CPS_BadHost:
|
|
other_parse_error("Invalid host/IP address");
|
|
break;
|
|
case CPS_BadPort:
|
|
other_parse_error("Unreadable port");
|
|
break;
|
|
case CPS_BadMinpoll:
|
|
other_parse_error("Unreadable minpoll");
|
|
break;
|
|
case CPS_BadMaxpoll:
|
|
other_parse_error("Unreadable maxpoll");
|
|
break;
|
|
case CPS_BadPresend:
|
|
other_parse_error("Unreadable presend");
|
|
break;
|
|
case CPS_BadMaxdelaydevratio:
|
|
other_parse_error("Unreadable maxdelaydevratio");
|
|
break;
|
|
case CPS_BadMaxdelayratio:
|
|
other_parse_error("Unreadable maxdelayratio");
|
|
break;
|
|
case CPS_BadMaxdelay:
|
|
other_parse_error("Unreadable maxdelay");
|
|
break;
|
|
case CPS_BadKey:
|
|
other_parse_error("Unreadable key");
|
|
break;
|
|
case CPS_BadMinstratum:
|
|
other_parse_error("Unreadable minstratum");
|
|
break;
|
|
case CPS_BadPolltarget:
|
|
other_parse_error("Unreadable polltarget");
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_sched_priority(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%d", &sched_priority) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_lockall(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
lock_memory = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_server(char *line)
|
|
{
|
|
parse_source(line, NTP_SERVER);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_peer(char *line)
|
|
{
|
|
parse_source(line, NTP_PEER);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_refclock(char *line)
|
|
{
|
|
int i, n, poll, dpoll, filter_length, pps_rate;
|
|
uint32_t ref_id, lock_ref_id;
|
|
double offset, delay, precision;
|
|
char *p, *cmd, *name, *param;
|
|
unsigned char ref[5];
|
|
SRC_SelectOption sel_option;
|
|
|
|
i = n_refclock_sources;
|
|
if (i >= MAX_RCL_SOURCES)
|
|
return;
|
|
|
|
poll = 4;
|
|
dpoll = 0;
|
|
filter_length = 64;
|
|
pps_rate = 0;
|
|
offset = 0.0;
|
|
delay = 1e-9;
|
|
precision = 0.0;
|
|
ref_id = 0;
|
|
lock_ref_id = 0;
|
|
sel_option = SRC_SelectNormal;
|
|
|
|
if (!*line) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
p = line;
|
|
line = CPS_SplitWord(line);
|
|
|
|
if (!*line) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
name = strdup(p);
|
|
|
|
p = line;
|
|
line = CPS_SplitWord(line);
|
|
param = strdup(p);
|
|
|
|
while (*line) {
|
|
cmd = line;
|
|
line = CPS_SplitWord(line);
|
|
if (!strcasecmp(cmd, "refid")) {
|
|
if (sscanf(line, "%4s%n", (char *)ref, &n) != 1)
|
|
break;
|
|
ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
|
} else if (!strcasecmp(cmd, "lock")) {
|
|
if (sscanf(line, "%4s%n", (char *)ref, &n) != 1)
|
|
break;
|
|
lock_ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
|
} else if (!strcasecmp(cmd, "poll")) {
|
|
if (sscanf(line, "%d%n", &poll, &n) != 1) {
|
|
break;
|
|
}
|
|
} else if (!strcasecmp(cmd, "dpoll")) {
|
|
if (sscanf(line, "%d%n", &dpoll, &n) != 1) {
|
|
break;
|
|
}
|
|
} else if (!strcasecmp(cmd, "filter")) {
|
|
if (sscanf(line, "%d%n", &filter_length, &n) != 1) {
|
|
break;
|
|
}
|
|
} else if (!strcasecmp(cmd, "rate")) {
|
|
if (sscanf(line, "%d%n", &pps_rate, &n) != 1)
|
|
break;
|
|
} else if (!strcasecmp(cmd, "offset")) {
|
|
if (sscanf(line, "%lf%n", &offset, &n) != 1)
|
|
break;
|
|
} else if (!strcasecmp(cmd, "delay")) {
|
|
if (sscanf(line, "%lf%n", &delay, &n) != 1)
|
|
break;
|
|
} else if (!strcasecmp(cmd, "precision")) {
|
|
if (sscanf(line, "%lf%n", &precision, &n) != 1)
|
|
break;
|
|
} else if (!strcasecmp(cmd, "noselect")) {
|
|
n = 0;
|
|
sel_option = SRC_SelectNoselect;
|
|
} else if (!strcasecmp(cmd, "prefer")) {
|
|
n = 0;
|
|
sel_option = SRC_SelectPrefer;
|
|
} else {
|
|
break;
|
|
}
|
|
line += n;
|
|
}
|
|
|
|
if (*line) {
|
|
other_parse_error("Invalid/unreadable refclock parameter");
|
|
return;
|
|
}
|
|
|
|
refclock_sources[i].driver_name = name;
|
|
refclock_sources[i].driver_parameter = param;
|
|
refclock_sources[i].driver_poll = dpoll;
|
|
refclock_sources[i].poll = poll;
|
|
refclock_sources[i].filter_length = filter_length;
|
|
refclock_sources[i].pps_rate = pps_rate;
|
|
refclock_sources[i].offset = offset;
|
|
refclock_sources[i].delay = delay;
|
|
refclock_sources[i].precision = precision;
|
|
refclock_sources[i].sel_option = sel_option;
|
|
refclock_sources[i].ref_id = ref_id;
|
|
refclock_sources[i].lock_ref_id = lock_ref_id;
|
|
|
|
n_refclock_sources++;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_some_port(char *line, int *portvar)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%d", portvar) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_acquisitionport(char *line)
|
|
{
|
|
parse_some_port(line, &acquisition_port);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_port(char *line)
|
|
{
|
|
parse_some_port(line, &ntp_port);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_maxupdateskew(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &max_update_skew) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_maxclockerror(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &max_clock_error) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_corrtimeratio(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &correction_time_ratio) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_reselectdist(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &reselect_distance) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_stratumweight(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &stratum_weight) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_combinelimit(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &combine_limit) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_driftfile(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
drift_file = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_keyfile(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
keys_file = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_rtcfile(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
rtc_file = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_rtcdevice(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
rtc_device = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_logbanner(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%d", &log_banner) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_logdir(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
logdir = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_dumpdir(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
dumpdir = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_dumponexit(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
do_dump_on_exit = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_log(char *line)
|
|
{
|
|
char *log_name;
|
|
do {
|
|
log_name = line;
|
|
line = CPS_SplitWord(line);
|
|
if (*log_name) {
|
|
if (!strcmp(log_name, "measurements")) {
|
|
do_log_measurements = 1;
|
|
} else if (!strcmp(log_name, "statistics")) {
|
|
do_log_statistics = 1;
|
|
} else if (!strcmp(log_name, "tracking")) {
|
|
do_log_tracking = 1;
|
|
} else if (!strcmp(log_name, "rtc")) {
|
|
do_log_rtc = 1;
|
|
} else if (!strcmp(log_name, "refclocks")) {
|
|
do_log_refclocks = 1;
|
|
} else if (!strcmp(log_name, "tempcomp")) {
|
|
do_log_tempcomp = 1;
|
|
} else {
|
|
other_parse_error("Invalid log parameter");
|
|
break;
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
} while (1);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_commandkey(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lu", &command_key_id) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_local(char *line)
|
|
{
|
|
int stratum;
|
|
if (sscanf(line, "stratum%d", &stratum) == 1) {
|
|
local_stratum = stratum;
|
|
enable_local = 1;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_cmdport(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%d", &cmd_port) != 1) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_initstepslew(char *line)
|
|
{
|
|
char *p, *hostname;
|
|
IPAddr ip_addr;
|
|
|
|
/* Ignore the line if chronyd was started with -R. */
|
|
if (restarted) {
|
|
return;
|
|
}
|
|
|
|
n_init_srcs = 0;
|
|
p = CPS_SplitWord(line);
|
|
|
|
if (sscanf(line, "%lf", &init_slew_threshold) != 1) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
while (*p) {
|
|
hostname = p;
|
|
p = CPS_SplitWord(p);
|
|
if (*hostname) {
|
|
if (DNS_Name2IPAddress(hostname, &ip_addr) == DNS_Success) {
|
|
init_srcs_ip[n_init_srcs] = ip_addr;
|
|
++n_init_srcs;
|
|
} else {
|
|
LOG(LOGS_WARN, LOGF_Configure, "Could not resolve address of initstepslew server %s", hostname);
|
|
}
|
|
|
|
if (n_init_srcs >= MAX_INIT_SRCS) {
|
|
other_parse_error("Too many initstepslew servers");
|
|
}
|
|
}
|
|
}
|
|
if (n_init_srcs > 0) {
|
|
do_init_stepslew = 1;
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_manual(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
enable_manual = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_rtconutc(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
rtc_on_utc = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_rtcsync(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
rtc_sync = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_noclientlog(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
no_client_log = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_clientloglimit(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lu", &client_log_limit) != 1) {
|
|
command_parse_error();
|
|
}
|
|
|
|
if (client_log_limit == 0) {
|
|
/* unlimited */
|
|
client_log_limit = (unsigned long)-1;
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_fallbackdrift(char *line)
|
|
{
|
|
check_number_of_args(line, 2);
|
|
if (sscanf(line, "%d %d", &fb_drift_min, &fb_drift_max) != 2) {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_generatecommandkey(char *line)
|
|
{
|
|
check_number_of_args(line, 0);
|
|
generate_command_key = 1;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_makestep(char *line)
|
|
{
|
|
check_number_of_args(line, 2);
|
|
if (sscanf(line, "%lf %d", &make_step_threshold, &make_step_limit) != 2) {
|
|
make_step_limit = 0;
|
|
command_parse_error();
|
|
}
|
|
|
|
/* Disable limited makestep if chronyd was started with -R. */
|
|
if (restarted && make_step_limit > 0) {
|
|
make_step_limit = 0;
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_maxchange(char *line)
|
|
{
|
|
check_number_of_args(line, 3);
|
|
if (sscanf(line, "%lf %d %d", &max_offset, &max_offset_delay, &max_offset_ignore) != 3) {
|
|
max_offset_delay = -1;
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_logchange(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (sscanf(line, "%lf", &log_change_threshold) == 1) {
|
|
do_log_change = 1;
|
|
} else {
|
|
do_log_change = 0;
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_mailonchange(char *line)
|
|
{
|
|
char *address;
|
|
check_number_of_args(line, 2);
|
|
address = line;
|
|
line = CPS_SplitWord(line);
|
|
if (sscanf(line, "%lf", &mail_change_threshold) == 1) {
|
|
mail_user_on_change = strdup(address);
|
|
} else {
|
|
mail_user_on_change = NULL;
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_allow_deny(char *line, AllowDeny *list, int allow)
|
|
{
|
|
char *p;
|
|
unsigned long a, b, c, d, n;
|
|
int all = 0;
|
|
AllowDeny *new_node = NULL;
|
|
IPAddr ip_addr;
|
|
|
|
p = line;
|
|
|
|
if (!strncmp(p, "all", 3)) {
|
|
all = 1;
|
|
p = CPS_SplitWord(line);
|
|
}
|
|
|
|
if (!*p) {
|
|
/* Empty line applies to all addresses */
|
|
new_node = MallocNew(AllowDeny);
|
|
new_node->allow = allow;
|
|
new_node->all = all;
|
|
new_node->ip.family = IPADDR_UNSPEC;
|
|
new_node->subnet_bits = 0;
|
|
} else {
|
|
char *slashpos;
|
|
slashpos = strchr(p, '/');
|
|
if (slashpos) *slashpos = 0;
|
|
|
|
check_number_of_args(p, 1);
|
|
n = 0;
|
|
if (UTI_StringToIP(p, &ip_addr) ||
|
|
(n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d)) >= 1) {
|
|
new_node = MallocNew(AllowDeny);
|
|
new_node->allow = allow;
|
|
new_node->all = all;
|
|
|
|
if (n == 0) {
|
|
new_node->ip = ip_addr;
|
|
if (ip_addr.family == IPADDR_INET6)
|
|
new_node->subnet_bits = 128;
|
|
else
|
|
new_node->subnet_bits = 32;
|
|
} else {
|
|
new_node->ip.family = IPADDR_INET4;
|
|
|
|
a &= 0xff;
|
|
b &= 0xff;
|
|
c &= 0xff;
|
|
d &= 0xff;
|
|
|
|
switch (n) {
|
|
case 1:
|
|
new_node->ip.addr.in4 = (a<<24);
|
|
new_node->subnet_bits = 8;
|
|
break;
|
|
case 2:
|
|
new_node->ip.addr.in4 = (a<<24) | (b<<16);
|
|
new_node->subnet_bits = 16;
|
|
break;
|
|
case 3:
|
|
new_node->ip.addr.in4 = (a<<24) | (b<<16) | (c<<8);
|
|
new_node->subnet_bits = 24;
|
|
break;
|
|
case 4:
|
|
new_node->ip.addr.in4 = (a<<24) | (b<<16) | (c<<8) | d;
|
|
new_node->subnet_bits = 32;
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
if (slashpos) {
|
|
int specified_subnet_bits, n;
|
|
n = sscanf(slashpos+1, "%d", &specified_subnet_bits);
|
|
if (n == 1) {
|
|
new_node->subnet_bits = specified_subnet_bits;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
} else {
|
|
if (DNS_Name2IPAddress(p, &ip_addr) == DNS_Success) {
|
|
new_node = MallocNew(AllowDeny);
|
|
new_node->allow = allow;
|
|
new_node->all = all;
|
|
new_node->ip = ip_addr;
|
|
if (ip_addr.family == IPADDR_INET6)
|
|
new_node->subnet_bits = 128;
|
|
else
|
|
new_node->subnet_bits = 32;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (new_node) {
|
|
new_node->prev = list->prev;
|
|
new_node->next = list;
|
|
list->prev->next = new_node;
|
|
list->prev = new_node;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_allow(char *line)
|
|
{
|
|
parse_allow_deny(line, &ntp_auth_list, 1);
|
|
}
|
|
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_deny(char *line)
|
|
{
|
|
parse_allow_deny(line, &ntp_auth_list, 0);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_cmdallow(char *line)
|
|
{
|
|
parse_allow_deny(line, &cmd_auth_list, 1);
|
|
}
|
|
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_cmddeny(char *line)
|
|
{
|
|
parse_allow_deny(line, &cmd_auth_list, 0);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_bindaddress(char *line)
|
|
{
|
|
IPAddr ip;
|
|
|
|
check_number_of_args(line, 1);
|
|
if (UTI_StringToIP(line, &ip)) {
|
|
if (ip.family == IPADDR_INET4)
|
|
bind_address4 = ip;
|
|
else if (ip.family == IPADDR_INET6)
|
|
bind_address6 = ip;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_bindcmdaddress(char *line)
|
|
{
|
|
IPAddr ip;
|
|
|
|
check_number_of_args(line, 1);
|
|
if (UTI_StringToIP(line, &ip)) {
|
|
if (ip.family == IPADDR_INET4)
|
|
bind_cmd_address4 = ip;
|
|
else if (ip.family == IPADDR_INET6)
|
|
bind_cmd_address6 = ip;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_pidfile(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
pidfile = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_broadcast(char *line)
|
|
{
|
|
/* Syntax : broadcast <interval> <broadcast-IP-addr> [<port>] */
|
|
int port;
|
|
int interval;
|
|
char *p;
|
|
IPAddr ip;
|
|
|
|
p = line;
|
|
line = CPS_SplitWord(line);
|
|
|
|
if (sscanf(p, "%d", &interval) != 1) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
p = line;
|
|
line = CPS_SplitWord(line);
|
|
|
|
if (!UTI_StringToIP(p, &ip)) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
p = line;
|
|
line = CPS_SplitWord(line);
|
|
|
|
if (*p) {
|
|
if (sscanf(p, "%d", &port) != 1 || *line) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
} else {
|
|
/* default port */
|
|
port = 123;
|
|
}
|
|
|
|
if (max_broadcasts == n_broadcasts) {
|
|
/* Expand array */
|
|
max_broadcasts += 8;
|
|
if (broadcasts) {
|
|
broadcasts = ReallocArray(NTP_Broadcast_Destination, max_broadcasts, broadcasts);
|
|
} else {
|
|
broadcasts = MallocArray(NTP_Broadcast_Destination, max_broadcasts);
|
|
}
|
|
}
|
|
|
|
broadcasts[n_broadcasts].addr = ip;
|
|
broadcasts[n_broadcasts].port = port;
|
|
broadcasts[n_broadcasts].interval = interval;
|
|
++n_broadcasts;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_tempcomp(char *line)
|
|
{
|
|
char *p;
|
|
|
|
check_number_of_args(line, 6);
|
|
p = line;
|
|
line = CPS_SplitWord(line);
|
|
|
|
if (!*p) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
if (sscanf(line, "%lf %lf %lf %lf %lf", &tempcomp_interval, &tempcomp_T0, &tempcomp_k0, &tempcomp_k1, &tempcomp_k2) != 5) {
|
|
command_parse_error();
|
|
return;
|
|
}
|
|
|
|
tempcomp_file = strdup(p);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_include(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
CNF_ReadFile(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_leapsectz(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
leapsec_tz = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_linux_hz(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (1 == sscanf(line, "%d", &linux_hz)) {
|
|
set_linux_hz = 1;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_linux_freq_scale(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
if (1 == sscanf(line, "%lf", &linux_freq_scale)) {
|
|
set_linux_freq_scale = 1;
|
|
} else {
|
|
command_parse_error();
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
static void
|
|
parse_user(char *line)
|
|
{
|
|
check_number_of_args(line, 1);
|
|
user = strdup(line);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_ProcessInitStepSlew(void (*after_hook)(void *), void *anything)
|
|
{
|
|
if (do_init_stepslew) {
|
|
ACQ_StartAcquisition(n_init_srcs, init_srcs_ip, init_slew_threshold, after_hook, anything);
|
|
} else {
|
|
(after_hook)(anything);
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_AddSources(void) {
|
|
int i;
|
|
|
|
for (i=0; i<n_ntp_sources; i++) {
|
|
NSR_AddUnresolvedSource(ntp_sources[i].params.name, ntp_sources[i].params.port,
|
|
ntp_sources[i].type, &ntp_sources[i].params.params);
|
|
}
|
|
|
|
NSR_ResolveSources();
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_AddRefclocks(void) {
|
|
int i;
|
|
|
|
for (i=0; i<n_refclock_sources; i++) {
|
|
RCL_AddRefclock(&refclock_sources[i]);
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_AddBroadcasts(void)
|
|
{
|
|
int i;
|
|
for (i=0; i<n_broadcasts; i++) {
|
|
BRD_AddDestination(&broadcasts[i].addr,
|
|
broadcasts[i].port,
|
|
broadcasts[i].interval);
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
unsigned short
|
|
CNF_GetNTPPort(void)
|
|
{
|
|
return ntp_port;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
unsigned short
|
|
CNF_GetAcquisitionPort(void)
|
|
{
|
|
return acquisition_port;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetDriftFile(void)
|
|
{
|
|
return drift_file;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogBanner(void)
|
|
{
|
|
return log_banner;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetLogDir(void)
|
|
{
|
|
return logdir;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetDumpDir(void)
|
|
{
|
|
return dumpdir;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogMeasurements(void)
|
|
{
|
|
return do_log_measurements;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogStatistics(void)
|
|
{
|
|
return do_log_statistics;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogTracking(void)
|
|
{
|
|
return do_log_tracking;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogRtc(void)
|
|
{
|
|
return do_log_rtc;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogRefclocks(void)
|
|
{
|
|
return do_log_refclocks;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLogTempComp(void)
|
|
{
|
|
return do_log_tempcomp;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetKeysFile(void)
|
|
{
|
|
return keys_file;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetRtcFile(void)
|
|
{
|
|
return rtc_file;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetRtcDevice(void)
|
|
{
|
|
return rtc_device;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
unsigned long
|
|
CNF_GetCommandKey(void)
|
|
{
|
|
return command_key_id;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetGenerateCommandKey(void)
|
|
{
|
|
return generate_command_key;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetDumpOnExit(void)
|
|
{
|
|
return do_dump_on_exit;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
double
|
|
CNF_GetMaxUpdateSkew(void)
|
|
{
|
|
return max_update_skew;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
double
|
|
CNF_GetMaxClockError(void)
|
|
{
|
|
return max_clock_error;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
double
|
|
CNF_GetCorrectionTimeRatio(void)
|
|
{
|
|
return correction_time_ratio;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
double
|
|
CNF_GetReselectDistance(void)
|
|
{
|
|
return reselect_distance;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
double
|
|
CNF_GetStratumWeight(void)
|
|
{
|
|
return stratum_weight;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
double
|
|
CNF_GetCombineLimit(void)
|
|
{
|
|
return combine_limit;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetManualEnabled(void)
|
|
{
|
|
return enable_manual;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetCommandPort(void) {
|
|
return cmd_port;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_AllowLocalReference(int *stratum)
|
|
{
|
|
if (enable_local) {
|
|
*stratum = local_stratum;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetRTCOnUTC(void)
|
|
{
|
|
return rtc_on_utc;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetRTCSync(void)
|
|
{
|
|
return rtc_sync;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetMakeStep(int *limit, double *threshold)
|
|
{
|
|
*limit = make_step_limit;
|
|
*threshold = make_step_threshold;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetMaxChange(int *delay, int *ignore, double *offset)
|
|
{
|
|
*delay = max_offset_delay;
|
|
*ignore = max_offset_ignore;
|
|
*offset = max_offset;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetLogChange(int *enabled, double *threshold)
|
|
{
|
|
*enabled = do_log_change;
|
|
*threshold = log_change_threshold;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetMailOnChange(int *enabled, double *threshold, char **user)
|
|
{
|
|
if (mail_user_on_change) {
|
|
*enabled = 1;
|
|
*threshold = mail_change_threshold;
|
|
*user = mail_user_on_change;
|
|
} else {
|
|
*enabled = 0;
|
|
*threshold = 0.0;
|
|
*user = NULL;
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_SetupAccessRestrictions(void)
|
|
{
|
|
AllowDeny *node;
|
|
int status;
|
|
|
|
for (node = ntp_auth_list.next; node != &ntp_auth_list; node = node->next) {
|
|
status = NCR_AddAccessRestriction(&node->ip, node->subnet_bits, node->allow, node->all);
|
|
if (!status) {
|
|
LOG_FATAL(LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
|
}
|
|
}
|
|
|
|
for (node = cmd_auth_list.next; node != &cmd_auth_list; node = node->next) {
|
|
status = CAM_AddAccessRestriction(&node->ip, node->subnet_bits, node->allow, node->all);
|
|
if (!status) {
|
|
LOG_FATAL(LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetNoClientLog(void)
|
|
{
|
|
return no_client_log;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
unsigned long
|
|
CNF_GetClientLogLimit(void)
|
|
{
|
|
return client_log_limit;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetFallbackDrifts(int *min, int *max)
|
|
{
|
|
*min = fb_drift_min;
|
|
*max = fb_drift_max;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetBindAddress(int family, IPAddr *addr)
|
|
{
|
|
if (family == IPADDR_INET4)
|
|
*addr = bind_address4;
|
|
else if (family == IPADDR_INET6)
|
|
*addr = bind_address6;
|
|
else
|
|
addr->family = IPADDR_UNSPEC;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetBindCommandAddress(int family, IPAddr *addr)
|
|
{
|
|
if (family == IPADDR_INET4)
|
|
*addr = bind_cmd_address4.family != IPADDR_UNSPEC ? bind_cmd_address4 : bind_address4;
|
|
else if (family == IPADDR_INET6)
|
|
*addr = bind_cmd_address6.family != IPADDR_UNSPEC ? bind_cmd_address6 : bind_address6;
|
|
else
|
|
addr->family = IPADDR_UNSPEC;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetPidFile(void)
|
|
{
|
|
return pidfile;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetLeapSecTimezone(void)
|
|
{
|
|
return leapsec_tz;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetLinuxHz(int *set, int *hz)
|
|
{
|
|
*set = set_linux_hz;
|
|
*hz = linux_hz;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetLinuxFreqScale(int *set, double *freq_scale)
|
|
{
|
|
*set = set_linux_freq_scale;
|
|
*freq_scale = linux_freq_scale ;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetSchedPriority(void)
|
|
{
|
|
return sched_priority;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
CNF_GetLockMemory(void)
|
|
{
|
|
return lock_memory;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
void
|
|
CNF_GetTempComp(char **file, double *interval, double *T0, double *k0, double *k1, double *k2)
|
|
{
|
|
*file = tempcomp_file;
|
|
*interval = tempcomp_interval;
|
|
*T0 = tempcomp_T0;
|
|
*k0 = tempcomp_k0;
|
|
*k1 = tempcomp_k1;
|
|
*k2 = tempcomp_k2;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
char *
|
|
CNF_GetUser(void)
|
|
{
|
|
return user;
|
|
}
|