Annotation of embedaddon/ntp/ntpdate/ntptime_config.c, revision 1.1
1.1 ! misho 1: /*
! 2: * ntptime_config.c
! 3: *
! 4: * What follows is a simplified version of the config parsing code
! 5: * in ntpd/ntp_config.c. We only parse a subset of the configuration
! 6: * syntax, and don't bother whining about things we don't understand.
! 7: *
! 8: */
! 9:
! 10: #ifdef HAVE_CONFIG_H
! 11: # include <config.h>
! 12: #endif
! 13:
! 14: #include "ntp_fp.h"
! 15: #include "ntp.h"
! 16: #include "ntp_io.h"
! 17: #include "ntp_unixtime.h"
! 18: #include "ntp_filegen.h"
! 19: #include "ntpdate.h"
! 20: #include "ntp_syslog.h"
! 21: #include "ntp_stdlib.h"
! 22:
! 23: #include <stdio.h>
! 24: #include <signal.h>
! 25: #include <ctype.h>
! 26:
! 27: /*
! 28: * These routines are used to read the configuration file at
! 29: * startup time. An entry in the file must fit on a single line.
! 30: * Entries are processed as multiple tokens separated by white space
! 31: * Lines are considered terminated when a '#' is encountered. Blank
! 32: * lines are ignored.
! 33: */
! 34:
! 35: /*
! 36: * Configuration file name
! 37: */
! 38: #ifndef CONFIG_FILE
! 39: # ifndef SYS_WINNT
! 40: # define CONFIG_FILE "/etc/ntp.conf"
! 41: # else /* SYS_WINNT */
! 42: # define CONFIG_FILE "%windir%\\ntp.conf"
! 43: # define ALT_CONFIG_FILE "%windir%\\ntp.ini"
! 44: # endif /* SYS_WINNT */
! 45: #endif /* not CONFIG_FILE */
! 46:
! 47: /*
! 48: *
! 49: * We understand the following configuration entries and defaults.
! 50: *
! 51: * peer [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
! 52: * server [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
! 53: * keys file_name
! 54: */
! 55:
! 56: #define CONFIG_UNKNOWN 0
! 57:
! 58: #define CONFIG_PEER 1
! 59: #define CONFIG_SERVER 2
! 60: #define CONFIG_KEYS 8
! 61:
! 62: #define CONF_MOD_VERSION 1
! 63: #define CONF_MOD_KEY 2
! 64: #define CONF_MOD_MINPOLL 3
! 65: #define CONF_MOD_MAXPOLL 4
! 66: #define CONF_MOD_PREFER 5
! 67: #define CONF_MOD_BURST 6
! 68: #define CONF_MOD_SKEY 7
! 69: #define CONF_MOD_TTL 8
! 70: #define CONF_MOD_MODE 9
! 71:
! 72: /*
! 73: * Translation table - keywords to function index
! 74: */
! 75: struct keyword {
! 76: const char *text;
! 77: int keytype;
! 78: };
! 79:
! 80: /*
! 81: * Command keywords
! 82: */
! 83: static struct keyword keywords[] = {
! 84: { "peer", CONFIG_PEER },
! 85: { "server", CONFIG_SERVER },
! 86: { "keys", CONFIG_KEYS },
! 87: { "", CONFIG_UNKNOWN }
! 88: };
! 89:
! 90: /*
! 91: * "peer", "server", "broadcast" modifier keywords
! 92: */
! 93: static struct keyword mod_keywords[] = {
! 94: { "version", CONF_MOD_VERSION },
! 95: { "key", CONF_MOD_KEY },
! 96: { "minpoll", CONF_MOD_MINPOLL },
! 97: { "maxpoll", CONF_MOD_MAXPOLL },
! 98: { "prefer", CONF_MOD_PREFER },
! 99: { "burst", CONF_MOD_BURST },
! 100: { "autokey", CONF_MOD_SKEY },
! 101: { "mode", CONF_MOD_MODE }, /* reference clocks */
! 102: { "ttl", CONF_MOD_TTL }, /* NTP peers */
! 103: { "", CONFIG_UNKNOWN }
! 104: };
! 105:
! 106: /*
! 107: * Limits on things
! 108: */
! 109: #define MAXTOKENS 20 /* 20 tokens on line */
! 110: #define MAXLINE 1024 /* maximum length of line */
! 111: #define MAXFILENAME 128 /* maximum length of a file name (alloca()?) */
! 112:
! 113: /*
! 114: * Miscellaneous macros
! 115: */
! 116: #define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
! 117: #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
! 118: #define ISSPACE(c) ((c) == ' ' || (c) == '\t')
! 119: #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
! 120:
! 121: /*
! 122: * Systemwide parameters and flags
! 123: */
! 124: extern struct server **sys_servers; /* the server list */
! 125: extern int sys_numservers; /* number of servers to poll */
! 126: extern char *key_file;
! 127:
! 128: /*
! 129: * Function prototypes
! 130: */
! 131: static int gettokens P((FILE *, char *, char **, int *));
! 132: static int matchkey P((char *, struct keyword *));
! 133: static int getnetnum P((const char *num, struct sockaddr_in *addr,
! 134: int complain));
! 135:
! 136:
! 137: /*
! 138: * loadservers - load list of NTP servers from configuration file
! 139: */
! 140: void
! 141: loadservers(
! 142: char *cfgpath
! 143: )
! 144: {
! 145: register int i;
! 146: int errflg;
! 147: int peerversion;
! 148: int minpoll;
! 149: int maxpoll;
! 150: /* int ttl; */
! 151: int srvcnt;
! 152: /* u_long peerkey; */
! 153: int peerflags;
! 154: struct sockaddr_in peeraddr;
! 155: FILE *fp;
! 156: char line[MAXLINE];
! 157: char *(tokens[MAXTOKENS]);
! 158: int ntokens;
! 159: int tok;
! 160: const char *config_file;
! 161: #ifdef SYS_WINNT
! 162: char *alt_config_file;
! 163: LPTSTR temp;
! 164: char config_file_storage[MAX_PATH];
! 165: char alt_config_file_storage[MAX_PATH];
! 166: #endif /* SYS_WINNT */
! 167: struct server *server, *srvlist;
! 168:
! 169: /*
! 170: * Initialize, initialize
! 171: */
! 172: srvcnt = 0;
! 173: srvlist = 0;
! 174: errflg = 0;
! 175: #ifdef DEBUG
! 176: debug = 0;
! 177: #endif /* DEBUG */
! 178: #ifndef SYS_WINNT
! 179: config_file = cfgpath ? cfgpath : CONFIG_FILE;
! 180: #else
! 181: if (cfgpath) {
! 182: config_file = cfgpath;
! 183: } else {
! 184: temp = CONFIG_FILE;
! 185: if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) {
! 186: msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n");
! 187: exit(1);
! 188: }
! 189: config_file = config_file_storage;
! 190: }
! 191:
! 192: temp = ALT_CONFIG_FILE;
! 193: if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) {
! 194: msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n");
! 195: exit(1);
! 196: }
! 197: alt_config_file = alt_config_file_storage;
! 198: M
! 199: #endif /* SYS_WINNT */
! 200:
! 201: if ((fp = fopen(FindConfig(config_file), "r")) == NULL)
! 202: {
! 203: fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file));
! 204: msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file));
! 205: #ifdef SYS_WINNT
! 206: /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
! 207:
! 208: if ((fp = fopen(FindConfig(alt_config_file), "r")) == NULL) {
! 209:
! 210: /*
! 211: * Broadcast clients can sometimes run without
! 212: * a configuration file.
! 213: */
! 214:
! 215: fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file));
! 216: msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file));
! 217: return;
! 218: }
! 219: #else /* not SYS_WINNT */
! 220: return;
! 221: #endif /* not SYS_WINNT */
! 222: }
! 223:
! 224: while ((tok = gettokens(fp, line, tokens, &ntokens))
! 225: != CONFIG_UNKNOWN) {
! 226: switch(tok) {
! 227: case CONFIG_PEER:
! 228: case CONFIG_SERVER:
! 229:
! 230: if (ntokens < 2) {
! 231: msyslog(LOG_ERR,
! 232: "No address for %s, line ignored",
! 233: tokens[0]);
! 234: break;
! 235: }
! 236:
! 237: if (!getnetnum(tokens[1], &peeraddr, 1)) {
! 238: /* Resolve now, or lose! */
! 239: break;
! 240: } else {
! 241: errflg = 0;
! 242:
! 243: /* Shouldn't be able to specify multicast */
! 244: if (IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))
! 245: || ISBADADR(&peeraddr)) {
! 246: msyslog(LOG_ERR,
! 247: "attempt to configure invalid address %s",
! 248: ntoa(&peeraddr));
! 249: break;
! 250: }
! 251: }
! 252:
! 253: peerversion = NTP_VERSION;
! 254: minpoll = NTP_MINDPOLL;
! 255: maxpoll = NTP_MAXDPOLL;
! 256: /* peerkey = 0; */
! 257: peerflags = 0;
! 258: /* ttl = 0; */
! 259: for (i = 2; i < ntokens; i++)
! 260: switch (matchkey(tokens[i], mod_keywords)) {
! 261: case CONF_MOD_VERSION:
! 262: if (i >= ntokens-1) {
! 263: msyslog(LOG_ERR,
! 264: "peer/server version requires an argument");
! 265: errflg = 1;
! 266: break;
! 267: }
! 268: peerversion = atoi(tokens[++i]);
! 269: if ((u_char)peerversion > NTP_VERSION
! 270: || (u_char)peerversion < NTP_OLDVERSION) {
! 271: msyslog(LOG_ERR,
! 272: "inappropriate version number %s, line ignored",
! 273: tokens[i]);
! 274: errflg = 1;
! 275: }
! 276: break;
! 277:
! 278: case CONF_MOD_KEY:
! 279: if (i >= ntokens-1) {
! 280: msyslog(LOG_ERR,
! 281: "key: argument required");
! 282: errflg = 1;
! 283: break;
! 284: }
! 285: ++i;
! 286: /* peerkey = (int)atol(tokens[i]); */
! 287: peerflags |= FLAG_AUTHENABLE;
! 288: break;
! 289:
! 290: case CONF_MOD_MINPOLL:
! 291: if (i >= ntokens-1) {
! 292: msyslog(LOG_ERR,
! 293: "minpoll: argument required");
! 294: errflg = 1;
! 295: break;
! 296: }
! 297: minpoll = atoi(tokens[++i]);
! 298: if (minpoll < NTP_MINPOLL)
! 299: minpoll = NTP_MINPOLL;
! 300: break;
! 301:
! 302: case CONF_MOD_MAXPOLL:
! 303: if (i >= ntokens-1) {
! 304: msyslog(LOG_ERR,
! 305: "maxpoll: argument required"
! 306: );
! 307: errflg = 1;
! 308: break;
! 309: }
! 310: maxpoll = atoi(tokens[++i]);
! 311: if (maxpoll > NTP_MAXPOLL)
! 312: maxpoll = NTP_MAXPOLL;
! 313: break;
! 314:
! 315: case CONF_MOD_PREFER:
! 316: peerflags |= FLAG_PREFER;
! 317: break;
! 318:
! 319: case CONF_MOD_BURST:
! 320: peerflags |= FLAG_BURST;
! 321: break;
! 322:
! 323: case CONF_MOD_SKEY:
! 324: peerflags |= FLAG_SKEY | FLAG_AUTHENABLE;
! 325: break;
! 326:
! 327: case CONF_MOD_TTL:
! 328: if (i >= ntokens-1) {
! 329: msyslog(LOG_ERR,
! 330: "ttl: argument required");
! 331: errflg = 1;
! 332: break;
! 333: }
! 334: ++i;
! 335: /* ttl = atoi(tokens[i]); */
! 336: break;
! 337:
! 338: case CONF_MOD_MODE:
! 339: if (i >= ntokens-1) {
! 340: msyslog(LOG_ERR,
! 341: "mode: argument required");
! 342: errflg = 1;
! 343: break;
! 344: }
! 345: ++i;
! 346: /* ttl = atoi(tokens[i]); */
! 347: break;
! 348:
! 349: case CONFIG_UNKNOWN:
! 350: errflg = 1;
! 351: break;
! 352: }
! 353: if (minpoll > maxpoll) {
! 354: msyslog(LOG_ERR, "config error: minpoll > maxpoll");
! 355: errflg = 1;
! 356: }
! 357: if (errflg == 0) {
! 358: server = (struct server *)emalloc(sizeof(struct server));
! 359: memset((char *)server, 0, sizeof(struct server));
! 360: server->srcadr = peeraddr;
! 361: server->version = peerversion;
! 362: server->dispersion = PEER_MAXDISP;
! 363: server->next_server = srvlist;
! 364: srvlist = server;
! 365: srvcnt++;
! 366: }
! 367: break;
! 368:
! 369: case CONFIG_KEYS:
! 370: if (ntokens >= 2) {
! 371: key_file = (char *) emalloc(strlen(tokens[1]) + 1);
! 372: strcpy(key_file, tokens[1]);
! 373: }
! 374: break;
! 375: }
! 376: }
! 377: (void) fclose(fp);
! 378:
! 379: /* build final list */
! 380: sys_numservers = srvcnt;
! 381: sys_servers = (struct server **)
! 382: emalloc(sys_numservers * sizeof(struct server *));
! 383: for(i=0;i<sys_numservers;i++) {
! 384: sys_servers[i] = srvlist;
! 385: srvlist = srvlist->next_server;
! 386: }
! 387: }
! 388:
! 389:
! 390:
! 391: /*
! 392: * gettokens - read a line and return tokens
! 393: */
! 394: static int
! 395: gettokens(
! 396: FILE *fp,
! 397: char *line,
! 398: char **tokenlist,
! 399: int *ntokens
! 400: )
! 401: {
! 402: register char *cp;
! 403: register int eol;
! 404: register int ntok;
! 405: register int quoted = 0;
! 406:
! 407: /*
! 408: * Find start of first token
! 409: */
! 410: again:
! 411: while ((cp = fgets(line, MAXLINE, fp)) != NULL) {
! 412: cp = line;
! 413: while (ISSPACE(*cp))
! 414: cp++;
! 415: if (!ISEOL(*cp))
! 416: break;
! 417: }
! 418: if (cp == NULL) {
! 419: *ntokens = 0;
! 420: return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */
! 421: }
! 422:
! 423: /*
! 424: * Now separate out the tokens
! 425: */
! 426: eol = 0;
! 427: ntok = 0;
! 428: while (!eol) {
! 429: tokenlist[ntok++] = cp;
! 430: while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted))
! 431: quoted ^= (*cp++ == '"');
! 432:
! 433: if (ISEOL(*cp)) {
! 434: *cp = '\0';
! 435: eol = 1;
! 436: } else { /* must be space */
! 437: *cp++ = '\0';
! 438: while (ISSPACE(*cp))
! 439: cp++;
! 440: if (ISEOL(*cp))
! 441: eol = 1;
! 442: }
! 443: if (ntok == MAXTOKENS)
! 444: eol = 1;
! 445: }
! 446:
! 447: /*
! 448: * Return the match
! 449: */
! 450: *ntokens = ntok;
! 451: ntok = matchkey(tokenlist[0], keywords);
! 452: if (ntok == CONFIG_UNKNOWN)
! 453: goto again;
! 454: return ntok;
! 455: }
! 456:
! 457:
! 458:
! 459: /*
! 460: * matchkey - match a keyword to a list
! 461: */
! 462: static int
! 463: matchkey(
! 464: register char *word,
! 465: register struct keyword *keys
! 466: )
! 467: {
! 468: for (;;) {
! 469: if (keys->keytype == CONFIG_UNKNOWN) {
! 470: return CONFIG_UNKNOWN;
! 471: }
! 472: if (STRSAME(word, keys->text))
! 473: return keys->keytype;
! 474: keys++;
! 475: }
! 476: }
! 477:
! 478:
! 479: /*
! 480: * getnetnum - return a net number (this is crude, but careful)
! 481: */
! 482: static int
! 483: getnetnum(
! 484: const char *num,
! 485: struct sockaddr_in *addr,
! 486: int complain
! 487: )
! 488: {
! 489: register const char *cp;
! 490: register char *bp;
! 491: register int i;
! 492: register int temp;
! 493: char buf[80]; /* will core dump on really stupid stuff */
! 494: u_int32 netnum;
! 495:
! 496: /* XXX ELIMINATE replace with decodenetnum */
! 497: cp = num;
! 498: netnum = 0;
! 499: for (i = 0; i < 4; i++) {
! 500: bp = buf;
! 501: while (isdigit((int)*cp))
! 502: *bp++ = *cp++;
! 503: if (bp == buf)
! 504: break;
! 505:
! 506: if (i < 3) {
! 507: if (*cp++ != '.')
! 508: break;
! 509: } else if (*cp != '\0')
! 510: break;
! 511:
! 512: *bp = '\0';
! 513: temp = atoi(buf);
! 514: if (temp > 255)
! 515: break;
! 516: netnum <<= 8;
! 517: netnum += temp;
! 518: #ifdef DEBUG
! 519: if (debug > 3)
! 520: printf("getnetnum %s step %d buf %s temp %d netnum %lu\n",
! 521: num, i, buf, temp, (u_long)netnum);
! 522: #endif
! 523: }
! 524:
! 525: if (i < 4) {
! 526: if (complain)
! 527: msyslog(LOG_ERR,
! 528: "getnetnum: \"%s\" invalid host number, line ignored",
! 529: num);
! 530: #ifdef DEBUG
! 531: if (debug > 3)
! 532: printf(
! 533: "getnetnum: \"%s\" invalid host number, line ignored\n",
! 534: num);
! 535: #endif
! 536: return 0;
! 537: }
! 538:
! 539: /*
! 540: * make up socket address. Clear it out for neatness.
! 541: */
! 542: memset((void *)addr, 0, sizeof(struct sockaddr_in));
! 543: addr->sin_family = AF_INET;
! 544: addr->sin_port = htons(NTP_PORT);
! 545: addr->sin_addr.s_addr = htonl(netnum);
! 546: #ifdef DEBUG
! 547: if (debug > 1)
! 548: printf("getnetnum given %s, got %s (%lx)\n",
! 549: num, ntoa(addr), (u_long)netnum);
! 550: #endif
! 551: return 1;
! 552: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>