Blame cmdparse.c

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
}