📄 ntptime_config.c
字号:
/* * 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 */voidloadservers( 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 intgettokens( 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 intmatchkey( 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 intgetnetnum( 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -