2 * ntp_config.c - read and apply configuration information
9 # include <netinfo/ni.h>
14 #include "ntp_unixtime.h"
15 #include "ntp_refclock.h"
16 #include "ntp_filegen.h"
17 #include "ntp_stdlib.h"
18 #include "ntp_config.h"
19 #include "ntp_cmdargs.h"
22 # include "ntp_crypto.h"
27 #include <sys/param.h>
30 # define SIGCHLD SIGCLD
33 # ifdef HAVE_SYS_WAIT_H
34 # include <sys/wait.h>
40 extern HANDLE ResolverThreadHandle;
41 #endif /* SYS_WINNT */
43 extern int priority_done;
46 * These routines are used to read the configuration file at
47 * startup time. An entry in the file must fit on a single line.
48 * Entries are processed as multiple tokens separated by white space
49 * Lines are considered terminated when a '#' is encountered. Blank
54 * We understand the following configuration entries and defaults.
56 * peer [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
57 * server [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
58 * broadcast [ addr ] [ version 3 ] [ key 0 ] [ ttl 1 ]
60 * multicastclient [ 224.0.1.1 ]
61 * manycastclient [ addr ] [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
62 * manycastserver [ 224.0.1.1 ]
63 * broadcastdelay 0.0102
64 * restrict [ addr ] [ mask 255.255.255.0 ] ignore|noserve|notrust|noquery
68 * privatekey file_name
70 * filegen peerstats [ file peerstats ] [ type day ] [ link ]
72 * clientperiod [ 3600 ]
77 * fudge [ addr ] [ stratum ] [ refid ] ...
81 * logconfig [+|-|=][{sync|sys|peer|clock}{{,all}{info|statistics|events|status}}]...
82 * enable auth|bclient|pll|kernel|monitor|stats
83 * disable auth|bclient|pll|kernel|monitor|stats
85 * pps device [assert|clear] [hardpps]
86 * priority high|normal
90 * Translation table - keywords to function index
100 static struct keyword keywords[] = {
101 { "authenticate", CONFIG_AUTHENTICATE },
102 { "automax", CONFIG_AUTOMAX },
103 { "broadcast", CONFIG_BROADCAST },
104 { "broadcastclient", CONFIG_BROADCASTCLIENT },
105 { "broadcastdelay", CONFIG_BDELAY },
106 { "clientlimit", CONFIG_CLIENTLIMIT },
107 { "clientperiod", CONFIG_CLIENTPERIOD },
109 { "crypto", CONFIG_CRYPTO },
111 { "controlkey", CONFIG_CONTROLKEY },
112 { "disable", CONFIG_DISABLE },
113 { "driftfile", CONFIG_DRIFTFILE },
114 { "enable", CONFIG_ENABLE },
115 { "filegen", CONFIG_FILEGEN },
116 { "fudge", CONFIG_FUDGE },
117 { "includefile", CONFIG_INCLUDEFILE },
118 { "keys", CONFIG_KEYS },
120 { "keysdir", CONFIG_KEYSDIR },
122 { "logconfig", CONFIG_LOGCONFIG },
123 { "logfile", CONFIG_LOGFILE },
124 { "manycastclient", CONFIG_MANYCASTCLIENT },
125 { "manycastserver", CONFIG_MANYCASTSERVER },
126 { "multicastclient", CONFIG_MULTICASTCLIENT },
127 { "peer", CONFIG_PEER },
128 { "phone", CONFIG_PHONE },
129 { "pidfile", CONFIG_PIDFILE },
130 { "pps", CONFIG_PPS },
131 { "requestkey", CONFIG_REQUESTKEY },
132 { "restrict", CONFIG_RESTRICT },
133 { "revoke", CONFIG_REVOKE },
134 { "server", CONFIG_SERVER },
135 { "setvar", CONFIG_SETVAR },
136 { "statistics", CONFIG_STATISTICS },
137 { "statsdir", CONFIG_STATSDIR },
138 { "tinker", CONFIG_TINKER },
139 { "trap", CONFIG_TRAP },
140 { "trustedkey", CONFIG_TRUSTEDKEY },
141 { "", CONFIG_UNKNOWN }
145 * "peer", "server", "broadcast" modifier keywords
147 static struct keyword mod_keywords[] = {
148 { "autokey", CONF_MOD_SKEY },
149 { "burst", CONF_MOD_BURST },
150 { "iburst", CONF_MOD_IBURST },
151 { "key", CONF_MOD_KEY },
152 { "maxpoll", CONF_MOD_MAXPOLL },
153 { "minpoll", CONF_MOD_MINPOLL },
154 { "mode", CONF_MOD_MODE }, /* refclocks */
155 { "noselect", CONF_MOD_NOSELECT },
156 { "prefer", CONF_MOD_PREFER },
158 { "publickey", CONF_MOD_PUBLICKEY },
160 { "ttl", CONF_MOD_TTL }, /* NTP peers */
161 { "version", CONF_MOD_VERSION },
162 { "", CONFIG_UNKNOWN }
166 * "restrict" modifier keywords
168 static struct keyword res_keywords[] = {
169 { "ignore", CONF_RES_IGNORE },
170 { "limited", CONF_RES_LIMITED },
171 { "kod", CONF_RES_DEMOBILIZE },
172 { "lowpriotrap", CONF_RES_LPTRAP },
173 { "mask", CONF_RES_MASK },
174 { "nomodify", CONF_RES_NOMODIFY },
175 { "nopeer", CONF_RES_NOPEER },
176 { "noquery", CONF_RES_NOQUERY },
177 { "noserve", CONF_RES_NOSERVE },
178 { "notrap", CONF_RES_NOTRAP },
179 { "notrust", CONF_RES_NOTRUST },
180 { "ntpport", CONF_RES_NTPPORT },
181 { "version", CONF_RES_VERSION },
182 { "", CONFIG_UNKNOWN }
186 * "trap" modifier keywords
188 static struct keyword trap_keywords[] = {
189 { "port", CONF_TRAP_PORT },
190 { "interface", CONF_TRAP_INTERFACE },
191 { "", CONFIG_UNKNOWN }
195 * "fudge" modifier keywords
197 static struct keyword fudge_keywords[] = {
198 { "flag1", CONF_FDG_FLAG1 },
199 { "flag2", CONF_FDG_FLAG2 },
200 { "flag3", CONF_FDG_FLAG3 },
201 { "flag4", CONF_FDG_FLAG4 },
202 { "refid", CONF_FDG_REFID },
203 { "stratum", CONF_FDG_STRATUM },
204 { "time1", CONF_FDG_TIME1 },
205 { "time2", CONF_FDG_TIME2 },
206 { "", CONFIG_UNKNOWN }
211 * "filegen" modifier keywords
213 static struct keyword filegen_keywords[] = {
214 { "disable", CONF_FGEN_FLAG_DISABLE },
215 { "enable", CONF_FGEN_FLAG_ENABLE },
216 { "file", CONF_FGEN_FILE },
217 { "link", CONF_FGEN_FLAG_LINK },
218 { "nolink", CONF_FGEN_FLAG_NOLINK },
219 { "type", CONF_FGEN_TYPE },
220 { "", CONFIG_UNKNOWN }
224 * "type" modifier keywords
226 static struct keyword fgen_types[] = {
227 { "age", FILEGEN_AGE },
228 { "day", FILEGEN_DAY },
229 { "month", FILEGEN_MONTH },
230 { "none", FILEGEN_NONE },
231 { "pid", FILEGEN_PID },
232 { "week", FILEGEN_WEEK },
233 { "year", FILEGEN_YEAR },
234 { "", CONFIG_UNKNOWN}
238 * "enable", "disable" modifier keywords
240 static struct keyword flags_keywords[] = {
241 { "auth", PROTO_AUTHENTICATE },
242 { "bclient", PROTO_BROADCLIENT },
243 { "kernel", PROTO_KERNEL },
244 { "monitor", PROTO_MONITOR },
245 { "ntp", PROTO_NTP },
246 { "stats", PROTO_FILEGEN },
247 { "pps", PROTO_PPS },
248 { "calibrate", PROTO_CAL },
249 { "", CONFIG_UNKNOWN }
253 * "pps" modifier keywords
255 static struct keyword pps_keywords[] = {
256 { "assert", CONF_PPS_ASSERT },
257 { "clear", CONF_PPS_CLEAR },
258 { "hardpps", CONF_PPS_HARDPPS },
259 { "", CONFIG_UNKNOWN }
263 * "tinker" modifier keywords
265 static struct keyword tinker_keywords[] = {
266 { "step", CONF_CLOCK_MAX },
267 { "panic", CONF_CLOCK_PANIC },
268 { "dispersion", CONF_CLOCK_PHI },
269 { "stepout", CONF_CLOCK_MINSTEP },
270 { "minpoll", CONF_CLOCK_MINPOLL },
271 { "allan", CONF_CLOCK_ALLAN },
272 { "huffpuff", CONF_CLOCK_HUFFPUFF },
273 { "", CONFIG_UNKNOWN }
278 * "crypto" modifier keywords
280 static struct keyword crypto_keywords[] = {
281 { "dh", CONF_CRYPTO_DH },
282 { "flags", CONF_CRYPTO_FLAGS },
283 { "leap", CONF_CRYPTO_LEAP },
284 { "privatekey", CONF_CRYPTO_PRIVATEKEY },
285 { "publickey", CONF_CRYPTO_PUBLICKEY },
286 { "", CONFIG_UNKNOWN }
291 * "logconfig" building blocks
298 static struct masks logcfg_class[] = {
299 { "clock", NLOG_OCLOCK },
300 { "peer", NLOG_OPEER },
301 { "sync", NLOG_OSYNC },
302 { "sys", NLOG_OSYS },
306 static struct masks logcfg_item[] = {
307 { "info", NLOG_INFO },
308 { "allinfo", NLOG_SYSINFO|NLOG_PEERINFO|NLOG_CLOCKINFO|NLOG_SYNCINFO },
309 { "events", NLOG_EVENT },
310 { "allevents", NLOG_SYSEVENT|NLOG_PEEREVENT|NLOG_CLOCKEVENT|NLOG_SYNCEVENT },
311 { "status", NLOG_STATUS },
312 { "allstatus", NLOG_SYSSTATUS|NLOG_PEERSTATUS|NLOG_CLOCKSTATUS|NLOG_SYNCSTATUS },
313 { "statistics", NLOG_STATIST },
314 { "allstatistics", NLOG_SYSSTATIST|NLOG_PEERSTATIST|NLOG_CLOCKSTATIST|NLOG_SYNCSTATIST },
315 { "allclock", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OCLOCK },
316 { "allpeer", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OPEER },
317 { "allsys", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYS },
318 { "allsync", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYNC },
319 { "all", NLOG_SYSMASK|NLOG_PEERMASK|NLOG_CLOCKMASK|NLOG_SYNCMASK },
326 #define MAXTOKENS 20 /* 20 tokens on line */
327 #define MAXLINE 1024 /* maximum length of line */
328 #define MAXPHONE 5 /* maximum number of phone strings */
329 #define MAXPPS 20 /* maximum length of PPS device string */
330 #define MAXINCLUDELEVEL 5 /* maximum include file levels */
333 * Miscellaneous macros
335 #define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
336 #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
337 #define ISSPACE(c) ((c) == ' ' || (c) == '\t')
338 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
340 #define KEY_TYPE_MD5 4
343 * File descriptor used by the resolver save routines, and temporary file
348 static char res_file[20]; /* enough for /tmp/ntpXXXXXX\0 */
349 #define RES_TEMPFILE "/tmp/ntpXXXXXX"
351 static char res_file[MAX_PATH];
352 #endif /* SYS_WINNT */
355 * Definitions of things either imported from or exported to outside
357 char const *progname;
358 char sys_phone[MAXPHONE][MAXDIAL]; /* ACTS phone numbers */
359 char pps_device[MAXPPS + 1]; /* PPS device name */
362 #if defined(HAVE_SCHED_SETSCHEDULER)
363 int config_priority_override = 0;
367 const char *config_file;
369 struct netinfo_config_state *config_netinfo = NULL;
370 int check_netinfo = 1;
371 #endif /* HAVE_NETINFO */
373 char *alt_config_file;
375 char config_file_storage[MAX_PATH];
376 char alt_config_file_storage[MAX_PATH];
377 #endif /* SYS_WINNT */
381 * NetInfo configuration state
383 struct netinfo_config_state {
384 void *domain; /* domain with config */
385 ni_id config_dir; /* ID config dir */
386 int prop_index; /* current property */
387 int val_index; /* current value */
388 char **val_list; /* value list */
393 * Function prototypes
395 static unsigned long get_pfxmatch P((char **, struct masks *));
396 static unsigned long get_match P((char *, struct masks *));
397 static unsigned long get_logmask P((char *));
399 static struct netinfo_config_state *get_netinfo_config P((void));
400 static void free_netinfo_config P((struct netinfo_config_state *));
401 static int gettokens_netinfo P((struct netinfo_config_state *, char **, int *));
403 static int gettokens P((FILE *, char *, char **, int *));
404 static int matchkey P((char *, struct keyword *));
405 static int getnetnum P((const char *, struct sockaddr_in *, int));
406 static void save_resolve P((char *, int, int, int, int, u_int, int,
408 static void do_resolve_internal P((void));
409 static void abort_resolve P((void));
411 static RETSIGTYPE catchchild P((int));
415 * get_pfxmatch - find value for prefixmatch
416 * and update char * accordingly
425 if (strncmp(*s, m->name, strlen(m->name)) == 0) {
426 *s += strlen(m->name);
436 * get_match - find logmask value
445 if (strcmp(s, m->name) == 0) {
455 * get_logmask - build bitmask for ntp_syslogmask
463 unsigned long offset;
467 offset = get_pfxmatch(&t, logcfg_class);
468 mask = get_match(t, logcfg_item);
471 return mask << offset;
473 msyslog(LOG_ERR, "logconfig: illegal argument %s - ignored", s);
480 * getconfig - get command line options and read the configuration file
502 struct sockaddr_in peeraddr;
503 struct sockaddr_in maskaddr;
504 FILE *fp[MAXINCLUDELEVEL+1];
506 int includelevel = 0;
508 char *(tokens[MAXTOKENS]);
510 int tok = CONFIG_UNKNOWN;
511 struct interface *localaddr;
512 struct refclockstat clock_stat;
516 * Initialize, initialize
519 /* HMS: don't initialize debug to 0 here! */
521 config_file = CONFIG_FILE;
524 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) {
525 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n");
528 config_file = config_file_storage;
530 temp = ALT_CONFIG_FILE;
531 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) {
532 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n");
535 alt_config_file = alt_config_file_storage;
537 #endif /* SYS_WINNT */
540 memset((char *)sys_phone, 0, sizeof(sys_phone));
541 ntp_syslogmask = NLOG_SYNCMASK; /* set more via logconfig */
544 * install a non default variable with this daemon version
546 (void) sprintf(line, "daemon_version=\"%s\"", Version);
547 set_sys_var(line, strlen(line)+1, RO);
550 * Say how we're setting the time of day
552 (void) sprintf(line, "settimeofday=\"%s\"", set_tod_using);
553 set_sys_var(line, strlen(line)+1, RO);
556 * Initialize the loop.
558 loop_config(LOOP_DRIFTINIT, 0.);
560 getCmdOpts(argc, argv);
563 (fp[0] = fopen(FindConfig(config_file), "r")) == NULL
565 /* If there is no config_file, try NetInfo. */
566 && check_netinfo && !(config_netinfo = get_netinfo_config())
567 #endif /* HAVE_NETINFO */
569 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file));
570 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file));
572 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
574 if ((fp[0] = fopen(FindConfig(alt_config_file), "r")) == NULL) {
577 * Broadcast clients can sometimes run without
578 * a configuration file.
581 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file));
582 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file));
585 #else /* not SYS_WINNT */
587 #endif /* not SYS_WINNT */
591 if (fp[includelevel])
592 tok = gettokens(fp[includelevel], line, tokens, &ntokens);
595 tok = gettokens_netinfo(config_netinfo, tokens, &ntokens);
596 #endif /* HAVE_NETINFO */
598 if (tok == CONFIG_UNKNOWN) {
599 if (includelevel > 0) {
600 fclose(fp[includelevel--]);
610 case CONFIG_MANYCASTCLIENT:
611 case CONFIG_BROADCAST:
612 if (tok == CONFIG_PEER)
614 else if (tok == CONFIG_SERVER)
616 else if (tok == CONFIG_MANYCASTCLIENT)
619 hmode = MODE_BROADCAST;
623 "No address for %s, line ignored",
628 if (!getnetnum(tokens[1], &peeraddr, 0)) {
635 !ISREFCLOCKADR(&peeraddr) &&
637 ISBADADR(&peeraddr)) {
639 "attempt to configure invalid address %s",
644 * Shouldn't be able to specify multicast
645 * address for server/peer!
646 * and unicast address for manycastclient!
648 if (((tok == CONFIG_SERVER) ||
649 (tok == CONFIG_PEER)) &&
651 !ISREFCLOCKADR(&peeraddr) &&
653 IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))) {
655 "attempt to configure invalid address %s",
659 if ((tok == CONFIG_MANYCASTCLIENT) &&
660 !IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr))) {
662 "attempt to configure invalid address %s",
668 peerversion = NTP_VERSION;
669 minpoll = NTP_MINDPOLL;
670 maxpoll = NTP_MAXDPOLL;
675 for (i = 2; i < ntokens; i++)
676 switch (matchkey(tokens[i], mod_keywords)) {
677 case CONF_MOD_VERSION:
678 if (i >= ntokens-1) {
680 "peer/server version requires an argument");
684 peerversion = atoi(tokens[++i]);
685 if ((u_char)peerversion > NTP_VERSION
686 || (u_char)peerversion < NTP_OLDVERSION) {
688 "inappropriate version number %s, line ignored",
695 if (i >= ntokens-1) {
697 "key: argument required");
701 peerkey = (int)atol(tokens[++i]);
702 peerflags |= FLAG_AUTHENABLE;
705 case CONF_MOD_MINPOLL:
706 if (i >= ntokens-1) {
708 "minpoll: argument required");
712 minpoll = atoi(tokens[++i]);
713 if (minpoll < NTP_MINPOLL) {
715 "minpoll: provided value (%d) is below minimum (%d)",
716 minpoll, NTP_MINPOLL);
717 minpoll = NTP_MINPOLL;
721 case CONF_MOD_MAXPOLL:
722 if (i >= ntokens-1) {
724 "maxpoll: argument required"
729 maxpoll = atoi(tokens[++i]);
730 if (maxpoll > NTP_MAXPOLL) {
732 "maxpoll: provided value (%d) is above maximum (%d)",
733 maxpoll, NTP_MAXPOLL);
734 maxpoll = NTP_MAXPOLL;
738 case CONF_MOD_PREFER:
739 peerflags |= FLAG_PREFER;
742 case CONF_MOD_NOSELECT:
743 peerflags |= FLAG_NOSELECT;
747 peerflags |= FLAG_BURST;
750 case CONF_MOD_IBURST:
751 peerflags |= FLAG_IBURST;
755 peerflags |= FLAG_SKEY |
760 case CONF_MOD_PUBLICKEY:
761 if (i >= ntokens - 1) {
763 "Public key file name required");
767 peerflags |= FLAG_SKEY |
769 peerkeystr = tokens[++i];
775 if (i >= ntokens-1) {
777 "ttl: argument required");
781 ttl = atoi(tokens[++i]);
785 if (i >= ntokens-1) {
787 "mode: argument required");
791 ttl = atoi(tokens[++i]);
798 if (minpoll > maxpoll) {
799 msyslog(LOG_ERR, "config error: minpoll > maxpoll");
803 if (peer_config(&peeraddr, any_interface, hmode,
804 peerversion, minpoll, maxpoll, peerflags,
805 ttl, peerkey, peerkeystr) == 0) {
807 "configuration of %s failed",
811 } else if (errflg == -1) {
812 save_resolve(tokens[1], hmode, peerversion,
813 minpoll, maxpoll, peerflags, ttl,
814 peerkey, peerkeystr);
818 case CONFIG_DRIFTFILE:
820 stats_config(STATS_FREQ_FILE, tokens[1]);
822 stats_config(STATS_FREQ_FILE, (char *)0);
827 stats_config(STATS_PID_FILE, tokens[1]);
829 stats_config(STATS_PID_FILE, (char *)0);
832 case CONFIG_INCLUDEFILE:
834 msyslog(LOG_ERR, "includefile needs one argument");
837 if (includelevel >= MAXINCLUDELEVEL) {
838 fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
839 msyslog(LOG_INFO, "getconfig: Maximum include file level exceeded.");
842 includefile = fopen(FindConfig(tokens[1]), "r");
843 if (includefile == NULL) {
844 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(tokens[1]));
845 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(tokens[1]));
848 fp[++includelevel] = includefile;
855 new_file = fopen(tokens[1], "a");
856 if (new_file != NULL) {
857 NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
858 msyslog(LOG_NOTICE, "logging to file %s", tokens[1]);
859 if (syslog_file != NULL &&
860 fileno(syslog_file) != fileno(new_file))
861 (void)fclose(syslog_file);
863 syslog_file = new_file;
868 "Cannot open log file %s",
872 msyslog(LOG_ERR, "logfile needs one argument");
875 case CONFIG_LOGCONFIG:
876 for (i = 1; i < ntokens; i++)
880 char * s = &tokens[i][0];
895 ntp_syslogmask = get_logmask(s);
898 ntp_syslogmask |= get_logmask(s);
900 ntp_syslogmask &= ~get_logmask(s);
905 printf("ntp_syslogmask = 0x%08lx (%s)\n", ntp_syslogmask, tokens[i]);
910 case CONFIG_BROADCASTCLIENT:
911 proto_config(PROTO_BROADCLIENT, 1, 0.);
914 case CONFIG_MULTICASTCLIENT:
915 case CONFIG_MANYCASTSERVER:
917 for (i = 1; i < ntokens; i++) {
918 if (getnetnum(tokens[i], &peeraddr, 1))
919 proto_config(PROTO_MULTICAST_ADD,
920 peeraddr.sin_addr.s_addr, 0.);
923 proto_config(PROTO_MULTICAST_ADD,
924 htonl(INADDR_NTP), 0.);
925 if (tok == CONFIG_MULTICASTCLIENT)
927 else if (tok == CONFIG_MANYCASTSERVER)
928 sys_manycastserver = 1;
931 case CONFIG_AUTHENTICATE:
934 if (STREQ(tokens[1], "yes"))
935 proto_config(PROTO_AUTHENTICATE, 1, 0.);
936 else if (STREQ(tokens[1], "no"))
937 proto_config(PROTO_AUTHENTICATE, 0, 0.);
946 "should be `authenticate yes|no'");
951 getauthkeys(tokens[1]);
956 for (i = 1; i < ntokens; i++) {
960 temp = matchkey(tokens[i++],
962 if (i > ntokens - 1) {
964 "tinker: missing argument");
968 sscanf(tokens[i], "%lf", &ftemp);
971 loop_config(LOOP_MAX, ftemp);
974 case CONF_CLOCK_PANIC:
975 loop_config(LOOP_PANIC, ftemp);
979 loop_config(LOOP_PHI, ftemp);
982 case CONF_CLOCK_MINSTEP:
983 loop_config(LOOP_MINSTEP, ftemp);
986 case CONF_CLOCK_MINPOLL:
987 loop_config(LOOP_MINPOLL, ftemp);
990 case CONF_CLOCK_ALLAN:
991 loop_config(LOOP_ALLAN, ftemp);
994 case CONF_CLOCK_HUFFPUFF:
995 loop_config(LOOP_HUFFPUFF, ftemp);
1004 sys_revoke = 1 << max(atoi(tokens[1]), 10);
1007 case CONFIG_AUTOMAX:
1009 sys_automax = 1 << max(atoi(tokens[1]), 10);
1013 case CONFIG_KEYSDIR:
1016 "Keys directory name required");
1019 crypto_config(CRYPTO_CONF_KEYS, tokens[1]);
1024 crypto_config(CRYPTO_CONF_FLAGS , "0");
1027 for (i = 1; i < ntokens; i++) {
1030 temp = matchkey(tokens[i++], crypto_keywords);
1031 if (i > ntokens - 1) {
1033 "crypto: missing argument");
1038 case CONF_CRYPTO_FLAGS:
1039 crypto_config(CRYPTO_CONF_FLAGS, tokens[i]);
1042 case CONF_CRYPTO_LEAP:
1043 crypto_config(CRYPTO_CONF_LEAP, tokens[i]);
1046 case CONF_CRYPTO_DH:
1047 crypto_config(CRYPTO_CONF_DH, tokens[i]);
1050 case CONF_CRYPTO_PRIVATEKEY:
1051 crypto_config(CRYPTO_CONF_PRIV, tokens[i]);
1054 case CONF_CRYPTO_PUBLICKEY:
1055 crypto_config(CRYPTO_CONF_PUBL, tokens[i]);
1058 case CONF_CRYPTO_CERT:
1059 crypto_config(CRYPTO_CONF_CERT, tokens[i]);
1063 msyslog(LOG_ERR, "crypto: unknown keyword");
1069 #endif /* AUTOKEY */
1071 case CONFIG_RESTRICT:
1073 msyslog(LOG_ERR, "restrict requires an address");
1076 if (STREQ(tokens[1], "default"))
1077 peeraddr.sin_addr.s_addr = htonl(INADDR_ANY);
1078 else if (!getnetnum(tokens[1], &peeraddr, 1))
1082 * Use peerversion as flags, peerkey as mflags. Ick.
1087 maskaddr.sin_addr.s_addr = ~(u_int32)0;
1088 for (i = 2; i < ntokens; i++) {
1089 switch (matchkey(tokens[i], res_keywords)) {
1091 if (i >= ntokens-1) {
1093 "mask keyword needs argument");
1098 if (!getnetnum(tokens[i], &maskaddr, 1))
1102 case CONF_RES_IGNORE:
1103 peerversion |= RES_IGNORE;
1106 case CONF_RES_NOSERVE:
1107 peerversion |= RES_DONTSERVE;
1110 case CONF_RES_NOTRUST:
1111 peerversion |= RES_DONTTRUST;
1114 case CONF_RES_NOQUERY:
1115 peerversion |= RES_NOQUERY;
1118 case CONF_RES_NOMODIFY:
1119 peerversion |= RES_NOMODIFY;
1122 case CONF_RES_NOPEER:
1123 peerversion |= RES_NOPEER;
1126 case CONF_RES_NOTRAP:
1127 peerversion |= RES_NOTRAP;
1130 case CONF_RES_LPTRAP:
1131 peerversion |= RES_LPTRAP;
1134 case CONF_RES_NTPPORT:
1135 peerkey |= RESM_NTPONLY;
1138 case CONF_RES_VERSION:
1139 peerversion |= RES_VERSION;
1142 case CONF_RES_DEMOBILIZE:
1143 peerversion |= RES_DEMOBILIZE;
1146 case CONF_RES_LIMITED:
1147 peerversion |= RES_LIMITED;
1150 case CONFIG_UNKNOWN:
1155 if (SRCADR(&peeraddr) == htonl(INADDR_ANY))
1156 maskaddr.sin_addr.s_addr = 0;
1158 hack_restrict(RESTRICT_FLAGS, &peeraddr, &maskaddr,
1159 (int)peerkey, peerversion);
1166 if (sscanf(tokens[1], "%lf", &tmp) != 1) {
1168 "broadcastdelay value %s undecodable",
1171 proto_config(PROTO_BROADDELAY, 0, tmp);
1176 case CONFIG_TRUSTEDKEY:
1177 for (i = 1; i < ntokens; i++) {
1180 tkey = atol(tokens[i]);
1183 "trusted key %s unlikely",
1191 case CONFIG_REQUESTKEY:
1193 if (!atouint(tokens[1], &ul)) {
1195 "%s is undecodable as request key",
1197 } else if (ul == 0) {
1199 "%s makes a poor request keyid",
1205 "set info_auth_key to %08lx\n", ul);
1207 info_auth_keyid = (keyid_t)ul;
1212 case CONFIG_CONTROLKEY:
1216 ckey = atol(tokens[1]);
1219 "%s makes a poor control keyid",
1222 ctl_auth_keyid = ckey;
1230 "no address for trap command, line ignored");
1233 if (!getnetnum(tokens[1], &peeraddr, 1))
1237 * Use peerversion for port number. Barf.
1242 for (i = 2; i < ntokens-1; i++)
1243 switch (matchkey(tokens[i], trap_keywords)) {
1244 case CONF_TRAP_PORT:
1245 if (i >= ntokens-1) {
1247 "trap port requires an argument");
1251 peerversion = atoi(tokens[++i]);
1252 if (peerversion <= 0
1253 || peerversion > 32767) {
1255 "invalid port number %s, trap ignored",
1261 case CONF_TRAP_INTERFACE:
1262 if (i >= ntokens-1) {
1264 "trap interface requires an argument");
1269 if (!getnetnum(tokens[++i],
1275 localaddr = findinterface(&maskaddr);
1276 if (localaddr == NULL) {
1278 "can't find interface with address %s",
1284 case CONFIG_UNKNOWN:
1290 if (peerversion != 0)
1291 peeraddr.sin_port = htons( (u_short) peerversion);
1293 peeraddr.sin_port = htons(TRAPPORT);
1294 if (localaddr == NULL)
1295 localaddr = any_interface;
1296 if (!ctlsettrap(&peeraddr, localaddr, 0,
1299 "can't set trap for %s, no resources",
1307 "no address for fudge command, line ignored");
1310 if (!getnetnum(tokens[1], &peeraddr, 1))
1313 if (!ISREFCLOCKADR(&peeraddr)) {
1315 "%s is inappropriate address for the fudge command, line ignored",
1320 memset((void *)&clock_stat, 0, sizeof clock_stat);
1323 for (i = 2; i < ntokens-1; i++) {
1324 switch (c = matchkey(tokens[i],
1326 case CONF_FDG_TIME1:
1327 if (sscanf(tokens[++i], "%lf",
1328 &clock_stat.fudgetime1) != 1) {
1330 "fudge %s time1 value in error",
1335 clock_stat.haveflags |= CLK_HAVETIME1;
1338 case CONF_FDG_TIME2:
1339 if (sscanf(tokens[++i], "%lf",
1340 &clock_stat.fudgetime2) != 1) {
1342 "fudge %s time2 value in error",
1347 clock_stat.haveflags |= CLK_HAVETIME2;
1351 case CONF_FDG_STRATUM:
1352 if (!atoint(tokens[++i], &stratum))
1355 "fudge %s stratum value in error",
1360 clock_stat.fudgeval1 = stratum;
1361 clock_stat.haveflags |= CLK_HAVEVAL1;
1364 case CONF_FDG_REFID:
1365 /* HMS: Endianness and 0 bytes? */
1367 strncpy((char *)&clock_stat.fudgeval2,
1369 clock_stat.haveflags |= CLK_HAVEVAL2;
1372 case CONF_FDG_FLAG1:
1373 case CONF_FDG_FLAG2:
1374 case CONF_FDG_FLAG3:
1375 case CONF_FDG_FLAG4:
1376 if (!atouint(tokens[++i], &fudgeflag)
1379 "fudge %s flag value in error",
1385 case CONF_FDG_FLAG1:
1387 clock_stat.haveflags|=CLK_HAVEFLAG1;
1389 case CONF_FDG_FLAG2:
1391 clock_stat.haveflags|=CLK_HAVEFLAG2;
1393 case CONF_FDG_FLAG3:
1395 clock_stat.haveflags|=CLK_HAVEFLAG3;
1397 case CONF_FDG_FLAG4:
1399 clock_stat.haveflags|=CLK_HAVEFLAG4;
1403 clock_stat.flags &= ~c;
1405 clock_stat.flags |= c;
1408 case CONFIG_UNKNOWN:
1416 * If reference clock support isn't defined the
1417 * fudge line will still be accepted and syntax
1418 * checked, but will essentially do nothing.
1421 refclock_control(&peeraddr, &clock_stat,
1422 (struct refclockstat *)0);
1427 case CONFIG_STATSDIR:
1429 stats_config(STATS_STATSDIR,tokens[1]);
1432 case CONFIG_STATISTICS:
1433 for (i = 1; i < ntokens; i++) {
1434 filegen = filegen_get(tokens[i]);
1436 if (filegen == NULL) {
1438 "no statistics named %s available",
1444 printf("enabling filegen for %s statistics \"%s%s\"\n",
1445 tokens[i], filegen->prefix, filegen->basename);
1447 filegen->flag |= FGEN_FLAG_ENABLED;
1451 case CONFIG_FILEGEN:
1454 "no id for filegen command, line ignored");
1458 filegen = filegen_get(tokens[1]);
1459 if (filegen == NULL) {
1461 "unknown filegen \"%s\" ignored",
1466 * peerversion is (ab)used for filegen file (index)
1467 * peerkey is (ab)used for filegen type
1468 * peerflags is (ab)used for filegen flags
1471 peerkey = filegen->type;
1472 peerflags = filegen->flag;
1475 for (i = 2; i < ntokens; i++) {
1476 switch (matchkey(tokens[i], filegen_keywords)) {
1477 case CONF_FGEN_FILE:
1478 if (i >= ntokens - 1) {
1480 "filegen %s file requires argument",
1487 case CONF_FGEN_TYPE:
1488 if (i >= ntokens -1) {
1490 "filegen %s type requires argument",
1495 peerkey = matchkey(tokens[++i], fgen_types);
1496 if (peerkey == CONFIG_UNKNOWN) {
1498 "filegen %s unknown type \"%s\"",
1499 tokens[1], tokens[i]);
1505 case CONF_FGEN_FLAG_LINK:
1506 peerflags |= FGEN_FLAG_LINK;
1509 case CONF_FGEN_FLAG_NOLINK:
1510 peerflags &= ~FGEN_FLAG_LINK;
1513 case CONF_FGEN_FLAG_ENABLE:
1514 peerflags |= FGEN_FLAG_ENABLED;
1517 case CONF_FGEN_FLAG_DISABLE:
1518 peerflags &= ~FGEN_FLAG_ENABLED;
1523 filegen_config(filegen, tokens[peerversion],
1524 (u_char)peerkey, (u_char)peerflags);
1530 "no value for setvar command - line ignored");
1532 set_sys_var(tokens[1], strlen(tokens[1])+1,
1535 && !strcmp(tokens[2],
1542 case CONFIG_CLIENTLIMIT:
1545 "no value for clientlimit command - line ignored");
1549 if (!atouint(tokens[1], &ui) || !ui) {
1551 "illegal value for clientlimit command - line ignored");
1557 sprintf(bp, "client_limit=%lu", ui);
1559 set_sys_var(bp, strlen(bp)+1, RO);
1565 case CONFIG_CLIENTPERIOD:
1568 "no value for clientperiod command - line ignored");
1572 if (!atouint(tokens[1], &ui) || ui < 64) {
1574 "illegal value for clientperiod command - line ignored");
1578 sprintf(bp, "client_limit_period=%ld", ui);
1579 set_sys_var(bp, strlen(bp)+1, RO);
1580 client_limit_period = ui;
1586 for (i = 1; i < ntokens; i++) {
1589 flag = matchkey(tokens[i], flags_keywords);
1590 if (flag == CONFIG_UNKNOWN) {
1592 "enable unknown flag %s",
1597 proto_config(flag, 1, 0.);
1601 case CONFIG_DISABLE:
1602 for (i = 1; i < ntokens; i++) {
1605 flag = matchkey(tokens[i], flags_keywords);
1606 if (flag == CONFIG_UNKNOWN) {
1608 "disable unknown flag %s",
1613 proto_config(flag, 0, 0.);
1618 for (i = 1; i < ntokens && i < MAXPHONE; i++) {
1619 (void)strncpy(sys_phone[i - 1],
1620 tokens[i], MAXDIAL);
1622 sys_phone[i - 1][0] = '\0';
1628 "pps missing device name");
1631 (void)strncpy(pps_device, tokens[1], MAXPPS);
1632 for (i = 2; i < ntokens; i++) {
1635 flag = matchkey(tokens[i], pps_keywords);
1637 case CONF_PPS_ASSERT:
1640 case CONF_PPS_CLEAR:
1643 case CONF_PPS_HARDPPS:
1648 "pps unknown flag %s",
1660 (void)fclose(fp[0]);
1664 free_netinfo_config(config_netinfo);
1665 #endif /* HAVE_NETINFO */
1667 #if !defined(VMS) && !defined(SYS_VXWORKS)
1669 if (info_auth_keyid == 0)
1672 req_keyid = info_auth_keyid;
1674 /* if doesn't exist, make up one at random */
1675 if (!authhavekey(req_keyid)) {
1679 for (i = 0; i < 8; i++)
1680 for (j = 1; j < 100; ++j) {
1681 rankey[i] = RANDOM & 0xff;
1682 if (rankey[i] != 0) break;
1685 authusekey(req_keyid, KEY_TYPE_MD5, (u_char *)rankey);
1686 authtrust(req_keyid, 1);
1687 if (!authhavekey(req_keyid)) {
1688 msyslog(LOG_ERR, "getconfig: Couldn't generate a valid random key!");
1689 /* HMS: Should this be fatal? */
1693 /* save keyid so we will accept config requests with it */
1694 info_auth_keyid = req_keyid;
1695 #endif /* !defined(VMS) && !defined(SYS_VXWORKS) */
1697 if (res_fp != NULL) {
1699 * Need name resolution
1701 do_resolve_internal();
1709 * get_netinfo_config - find the nearest NetInfo domain with an ntp
1710 * configuration and initialize the configuration state.
1712 static struct netinfo_config_state *
1713 get_netinfo_config()
1718 struct netinfo_config_state *config;
1720 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL;
1722 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) {
1724 if (ni_open(domain, "..", &next_domain) != NI_OK) {
1725 ni_free(next_domain);
1729 domain = next_domain;
1731 if (status != NI_OK) {
1736 config = (struct netinfo_config_state *)malloc(sizeof(struct netinfo_config_state));
1737 config->domain = domain;
1738 config->config_dir = config_dir;
1739 config->prop_index = 0;
1740 config->val_index = 0;
1741 config->val_list = NULL;
1749 * free_netinfo_config - release NetInfo configuration state
1752 free_netinfo_config(struct netinfo_config_state *config)
1754 ni_free(config->domain);
1761 * gettokens_netinfo - return tokens from NetInfo
1765 struct netinfo_config_state *config,
1770 int prop_index = config->prop_index;
1771 int val_index = config->val_index;
1772 char **val_list = config->val_list;
1775 * Iterate through each keyword and look for a property that matches it.
1779 for (; prop_index < (sizeof(keywords)/sizeof(keywords[0])); prop_index++)
1781 ni_namelist namelist;
1782 struct keyword current_prop = keywords[prop_index];
1785 * For each value associated in the property, we're going to return
1786 * a separate line. We squirrel away the values in the config state
1787 * so the next time through, we don't need to do this lookup.
1790 if (ni_lookupprop(config->domain, &config->config_dir, current_prop.text, &namelist) == NI_OK) {
1793 /* Found the property, but it has no values */
1794 if (namelist.ni_namelist_len == 0) continue;
1796 if (! (val_list = config->val_list = (char**)malloc(sizeof(char*) * (namelist.ni_namelist_len + 1))))
1797 { msyslog(LOG_ERR, "out of memory while configuring"); break; }
1799 for (index = 0; index < namelist.ni_namelist_len; index++) {
1800 char *value = namelist.ni_namelist_val[index];
1802 if (! (val_list[index] = (char*)malloc(strlen(value+1))))
1803 { msyslog(LOG_ERR, "out of memory while configuring"); break; }
1805 strcpy(val_list[index], value);
1807 val_list[index] = NULL;
1811 ni_namelist_free(&namelist);
1813 config->prop_index = prop_index;
1816 /* No list; we're done here. */
1817 if (!val_list) return CONFIG_UNKNOWN;
1820 * We have a list of values for the current property.
1821 * Iterate through them and return each in order.
1823 if (val_list[val_index])
1827 char *tokens = val_list[val_index];
1829 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]);
1831 (const char*)tokenlist[0] = keywords[prop_index].text;
1832 for (ntok = 1; ntok < MAXTOKENS; ntok++) {
1833 tokenlist[ntok] = tokens;
1834 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted))
1835 quoted ^= (*tokens++ == '"');
1837 if (ISEOL(*tokens)) {
1840 } else { /* must be space */
1842 while (ISSPACE(*tokens)) tokens++;
1843 if (ISEOL(*tokens)) break;
1846 *ntokens = ntok + 1;
1848 config->val_index++;
1850 return keywords[prop_index].keytype;
1853 /* We're done with the current property. */
1854 prop_index = ++config->prop_index;
1856 /* Free val_list and reset counters. */
1857 for (val_index = 0; val_list[val_index]; val_index++)
1858 free(val_list[val_index]);
1859 free(val_list); val_list = config->val_list = NULL; val_index = config->val_index = 0;
1864 #endif /* HAVE_NETINFO */
1868 * gettokens - read a line and return tokens
1880 register int quoted = 0;
1883 * Find start of first token
1886 while ((cp = fgets(line, MAXLINE, fp)) != NULL) {
1888 while (ISSPACE(*cp))
1895 return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */
1899 * Now separate out the tokens
1901 for (ntok = 0; ntok < MAXTOKENS; ntok++) {
1902 tokenlist[ntok] = cp;
1903 while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted))
1904 quoted ^= (*cp++ == '"');
1909 } else { /* must be space */
1911 while (ISSPACE(*cp))
1921 *ntokens = ntok + 1;
1922 ntok = matchkey(tokenlist[0], keywords);
1923 if (ntok == CONFIG_UNKNOWN)
1931 * matchkey - match a keyword to a list
1935 register char *word,
1936 register struct keyword *keys
1940 if (keys->keytype == CONFIG_UNKNOWN) {
1942 "configure: keyword \"%s\" unknown, line ignored",
1944 return CONFIG_UNKNOWN;
1946 if (STRSAME(word, keys->text))
1947 return keys->keytype;
1954 * getnetnum - return a net number (this is crude, but careful)
1959 struct sockaddr_in *addr,
1963 register const char *cp;
1967 char buf[80]; /* will core dump on really stupid stuff */
1970 /* XXX ELIMINATE replace with decodenetnum */
1973 for (i = 0; i < 4; i++) {
1975 while (isdigit((int)*cp))
1983 } else if (*cp != '\0')
1994 printf("getnetnum %s step %d buf %s temp %d netnum %lu\n",
1995 num, i, buf, temp, (u_long)netnum);
2002 "getnetnum: \"%s\" invalid host number, line ignored",
2007 "getnetnum: \"%s\" invalid host number, line ignored\n",
2014 * make up socket address. Clear it out for neatness.
2016 memset((void *)addr, 0, sizeof(struct sockaddr_in));
2017 addr->sin_family = AF_INET;
2018 addr->sin_port = htons(NTP_PORT);
2019 addr->sin_addr.s_addr = htonl(netnum);
2022 printf("getnetnum given %s, got %s (%lx)\n",
2023 num, ntoa(addr), (u_long)netnum);
2031 * catchchild - receive the resolver's exit status
2039 * We only start up one child, and if we're here
2040 * it should have already exited. Hence the following
2041 * shouldn't hang. If it does, please tell me.
2043 #if !defined (SYS_WINNT) && !defined(SYS_VXWORKS)
2045 #endif /* SYS_WINNT && VXWORKS*/
2051 * save_resolve - save configuration info into a file for later name resolution
2067 if (res_fp == NULL) {
2069 (void) strcpy(res_file, RES_TEMPFILE);
2071 /* no /tmp directory under NT */
2074 if(!(len = GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) {
2075 msyslog(LOG_ERR, "cannot get pathname for temporary directory: %m");
2078 (void) strcat(res_file, "ntpdXXXXXX");
2080 #endif /* SYS_WINNT */
2086 if ((fd = mkstemp(res_file)) != -1)
2087 res_fp = fdopen(fd, "r+");
2090 (void) mktemp(res_file);
2091 res_fp = fopen(res_file, "w");
2093 if (res_fp == NULL) {
2094 msyslog(LOG_ERR, "open failed for %s: %m", res_file);
2100 printf("resolving %s\n", name);
2104 (void)fprintf(res_fp, "%s %d %d %d %d %d %d %d %s\n", name,
2105 mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr);
2108 printf("config: %s %d %d %d %d %x %d %08x %s\n", name, mode,
2109 version, minpoll, maxpoll, flags, ttl, keyid, keystr);
2112 #else /* SYS_VXWORKS */
2113 /* save resolve info to a struct */
2114 #endif /* SYS_VXWORKS */
2119 * abort_resolve - terminate the resolver stuff and delete the file
2125 * In an ideal world we would might reread the file and
2126 * log the hosts which aren't getting configured. Since
2127 * this is too much work, however, just close and delete
2131 (void) fclose(res_fp);
2134 #ifndef SYS_VXWORKS /* we don't open the file to begin with */
2136 (void) unlink(res_file);
2138 (void) delete(res_file);
2140 #endif /* SYS_VXWORKS */
2145 * do_resolve_internal - start up the resolver function (not program)
2148 * On VMS, this routine will simply refuse to resolve anything.
2150 * Possible implementation: keep `res_file' in memory, do async
2151 * name resolution via QIO, update from within completion AST.
2152 * I'm unlikely to find the time for doing this, though. -wjm
2155 do_resolve_internal(void)
2159 if (res_fp == NULL) {
2162 "do_resolve_internal: Fatal: res_fp == NULL");
2166 /* we are done with this now */
2167 (void) fclose(res_fp);
2170 #if !defined(VMS) && !defined (SYS_VXWORKS)
2171 req_file = res_file; /* set up pointer to res file */
2173 (void) signal_no_reset(SIGCHLD, catchchild);
2179 * this used to close everything
2180 * I don't think this is necessary
2183 * To the unknown commenter above:
2184 * Well, I think it's better to clean up
2185 * after oneself. I have had problems with
2186 * refclock-io when intres was running - things
2187 * where fine again when ntpintres was gone.
2188 * So some systems react erratic at least.
2193 * Further debugging has proven that the above is
2194 * absolutely harmful. The internal resolver
2195 * is still in the SIGIO process group and the lingering
2196 * async io information causes it to process requests from
2197 * all file decriptor causing a race between the NTP daemon
2198 * and the resolver. which then eats data when it wins 8-(.
2199 * It is absolutly necessary to kill any IO associations
2200 * shared with the NTP daemon.
2202 * We also block SIGIO (currently no ports means to
2203 * disable the signal handle for IO).
2205 * Thanks to wgstuken@informatik.uni-erlangen.de to notice
2206 * that it is the ntp-resolver child running into trouble.
2214 (void) signal_no_reset(SIGCHLD, SIG_DFL);
2222 openlog("ntpd_initres", LOG_PID);
2223 # else /* LOG_DAEMON */
2226 # define LOG_NTP LOG_DAEMON
2228 openlog("ntpd_initres", LOG_PID | LOG_NDELAY, LOG_NTP);
2229 #ifndef SYS_CYGWIN32
2232 setlogmask(LOG_UPTO(LOG_DEBUG));
2235 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
2236 # endif /* LOG_DAEMON */
2242 * If we got here, the intres code screwed up.
2243 * Print something so we don't die without complaint
2245 msyslog(LOG_ERR, "call to ntp_intres lost");
2250 /* vxWorks spawns a thread... -casey */
2251 i = sp (ntp_intres);
2252 /*i = taskSpawn("ntp_intres",100,VX_FP_TASK,20000,ntp_intres);*/
2255 msyslog(LOG_ERR, "fork() failed, can't start ntp_intres: %m");
2256 (void) signal_no_reset(SIGCHLD, SIG_DFL);
2259 #else /* SYS_WINNT */
2261 /* NT's equivalent of fork() is _spawn(), but the start point
2262 * of the new process is an executable filename rather than
2263 * a function name as desired here.
2267 if (!(ResolverThreadHandle = CreateThread(
2268 NULL, /* no security attributes */
2269 0, /* use default stack size */
2270 (LPTHREAD_START_ROUTINE) ntp_intres, /* thread function */
2271 NULL, /* argument to thread function */
2272 0, /* use default creation flags */
2273 &dwThreadId))) { /* returns the thread identifier */
2274 msyslog(LOG_ERR, "CreateThread() failed, can't start ntp_intres");
2278 #endif /* SYS_WINNT */
2279 #else /* VMS VX_WORKS */
2281 "Name resolution not implemented for VMS - use numeric addresses");
2283 #endif /* VMS VX_WORKS */