summaryrefslogtreecommitdiffstats
path: root/ntpdate/ntptime_config.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
committerroberto <roberto@FreeBSD.org>2008-08-17 17:37:33 +0000
commit4ded1c1fa0bc21c61f91a2dbe864835986745121 (patch)
tree16d100fbc9dae63888d48b464e471ba0e5065193 /ntpdate/ntptime_config.c
parent8b5a86d4fda08a9c68231415812edcb26be52f79 (diff)
downloadFreeBSD-src-4ded1c1fa0bc21c61f91a2dbe864835986745121.zip
FreeBSD-src-4ded1c1fa0bc21c61f91a2dbe864835986745121.tar.gz
Flatten the dist and various 4.n.n trees in preparation of future ntp imports.
Diffstat (limited to 'ntpdate/ntptime_config.c')
-rw-r--r--ntpdate/ntptime_config.c552
1 files changed, 552 insertions, 0 deletions
diff --git a/ntpdate/ntptime_config.c b/ntpdate/ntptime_config.c
new file mode 100644
index 0000000..e784d28
--- /dev/null
+++ b/ntpdate/ntptime_config.c
@@ -0,0 +1,552 @@
+/*
+ * ntptime_config.c
+ *
+ * What follows is a simplified version of the config parsing code
+ * in ntpd/ntp_config.c. We only parse a subset of the configuration
+ * syntax, and don't bother whining about things we don't understand.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_io.h"
+#include "ntp_unixtime.h"
+#include "ntp_filegen.h"
+#include "ntpdate.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+
+/*
+ * These routines are used to read the configuration file at
+ * startup time. An entry in the file must fit on a single line.
+ * Entries are processed as multiple tokens separated by white space
+ * Lines are considered terminated when a '#' is encountered. Blank
+ * lines are ignored.
+ */
+
+/*
+ * Configuration file name
+ */
+#ifndef CONFIG_FILE
+# ifndef SYS_WINNT
+# define CONFIG_FILE "/etc/ntp.conf"
+# else /* SYS_WINNT */
+# define CONFIG_FILE "%windir%\\ntp.conf"
+# define ALT_CONFIG_FILE "%windir%\\ntp.ini"
+# endif /* SYS_WINNT */
+#endif /* not CONFIG_FILE */
+
+/*
+ *
+ * We understand the following configuration entries and defaults.
+ *
+ * peer [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
+ * server [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
+ * keys file_name
+ */
+
+#define CONFIG_UNKNOWN 0
+
+#define CONFIG_PEER 1
+#define CONFIG_SERVER 2
+#define CONFIG_KEYS 8
+
+#define CONF_MOD_VERSION 1
+#define CONF_MOD_KEY 2
+#define CONF_MOD_MINPOLL 3
+#define CONF_MOD_MAXPOLL 4
+#define CONF_MOD_PREFER 5
+#define CONF_MOD_BURST 6
+#define CONF_MOD_SKEY 7
+#define CONF_MOD_TTL 8
+#define CONF_MOD_MODE 9
+
+/*
+ * Translation table - keywords to function index
+ */
+struct keyword {
+ const char *text;
+ int keytype;
+};
+
+/*
+ * Command keywords
+ */
+static struct keyword keywords[] = {
+ { "peer", CONFIG_PEER },
+ { "server", CONFIG_SERVER },
+ { "keys", CONFIG_KEYS },
+ { "", CONFIG_UNKNOWN }
+};
+
+/*
+ * "peer", "server", "broadcast" modifier keywords
+ */
+static struct keyword mod_keywords[] = {
+ { "version", CONF_MOD_VERSION },
+ { "key", CONF_MOD_KEY },
+ { "minpoll", CONF_MOD_MINPOLL },
+ { "maxpoll", CONF_MOD_MAXPOLL },
+ { "prefer", CONF_MOD_PREFER },
+ { "burst", CONF_MOD_BURST },
+ { "autokey", CONF_MOD_SKEY },
+ { "mode", CONF_MOD_MODE }, /* reference clocks */
+ { "ttl", CONF_MOD_TTL }, /* NTP peers */
+ { "", CONFIG_UNKNOWN }
+};
+
+/*
+ * Limits on things
+ */
+#define MAXTOKENS 20 /* 20 tokens on line */
+#define MAXLINE 1024 /* maximum length of line */
+#define MAXFILENAME 128 /* maximum length of a file name (alloca()?) */
+
+/*
+ * Miscellaneous macros
+ */
+#define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
+#define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
+#define ISSPACE(c) ((c) == ' ' || (c) == '\t')
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+/*
+ * Systemwide parameters and flags
+ */
+extern struct server **sys_servers; /* the server list */
+extern int sys_numservers; /* number of servers to poll */
+extern char *key_file;
+
+/*
+ * Function prototypes
+ */
+static int gettokens P((FILE *, char *, char **, int *));
+static int matchkey P((char *, struct keyword *));
+static int getnetnum P((const char *num, struct sockaddr_in *addr,
+ int complain));
+
+
+/*
+ * loadservers - load list of NTP servers from configuration file
+ */
+void
+loadservers(
+ char *cfgpath
+ )
+{
+ register int i;
+ int errflg;
+ int peerversion;
+ int minpoll;
+ int maxpoll;
+ /* int ttl; */
+ int srvcnt;
+ /* u_long peerkey; */
+ int peerflags;
+ struct sockaddr_in peeraddr;
+ FILE *fp;
+ char line[MAXLINE];
+ char *(tokens[MAXTOKENS]);
+ int ntokens;
+ int tok;
+ const char *config_file;
+#ifdef SYS_WINNT
+ char *alt_config_file;
+ LPTSTR temp;
+ char config_file_storage[MAX_PATH];
+ char alt_config_file_storage[MAX_PATH];
+#endif /* SYS_WINNT */
+ struct server *server, *srvlist;
+
+ /*
+ * Initialize, initialize
+ */
+ srvcnt = 0;
+ srvlist = 0;
+ errflg = 0;
+#ifdef DEBUG
+ debug = 0;
+#endif /* DEBUG */
+#ifndef SYS_WINNT
+ config_file = cfgpath ? cfgpath : CONFIG_FILE;
+#else
+ if (cfgpath) {
+ config_file = cfgpath;
+ } else {
+ temp = CONFIG_FILE;
+ if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) {
+ msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n");
+ exit(1);
+ }
+ config_file = config_file_storage;
+ }
+
+ temp = ALT_CONFIG_FILE;
+ if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) {
+ msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n");
+ exit(1);
+ }
+ alt_config_file = alt_config_file_storage;
+M
+#endif /* SYS_WINNT */
+
+ if ((fp = fopen(FindConfig(config_file), "r")) == NULL)
+ {
+ fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file));
+ msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file));
+#ifdef SYS_WINNT
+ /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
+
+ if ((fp = fopen(FindConfig(alt_config_file), "r")) == NULL) {
+
+ /*
+ * Broadcast clients can sometimes run without
+ * a configuration file.
+ */
+
+ fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file));
+ msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file));
+ return;
+ }
+#else /* not SYS_WINNT */
+ return;
+#endif /* not SYS_WINNT */
+ }
+
+ while ((tok = gettokens(fp, line, tokens, &ntokens))
+ != CONFIG_UNKNOWN) {
+ switch(tok) {
+ case CONFIG_PEER:
+ case CONFIG_SERVER:
+
+ if (ntokens < 2) {
+ msyslog(LOG_ERR,
+ "No address for %s, line ignored",
+ tokens[0]);
+ break;
+ }
+
+ if (!getnetnum(tokens[1], &peeraddr, 1)) {
+ /* Resolve now, or lose! */
+ break;
+ } else {
+ errflg = 0;
+
+ /* Shouldn't be able to specify multicast */
+ if (IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))
+ || ISBADADR(&peeraddr)) {
+ msyslog(LOG_ERR,
+ "attempt to configure invalid address %s",
+ ntoa(&peeraddr));
+ break;
+ }
+ }
+
+ peerversion = NTP_VERSION;
+ minpoll = NTP_MINDPOLL;
+ maxpoll = NTP_MAXDPOLL;
+ /* peerkey = 0; */
+ peerflags = 0;
+ /* ttl = 0; */
+ for (i = 2; i < ntokens; i++)
+ switch (matchkey(tokens[i], mod_keywords)) {
+ case CONF_MOD_VERSION:
+ if (i >= ntokens-1) {
+ msyslog(LOG_ERR,
+ "peer/server version requires an argument");
+ errflg = 1;
+ break;
+ }
+ peerversion = atoi(tokens[++i]);
+ if ((u_char)peerversion > NTP_VERSION
+ || (u_char)peerversion < NTP_OLDVERSION) {
+ msyslog(LOG_ERR,
+ "inappropriate version number %s, line ignored",
+ tokens[i]);
+ errflg = 1;
+ }
+ break;
+
+ case CONF_MOD_KEY:
+ if (i >= ntokens-1) {
+ msyslog(LOG_ERR,
+ "key: argument required");
+ errflg = 1;
+ break;
+ }
+ ++i;
+ /* peerkey = (int)atol(tokens[i]); */
+ peerflags |= FLAG_AUTHENABLE;
+ break;
+
+ case CONF_MOD_MINPOLL:
+ if (i >= ntokens-1) {
+ msyslog(LOG_ERR,
+ "minpoll: argument required");
+ errflg = 1;
+ break;
+ }
+ minpoll = atoi(tokens[++i]);
+ if (minpoll < NTP_MINPOLL)
+ minpoll = NTP_MINPOLL;
+ break;
+
+ case CONF_MOD_MAXPOLL:
+ if (i >= ntokens-1) {
+ msyslog(LOG_ERR,
+ "maxpoll: argument required"
+ );
+ errflg = 1;
+ break;
+ }
+ maxpoll = atoi(tokens[++i]);
+ if (maxpoll > NTP_MAXPOLL)
+ maxpoll = NTP_MAXPOLL;
+ break;
+
+ case CONF_MOD_PREFER:
+ peerflags |= FLAG_PREFER;
+ break;
+
+ case CONF_MOD_BURST:
+ peerflags |= FLAG_BURST;
+ break;
+
+ case CONF_MOD_SKEY:
+ peerflags |= FLAG_SKEY | FLAG_AUTHENABLE;
+ break;
+
+ case CONF_MOD_TTL:
+ if (i >= ntokens-1) {
+ msyslog(LOG_ERR,
+ "ttl: argument required");
+ errflg = 1;
+ break;
+ }
+ ++i;
+ /* ttl = atoi(tokens[i]); */
+ break;
+
+ case CONF_MOD_MODE:
+ if (i >= ntokens-1) {
+ msyslog(LOG_ERR,
+ "mode: argument required");
+ errflg = 1;
+ break;
+ }
+ ++i;
+ /* ttl = atoi(tokens[i]); */
+ break;
+
+ case CONFIG_UNKNOWN:
+ errflg = 1;
+ break;
+ }
+ if (minpoll > maxpoll) {
+ msyslog(LOG_ERR, "config error: minpoll > maxpoll");
+ errflg = 1;
+ }
+ if (errflg == 0) {
+ server = (struct server *)emalloc(sizeof(struct server));
+ memset((char *)server, 0, sizeof(struct server));
+ server->srcadr = peeraddr;
+ server->version = peerversion;
+ server->dispersion = PEER_MAXDISP;
+ server->next_server = srvlist;
+ srvlist = server;
+ srvcnt++;
+ }
+ break;
+
+ case CONFIG_KEYS:
+ if (ntokens >= 2) {
+ key_file = (char *) emalloc(strlen(tokens[1]) + 1);
+ strcpy(key_file, tokens[1]);
+ }
+ break;
+ }
+ }
+ (void) fclose(fp);
+
+ /* build final list */
+ sys_numservers = srvcnt;
+ sys_servers = (struct server **)
+ emalloc(sys_numservers * sizeof(struct server *));
+ for(i=0;i<sys_numservers;i++) {
+ sys_servers[i] = srvlist;
+ srvlist = srvlist->next_server;
+ }
+}
+
+
+
+/*
+ * gettokens - read a line and return tokens
+ */
+static int
+gettokens(
+ FILE *fp,
+ char *line,
+ char **tokenlist,
+ int *ntokens
+ )
+{
+ register char *cp;
+ register int eol;
+ register int ntok;
+ register int quoted = 0;
+
+ /*
+ * Find start of first token
+ */
+ again:
+ while ((cp = fgets(line, MAXLINE, fp)) != NULL) {
+ cp = line;
+ while (ISSPACE(*cp))
+ cp++;
+ if (!ISEOL(*cp))
+ break;
+ }
+ if (cp == NULL) {
+ *ntokens = 0;
+ return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */
+ }
+
+ /*
+ * Now separate out the tokens
+ */
+ eol = 0;
+ ntok = 0;
+ while (!eol) {
+ tokenlist[ntok++] = cp;
+ while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted))
+ quoted ^= (*cp++ == '"');
+
+ if (ISEOL(*cp)) {
+ *cp = '\0';
+ eol = 1;
+ } else { /* must be space */
+ *cp++ = '\0';
+ while (ISSPACE(*cp))
+ cp++;
+ if (ISEOL(*cp))
+ eol = 1;
+ }
+ if (ntok == MAXTOKENS)
+ eol = 1;
+ }
+
+ /*
+ * Return the match
+ */
+ *ntokens = ntok;
+ ntok = matchkey(tokenlist[0], keywords);
+ if (ntok == CONFIG_UNKNOWN)
+ goto again;
+ return ntok;
+}
+
+
+
+/*
+ * matchkey - match a keyword to a list
+ */
+static int
+matchkey(
+ register char *word,
+ register struct keyword *keys
+ )
+{
+ for (;;) {
+ if (keys->keytype == CONFIG_UNKNOWN) {
+ return CONFIG_UNKNOWN;
+ }
+ if (STRSAME(word, keys->text))
+ return keys->keytype;
+ keys++;
+ }
+}
+
+
+/*
+ * getnetnum - return a net number (this is crude, but careful)
+ */
+static int
+getnetnum(
+ const char *num,
+ struct sockaddr_in *addr,
+ int complain
+ )
+{
+ register const char *cp;
+ register char *bp;
+ register int i;
+ register int temp;
+ char buf[80]; /* will core dump on really stupid stuff */
+ u_int32 netnum;
+
+ /* XXX ELIMINATE replace with decodenetnum */
+ cp = num;
+ netnum = 0;
+ for (i = 0; i < 4; i++) {
+ bp = buf;
+ while (isdigit((int)*cp))
+ *bp++ = *cp++;
+ if (bp == buf)
+ break;
+
+ if (i < 3) {
+ if (*cp++ != '.')
+ break;
+ } else if (*cp != '\0')
+ break;
+
+ *bp = '\0';
+ temp = atoi(buf);
+ if (temp > 255)
+ break;
+ netnum <<= 8;
+ netnum += temp;
+#ifdef DEBUG
+ if (debug > 3)
+ printf("getnetnum %s step %d buf %s temp %d netnum %lu\n",
+ num, i, buf, temp, (u_long)netnum);
+#endif
+ }
+
+ if (i < 4) {
+ if (complain)
+ msyslog(LOG_ERR,
+ "getnetnum: \"%s\" invalid host number, line ignored",
+ num);
+#ifdef DEBUG
+ if (debug > 3)
+ printf(
+ "getnetnum: \"%s\" invalid host number, line ignored\n",
+ num);
+#endif
+ return 0;
+ }
+
+ /*
+ * make up socket address. Clear it out for neatness.
+ */
+ memset((void *)addr, 0, sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(NTP_PORT);
+ addr->sin_addr.s_addr = htonl(netnum);
+#ifdef DEBUG
+ if (debug > 1)
+ printf("getnetnum given %s, got %s (%lx)\n",
+ num, ntoa(addr), (u_long)netnum);
+#endif
+ return 1;
+}
OpenPOWER on IntegriCloud