]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - ntpdate/ntpdate.c
Fix compilation with gcc 4.1. This is imported on the vendor branch as it
[FreeBSD/FreeBSD.git] / ntpdate / ntpdate.c
1 /*
2  * ntpdate - set the time of day by polling one or more NTP servers
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #ifdef HAVE_NETINFO
10 #include <netinfo/ni.h>
11 #endif
12
13 #include "ntp_machine.h"
14 #include "ntp_fp.h"
15 #include "ntp.h"
16 #include "ntp_io.h"
17 #include "ntp_unixtime.h"
18 #include "ntpdate.h"
19 #include "ntp_string.h"
20 #include "ntp_syslog.h"
21 #include "ntp_select.h"
22 #include "ntp_stdlib.h"
23
24 #ifdef HAVE_UNISTD_H
25 # include <unistd.h>
26 #endif
27
28 #include <stdio.h>
29 #include <signal.h>
30 #include <ctype.h>
31 #ifdef HAVE_POLL_H
32 # include <poll.h>
33 #endif
34 #ifndef SYS_WINNT
35 # include <netdb.h>
36 # ifdef HAVE_SYS_SIGNAL_H
37 #  include <sys/signal.h>
38 # else
39 #  include <signal.h>
40 # endif
41 # ifdef HAVE_SYS_IOCTL_H
42 #  include <sys/ioctl.h>
43 # endif
44 #endif /* SYS_WINNT */
45 #ifdef HAVE_SYS_RESOURCE_H
46 # include <sys/resource.h>
47 #endif /* HAVE_SYS_RESOURCE_H */
48
49 #include <arpa/inet.h>
50
51 #ifdef __QNXNTO__
52 # include "adjtime.h"
53 #endif
54
55 #ifdef SYS_VXWORKS
56 # include "ioLib.h"
57 # include "sockLib.h"
58 # include "timers.h"
59
60 /* select wants a zero structure ... */
61 struct timeval timeout = {0,0};
62 #else
63 struct timeval timeout = {60,0};
64 #endif
65
66 #ifdef HAVE_NETINFO
67 #include <netinfo/ni.h>
68 #endif
69
70 #include "recvbuff.h"
71
72 #ifdef SYS_WINNT
73 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
74 #define EAFNOSUPPORT    WSAEAFNOSUPPORT
75 #define EPFNOSUPPORT    WSAEPFNOSUPPORT
76 #define TARGET_RESOLUTION 1  /* Try for 1-millisecond accuracy
77                                 on Windows NT timers. */
78 #pragma comment(lib, "winmm")
79 #endif /* SYS_WINNT */
80
81 /*
82  * Scheduling priority we run at
83  */
84 #ifndef SYS_VXWORKS
85 # define        NTPDATE_PRIO    (-12)
86 #else
87 # define        NTPDATE_PRIO    (100)
88 #endif
89
90 #if defined(HAVE_TIMER_SETTIME) || defined (HAVE_TIMER_CREATE)
91 /* POSIX TIMERS - vxWorks doesn't have itimer - casey */
92 static timer_t ntpdate_timerid;
93 #endif
94
95 /*
96  * Compatibility stuff for Version 2
97  */
98 #define NTP_MAXSKW      0x28f   /* 0.01 sec in fp format */
99 #define NTP_MINDIST 0x51f       /* 0.02 sec in fp format */
100 #define PEER_MAXDISP    (64*FP_SECOND)  /* maximum dispersion (fp 64) */
101 #define NTP_INFIN       15      /* max stratum, infinity a la Bellman-Ford */
102 #define NTP_MAXWGT      (8*FP_SECOND)   /* maximum select weight 8 seconds */
103 #define NTP_MAXLIST 5   /* maximum select list size */
104 #define PEER_SHIFT      8       /* 8 suitable for crystal time base */
105
106 /*
107  * Debugging flag
108  */
109 volatile int debug = 0;
110
111 /*
112  * File descriptor masks etc. for call to select
113  */
114
115 int ai_fam_templ;
116 int nbsock;
117 SOCKET fd[MAX_AF];      /* support up to 2 sockets */
118 int fd_family[MAX_AF];  /* to remember the socket family */
119 #ifdef HAVE_POLL_H
120 struct pollfd fdmask[MAX_AF];
121 #else
122 fd_set fdmask;
123 int maxfd;
124 #endif
125 int polltest = 0;
126
127 /*
128  * Initializing flag.  All async routines watch this and only do their
129  * thing when it is clear.
130  */
131 int initializing = 1;
132
133 /*
134  * Alarm flag.  Set when an alarm occurs
135  */
136 volatile int alarm_flag = 0;
137
138 /*
139  * Simple query flag.
140  */
141 int simple_query = 0;
142
143 /*
144  * Unpriviledged port flag.
145  */
146 int unpriv_port = 0;
147
148 /*
149  * Time to spend measuring drift rate
150  */
151 int rate = 0;
152
153 /*
154  * Program name.
155  */
156 char *progname;
157
158 /*
159  * Systemwide parameters and flags
160  */
161 int sys_samples = DEFSAMPLES;   /* number of samples/server */
162 u_long sys_timeout = DEFTIMEOUT; /* timeout time, in TIMER_HZ units */
163 struct server *sys_servers;     /* the server list */
164 int sys_numservers = 0;         /* number of servers to poll */
165 int sys_authenticate = 0;       /* true when authenticating */
166 u_int32 sys_authkey = 0;        /* set to authentication key in use */
167 u_long sys_authdelay = 0;       /* authentication delay */
168 int sys_version = NTP_VERSION;  /* version to poll with */
169
170 /*
171  * The current internal time
172  */
173 u_long current_time = 0;
174
175 /*
176  * Counter for keeping track of completed servers
177  */
178 int complete_servers = 0;
179
180 /*
181  * File of encryption keys
182  */
183
184 #ifndef KEYFILE
185 # ifndef SYS_WINNT
186 #define KEYFILE         "/etc/ntp.keys"
187 # else
188 #define KEYFILE         "%windir%\\ntp.keys"
189 # endif /* SYS_WINNT */
190 #endif /* KEYFILE */
191
192 #ifndef SYS_WINNT
193 const char *key_file = KEYFILE;
194 #else
195 char key_file_storage[MAX_PATH+1], *key_file ;
196 #endif   /* SYS_WINNT */
197
198 /*
199  * Miscellaneous flags
200  */
201 int verbose = 0;
202 int always_step = 0;
203 int never_step = 0;
204
205 int     ntpdatemain P((int, char **));
206
207 static  void    transmit        P((struct server *));
208 static  void    receive         P((struct recvbuf *));
209 static  void    server_data P((struct server *, s_fp, l_fp *, u_fp));
210 static  void    clock_filter    P((struct server *));
211 static  struct server *clock_select P((void));
212 static  int clock_adjust        P((void));
213 static  void    addserver       P((char *));
214 static  struct server *findserver P((struct sockaddr_storage *));
215                 void    timer           P((void));
216 static  void    init_alarm      P((void));
217 #ifndef SYS_WINNT
218 static  RETSIGTYPE alarming P((int));
219 #endif /* SYS_WINNT */
220 static  void    init_io         P((void));
221 static  void    sendpkt         P((struct sockaddr_storage *, struct pkt *, int));
222 void    input_handler   P((void));
223
224 static  int l_adj_systime       P((l_fp *));
225 static  int l_step_systime      P((l_fp *));
226
227 static  void    printserver P((struct server *, FILE *));
228
229 #ifdef SYS_WINNT
230 int     on = 1;
231 WORD    wVersionRequested;
232 WSADATA wsaData;
233 HANDLE  TimerThreadHandle = NULL;
234 #endif /* SYS_WINNT */
235
236 #ifdef NO_MAIN_ALLOWED
237 CALL(ntpdate,"ntpdate",ntpdatemain);
238
239 void clear_globals()
240 {
241   /*
242    * Debugging flag
243    */
244   debug = 0;
245
246   ntp_optind = 0;
247   /*
248    * Initializing flag.  All async routines watch this and only do their
249    * thing when it is clear.
250    */
251   initializing = 1;
252
253   /*
254    * Alarm flag.  Set when an alarm occurs
255    */
256   alarm_flag = 0;
257
258   /*
259    * Simple query flag.
260    */
261   simple_query = 0;
262
263   /*
264    * Unpriviledged port flag.
265    */
266   unpriv_port = 0;
267
268   /*
269    * Time to spend measuring drift rate
270    */
271   rate = 0;
272   /*
273    * Systemwide parameters and flags
274    */
275   sys_numservers = 0;     /* number of servers to poll */
276   sys_authenticate = 0;   /* true when authenticating */
277   sys_authkey = 0;         /* set to authentication key in use */
278   sys_authdelay = 0;   /* authentication delay */
279   sys_version = NTP_VERSION;  /* version to poll with */
280
281   /*
282    * The current internal time
283    */
284   current_time = 0;
285
286   /*
287    * Counter for keeping track of completed servers
288    */
289   complete_servers = 0;
290   verbose = 0;
291   always_step = 0;
292   never_step = 0;
293 }
294 #endif
295
296 #ifdef HAVE_NETINFO
297 static ni_namelist *getnetinfoservers P((void));
298 #endif
299
300 /*
301  * Main program.  Initialize us and loop waiting for I/O and/or
302  * timer expiries.
303  */
304 #ifndef NO_MAIN_ALLOWED
305 int
306 main(
307         int argc,
308         char *argv[]
309         )
310 {
311         return ntpdatemain (argc, argv);
312 }
313 #endif /* NO_MAIN_ALLOWED */
314
315 int
316 ntpdatemain (
317         int argc,
318         char *argv[]
319         )
320 {
321         int was_alarmed;
322         struct recvbuf *rbuflist;
323         struct recvbuf *rbuf;
324         l_fp tmp;
325         int errflg;
326         int c;
327         int nfound;
328
329 #ifdef HAVE_NETINFO
330         ni_namelist *netinfoservers;
331 #endif
332 #ifdef SYS_WINNT
333         HANDLE process_handle;
334
335         wVersionRequested = MAKEWORD(1,1);
336         if (WSAStartup(wVersionRequested, &wsaData)) {
337                 netsyslog(LOG_ERR, "No useable winsock.dll: %m");
338                 exit(1);
339         }
340
341         key_file = key_file_storage;
342
343         if (!ExpandEnvironmentStrings(KEYFILE, key_file, MAX_PATH))
344         {
345                 msyslog(LOG_ERR, "ExpandEnvironmentStrings(KEYFILE) failed: %m\n");
346         }
347 #endif /* SYS_WINNT */
348
349 #ifdef NO_MAIN_ALLOWED
350         clear_globals();
351 #endif
352
353         errflg = 0;
354         progname = argv[0];
355         syslogit = 0;
356
357         /*
358          * Decode argument list
359          */
360         while ((c = ntp_getopt(argc, argv, "46a:bBde:k:o:p:qr:st:uv")) != EOF)
361                 switch (c)
362                 {
363                 case '4':
364                         ai_fam_templ = AF_INET;
365                         break;
366                 case '6':
367                         ai_fam_templ = AF_INET6;
368                         break;
369                 case 'a':
370                         c = atoi(ntp_optarg);
371                         sys_authenticate = 1;
372                         sys_authkey = c;
373                         break;
374                 case 'b':
375                         always_step++;
376                         never_step = 0;
377                         break;
378                 case 'B':
379                         never_step++;
380                         always_step = 0;
381                         break;
382                 case 'd':
383                         ++debug;
384                         break;
385                 case 'e':
386                         if (!atolfp(ntp_optarg, &tmp)
387                         || tmp.l_ui != 0) {
388                                 (void) fprintf(stderr,
389                                            "%s: encryption delay %s is unlikely\n",
390                                            progname, ntp_optarg);
391                                 errflg++;
392                         } else {
393                                 sys_authdelay = tmp.l_uf;
394                         }
395                         break;
396                 case 'k':
397                         key_file = ntp_optarg;
398                         break;
399                 case 'o':
400                         sys_version = atoi(ntp_optarg);
401                         break;
402                 case 'p':
403                         c = atoi(ntp_optarg);
404                         if (c <= 0 || c > NTP_SHIFT) {
405                                 (void) fprintf(stderr,
406                                            "%s: number of samples (%d) is invalid\n",
407                                            progname, c);
408                                 errflg++;
409                         } else {
410                                 sys_samples = c;
411                         }
412                         break;
413                 case 'q':
414                         simple_query = 1;
415                         break;
416                 case 'r':
417                         c = atoi(ntp_optarg);
418                         if (c <= 0 || c > (60 * 60)) {
419                                 (void) fprintf(stderr,
420                                            "%s: rate (%d) is invalid: 0 - %d\n",
421                                            progname, c, (60 * 60));
422                                 errflg++;
423                         } else {
424                                 rate = c;
425                         }
426                         break;
427                 case 's':
428                         syslogit = 1;
429                         break;
430                 case 't':
431                         if (!atolfp(ntp_optarg, &tmp)) {
432                                 (void) fprintf(stderr,
433                                            "%s: timeout %s is undecodeable\n",
434                                            progname, ntp_optarg);
435                                 errflg++;
436                         } else {
437                                 sys_timeout = ((LFPTOFP(&tmp) * TIMER_HZ)
438                                            + 0x8000) >> 16;
439                                 if (sys_timeout == 0)
440                                 sys_timeout = 1;
441                         }
442                         break;
443                 case 'v':
444                         verbose = 1;
445                         break;
446                 case 'u':
447                         unpriv_port = 1;
448                         break;
449                 case '?':
450                         ++errflg;
451                         break;
452                 default:
453                         break;
454             }
455         
456         if (errflg) {
457                 (void) fprintf(stderr,
458                     "usage: %s [-46bBdqsuv] [-a key#] [-e delay] [-k file] [-p samples] [-o version#] [-r rate] [-t timeo] server ...\n",
459                     progname);
460                 exit(2);
461         }
462
463         if (debug || simple_query) {
464 #ifdef HAVE_SETVBUF
465                 static char buf[BUFSIZ];
466                 setvbuf(stdout, buf, _IOLBF, BUFSIZ);
467 #else
468                 setlinebuf(stdout);
469 #endif
470         }
471
472         /*
473          * Logging.  Open the syslog if we have to
474          */
475         if (syslogit) {
476 #if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) && !defined SYS_CYGWIN32
477 # ifndef        LOG_DAEMON
478                 openlog("ntpdate", LOG_PID);
479 # else
480
481 #  ifndef       LOG_NTP
482 #       define  LOG_NTP LOG_DAEMON
483 #  endif
484                 openlog("ntpdate", LOG_PID | LOG_NDELAY, LOG_NTP);
485                 if (debug)
486                         setlogmask(LOG_UPTO(LOG_DEBUG));
487                 else
488                         setlogmask(LOG_UPTO(LOG_INFO));
489 # endif /* LOG_DAEMON */
490 #endif  /* SYS_WINNT */
491         }
492
493         if (debug || verbose)
494                 msyslog(LOG_NOTICE, "%s", Version);
495
496         /*
497          * Add servers we are going to be polling
498          */
499 #ifdef HAVE_NETINFO
500         netinfoservers = getnetinfoservers();
501 #endif
502
503         for ( ; ntp_optind < argc; ntp_optind++)
504                 addserver(argv[ntp_optind]);
505
506 #ifdef HAVE_NETINFO
507         if (netinfoservers) {
508                 if ( netinfoservers->ni_namelist_len &&
509                     *netinfoservers->ni_namelist_val ) {
510                         u_int servercount = 0;
511                         while (servercount < netinfoservers->ni_namelist_len) {
512                                 if (debug) msyslog(LOG_DEBUG,
513                                                    "Adding time server %s from NetInfo configuration.",
514                                                    netinfoservers->ni_namelist_val[servercount]);
515                                 addserver(netinfoservers->ni_namelist_val[servercount++]);
516                         }
517                 }
518                 ni_namelist_free(netinfoservers);
519                 free(netinfoservers);
520         }
521 #endif
522
523         if (sys_numservers == 0) {
524                 msyslog(LOG_ERR, "no servers can be used, exiting");
525                 exit(1);
526         }
527
528         /*
529          * Initialize the time of day routines and the I/O subsystem
530          */
531         if (sys_authenticate) {
532                 init_auth();
533                 if (!authreadkeys(key_file)) {
534                         msyslog(LOG_ERR, "no key file <%s>, exiting", key_file);
535                         exit(1);
536                 }
537                 authtrust(sys_authkey, 1);
538                 if (!authistrusted(sys_authkey)) {
539                         char buf[10];
540
541                         (void) sprintf(buf, "%lu", (unsigned long)sys_authkey);
542                         msyslog(LOG_ERR, "authentication key %s unknown", buf);
543                         exit(1);
544                 }
545         }
546         init_io();
547         init_alarm();
548
549         /*
550          * Set the priority.
551          */
552 #ifdef SYS_VXWORKS
553         taskPrioritySet( taskIdSelf(), NTPDATE_PRIO);
554 #endif
555 #if defined(HAVE_ATT_NICE)
556         nice (NTPDATE_PRIO);
557 #endif
558 #if defined(HAVE_BSD_NICE)
559         (void) setpriority(PRIO_PROCESS, 0, NTPDATE_PRIO);
560 #endif
561 #ifdef SYS_WINNT
562         process_handle = GetCurrentProcess();
563         if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS)) {
564                 msyslog(LOG_ERR, "SetPriorityClass failed: %m");
565         }
566 #endif /* SYS_WINNT */
567
568
569
570         initializing = 0;
571         was_alarmed = 0;
572         rbuflist = (struct recvbuf *)0;
573
574         while (complete_servers < sys_numservers) {
575 #ifdef HAVE_POLL_H
576                 struct pollfd* rdfdes;
577                 rdfdes = fdmask;
578 #else
579                 fd_set rdfdes;
580                 rdfdes = fdmask;
581 #endif
582
583                 if (alarm_flag) {               /* alarmed? */
584                         was_alarmed = 1;
585                         alarm_flag = 0;
586                 }
587                 rbuflist = getrecvbufs();       /* get received buffers */
588
589                 if (!was_alarmed && rbuflist == (struct recvbuf *)0) {
590                         /*
591                          * Nothing to do.        Wait for something.
592                          */
593 #ifdef HAVE_POLL_H
594                         nfound = poll(rdfdes, (unsigned int)nbsock, timeout.tv_sec * 1000);
595
596 #else
597                         nfound = select(maxfd, &rdfdes, (fd_set *)0,
598                                         (fd_set *)0, &timeout);
599 #endif
600                         if (nfound > 0)
601                                 input_handler();
602                         else if (
603 #ifndef SYS_WINNT
604                                 nfound == -1
605 #else
606                                 nfound == SOCKET_ERROR
607 #endif /* SYS_WINNT */
608                                 ) {
609 #ifndef SYS_WINNT
610                                 if (errno != EINTR)
611 #endif
612                                         netsyslog(LOG_ERR,
613 #ifdef HAVE_POLL_H
614                                                 "poll() error: %m"
615 #else
616                                                 "select() error: %m"
617 #endif
618                                                 );
619                         } else {
620 #ifndef SYS_VXWORKS
621                                 netsyslog(LOG_DEBUG,
622 #ifdef HAVE_POLL_H
623                                         "poll(): nfound = %d, error: %m",
624 #else
625                                         "select(): nfound = %d, error: %m",
626 #endif
627                                         nfound);
628 #endif
629                         }
630                         if (alarm_flag) {               /* alarmed? */
631                                 was_alarmed = 1;
632                                 alarm_flag = 0;
633                         }
634                         rbuflist = getrecvbufs();       /* get received buffers */
635                 }
636
637                 /*
638                  * Out here, signals are unblocked.  Call receive
639                  * procedure for each incoming packet.
640                  */
641                 while (rbuflist != (struct recvbuf *)0) {
642                         rbuf = rbuflist;
643                         rbuflist = rbuf->next;
644                         receive(rbuf);
645                         freerecvbuf(rbuf);
646                 }
647
648                 /*
649                  * Call timer to process any timeouts
650                  */
651                 if (was_alarmed) {
652                         timer();
653                         was_alarmed = 0;
654                 }
655
656                 /*
657                  * Go around again
658                  */
659         }
660
661         /*
662          * When we get here we've completed the polling of all servers.
663          * Adjust the clock, then exit.
664          */
665 #ifdef SYS_WINNT
666         WSACleanup();
667 #endif
668 #ifdef SYS_VXWORKS
669         close (fd);
670         timer_delete(ntpdate_timerid);
671 #endif
672
673         return clock_adjust();
674 }
675
676
677 /*
678  * transmit - transmit a packet to the given server, or mark it completed.
679  *                This is called by the timeout routine and by the receive
680  *                procedure.
681  */
682 static void
683 transmit(
684         register struct server *server
685         )
686 {
687         struct pkt xpkt;
688
689         if (debug)
690                 printf("transmit(%s)\n", stoa(&(server->srcadr)));
691
692         if (server->filter_nextpt < server->xmtcnt) {
693                 l_fp ts;
694                 /*
695                  * Last message to this server timed out.  Shift
696                  * zeros into the filter.
697                  */
698                 L_CLR(&ts);
699                 server_data(server, 0, &ts, 0);
700         }
701
702         if ((int)server->filter_nextpt >= sys_samples) {
703                 /*
704                  * Got all the data we need.  Mark this guy
705                  * completed and return.
706                  */
707                 server->event_time = 0;
708                 complete_servers++;
709                 return;
710         }
711
712         /*
713          * If we're here, send another message to the server.    Fill in
714          * the packet and let 'er rip.
715          */
716         xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
717                                          sys_version, MODE_CLIENT);
718         xpkt.stratum = STRATUM_TO_PKT(STRATUM_UNSPEC);
719         xpkt.ppoll = NTP_MINPOLL;
720         xpkt.precision = NTPDATE_PRECISION;
721         xpkt.rootdelay = htonl(NTPDATE_DISTANCE);
722         xpkt.rootdispersion = htonl(NTPDATE_DISP);
723         xpkt.refid = htonl(NTPDATE_REFID);
724         L_CLR(&xpkt.reftime);
725         L_CLR(&xpkt.org);
726         L_CLR(&xpkt.rec);
727
728         /*
729          * Determine whether to authenticate or not.    If so,
730          * fill in the extended part of the packet and do it.
731          * If not, just timestamp it and send it away.
732          */
733         if (sys_authenticate) {
734                 int len;
735
736                 xpkt.exten[0] = htonl(sys_authkey);
737                 get_systime(&server->xmt);
738                 L_ADDUF(&server->xmt, sys_authdelay);
739                 HTONL_FP(&server->xmt, &xpkt.xmt);
740                 len = authencrypt(sys_authkey, (u_int32 *)&xpkt, LEN_PKT_NOMAC);
741                 sendpkt(&(server->srcadr), &xpkt, (int)(LEN_PKT_NOMAC + len));
742
743                 if (debug > 1)
744                         printf("transmit auth to %s\n",
745                            stoa(&(server->srcadr)));
746         } else {
747                 get_systime(&(server->xmt));
748                 HTONL_FP(&server->xmt, &xpkt.xmt);
749                 sendpkt(&(server->srcadr), &xpkt, LEN_PKT_NOMAC);
750
751                 if (debug > 1)
752                         printf("transmit to %s\n", stoa(&(server->srcadr)));
753         }
754
755         /*
756          * Update the server timeout and transmit count
757          */
758         server->event_time = current_time + sys_timeout;
759         server->xmtcnt++;
760 }
761
762
763 /*
764  * receive - receive and process an incoming frame
765  */
766 static void
767 receive(
768         struct recvbuf *rbufp
769         )
770 {
771         register struct pkt *rpkt;
772         register struct server *server;
773         register s_fp di;
774         l_fp t10, t23, tmp;
775         l_fp org;
776         l_fp rec;
777         l_fp ci;
778         int has_mac;
779         int is_authentic;
780
781         if (debug)
782                 printf("receive(%s)\n", stoa(&rbufp->recv_srcadr));
783         /*
784          * Check to see if the packet basically looks like something
785          * intended for us.
786          */
787         if (rbufp->recv_length == LEN_PKT_NOMAC)
788                 has_mac = 0;
789         else if (rbufp->recv_length >= LEN_PKT_NOMAC)
790                 has_mac = 1;
791         else {
792                 if (debug)
793                         printf("receive: packet length %d\n",
794                            rbufp->recv_length);
795                 return;                 /* funny length packet */
796         }
797
798         rpkt = &(rbufp->recv_pkt);
799         if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||
800                 PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {
801                 return;
802         }
803
804         if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER
805                  && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE)
806                 || rpkt->stratum >= STRATUM_UNSPEC) {
807                 if (debug)
808                         printf("receive: mode %d stratum %d\n",
809                            PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
810                 return;
811         }
812
813         /*
814          * So far, so good.  See if this is from a server we know.
815          */
816         server = findserver(&(rbufp->recv_srcadr));
817         if (server == NULL) {
818                 if (debug)
819                         printf("receive: server not found\n");
820                 return;
821         }
822
823         /*
824          * Decode the org timestamp and make sure we're getting a response
825          * to our last request.
826          */
827         NTOHL_FP(&rpkt->org, &org);
828         if (!L_ISEQU(&org, &server->xmt)) {
829                 if (debug)
830                         printf("receive: pkt.org and peer.xmt differ\n");
831                 return;
832         }
833
834         /*
835          * Check out the authenticity if we're doing that.
836          */
837         if (!sys_authenticate)
838                 is_authentic = 1;
839         else {
840                 is_authentic = 0;
841
842                 if (debug > 3)
843                         printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n",
844                            (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey,
845                            (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt,
846                                 LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC)));
847
848                 if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey &&
849                         authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC,
850                         (int)(rbufp->recv_length - LEN_PKT_NOMAC)))
851                         is_authentic = 1;
852                 if (debug)
853                         printf("receive: authentication %s\n",
854                            is_authentic ? "passed" : "failed");
855         }
856         server->trust <<= 1;
857         if (!is_authentic)
858                 server->trust |= 1;
859
860         /*
861          * Looks good.  Record info from the packet.
862          */
863         server->leap = PKT_LEAP(rpkt->li_vn_mode);
864         server->stratum = PKT_TO_STRATUM(rpkt->stratum);
865         server->precision = rpkt->precision;
866         server->rootdelay = ntohl(rpkt->rootdelay);
867         server->rootdispersion = ntohl(rpkt->rootdispersion);
868         server->refid = rpkt->refid;
869         NTOHL_FP(&rpkt->reftime, &server->reftime);
870         NTOHL_FP(&rpkt->rec, &rec);
871         NTOHL_FP(&rpkt->xmt, &server->org);
872
873         /*
874          * Make sure the server is at least somewhat sane.      If not, try
875          * again.
876          */
877         if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) {
878                 transmit(server);
879                 return;
880         }
881
882         /*
883          * Calculate the round trip delay (di) and the clock offset (ci).
884          * We use the equations (reordered from those in the spec):
885          *
886          * d = (t2 - t3) - (t1 - t0)
887          * c = ((t2 - t3) + (t1 - t0)) / 2
888          */
889         t10 = server->org;              /* pkt.xmt == t1 */
890         L_SUB(&t10, &rbufp->recv_time); /* recv_time == t0*/
891
892         t23 = rec;                      /* pkt.rec == t2 */
893         L_SUB(&t23, &org);              /* pkt->org == t3 */
894
895         /* now have (t2 - t3) and (t0 - t1).    Calculate (ci) and (di) */
896         /*
897          * Calculate (ci) = ((t1 - t0) / 2) + ((t2 - t3) / 2)
898          * For large offsets this may prevent an overflow on '+'
899          */
900         ci = t10;
901         L_RSHIFT(&ci);
902         tmp = t23;
903         L_RSHIFT(&tmp);
904         L_ADD(&ci, &tmp);
905
906         /*
907          * Calculate di in t23 in full precision, then truncate
908          * to an s_fp.
909          */
910         L_SUB(&t23, &t10);
911         di = LFPTOFP(&t23);
912
913         if (debug > 3)
914                 printf("offset: %s, delay %s\n", lfptoa(&ci, 6), fptoa(di, 5));
915
916         di += (FP_SECOND >> (-(int)NTPDATE_PRECISION))
917                 + (FP_SECOND >> (-(int)server->precision)) + NTP_MAXSKW;
918
919         if (di <= 0) {          /* value still too raunchy to use? */
920                 L_CLR(&ci);
921                 di = 0;
922         } else {
923                 di = max(di, NTP_MINDIST);
924         }
925
926         /*
927          * Shift this data in, then transmit again.
928          */
929         server_data(server, (s_fp) di, &ci, 0);
930         transmit(server);
931 }
932
933
934 /*
935  * server_data - add a sample to the server's filter registers
936  */
937 static void
938 server_data(
939         register struct server *server,
940         s_fp d,
941         l_fp *c,
942         u_fp e
943         )
944 {
945         u_short i;
946
947         i = server->filter_nextpt;
948         if (i < NTP_SHIFT) {
949                 server->filter_delay[i] = d;
950                 server->filter_offset[i] = *c;
951                 server->filter_soffset[i] = LFPTOFP(c);
952                 server->filter_error[i] = e;
953                 server->filter_nextpt = (u_short)(i + 1);
954         }
955 }
956
957
958 /*
959  * clock_filter - determine a server's delay, dispersion and offset
960  */
961 static void
962 clock_filter(
963         register struct server *server
964         )
965 {
966         register int i, j;
967         int ord[NTP_SHIFT];
968
969         /*
970          * Sort indices into increasing delay order
971          */
972         for (i = 0; i < sys_samples; i++)
973                 ord[i] = i;
974
975         for (i = 0; i < (sys_samples-1); i++) {
976                 for (j = i+1; j < sys_samples; j++) {
977                         if (server->filter_delay[ord[j]] == 0)
978                                 continue;
979                         if (server->filter_delay[ord[i]] == 0
980                                 || (server->filter_delay[ord[i]]
981                                 > server->filter_delay[ord[j]])) {
982                                 register int tmp;
983
984                                 tmp = ord[i];
985                                 ord[i] = ord[j];
986                                 ord[j] = tmp;
987                         }
988                 }
989         }
990
991         /*
992          * Now compute the dispersion, and assign values to delay and
993          * offset.      If there are no samples in the register, delay and
994          * offset go to zero and dispersion is set to the maximum.
995          */
996         if (server->filter_delay[ord[0]] == 0) {
997                 server->delay = 0;
998                 L_CLR(&server->offset);
999                 server->soffset = 0;
1000                 server->dispersion = PEER_MAXDISP;
1001         } else {
1002                 register s_fp d;
1003
1004                 server->delay = server->filter_delay[ord[0]];
1005                 server->offset = server->filter_offset[ord[0]];
1006                 server->soffset = LFPTOFP(&server->offset);
1007                 server->dispersion = 0;
1008                 for (i = 1; i < sys_samples; i++) {
1009                         if (server->filter_delay[ord[i]] == 0)
1010                                 d = PEER_MAXDISP;
1011                         else {
1012                                 d = server->filter_soffset[ord[i]]
1013                                         - server->filter_soffset[ord[0]];
1014                                 if (d < 0)
1015                                         d = -d;
1016                                 if (d > PEER_MAXDISP)
1017                                         d = PEER_MAXDISP;
1018                         }
1019                         /*
1020                          * XXX This *knows* PEER_FILTER is 1/2
1021                          */
1022                         server->dispersion += (u_fp)(d) >> i;
1023                 }
1024         }
1025         /*
1026          * We're done
1027          */
1028 }
1029
1030
1031 /*
1032  * clock_select - select the pick-of-the-litter clock from the samples
1033  *                we've got.
1034  */
1035 static struct server *
1036 clock_select(void)
1037 {
1038         register struct server *server;
1039         register int i;
1040         register int nlist;
1041         register s_fp d;
1042         register int j;
1043         register int n;
1044         s_fp local_threshold;
1045         struct server *server_list[NTP_MAXCLOCK];
1046         u_fp server_badness[NTP_MAXCLOCK];
1047         struct server *sys_server;
1048
1049         /*
1050          * This first chunk of code is supposed to go through all
1051          * servers we know about to find the NTP_MAXLIST servers which
1052          * are most likely to succeed.  We run through the list
1053          * doing the sanity checks and trying to insert anyone who
1054          * looks okay.  We are at all times aware that we should
1055          * only keep samples from the top two strata and we only need
1056          * NTP_MAXLIST of them.
1057          */
1058         nlist = 0;      /* none yet */
1059         for (server = sys_servers; server != NULL; server = server->next_server) {
1060                 if (server->delay == 0) {
1061                         if (debug)
1062                                 printf("%s: Server dropped: no data\n", ntoa(&server->srcadr));
1063                         continue;   /* no data */
1064                 }
1065                 if (server->stratum > NTP_INFIN) {
1066                         if (debug)
1067                                 printf("%s: Server dropped: strata too high\n", ntoa(&server->srcadr));
1068                         continue;   /* stratum no good */
1069                 }
1070                 if (server->delay > NTP_MAXWGT) {
1071                         if (debug)
1072                                 printf("%s: Server dropped: server too far away\n", 
1073                                        ntoa(&server->srcadr));
1074                         continue;   /* too far away */
1075                 }
1076                 if (server->leap == LEAP_NOTINSYNC) {
1077                         if (debug)
1078                                 printf("%s: Server dropped: Leap not in sync\n", ntoa(&server->srcadr));
1079                         continue;   /* he's in trouble */
1080                 }
1081                 if (!L_ISHIS(&server->org, &server->reftime)) {
1082                         if (debug)
1083                                 printf("%s: Server dropped: server is very broken\n", 
1084                                        ntoa(&server->srcadr));
1085                         continue;   /* very broken host */
1086                 }
1087                 if ((server->org.l_ui - server->reftime.l_ui)
1088                     >= NTP_MAXAGE) {
1089                         if (debug)
1090                                 printf("%s: Server dropped: Server has gone too long without sync\n", 
1091                                        ntoa(&server->srcadr));
1092                         continue;       /* too long without sync */
1093                 }
1094                 if (server->trust != 0) {
1095                         if (debug)
1096                                 printf("%s: Server dropped: Server is untrusted\n",
1097                                        ntoa(&server->srcadr));
1098                         continue;
1099                 }
1100
1101                 /*
1102                  * This one seems sane.  Find where he belongs
1103                  * on the list.
1104                  */
1105                 d = server->dispersion + server->dispersion;
1106                 for (i = 0; i < nlist; i++)
1107                         if (server->stratum <= server_list[i]->stratum)
1108                         break;
1109                 for ( ; i < nlist; i++) {
1110                         if (server->stratum < server_list[i]->stratum)
1111                                 break;
1112                         if (d < (s_fp) server_badness[i])
1113                                 break;
1114                 }
1115
1116                 /*
1117                  * If i points past the end of the list, this
1118                  * guy is a loser, else stick him in.
1119                  */
1120                 if (i >= NTP_MAXLIST)
1121                         continue;
1122                 for (j = nlist; j > i; j--)
1123                         if (j < NTP_MAXLIST) {
1124                                 server_list[j] = server_list[j-1];
1125                                 server_badness[j]
1126                                         = server_badness[j-1];
1127                         }
1128
1129                 server_list[i] = server;
1130                 server_badness[i] = d;
1131                 if (nlist < NTP_MAXLIST)
1132                         nlist++;
1133         }
1134
1135         /*
1136          * Got the five-or-less best.    Cut the list where the number of
1137          * strata exceeds two.
1138          */
1139         j = 0;
1140         for (i = 1; i < nlist; i++)
1141                 if (server_list[i]->stratum > server_list[i-1]->stratum)
1142                 if (++j == 2) {
1143                         nlist = i;
1144                         break;
1145                 }
1146
1147         /*
1148          * Whew!  What we should have by now is 0 to 5 candidates for
1149          * the job of syncing us.  If we have none, we're out of luck.
1150          * If we have one, he's a winner.  If we have more, do falseticker
1151          * detection.
1152          */
1153
1154         if (nlist == 0)
1155                 sys_server = 0;
1156         else if (nlist == 1) {
1157                 sys_server = server_list[0];
1158         } else {
1159                 /*
1160                  * Re-sort by stratum, bdelay estimate quality and
1161                  * server.delay.
1162                  */
1163                 for (i = 0; i < nlist-1; i++)
1164                         for (j = i+1; j < nlist; j++) {
1165                                 if (server_list[i]->stratum
1166                                 < server_list[j]->stratum)
1167                                 break;  /* already sorted by stratum */
1168                                 if (server_list[i]->delay
1169                                 < server_list[j]->delay)
1170                                 continue;
1171                                 server = server_list[i];
1172                                 server_list[i] = server_list[j];
1173                                 server_list[j] = server;
1174                         }
1175
1176                 /*
1177                  * Calculate the fixed part of the dispersion limit
1178                  */
1179                 local_threshold = (FP_SECOND >> (-(int)NTPDATE_PRECISION))
1180                         + NTP_MAXSKW;
1181
1182                 /*
1183                  * Now drop samples until we're down to one.
1184                  */
1185                 while (nlist > 1) {
1186                         for (n = 0; n < nlist; n++) {
1187                                 server_badness[n] = 0;
1188                                 for (j = 0; j < nlist; j++) {
1189                                         if (j == n) /* with self? */
1190                                                 continue;
1191                                         d = server_list[j]->soffset
1192                                                 - server_list[n]->soffset;
1193                                         if (d < 0)      /* absolute value */
1194                                                 d = -d;
1195                                         /*
1196                                          * XXX This code *knows* that
1197                                          * NTP_SELECT is 3/4
1198                                          */
1199                                         for (i = 0; i < j; i++)
1200                                                 d = (d>>1) + (d>>2);
1201                                         server_badness[n] += d;
1202                                 }
1203                         }
1204
1205                         /*
1206                          * We now have an array of nlist badness
1207                          * coefficients.        Find the badest.  Find
1208                          * the minimum precision while we're at
1209                          * it.
1210                          */
1211                         i = 0;
1212                         n = server_list[0]->precision;;
1213                         for (j = 1; j < nlist; j++) {
1214                                 if (server_badness[j] >= server_badness[i])
1215                                         i = j;
1216                                 if (n > server_list[j]->precision)
1217                                         n = server_list[j]->precision;
1218                         }
1219
1220                         /*
1221                          * i is the index of the server with the worst
1222                          * dispersion.  If his dispersion is less than
1223                          * the threshold, stop now, else delete him and
1224                          * continue around again.
1225                          */
1226                         if ( (s_fp) server_badness[i] < (local_threshold
1227                                                          + (FP_SECOND >> (-n))))
1228                                 break;
1229                         for (j = i + 1; j < nlist; j++)
1230                                 server_list[j-1] = server_list[j];
1231                         nlist--;
1232                 }
1233
1234                 /*
1235                  * What remains is a list of less than 5 servers.  Take
1236                  * the best.
1237                  */
1238                 sys_server = server_list[0];
1239         }
1240
1241         /*
1242          * That's it.    Return our server.
1243          */
1244         return sys_server;
1245 }
1246
1247
1248 /*
1249  * clock_adjust - process what we've received, and adjust the time
1250  *               if we got anything decent.
1251  */
1252 static int
1253 clock_adjust(void)
1254 {
1255         register struct server *sp, *server;
1256         s_fp absoffset;
1257         int dostep;
1258
1259         for (sp = sys_servers; sp != NULL; sp = sp->next_server)
1260                 clock_filter(sp);
1261         server = clock_select();
1262
1263         if (debug || simple_query) {
1264                 for (sp = sys_servers; sp != NULL; sp = sp->next_server)
1265                         printserver(sp, stdout);
1266         }
1267
1268         if (server == 0) {
1269                 msyslog(LOG_ERR,
1270                         "no server suitable for synchronization found");
1271                 return(1);
1272         }
1273
1274         if (always_step) {
1275                 dostep = 1;
1276         } else if (never_step) {
1277                 dostep = 0;
1278         } else {
1279                 absoffset = server->soffset;
1280                 if (absoffset < 0)
1281                         absoffset = -absoffset;
1282                 dostep = (absoffset >= NTPDATE_THRESHOLD || absoffset < 0);
1283         }
1284
1285         if (dostep) {
1286                 if (simple_query || l_step_systime(&server->offset)) {
1287                         msyslog(LOG_NOTICE, "step time server %s offset %s sec",
1288                                 stoa(&server->srcadr),
1289                                 lfptoa(&server->offset, 6));
1290                 }
1291         } else {
1292 #if !defined SYS_WINNT && !defined SYS_CYGWIN32
1293                 if (simple_query || l_adj_systime(&server->offset)) {
1294                         msyslog(LOG_NOTICE, "adjust time server %s offset %s sec",
1295                                 stoa(&server->srcadr),
1296                                 lfptoa(&server->offset, 6));
1297                 }
1298 #else
1299                 /* The NT SetSystemTimeAdjustment() call achieves slewing by
1300                  * changing the clock frequency. This means that we cannot specify
1301                  * it to slew the clock by a definite amount and then stop like
1302                  * the Unix adjtime() routine. We can technically adjust the clock
1303                  * frequency, have ntpdate sleep for a while, and then wake
1304                  * up and reset the clock frequency, but this might cause some
1305                  * grief if the user attempts to run ntpd immediately after
1306                  * ntpdate and the socket is in use.
1307                  */
1308                 printf("\nThe -b option is required by ntpdate on Windows NT platforms\n");
1309                 exit(1);
1310 #endif /* SYS_WINNT */
1311         }
1312         return(0);
1313 }
1314
1315
1316 /* XXX ELIMINATE: merge BIG slew into adj_systime in lib/systime.c */
1317 /*
1318  * addserver - determine a server's address and allocate a new structure
1319  *                 for it.
1320  */
1321 static void
1322 addserver(
1323         char *serv
1324         )
1325 {
1326         register struct server *server;
1327         /* Address infos structure to store result of getaddrinfo */
1328         struct addrinfo *addrResult;
1329         /* Address infos structure to store hints for getaddrinfo */
1330         struct addrinfo hints;
1331         /* Error variable for getaddrinfo */
1332         int error;
1333         /* Service name */
1334         char service[5];
1335         strcpy(service, "ntp");
1336
1337         /* Get host address. Looking for UDP datagram connection. */
1338         memset(&hints, 0, sizeof(hints));
1339         hints.ai_family = ai_fam_templ;
1340         hints.ai_socktype = SOCK_DGRAM;
1341
1342 #ifdef DEBUG
1343         if (debug)
1344                 printf("Looking for host %s and service %s\n", serv, service);
1345 #endif
1346
1347         error = getaddrinfo(serv, service, &hints, &addrResult);
1348         if (error != 0) {
1349                 fprintf(stderr, "Error : %s\n", gai_strerror(error));
1350                 msyslog(LOG_ERR, "can't find host %s\n", serv);
1351                 return;
1352         }
1353 #ifdef DEBUG
1354         else if (debug) {
1355                 fprintf(stderr, "host found : %s\n", stohost((struct sockaddr_storage*)addrResult->ai_addr));
1356         }
1357 #endif
1358
1359         server = (struct server *)emalloc(sizeof(struct server));
1360         memset((char *)server, 0, sizeof(struct server));
1361
1362         /* For now we only get the first returned server of the addrinfo list */
1363         memset(&(server->srcadr), 0, sizeof(struct sockaddr_storage));
1364         memcpy(&(server->srcadr), addrResult->ai_addr, addrResult->ai_addrlen);
1365         server->event_time = ++sys_numservers;
1366         if (sys_servers == NULL)
1367                 sys_servers = server;
1368         else {
1369                 struct server *sp;
1370
1371                 for (sp = sys_servers; sp->next_server != NULL;
1372                      sp = sp->next_server) ;
1373                 sp->next_server = server;
1374         }
1375 }
1376
1377
1378 /*
1379  * findserver - find a server in the list given its address
1380  * ***(For now it isn't totally AF-Independant, to check later..)
1381  */
1382 static struct server *
1383 findserver(
1384         struct sockaddr_storage *addr
1385         )
1386 {
1387         struct server *server;
1388         struct server *mc_server;
1389
1390         mc_server = NULL;
1391         if (htons(((struct sockaddr_in*)addr)->sin_port) != NTP_PORT)
1392                 return 0;
1393
1394         for (server = sys_servers; server != NULL; 
1395              server = server->next_server) {
1396                 
1397                 if (memcmp(addr, &server->srcadr, SOCKLEN(addr))==0)
1398                         return server;
1399                 /* Multicast compatibility to verify here... I'm not sure it's working */
1400                 if(addr->ss_family == AF_INET) {
1401                         if (IN_MULTICAST(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
1402                                 mc_server = server;
1403                 }
1404                 else {
1405 #ifdef AF_INET6
1406                         if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)(&server->srcadr))->sin6_addr))
1407                         mc_server = server;
1408 #else
1409                         return 0;
1410 #endif
1411                 }
1412         }
1413
1414         if (mc_server != NULL) {        
1415
1416                 struct server *sp;
1417
1418                 if (mc_server->event_time != 0) {
1419                         mc_server->event_time = 0;
1420                         complete_servers++;
1421                 }
1422
1423                 server = (struct server *)emalloc(sizeof(struct server));
1424                 memset((char *)server, 0, sizeof(struct server));
1425
1426                 memcpy(&server->srcadr, &addr, sizeof(struct sockaddr_storage));
1427
1428                 server->event_time = ++sys_numservers;
1429
1430                 for (sp = sys_servers; sp->next_server != NULL;
1431                      sp = sp->next_server) ;
1432                 sp->next_server = server;
1433                 transmit(server);
1434         }
1435         return NULL;
1436 }
1437
1438
1439 /*
1440  * timer - process a timer interrupt
1441  */
1442 void
1443 timer(void)
1444 {
1445         struct server *server;
1446
1447         /*
1448          * Bump the current idea of the time
1449          */
1450         current_time++;
1451
1452         /*
1453          * Search through the server list looking for guys
1454          * who's event timers have expired.  Give these to
1455          * the transmit routine.
1456          */
1457         for (server = sys_servers; server != NULL; 
1458              server = server->next_server) {
1459                 if (server->event_time != 0
1460                     && server->event_time <= current_time)
1461                         transmit(server);
1462         }
1463 }
1464
1465
1466 /*
1467  * The code duplication in the following subroutine sucks, but
1468  * we need to appease ansi2knr.
1469  */
1470
1471 #ifndef SYS_WINNT
1472 /*
1473  * alarming - record the occurance of an alarm interrupt
1474  */
1475 static RETSIGTYPE
1476 alarming(
1477         int sig
1478         )
1479 {
1480         alarm_flag++;
1481 }
1482 #else
1483 void CALLBACK 
1484 alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
1485 {
1486         alarm_flag++;
1487 }
1488 #endif /* SYS_WINNT */
1489
1490
1491 /*
1492  * init_alarm - set up the timer interrupt
1493  */
1494 static void
1495 init_alarm(void)
1496 {
1497 #ifndef SYS_WINNT
1498 # ifndef HAVE_TIMER_SETTIME
1499         struct itimerval itimer;
1500 # else
1501         struct itimerspec ntpdate_itimer;
1502 # endif
1503 #else
1504         TIMECAPS tc;
1505         UINT wTimerRes, wTimerID;
1506 # endif /* SYS_WINNT */
1507 #if defined SYS_CYGWIN32 || defined SYS_WINNT
1508         HANDLE hToken;
1509         TOKEN_PRIVILEGES tkp;
1510         DWORD dwUser = 0;
1511 #endif /* SYS_WINNT */
1512
1513         alarm_flag = 0;
1514
1515 #ifndef SYS_WINNT
1516 # if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME)
1517         alarm_flag = 0;
1518         /* this code was put in as setitimer() is non existant this us the
1519          * POSIX "equivalents" setup - casey
1520          */
1521         /* ntpdate_timerid is global - so we can kill timer later */
1522         if (timer_create (CLOCK_REALTIME, NULL, &ntpdate_timerid) ==
1523 #  ifdef SYS_VXWORKS
1524                 ERROR
1525 #  else
1526                 -1
1527 #  endif
1528                 )
1529         {
1530                 fprintf (stderr, "init_alarm(): timer_create (...) FAILED\n");
1531                 return;
1532         }
1533
1534         /*      TIMER_HZ = (5)
1535          * Set up the alarm interrupt.  The first comes 1/(2*TIMER_HZ)
1536          * seconds from now and they continue on every 1/TIMER_HZ seconds.
1537          */
1538         (void) signal_no_reset(SIGALRM, alarming);
1539         ntpdate_itimer.it_interval.tv_sec = ntpdate_itimer.it_value.tv_sec = 0;
1540         ntpdate_itimer.it_interval.tv_nsec = 1000000000/TIMER_HZ;
1541         ntpdate_itimer.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1);
1542         timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &ntpdate_itimer, NULL);
1543 # else
1544         /*
1545          * Set up the alarm interrupt.  The first comes 1/(2*TIMER_HZ)
1546          * seconds from now and they continue on every 1/TIMER_HZ seconds.
1547          */
1548         (void) signal_no_reset(SIGALRM, alarming);
1549         itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0;
1550         itimer.it_interval.tv_usec = 1000000/TIMER_HZ;
1551         itimer.it_value.tv_usec = 1000000/(TIMER_HZ<<1);
1552
1553         setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
1554 # endif
1555 #if defined SYS_CYGWIN32
1556         /*
1557          * Get previleges needed for fiddling with the clock
1558          */
1559
1560         /* get the current process token handle */
1561         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
1562                 msyslog(LOG_ERR, "OpenProcessToken failed: %m");
1563                 exit(1);
1564         }
1565         /* get the LUID for system-time privilege. */
1566         LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
1567         tkp.PrivilegeCount = 1;  /* one privilege to set */
1568         tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1569         /* get set-time privilege for this process. */
1570         AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);
1571         /* cannot test return value of AdjustTokenPrivileges. */
1572         if (GetLastError() != ERROR_SUCCESS)
1573                 msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
1574 #endif
1575 #else   /* SYS_WINNT */
1576         _tzset();
1577
1578         /*
1579          * Get previleges needed for fiddling with the clock
1580          */
1581
1582         /* get the current process token handle */
1583         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
1584                 msyslog(LOG_ERR, "OpenProcessToken failed: %m");
1585                 exit(1);
1586         }
1587         /* get the LUID for system-time privilege. */
1588         LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
1589         tkp.PrivilegeCount = 1;  /* one privilege to set */
1590         tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1591         /* get set-time privilege for this process. */
1592         AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);
1593         /* cannot test return value of AdjustTokenPrivileges. */
1594         if (GetLastError() != ERROR_SUCCESS)
1595                 msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
1596
1597         /*
1598          * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds
1599          * Under Win/NT, expiry of timer interval leads to invocation
1600          * of a callback function (on a different thread) rather than
1601          * generating an alarm signal
1602          */
1603
1604         /* determine max and min resolution supported */
1605         if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
1606                 msyslog(LOG_ERR, "timeGetDevCaps failed: %m");
1607                 exit(1);
1608         }
1609         wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
1610         /* establish the minimum timer resolution that we'll use */
1611         timeBeginPeriod(wTimerRes);
1612
1613         /* start the timer event */
1614         wTimerID = timeSetEvent(
1615                 (UINT) (1000/TIMER_HZ),    /* Delay */
1616                 wTimerRes,                       /* Resolution */
1617                 (LPTIMECALLBACK) alarming, /* Callback function */
1618                 (DWORD) dwUser,          /* User data */
1619                 TIME_PERIODIC);          /* Event type (periodic) */
1620         if (wTimerID == 0) {
1621                 msyslog(LOG_ERR, "timeSetEvent failed: %m");
1622                 exit(1);
1623         }
1624 #endif /* SYS_WINNT */
1625 }
1626
1627
1628
1629
1630 /*
1631  * We do asynchronous input using the SIGIO facility.  A number of
1632  * recvbuf buffers are preallocated for input.  In the signal
1633  * handler we poll to see if the socket is ready and read the
1634  * packets from it into the recvbuf's along with a time stamp and
1635  * an indication of the source host and the interface it was received
1636  * through.  This allows us to get as accurate receive time stamps
1637  * as possible independent of other processing going on.
1638  *
1639  * We allocate a number of recvbufs equal to the number of servers
1640  * plus 2.      This should be plenty.
1641  */
1642
1643
1644 /*
1645  * init_io - initialize I/O data and open socket
1646  */
1647 static void
1648 init_io(void)
1649 {
1650         struct addrinfo *res, *ressave;
1651         struct addrinfo hints;
1652         char service[5];
1653         int optval = 1;
1654
1655         /*
1656          * Init buffer free list and stat counters
1657          */
1658         init_recvbuff(sys_numservers + 2);
1659
1660         /*
1661          * Open the socket
1662          */
1663
1664         strcpy(service, "ntp");
1665
1666         /*
1667          * Init hints addrinfo structure
1668          */
1669         memset(&hints, 0, sizeof(hints));
1670         hints.ai_flags = AI_PASSIVE;
1671         hints.ai_socktype = SOCK_DGRAM;
1672
1673         if(getaddrinfo(NULL, service, &hints, &res) != 0) {
1674                msyslog(LOG_ERR, "getaddrinfo() failed: %m");
1675                exit(1);
1676                /*NOTREACHED*/
1677         }
1678
1679         /* Remember the address of the addrinfo structure chain */
1680         ressave = res;
1681
1682         /*
1683          * For each structure returned, open and bind socket
1684          */
1685         for(nbsock = 0; (nbsock < MAX_AF) && res ; res = res->ai_next) {
1686         /* create a datagram (UDP) socket */
1687            if ((fd[nbsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
1688                 if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT ||
1689                     errno == EPFNOSUPPORT)
1690                         continue;
1691                 netsyslog(LOG_ERR, "socket() failed: %m");
1692                 exit(1);
1693                 /*NOTREACHED*/
1694         }
1695            /* set socket to reuse address */
1696            if (setsockopt(fd[nbsock], SOL_SOCKET, SO_REUSEADDR, (void*) &optval, sizeof(optval)) < 0) {
1697                    netsyslog(LOG_ERR, "setsockopt() SO_REUSEADDR failed: %m");
1698                    exit(1);
1699                    /*NOTREACHED*/
1700            }
1701 #ifdef IPV6_V6ONLY
1702            /* Restricts AF_INET6 socket to IPv6 communications (see RFC 2553bis-03) */
1703            if (res->ai_family == AF_INET6)
1704                 if (setsockopt(fd[nbsock], IPPROTO_IPV6, IPV6_V6ONLY, (void*) &optval, sizeof(optval)) < 0) {
1705                            netsyslog(LOG_ERR, "setsockopt() IPV6_V6ONLY failed: %m");
1706                            exit(1);
1707                            /*NOTREACHED*/
1708                 }
1709 #endif
1710
1711            /* Remember the socket family in fd_family structure */
1712            fd_family[nbsock] = res->ai_family;
1713
1714         /*
1715          * bind the socket to the NTP port
1716          */
1717         if (!debug && !simple_query && !unpriv_port) {
1718                 if (bind(fd[nbsock], res->ai_addr, SOCKLEN(res->ai_addr)) < 0) {
1719 #ifndef SYS_WINNT
1720                         if (errno == EADDRINUSE)
1721 #else
1722                                 if (WSAGetLastError() == WSAEADDRINUSE)
1723 #endif /* SYS_WINNT */
1724                                 netsyslog(LOG_ERR,
1725                                         "the NTP socket is in use, exiting");
1726                                 else
1727                                 netsyslog(LOG_ERR, "bind() fails: %m");
1728                         exit(1);
1729                 }
1730         }
1731
1732 #ifdef HAVE_POLL_H
1733             fdmask[nbsock].fd = fd[nbsock];
1734             fdmask[nbsock].events = POLLIN;
1735 #else
1736             FD_SET(fd[nbsock], &fdmask);
1737             if ((SOCKET) maxfd < fd[nbsock]+1) {
1738                 maxfd = fd[nbsock]+1;
1739             }
1740 #endif
1741
1742         /*
1743          * set non-blocking,
1744          */
1745 #ifndef SYS_WINNT
1746 # ifdef SYS_VXWORKS
1747   {
1748         int on = TRUE;
1749
1750            if (ioctl(fd[nbsock],FIONBIO, &on) == ERROR) {
1751           netsyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m");
1752           exit(1);
1753         }
1754   }
1755 # else /* not SYS_VXWORKS */
1756 #  if defined(O_NONBLOCK)
1757            if (fcntl(fd[nbsock], F_SETFL, O_NONBLOCK) < 0) {
1758                 netsyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails: %m");
1759                 exit(1);
1760                 /*NOTREACHED*/
1761         }
1762 #  else /* not O_NONBLOCK */
1763 #       if defined(FNDELAY)
1764            if (fcntl(fd[nbsock], F_SETFL, FNDELAY) < 0) {
1765                 netsyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails: %m");
1766                 exit(1);
1767                 /*NOTREACHED*/
1768         }
1769 #       else /* FNDELAY */
1770 #        include "Bletch: Need non blocking I/O"
1771 #       endif /* FNDELAY */
1772 #  endif /* not O_NONBLOCK */
1773 # endif /* SYS_VXWORKS */
1774 #else /* SYS_WINNT */
1775         if (ioctlsocket(fd[nbsock], FIONBIO, (u_long *) &on) == SOCKET_ERROR) {
1776                 netsyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
1777                 exit(1);
1778         }
1779 #endif /* SYS_WINNT */
1780         nbsock++;
1781     }
1782     freeaddrinfo(ressave);
1783 }
1784
1785 /*
1786  * sendpkt - send a packet to the specified destination
1787  */
1788 static void
1789 sendpkt(
1790         struct sockaddr_storage *dest,
1791         struct pkt *pkt,
1792         int len
1793         )
1794 {
1795         int i;
1796         int cc;
1797         SOCKET sock = 0;
1798
1799 #ifdef SYS_WINNT
1800         DWORD err;
1801 #endif /* SYS_WINNT */
1802
1803         /* Find a local family compatible socket to send ntp packet to ntp server */
1804         for(i = 0; (i < MAX_AF); i++) {
1805                 if(dest->ss_family == fd_family[i]) {
1806                         sock = fd[i];
1807                 break;
1808                 }
1809         }
1810
1811         if ( sock == 0 ) {
1812                 netsyslog(LOG_ERR, "cannot find family compatible socket to send ntp packet");
1813                 exit(1);
1814                 /*NOTREACHED*/
1815         }
1816
1817         cc = sendto(sock, (char *)pkt, len, 0, (struct sockaddr *)dest,
1818                         SOCKLEN(dest));
1819
1820 #ifndef SYS_WINNT
1821         if (cc == -1) {
1822                 if (errno != EWOULDBLOCK && errno != ENOBUFS)
1823 #else
1824         if (cc == SOCKET_ERROR) {
1825                 err = WSAGetLastError();
1826                 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS)
1827 #endif /* SYS_WINNT */
1828                         netsyslog(LOG_ERR, "sendto(%s): %m", stohost(dest));
1829         }
1830 }
1831
1832
1833 /*
1834  * input_handler - receive packets asynchronously
1835  */
1836 void
1837 input_handler(void)
1838 {
1839         register int n;
1840         register struct recvbuf *rb;
1841         struct timeval tvzero;
1842         int fromlen;
1843         l_fp ts;
1844         int i;
1845 #ifdef HAVE_POLL_H
1846         struct pollfd fds[MAX_AF];
1847 #else
1848         fd_set fds;
1849 #endif
1850         int fdc = 0;
1851
1852         /*
1853          * Do a poll to see if we have data
1854          */
1855         for (;;) {
1856                 tvzero.tv_sec = tvzero.tv_usec = 0;
1857 #ifdef HAVE_POLL_H
1858                 memcpy(fds, fdmask, sizeof(fdmask));
1859                 n = poll(fds, (unsigned int)nbsock, tvzero.tv_sec * 1000);
1860
1861                 /*
1862                  * Determine which socket received data
1863                  */
1864
1865                  for(i=0; i < nbsock; i++) {
1866                         if(fds[i].revents & POLLIN) {
1867                                 fdc = fd[i];
1868                                 break;
1869                         }
1870                  }
1871
1872 #else
1873                 fds = fdmask;
1874                 n = select(maxfd, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
1875
1876                 /*
1877                  * Determine which socket received data
1878                  */
1879
1880                 for(i=0; i < maxfd; i++) {
1881                         if(FD_ISSET(fd[i], &fds)) {
1882                                  fdc = fd[i];
1883                                  break;
1884                         }
1885                 }
1886
1887 #endif
1888
1889                 /*
1890                  * If nothing to do, just return.  If an error occurred,
1891                  * complain and return.  If we've got some, freeze a
1892                  * timestamp.
1893                  */
1894                 if (n == 0)
1895                         return;
1896                 else if (n == -1) {
1897                         if (errno != EINTR)
1898                                 netsyslog(LOG_ERR,
1899 #ifdef HAVE_POLL_H
1900                                         "poll() error: %m"
1901 #else
1902                                         "select() error: %m"
1903 #endif
1904                                         );
1905                         return;
1906                 }
1907                 get_systime(&ts);
1908
1909                 /*
1910                  * Get a buffer and read the frame.  If we
1911                  * haven't got a buffer, or this is received
1912                  * on the wild card socket, just dump the packet.
1913                  */
1914                 if (initializing || free_recvbuffs() == 0) {
1915                         char buf[100];
1916
1917
1918 #ifndef SYS_WINNT
1919                         (void) read(fdc, buf, sizeof buf);
1920 #else
1921                         /* NT's _read does not operate on nonblocking sockets
1922                          * either recvfrom or ReadFile() has to be used here.
1923                          * ReadFile is used in [ntpd]ntp_intres() and ntpdc,
1924                          * just to be different use recvfrom() here
1925                          */
1926                         recvfrom(fdc, buf, sizeof(buf), 0, (struct sockaddr *)0, NULL);
1927 #endif /* SYS_WINNT */
1928                         continue;
1929                 }
1930
1931                 rb = get_free_recv_buffer();
1932
1933                 fromlen = sizeof(struct sockaddr_storage);
1934                 rb->recv_length = recvfrom(fdc, (char *)&rb->recv_pkt,
1935                    sizeof(rb->recv_pkt), 0,
1936                    (struct sockaddr *)&rb->recv_srcadr, &fromlen);
1937                 if (rb->recv_length == -1) {
1938                         freerecvbuf(rb);
1939                         continue;
1940                 }
1941
1942                 /*
1943                  * Got one.  Mark how and when it got here,
1944                  * put it on the full list.
1945                  */
1946                 rb->recv_time = ts;
1947                 add_full_recv_buffer(rb);
1948         }
1949 }
1950
1951
1952 #if !defined SYS_WINNT && !defined SYS_CYGWIN32
1953 /*
1954  * adj_systime - do a big long slew of the system time
1955  */
1956 static int
1957 l_adj_systime(
1958         l_fp *ts
1959         )
1960 {
1961         struct timeval adjtv, oadjtv;
1962         int isneg = 0;
1963         l_fp offset;
1964 #ifndef STEP_SLEW
1965         l_fp overshoot;
1966 #endif
1967
1968         /*
1969          * Take the absolute value of the offset
1970          */
1971         offset = *ts;
1972         if (L_ISNEG(&offset)) {
1973                 isneg = 1;
1974                 L_NEG(&offset);
1975         }
1976
1977 #ifndef STEP_SLEW
1978         /*
1979          * Calculate the overshoot.  XXX N.B. This code *knows*
1980          * ADJ_OVERSHOOT is 1/2.
1981          */
1982         overshoot = offset;
1983         L_RSHIFTU(&overshoot);
1984         if (overshoot.l_ui != 0 || (overshoot.l_uf > ADJ_MAXOVERSHOOT)) {
1985                 overshoot.l_ui = 0;
1986                 overshoot.l_uf = ADJ_MAXOVERSHOOT;
1987         }
1988         L_ADD(&offset, &overshoot);
1989 #endif
1990         TSTOTV(&offset, &adjtv);
1991
1992         if (isneg) {
1993                 adjtv.tv_sec = -adjtv.tv_sec;
1994                 adjtv.tv_usec = -adjtv.tv_usec;
1995         }
1996
1997         if (adjtv.tv_usec != 0 && !debug) {
1998                 if (adjtime(&adjtv, &oadjtv) < 0) {
1999                         msyslog(LOG_ERR, "Can't adjust the time of day: %m");
2000                         return 0;
2001                 }
2002         }
2003         return 1;
2004 }
2005 #endif /* SYS_WINNT */
2006
2007
2008 /*
2009  * This fuction is not the same as lib/systime step_systime!!!
2010  */
2011 static int
2012 l_step_systime(
2013         l_fp *ts
2014         )
2015 {
2016         double dtemp;
2017
2018 #ifdef SLEWALWAYS
2019 #ifdef STEP_SLEW
2020         l_fp ftmp;
2021         int isneg;
2022         int n;
2023
2024         if (debug) return 1;
2025         /*
2026          * Take the absolute value of the offset
2027          */
2028         ftmp = *ts;
2029         if (L_ISNEG(&ftmp)) {
2030                 L_NEG(&ftmp);
2031                 isneg = 1;
2032         } else
2033                 isneg = 0;
2034
2035         if (ftmp.l_ui >= 3) {           /* Step it and slew - we might win */
2036                 LFPTOD(ts, dtemp);
2037                 n = step_systime(dtemp);
2038                 if (!n)
2039                         return n;
2040                 if (isneg)
2041                         ts->l_ui = ~0;
2042                 else
2043                         ts->l_ui = ~0;
2044         }
2045         /*
2046          * Just add adjustment into the current offset.  The update
2047          * routine will take care of bringing the system clock into
2048          * line.
2049          */
2050 #endif
2051         if (debug)
2052                 return 1;
2053 #ifdef FORCE_NTPDATE_STEP
2054         LFPTOD(ts, dtemp);
2055         return step_systime(dtemp);
2056 #else
2057         l_adj_systime(ts);
2058         return 1;
2059 #endif
2060 #else /* SLEWALWAYS  */
2061         if (debug)
2062                 return 1;
2063         LFPTOD(ts, dtemp);
2064         return step_systime(dtemp);
2065 #endif  /* SLEWALWAYS */
2066 }
2067
2068
2069 /* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */
2070 /*
2071  * printserver - print detail information for a server
2072  */
2073 static void
2074 printserver(
2075         register struct server *pp,
2076         FILE *fp
2077         )
2078 {
2079         register int i;
2080         char junk[5];
2081         char *str;
2082
2083         if (!debug) {
2084                 (void) fprintf(fp, "server %s, stratum %d, offset %s, delay %s\n",
2085                                    stoa(&pp->srcadr), pp->stratum,
2086                                    lfptoa(&pp->offset, 6), fptoa((s_fp)pp->delay, 5));
2087                 return;
2088         }
2089
2090         (void) fprintf(fp, "server %s, port %d\n",
2091                            stoa(&pp->srcadr), ntohs(((struct sockaddr_in*)&(pp->srcadr))->sin_port));
2092
2093         (void) fprintf(fp, "stratum %d, precision %d, leap %c%c, trust %03o\n",
2094                            pp->stratum, pp->precision,
2095                            pp->leap & 0x2 ? '1' : '0',
2096                            pp->leap & 0x1 ? '1' : '0',
2097                            pp->trust);
2098
2099         if (pp->stratum == 1) {
2100                 junk[4] = 0;
2101                 memmove(junk, (char *)&pp->refid, 4);
2102                 str = junk;
2103         } else {
2104                 str = stoa(&pp->srcadr);
2105         }
2106         (void) fprintf(fp,
2107                            "refid [%s], delay %s, dispersion %s\n",
2108                            str, fptoa((s_fp)pp->delay, 5),
2109                            ufptoa(pp->dispersion, 5));
2110
2111         (void) fprintf(fp, "transmitted %d, in filter %d\n",
2112                            pp->xmtcnt, pp->filter_nextpt);
2113
2114         (void) fprintf(fp, "reference time:    %s\n",
2115                            prettydate(&pp->reftime));
2116         (void) fprintf(fp, "originate timestamp: %s\n",
2117                            prettydate(&pp->org));
2118         (void) fprintf(fp, "transmit timestamp:  %s\n",
2119                            prettydate(&pp->xmt));
2120
2121         (void) fprintf(fp, "filter delay: ");
2122         for (i = 0; i < NTP_SHIFT; i++) {
2123                 (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5));
2124                 if (i == (NTP_SHIFT>>1)-1)
2125                         (void) fprintf(fp, "\n        ");
2126         }
2127         (void) fprintf(fp, "\n");
2128
2129         (void) fprintf(fp, "filter offset:");
2130         for (i = 0; i < PEER_SHIFT; i++) {
2131                 (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6));
2132                 if (i == (PEER_SHIFT>>1)-1)
2133                         (void) fprintf(fp, "\n        ");
2134         }
2135         (void) fprintf(fp, "\n");
2136
2137         (void) fprintf(fp, "delay %s, dispersion %s\n",
2138                            fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5));
2139
2140         (void) fprintf(fp, "offset %s\n\n",
2141                            lfptoa(&pp->offset, 6));
2142 }
2143
2144 #if !defined(HAVE_VSPRINTF)
2145 int
2146 vsprintf(
2147         char *str,
2148         const char *fmt,
2149         va_list ap
2150         )
2151 {
2152         FILE f;
2153         int len;
2154
2155         f._flag = _IOWRT+_IOSTRG;
2156         f._ptr = str;
2157         f._cnt = 32767;
2158         len = _doprnt(fmt, ap, &f);
2159         *f._ptr = 0;
2160         return (len);
2161 }
2162 #endif
2163
2164 #if 0
2165 /* override function in library since SA_RESTART makes ALL syscalls restart */
2166 #ifdef SA_RESTART
2167 void
2168 signal_no_reset(
2169         int sig,
2170         void (*func)()
2171         )
2172 {
2173         int n;
2174         struct sigaction vec;
2175
2176         vec.sa_handler = func;
2177         sigemptyset(&vec.sa_mask);
2178         vec.sa_flags = 0;
2179
2180         while (1)
2181         {
2182                 n = sigaction(sig, &vec, NULL);
2183                 if (n == -1 && errno == EINTR)
2184                         continue;
2185                 break;
2186         }
2187         if (n == -1)
2188         {
2189                 perror("sigaction");
2190                 exit(1);
2191         }
2192 }
2193 #endif
2194 #endif
2195
2196 #ifdef HAVE_NETINFO
2197 static ni_namelist *
2198 getnetinfoservers(void)
2199 {
2200         ni_status status;
2201         void *domain;
2202         ni_id confdir;
2203         ni_namelist *namelist = (ni_namelist*)malloc(sizeof(ni_namelist));
2204
2205         /* Find a time server in NetInfo */
2206         if ((status = ni_open(NULL, ".", &domain)) != NI_OK) return NULL;
2207
2208         while (status = ni_pathsearch(domain, &confdir, NETINFO_CONFIG_DIR) == NI_NODIR) {
2209                 void *next_domain;
2210                 if (ni_open(domain, "..", &next_domain) != NI_OK) break;
2211                 ni_free(domain);
2212                 domain = next_domain;
2213         }
2214         if (status != NI_OK) return NULL;
2215
2216         NI_INIT(namelist);
2217         if (ni_lookupprop(domain, &confdir, "server", namelist) != NI_OK) {
2218                 ni_namelist_free(namelist);
2219                 free(namelist);
2220                 return NULL;
2221         }
2222
2223         return(namelist);
2224 }
2225 #endif