1: #if !defined(lint) && defined(DOSCCS)
   2: static char *rcsid = "$Source: /usr/src/new/ntp/ntpd.c,v $ $Revision: 3.4.1.12 $ $Date: 95/07/1 20:35:17 $";
   3: #endif	lint
   4: 
   5: /*
   6:  *  $Log:	ntpd.c,v $
   7:  * Revision 3.4.1.11 95/01/31 20:35:17 sms
   8:  * Fix missing initializer before calling sysctl().
   9:  *
  10:  * Revision 3.4.1.10 95/01/27 17:20:17 sms
  11:  * 2.11BSD - remove SETTICKADJ from ntpd.c.  This was done for several reasons:
  12:  * 1) tickadj does not (and never has) existed, 2) this is an old version and
  13:  * not going to be ported to a system with tickadj, 3) with 'securelevel'
  14:  * (see sysctl(3), init(8) and sysctl(8)) set to 1 or 2 /dev/{k}mem can not
  15:  * be written even by root.  If tickadj were ever added it would need an
  16:  * extension to sysctl(3) to have a chance of working.
  17:  *
  18:  * Revision 3.4.1.9  89/05/18  18:30:17  louie
  19:  * Changes in ntpd.c for reference clock support.  Also, a few diddles to
  20:  * accomodate the NeXT computer system that has a slightly different nlist.h
  21:  *
  22:  * Revision 3.4.1.8  89/05/03  15:16:17  louie
  23:  * Add code to save the value of the drift compensation register to a file every
  24:  * hour.  Add additional configuration file directives which can specify the same
  25:  * information as on the command line.
  26:  *
  27:  * Revision 3.4.1.7  89/04/10  15:58:45  louie
  28:  * Add -l option to enable logging of clock adjust messages.
  29:  *
  30:  * Revision 3.4.1.6  89/04/07  19:09:04  louie
  31:  * Added NOSWAP code for Ultrix systems to lock NTP process in memory.  Deleted
  32:  * unused variable in ntpd.c
  33:  *
  34:  * Revision 3.4.1.5  89/03/31  16:37:49  louie
  35:  * Add support for "trusting" directive in NTP configuration file.  It allows
  36:  * you to specify at run time if non-configured peers will be synced to.
  37:  *
  38:  * Revision 3.4.1.4  89/03/29  12:30:46  louie
  39:  * peer->mode has been renamed peer->hmode.  Drop PEER_FL_SYNC since the
  40:  * PEER_FL_CONFIG flag means much the same thing.
  41:  *
  42:  * Revision 3.4.1.3  89/03/22  18:29:41  louie
  43:  * patch3: Use new RCS headers.
  44:  *
  45:  * Revision 3.4.1.2  89/03/22  18:03:17  louie
  46:  * The peer->refid field was being htonl()'ed when it was already in network
  47:  * byte order.
  48:  *
  49:  * Revision 3.4.1.1  89/03/20  00:12:10  louie
  50:  * patch1: Diddle syslog messages a bit.  Handle case of udp/ntp not being
  51:  * patch1: defined in /etc/services.  Compute default value for tickadj if
  52:  * patch1: the change-kernel-tickadj flag is set, but no tickadj directive
  53:  * patch1: is present in the configuration file.
  54:  *
  55:  * Revision 3.4  89/03/17  18:37:11  louie
  56:  * Latest test release.
  57:  *
  58:  * Revision 3.3.1.1  89/03/17  18:26:32  louie
  59:  * 1
  60:  *
  61:  * Revision 3.3  89/03/15  14:19:56  louie
  62:  * New baseline for next release.
  63:  *
  64:  * Revision 3.2.1.2  89/03/15  13:59:50  louie
  65:  * Initialize random number generator.  The ntpdc query_mode() routine has been
  66:  * revised to send more peers per packet, a count of the total number of peers
  67:  * which will be transmited, the number of packets to be transmitted, and a
  68:  * sequence number for each packet.  There is a new version number for the
  69:  * ntpdc query packets, which is now symbolically defined in ntp.h
  70:  *
  71:  * Revision 3.2.1.1  89/03/10  12:27:41  louie
  72:  * Removed reference to HUGE, and replaced it by a suitable large number.  Added
  73:  * some #ifdef DEBUG .. #endif around some debug code that was missing.  Display
  74:  * patchlevel along with version.
  75:  *
  76:  * Revision 3.2  89/03/07  18:26:30  louie
  77:  * New version of the UNIX NTP daemon based on the 6 March 1989 draft of the
  78:  * new NTP protcol spec.  A bunch of cosmetic changes.  The peer list is
  79:  * now doublely linked, and a subroutine (enqueue()) replaces the ENQUEUE
  80:  * macro used previously.
  81:  *
  82:  * Revision 3.1.1.1  89/02/15  08:58:46  louie
  83:  * Bugfixes to released version.
  84:  *
  85:  *
  86:  * Revision 3.1  89/01/30  14:43:14  louie
  87:  * Second UNIX NTP test release.
  88:  *
  89:  * Revision 3.0  88/12/12  15:56:38  louie
  90:  * Test release of new UNIX NTP software.  This version should conform to the
  91:  * revised NTP protocol specification.
  92:  *
  93:  */
  94: 
  95: #include <stdio.h>
  96: #include <sys/types.h>
  97: #include <sys/param.h>
  98: #include <sys/uio.h>
  99: #include <sys/socket.h>
 100: #include <sys/time.h>
 101: #include <sys/ioctl.h>
 102: #include <sys/resource.h>
 103: #include <sys/file.h>
 104: #ifdef NOSWAP
 105: #include <sys/lock.h>
 106: #endif
 107: 
 108: #include <net/if.h>
 109: 
 110: #include <netinet/in.h>
 111: #include <netinet/in_systm.h>
 112: #include <netinet/ip.h>
 113: #include <netinet/udp.h>
 114: 
 115: #include <arpa/inet.h>
 116: #include <netdb.h>
 117: #include <strings.h>
 118: #include <errno.h>
 119: #include <syslog.h>
 120: 
 121: #include "ntp.h"
 122: #include "patchlevel.h"
 123: 
 124: #define TRUE    1
 125: #define FALSE   0
 126: 
 127: struct sockaddr_in dst_sock = {AF_INET};
 128: 
 129: struct servent *servp;
 130: struct list peer_list;
 131: 
 132: struct itimerval it;
 133: struct itimerval *itp = &it;
 134: struct timeval tv;
 135: char *prog_name;
 136: 
 137: char *conf = NTPINITFILE;
 138: char *driftcomp_file = NTPDRIFTCOMP;
 139: static int drift_fd = -1;
 140: 
 141: #ifdef  DEBUG
 142: int debug = 0;
 143: #endif
 144: 
 145: #ifdef  NOSWAP
 146: int noswap = 0;
 147: #endif
 148: 
 149: int doset = 1;
 150: int ticked;
 151: int selfds;
 152: int trusting = 1;
 153: int logstats;
 154: 
 155: double WayTooBig = WAYTOOBIG;
 156: u_long clock_watchdog;
 157: 
 158: struct ntpdata ntpframe;
 159: struct sysdata sys;
 160: 
 161: extern int errno;
 162: extern char *malloc(), *ntoa();
 163: 
 164: void finish(), timeout(), tock(), make_new_peer(), init_ntp(), initialize(),
 165:     init_kern_vars(), hourly();
 166: extern void transmit(), process_packet(), clock_update(),
 167:     clear(), clock_filter(), select_clock();
 168: 
 169: extern void init_logical_clock();
 170: 
 171: main(argc, argv)
 172:     int argc;
 173:     char *argv[];
 174: {
 175:     struct sockaddr_in *dst = &dst_sock;
 176:     struct ntpdata *pkt = &ntpframe;
 177:     fd_set readfds, tmpmask;
 178:     int dstlen = sizeof(struct sockaddr_in);
 179:     int cc;
 180:     register int i;
 181:     extern char *optarg;
 182:     extern int atoi();
 183: 
 184: #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
 185:     void incdebug(), decdebug();
 186: #endif
 187:     initialize();       /* call NTP protocol initialization first,
 188: 				   then allow others to override default
 189: 				   values */
 190:     prog_name = argv[0];
 191:     while ((cc = getopt(argc, argv, "a:c:dD:lstn")) != EOF) {
 192:         switch (cc) {
 193:         case 'a':
 194:             if (strcmp(optarg, "any") == 0)
 195:                 WayTooBig = 10e15;
 196:             else
 197:                 WayTooBig = atof(optarg);
 198:             break;
 199: 
 200:         case 'd':
 201: #ifdef  DEBUG
 202:             debug++;
 203: #else
 204:             fprintf(stderr, "%s: not compiled with DEBUG\n",
 205:                 prog_name);
 206: #endif
 207:             break;
 208: 
 209:         case 'D':
 210: #ifdef  DEBUG
 211:             debug = atoi(optarg);
 212: #else
 213:             fprintf(stderr, "%s: not compiled with DEBUG\n",
 214:                 prog_name);
 215: #endif
 216:             break;
 217: 
 218:         case 's':
 219:             doset = 0;
 220:             break;
 221: 
 222:         case 't':
 223:             fprintf(stderr, "%s: tickadj not supported\n",
 224:                 prog_name);
 225:             break;
 226: 
 227:         case 'n':
 228: #ifdef  NOSWAP
 229:             noswap = 1;
 230: #else
 231:             fprintf(stderr, "%s: not compiled for noswap\n",
 232:                 prog_name);
 233: #endif
 234:             break;
 235: 
 236:         case 'l':
 237:             logstats = 1;
 238:             break;
 239: 
 240:         case 'c':
 241:             conf = optarg;
 242:             break;
 243: 
 244:         default:
 245:             fprintf(stderr, "ntpd: -%c: unknown option\n", cc);
 246:             break;
 247:         }
 248:     }
 249: 
 250: #ifdef  DEBUG
 251:     if (!debug) {
 252: #endif
 253:         if (fork())
 254:             exit(0);
 255: 
 256:         {
 257:             int s;
 258:             for (s = getdtablesize(); s >= 0; s--)
 259:                 (void) close(s);
 260:             (void) open("/", 0);
 261:             (void) dup2(0, 1);
 262:             (void) dup2(0, 2);
 263:             (void) setpgrp(0, getpid());
 264:             s = open("/dev/tty", 2);
 265:             if (s >= 0) {
 266:                 (void) ioctl(s, (u_long) TIOCNOTTY, (char *) 0);
 267:                 (void) close(s);
 268:             }
 269:         }
 270: #ifdef  DEBUG
 271:     }
 272: #endif
 273: 
 274: #ifndef LOG_DAEMON
 275:     openlog("ntpd", LOG_PID);
 276: #else
 277: 
 278: #ifndef LOG_NTP
 279: #define LOG_NTP LOG_DAEMON
 280: #endif
 281:     openlog("ntpd", LOG_PID | LOG_NDELAY, LOG_NTP);
 282: #ifdef  DEBUG
 283:     if (debug)
 284:         setlogmask(LOG_UPTO(LOG_DEBUG));
 285:     else
 286: #endif	/* DEBUG */
 287:         setlogmask(LOG_UPTO(LOG_INFO));
 288: #endif	/* LOG_DAEMON */
 289: 
 290:     syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.9 $", prog_name);
 291:     syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
 292: 
 293: #ifdef  DEBUG
 294:     if (debug)
 295:         printf("%s version $Revision: 3.4.1.9 $ patchlevel %d\n",
 296:                prog_name, PATCHLEVEL);
 297: #endif
 298:     (void) setpriority(PRIO_PROCESS, 0, -10);
 299: 
 300: #ifdef  NOSWAP
 301:     if (noswap)
 302:         if (plock(PROCLOCK) != 0)  {
 303:             syslog(LOG_ERR, "plock() failed: %m");
 304: #ifdef  DEBUG
 305:             if (debug)
 306:                 perror("plock() failed");
 307: #endif
 308:         }
 309: #endif
 310: 
 311:     servp = getservbyname("ntp", "udp");
 312:     if (servp == NULL) {
 313:         syslog(LOG_CRIT, "udp/ntp: service unknown, using default %d",
 314:                NTP_PORT);
 315:         (void) create_sockets(htons(NTP_PORT));
 316:     } else
 317:         (void) create_sockets(servp->s_port);
 318: 
 319: 
 320:     peer_list.head = peer_list.tail = NULL;
 321:     peer_list.members = 0;
 322: 
 323:     init_ntp(conf);
 324:     init_kern_vars();
 325:     init_logical_clock();
 326: 
 327:     /*
 328: 	 * Attempt to open for writing the file for storing the drift comp
 329: 	 * register.  File must already exist for snapshots to be taken.
 330: 	 */
 331:     if ((i = open(driftcomp_file, O_WRONLY|O_CREAT, 0644)) >= 0) {
 332:         drift_fd = i;
 333:     }
 334:     (void) gettimeofday(&tv, (struct timezone *) 0);
 335:     srand(tv.tv_sec);
 336: 
 337:     FD_ZERO(&tmpmask);
 338:     for (i = 0; i < nintf; i++) {
 339:         FD_SET(addrs[i].fd, &tmpmask);
 340: #ifdef  DEBUG
 341:         if (debug>2) {
 342:             if (addrs[i].if_flags & IFF_BROADCAST)
 343:                 printf("Addr %d: %s fd %d %s broadcast %s\n",
 344:                        i, addrs[i].name, addrs[i].fd,
 345:                        ntoa(addrs[i].sin.sin_addr),
 346:                        ntoa(addrs[i].bcast.sin_addr));
 347:             else
 348:                 printf("Addr %d: %s fd %d %s\n", i,
 349:                        addrs[i].name, addrs[i].fd,
 350:                        ntoa(addrs[i].sin.sin_addr));
 351:         }
 352: #endif
 353:     }
 354: 
 355:     (void) signal(SIGINT, finish);
 356:     (void) signal(SIGTERM, finish);
 357:     (void) signal(SIGALRM, tock);
 358: #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
 359:     (void) signal(SIGUSR1, incdebug);
 360:     (void) signal(SIGUSR2, decdebug);
 361: #endif
 362:     itp->it_interval.tv_sec = (1<<CLOCK_ADJ);
 363:     itp->it_interval.tv_usec = 0;
 364:     itp->it_value.tv_sec = 1;
 365:     itp->it_value.tv_usec = 0;
 366: 
 367:     /*
 368: 	 * Find highest fd in use.  This might save a few microseconds in
 369: 	 * the select system call.
 370: 	 */
 371:     for (selfds = FD_SETSIZE - 1; selfds; selfds--)
 372:         if (FD_ISSET(selfds, &tmpmask))
 373:             break;
 374: #ifdef  DEBUG
 375:     if (debug > 2)
 376:         printf("Highest fd in use is %d\n", selfds);
 377:     if (!selfds) abort();
 378: #endif
 379:     selfds++;
 380: 
 381:     (void) setitimer(ITIMER_REAL, itp, (struct itimerval *) 0);
 382: 
 383:     for (;;) {      /* go into a finite but hopefully very long
 384: 				 * loop */
 385:         int nfds;
 386: 
 387:         readfds = tmpmask;
 388:         nfds = select(selfds, &readfds, (fd_set *) 0, (fd_set *) 0,
 389:                         (struct timeval *) 0);
 390:         (void) gettimeofday(&tv, (struct timezone *) 0);
 391: 
 392:         for(i = 0; i < nintf && nfds > 0; i++) {
 393:             if (!FD_ISSET(addrs[i].fd, &readfds))
 394:                 continue;
 395:             addrs[i].uses++;
 396:             dstlen = sizeof(struct sockaddr_in);
 397:             if ((cc =
 398:                  recvfrom(addrs[i].fd, (char *) pkt,
 399:                       sizeof(ntpframe), 0,
 400:                       (struct sockaddr *) dst, &dstlen)) < 0) {
 401: 
 402:                 if (errno != EWOULDBLOCK) {
 403:                     syslog(LOG_NOTICE, "recvfrom: %m");
 404: #ifdef  DEBUG
 405:                     if(debug > 2)
 406:                         perror("recvfrom");
 407: #endif
 408:                 }
 409:                 continue;
 410:             }
 411: 
 412:             if (cc < sizeof(*pkt)) {
 413: #ifdef  DEBUG
 414:                 if (debug)
 415:                     printf("Runt packet from %s\n",
 416:                            ntoa(dst->sin_addr));
 417: #endif
 418:                 continue;
 419:             }
 420: 
 421:             if (pkt->stratum == INFO_QUERY ||
 422:                 pkt->stratum == INFO_REPLY) {
 423:                 query_mode(dst, pkt, i);
 424:                 continue;
 425:             }
 426: #ifdef  DEBUG
 427:             if (debug > 3) {
 428:                 printf("\nInput ");
 429:                 dump_pkt(dst, pkt, NULL);
 430:             }
 431: #endif
 432:             if ((pkt->status & VERSIONMASK) != NTPVERSION_1)
 433:                 continue;
 434: 
 435:             receive(dst, pkt, &tv, i);
 436:         }
 437:         if (ticked) {
 438:             ticked = 0;
 439:             timeout();
 440:         }
 441:     }           /* end of forever loop */
 442: }
 443: 
 444: struct ntp_peer *
 445: check_peer(dst, sock)
 446:     struct sockaddr_in *dst;
 447:     int sock;
 448: {
 449:     register struct ntp_peer *peer = peer_list.head;
 450: 
 451:     while (peer != NULL) {
 452:         if ((peer->src.sin_addr.s_addr == dst->sin_addr.s_addr) &&
 453:             (peer->src.sin_port == dst->sin_port) &&
 454:             ((peer->sock == sock) || (peer->sock == -1)))
 455:             return peer;
 456:         peer = peer->next;
 457:     }
 458:     return ((struct ntp_peer *) NULL);
 459: }
 460: 
 461: #ifdef  DEBUG
 462: dump_pkt(dst, pkt, peer)
 463:     struct sockaddr_in *dst;
 464:     struct ntpdata *pkt;
 465:     struct ntp_peer *peer;
 466: {
 467:     struct in_addr clock_host;
 468: 
 469:     printf("Packet: [%s](%d)\n", inet_ntoa(dst->sin_addr),
 470:            (int) htons(dst->sin_port));
 471:     printf("Leap %d, version %d, mode %d, poll %d, precision %d stratum %d",
 472:            (pkt->status & LEAPMASK) >> 6, (pkt->status & VERSIONMASK) >> 3,
 473:            pkt->status & MODEMASK, pkt->ppoll, pkt->precision,
 474:            pkt->stratum);
 475:     switch (pkt->stratum) {
 476:     case 0:
 477:     case 1:
 478:         printf(" (%.4s)\n", (char *)&pkt->refid);
 479:         break;
 480:     default:
 481:         clock_host.s_addr = (u_long) pkt->refid;
 482:         printf(" [%s]\n", inet_ntoa(clock_host));
 483:         break;
 484:     }
 485:     printf("Synch Dist is %04x.%04x  Synch Dispersion is %04x.%04x\n",
 486:            ntohs((u_short) pkt->distance.int_part),
 487:            ntohs((u_short) pkt->distance.fraction),
 488:            ntohs((u_short) pkt->dispersion.int_part),
 489:            ntohs((u_short) pkt->dispersion.fraction));
 490:     printf("Reference Timestamp is %08lx.%08lx\n",
 491:            ntohl(pkt->reftime.int_part),
 492:            ntohl(pkt->reftime.fraction));
 493:     printf("Originate Timestamp is %08lx.%08lx\n",
 494:            ntohl(pkt->org.int_part),
 495:            ntohl(pkt->org.fraction));
 496:     printf("Receive Timestamp is   %08lx.%08lx\n",
 497:            ntohl(pkt->rec.int_part),
 498:            ntohl(pkt->rec.fraction));
 499:     printf("Transmit Timestamp is  %08lx.%08lx\n",
 500:            ntohl(pkt->xmt.int_part),
 501:            ntohl(pkt->xmt.fraction));
 502:     if(peer != NULL)
 503:         printf("Input Timestamp is     %08lx.%08lx\n",
 504:                ntohl(peer->rec.int_part),
 505:                ntohl(peer->rec.fraction));
 506:     putchar('\n');
 507: }
 508: #endif
 509: 
 510: void
 511: make_new_peer(peer)
 512:     struct ntp_peer *peer;
 513: {
 514:     int i;
 515: 
 516:     /*
 517: 	 * initialize peer data fields
 518: 	 */
 519:     peer->src.sin_family = AF_INET;
 520:     peer->src.sin_port = 0;
 521:     peer->src.sin_addr.s_addr = 0;
 522:     peer->hmode = MODE_SYM_PAS; /* default: symmetric passive mode */
 523:     peer->flags = 0;
 524:     peer->timer = 1 << NTP_MINPOLL;
 525:     peer->stopwatch = 0;
 526:     peer->hpoll = NTP_MINPOLL;
 527:     double_to_s_fixed(&peer->dispersion, PEER_MAXDISP);
 528:     peer->reach = 0;
 529:     peer->estoffset = 0.0;
 530:     peer->estdelay = 0.0;
 531:     peer->org.int_part = peer->org.fraction = 0;
 532:     peer->rec.int_part = peer->rec.fraction = 0;
 533:     peer->filter.samples = 0;
 534:     for (i = 0; i < NTP_WINDOW; i++) {
 535:         peer->filter.offset[i] = 0.0;
 536:         peer->filter.delay[i] = 0.0;
 537:     }
 538:     peer->pkt_sent = 0;
 539:     peer->pkt_rcvd = 0;
 540:     peer->pkt_dropped = 0;
 541: }
 542: 
 543: /*
 544:  *  This procedure is called to delete a peer from our list of peers.
 545:  */
 546: void
 547: demobilize(l, peer)
 548:     struct list *l;
 549:     struct ntp_peer *peer;
 550: {
 551:     extern struct ntp_peer dummy_peer;
 552: 
 553:     if (peer == &dummy_peer)
 554: #ifdef  DEBUG
 555:         abort();
 556: #else
 557:         return;
 558: #endif
 559: 
 560: #ifdef  DEBUG
 561:     if ((peer->next == NULL && peer->prev == NULL) ||
 562:         l->tail == NULL || l->head == NULL)
 563:         abort();
 564: #endif
 565: 
 566:     /* delete only peer in list? */
 567:     if (l->head == l->tail) {
 568: #ifdef  DEBUG
 569:         if (l->head != peer) abort();
 570: #endif
 571:         l->head = l->tail = NULL;
 572:         goto dropit;
 573:     }
 574: 
 575:     /* delete first peer? */
 576:     if (l->head == peer) {
 577:         l->head = peer->next;
 578:         l->head->prev = NULL;
 579:         goto dropit;
 580:     }
 581: 
 582:     /* delete last peer? */
 583:     if (l->tail == peer) {
 584:         l->tail = peer->prev;
 585:         l->tail->next = NULL;
 586:         goto dropit;
 587:     }
 588: 
 589:     /* drop peer in middle */
 590:     peer->prev->next = peer->next;
 591:     peer->next->prev = peer->prev;
 592: 
 593:  dropit:
 594: #ifdef  DEBUG
 595:     /* just some sanity checking */
 596:     if ((l->members < 0) ||
 597:         (l->members && l->tail == NULL) ||
 598:         (l->members == 0 && l->tail != NULL)) {
 599:         syslog(LOG_ERR, "List hosed (demobilize)");
 600:         abort();
 601:     }
 602:     peer->next = peer->prev = NULL;
 603: #endif
 604:     free((char *) peer);
 605:     l->members--;
 606: 
 607:     return;
 608: }
 609: 
 610: enqueue(l, peer)
 611:     register struct list *l;
 612:     struct ntp_peer *peer;
 613: {
 614:     l->members++;
 615:     if (l->tail == NULL) {
 616:         /* insertion into empty list */
 617:         l->tail = l->head = peer;
 618:         peer->next = peer->prev = NULL;
 619:         return;
 620:     }
 621: 
 622:     /* insert at end of list */
 623:     l->tail->next = peer;
 624:     peer->next = NULL;
 625:     peer->prev = l->tail;
 626:     l->tail = peer;
 627: }
 628: 
 629: /* XXX */
 630: /*
 631:  *  Trivial signal handler.  Assumes you have Berkeley flavored signals which
 632:  *  re-enable themselves.
 633:  */
 634: void
 635: tock() {
 636:     ticked = 1;
 637: }
 638: 
 639: void
 640: timeout()
 641: {
 642:     static int periodic = 0;
 643:     register struct ntp_peer *peer = peer_list.head, *next;
 644: #ifndef XADJTIME2
 645:     extern void adj_host_clock();
 646: 
 647:     adj_host_clock();
 648: #endif
 649:     /*
 650: 	 * Count down sys.hold if necessary.
 651: 	 */
 652:     if (sys.hold) {
 653:         if (sys.hold <= (1<<CLOCK_ADJ))
 654:             sys.hold = 0;
 655:         else
 656:             sys.hold -= (1<<CLOCK_ADJ);
 657:     }
 658:     /*
 659: 	 * If interval has expired blast off an NTP to that host.
 660: 	 */
 661:     while (peer != NULL) {
 662: #ifdef  DEBUG
 663:         if (peer->next == NULL && peer != peer_list.tail) {
 664:             printf("Broken peer list\n");
 665:             syslog(LOG_ERR, "Broken peer list");
 666:             abort();
 667:         }
 668: #endif
 669:         next = peer->next;
 670:         if (peer->reach != 0 || peer->hmode != MODE_SERVER) {
 671:             peer->stopwatch +=(1<<CLOCK_ADJ);
 672:             if (peer->timer <= peer->stopwatch) {
 673:                 transmit(peer);
 674:                 peer->stopwatch = 0;
 675:             }
 676:         }
 677:         peer = next;
 678:     }
 679: 
 680:     periodic += (1<<CLOCK_ADJ);
 681:     if (periodic >= 60*60) {
 682:         periodic = 0;
 683:         hourly();
 684:     }
 685: 
 686:     clock_watchdog += (1 << CLOCK_ADJ);
 687:     if (clock_watchdog >= NTP_MAXAGE) {
 688:         /* woof, woof - barking dogs bite! */
 689:         sys.leap = ALARM;
 690:         if (clock_watchdog < NTP_MAXAGE + (1 << CLOCK_ADJ)) {
 691:             syslog(LOG_ERR,
 692:                    "logical clock adjust timeout (%d seconds)",
 693:                    NTP_MAXAGE);
 694: #ifdef  DEBUG
 695:             if (debug)
 696:              printf("logical clock adjust timeout (%d seconds)\n",
 697:                 NTP_MAXAGE);
 698: #endif
 699:         }
 700:     }
 701: 
 702: #ifdef  DEBUG
 703:     if (debug)
 704:         (void) fflush(stdout);
 705: #endif
 706: }
 707: 
 708: 
 709: /*
 710:  * init_ntp() reads NTP daemon configuration information from disk file.
 711:  */
 712: void
 713: init_ntp(config)
 714:     char *config;
 715: {
 716:     struct sockaddr_in sin;
 717:     char ref_clock[5];
 718:     char name[81];
 719:     FILE *fp;
 720:     int error = FALSE, c;
 721:     struct ntp_peer *peer;
 722:     int precision;
 723:     int stratum;
 724:     int i;
 725:     int debuglevel;
 726:     int stagger = 0;
 727:     double j;
 728:     extern double drift_comp;
 729: 
 730:     bzero((char *) &sin, sizeof(sin));
 731:     fp = fopen(config, "r");
 732:     if (fp == NULL) {
 733:         fprintf(stderr,"Problem opening NTP initialization file %s\n",
 734:             config);
 735:         syslog(LOG_ERR,"Problem opening NTP initialization file %s",
 736:             config);
 737:         exit(1);
 738:     }
 739: 
 740:     while (fscanf(fp, "%s", name) != EOF) { /* read first word of line
 741: 						 * and compare to key words */
 742:         if (strcmp(name, "maxpeers") == 0) {
 743:             if (fscanf(fp, "%d", &sys.maxpeers) != 1)
 744:                 error = TRUE;
 745:         } else if (strcmp(name, "trusting") == 0) {
 746:             if (fscanf(fp, "%s", name) != 1)
 747:                 error = TRUE;
 748:             else {
 749:                 if (*name == 'Y' || *name == 'y') {
 750:                     trusting = 1;
 751:                 } else if (*name == 'N' || *name == 'n') {
 752:                     trusting = 0;
 753:                 } else
 754:                     trusting = atoi(name);
 755:             }
 756:         } else if (strcmp(name, "logclock") == 0) {
 757:             if (fscanf(fp, "%s", name) != 1)
 758:                 error = TRUE;
 759:             else {
 760:                 if (*name == 'Y' || *name == 'y') {
 761:                     logstats = 1;
 762:                 } else if (*name == 'N' || *name == 'n') {
 763:                     logstats = 0;
 764:                 } else
 765:                     logstats = atoi(name);
 766:             }
 767:         } else if (strcmp(name, "driftfile") == 0) {
 768:             if (fscanf(fp, "%s", name) != 1)
 769:                 error = TRUE;
 770:             else {
 771:                 if (driftcomp_file = malloc(strlen(name)+1))
 772:                     strcpy(driftcomp_file, name);
 773:             }
 774:         } else if (strcmp(name, "waytoobig") == 0 ||
 775:                strcmp(name, "setthreshold") == 0) {
 776:             if (fscanf(fp, "%s", name) != 1)
 777:                 error = TRUE;
 778:             else {
 779:                 if (strcmp(name, "any") == 0)
 780:                     WayTooBig = 10e15;
 781:                 else
 782:                     WayTooBig = atof(name);
 783:             }
 784:         } else if (strncmp(name, "debuglevel", 5) == 0) {
 785:             if (fscanf(fp, "%d", &debuglevel) != 1)
 786:                 error = TRUE;
 787: #ifdef  DEBUG
 788:             else debug += debuglevel;
 789: #endif
 790:         } else if (strcmp(name, "stratum") == 0) {
 791:             fprintf(stderr, "Obsolete command 'stratum'\n");
 792:             error = TRUE;
 793:         } else if (strcmp(name, "precision") == 0) {
 794:             if (fscanf(fp, "%d", &precision) != 1)
 795:                 error = TRUE;
 796:             else sys.precision = (char) precision;
 797: #ifdef  NOSWAP
 798:         } else if (strcmp(name, "noswap") == 0) {
 799:             noswap = 1;
 800: #endif
 801: #ifdef  BROADCAST_NTP
 802:         } else if (strcmp(name, "broadcast") == 0) {
 803:             if (fscanf(fp, "%s", name) != 1) {
 804:                 error = TRUE;
 805:                 goto skipit;
 806:             }
 807:             for (i = 0; i < nintf; i++)
 808:                 if (strcmp(addrs[i].name, name) == 0)
 809:                     break;
 810:             if (i == nintf) {
 811:                 syslog(LOG_ERR, "config file: %s not a known interface");
 812:                 error = TRUE;
 813:                 goto skipit;
 814:             }
 815:             if ((addrs[i].if_flags & IFF_BROADCAST) == 0) {
 816:                 syslog(LOG_ERR, "config file: %s doesn't support broadcast", name);
 817:                 error = TRUE;
 818:                 goto skipit;
 819:             }
 820:             if (peer = check_peer(&addrs[i].bcast, -1)) {
 821:                 syslog(LOG_ERR, "config file: duplicate broadcast for %s",
 822:                        name);
 823:                 error = TRUE;
 824:                 goto skipit;
 825:             }
 826:             peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer));
 827:             if (peer == NULL) {
 828:                 error = TRUE;
 829:                 syslog(LOG_ERR, "No memory");
 830:                 goto skipit;
 831:             }
 832:             make_new_peer(peer);
 833:             peer->flags = PEER_FL_BCAST;
 834:             peer->hmode = MODE_BROADCAST;
 835:             peer->src = addrs[i].bcast;
 836:             peer->sock = i;
 837: #endif	/* BROADCAST_NTP */
 838:         } else if ((strcmp(name, "peer") == 0) ||
 839:                (strcmp(name, "passive") == 0) ||
 840:                (strcmp(name, "server") == 0)) {
 841:             int mode = 0;
 842: 
 843:             if (strcmp(name, "peer") == 0) {
 844:                 mode = MODE_SYM_ACT;
 845:             } else if (strcmp(name, "server") == 0) {
 846:                 mode = MODE_CLIENT;
 847:             } else if (strcmp(name, "passive") == 0) {
 848:                 mode = MODE_SYM_PAS;
 849:             } else {
 850:                 printf("can't happen\n");
 851:                 abort();
 852:             }
 853:             if (fscanf(fp, "%s", name) != 1)
 854:                 error = TRUE;
 855: #ifdef REFCLOCK
 856:             else if (name[0] == '/') {
 857:                 int stratum, precision;
 858:                 char clk_type[20];
 859: 
 860:                 if (fscanf(fp, "%4s", ref_clock) != 1) {
 861:                     error = TRUE;
 862:                     syslog(LOG_ERR, "reference id missing");
 863:                     goto skipit;
 864:                 }
 865:                 if (fscanf(fp, "%4d", &stratum) != 1) {
 866:                     error = TRUE;
 867:                     syslog(LOG_ERR, "reference stratum missing");
 868:                     goto skipit;
 869:                 }
 870:                 if (fscanf(fp, "%4d", &precision) != 1) {
 871:                     error = TRUE;
 872:                     syslog(LOG_ERR, "reference precision missing");
 873:                     goto skipit;
 874:                 }
 875:                 if (fscanf(fp, "%19s", clk_type) != 1) {
 876:                     error = TRUE;
 877:                     syslog(LOG_ERR, "reference type missing");
 878:                     goto skipit;
 879:                 }
 880: 
 881:                 if((i = init_clock(name, clk_type)) < 0) {
 882:                     /* If we could not initialize clock line */
 883: #ifdef DEBUG
 884:                     if (debug)
 885:                         printf("Could not init reference source %s (type %s)\n",
 886:                             name, clk_type);
 887:                     else
 888: #endif DEBUG
 889:                         syslog(LOG_ERR, "Could not init reference source %s (type %s)",
 890:                             name, clk_type);
 891:                     error = TRUE;
 892:                     goto skipit;
 893:                 }
 894:                 peer = (struct ntp_peer *)
 895:                     malloc(sizeof(struct ntp_peer));
 896:                 if (peer == NULL) {
 897:                     close(i);
 898:                     error = TRUE;
 899:                     goto skipit;
 900:                 }
 901:                 make_new_peer(peer);
 902:                 ref_clock[4] = 0;
 903:                 (void) strncpy((char *) &peer->refid,
 904:                         ref_clock, 4);
 905:                 peer->flags = PEER_FL_CONFIG|PEER_FL_REFCLOCK;
 906:                 peer->hmode = MODE_SYM_ACT;
 907:                 peer->stopwatch = stagger;
 908:                 stagger += (1<<CLOCK_ADJ);
 909:                 peer->flags |= PEER_FL_SYNC;
 910:                 peer->sock = i;
 911:                 peer->stratum = stratum;
 912:                 peer->precision = precision;
 913:                 clear(peer);
 914:                 enqueue(&peer_list, peer);
 915:                 if (debug > 1)
 916:                     printf("Peer %s mode %d refid %.4s stratum %d precision %d\n",
 917:                            name,
 918:                            peer->hmode,
 919:                            (char *)&peer->refid,
 920:                            stratum, precision);
 921:                 transmit(peer); /* head start for REFCLOCK */
 922:             }
 923: #endif REFCLOCK
 924:             else if (GetHostName(name, &sin) == 0)
 925:                 syslog(LOG_ERR, "%s: unknown host", name);
 926:             else {
 927:                 for (i=0; i<nintf; i++)
 928:                     if (addrs[i].sin.sin_addr.s_addr ==
 929:                         sin.sin_addr.s_addr)
 930:                         goto skipit;
 931: 
 932:                 if (servp)
 933:                     sin.sin_port = servp->s_port;
 934:                 else
 935:                     sin.sin_port = htons(NTP_PORT);
 936: 
 937:                 peer = check_peer(&sin, -1);
 938:                 if (peer == NULL) {
 939:                     peer = (struct ntp_peer *)
 940:                         malloc(sizeof(struct ntp_peer));
 941:                     if (peer == NULL)
 942:                         error = TRUE;
 943:                     else {
 944:                         make_new_peer(peer);
 945:                         peer->flags = PEER_FL_CONFIG;
 946:                         switch (mode) {
 947:                         case MODE_SYM_ACT:  /* "peer" */
 948:                             peer->hmode = MODE_SYM_ACT;
 949:                             peer->stopwatch = stagger;
 950:                             stagger += (1<<CLOCK_ADJ);
 951:                             peer->flags |= PEER_FL_SYNC;
 952:                             break;
 953:                         case MODE_CLIENT:   /* "server" */
 954:                             peer->hmode = MODE_CLIENT;
 955:                             peer->stopwatch = stagger;
 956:                             stagger += (1<<CLOCK_ADJ);
 957:                             peer->flags |= PEER_FL_SYNC;
 958:                             break;
 959:                         case MODE_SYM_PAS:  /* "passive" */
 960:                             peer->hmode = MODE_SYM_PAS;
 961:                             peer->flags |= PEER_FL_SYNC;
 962:                             break;
 963:                         default:
 964:                             printf("can't happen\n");
 965:                             abort();
 966:                         }
 967:                         peer->src = sin;
 968:                         peer->sock = -1;
 969:                         clear(peer);
 970:                         enqueue(&peer_list, peer);
 971: #ifdef  DEBUG
 972:                         if (debug > 1)
 973:                             printf("Peer %s/%d af %d mode %d\n",
 974:                                    inet_ntoa(peer->src.sin_addr),
 975:                                    ntohs(peer->src.sin_port),
 976:                                    peer->src.sin_family,
 977:                                    peer->hmode);
 978: #endif
 979:                     }
 980:                 } else {
 981:                     syslog(LOG_WARNING,
 982:                      "Duplicate peer %s in in config file",
 983:                            inet_ntoa(sin));
 984: #ifdef  DEBUG
 985:                     if(debug)
 986:                         printf("Duplicate peer %s in in config file\n",
 987:                                inet_ntoa(sin));
 988: #endif
 989:                 }
 990:             }
 991:             skipit:;
 992:         } else if( *name != '#' ) {
 993:             syslog(LOG_ERR, "config file: %s not recognized", name);
 994: #ifdef DEBUG
 995:             if(debug)
 996:                 printf("unrecognized option in config file: %s\n", name);
 997: #endif
 998:         }
 999:         do
1000:             c = fgetc(fp);
1001:         while (c != '\n' && c != EOF);  /* next line */
1002:     }           /* end while */
1003:     if (error) {
1004:         fprintf(stderr, "init_ntp: %s: initialization error\n", config);
1005:         syslog(LOG_ERR, "init_ntp: %s: initialization error", config);
1006: 
1007:         exit(1);
1008:     }
1009:     /*
1010: 	 *  Read saved drift compensation register value.
1011: 	 */
1012:     if ((fp = fopen(driftcomp_file, "r")) != NULL) {
1013:         if (fscanf(fp, "%lf", &j) == 1 && j > -1.0 && j < 1.0) {
1014:             drift_comp = j;
1015:             syslog(LOG_INFO,
1016:                    "Drift compensation value initialized to %f", j);
1017:         } else {
1018:             fprintf(stderr,
1019:                 "init_ntp: bad drift compensation value\n");
1020:             syslog(LOG_ERR,
1021:                    "init_ntp: bad drift compensation value\n");
1022:         }
1023:         fclose(fp);
1024:     }
1025: }
1026: 
1027: int kern_hz;
1028: 
1029: #include <sys/sysctl.h>
1030: 
1031: void
1032: init_kern_vars() {
1033:     int size, mib[2];
1034:     struct clockinfo cinfo;
1035: 
1036:     mib[0] = CTL_KERN;
1037:     mib[1] = KERN_CLOCKRATE;
1038:     size = sizeof (struct clockinfo);
1039:     if  (sysctl(mib, 2, &cinfo, &size, NULL, 0) < 0)
1040:         {
1041:         syslog(LOG_ERR, "sysctl() for kern.clockrate: %m\n");
1042:         return;
1043:         }
1044:     kern_hz = cinfo.hz;
1045: 
1046:     /*
1047: 	 *  If we have successfully discovered `hz' from the kernel, then we
1048: 	 *  can set sys.precision, if it has not already been specified.  If
1049: 	 *  no value of `hz' is available, then use default (-6)
1050: 	 */
1051:     if (sys.precision == 0) {
1052:         if (kern_hz <= 64)
1053:             sys.precision = -6;
1054:         else if (kern_hz <= 128)
1055:             sys.precision = -7;
1056:         else if (kern_hz <= 256)
1057:             sys.precision = -8;
1058:         else if (kern_hz <= 512)
1059:             sys.precision = -9;
1060:         else if (kern_hz <= 1024)
1061:             sys.precision = -10;
1062:         else sys.precision = -11;
1063:         syslog(LOG_INFO, "sys.precision set to %d from sys clock of %d HZ",
1064:                sys.precision, kern_hz);
1065:     }
1066: }
1067: 
1068: 
1069: /*
1070:  * Given host or net name or internet address in dot notation assign the
1071:  * internet address in byte format. source is ../routed/startup.c with minor
1072:  * changes to detect syntax errors.
1073:  *
1074:  * We now try to interpret the name as in address before we go off and bother
1075:  * the domain name servers.
1076:  *
1077:  * Unfortunately the library routine inet_addr() does not detect mal formed
1078:  * addresses that have characters or byte values > 255.
1079:  */
1080: 
1081: GetHostName(name, sin)
1082:     char *name;
1083:     struct sockaddr_in *sin;
1084: {
1085:     long HostAddr;
1086:     struct hostent *hp;
1087: 
1088:     if ((HostAddr = inet_addr(name)) != -1) {
1089:         sin->sin_addr.s_addr = (u_long) HostAddr;
1090:         sin->sin_family = AF_INET;
1091:         return (1);
1092:     }
1093: 
1094:     if (hp = gethostbyname(name)) {
1095:         if (hp->h_addrtype != AF_INET)
1096:             return (0);
1097:         bcopy((char *) hp->h_addr, (char *) &sin->sin_addr,
1098:               hp->h_length);
1099:         sin->sin_family = hp->h_addrtype;
1100:         return (1);
1101:     }
1102:     return (0);
1103: }
1104: 
1105: #define PKTBUF_SIZE 536
1106: 
1107: /* number of clocks per packet */
1108: #define N_NTP_PKTS \
1109:       ((PKTBUF_SIZE - sizeof(struct ntpinfo))/(sizeof(struct xclockinfo)))
1110: 
1111: query_mode(dst, ntp, sock)
1112:     struct sockaddr_in *dst;
1113:     struct ntpdata *ntp;
1114:     int sock;       /* which socket packet arrived on */
1115: {
1116:     char packet[PKTBUF_SIZE];
1117:     register struct ntpinfo *nip = (struct ntpinfo *) packet;
1118:     register struct ntp_peer *peer = peer_list.head;
1119:     struct xclockinfo *cip;
1120:     int seq = 0;
1121:     int i;
1122: 
1123:     if (ntp->stratum != INFO_QUERY)
1124:         return;
1125:     nip->version = NTPDC_VERSION;
1126:     nip->type = INFO_REPLY;
1127:     nip->seq = 0;
1128:     nip->npkts = peer_list.members/N_NTP_PKTS;
1129:     if (peer_list.members % N_NTP_PKTS)
1130:         nip->npkts++;
1131:     nip->peers = peer_list.members;
1132:     nip->count = 0;
1133:     cip = (struct xclockinfo *)&nip[1];
1134: 
1135:     while (peer != NULL) {
1136:         cip->net_address = peer->src.sin_addr.s_addr;
1137:         if (peer->sock < 0)
1138:             cip->my_address = htonl(0);
1139:         else
1140:             cip->my_address = addrs[peer->sock].sin.sin_addr.s_addr;
1141:         cip->port = peer->src.sin_port; /* already in network order */
1142:         cip->flags = htons(peer->flags);
1143:         if (sys.peer == peer)
1144:             cip->flags |= htons(PEER_FL_SELECTED);
1145:         cip->pkt_sent = htonl(peer->pkt_sent);
1146:         cip->pkt_rcvd = htonl(peer->pkt_rcvd);
1147:         cip->pkt_dropped = htonl(peer->pkt_dropped);
1148:         cip->timer = htonl(peer->timer);
1149:         cip->leap = peer->leap;
1150:         cip->stratum = peer->stratum;
1151:         cip->ppoll = peer->ppoll;
1152:         cip->precision = (int) peer->precision;
1153:         cip->hpoll = peer->hpoll;
1154:         cip->reach = htons((u_short)peer->reach & NTP_WINDOW_SHIFT_MASK);
1155:         cip->estdisp = htonl((long) (peer->estdisp * 1000.0));
1156:         cip->estdelay = htonl((long) (peer->estdelay * 1000.0));
1157:         cip->estoffset = htonl((long) (peer->estoffset * 1000.0));
1158:         cip->refid = peer->refid;
1159:         cip->reftime.int_part = htonl(peer->reftime.int_part);
1160:         cip->reftime.fraction = htonl(peer->reftime.fraction);
1161: 
1162:         cip->info_filter.index = htons(peer->filter.samples);
1163:         for (i = 0; i < PEER_SHIFT; i++) {
1164:             cip->info_filter.offset[i] =
1165:                 htonl((long)(peer->filter.offset[i] * 1000.0));
1166:             cip->info_filter.delay[i] =
1167:                 htonl((long)(peer->filter.delay[i] * 1000.0));
1168:         }
1169:         cip++;
1170:         if (nip->count++ >= N_NTP_PKTS - 1) {
1171:             nip->seq =seq++;
1172:             if ((sendto(addrs[sock].fd, (char *) packet,
1173:                     sizeof(packet), 0,
1174:                     (struct sockaddr *) dst,
1175:                     sizeof(struct sockaddr_in))) < 0) {
1176:                 syslog(LOG_ERR, "sendto: %s  %m",
1177:                        inet_ntoa(dst->sin_addr));
1178:             }
1179:             nip->type = INFO_REPLY;
1180:             nip->count = 0;
1181:             cip = (struct xclockinfo *)&nip[1];
1182:         }
1183:         peer = peer->next;
1184:     }
1185:     if (nip->count) {
1186:         nip->seq = seq;
1187:         if ((sendto(addrs[sock].fd, (char *) packet, sizeof(packet), 0,
1188:                 dst, sizeof(struct sockaddr_in))) < 0) {
1189:             syslog(LOG_ERR, "sendto: %s  %m", ntoa(dst->sin_addr));
1190:         }
1191:     }
1192: }
1193: 
1194: /* every hour, dump some useful information to the log */
1195: void
1196: hourly() {
1197:     char buf[200];
1198:     register int p = 0;
1199:     static double drifts[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
1200:     static int drift_count = 0;
1201:     extern double drift_comp, compliance;
1202:     extern int peer_switches, peer_sw_inhibited;
1203: 
1204:     (void) sprintf(buf, "stats: dc %f comp %f peersw %d inh %d",
1205:                drift_comp, compliance, peer_switches,
1206:                peer_sw_inhibited);
1207: 
1208:     if (sys.peer == NULL) {
1209:         strcat(buf, " UNSYNC");
1210: #ifdef  REFCLOCK
1211:     } else if (sys.peer->flags & PEER_FL_REFCLOCK) {
1212:         p = strlen(buf);
1213:         (void) sprintf(buf + p, " off %f SYNC %.4s %d",
1214:                    sys.peer->estoffset,
1215:                    (char *)&sys.peer->refid,
1216:                    sys.peer->stratum);
1217: #endif
1218:     } else {
1219:         p = strlen(buf);
1220:         (void) sprintf(buf + p, " off %f SYNC %s %d",
1221:                    sys.peer->estoffset,
1222:                    ntoa(sys.peer->src.sin_addr),
1223:                    sys.peer->stratum);
1224:     }
1225:     syslog(LOG_INFO, buf);
1226: #ifdef  DEBUG
1227:     if (debug)
1228:         puts(buf);
1229: #endif
1230:     /*
1231: 	 *  If the drift compensation snapshot file is open, then write
1232: 	 *  the current value to it.  Since there's only one block in the
1233: 	 *  file, and no one else is reading it, we'll just keep the file
1234: 	 *  open and write to it.
1235: 	 */
1236:     if (drift_fd >= 0) {
1237:         drifts[drift_count % 5] = drift_comp;
1238:         /* works out to be 70 bytes */
1239:         (void) sprintf(buf,
1240:              "%12.10f %12.10f %12.10f %12.10f %12.10f %4d\n",
1241:                    drifts[drift_count % 5],
1242:                    drifts[(drift_count+4) % 5],
1243:                    drifts[(drift_count+3) % 5],
1244:                    drifts[(drift_count+2) % 5],
1245:                    drifts[(drift_count+1) % 5],
1246:                    drift_count + 1);
1247: 
1248:         (void) lseek(drift_fd, 0L, L_SET);
1249:         if (write(drift_fd, buf, strlen(buf)) < 0) {
1250:             syslog(LOG_ERR, "Error writing drift comp file: %m");
1251:         }
1252:         drift_count++;
1253:     }
1254: }
1255: 
1256: #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
1257: void
1258: incdebug()
1259: {
1260:     if (debug == 255)
1261:         return;
1262:     debug++;
1263:     printf("DEBUG LEVEL %d\n", debug);
1264: #ifdef  LOG_DAEMON
1265:     (void) setlogmask(LOG_UPTO(LOG_DEBUG));
1266: #endif
1267:     syslog(LOG_DEBUG, "DEBUG LEVEL %d", debug);
1268: }
1269: 
1270: void
1271: decdebug()
1272: {
1273:     if (debug == 0)
1274:         return;
1275:     debug--;
1276:     printf("DEBUG LEVEL %d\n", debug);
1277:     syslog(LOG_DEBUG, "DEBUG LEVEL %d", debug);
1278: #ifdef  LOG_DAEMON
1279:     if (debug == 0)
1280:         (void) setlogmask(LOG_UPTO(LOG_INFO));
1281: #endif
1282: }
1283: #endif
1284: 
1285: void
1286: finish(sig)
1287:     int sig;
1288: {
1289:     syslog(LOG_NOTICE, "terminated: (sig %d)", sig);
1290: #ifdef  DEBUG
1291:     if (debug)
1292:         printf("ntpd terminated (sig %d)\n", sig);
1293: #endif
1294:     exit(1);
1295: }
1296: 
1297: #ifdef  REFCLOCK
1298: struct refclock {
1299:     int fd;
1300:     int (*reader)();
1301:     struct refclock *next;
1302: } *refclocks = NULL;
1303: 
1304: int init_clock_local(), read_clock_local();
1305: #ifdef PSTI
1306: int init_clock_psti(), read_clock_psti();
1307: #endif PSTI
1308: 
1309: init_clock(name, type)
1310: char *name, *type;
1311: {
1312:     struct refclock *r;
1313:     int (*reader)();
1314:     int cfd;
1315: 
1316:     if (strcmp(type, "local") == 0) {
1317:         reader = read_clock_local;
1318:         cfd = init_clock_local(name);
1319:     }
1320: #ifdef PSTI
1321:     else if (strcmp(type, "psti") == 0) {
1322:         reader = read_clock_psti;
1323:         cfd = init_clock_psti(name);
1324:     }
1325: #endif PSTI
1326:     else {
1327:         if (debug) printf("Unknown reference type\n"); else
1328:         syslog(LOG_ERR, "Unknown reference clock type (%s)\n", type);
1329:         return(-1);
1330:     }
1331:     if (cfd >= 0) {
1332:         r = (struct refclock *)malloc(sizeof(struct refclock));
1333:         r->fd = cfd;
1334:         r->reader = reader;
1335:         r->next = refclocks;
1336:         refclocks = r;
1337:     }
1338:     return(cfd);
1339: }
1340: 
1341: read_clock(cfd, tvpp, otvpp)
1342: int cfd;
1343: struct timeval **tvpp, **otvpp;
1344: {
1345:     struct refclock *r;
1346: 
1347:     for (r = refclocks; r; r = r->next)
1348:         if(r->fd == cfd)
1349:             return((r->reader)(cfd, tvpp, otvpp));
1350:     return(1); /* Can't happen */
1351: }
1352: #endif

Defined functions

GetHostName defined in line 1081; used 1 times
check_peer defined in line 444; used 4 times
decdebug defined in line 1270; used 2 times
demobilize defined in line 546; used 3 times
dump_pkt defined in line 462; used 4 times
enqueue defined in line 610; used 3 times
finish defined in line 1285; used 3 times
hourly defined in line 1195; used 2 times
incdebug defined in line 1257; used 2 times
init_clock defined in line 1309; used 1 times
init_kern_vars defined in line 1031; used 2 times
init_ntp defined in line 712; used 2 times
main defined in line 171; never used
make_new_peer defined in line 510; used 7 times
query_mode defined in line 1111; used 1 times
read_clock defined in line 1341; used 1 times
timeout defined in line 639; used 2 times
tock defined in line 634; used 2 times

Defined variables

WayTooBig defined in line 155; used 7 times
clock_watchdog defined in line 156; used 4 times
conf defined in line 137; used 2 times
debug defined in line 142; used 31 times
doset defined in line 149; used 3 times
drift_fd defined in line 139; used 4 times
driftcomp_file defined in line 138; used 4 times
dst_sock defined in line 127; used 1 times
it defined in line 132; used 1 times
itp defined in line 133; used 5 times
kern_hz defined in line 1027; used 7 times
logstats defined in line 153; used 5 times
noswap defined in line 146; used 3 times
ntpframe defined in line 158; used 2 times
peer_list defined in line 130; used 17 times
prog_name defined in line 135; used 7 times
rcsid defined in line 2; never used
refclocks defined in line 1302; used 3 times
selfds defined in line 151; used 8 times
servp defined in line 129; used 6 times
sys defined in line 159; used 81 times
ticked defined in line 150; used 3 times
trusting defined in line 152; used 4 times
tv defined in line 134; used 4 times

Defined struct's

refclock defined in line 1298; used 10 times

Defined macros

FALSE defined in line 125; used 1 times
LOG_NTP defined in line 279; used 2 times
N_NTP_PKTS defined in line 1108; used 3 times
PKTBUF_SIZE defined in line 1105; used 2 times
TRUE defined in line 124; used 21 times
Last modified: 1995-07-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 7842
Valid CSS Valid XHTML 1.0 Strict