Annotation of embedaddon/ntp/ntpd/ntpd.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * ntpd.c - main program for the fixed point NTP daemon
                      3:  */
                      4: 
                      5: #ifdef HAVE_CONFIG_H
                      6: # include <config.h>
                      7: #endif
                      8: 
                      9: #include "ntp_machine.h"
                     10: #include "ntpd.h"
                     11: #include "ntp_io.h"
                     12: #include "ntp_stdlib.h"
                     13: #include <ntp_random.h>
                     14: 
                     15: #include "ntp_syslog.h"
                     16: #include "isc/assertions.h"
                     17: #include "isc/error.h"
                     18: #include "isc/strerror.h"
                     19: #include "isc/formatcheck.h"
                     20: 
                     21: #ifdef SIM
                     22: # include "ntpsim.h"
                     23: #endif
                     24: 
                     25: #include "ntp_libopts.h"
                     26: #include "ntpd-opts.h"
                     27: 
                     28: #ifdef HAVE_UNISTD_H
                     29: # include <unistd.h>
                     30: #endif
                     31: #ifdef HAVE_SYS_STAT_H
                     32: # include <sys/stat.h>
                     33: #endif
                     34: #include <stdio.h>
                     35: #if !defined(VMS)      /*wjm*/
                     36: # ifdef HAVE_SYS_PARAM_H
                     37: #  include <sys/param.h>
                     38: # endif
                     39: #endif /* VMS */
                     40: #ifdef HAVE_SYS_SIGNAL_H
                     41: # include <sys/signal.h>
                     42: #else
                     43: # include <signal.h>
                     44: #endif
                     45: #ifdef HAVE_SYS_IOCTL_H
                     46: # include <sys/ioctl.h>
                     47: #endif /* HAVE_SYS_IOCTL_H */
                     48: #ifdef HAVE_SYS_RESOURCE_H
                     49: # include <sys/resource.h>
                     50: #endif /* HAVE_SYS_RESOURCE_H */
                     51: #if defined(HAVE_RTPRIO)
                     52: # ifdef HAVE_SYS_RESOURCE_H
                     53: #  include <sys/resource.h>
                     54: # endif
                     55: # ifdef HAVE_SYS_LOCK_H
                     56: #  include <sys/lock.h>
                     57: # endif
                     58: # include <sys/rtprio.h>
                     59: #else
                     60: # ifdef HAVE_PLOCK
                     61: #  ifdef HAVE_SYS_LOCK_H
                     62: #      include <sys/lock.h>
                     63: #  endif
                     64: # endif
                     65: #endif
                     66: #if defined(HAVE_SCHED_SETSCHEDULER)
                     67: # ifdef HAVE_SCHED_H
                     68: #  include <sched.h>
                     69: # else
                     70: #  ifdef HAVE_SYS_SCHED_H
                     71: #   include <sys/sched.h>
                     72: #  endif
                     73: # endif
                     74: #endif
                     75: #if defined(HAVE_SYS_MMAN_H)
                     76: # include <sys/mman.h>
                     77: #endif
                     78: 
                     79: #ifdef HAVE_TERMIOS_H
                     80: # include <termios.h>
                     81: #endif
                     82: 
                     83: #ifdef SYS_DOMAINOS
                     84: # include <apollo/base.h>
                     85: #endif /* SYS_DOMAINOS */
                     86: 
                     87: #include "recvbuff.h"
                     88: #include "ntp_cmdargs.h"
                     89: 
                     90: #if 0                          /* HMS: I don't think we need this. 961223 */
                     91: #ifdef LOCK_PROCESS
                     92: # ifdef SYS_SOLARIS
                     93: #  include <sys/mman.h>
                     94: # else
                     95: #  include <sys/lock.h>
                     96: # endif
                     97: #endif
                     98: #endif
                     99: 
                    100: #ifdef _AIX
                    101: # include <ulimit.h>
                    102: #endif /* _AIX */
                    103: 
                    104: #ifdef SCO5_CLOCK
                    105: # include <sys/ci/ciioctl.h>
                    106: #endif
                    107: 
                    108: #ifdef HAVE_DROPROOT
                    109: # include <ctype.h>
                    110: # include <grp.h>
                    111: # include <pwd.h>
                    112: #ifdef HAVE_LINUX_CAPABILITIES
                    113: # include <sys/capability.h>
                    114: # include <sys/prctl.h>
                    115: #endif
                    116: #endif
                    117: 
                    118: /*
                    119:  * Signals we catch for debugging.     If not debugging we ignore them.
                    120:  */
                    121: #define MOREDEBUGSIG   SIGUSR1
                    122: #define LESSDEBUGSIG   SIGUSR2
                    123: 
                    124: /*
                    125:  * Signals which terminate us gracefully.
                    126:  */
                    127: #ifndef SYS_WINNT
                    128: # define SIGDIE1       SIGHUP
                    129: # define SIGDIE3       SIGQUIT
                    130: # define SIGDIE2       SIGINT
                    131: # define SIGDIE4       SIGTERM
                    132: #endif /* SYS_WINNT */
                    133: 
                    134: #ifdef HAVE_DNSREGISTRATION
                    135: #include <dns_sd.h>
                    136: DNSServiceRef mdns;
                    137: #endif
                    138: 
                    139: /*
                    140:  * Scheduling priority we run at
                    141:  */
                    142: #define NTPD_PRIO      (-12)
                    143: 
                    144: int priority_done = 2;         /* 0 - Set priority */
                    145:                                /* 1 - priority is OK where it is */
                    146:                                /* 2 - Don't set priority */
                    147:                                /* 1 and 2 are pretty much the same */
                    148: 
                    149: #ifdef DEBUG
                    150: /*
                    151:  * Debugging flag
                    152:  */
                    153: volatile int debug = 0;                /* No debugging by default */
                    154: #endif
                    155: 
                    156: int    listen_to_virtual_ips = 1;
                    157: const char *specific_interface = NULL;        /* interface name or IP address to bind to */
                    158: 
                    159: /*
                    160:  * No-fork flag.  If set, we do not become a background daemon.
                    161:  */
                    162: int nofork = 0;                        /* Fork by default */
                    163: 
                    164: #ifdef HAVE_DNSREGISTRATION
                    165: /*
                    166:  * mDNS registration flag. If set, we attempt to register with the mDNS system, but only
                    167:  * after we have synched the first time. If the attempt fails, then try again once per 
                    168:  * minute for up to 5 times. After all, we may be starting before mDNS.
                    169:  */
                    170: int mdnsreg = 1;
                    171: int mdnstries = 5;
                    172: #endif  /* HAVE_DNSREGISTRATION */
                    173: 
                    174: #ifdef HAVE_DROPROOT
                    175: int droproot = 0;
                    176: char *user = NULL;             /* User to switch to */
                    177: char *group = NULL;            /* group to switch to */
                    178: const char *chrootdir = NULL;  /* directory to chroot to */
                    179: int sw_uid;
                    180: int sw_gid;
                    181: char *endp;
                    182: struct group *gr;
                    183: struct passwd *pw;
                    184: #endif /* HAVE_DROPROOT */
                    185: 
                    186: /*
                    187:  * Initializing flag.  All async routines watch this and only do their
                    188:  * thing when it is clear.
                    189:  */
                    190: int initializing;
                    191: 
                    192: /*
                    193:  * Version declaration
                    194:  */
                    195: extern const char *Version;
                    196: 
                    197: char const *progname;
                    198: 
                    199: int was_alarmed;
                    200: 
                    201: #ifdef DECL_SYSCALL
                    202: /*
                    203:  * We put this here, since the argument profile is syscall-specific
                    204:  */
                    205: extern int syscall     (int, ...);
                    206: #endif /* DECL_SYSCALL */
                    207: 
                    208: 
                    209: #ifdef SIGDIE2
                    210: static RETSIGTYPE      finish          (int);
                    211: #endif /* SIGDIE2 */
                    212: 
                    213: #ifdef DEBUG
                    214: #ifndef SYS_WINNT
                    215: static RETSIGTYPE      moredebug       (int);
                    216: static RETSIGTYPE      lessdebug       (int);
                    217: #endif
                    218: #else /* not DEBUG */
                    219: static RETSIGTYPE      no_debug        (int);
                    220: #endif /* not DEBUG */
                    221: 
                    222: int            ntpdmain                (int, char **);
                    223: static void    set_process_priority    (void);
                    224: void           init_logging            (char const *, int);
                    225: void           setup_logfile           (void);
                    226: static void    process_commandline_opts(int *, char ***);
                    227: 
                    228: static void    assertion_failed        (const char *file, int line,
                    229:        isc_assertiontype_t type, const char *cond);
                    230: static void    library_fatal_error     (const char *file, int line,
                    231:        const char *format, va_list args) ISC_FORMAT_PRINTF(3, 0);
                    232: static void    library_unexpected_error(const char *file, int line,
                    233:        const char *format, va_list args) ISC_FORMAT_PRINTF(3, 0);
                    234: 
                    235: 
                    236: /*
                    237:  * Initialize the logging
                    238:  */
                    239: void
                    240: init_logging(
                    241:        char const *name,
                    242:        int log_version
                    243:        )
                    244: {
                    245:        const char *cp;
                    246: 
                    247:        /*
                    248:         * Logging.  This may actually work on the gizmo board.  Find a name
                    249:         * to log with by using the basename
                    250:         */
                    251:        cp = strrchr(name, '/');
                    252:        if (cp == 0)
                    253:                cp = name;
                    254:        else
                    255:                cp++;
                    256: 
                    257: #if !defined(VMS)
                    258: 
                    259: # ifndef LOG_DAEMON
                    260:        openlog(cp, LOG_PID);
                    261: # else /* LOG_DAEMON */
                    262: 
                    263: #  ifndef LOG_NTP
                    264: #      define  LOG_NTP LOG_DAEMON
                    265: #  endif
                    266:        openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);
                    267: #  ifdef DEBUG
                    268:        if (debug)
                    269:                setlogmask(LOG_UPTO(LOG_DEBUG));
                    270:        else
                    271: #  endif /* DEBUG */
                    272:                setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
                    273: # endif /* LOG_DAEMON */
                    274: #endif /* !VMS */
                    275: 
                    276:        if (log_version)
                    277:            NLOG(NLOG_SYSINFO) /* 'if' clause for syslog */
                    278:                msyslog(LOG_NOTICE, "%s", Version);
                    279: }
                    280: 
                    281: 
                    282: /*
                    283:  * Redirect logging to a file if requested with -l.
                    284:  * The ntp.conf logfile directive does not use this code, see
                    285:  * config_vars() in ntp_config.c.
                    286:  */
                    287: void
                    288: setup_logfile(
                    289:        void
                    290:        )
                    291: {
                    292:        if (HAVE_OPT( LOGFILE )) {
                    293:                const char *my_optarg = OPT_ARG( LOGFILE );
                    294:                FILE *new_file;
                    295: 
                    296:                if(strcmp(my_optarg, "stderr") == 0)
                    297:                        new_file = stderr;
                    298:                else if(strcmp(my_optarg, "stdout") == 0)
                    299:                        new_file = stdout;
                    300:                else
                    301:                        new_file = fopen(my_optarg, "a");
                    302:                if (new_file != NULL) {
                    303:                        NLOG(NLOG_SYSINFO)
                    304:                                msyslog(LOG_NOTICE, "logging to file %s", my_optarg);
                    305:                        if (syslog_file != NULL &&
                    306:                                fileno(syslog_file) != fileno(new_file))
                    307:                                (void)fclose(syslog_file);
                    308: 
                    309:                        syslog_file = new_file;
                    310:                        syslogit = 0;
                    311:                }
                    312:                else
                    313:                        msyslog(LOG_ERR,
                    314:                                "Cannot open log file %s",
                    315:                                my_optarg);
                    316:        }
                    317: }
                    318: 
                    319: 
                    320: static void
                    321: process_commandline_opts(
                    322:        int *pargc,
                    323:        char ***pargv
                    324:        )
                    325: {
                    326:        int optct;
                    327:        
                    328:        optct = ntpOptionProcess(&ntpdOptions, *pargc, *pargv);
                    329:        *pargc -= optct;
                    330:        *pargv += optct;
                    331: }
                    332: 
                    333: 
                    334: #ifdef SIM
                    335: int
                    336: main(
                    337:        int argc,
                    338:        char *argv[]
                    339:        )
                    340: {
                    341:        process_commandline_opts(&argc, &argv);
                    342: 
                    343:        return ntpsim(argc, argv);
                    344: }
                    345: #else /* SIM */
                    346: #ifdef NO_MAIN_ALLOWED
                    347: CALL(ntpd,"ntpd",ntpdmain);
                    348: #else
                    349: #ifndef SYS_WINNT
                    350: int
                    351: main(
                    352:        int argc,
                    353:        char *argv[]
                    354:        )
                    355: {
                    356:        return ntpdmain(argc, argv);
                    357: }
                    358: #endif /* SYS_WINNT */
                    359: #endif /* NO_MAIN_ALLOWED */
                    360: #endif /* SIM */
                    361: 
                    362: #ifdef _AIX
                    363: /*
                    364:  * OK. AIX is different than solaris in how it implements plock().
                    365:  * If you do NOT adjust the stack limit, you will get the MAXIMUM
                    366:  * stack size allocated and PINNED with you program. To check the
                    367:  * value, use ulimit -a.
                    368:  *
                    369:  * To fix this, we create an automatic variable and set our stack limit
                    370:  * to that PLUS 32KB of extra space (we need some headroom).
                    371:  *
                    372:  * This subroutine gets the stack address.
                    373:  *
                    374:  * Grover Davidson and Matt Ladendorf
                    375:  *
                    376:  */
                    377: static char *
                    378: get_aix_stack(void)
                    379: {
                    380:        char ch;
                    381:        return (&ch);
                    382: }
                    383: 
                    384: /*
                    385:  * Signal handler for SIGDANGER.
                    386:  */
                    387: static void
                    388: catch_danger(int signo)
                    389: {
                    390:        msyslog(LOG_INFO, "ntpd: setpgid(): %m");
                    391:        /* Make the system believe we'll free something, but don't do it! */
                    392:        return;
                    393: }
                    394: #endif /* _AIX */
                    395: 
                    396: /*
                    397:  * Set the process priority
                    398:  */
                    399: static void
                    400: set_process_priority(void)
                    401: {
                    402: 
                    403: #ifdef DEBUG
                    404:        if (debug > 1)
                    405:                msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
                    406:                        ((priority_done)
                    407:                         ? "Leave priority alone"
                    408:                         : "Attempt to set priority"
                    409:                                ),
                    410:                        priority_done);
                    411: #endif /* DEBUG */
                    412: 
                    413: #if defined(HAVE_SCHED_SETSCHEDULER)
                    414:        if (!priority_done) {
                    415:                extern int config_priority_override, config_priority;
                    416:                int pmax, pmin;
                    417:                struct sched_param sched;
                    418: 
                    419:                pmax = sched_get_priority_max(SCHED_FIFO);
                    420:                sched.sched_priority = pmax;
                    421:                if ( config_priority_override ) {
                    422:                        pmin = sched_get_priority_min(SCHED_FIFO);
                    423:                        if ( config_priority > pmax )
                    424:                                sched.sched_priority = pmax;
                    425:                        else if ( config_priority < pmin )
                    426:                                sched.sched_priority = pmin;
                    427:                        else
                    428:                                sched.sched_priority = config_priority;
                    429:                }
                    430:                if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
                    431:                        msyslog(LOG_ERR, "sched_setscheduler(): %m");
                    432:                else
                    433:                        ++priority_done;
                    434:        }
                    435: #endif /* HAVE_SCHED_SETSCHEDULER */
                    436: #if defined(HAVE_RTPRIO)
                    437: # ifdef RTP_SET
                    438:        if (!priority_done) {
                    439:                struct rtprio srtp;
                    440: 
                    441:                srtp.type = RTP_PRIO_REALTIME;  /* was: RTP_PRIO_NORMAL */
                    442:                srtp.prio = 0;          /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
                    443: 
                    444:                if (rtprio(RTP_SET, getpid(), &srtp) < 0)
                    445:                        msyslog(LOG_ERR, "rtprio() error: %m");
                    446:                else
                    447:                        ++priority_done;
                    448:        }
                    449: # else /* not RTP_SET */
                    450:        if (!priority_done) {
                    451:                if (rtprio(0, 120) < 0)
                    452:                        msyslog(LOG_ERR, "rtprio() error: %m");
                    453:                else
                    454:                        ++priority_done;
                    455:        }
                    456: # endif /* not RTP_SET */
                    457: #endif  /* HAVE_RTPRIO */
                    458: #if defined(NTPD_PRIO) && NTPD_PRIO != 0
                    459: # ifdef HAVE_ATT_NICE
                    460:        if (!priority_done) {
                    461:                errno = 0;
                    462:                if (-1 == nice (NTPD_PRIO) && errno != 0)
                    463:                        msyslog(LOG_ERR, "nice() error: %m");
                    464:                else
                    465:                        ++priority_done;
                    466:        }
                    467: # endif /* HAVE_ATT_NICE */
                    468: # ifdef HAVE_BSD_NICE
                    469:        if (!priority_done) {
                    470:                if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
                    471:                        msyslog(LOG_ERR, "setpriority() error: %m");
                    472:                else
                    473:                        ++priority_done;
                    474:        }
                    475: # endif /* HAVE_BSD_NICE */
                    476: #endif /* NTPD_PRIO && NTPD_PRIO != 0 */
                    477:        if (!priority_done)
                    478:                msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
                    479: }
                    480: 
                    481: 
                    482: /*
                    483:  * Main program.  Initialize us, disconnect us from the tty if necessary,
                    484:  * and loop waiting for I/O and/or timer expiries.
                    485:  */
                    486: int
                    487: ntpdmain(
                    488:        int argc,
                    489:        char *argv[]
                    490:        )
                    491: {
                    492:        l_fp now;
                    493:        struct recvbuf *rbuf;
                    494: #ifdef _AIX                    /* HMS: ifdef SIGDANGER? */
                    495:        struct sigaction sa;
                    496: #endif
                    497: 
                    498:        progname = argv[0];
                    499:        initializing = 1;               /* mark that we are initializing */
                    500:        process_commandline_opts(&argc, &argv);
                    501:        init_logging(progname, 1);      /* Open the log file */
                    502: 
                    503: #ifdef HAVE_UMASK
                    504:        {
                    505:                mode_t uv;
                    506: 
                    507:                uv = umask(0);
                    508:                if(uv)
                    509:                        (void) umask(uv);
                    510:                else
                    511:                        (void) umask(022);
                    512:        }
                    513: #endif
                    514: 
                    515: #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
                    516:        {
                    517:                uid_t uid;
                    518: 
                    519:                uid = getuid();
                    520:                if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
                    521:                        msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
                    522:                        printf("must be run as root, not uid %ld\n", (long)uid);
                    523:                        exit(1);
                    524:                }
                    525:        }
                    526: #endif
                    527: 
                    528:        /* getstartup(argc, argv); / * startup configuration, may set debug */
                    529: 
                    530: #ifdef DEBUG
                    531:        debug = DESC(DEBUG_LEVEL).optOccCt;
                    532:        DPRINTF(1, ("%s\n", Version));
                    533: #endif
                    534: 
                    535:        /* honor -l/--logfile option to log to a file */
                    536:        setup_logfile();
                    537: 
                    538: /*
                    539:  * Enable the Multi-Media Timer for Windows?
                    540:  */
                    541: #ifdef SYS_WINNT
                    542:        if (HAVE_OPT( MODIFYMMTIMER ))
                    543:                set_mm_timer(MM_TIMER_HIRES);
                    544: #endif
                    545: 
                    546:        if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT )
                    547: #ifdef DEBUG
                    548:            || debug
                    549: #endif
                    550:            || HAVE_OPT( SAVECONFIGQUIT ))
                    551:                nofork = 1;
                    552: 
                    553:        if (HAVE_OPT( NOVIRTUALIPS ))
                    554:                listen_to_virtual_ips = 0;
                    555: 
                    556:        /*
                    557:         * --interface, listen on specified interfaces
                    558:         */
                    559:        if (HAVE_OPT( INTERFACE )) {
                    560:                int             ifacect = STACKCT_OPT( INTERFACE );
                    561:                const char**    ifaces  = STACKLST_OPT( INTERFACE );
                    562:                sockaddr_u      addr;
                    563: 
                    564:                while (ifacect-- > 0) {
                    565:                        add_nic_rule(
                    566:                                is_ip_address(*ifaces, &addr)
                    567:                                        ? MATCH_IFADDR
                    568:                                        : MATCH_IFNAME,
                    569:                                *ifaces, -1, ACTION_LISTEN);
                    570:                        ifaces++;
                    571:                }
                    572:        }
                    573: 
                    574:        if (HAVE_OPT( NICE ))
                    575:                priority_done = 0;
                    576: 
                    577: #if defined(HAVE_SCHED_SETSCHEDULER)
                    578:        if (HAVE_OPT( PRIORITY )) {
                    579:                config_priority = OPT_VALUE_PRIORITY;
                    580:                config_priority_override = 1;
                    581:                priority_done = 0;
                    582:        }
                    583: #endif
                    584: 
                    585: #ifdef SYS_WINNT
                    586:        /*
                    587:         * Start interpolation thread, must occur before first
                    588:         * get_systime()
                    589:         */
                    590:        init_winnt_time();
                    591: #endif
                    592:        /*
                    593:         * Initialize random generator and public key pair
                    594:         */
                    595:        get_systime(&now);
                    596: 
                    597:        ntp_srandom((int)(now.l_i * now.l_uf));
                    598: 
                    599: #if !defined(VMS)
                    600: # ifndef NODETACH
                    601:        /*
                    602:         * Detach us from the terminal.  May need an #ifndef GIZMO.
                    603:         */
                    604:        if (!nofork) {
                    605: 
                    606:                /*
                    607:                 * Install trap handlers to log errors and assertion
                    608:                 * failures.  Default handlers print to stderr which 
                    609:                 * doesn't work if detached.
                    610:                 */
                    611:                isc_assertion_setcallback(assertion_failed);
                    612:                isc_error_setfatal(library_fatal_error);
                    613:                isc_error_setunexpected(library_unexpected_error);
                    614: 
                    615: #  ifndef SYS_WINNT
                    616: #   ifdef HAVE_DAEMON
                    617:                daemon(0, 0);
                    618: #   else /* not HAVE_DAEMON */
                    619:                if (fork())     /* HMS: What about a -1? */
                    620:                        exit(0);
                    621: 
                    622:                {
                    623: #if !defined(F_CLOSEM)
                    624:                        u_long s;
                    625:                        int max_fd;
                    626: #endif /* !FCLOSEM */
                    627:                        if (syslog_file != NULL) {
                    628:                                fclose(syslog_file);
                    629:                                syslog_file = NULL;
                    630:                        }
                    631: #if defined(F_CLOSEM)
                    632:                        /*
                    633:                         * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
                    634:                         * by Eric Agar (saves us from doing 32767 system
                    635:                         * calls)
                    636:                         */
                    637:                        if (fcntl(0, F_CLOSEM, 0) == -1)
                    638:                            msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
                    639: #else  /* not F_CLOSEM */
                    640: 
                    641: # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
                    642:                        max_fd = sysconf(_SC_OPEN_MAX);
                    643: # else /* HAVE_SYSCONF && _SC_OPEN_MAX */
                    644:                        max_fd = getdtablesize();
                    645: # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
                    646:                        for (s = 0; s < max_fd; s++)
                    647:                                (void) close((int)s);
                    648: #endif /* not F_CLOSEM */
                    649:                        (void) open("/", 0);
                    650:                        (void) dup2(0, 1);
                    651:                        (void) dup2(0, 2);
                    652: 
                    653:                        init_logging(progname, 0);
                    654:                        /* we lost our logfile (if any) daemonizing */
                    655:                        setup_logfile();
                    656: 
                    657: #ifdef SYS_DOMAINOS
                    658:                        {
                    659:                                uid_$t puid;
                    660:                                status_$t st;
                    661: 
                    662:                                proc2_$who_am_i(&puid);
                    663:                                proc2_$make_server(&puid, &st);
                    664:                        }
                    665: #endif /* SYS_DOMAINOS */
                    666: #if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
                    667: # ifdef HAVE_SETSID
                    668:                        if (setsid() == (pid_t)-1)
                    669:                                msyslog(LOG_ERR, "ntpd: setsid(): %m");
                    670: # else
                    671:                        if (setpgid(0, 0) == -1)
                    672:                                msyslog(LOG_ERR, "ntpd: setpgid(): %m");
                    673: # endif
                    674: #else /* HAVE_SETPGID || HAVE_SETSID */
                    675:                        {
                    676: # if defined(TIOCNOTTY)
                    677:                                int fid;
                    678: 
                    679:                                fid = open("/dev/tty", 2);
                    680:                                if (fid >= 0)
                    681:                                {
                    682:                                        (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
                    683:                                        (void) close(fid);
                    684:                                }
                    685: # endif /* defined(TIOCNOTTY) */
                    686: # ifdef HAVE_SETPGRP_0
                    687:                                (void) setpgrp();
                    688: # else /* HAVE_SETPGRP_0 */
                    689:                                (void) setpgrp(0, getpid());
                    690: # endif /* HAVE_SETPGRP_0 */
                    691:                        }
                    692: #endif /* HAVE_SETPGID || HAVE_SETSID */
                    693: #ifdef _AIX
                    694:                        /* Don't get killed by low-on-memory signal. */
                    695:                        sa.sa_handler = catch_danger;
                    696:                        sigemptyset(&sa.sa_mask);
                    697:                        sa.sa_flags = SA_RESTART;
                    698: 
                    699:                        (void) sigaction(SIGDANGER, &sa, NULL);
                    700: #endif /* _AIX */
                    701:                }
                    702: #   endif /* not HAVE_DAEMON */
                    703: #  endif /* SYS_WINNT */
                    704:        }
                    705: # endif /* NODETACH */
                    706: #endif /* VMS */
                    707: 
                    708: #ifdef SCO5_CLOCK
                    709:        /*
                    710:         * SCO OpenServer's system clock offers much more precise timekeeping
                    711:         * on the base CPU than the other CPUs (for multiprocessor systems),
                    712:         * so we must lock to the base CPU.
                    713:         */
                    714:        {
                    715:            int fd = open("/dev/at1", O_RDONLY);
                    716:            if (fd >= 0) {
                    717:                int zero = 0;
                    718:                if (ioctl(fd, ACPU_LOCK, &zero) < 0)
                    719:                    msyslog(LOG_ERR, "cannot lock to base CPU: %m");
                    720:                close( fd );
                    721:            } /* else ...
                    722:               *   If we can't open the device, this probably just isn't
                    723:               *   a multiprocessor system, so we're A-OK.
                    724:               */
                    725:        }
                    726: #endif
                    727: 
                    728: #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
                    729: # ifdef HAVE_SETRLIMIT
                    730:        /*
                    731:         * Set the stack limit to something smaller, so that we don't lock a lot
                    732:         * of unused stack memory.
                    733:         */
                    734:        {
                    735:            struct rlimit rl;
                    736: 
                    737:            /* HMS: must make the rlim_cur amount configurable */
                    738:            if (getrlimit(RLIMIT_STACK, &rl) != -1
                    739:                && (rl.rlim_cur = 50 * 4096) < rl.rlim_max)
                    740:            {
                    741:                    if (setrlimit(RLIMIT_STACK, &rl) == -1)
                    742:                    {
                    743:                            msyslog(LOG_ERR,
                    744:                                "Cannot adjust stack limit for mlockall: %m");
                    745:                    }
                    746:            }
                    747: #  ifdef RLIMIT_MEMLOCK
                    748:            /*
                    749:             * The default RLIMIT_MEMLOCK is very low on Linux systems.
                    750:             * Unless we increase this limit malloc calls are likely to
                    751:             * fail if we drop root privlege.  To be useful the value
                    752:             * has to be larger than the largest ntpd resident set size.
                    753:             */
                    754:            rl.rlim_cur = rl.rlim_max = 32*1024*1024;
                    755:            if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) {
                    756:                msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
                    757:            }
                    758: #  endif /* RLIMIT_MEMLOCK */
                    759:        }
                    760: # endif /* HAVE_SETRLIMIT */
                    761:        /*
                    762:         * lock the process into memory
                    763:         */
                    764:        if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
                    765:                msyslog(LOG_ERR, "mlockall(): %m");
                    766: #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
                    767: # ifdef HAVE_PLOCK
                    768: #  ifdef PROCLOCK
                    769: #   ifdef _AIX
                    770:        /*
                    771:         * set the stack limit for AIX for plock().
                    772:         * see get_aix_stack() for more info.
                    773:         */
                    774:        if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
                    775:        {
                    776:                msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
                    777:        }
                    778: #   endif /* _AIX */
                    779:        /*
                    780:         * lock the process into memory
                    781:         */
                    782:        if (plock(PROCLOCK) < 0)
                    783:                msyslog(LOG_ERR, "plock(PROCLOCK): %m");
                    784: #  else /* not PROCLOCK */
                    785: #   ifdef TXTLOCK
                    786:        /*
                    787:         * Lock text into ram
                    788:         */
                    789:        if (plock(TXTLOCK) < 0)
                    790:                msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
                    791: #   else /* not TXTLOCK */
                    792:        msyslog(LOG_ERR, "plock() - don't know what to lock!");
                    793: #   endif /* not TXTLOCK */
                    794: #  endif /* not PROCLOCK */
                    795: # endif /* HAVE_PLOCK */
                    796: #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
                    797: 
                    798:        /*
                    799:         * Set up signals we pay attention to locally.
                    800:         */
                    801: #ifdef SIGDIE1
                    802:        (void) signal_no_reset(SIGDIE1, finish);
                    803: #endif /* SIGDIE1 */
                    804: #ifdef SIGDIE2
                    805:        (void) signal_no_reset(SIGDIE2, finish);
                    806: #endif /* SIGDIE2 */
                    807: #ifdef SIGDIE3
                    808:        (void) signal_no_reset(SIGDIE3, finish);
                    809: #endif /* SIGDIE3 */
                    810: #ifdef SIGDIE4
                    811:        (void) signal_no_reset(SIGDIE4, finish);
                    812: #endif /* SIGDIE4 */
                    813: 
                    814: #ifdef SIGBUS
                    815:        (void) signal_no_reset(SIGBUS, finish);
                    816: #endif /* SIGBUS */
                    817: 
                    818: #if !defined(SYS_WINNT) && !defined(VMS)
                    819: # ifdef DEBUG
                    820:        (void) signal_no_reset(MOREDEBUGSIG, moredebug);
                    821:        (void) signal_no_reset(LESSDEBUGSIG, lessdebug);
                    822: # else
                    823:        (void) signal_no_reset(MOREDEBUGSIG, no_debug);
                    824:        (void) signal_no_reset(LESSDEBUGSIG, no_debug);
                    825: # endif /* DEBUG */
                    826: #endif /* !SYS_WINNT && !VMS */
                    827: 
                    828:        /*
                    829:         * Set up signals we should never pay attention to.
                    830:         */
                    831: #if defined SIGPIPE
                    832:        (void) signal_no_reset(SIGPIPE, SIG_IGN);
                    833: #endif /* SIGPIPE */
                    834: 
                    835:        /*
                    836:         * Call the init_ routines to initialize the data structures.
                    837:         *
                    838:         * Exactly what command-line options are we expecting here?
                    839:         */
                    840:        init_auth();
                    841:        init_util();
                    842:        init_restrict();
                    843:        init_mon();
                    844:        init_timer();
                    845:        init_lib();
                    846:        init_request();
                    847:        init_control();
                    848:        init_peer();
                    849: #ifdef REFCLOCK
                    850:        init_refclock();
                    851: #endif
                    852:        set_process_priority();
                    853:        init_proto();           /* Call at high priority */
                    854:        init_io();
                    855:        init_loopfilter();
                    856:        mon_start(MON_ON);      /* monitor on by default now      */
                    857:                                /* turn off in config if unwanted */
                    858: 
                    859:        /*
                    860:         * Get the configuration.  This is done in a separate module
                    861:         * since this will definitely be different for the gizmo board.
                    862:         */
                    863:        getconfig(argc, argv);
                    864:        report_event(EVNT_SYSRESTART, NULL, NULL);
                    865:        loop_config(LOOP_DRIFTCOMP, old_drift);
                    866:        initializing = 0;
                    867: 
                    868: #ifdef HAVE_DROPROOT
                    869:        if( droproot ) {
                    870:                /* Drop super-user privileges and chroot now if the OS supports this */
                    871: 
                    872: #ifdef HAVE_LINUX_CAPABILITIES
                    873:                /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
                    874:                if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
                    875:                        msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
                    876:                        exit(-1);
                    877:                }
                    878: #else
                    879:                /* we need a user to switch to */
                    880:                if (user == NULL) {
                    881:                        msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
                    882:                        exit(-1);
                    883:                }
                    884: #endif /* HAVE_LINUX_CAPABILITIES */
                    885: 
                    886:                if (user != NULL) {
                    887:                        if (isdigit((unsigned char)*user)) {
                    888:                                sw_uid = (uid_t)strtoul(user, &endp, 0);
                    889:                                if (*endp != '\0')
                    890:                                        goto getuser;
                    891: 
                    892:                                if ((pw = getpwuid(sw_uid)) != NULL) {
                    893:                                        user = strdup(pw->pw_name);
                    894:                                        if (NULL == user) {
                    895:                                                msyslog(LOG_ERR, "strdup() failed: %m");
                    896:                                                exit (-1);
                    897:                                        }
                    898:                                        sw_gid = pw->pw_gid;
                    899:                                } else {
                    900:                                        errno = 0;
                    901:                                        msyslog(LOG_ERR, "Cannot find user ID %s", user);
                    902:                                        exit (-1);
                    903:                                }
                    904: 
                    905:                        } else {
                    906: getuser:
                    907:                                errno = 0;
                    908:                                if ((pw = getpwnam(user)) != NULL) {
                    909:                                        sw_uid = pw->pw_uid;
                    910:                                        sw_gid = pw->pw_gid;
                    911:                                } else {
                    912:                                        if (errno)
                    913:                                            msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
                    914:                                        else
                    915:                                            msyslog(LOG_ERR, "Cannot find user `%s'", user);
                    916:                                        exit (-1);
                    917:                                }
                    918:                        }
                    919:                }
                    920:                if (group != NULL) {
                    921:                        if (isdigit((unsigned char)*group)) {
                    922:                                sw_gid = (gid_t)strtoul(group, &endp, 0);
                    923:                                if (*endp != '\0')
                    924:                                        goto getgroup;
                    925:                        } else {
                    926: getgroup:
                    927:                                if ((gr = getgrnam(group)) != NULL) {
                    928:                                        sw_gid = gr->gr_gid;
                    929:                                } else {
                    930:                                        errno = 0;
                    931:                                        msyslog(LOG_ERR, "Cannot find group `%s'", group);
                    932:                                        exit (-1);
                    933:                                }
                    934:                        }
                    935:                }
                    936: 
                    937:                if (chrootdir ) {
                    938:                        /* make sure cwd is inside the jail: */
                    939:                        if (chdir(chrootdir)) {
                    940:                                msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
                    941:                                exit (-1);
                    942:                        }
                    943:                        if (chroot(chrootdir)) {
                    944:                                msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
                    945:                                exit (-1);
                    946:                        }
                    947:                        if (chdir("/")) {
                    948:                                msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
                    949:                                exit (-1);
                    950:                        }
                    951:                }
                    952:                if (user && initgroups(user, sw_gid)) {
                    953:                        msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
                    954:                        exit (-1);
                    955:                }
                    956:                if (group && setgid(sw_gid)) {
                    957:                        msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
                    958:                        exit (-1);
                    959:                }
                    960:                if (group && setegid(sw_gid)) {
                    961:                        msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
                    962:                        exit (-1);
                    963:                }
                    964:                if (user && setuid(sw_uid)) {
                    965:                        msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
                    966:                        exit (-1);
                    967:                }
                    968:                if (user && seteuid(sw_uid)) {
                    969:                        msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
                    970:                        exit (-1);
                    971:                }
                    972: 
                    973: #ifndef HAVE_LINUX_CAPABILITIES
                    974:                /*
                    975:                 * for now assume that the privilege to bind to privileged ports
                    976:                 * is associated with running with uid 0 - should be refined on
                    977:                 * ports that allow binding to NTP_PORT with uid != 0
                    978:                 */
                    979:                disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
                    980: #endif
                    981: 
                    982:                if (disable_dynamic_updates && interface_interval) {
                    983:                        interface_interval = 0;
                    984:                        msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking");
                    985:                }
                    986: 
                    987: #ifdef HAVE_LINUX_CAPABILITIES
                    988:                do {
                    989:                        /*
                    990:                         *  We may be running under non-root uid now, but we still hold full root privileges!
                    991:                         *  We drop all of them, except for the crucial one or two: cap_sys_time and
                    992:                         *  cap_net_bind_service if doing dynamic interface tracking.
                    993:                         */
                    994:                        cap_t caps;
                    995:                        char *captext = (interface_interval)
                    996:                                ? "cap_sys_time,cap_net_bind_service=ipe"
                    997:                                : "cap_sys_time=ipe";
                    998:                        if( ! ( caps = cap_from_text( captext ) ) ) {
                    999:                                msyslog( LOG_ERR, "cap_from_text() failed: %m" );
                   1000:                                exit(-1);
                   1001:                        }
                   1002:                        if( cap_set_proc( caps ) == -1 ) {
                   1003:                                msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" );
                   1004:                                exit(-1);
                   1005:                        }
                   1006:                        cap_free( caps );
                   1007:                } while(0);
                   1008: #endif /* HAVE_LINUX_CAPABILITIES */
                   1009: 
                   1010:        }    /* if( droproot ) */
                   1011: #endif /* HAVE_DROPROOT */
                   1012: 
                   1013:        /*
                   1014:         * Use select() on all on all input fd's for unlimited
                   1015:         * time.  select() will terminate on SIGALARM or on the
                   1016:         * reception of input.  Using select() means we can't do
                   1017:         * robust signal handling and we get a potential race
                   1018:         * between checking for alarms and doing the select().
                   1019:         * Mostly harmless, I think.
                   1020:         */
                   1021:        /* On VMS, I suspect that select() can't be interrupted
                   1022:         * by a "signal" either, so I take the easy way out and
                   1023:         * have select() time out after one second.
                   1024:         * System clock updates really aren't time-critical,
                   1025:         * and - lacking a hardware reference clock - I have
                   1026:         * yet to learn about anything else that is.
                   1027:         */
                   1028: #if defined(HAVE_IO_COMPLETION_PORT)
                   1029: 
                   1030:        for (;;) {
                   1031:                GetReceivedBuffers();
                   1032: #else /* normal I/O */
                   1033: 
                   1034:        BLOCK_IO_AND_ALARM();
                   1035:        was_alarmed = 0;
                   1036:        for (;;)
                   1037:        {
                   1038: # if !defined(HAVE_SIGNALED_IO)
                   1039:                extern fd_set activefds;
                   1040:                extern int maxactivefd;
                   1041: 
                   1042:                fd_set rdfdes;
                   1043:                int nfound;
                   1044: # endif
                   1045: 
                   1046:                if (alarm_flag)         /* alarmed? */
                   1047:                {
                   1048:                        was_alarmed = 1;
                   1049:                        alarm_flag = 0;
                   1050:                }
                   1051: 
                   1052:                if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE)
                   1053:                {
                   1054:                        /*
                   1055:                         * Nothing to do.  Wait for something.
                   1056:                         */
                   1057: # ifndef HAVE_SIGNALED_IO
                   1058:                        rdfdes = activefds;
                   1059: #  if defined(VMS) || defined(SYS_VXWORKS)
                   1060:                        /* make select() wake up after one second */
                   1061:                        {
                   1062:                                struct timeval t1;
                   1063: 
                   1064:                                t1.tv_sec = 1; t1.tv_usec = 0;
                   1065:                                nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
                   1066:                                                (fd_set *)0, &t1);
                   1067:                        }
                   1068: #  else
                   1069:                        nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
                   1070:                                        (fd_set *)0, (struct timeval *)0);
                   1071: #  endif /* VMS */
                   1072:                        if (nfound > 0)
                   1073:                        {
                   1074:                                l_fp ts;
                   1075: 
                   1076:                                get_systime(&ts);
                   1077: 
                   1078:                                (void)input_handler(&ts);
                   1079:                        }
                   1080:                        else if (nfound == -1 && errno != EINTR)
                   1081:                                msyslog(LOG_ERR, "select() error: %m");
                   1082: #  ifdef DEBUG
                   1083:                        else if (debug > 5)
                   1084:                                msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
                   1085: #  endif /* DEBUG */
                   1086: # else /* HAVE_SIGNALED_IO */
                   1087: 
                   1088:                        wait_for_signal();
                   1089: # endif /* HAVE_SIGNALED_IO */
                   1090:                        if (alarm_flag)         /* alarmed? */
                   1091:                        {
                   1092:                                was_alarmed = 1;
                   1093:                                alarm_flag = 0;
                   1094:                        }
                   1095:                }
                   1096: 
                   1097:                if (was_alarmed)
                   1098:                {
                   1099:                        UNBLOCK_IO_AND_ALARM();
                   1100:                        /*
                   1101:                         * Out here, signals are unblocked.  Call timer routine
                   1102:                         * to process expiry.
                   1103:                         */
                   1104:                        timer();
                   1105:                        was_alarmed = 0;
                   1106:                        BLOCK_IO_AND_ALARM();
                   1107:                }
                   1108: 
                   1109: #endif /* ! HAVE_IO_COMPLETION_PORT */
                   1110: 
                   1111: #ifdef DEBUG_TIMING
                   1112:                {
                   1113:                        l_fp pts;
                   1114:                        l_fp tsa, tsb;
                   1115:                        int bufcount = 0;
                   1116: 
                   1117:                        get_systime(&pts);
                   1118:                        tsa = pts;
                   1119: #endif
                   1120:                        rbuf = get_full_recv_buffer();
                   1121:                        while (rbuf != NULL)
                   1122:                        {
                   1123:                                if (alarm_flag)
                   1124:                                {
                   1125:                                        was_alarmed = 1;
                   1126:                                        alarm_flag = 0;
                   1127:                                }
                   1128:                                UNBLOCK_IO_AND_ALARM();
                   1129: 
                   1130:                                if (was_alarmed)
                   1131:                                {       /* avoid timer starvation during lengthy I/O handling */
                   1132:                                        timer();
                   1133:                                        was_alarmed = 0;
                   1134:                                }
                   1135: 
                   1136:                                /*
                   1137:                                 * Call the data procedure to handle each received
                   1138:                                 * packet.
                   1139:                                 */
                   1140:                                if (rbuf->receiver != NULL)     /* This should always be true */
                   1141:                                {
                   1142: #ifdef DEBUG_TIMING
                   1143:                                        l_fp dts = pts;
                   1144: 
                   1145:                                        L_SUB(&dts, &rbuf->recv_time);
                   1146:                                        DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
                   1147:                                        collect_timing(rbuf, "buffer processing delay", 1, &dts);
                   1148:                                        bufcount++;
                   1149: #endif
                   1150:                                        (rbuf->receiver)(rbuf);
                   1151:                                } else {
                   1152:                                        msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING");
                   1153:                                        abort();
                   1154:                                }
                   1155: 
                   1156:                                BLOCK_IO_AND_ALARM();
                   1157:                                freerecvbuf(rbuf);
                   1158:                                rbuf = get_full_recv_buffer();
                   1159:                        }
                   1160: #ifdef DEBUG_TIMING
                   1161:                        get_systime(&tsb);
                   1162:                        L_SUB(&tsb, &tsa);
                   1163:                        if (bufcount) {
                   1164:                                collect_timing(NULL, "processing", bufcount, &tsb);
                   1165:                                DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
                   1166:                        }
                   1167:                }
                   1168: #endif
                   1169: 
                   1170:                /*
                   1171:                 * Go around again
                   1172:                 */
                   1173: 
                   1174: #ifdef HAVE_DNSREGISTRATION
                   1175:                if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
                   1176:                        mdnsreg = current_time;
                   1177:                        msyslog(LOG_INFO, "Attempting to register mDNS");
                   1178:                        if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, 
                   1179:                            htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
                   1180:                                if (!--mdnstries) {
                   1181:                                        msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
                   1182:                                } else {        
                   1183:                                        msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
                   1184:                                }
                   1185:                        } else {
                   1186:                                msyslog(LOG_INFO, "mDNS service registered.");
                   1187:                                mdnsreg = 0;
                   1188:                        }
                   1189:                }
                   1190: #endif /* HAVE_DNSREGISTRATION */
                   1191: 
                   1192:        }
                   1193:        UNBLOCK_IO_AND_ALARM();
                   1194:        return 1;
                   1195: }
                   1196: 
                   1197: 
                   1198: #ifdef SIGDIE2
                   1199: /*
                   1200:  * finish - exit gracefully
                   1201:  */
                   1202: static RETSIGTYPE
                   1203: finish(
                   1204:        int sig
                   1205:        )
                   1206: {
                   1207:        msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
                   1208: #ifdef HAVE_DNSREGISTRATION
                   1209:        if (mdns != NULL)
                   1210:                DNSServiceRefDeallocate(mdns);
                   1211: #endif
                   1212:        switch (sig) {
                   1213: # ifdef SIGBUS
                   1214:        case SIGBUS:
                   1215:                printf("\nfinish(SIGBUS)\n");
                   1216:                exit(0);
                   1217: # endif
                   1218:        case 0:                 /* Should never happen... */
                   1219:                return;
                   1220: 
                   1221:        default:
                   1222:                exit(0);
                   1223:        }
                   1224: }
                   1225: #endif /* SIGDIE2 */
                   1226: 
                   1227: 
                   1228: /* assertion_failed
                   1229:  * Redirect trap messages from ISC libraries to syslog.
                   1230:  * This code was cloned and simplified from BIND.
                   1231:  */
                   1232: 
                   1233: /*
                   1234:  * assertion_failed - Handle assertion failures.
                   1235:  */
                   1236: 
                   1237: static void
                   1238: assertion_failed(const char *file, int line, isc_assertiontype_t type,
                   1239:                  const char *cond)
                   1240: {
                   1241:        isc_assertion_setcallback(NULL);    /* Avoid recursion */
                   1242: 
                   1243:        msyslog(LOG_ERR, "%s:%d: %s(%s) failed",
                   1244:                file, line, isc_assertion_typetotext(type), cond);
                   1245:        msyslog(LOG_ERR, "exiting (due to assertion failure)");
                   1246: 
                   1247:        abort();
                   1248: }
                   1249: 
                   1250: /*
                   1251:  * library_fatal_error - Handle fatal errors from our libraries.
                   1252:  */
                   1253: 
                   1254: static void
                   1255: library_fatal_error(const char *file, int line, const char *format,
                   1256:                     va_list args)
                   1257: {
                   1258:        char errbuf[256];
                   1259: 
                   1260:        isc_error_setfatal(NULL);  /* Avoid recursion */
                   1261: 
                   1262:        msyslog(LOG_ERR, "%s:%d: fatal error:", file, line);
                   1263:        vsnprintf(errbuf, sizeof(errbuf), format, args);
                   1264:        msyslog(LOG_ERR, errbuf);
                   1265:        msyslog(LOG_ERR, "exiting (due to fatal error in library)");
                   1266: 
                   1267:        abort();
                   1268: }
                   1269: 
                   1270: /*
                   1271:  * library_unexpected_error - Handle non fatal errors from our libraries.
                   1272:  */
                   1273: #define MAX_UNEXPECTED_ERRORS 100
                   1274: int unexpected_error_cnt = 0;
                   1275: static void
                   1276: library_unexpected_error(const char *file, int line, const char *format,
                   1277:                          va_list args)
                   1278: {
                   1279:        char errbuf[256];
                   1280: 
                   1281:        if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS)
                   1282:                return; /* avoid clutter in log */
                   1283: 
                   1284:        msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line);
                   1285:        vsnprintf(errbuf, sizeof(errbuf), format, args);
                   1286:        msyslog(LOG_ERR, errbuf);
                   1287: 
                   1288:        if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS)
                   1289:        {
                   1290:                msyslog(LOG_ERR, "Too many errors.  Shutting up.");
                   1291:        }
                   1292: 
                   1293: }
                   1294: 
                   1295: 
                   1296: #ifdef DEBUG
                   1297: #ifndef SYS_WINNT
                   1298: /*
                   1299:  * moredebug - increase debugging verbosity
                   1300:  */
                   1301: static RETSIGTYPE
                   1302: moredebug(
                   1303:        int sig
                   1304:        )
                   1305: {
                   1306:        int saved_errno = errno;
                   1307: 
                   1308:        if (debug < 255)
                   1309:        {
                   1310:                debug++;
                   1311:                msyslog(LOG_DEBUG, "debug raised to %d", debug);
                   1312:        }
                   1313:        errno = saved_errno;
                   1314: }
                   1315: 
                   1316: /*
                   1317:  * lessdebug - decrease debugging verbosity
                   1318:  */
                   1319: static RETSIGTYPE
                   1320: lessdebug(
                   1321:        int sig
                   1322:        )
                   1323: {
                   1324:        int saved_errno = errno;
                   1325: 
                   1326:        if (debug > 0)
                   1327:        {
                   1328:                debug--;
                   1329:                msyslog(LOG_DEBUG, "debug lowered to %d", debug);
                   1330:        }
                   1331:        errno = saved_errno;
                   1332: }
                   1333: #endif
                   1334: #else /* not DEBUG */
                   1335: #ifndef SYS_WINNT
                   1336: /*
                   1337:  * no_debug - We don't do the debug here.
                   1338:  */
                   1339: static RETSIGTYPE
                   1340: no_debug(
                   1341:        int sig
                   1342:        )
                   1343: {
                   1344:        int saved_errno = errno;
                   1345: 
                   1346:        msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
                   1347:        errno = saved_errno;
                   1348: }
                   1349: #endif  /* not SYS_WINNT */
                   1350: #endif /* not DEBUG */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>