Annotation of embedaddon/ntp/libntp/clocktime.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * clocktime - compute the NTP date from a day of year, hour, minute
        !             3:  *            and second.
        !             4:  */
        !             5: #include "ntp_fp.h"
        !             6: #include "ntp_unixtime.h"
        !             7: #include "ntp_stdlib.h"
        !             8: 
        !             9: /*
        !            10:  * Hacks to avoid excercising the multiplier.  I have no pride.
        !            11:  */
        !            12: #define        MULBY10(x)      (((x)<<3) + ((x)<<1))
        !            13: #define        MULBY60(x)      (((x)<<6) - ((x)<<2))   /* watch overflow */
        !            14: #define        MULBY24(x)      (((x)<<4) + ((x)<<3))
        !            15: 
        !            16: /*
        !            17:  * Two days, in seconds.
        !            18:  */
        !            19: #define        TWODAYS         (2*24*60*60)
        !            20: 
        !            21: /*
        !            22:  * We demand that the time be within CLOSETIME seconds of the receive
        !            23:  * time stamp.  This is about 4 hours, which hopefully should be
        !            24:  * wide enough to collect most data, while close enough to keep things
        !            25:  * from getting confused.
        !            26:  */
        !            27: #define        CLOSETIME       (4*60*60)
        !            28: 
        !            29: 
        !            30: int
        !            31: clocktime(
        !            32:        int yday,
        !            33:        int hour,
        !            34:        int minute,
        !            35:        int second,
        !            36:        int tzoff,
        !            37:        u_long rec_ui,
        !            38:        u_long *yearstart,
        !            39:        u_int32 *ts_ui
        !            40:        )
        !            41: {
        !            42:        register long tmp;
        !            43:        register u_long date;
        !            44:        register u_long yst;
        !            45: 
        !            46:        /*
        !            47:         * Compute the offset into the year in seconds.  Note that
        !            48:         * this could come out to be a negative number.
        !            49:         */
        !            50:        tmp = (long)(MULBY24((yday-1)) + hour + tzoff);
        !            51:        tmp = MULBY60(tmp) + (long)minute;
        !            52:        tmp = MULBY60(tmp) + (long)second;
        !            53: 
        !            54:        /*
        !            55:         * Initialize yearstart, if necessary.
        !            56:         */
        !            57:        yst = *yearstart;
        !            58:        if (yst == 0) {
        !            59:                yst = calyearstart(rec_ui);
        !            60:                *yearstart = yst;
        !            61:        }
        !            62: 
        !            63:        /*
        !            64:         * Now the fun begins.  We demand that the received clock time
        !            65:         * be within CLOSETIME of the receive timestamp, but
        !            66:         * there is uncertainty about the year the timestamp is in.
        !            67:         * Use the current year start for the first check, this should
        !            68:         * work most of the time.
        !            69:         */
        !            70:        date = (u_long)(tmp + (long)yst);
        !            71:        if (date < (rec_ui + CLOSETIME) &&
        !            72:            date > (rec_ui - CLOSETIME)) {
        !            73:                *ts_ui = date;
        !            74:                return 1;
        !            75:        }
        !            76: 
        !            77:        /*
        !            78:         * Trouble.  Next check is to see if the year rolled over and, if
        !            79:         * so, try again with the new year's start.
        !            80:         */
        !            81:        yst = calyearstart(rec_ui);
        !            82:        if (yst != *yearstart) {
        !            83:                date = (u_long)((long)yst + tmp);
        !            84:                *ts_ui = date;
        !            85:                if (date < (rec_ui + CLOSETIME) &&
        !            86:                    date > (rec_ui - CLOSETIME)) {
        !            87:                        *yearstart = yst;
        !            88:                        return 1;
        !            89:                }
        !            90:        }
        !            91: 
        !            92:        /*
        !            93:         * Here we know the year start matches the current system
        !            94:         * time.  One remaining possibility is that the time code
        !            95:         * is in the year previous to that of the system time.  This
        !            96:         * is only worth checking if the receive timestamp is less
        !            97:         * than a couple of days into the new year.
        !            98:         */
        !            99:        if ((rec_ui - yst) < TWODAYS) {
        !           100:                yst = calyearstart(yst - TWODAYS);
        !           101:                if (yst != *yearstart) {
        !           102:                        date = (u_long)(tmp + (long)yst);
        !           103:                        if (date < (rec_ui + CLOSETIME) &&
        !           104:                            date > (rec_ui - CLOSETIME)) {
        !           105:                                *yearstart = yst;
        !           106:                                *ts_ui = date;
        !           107:                                return 1;
        !           108:                        }
        !           109:                }
        !           110:        }
        !           111: 
        !           112:        /*
        !           113:         * One last possibility is that the time stamp is in the year
        !           114:         * following the year the system is in.  Try this one before
        !           115:         * giving up.
        !           116:         */
        !           117:        yst = calyearstart(rec_ui + TWODAYS);
        !           118:        if (yst != *yearstart) {
        !           119:                date = (u_long)((long)yst + tmp);
        !           120:                if (date < (rec_ui + CLOSETIME) &&
        !           121:                    date > (rec_ui - CLOSETIME)) {
        !           122:                        *yearstart = yst;
        !           123:                        *ts_ui = date;
        !           124:                        return 1;
        !           125:                }
        !           126:        }
        !           127: 
        !           128:        /*
        !           129:         * Give it up.
        !           130:         */
        !           131:        return 0;
        !           132: }

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