]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ntp/libntp/prettydate.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ntp / libntp / prettydate.c
1 /*
2  * prettydate - convert a time stamp to something readable
3  */
4 #include <stdio.h>
5
6 #include "ntp_fp.h"
7 #include "ntp_unixtime.h"       /* includes <sys/time.h> */
8 #include "lib_strbuf.h"
9 #include "ntp_stdlib.h"
10
11 static const char *months[] = {
12   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
13   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
14 };
15
16 static const char *days[] = {
17   "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
18 };
19
20 /* Helper function to handle possible wraparound of the ntp epoch.
21
22    Works by assuming that the localtime/gmtime library functions 
23    have been updated so that they work
24 */
25
26 #define MAX_EPOCH_NR 1000
27
28 struct tm *
29 ntp2unix_tm(
30         u_long ntp, int local
31         )
32 {
33         time_t t, curr;
34         struct tm *tm;
35         int curr_year, epoch_nr;
36
37         /* First get the current year: */
38         curr = time(NULL);
39         tm = local ? localtime(&curr) : gmtime(&curr);
40         if (!tm) return NULL;
41
42         curr_year = 1900 + tm->tm_year;
43
44         /* Convert the ntp timestamp to a unix utc seconds count: */
45         t = (time_t) ntp - JAN_1970;
46
47         /* Check that the ntp timestamp is not before a 136 year window centered
48            around the current year:
49
50            Failsafe in case of an infinite loop:
51        Allow up to 1000 epochs of 136 years each!
52         */
53     for (epoch_nr = 0; epoch_nr < MAX_EPOCH_NR; epoch_nr++) {
54                 tm = local ? localtime(&t) : gmtime(&t);
55
56 #if SIZEOF_TIME_T < 4
57 # include "Bletch: sizeof(time_t) < 4!"
58 #endif
59
60 #if SIZEOF_TIME_T == 4
61                 /* If 32 bits, then year is 1970-2038, so no sense looking */
62                 epoch_nr = MAX_EPOCH_NR;
63 #else   /* SIZEOF_TIME_T > 4 */
64                 /* Check that the resulting year is in the correct epoch: */
65                 if (1900 + tm->tm_year > curr_year - 68) break;
66
67                 /* Epoch wraparound: Add 2^32 seconds! */
68                 t += (time_t) 65536 << 16;
69 #endif /* SIZEOF_TIME_T > 4 */
70         }
71         return tm;
72 }
73
74 char *
75 prettydate(
76         l_fp *ts
77         )
78 {
79         char *bp;
80         struct tm *tm;
81         time_t sec;
82         u_long msec;
83
84         LIB_GETBUF(bp);
85         
86         sec = ts->l_ui;
87         msec = ts->l_uf / 4294967;      /* fract / (2 ** 32 / 1000) */
88
89         tm = ntp2unix_tm(sec, 1);
90         if (!tm) {
91                 (void) sprintf(bp, "%08lx.%08lx  --- --- -- ---- --:--:--",
92                        (u_long)ts->l_ui, (u_long)ts->l_uf);
93         }
94         else {
95                 (void) sprintf(bp, "%08lx.%08lx  %s, %s %2d %4d %2d:%02d:%02d.%03lu",
96                        (u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday],
97                        months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year,
98                        tm->tm_hour,tm->tm_min, tm->tm_sec, msec);
99         }
100         
101         return bp;
102 }
103
104 char *
105 gmprettydate(
106         l_fp *ts
107         )
108 {
109         char *bp;
110         struct tm *tm;
111         time_t sec;
112         u_long msec;
113
114         LIB_GETBUF(bp);
115         
116         sec = ts->l_ui;
117         msec = ts->l_uf / 4294967;      /* fract / (2 ** 32 / 1000) */
118
119         tm = ntp2unix_tm(sec, 0);
120         if (!tm) {
121                 (void) sprintf(bp, "%08lx.%08lx  --- --- -- ---- --:--:--",
122                        (u_long)ts->l_ui, (u_long)ts->l_uf);
123         }
124         else {
125                 (void) sprintf(bp, "%08lx.%08lx  %s, %s %2d %4d %2d:%02d:%02d.%03lu",
126                        (u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday],
127                        months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year,
128                        tm->tm_hour,tm->tm_min, tm->tm_sec, msec);
129         }
130
131         return bp;
132 }