2 * ntp_config.c - read and apply configuration information
11 #include <sys/param.h>
12 #include <sys/types.h>
15 #define SIGCHLD SIGCLD
18 #ifdef HAVE_SYS_WAIT_H
25 #include <netinfo/ni.h>
30 #include "ntp_unixtime.h"
31 #include "ntp_refclock.h"
32 #include "ntp_filegen.h"
33 #include "ntp_stdlib.h"
37 extern HANDLE ResolverThreadHandle;
38 #endif /* SYS_WINNT */
41 * These routines are used to read the configuration file at
42 * startup time. An entry in the file must fit on a single line.
43 * Entries are processed as multiple tokens separated by white space
44 * Lines are considered terminated when a '#' is encountered. Blank
49 * Configuration file name
53 # define CONFIG_FILE "/etc/ntp.conf"
54 # else /* SYS_WINNT */
55 # define CONFIG_FILE "%windir%\\system32\\drivers\\etc\\ntp.conf"
56 # define ALT_CONFIG_FILE "%windir%\\ntp.conf"
57 # endif /* SYS_WINNT */
58 #endif /* not CONFIG_FILE */
61 * We understand the following configuration entries and defaults.
63 * peer [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
64 * server [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
65 * broadcast [ addr ] [ version 3 ] [ key 0 ] [ ttl 1 ]
67 * multicastclient [ 224.0.1.1 ]
68 * manycastclient [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
69 * manycastserver [ 224.0.1.1 ]
70 * broadcastdelay 0.0102
71 * restrict [ addr ] [ mask 255.255.255.0 ] ignore|noserve|notrust|noquery
75 * filegen peerstats [ file peerstats ] [ type day ] [ link ]
77 * clientperiod [ 3600 ]
82 * fudge [ addr ] [ stratum ] [ refid ] ...
86 * logconfig [+|-|=][{sync|sys|peer|clock}{{,all}{info|statistics|events|status}}]...
87 * enable auth|bclient|pll|kernel|monitor|stats
88 * disable auth|bclient|pll|kernel|monitor|stats
90 * pps device [assert|clear] [hardpps]
94 * Types of entries we understand.
96 #define CONFIG_UNKNOWN 0
99 #define CONFIG_SERVER 2
100 #define CONFIG_AUTOMAX 3
101 #define CONFIG_DRIFTFILE 4
102 #define CONFIG_BROADCAST 5
103 #define CONFIG_BROADCASTCLIENT 6
104 #define CONFIG_AUTHENTICATE 7
105 #define CONFIG_KEYS 8
106 #define CONFIG_REVOKE 9
107 #define CONFIG_PPS 10
108 #define CONFIG_RESTRICT 11
109 #define CONFIG_BDELAY 12
110 #define CONFIG_TRUSTEDKEY 13
111 #define CONFIG_REQUESTKEY 14
112 #define CONFIG_CONTROLKEY 15
113 #define CONFIG_TRAP 16
114 #define CONFIG_FUDGE 17
115 #define CONFIG_18 18 /* unused */
116 #define CONFIG_STATSDIR 19
117 #define CONFIG_FILEGEN 20
118 #define CONFIG_STATISTICS 21
119 #define CONFIG_PIDFILE 22
120 #define CONFIG_SETVAR 23
121 #define CONFIG_CLIENTLIMIT 24
122 #define CONFIG_CLIENTPERIOD 25
123 #define CONFIG_MULTICASTCLIENT 26
124 #define CONFIG_ENABLE 27
125 #define CONFIG_DISABLE 28
126 #define CONFIG_PHONE 29
127 #define CONFIG_LOGFILE 30
128 #define CONFIG_LOGCONFIG 31
129 #define CONFIG_MANYCASTCLIENT 32
130 #define CONFIG_MANYCASTSERVER 33
132 #define CONF_MOD_VERSION 1
133 #define CONF_MOD_KEY 2
134 #define CONF_MOD_MINPOLL 3
135 #define CONF_MOD_MAXPOLL 4
136 #define CONF_MOD_PREFER 5
137 #define CONF_MOD_BURST 6
138 #define CONF_MOD_SKEY 7
139 #define CONF_MOD_TTL 8
140 #define CONF_MOD_MODE 9
141 #define CONF_MOD_NOSELECT 10
143 #define CONF_RES_MASK 1
144 #define CONF_RES_IGNORE 2
145 #define CONF_RES_NOSERVE 3
146 #define CONF_RES_NOTRUST 4
147 #define CONF_RES_NOQUERY 5
148 #define CONF_RES_NOMODIFY 6
149 #define CONF_RES_NOPEER 7
150 #define CONF_RES_NOTRAP 8
151 #define CONF_RES_LPTRAP 9
152 #define CONF_RES_NTPPORT 10
153 #define CONF_RES_LIMITED 11
155 #define CONF_TRAP_PORT 1
156 #define CONF_TRAP_INTERFACE 2
158 #define CONF_FDG_TIME1 1
159 #define CONF_FDG_TIME2 2
160 #define CONF_FDG_STRATUM 3
161 #define CONF_FDG_REFID 4
162 #define CONF_FDG_FLAG1 5
163 #define CONF_FDG_FLAG2 6
164 #define CONF_FDG_FLAG3 7
165 #define CONF_FDG_FLAG4 8
167 #define CONF_FGEN_FILE 1
168 #define CONF_FGEN_TYPE 2
169 #define CONF_FGEN_FLAG_LINK 3
170 #define CONF_FGEN_FLAG_NOLINK 4
171 #define CONF_FGEN_FLAG_ENABLE 5
172 #define CONF_FGEN_FLAG_DISABLE 6
174 #define CONF_PPS_ASSERT 1
175 #define CONF_PPS_CLEAR 2
176 #define CONF_PPS_HARDPPS 3
179 * Translation table - keywords to function index
189 static struct keyword keywords[] = {
190 { "peer", CONFIG_PEER },
191 { "server", CONFIG_SERVER },
192 { "driftfile", CONFIG_DRIFTFILE },
193 { "broadcast", CONFIG_BROADCAST },
194 { "broadcastclient", CONFIG_BROADCASTCLIENT },
195 { "multicastclient", CONFIG_MULTICASTCLIENT },
196 { "manycastclient", CONFIG_MANYCASTCLIENT },
197 { "manycastserver", CONFIG_MANYCASTSERVER },
198 { "authenticate", CONFIG_AUTHENTICATE },
199 { "keys", CONFIG_KEYS },
200 { "revoke", CONFIG_REVOKE },
201 { "pps", CONFIG_PPS },
202 { "automax", CONFIG_AUTOMAX },
203 { "restrict", CONFIG_RESTRICT },
204 { "broadcastdelay", CONFIG_BDELAY },
205 { "trustedkey", CONFIG_TRUSTEDKEY },
206 { "requestkey", CONFIG_REQUESTKEY },
207 { "controlkey", CONFIG_CONTROLKEY },
208 { "trap", CONFIG_TRAP },
209 { "fudge", CONFIG_FUDGE },
210 { "statsdir", CONFIG_STATSDIR },
211 { "filegen", CONFIG_FILEGEN },
212 { "statistics", CONFIG_STATISTICS },
213 { "pidfile", CONFIG_PIDFILE },
214 { "setvar", CONFIG_SETVAR },
215 { "clientlimit", CONFIG_CLIENTLIMIT },
216 { "clientperiod", CONFIG_CLIENTPERIOD },
217 { "enable", CONFIG_ENABLE },
218 { "disable", CONFIG_DISABLE },
219 { "phone", CONFIG_PHONE },
220 { "logfile", CONFIG_LOGFILE },
221 { "logconfig", CONFIG_LOGCONFIG },
222 { "", CONFIG_UNKNOWN }
226 * "peer", "server", "broadcast" modifier keywords
228 static struct keyword mod_keywords[] = {
229 { "version", CONF_MOD_VERSION },
230 { "key", CONF_MOD_KEY },
231 { "minpoll", CONF_MOD_MINPOLL },
232 { "maxpoll", CONF_MOD_MAXPOLL },
233 { "prefer", CONF_MOD_PREFER },
234 { "noselect", CONF_MOD_NOSELECT },
235 { "burst", CONF_MOD_BURST },
236 { "autokey", CONF_MOD_SKEY },
237 { "mode", CONF_MOD_MODE }, /* reference clocks */
238 { "ttl", CONF_MOD_TTL }, /* NTP peers */
239 { "", CONFIG_UNKNOWN }
243 * "restrict" modifier keywords
245 static struct keyword res_keywords[] = {
246 { "mask", CONF_RES_MASK },
247 { "ignore", CONF_RES_IGNORE },
248 { "noserve", CONF_RES_NOSERVE },
249 { "notrust", CONF_RES_NOTRUST },
250 { "noquery", CONF_RES_NOQUERY },
251 { "nomodify", CONF_RES_NOMODIFY },
252 { "nopeer", CONF_RES_NOPEER },
253 { "notrap", CONF_RES_NOTRAP },
254 { "lowpriotrap", CONF_RES_LPTRAP },
255 { "ntpport", CONF_RES_NTPPORT },
256 { "limited", CONF_RES_LIMITED },
257 { "", CONFIG_UNKNOWN }
261 * "trap" modifier keywords
263 static struct keyword trap_keywords[] = {
264 { "port", CONF_TRAP_PORT },
265 { "interface", CONF_TRAP_INTERFACE },
266 { "", CONFIG_UNKNOWN }
271 * "fudge" modifier keywords
273 static struct keyword fudge_keywords[] = {
274 { "time1", CONF_FDG_TIME1 },
275 { "time2", CONF_FDG_TIME2 },
276 { "stratum", CONF_FDG_STRATUM },
277 { "refid", CONF_FDG_REFID },
278 { "flag1", CONF_FDG_FLAG1 },
279 { "flag2", CONF_FDG_FLAG2 },
280 { "flag3", CONF_FDG_FLAG3 },
281 { "flag4", CONF_FDG_FLAG4 },
282 { "", CONFIG_UNKNOWN }
287 * "filegen" modifier keywords
289 static struct keyword filegen_keywords[] = {
290 { "file", CONF_FGEN_FILE },
291 { "type", CONF_FGEN_TYPE },
292 { "link", CONF_FGEN_FLAG_LINK },
293 { "nolink", CONF_FGEN_FLAG_NOLINK },
294 { "enable", CONF_FGEN_FLAG_ENABLE },
295 { "disable", CONF_FGEN_FLAG_DISABLE },
296 { "", CONFIG_UNKNOWN }
300 * "type" modifier keywords
302 static struct keyword fgen_types[] = {
303 { "none", FILEGEN_NONE },
304 { "pid", FILEGEN_PID },
305 { "day", FILEGEN_DAY },
306 { "week", FILEGEN_WEEK },
307 { "month", FILEGEN_MONTH },
308 { "year", FILEGEN_YEAR },
309 { "age", FILEGEN_AGE },
310 { "", CONFIG_UNKNOWN}
314 * "enable", "disable" modifier keywords
316 static struct keyword flags_keywords[] = {
317 { "auth", PROTO_AUTHENTICATE },
318 { "bclient", PROTO_BROADCLIENT },
319 { "ntp", PROTO_NTP },
320 { "kernel", PROTO_KERNEL },
321 { "monitor", PROTO_MONITOR },
322 { "stats", PROTO_FILEGEN },
323 { "", CONFIG_UNKNOWN }
327 * pps modifier keywords
329 static struct keyword pps_keywords[] = {
330 { "assert", CONF_PPS_ASSERT },
331 { "clear", CONF_PPS_CLEAR },
332 { "hardpps", CONF_PPS_HARDPPS },
333 { "", CONFIG_UNKNOWN }
337 * "logconfig" building blocks
344 static struct masks logcfg_class[] = {
345 { "sys", NLOG_OSYS },
346 { "peer", NLOG_OPEER },
347 { "clock", NLOG_OCLOCK },
348 { "sync", NLOG_OSYNC },
352 static struct masks logcfg_item[] = {
353 { "info", NLOG_INFO },
354 { "allinfo", NLOG_SYSINFO|NLOG_PEERINFO|NLOG_CLOCKINFO|NLOG_SYNCINFO },
355 { "events", NLOG_EVENT },
356 { "allevents", NLOG_SYSEVENT|NLOG_PEEREVENT|NLOG_CLOCKEVENT|NLOG_SYNCEVENT },
357 { "status", NLOG_STATUS },
358 { "allstatus", NLOG_SYSSTATUS|NLOG_PEERSTATUS|NLOG_CLOCKSTATUS|NLOG_SYNCSTATUS },
359 { "statistics", NLOG_STATIST },
360 { "allstatistics", NLOG_SYSSTATIST|NLOG_PEERSTATIST|NLOG_CLOCKSTATIST|NLOG_SYNCSTATIST },
361 { "allclock", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OCLOCK },
362 { "allpeer", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OPEER },
363 { "allsys", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYS },
364 { "allsync", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYNC },
365 { "all", NLOG_SYSMASK|NLOG_PEERMASK|NLOG_CLOCKMASK|NLOG_SYNCMASK },
372 #define MAXTOKENS 20 /* 20 tokens on line */
373 #define MAXLINE 1024 /* maximum length of line */
374 #define MAXPHONE 5 /* maximum number of phone strings */
375 #define MAXPPS 20 /* maximum length of PPS device string */
376 #define MAXFILENAME 128 /* maximum length of a file name (alloca()?) */
380 * Miscellaneous macros
382 #define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
383 #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
384 #define ISSPACE(c) ((c) == ' ' || (c) == '\t')
385 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
388 * File descriptor used by the resolver save routines, and temporary file
393 static char res_file[20]; /* enough for /tmp/ntpXXXXXX\0 */
394 #define RES_TEMPFILE "/tmp/ntpXXXXXX"
396 static char res_file[MAX_PATH];
397 #endif /* SYS_WINNT */
400 * Definitions of things either imported from or exported to outside
402 char const *progname;
403 char sys_phone[MAXPHONE][MAXDIAL]; /* ACTS phone numbers */
404 char pps_device[MAXPPS + 1]; /* PPS device name */
407 int listen_to_virtual_ips = 0;
408 #if defined(HAVE_SCHED_SETSCHEDULER)
409 int config_priority_override = 0;
413 static const char *ntp_options = "aAbc:dD:f:gk:l:Lmnp:P:r:s:t:v:V:x";
417 * NetInfo configuration state
419 struct netinfo_config_state {
420 void *domain; /* domain with config */
421 ni_id config_dir; /* ID config dir */
422 int prop_index; /* current property */
423 int val_index; /* current value */
424 char **val_list; /* value list */
429 * Function prototypes
431 static unsigned long get_pfxmatch P((char **, struct masks *));
432 static unsigned long get_match P((char *, struct masks *));
433 static unsigned long get_logmask P((char *));
435 static struct netinfo_config_state *get_netinfo_config P((void));
436 static void free_netinfo_config P((struct netinfo_config_state *));
437 static int gettokens_netinfo P((struct netinfo_config_state *, char **, int *));
439 static int gettokens P((FILE *, char *, char **, int *));
440 static int matchkey P((char *, struct keyword *));
441 static int getnetnum P((const char *, struct sockaddr_in *, int));
442 static void save_resolve P((char *, int, int, int, int, int, int, u_long));
443 static void do_resolve_internal P((void));
444 static void abort_resolve P((void));
446 static RETSIGTYPE catchchild P((int));
450 * get_pfxmatch - find value for prefixmatch
451 * and update char * accordingly
460 if (strncmp(*s, m->name, strlen(m->name)) == 0) {
461 *s += strlen(m->name);
471 * get_match - find logmask value
480 if (strcmp(s, m->name) == 0) {
490 * get_logmask - build bitmask for ntp_syslogmask
498 unsigned long offset;
502 offset = get_pfxmatch(&t, logcfg_class);
503 mask = get_match(t, logcfg_item);
506 return mask << offset;
508 msyslog(LOG_ERR, "logconfig: illegal argument %s - ignored", s);
514 * getstartup - search through the options looking for a debugging flag
526 debug = 0; /* no debugging by default */
530 * This is a big hack. We don't really want to read command line
531 * configuration until everything else is initialized, since
532 * the ability to configure the system may depend on storage
533 * and the like having been initialized. Except that we also
534 * don't want to initialize anything until after detaching from
535 * the terminal, but we won't know to do that until we've
536 * parsed the command line. Do that now, crudely, and do it
537 * again later. Our ntp_getopt() is explicitly reusable, by the
538 * way. Your own mileage may vary.
540 * This hack is even called twice (to allow complete logging to file)
546 * Decode argument list
548 while ((c = ntp_getopt(argc, argv, ntp_options)) != EOF)
555 debug = (int)atol(ntp_optarg);
556 printf("Debug1: %s -> %x = %d\n", ntp_optarg, debug, debug);
561 msyslog(LOG_ERR, "ntpd not compiled with -DDEBUG option - no DEBUG support");
562 fprintf(stderr, "ntpd not compiled with -DDEBUG option - no DEBUG support");
567 listen_to_virtual_ips = 1;
573 new_file = fopen(ntp_optarg, "a");
574 if (new_file != NULL) {
576 msyslog(LOG_NOTICE, "logging to file %s", ntp_optarg);
577 if (syslog_file != NULL &&
578 fileno(syslog_file) != fileno(new_file))
579 (void)fclose(syslog_file);
581 syslog_file = new_file;
586 "Cannot open log file %s",
603 if (errflg || ntp_optind != argc) {
604 (void) fprintf(stderr, "usage: %s [ -abdgmnx ] [ -c config_file ] [ -e e_delay ]\n", progname);
605 (void) fprintf(stderr, "\t\t[ -f freq_file ] [ -k key_file ] [ -l log_file ]\n");
606 (void) fprintf(stderr, "\t\t[ -p pid_file ] [ -r broad_delay ] [ -s statdir ]\n");
607 (void) fprintf(stderr, "\t\t[ -t trust_key ] [ -v sys_var ] [ -V default_sysvar ]\n");
608 #if defined(HAVE_SCHED_SETSCHEDULER)
609 (void) fprintf(stderr, "\t\t[ -P fixed_process_priority ]\n");
613 ntp_optind = 0; /* reset ntp_optind to restart ntp_getopt */
618 static char buf[BUFSIZ];
619 setvbuf(stdout, buf, _IOLBF, BUFSIZ);
628 * getconfig - get command line options and read the configuration file
647 struct sockaddr_in peeraddr;
648 struct sockaddr_in maskaddr;
651 char *(tokens[MAXTOKENS]);
653 int tok = CONFIG_UNKNOWN;
654 struct interface *localaddr;
655 const char *config_file;
657 struct netinfo_config_state *config_netinfo = NULL;
658 int check_netinfo = 1;
659 #endif /* HAVE_NETINFO */
661 char *alt_config_file;
663 char config_file_storage[MAX_PATH];
664 char alt_config_file_storage[MAX_PATH];
665 #endif /* SYS_WINNT */
666 struct refclockstat clock_stat;
670 * Initialize, initialize
677 config_file = CONFIG_FILE;
680 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) {
681 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n");
684 config_file = config_file_storage;
686 temp = ALT_CONFIG_FILE;
687 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) {
688 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n");
691 alt_config_file = alt_config_file_storage;
693 #endif /* SYS_WINNT */
696 memset((char *)sys_phone, 0, sizeof(sys_phone));
697 ntp_syslogmask = NLOG_SYNCMASK; /* set more via logconfig */
700 * install a non default variable with this daemon version
702 (void) sprintf(line, "daemon_version=\"%s\"", Version);
703 set_sys_var(line, strlen(line)+1, RO);
706 * Say how we're setting the time of day
708 (void) sprintf(line, "settimeofday=\"%s\"", set_tod_using);
709 set_sys_var(line, strlen(line)+1, RO);
712 * Initialize the loop.
714 loop_config(LOOP_DRIFTINIT, 0.);
717 * Decode argument list
719 while ((c = ntp_getopt(argc, argv, ntp_options)) != EOF) {
722 proto_config(PROTO_AUTHENTICATE, 1, 0.);
726 proto_config(PROTO_AUTHENTICATE, 0, 0.);
730 proto_config(PROTO_BROADCLIENT, 1, 0.);
734 config_file = ntp_optarg;
750 debug = (int)atol(ntp_optarg);
751 printf("Debug2: %s -> %x = %d\n", ntp_optarg, debug, debug);
758 stats_config(STATS_FREQ_FILE, ntp_optarg);
766 getauthkeys(ntp_optarg);
769 case 'L': /* already done at pre-scan */
770 case 'l': /* already done at pre-scan */
774 proto_config(PROTO_MULTICAST_ADD, htonl(INADDR_NTP), 0.);
778 case 'n': /* already done at pre-scan */
782 stats_config(STATS_PID_FILE, ntp_optarg);
786 #if defined(HAVE_SCHED_SETSCHEDULER)
787 config_priority = (int)atol(ntp_optarg);
788 config_priority_override = 1;
798 if (sscanf(ntp_optarg, "%lf", &tmp) != 1) {
800 "command line broadcast delay value %s undecodable",
803 proto_config(PROTO_BROADDELAY, 0, tmp);
809 stats_config(STATS_STATSDIR, ntp_optarg);
816 tkey = (int)atol(ntp_optarg);
817 if (tkey <= 0 || tkey > NTP_MAXKEY) {
819 "command line trusted key %s is invalid",
829 set_sys_var(ntp_optarg, strlen(ntp_optarg)+1,
830 RW | ((c == 'V') ? DEF : 0));
834 allow_set_backward = FALSE;
843 if (errflg || ntp_optind != argc) {
844 (void) fprintf(stderr, "usage: %s [ -abdgmnx ] [ -c config_file ] [ -e e_delay ]\n", progname);
845 (void) fprintf(stderr, "\t\t[ -f freq_file ] [ -k key_file ] [ -l log_file ]\n");
846 (void) fprintf(stderr, "\t\t[ -p pid_file ] [ -r broad_delay ] [ -s statdir ]\n");
847 (void) fprintf(stderr, "\t\t[ -t trust_key ] [ -v sys_var ] [ -V default_sysvar ]\n");
848 #if defined(HAVE_SCHED_SETSCHEDULER)
849 (void) fprintf(stderr, "\t\t[ -P fixed_process_priority ]\n");
855 (fp = fopen(FindConfig(config_file), "r")) == NULL
857 /* If there is no config_file, try NetInfo. */
858 && check_netinfo && !(config_netinfo = get_netinfo_config())
859 #endif /* HAVE_NETINFO */
861 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file));
862 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file));
864 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
866 if ((fp = fopen(FindConfig(alt_config_file), "r")) == NULL) {
869 * Broadcast clients can sometimes run without
870 * a configuration file.
873 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file));
874 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file));
877 #else /* not SYS_WINNT */
879 #endif /* not SYS_WINNT */
884 tok = gettokens(fp, line, tokens, &ntokens);
887 tok = gettokens_netinfo(config_netinfo, tokens, &ntokens);
888 #endif /* HAVE_NETINFO */
890 if (tok == CONFIG_UNKNOWN) break;
895 case CONFIG_MANYCASTCLIENT:
896 case CONFIG_BROADCAST:
897 if (tok == CONFIG_PEER)
899 else if (tok == CONFIG_SERVER)
901 else if (tok == CONFIG_MANYCASTCLIENT)
904 hmode = MODE_BROADCAST;
908 "No address for %s, line ignored",
913 if (!getnetnum(tokens[1], &peeraddr, 0)) {
920 !ISREFCLOCKADR(&peeraddr) &&
922 ISBADADR(&peeraddr)) {
924 "attempt to configure invalid address %s",
929 * Shouldn't be able to specify multicast
930 * address for server/peer!
931 * and unicast address for manycastclient!
933 if (((tok == CONFIG_SERVER) ||
934 (tok == CONFIG_PEER)) &&
936 !ISREFCLOCKADR(&peeraddr) &&
938 IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))) {
940 "attempt to configure invalid address %s",
944 if ((tok == CONFIG_MANYCASTCLIENT) &&
945 !IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))) {
947 "attempt to configure invalid address %s",
953 peerversion = NTP_VERSION;
954 minpoll = NTP_MINDPOLL;
955 maxpoll = NTP_MAXDPOLL;
959 for (i = 2; i < ntokens; i++)
960 switch (matchkey(tokens[i], mod_keywords)) {
961 case CONF_MOD_VERSION:
962 if (i >= ntokens-1) {
964 "peer/server version requires an argument");
968 peerversion = atoi(tokens[++i]);
969 if ((u_char)peerversion > NTP_VERSION
970 || (u_char)peerversion < NTP_OLDVERSION) {
972 "inappropriate version number %s, line ignored",
979 if (i >= ntokens-1) {
981 "key: argument required");
985 peerkey = (int)atol(tokens[++i]);
986 peerflags |= FLAG_AUTHENABLE;
989 case CONF_MOD_MINPOLL:
990 if (i >= ntokens-1) {
992 "minpoll: argument required");
996 minpoll = atoi(tokens[++i]);
997 if (minpoll < NTP_MINPOLL)
998 minpoll = NTP_MINPOLL;
1001 case CONF_MOD_MAXPOLL:
1002 if (i >= ntokens-1) {
1004 "maxpoll: argument required"
1009 maxpoll = atoi(tokens[++i]);
1010 if (maxpoll > NTP_MAXPOLL)
1011 maxpoll = NTP_MAXPOLL;
1014 case CONF_MOD_PREFER:
1015 peerflags |= FLAG_PREFER;
1018 case CONF_MOD_NOSELECT:
1019 peerflags |= FLAG_NOSELECT;
1022 case CONF_MOD_BURST:
1023 peerflags |= FLAG_BURST;
1027 peerflags |= FLAG_SKEY | FLAG_AUTHENABLE;
1031 if (i >= ntokens-1) {
1033 "ttl: argument required");
1037 ttl = atoi(tokens[++i]);
1041 if (i >= ntokens-1) {
1043 "mode: argument required");
1047 ttl = atoi(tokens[++i]);
1050 case CONFIG_UNKNOWN:
1054 if (minpoll > maxpoll) {
1055 msyslog(LOG_ERR, "config error: minpoll > maxpoll");
1059 if (peer_config(&peeraddr,
1060 (struct interface *)0, hmode,
1061 peerversion, minpoll, maxpoll,
1062 peerflags, ttl, peerkey)
1065 "configuration of %s failed",
1068 } else if (errflg == -1) {
1069 save_resolve(tokens[1], hmode, peerversion,
1070 minpoll, maxpoll, peerflags, ttl,
1075 case CONFIG_DRIFTFILE:
1077 stats_config(STATS_FREQ_FILE, tokens[1]);
1079 stats_config(STATS_FREQ_FILE, (char *)0);
1082 case CONFIG_PIDFILE:
1084 stats_config(STATS_PID_FILE, tokens[1]);
1086 stats_config(STATS_PID_FILE, (char *)0);
1089 case CONFIG_LOGFILE:
1092 new_file = fopen(tokens[1], "a");
1093 if (new_file != NULL) {
1094 NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
1095 msyslog(LOG_NOTICE, "logging to file %s", tokens[1]);
1096 if (syslog_file != NULL &&
1097 fileno(syslog_file) != fileno(new_file))
1098 (void)fclose(syslog_file);
1100 syslog_file = new_file;
1105 "Cannot open log file %s",
1109 msyslog(LOG_ERR, "logfile needs one argument");
1112 case CONFIG_LOGCONFIG:
1113 for (i = 1; i < ntokens; i++)
1117 char * s = &tokens[i][0];
1132 ntp_syslogmask = get_logmask(s);
1135 ntp_syslogmask |= get_logmask(s);
1137 ntp_syslogmask &= ~get_logmask(s);
1142 printf("ntp_syslogmask = 0x%08lx (%s)\n", ntp_syslogmask, tokens[i]);
1147 case CONFIG_BROADCASTCLIENT:
1148 proto_config(PROTO_BROADCLIENT, 1, 0.);
1151 case CONFIG_MULTICASTCLIENT:
1152 case CONFIG_MANYCASTSERVER:
1154 for (i = 1; i < ntokens; i++) {
1155 if (getnetnum(tokens[i], &peeraddr, 1))
1156 proto_config(PROTO_MULTICAST_ADD,
1157 peeraddr.sin_addr.s_addr, 0.);
1160 proto_config(PROTO_MULTICAST_ADD,
1161 htonl(INADDR_NTP), 0.);
1162 if (tok == CONFIG_MULTICASTCLIENT) {
1166 printf("sys_bclient\n");
1169 else if (tok == CONFIG_MANYCASTSERVER) {
1170 sys_manycastserver = 1;
1173 printf("sys_manycastserver\n");
1178 case CONFIG_AUTHENTICATE:
1181 if (STREQ(tokens[1], "yes"))
1182 proto_config(PROTO_AUTHENTICATE, 1, 0.);
1183 else if (STREQ(tokens[1], "no"))
1184 proto_config(PROTO_AUTHENTICATE, 0, 0.);
1193 "should be `authenticate yes|no'");
1198 getauthkeys(tokens[1]);
1204 sys_revoke = 1 << max(atoi(tokens[1]), 10);
1208 case CONFIG_AUTOMAX:
1210 sys_automax = 1 << max(atoi(tokens[1]), 10);
1214 case CONFIG_RESTRICT:
1216 msyslog(LOG_ERR, "restrict requires an address");
1219 if (STREQ(tokens[1], "default"))
1220 peeraddr.sin_addr.s_addr = htonl(INADDR_ANY);
1221 else if (!getnetnum(tokens[1], &peeraddr, 1))
1225 * Use peerversion as flags, peerkey as mflags. Ick.
1230 maskaddr.sin_addr.s_addr = ~(u_int32)0;
1231 for (i = 2; i < ntokens; i++) {
1232 switch (matchkey(tokens[i], res_keywords)) {
1234 if (i >= ntokens-1) {
1236 "mask keyword needs argument");
1241 if (!getnetnum(tokens[i], &maskaddr, 1))
1245 case CONF_RES_IGNORE:
1246 peerversion |= RES_IGNORE;
1249 case CONF_RES_NOSERVE:
1250 peerversion |= RES_DONTSERVE;
1253 case CONF_RES_NOTRUST:
1254 peerversion |= RES_DONTTRUST;
1257 case CONF_RES_NOQUERY:
1258 peerversion |= RES_NOQUERY;
1261 case CONF_RES_NOMODIFY:
1262 peerversion |= RES_NOMODIFY;
1265 case CONF_RES_NOPEER:
1266 peerversion |= RES_NOPEER;
1269 case CONF_RES_NOTRAP:
1270 peerversion |= RES_NOTRAP;
1273 case CONF_RES_LPTRAP:
1274 peerversion |= RES_LPTRAP;
1277 case CONF_RES_NTPPORT:
1278 peerkey |= RESM_NTPONLY;
1281 case CONF_RES_LIMITED:
1282 peerversion |= RES_LIMITED;
1285 case CONFIG_UNKNOWN:
1290 if (SRCADR(&peeraddr) == htonl(INADDR_ANY))
1291 maskaddr.sin_addr.s_addr = 0;
1293 hack_restrict(RESTRICT_FLAGS, &peeraddr, &maskaddr,
1294 (int)peerkey, peerversion);
1301 if (sscanf(tokens[1], "%lf", &tmp) != 1) {
1303 "broadcastdelay value %s undecodable",
1306 proto_config(PROTO_BROADDELAY, 0, tmp);
1311 case CONFIG_TRUSTEDKEY:
1312 for (i = 1; i < ntokens; i++) {
1315 tkey = atol(tokens[i]);
1318 "trusted key %s unlikely",
1326 case CONFIG_REQUESTKEY:
1330 if (!atouint(tokens[1], &rkey)) {
1332 "%s is undecodable as request key",
1334 } else if (rkey == 0) {
1336 "%s makes a poor request keyid",
1342 "set info_auth_key to %lu\n", rkey);
1344 info_auth_keyid = rkey;
1349 case CONFIG_CONTROLKEY:
1353 ckey = atol(tokens[1]);
1356 "%s makes a poor control keyid",
1359 ctl_auth_keyid = ckey;
1367 "no address for trap command, line ignored");
1370 if (!getnetnum(tokens[1], &peeraddr, 1))
1374 * Use peerversion for port number. Barf.
1379 for (i = 2; i < ntokens-1; i++)
1380 switch (matchkey(tokens[i], trap_keywords)) {
1381 case CONF_TRAP_PORT:
1382 if (i >= ntokens-1) {
1384 "trap port requires an argument");
1388 peerversion = atoi(tokens[++i]);
1389 if (peerversion <= 0
1390 || peerversion > 32767) {
1392 "invalid port number %s, trap ignored",
1398 case CONF_TRAP_INTERFACE:
1399 if (i >= ntokens-1) {
1401 "trap interface requires an argument");
1406 if (!getnetnum(tokens[++i],
1412 localaddr = findinterface(&maskaddr);
1413 if (localaddr == NULL) {
1415 "can't find interface with address %s",
1421 case CONFIG_UNKNOWN:
1427 if (peerversion != 0)
1428 peeraddr.sin_port = htons( (u_short) peerversion);
1430 peeraddr.sin_port = htons(TRAPPORT);
1431 if (localaddr == NULL)
1432 localaddr = any_interface;
1433 if (!ctlsettrap(&peeraddr, localaddr, 0,
1436 "can't set trap for %s, no resources",
1444 "no address for fudge command, line ignored");
1447 if (!getnetnum(tokens[1], &peeraddr, 1))
1450 if (!ISREFCLOCKADR(&peeraddr)) {
1452 "%s is inappropriate address for the fudge command, line ignored",
1457 memset((void *)&clock_stat, 0, sizeof clock_stat);
1459 for (i = 2; i < ntokens-1; i++) {
1460 switch (c = matchkey(tokens[i],
1462 case CONF_FDG_TIME1:
1463 if (sscanf(tokens[++i], "%lf",
1464 &clock_stat.fudgetime1) != 1) {
1466 "fudge %s time1 value in error",
1471 clock_stat.haveflags |= CLK_HAVETIME1;
1474 case CONF_FDG_TIME2:
1475 if (sscanf(tokens[++i], "%lf",
1476 &clock_stat.fudgetime2) != 1) {
1478 "fudge %s time2 value in error",
1483 clock_stat.haveflags |= CLK_HAVETIME2;
1487 case CONF_FDG_STRATUM:
1488 /* HMS: the (long *)_ may be trouble */
1489 if (!atoint(tokens[++i],
1490 (long *)&clock_stat.fudgeval1))
1493 "fudge %s stratum value in error",
1498 clock_stat.haveflags |= CLK_HAVEVAL1;
1501 case CONF_FDG_REFID:
1502 /* HMS: Endianness and 0 bytes? */
1504 strncpy((char *)&clock_stat.fudgeval2,
1506 clock_stat.haveflags |= CLK_HAVEVAL2;
1509 case CONF_FDG_FLAG1:
1510 case CONF_FDG_FLAG2:
1511 case CONF_FDG_FLAG3:
1512 case CONF_FDG_FLAG4:
1513 if (!atouint(tokens[++i], &lpeerkey)
1516 "fudge %s flag value in error",
1524 case CONF_FDG_FLAG1:
1526 clock_stat.haveflags|=CLK_HAVEFLAG1;
1528 case CONF_FDG_FLAG2:
1530 clock_stat.haveflags|=CLK_HAVEFLAG2;
1532 case CONF_FDG_FLAG3:
1534 clock_stat.haveflags|=CLK_HAVEFLAG3;
1536 case CONF_FDG_FLAG4:
1538 clock_stat.haveflags|=CLK_HAVEFLAG4;
1542 clock_stat.flags &= ~c;
1544 clock_stat.flags |= c;
1547 case CONFIG_UNKNOWN:
1555 * If reference clock support isn't defined the
1556 * fudge line will still be accepted and syntax
1557 * checked, but will essentially do nothing.
1560 refclock_control(&peeraddr, &clock_stat,
1561 (struct refclockstat *)0);
1566 case CONFIG_STATSDIR:
1568 stats_config(STATS_STATSDIR,tokens[1]);
1572 case CONFIG_STATISTICS:
1573 for (i = 1; i < ntokens; i++) {
1574 filegen = filegen_get(tokens[i]);
1576 if (filegen == NULL) {
1578 "no statistics named %s available",
1584 printf("enabling filegen for %s statistics \"%s%s\"\n",
1585 tokens[i], filegen->prefix, filegen->basename);
1587 filegen->flag |= FGEN_FLAG_ENABLED;
1591 case CONFIG_FILEGEN:
1594 "no id for filegen command, line ignored");
1598 filegen = filegen_get(tokens[1]);
1599 if (filegen == NULL) {
1601 "unknown filegen \"%s\" ignored",
1606 * peerversion is (ab)used for filegen file (index)
1607 * peerkey is (ab)used for filegen type
1608 * peerflags is (ab)used for filegen flags
1611 peerkey = filegen->type;
1612 peerflags = filegen->flag;
1615 for (i = 2; i < ntokens; i++) {
1616 switch (matchkey(tokens[i], filegen_keywords)) {
1617 case CONF_FGEN_FILE:
1618 if (i >= ntokens - 1) {
1620 "filegen %s file requires argument",
1627 case CONF_FGEN_TYPE:
1628 if (i >= ntokens -1) {
1630 "filegen %s type requires argument",
1635 peerkey = matchkey(tokens[++i], fgen_types);
1636 if (peerkey == CONFIG_UNKNOWN) {
1638 "filegen %s unknown type \"%s\"",
1639 tokens[1], tokens[i]);
1645 case CONF_FGEN_FLAG_LINK:
1646 peerflags |= FGEN_FLAG_LINK;
1649 case CONF_FGEN_FLAG_NOLINK:
1650 peerflags &= ~FGEN_FLAG_LINK;
1653 case CONF_FGEN_FLAG_ENABLE:
1654 peerflags |= FGEN_FLAG_ENABLED;
1657 case CONF_FGEN_FLAG_DISABLE:
1658 peerflags &= ~FGEN_FLAG_ENABLED;
1663 filegen_config(filegen, tokens[peerversion],
1664 (u_char)peerkey, (u_char)peerflags);
1671 "no value for setvar command - line ignored");
1673 set_sys_var(tokens[1], strlen(tokens[1])+1,
1676 && !strcmp(tokens[2],
1683 case CONFIG_CLIENTLIMIT:
1686 "no value for clientlimit command - line ignored");
1690 if (!atouint(tokens[1], &ui) || !ui) {
1692 "illegal value for clientlimit command - line ignored");
1698 sprintf(bp, "client_limit=%lu", ui);
1700 set_sys_var(bp, strlen(bp)+1, RO);
1706 case CONFIG_CLIENTPERIOD:
1709 "no value for clientperiod command - line ignored");
1713 if (!atouint(tokens[1], &ui) || ui < 64) {
1715 "illegal value for clientperiod command - line ignored");
1719 sprintf(bp, "client_limit_period=%ld", ui);
1720 set_sys_var(bp, strlen(bp)+1, RO);
1721 client_limit_period = ui;
1727 for (i = 1; i < ntokens; i++) {
1730 flag = matchkey(tokens[i], flags_keywords);
1731 if (flag == CONFIG_UNKNOWN) {
1733 "enable unknown flag %s",
1738 proto_config(flag, 1, 0.);
1742 case CONFIG_DISABLE:
1743 for (i = 1; i < ntokens; i++) {
1746 flag = matchkey(tokens[i], flags_keywords);
1747 if (flag == CONFIG_UNKNOWN) {
1749 "disable unknown flag %s",
1754 proto_config(flag, 0, 0.);
1759 for (i = 1; i < ntokens && i < MAXPHONE; i++) {
1760 (void)strncpy(sys_phone[i - 1],
1761 tokens[i], MAXDIAL);
1763 sys_phone[i - 1][0] = '\0';
1769 "pps missing device name");
1772 (void)strncpy(pps_device, tokens[1], MAXPPS);
1773 for (i = 2; i < ntokens; i++) {
1776 flag = matchkey(tokens[i], pps_keywords);
1778 case CONF_PPS_ASSERT:
1781 case CONF_PPS_CLEAR:
1784 case CONF_PPS_HARDPPS:
1789 "pps unknown flag %s",
1800 if (fp) (void)fclose(fp);
1802 if (config_netinfo) free_netinfo_config(config_netinfo);
1803 #endif /* HAVE_NETINFO */
1805 if (res_fp != NULL) {
1807 * Need name resolution
1809 do_resolve_internal();
1817 * get_netinfo_config - find the nearest NetInfo domain with an ntp
1818 * configuration and initialize the configuration state.
1820 static struct netinfo_config_state *
1821 get_netinfo_config()
1826 struct netinfo_config_state *config;
1828 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL;
1830 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) {
1832 if (ni_open(domain, "..", &next_domain) != NI_OK) {
1833 ni_free(next_domain);
1837 domain = next_domain;
1839 if (status != NI_OK) {
1844 config = (struct netinfo_config_state *)malloc(sizeof(struct netinfo_config_state));
1845 config->domain = domain;
1846 config->config_dir = config_dir;
1847 config->prop_index = 0;
1848 config->val_index = 0;
1849 config->val_list = NULL;
1857 * free_netinfo_config - release NetInfo configuration state
1860 free_netinfo_config(struct netinfo_config_state *config)
1862 ni_free(config->domain);
1869 * gettokens_netinfo - return tokens from NetInfo
1873 struct netinfo_config_state *config,
1878 int prop_index = config->prop_index;
1879 int val_index = config->val_index;
1880 char **val_list = config->val_list;
1883 * Iterate through each keyword and look for a property that matches it.
1887 for (; prop_index < (sizeof(keywords)/sizeof(keywords[0])); prop_index++)
1889 ni_namelist namelist;
1890 struct keyword current_prop = keywords[prop_index];
1893 * For each value associated in the property, we're going to return
1894 * a separate line. We squirrel away the values in the config state
1895 * so the next time through, we don't need to do this lookup.
1898 if (ni_lookupprop(config->domain, &config->config_dir, current_prop.text, &namelist) == NI_OK) {
1901 /* Found the property, but it has no values */
1902 if (namelist.ni_namelist_len == 0) continue;
1904 if (! (val_list = config->val_list = (char**)malloc(sizeof(char*) * (namelist.ni_namelist_len + 1))))
1905 { msyslog(LOG_ERR, "out of memory while configuring"); break; }
1907 for (index = 0; index < namelist.ni_namelist_len; index++) {
1908 char *value = namelist.ni_namelist_val[index];
1910 if (! (val_list[index] = (char*)malloc(strlen(value+1))))
1911 { msyslog(LOG_ERR, "out of memory while configuring"); break; }
1913 strcpy(val_list[index], value);
1915 val_list[index] = NULL;
1919 ni_namelist_free(&namelist);
1921 config->prop_index = prop_index;
1924 /* No list; we're done here. */
1925 if (!val_list) return CONFIG_UNKNOWN;
1928 * We have a list of values for the current property.
1929 * Iterate through them and return each in order.
1931 if (val_list[val_index])
1935 char *tokens = val_list[val_index];
1937 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]);
1939 (const char*)tokenlist[0] = keywords[prop_index].text;
1940 for (ntok = 1; ntok < MAXTOKENS; ntok++) {
1941 tokenlist[ntok] = tokens;
1942 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted))
1943 quoted ^= (*tokens++ == '"');
1945 if (ISEOL(*tokens)) {
1948 } else { /* must be space */
1950 while (ISSPACE(*tokens)) tokens++;
1951 if (ISEOL(*tokens)) break;
1954 *ntokens = ntok + 1;
1956 config->val_index++;
1958 return keywords[prop_index].keytype;
1961 /* We're done with the current property. */
1962 prop_index = ++config->prop_index;
1964 /* Free val_list and reset counters. */
1965 for (val_index = 0; val_list[val_index]; val_index++)
1966 free(val_list[val_index]);
1967 free(val_list); val_list = config->val_list = NULL; val_index = config->val_index = 0;
1972 #endif /* HAVE_NETINFO */
1976 * gettokens - read a line and return tokens
1988 register int quoted = 0;
1991 * Find start of first token
1994 while ((cp = fgets(line, MAXLINE, fp)) != NULL) {
1996 while (ISSPACE(*cp))
2003 return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */
2007 * Now separate out the tokens
2009 for (ntok = 0; ntok < MAXTOKENS; ntok++) {
2010 tokenlist[ntok] = cp;
2011 while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted))
2012 quoted ^= (*cp++ == '"');
2017 } else { /* must be space */
2019 while (ISSPACE(*cp))
2029 *ntokens = ntok + 1;
2030 ntok = matchkey(tokenlist[0], keywords);
2031 if (ntok == CONFIG_UNKNOWN)
2039 * matchkey - match a keyword to a list
2043 register char *word,
2044 register struct keyword *keys
2048 if (keys->keytype == CONFIG_UNKNOWN) {
2050 "configure: keyword \"%s\" unknown, line ignored",
2052 return CONFIG_UNKNOWN;
2054 if (STRSAME(word, keys->text))
2055 return keys->keytype;
2062 * getnetnum - return a net number (this is crude, but careful)
2067 struct sockaddr_in *addr,
2071 register const char *cp;
2075 char buf[80]; /* will core dump on really stupid stuff */
2078 /* XXX ELIMINATE replace with decodenetnum */
2081 for (i = 0; i < 4; i++) {
2083 while (isdigit((int)*cp))
2091 } else if (*cp != '\0')
2102 printf("getnetnum %s step %d buf %s temp %d netnum %lu\n",
2103 num, i, buf, temp, (u_long)netnum);
2110 "getnetnum: \"%s\" invalid host number, line ignored",
2115 "getnetnum: \"%s\" invalid host number, line ignored\n",
2122 * make up socket address. Clear it out for neatness.
2124 memset((void *)addr, 0, sizeof(struct sockaddr_in));
2125 addr->sin_family = AF_INET;
2126 addr->sin_port = htons(NTP_PORT);
2127 addr->sin_addr.s_addr = htonl(netnum);
2130 printf("getnetnum given %s, got %s (%lx)\n",
2131 num, ntoa(addr), (u_long)netnum);
2139 * catchchild - receive the resolver's exit status
2147 * We only start up one child, and if we're here
2148 * it should have already exited. Hence the following
2149 * shouldn't hang. If it does, please tell me.
2151 #if !defined (SYS_WINNT) && !defined(SYS_VXWORKS)
2153 #endif /* SYS_WINNT && VXWORKS*/
2159 * save_resolve - save configuration info into a file for later name resolution
2174 if (res_fp == NULL) {
2176 (void) strcpy(res_file, RES_TEMPFILE);
2178 /* no /tmp directory under NT */
2181 if(!(len = GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) {
2182 msyslog(LOG_ERR, "cannot get pathname for temporary directory: %m");
2185 (void) strcat(res_file, "ntpdXXXXXX");
2187 #endif /* SYS_WINNT */
2193 if ((fd = mkstemp(res_file)) != -1)
2194 res_fp = fdopen(fd, "w");
2197 (void) mktemp(res_file);
2198 res_fp = fopen(res_file, "w");
2200 if (res_fp == NULL) {
2201 msyslog(LOG_ERR, "open failed for %s: %m", res_file);
2207 printf("resolving %s\n", name);
2211 (void) fprintf(res_fp, "%s %d %d %d %d %d %d %lu\n", name, mode,
2212 version, minpoll, maxpoll, flags, ttl, keyid);
2213 #else /* SYS_VXWORKS */
2214 /* save resolve info to a struct */
2215 #endif /* SYS_VXWORKS */
2220 * abort_resolve - terminate the resolver stuff and delete the file
2226 * In an ideal world we would might reread the file and
2227 * log the hosts which aren't getting configured. Since
2228 * this is too much work, however, just close and delete
2232 (void) fclose(res_fp);
2235 #ifndef SYS_VXWORKS /* we don't open the file to begin with */
2237 (void) unlink(res_file);
2239 (void) delete(res_file);
2241 #endif /* SYS_VXWORKS */
2245 #define KEY_TYPE_MD5 4
2248 * do_resolve_internal - start up the resolver function (not program)
2251 * On VMS, this routine will simply refuse to resolve anything.
2253 * Possible implementation: keep `res_file' in memory, do async
2254 * name resolution via QIO, update from within completion AST.
2255 * I'm unlikely to find the time for doing this, though. -wjm
2258 do_resolve_internal(void)
2262 if (res_fp == NULL) {
2265 "internal error in do_resolve_internal: res_fp == NULL");
2269 /* we are done with this now */
2270 (void) fclose(res_fp);
2273 #if !defined(VMS) && !defined (SYS_VXWORKS)
2275 if (info_auth_keyid == 0)
2278 req_keyid = info_auth_keyid;
2280 /* if doesn't exist, make up one at random */
2281 if (!authhavekey(req_keyid)) {
2284 for (i = 0; i < 8; i++)
2285 rankey[i] = RANDOM & 0xff;
2286 authusekey(req_keyid, KEY_TYPE_MD5, (u_char *)rankey);
2287 authtrust(req_keyid, 1);
2290 /* save keyid so we will accept config requests with it */
2291 info_auth_keyid = req_keyid;
2292 req_file = res_file; /* set up pointer to res file */
2294 (void) signal_no_reset(SIGCHLD, catchchild);
2300 * this used to close everything
2301 * I don't think this is necessary
2304 * To the unknown commenter above:
2305 * Well, I think it's better to clean up
2306 * after oneself. I have had problems with
2307 * refclock-io when intres was running - things
2308 * where fine again when ntpintres was gone.
2309 * So some systems react erratic at least.
2314 * Further debugging has proven that the above is
2315 * absolutely harmful. The internal resolver
2316 * is still in the SIGIO process group and the lingering
2317 * async io information causes it to process requests from
2318 * all file decriptor causing a race between the NTP daemon
2319 * and the resolver. which then eats data when it wins 8-(.
2320 * It is absolutly necessary to kill ane io associations
2321 * shared with the NTP daemon. I currently don't want
2323 * we also block SIGIO (currently no portes means to
2324 * disable the signal handle for IO).
2326 * Thanks to wgstuken@informatik.uni-erlangen.de to notice
2327 * that it is the ntp-resolver child running into trouble.
2335 (void) signal_no_reset(SIGCHLD, SIG_DFL);
2343 openlog("ntpd_initres", LOG_PID);
2344 # else /* LOG_DAEMON */
2347 # define LOG_NTP LOG_DAEMON
2349 openlog("ntpd_initres", LOG_PID | LOG_NDELAY, LOG_NTP);
2350 #ifndef SYS_CYGWIN32
2353 setlogmask(LOG_UPTO(LOG_DEBUG));
2356 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
2357 # endif /* LOG_DAEMON */
2363 * If we got here, the intres code screwed up.
2364 * Print something so we don't die without complaint
2366 msyslog(LOG_ERR, "call to ntp_intres lost");
2371 /* vxWorks spawns a thread... -casey */
2372 i = sp (ntp_intres);
2373 /*i = taskSpawn("ntp_intres",100,VX_FP_TASK,20000,ntp_intres);*/
2376 msyslog(LOG_ERR, "fork() failed, can't start ntp_intres: %m");
2377 (void) signal_no_reset(SIGCHLD, SIG_DFL);
2380 #else /* SYS_WINNT */
2382 /* NT's equivalent of fork() is _spawn(), but the start point
2383 * of the new process is an executable filename rather than
2384 * a function name as desired here.
2388 if (!(ResolverThreadHandle = CreateThread(
2389 NULL, /* no security attributes */
2390 0, /* use default stack size */
2391 (LPTHREAD_START_ROUTINE) ntp_intres, /* thread function */
2392 NULL, /* argument to thread function */
2393 0, /* use default creation flags */
2394 &dwThreadId))) { /* returns the thread identifier */
2395 msyslog(LOG_ERR, "CreateThread() failed, can't start ntp_intres");
2399 #endif /* SYS_WINNT */
2400 #else /* VMS VX_WORKS */
2402 "Name resolution not implemented for VMS - use numeric addresses");
2404 #endif /* VMS VX_WORKS */