⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 160

📁 Unix/Linux 网络时间协议版本3 Network Time Protocol Version 3 (NTP) distribution for Unix systems
💻
📖 第 1 页 / 共 5 页
字号:
        /* WE HAVE NOW COLLECTED ONE TIMESTAMP (phew)... */#ifdef ARCRON_DEBUG        if(debug > 1) { printf("arc: NOW HAVE TIMESTAMP...\n"); }#endif        /* But check that we actually captured a system timestamp on it. */        if(L_ISZERO(&(up->lastrec))) {#ifdef ARCRON_DEBUG            if(debug) { printf("arc: FAILED TO GET SYSTEM TIMESTAMP\n"); }#endif            pp->lencode = 0;            refclock_report(peer, CEVNT_BADREPLY);            return;        }        /*        Append a mark of the clock's received signal quality for the        benefit of Derek Mulcahy's Tcl/Tk utility (we map the `unknown'        quality value to `6' for his s/w) and terminate the string for        sure.  This should not go off the buffer end.        */        pp->lastcode[pp->lencode] = ((up->quality == QUALITY_UNKNOWN) ?                                                '6' : ('0' + up->quality));        pp->lastcode[pp->lencode + 1] = '\0'; /* Terminate for printf(). */        record_clock_stats(&peer->srcadr, pp->lastcode);        /* We don't use the micro-/milli- second part... */        pp->usec = 0;        pp->msec = 0;        n = sscanf(pp->lastcode, "o%2d%2d%2d%1d%2d%2d%2d%1d%1d",            &pp->hour, &pp->minute, &pp->second,            &wday, &pp->day, &month, &pp->year, &bst, &status);        /* Validate format and numbers. */        if(n != 9) {#ifdef ARCRON_DEBUG            /* Would expect to have caught major problems already... */            if(debug) { printf("arc: badly formatted data.\n"); }#endif            refclock_report(peer, CEVNT_BADREPLY);            return;        }        /*        Validate received values at least enough to prevent internal        array-bounds problems, etc.        */        if((pp->hour < 0) || (pp->hour > 23) ||           (pp->minute < 0) || (pp->minute > 59) ||           (pp->second < 0) || (pp->second > 60) /*Allow for leap seconds.*/ ||           (wday < 1) || (wday > 7) ||           (pp->day < 1) || (pp->day > 31) ||           (month < 1) || (month > 12) ||           (pp->year < 0) || (pp->year > 99)) {            /* Data out of range. */            refclock_report(peer, CEVNT_BADREPLY);            return;        }        /* Check that BST/UTC bits are the complement of one another. */        if(!(bst & 2) == !(bst & 4)) {            refclock_report(peer, CEVNT_BADREPLY);            return;        }        if(status & 0x8) { syslog(LOG_NOTICE, "ARCRON: battery low"); }        /* Year-2000 alert! */        /* Attempt to wrap 2-digit date into sensible window. */        /* This code was written in 1997, so that is the window start. */        if(pp->year < 97) { pp->year += 2000; }        else /* if(pp->year < 100) */ { pp->year += 1900; }        /*        Attempt to do the right thing by screaming that the code will        soon break when we get to the end of its useful life.  What a        hero I am...  PLEASE FIX LEAP-YEAR AND WRAP CODE IN 209X!        */        if(pp->year >= 2090) {          /* This should get attention B^> */            syslog(LOG_NOTICE,"ARCRON: fix me!  EITHER YOUR DATE IS BADLY WRONG or else I will break soon!");        }#ifdef DEBUG        if(debug) {            printf("arc: n=%d %02d:%02d:%02d %02d/%02d/%04d %1d %1d\n",                n,                pp->hour, pp->minute, pp->second,                pp->day, month, pp->year, bst, status);        }#endif        /*        The status value tested for is not strictly supported by the        clock spec since the value of bit 2 (0x4) is claimed to be        undefined for MSF, yet does seem to indicate if the last resync        was successful or not.        */        pp->leap = LEAP_NOWARNING;        status &= 0x7;        if(status == 0x3) {            pp->lasttime = current_time;            if(status != up->status)                { syslog(LOG_NOTICE, "ARCRON: signal acquired"); }        } else {            if(status != up->status) {                syslog(LOG_NOTICE, "ARCRON: signal lost");                pp->leap = LEAP_NOTINSYNC; /* MSF clock is free-running. */                up->status = status;                refclock_report(peer, CEVNT_FAULT);                return;            }        }        up->status = status;        pp->day += moff[month - 1];        /* Good 'til 1st March 2100 */        if(((pp->year % 4) == 0) && month > 2) { pp->day++; }        /* Convert to UTC if required */        if(bst & 2) {            pp->hour--;            if (pp->hour < 0) {                pp->hour = 23;                pp->day--;                /* If we try to wrap round the year (BST on 1st Jan), reject.*/                if(pp->day < 0) {                    refclock_report(peer, CEVNT_BADTIME);                    return;                }            }        }        /* If clock signal quality is unknown, revert to default PRECISION...*/        if(up->quality == QUALITY_UNKNOWN) { peer->precision = PRECISION; }        /* ...else improve precision if flag3 is set... */        else {            peer->precision = ((pp->sloppyclockflag & CLK_FLAG3) ?                        HIGHPRECISION : PRECISION);        }        /* Notice and log any change (eg from initial defaults) for flags. */        if(up->saved_flags != pp->sloppyclockflag) {#ifdef ARCRON_DEBUG            syslog(LOG_NOTICE, "ARCRON: flags enabled: %s%s%s%s",                    ((pp->sloppyclockflag & CLK_FLAG1) ? "1" : "."),                    ((pp->sloppyclockflag & CLK_FLAG2) ? "2" : "."),                    ((pp->sloppyclockflag & CLK_FLAG3) ? "3" : "."),                    ((pp->sloppyclockflag & CLK_FLAG4) ? "4" : "."));            /* Note effects of flags changing... */            if(debug) {                printf("arc: CHOSENSAMPLES(pp) = %d.\n", CHOSENSAMPLES(pp));                printf("arc: NKEEP(pp) = %d.\n", NKEEP(pp));                printf("arc: PRECISION = %d.\n", peer->precision);            }#endif            up->saved_flags = pp->sloppyclockflag;        }        /* Note time of last believable timestamp. */        pp->lastrec = up->lastrec;#ifdef ARCRON_LEAPSECOND_KEEN        /* Find out if a leap-second might just have happened...           (ie is this the first hour of the first day of Jan or Jul?)         */        if((pp->hour == 0) &&           (pp->day == 1) &&           ((month == 1) || (month == 7))) {            if(possible_leap >= 0) {                /* A leap may have happened, and no resync has started yet...*/                possible_leap = 1;                }        } else {            /* Definitely not leap-second territory... */            possible_leap = 0;        }#endif        /*         * Process the new sample in the median filter and determine the         * reference clock offset and dispersion. We use lastrec as both         * the reference time and receive time in order to avoid being         * cute, like setting the reference time later than the receive         * time, which may cause a paranoid protocol module to chuck out         * the data.         */#ifdef ARCRON_OWN_FILTER        if(!arc_refclock_process(pp, CHOSENSAMPLES(pp), NKEEP(pp)))#else        if(!refclock_process(pp, CHOSENSAMPLES(pp), NKEEP(pp)))#endif            {            refclock_report(peer, CEVNT_BADTIME);            if(debug) { printf("arc: sample rejected.\n"); }            return;            }        trtmp = pp->lastrec;        refclock_receive(peer, &pp->offset, 0, pp->dispersion,            &trtmp, &pp->lastrec, pp->leap);}/* request_time() sends a time request to the clock with given peer. *//* This automatically reports a fault if necessary. *//* No data should be sent after this until arc_poll() returns. */static  void    request_time    P((int, struct peer *));static voidrequest_time(unit, peer)        int unit;        struct peer *peer;{        struct refclockproc *pp = peer->procptr;        register struct arcunit *up = (struct arcunit *)pp->unitptr;#ifdef DEBUG        if(debug) { printf("arc: unit %d: requesting time.\n", unit); }#endif        if (!send_slow(up, pp->io.fd, "o\r")) {#ifdef ARCRON_DEBUG            syslog(LOG_NOTICE, "ARCRON: unit %d: problem sending", unit);#endif            refclock_report(peer, CEVNT_FAULT);            return;        }        pp->polls++;}/* * arc_poll - called by the transmit procedure */static voidarc_poll(unit, peer)        int unit;        struct peer *peer;{        register struct arcunit *up;        struct refclockproc *pp;        int resync_needed;              /* Should we start a resync? */        pp = peer->procptr;        up = (struct arcunit *)pp->unitptr;        pp->lencode = 0;        memset(pp->lastcode, 0, sizeof(pp->lastcode));#if 0        /* Flush input. */        tcflush(pp->io.fd, TCIFLUSH);#endif        /* Resync if our next scheduled resync time is here or has passed. */        resync_needed = (up->next_resync <= current_time);#ifdef ARCRON_LEAPSECOND_KEEN        /*         Try to catch a potential leap-second insertion or deletion quickly.         In addition to the normal NTP fun of clocks that don't report         leap-seconds spooking their hosts, this clock does not even         sample the radio sugnal the whole time, so may miss a         leap-second insertion or deletion for up to a whole sample         time.         To try to minimise this effect, if in the first few minutes of         the day immediately following a leap-second-insertion point         (ie in the first hour of the first day of the first and sixth         months), and if the last resync was in the previous day, and a         resync is not already in progress, resync the clock         immediately.         */        if((possible_leap > 0) &&       /* Must be 00:XX 01/0{1,7}/XXXX. */           (!up->resyncing)) {          /* No resync in progress yet. */           resync_needed = 1;           possible_leap = -1;          /* Prevent multiple resyncs. */           syslog(LOG_NOTICE,"ARCRON: unit %d: checking for leap second",unit);           }#endif        /* Do a resync if required... */        if(resync_needed) {            /* First, reset quality value to `unknown' so we can detect */            /* when a quality message has been responded to by this     */            /* being set to some other value.                           */            up->quality = QUALITY_UNKNOWN;            /* Note that we are resyncing... */            up->resyncing = 1;            /* Now actually send the resync command and an immediate poll. */#ifdef DEBUG            if(debug) { printf("arc: sending resync command (h\\r).\n"); }#endif            syslog(LOG_NOTICE, "ARCRON: unit %d: sending resync command", unit);            send_slow(up, pp->io.fd, "h\r");            /* Schedule our next resync... */            up->next_resync = current_time + DEFAULT_RESYNC_TIME;            /* Drop through to request time if appropriate. */        }        /* If clock quality is too poor to trust, indicate a fault. */        /* If quality is QUALITY_UNKNOWN and ARCRON_KEEN is defined,*/        /* we'll cross our fingers and just hope that the thing     */        /* synced so quickly we did not catch it---we'll            */        /* double-check the clock is OK elsewhere.                  */        if(#ifdef ARCRON_KEEN           (up->quality != QUALITY_UNKNOWN) &&#else           (up->quality == QUALITY_UNKNOWN) ||#endif           (up->quality < MIN_CLOCK_QUALITY_OK)) {#ifdef DEBUG            if(debug) {                printf("arc: clock quality %d too poor.\n", up->quality);            }#endif            refclock_report(peer, CEVNT_FAULT);            return;        }        /* This is the normal case: request a timestamp. */        request_time(unit, peer);}#ifdef ARCRON_OWN_FILTER/* Very small fixes to the 3-5.90 ntp_refclock.c code. */#include "ntp_unixtime.h" /* For TVUTOTSF, etc. */#define REFCLOCKMAXDISPERSE (FP_SECOND/4) /* max sample dispersion *//* * Compare two l_fp's - used with qsort() */static intarc_refclock_cmpl_fp(p1, p2)        register const void *p1, *p2;   /* l_fp to compare */{        if (!L_ISGEQ((l_fp *)p1, (l_fp *)p2))                return (-1);        if (L_ISEQU((l_fp *)p1, (l_fp *)p2))                return (0);        return (1);}/* * refclock_process - process a pile of samples from the clock * * This routine converts the timecode in the form days, hours, minutes, * seconds, milliseconds/microseconds to internal timestamp format. * Further processing is then delegated to refclock sample */static intarc_refclock_process(pp, nstart, nskeep)        struct refclockproc *pp; /* peer structure pointer */        int nstart;             /* stages of median filter */        int nskeep;             /* stages after outlyer trim */{        l_fp offset;        /*         * Compute the timecode timestamp from the days, hours, minutes,         * seconds and milliseconds/microseconds of the timecode. Use         * clocktime() for the aggregate seconds and the msec/usec for         * the fraction, when present. Note that this code relies on the         * filesystem time for the years and does not use the years of         * the timecode.         */        if (!clocktime(pp->day, pp->hour, pp->minute, pp->second, GMT,            pp->lastrec.l_ui, &pp->yearstart, &offset.l_ui))                return (0);        if (pp->usec) {                TVUTOTSF(pp->usec, offset.l_uf);        } else {                MSUTOTSF(pp->msec, offset.l_uf);        }        L_ADD(&offset,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -