NOV
};
+#if 0
void
caljulian(
u_long ntptime,
jt->monthday = (u_char) monthday;
}
}
+#else
+
+/* Updated 2003-12-30 TMa
+
+ Uses common code with the *prettydate functions to convert an ntp
+ seconds count into a calendar date.
+ Will handle ntp epoch wraparound as long as the underlying os/library
+ does so for the unix epoch, i.e. works after 2038.
+*/
+
+struct tm * ntp2unix_tm(u_long ntp, int local);
+
+void
+caljulian(
+ u_long ntptime,
+ register struct calendar *jt
+ )
+{
+ struct tm *tm;
+
+ tm = ntp2unix_tm(ntptime, 0);
+
+ jt->hour = (u_char) tm->tm_hour;
+ jt->minute = (u_char) tm->tm_min;
+ jt->month = (u_char) (tm->tm_mon + 1);
+ jt->monthday = (u_char) tm->tm_mday;
+ jt->second = (u_char) tm->tm_sec;
+ jt->year = (u_short) (tm->tm_year + 1900);
+ jt->yearday = (u_short) (tm->tm_yday + 1); /* Assumes tm_yday starts with day 0! */
+}
+#endif
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
+struct tm * ntp2unix_tm(u_long ntp, int local);
+
char *
humandate(
u_long ntptime
{
char *bp;
struct tm *tm;
- time_t sec;
- sec = ntptime - JAN_1970;
- tm = localtime(&sec);
+ tm = ntp2unix_tm(ntptime, 1);
if (!tm)
return "--- --- -- ---- --:--:--";
{
char *bp;
time_t cursec = time((time_t *) 0);
- struct tm *tm = localtime(&cursec);
+ struct tm *tm;
+ tm = localtime(&cursec);
if (!tm)
return "-- --- --:--:--";
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
+/* Helper function to handle possible wraparound of the ntp epoch.
+
+ Works by assuming that the localtime/gmtime library functions
+ have been updated so that they work
+*/
+
+#define MAX_EPOCH_NR 1000
+
+struct tm *
+ntp2unix_tm(
+ u_long ntp, int local
+ )
+{
+ time_t t, curr;
+ struct tm *tm;
+ int curr_year, epoch_nr;
+
+ /* First get the current year: */
+ curr = time(NULL);
+ tm = local ? localtime(&curr) : gmtime(&curr);
+ if (!tm) return NULL;
+
+ curr_year = 1900 + tm->tm_year;
+
+ /* Convert the ntp timestamp to a unix utc seconds count: */
+ t = (time_t) ntp - JAN_1970;
+
+ /* Check that the ntp timestamp is not before a 136 year window centered
+ around the current year:
+
+ Failsafe in case of an infinite loop:
+ Allow up to 1000 epochs of 136 years each!
+ */
+ for (epoch_nr = 0; epoch_nr < MAX_EPOCH_NR; epoch_nr++) {
+ tm = local ? localtime(&t) : gmtime(&t);
+
+ /* Check that the resulting year is in the correct epoch: */
+ if (1900 + tm->tm_year > curr_year - 68) break;
+
+ /* Epoch wraparound: Add 2^32 seconds! */
+ t += (time_t) 65536 << 16;
+ }
+ return tm;
+}
+
char *
prettydate(
l_fp *ts
LIB_GETBUF(bp);
- sec = ts->l_ui - JAN_1970;
+ sec = ts->l_ui;
msec = ts->l_uf / 4294967; /* fract / (2 ** 32 / 1000) */
- tm = localtime(&sec);
-
- (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu",
+ tm = ntp2unix_tm(sec, 1);
+ if (!tm) {
+ (void) sprintf(bp, "%08lx.%08lx --- --- -- ---- --:--:--",
+ (u_long)ts->l_ui, (u_long)ts->l_uf);
+ }
+ else {
+ (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu",
(u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday],
months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year,
tm->tm_hour,tm->tm_min, tm->tm_sec, msec);
+ }
return bp;
}
LIB_GETBUF(bp);
- sec = ts->l_ui - JAN_1970;
+ sec = ts->l_ui;
msec = ts->l_uf / 4294967; /* fract / (2 ** 32 / 1000) */
- tm = gmtime(&sec);
-
- (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu UTC",
+ tm = ntp2unix_tm(sec, 0);
+ if (!tm) {
+ (void) sprintf(bp, "%08lx.%08lx --- --- -- ---- --:--:--",
+ (u_long)ts->l_ui, (u_long)ts->l_uf);
+ }
+ else {
+ (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu",
(u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday],
months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year,
tm->tm_hour,tm->tm_min, tm->tm_sec, msec);
-
+ }
+
return bp;
}