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

📄 144

📁 Unix/Linux 网络时间协议版本3 Network Time Protocol Version 3 (NTP) distribution for Unix systems
💻
📖 第 1 页 / 共 5 页
字号:
            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!");        }        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);        }        /*        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. */                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) {            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" : "."));            up->saved_flags = pp->sloppyclockflag;            /* 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);            }        }        /* Note time of last believable timestamp. */        pp->lastrec = up->lastrec;        /*         * 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); 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;        if(debug) { printf("arc: unit %d: requesting time.\n", unit); }        if (!send_slow(up, pp->io.fd, "o\r")) {            syslog(LOG_NOTICE, "ARCRON: unit %d: problem sending", unit);            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;        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. */        if(up->next_resync <= current_time) {            /* 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. */            if(debug) { printf("arc: sending resync command (h\\r).\n"); }            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)) {            if(debug) {                printf("arc: clock quality %d too poor.\n", up->quality);            }            refclock_report(peer, CEVNT_FAULT);            return;        }        if(debug) { printf("arc: *** poll: pollcnt=%d\n", up->pollcnt); }        if(up->pollcnt == 0) {                refclock_report(peer, CEVNT_TIMEOUT);                return;        }        up->pollcnt--;        /* 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, &pp->fudgetime1);        pp->lastref = offset;   /* save last reference time */        /*         * Include the configured fudgetime1 adjustment.         */        L_SUB(&offset, &pp->lastrec); /* form true offset */        if(debug > 1) { /* DHD addition. */            printf("arc: raw offset %sms.\n",                mfptoms(offset.l_i, offset.l_f, 2));        }        return arc_refclock_sample(&offset, pp, nstart, nskeep);}/* * refclock_sample - process a pile of samples from the clock * * This routine converts the timecode in the form days, hours, miinutes, * seconds, milliseconds/microseconds to internal timestamp format. It * then calculates the difference from the receive timestamp and * assembles the samples in a shift register. It implements a recursive * median filter to suppress spikes in the data, as well as determine a * rough dispersion estimate. A configuration constant time adjustment * fudgetime1 can be added to the final offset to compensate for various * systematic errors. The routine returns one if success and zero if * failure due to invalid timecode data or very noisy offsets. * * This interface is needed to allow for clocks (e. g. parse) that can * provide the correct offset including year information (though NTP * usually gives up on offsets greater than 1000 seconds). */static intarc_refclock_sample(sample_offset, pp, nstart, nskeep)        l_fp *sample_offset;    /* input offset (offset! - not a time stamp)                                   for filter machine */        struct refclockproc *pp; /* peer structure pointer */        int nstart;             /* stages of median filter */        int nskeep;             /* stages after outlyer trim */{        int i, n;        l_fp offset, median, lftmp;        l_fp off[MAXSTAGE];        u_fp disp;        /*         * Subtract the receive timestamp from the timecode timestamp         * to form the raw offset. Insert in the median filter shift         * register.         */        pp->nstages = nstart;        offset = *sample_offset;        i = ((int)(pp->coderecv)) % pp->nstages;        pp->filter[i] = offset;        if (pp->coderecv == 0)                for (i = 1; (u_int) i < pp->nstages; i++)

⌨️ 快捷键说明

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