|
Packit Service |
623930 |
/*
|
|
Packit Service |
623930 |
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
**********************************************************************
|
|
Packit Service |
623930 |
* Copyright (C) Richard P. Curnow 1997-2003
|
|
Packit Service |
623930 |
* Copyright (C) Miroslav Lichvar 2013-2014, 2016
|
|
Packit Service |
623930 |
*
|
|
Packit Service |
623930 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
623930 |
* it under the terms of version 2 of the GNU General Public License as
|
|
Packit Service |
623930 |
* published by the Free Software Foundation.
|
|
Packit Service |
623930 |
*
|
|
Packit Service |
623930 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit Service |
623930 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
623930 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
623930 |
* General Public License for more details.
|
|
Packit Service |
623930 |
*
|
|
Packit Service |
623930 |
* You should have received a copy of the GNU General Public License along
|
|
Packit Service |
623930 |
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit Service |
623930 |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit Service |
623930 |
*
|
|
Packit Service |
623930 |
**********************************************************************
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
=======================================================================
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
Module for parsing various forms of directive and command lines that
|
|
Packit Service |
623930 |
are common to the configuration file and to the command client.
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
*/
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
#include "config.h"
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
#include "sysincl.h"
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
#include "cmdparse.h"
|
|
Packit Service |
623930 |
#include "memory.h"
|
|
Packit Service |
623930 |
#include "nameserv.h"
|
|
Packit Service |
623930 |
#include "ntp.h"
|
|
Packit Service |
623930 |
#include "util.h"
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* ================================================== */
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
int
|
|
Packit Service |
623930 |
CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src)
|
|
Packit Service |
623930 |
{
|
|
Packit Service |
623930 |
char *hostname, *cmd;
|
|
Packit Service |
623930 |
int n;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
src->port = SRC_DEFAULT_PORT;
|
|
Packit Service |
623930 |
src->params.minpoll = SRC_DEFAULT_MINPOLL;
|
|
Packit Service |
623930 |
src->params.maxpoll = SRC_DEFAULT_MAXPOLL;
|
|
Packit Service |
623930 |
src->params.connectivity = SRC_ONLINE;
|
|
Packit Service |
623930 |
src->params.auto_offline = 0;
|
|
Packit Service |
623930 |
src->params.presend_minpoll = SRC_DEFAULT_PRESEND_MINPOLL;
|
|
Packit Service |
623930 |
src->params.burst = 0;
|
|
Packit Service |
623930 |
src->params.iburst = 0;
|
|
Packit Service |
623930 |
src->params.min_stratum = SRC_DEFAULT_MINSTRATUM;
|
|
Packit Service |
623930 |
src->params.poll_target = SRC_DEFAULT_POLLTARGET;
|
|
Packit Service |
623930 |
src->params.version = 0;
|
|
Packit Service |
623930 |
src->params.max_sources = SRC_DEFAULT_MAXSOURCES;
|
|
Packit Service |
623930 |
src->params.min_samples = SRC_DEFAULT_MINSAMPLES;
|
|
Packit Service |
623930 |
src->params.max_samples = SRC_DEFAULT_MAXSAMPLES;
|
|
Packit Service |
623930 |
src->params.filter_length = 0;
|
|
Packit Service |
623930 |
src->params.interleaved = 0;
|
|
Packit Service |
623930 |
src->params.sel_options = 0;
|
|
Packit Service |
623930 |
src->params.authkey = INACTIVE_AUTHKEY;
|
|
Packit Service |
623930 |
src->params.max_delay = SRC_DEFAULT_MAXDELAY;
|
|
Packit Service |
623930 |
src->params.max_delay_ratio = SRC_DEFAULT_MAXDELAYRATIO;
|
|
Packit Service |
623930 |
src->params.max_delay_dev_ratio = SRC_DEFAULT_MAXDELAYDEVRATIO;
|
|
Packit Service |
623930 |
src->params.min_delay = 0.0;
|
|
Packit Service |
623930 |
src->params.asymmetry = SRC_DEFAULT_ASYMMETRY;
|
|
Packit Service |
623930 |
src->params.offset = 0.0;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
hostname = line;
|
|
Packit Service |
623930 |
line = CPS_SplitWord(line);
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
if (!*hostname)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
src->name = hostname;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Parse options */
|
|
Packit Service |
623930 |
for (; *line; line += n) {
|
|
Packit Service |
623930 |
cmd = line;
|
|
Packit Service |
623930 |
line = CPS_SplitWord(line);
|
|
Packit Service |
623930 |
n = 0;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
if (!strcasecmp(cmd, "auto_offline")) {
|
|
Packit Service |
623930 |
src->params.auto_offline = 1;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "burst")) {
|
|
Packit Service |
623930 |
src->params.burst = 1;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "iburst")) {
|
|
Packit Service |
623930 |
src->params.iburst = 1;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "offline")) {
|
|
Packit Service |
623930 |
src->params.connectivity = SRC_OFFLINE;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "noselect")) {
|
|
Packit Service |
623930 |
src->params.sel_options |= SRC_SELECT_NOSELECT;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "prefer")) {
|
|
Packit Service |
623930 |
src->params.sel_options |= SRC_SELECT_PREFER;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "require")) {
|
|
Packit Service |
623930 |
src->params.sel_options |= SRC_SELECT_REQUIRE;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "trust")) {
|
|
Packit Service |
623930 |
src->params.sel_options |= SRC_SELECT_TRUST;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "key")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%"SCNu32"%n", &src->params.authkey, &n) != 1 ||
|
|
Packit Service |
623930 |
src->params.authkey == INACTIVE_AUTHKEY)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "asymmetry")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", &src->params.asymmetry, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "filter")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.filter_length, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "maxdelay")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", &src->params.max_delay, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "maxdelayratio")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", &src->params.max_delay_ratio, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "maxdelaydevratio")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", &src->params.max_delay_dev_ratio, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "maxpoll")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.maxpoll, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "maxsamples")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.max_samples, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "maxsources")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.max_sources, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "mindelay")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", &src->params.min_delay, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "minpoll")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.minpoll, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "minsamples")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.min_samples, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "minstratum")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.min_stratum, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "offset")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", &src->params.offset, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "port")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%hu%n", &src->port, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "polltarget")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.poll_target, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "presend")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.presend_minpoll, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "version")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", &src->params.version, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "xleave")) {
|
|
Packit Service |
623930 |
src->params.interleaved = 1;
|
|
Packit Service |
623930 |
} else {
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
return 1;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* ================================================== */
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
int
|
|
Packit Service |
623930 |
CPS_ParseLocal(char *line, int *stratum, int *orphan, double *distance)
|
|
Packit Service |
623930 |
{
|
|
Packit Service |
623930 |
int n;
|
|
Packit Service |
623930 |
char *cmd;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
*stratum = 10;
|
|
Packit Service |
623930 |
*distance = 1.0;
|
|
Packit Service |
623930 |
*orphan = 0;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
while (*line) {
|
|
Packit Service |
623930 |
cmd = line;
|
|
Packit Service |
623930 |
line = CPS_SplitWord(line);
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
if (!strcasecmp(cmd, "stratum")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%d%n", stratum, &n) != 1 ||
|
|
Packit Service |
623930 |
*stratum >= NTP_MAX_STRATUM || *stratum <= 0)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "orphan")) {
|
|
Packit Service |
623930 |
*orphan = 1;
|
|
Packit Service |
623930 |
n = 0;
|
|
Packit Service |
623930 |
} else if (!strcasecmp(cmd, "distance")) {
|
|
Packit Service |
623930 |
if (sscanf(line, "%lf%n", distance, &n) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
} else {
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
line += n;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
return 1;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* ================================================== */
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
void
|
|
Packit Service |
623930 |
CPS_NormalizeLine(char *line)
|
|
Packit Service |
623930 |
{
|
|
Packit Service |
623930 |
char *p, *q;
|
|
Packit Service |
623930 |
int space = 1, first = 1;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Remove white-space at beginning and replace white-spaces with space char */
|
|
Packit Service |
623930 |
for (p = q = line; *p; p++) {
|
|
Packit Service |
623930 |
if (isspace((unsigned char)*p)) {
|
|
Packit Service |
623930 |
if (!space)
|
|
Packit Service |
623930 |
*q++ = ' ';
|
|
Packit Service |
623930 |
space = 1;
|
|
Packit Service |
623930 |
continue;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Discard comment lines */
|
|
Packit Service |
623930 |
if (first && strchr("!;#%", *p))
|
|
Packit Service |
623930 |
break;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
*q++ = *p;
|
|
Packit Service |
623930 |
space = first = 0;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Strip trailing space */
|
|
Packit Service |
623930 |
if (q > line && q[-1] == ' ')
|
|
Packit Service |
623930 |
q--;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
*q = '\0';
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* ================================================== */
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
char *
|
|
Packit Service |
623930 |
CPS_SplitWord(char *line)
|
|
Packit Service |
623930 |
{
|
|
Packit Service |
623930 |
char *p = line, *q = line;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Skip white-space before the word */
|
|
Packit Service |
623930 |
while (*q && isspace((unsigned char)*q))
|
|
Packit Service |
623930 |
q++;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Move the word to the beginning */
|
|
Packit Service |
623930 |
while (*q && !isspace((unsigned char)*q))
|
|
Packit Service |
623930 |
*p++ = *q++;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Find the next word */
|
|
Packit Service |
623930 |
while (*q && isspace((unsigned char)*q))
|
|
Packit Service |
623930 |
q++;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
*p = '\0';
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Return pointer to the next word or NUL */
|
|
Packit Service |
623930 |
return q;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* ================================================== */
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
int
|
|
Packit Service |
623930 |
CPS_ParseKey(char *line, uint32_t *id, const char **hash, char **key)
|
|
Packit Service |
623930 |
{
|
|
Packit Service |
623930 |
char *s1, *s2, *s3, *s4;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
s1 = line;
|
|
Packit Service |
623930 |
s2 = CPS_SplitWord(s1);
|
|
Packit Service |
623930 |
s3 = CPS_SplitWord(s2);
|
|
Packit Service |
623930 |
s4 = CPS_SplitWord(s3);
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
/* Require two or three words */
|
|
Packit Service |
623930 |
if (!*s2 || *s4)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
if (sscanf(s1, "%"SCNu32, id) != 1)
|
|
Packit Service |
623930 |
return 0;
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
if (*s3) {
|
|
Packit Service |
623930 |
*hash = s2;
|
|
Packit Service |
623930 |
*key = s3;
|
|
Packit Service |
623930 |
} else {
|
|
Packit Service |
623930 |
*hash = "MD5";
|
|
Packit Service |
623930 |
*key = s2;
|
|
Packit Service |
623930 |
}
|
|
Packit Service |
623930 |
|
|
Packit Service |
623930 |
return 1;
|
|
Packit Service |
623930 |
}
|