Annotation of embedaddon/ntp/libntp/clocktime.c, revision 1.1.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>