66//
77// ===----------------------------------------------------------------------===//
88
9+ #include < fcntl.h>
10+ #include < unistd.h>
11+ #include < stdio.h> // TODO: Remove all printf functions
12+ #include < sys/types.h>
13+
914#include " src/time/time_utils.h"
1015#include " src/__support/common.h"
1116#include " src/time/timezone.h"
@@ -15,8 +20,106 @@ namespace timezone {
1520
1621using LIBC_NAMESPACE::time_utils::TimeConstants;
1722
23+ void rev_str (char *str) {
24+ int start = 0 ;
25+ int end = 0 ;
26+
27+ while (str[end] != ' \0 ' ) {
28+ end++;
29+ }
30+ end--;
31+
32+ while (start < end) {
33+ str[start] = str[start] ^ str[end];
34+ str[end] = str[start] ^ str[end];
35+ str[start] = str[start] ^ str[end];
36+
37+ start++;
38+ end--;
39+ }
40+ }
41+
1842int get_timezone_offset (char *timezone) {
1943 (void )timezone;
44+
45+ unsigned char hdr[TIMEZONE_HDR_SIZE];
46+
47+ int32_t magic;
48+ unsigned char version;
49+ __int128_t reserved;
50+ int32_t tzh_ttisutcnt;
51+ int32_t tzh_ttisstdcnt;
52+ int32_t tzh_leapcnt;
53+ int32_t tzh_timecnt;
54+ int32_t tzh_typecnt;
55+ int32_t tzh_charcnt;
56+
57+ int fd;
58+ size_t bytes;
59+
60+ fd = open (" /etc/localtime" , O_RDONLY);
61+ if (fd < 0 ) {
62+ return 0 ;
63+ }
64+
65+ bytes = read (fd, hdr, sizeof (hdr));
66+ if (bytes != sizeof (hdr)) {
67+ return 0 ;
68+ }
69+
70+ size_t i;
71+ __uint128_t tmp;
72+
73+ // these locations in timezone files are defined in `tzfile`
74+ magic = (hdr[0 ] << 24 ) | (hdr[1 ] << 16 ) | (hdr[2 ] << 8 ) | hdr[3 ];
75+ version = hdr[4 ];
76+ for (i = 5 ; i <= 20 ; i++) {
77+ tmp = (tmp << 8 ) | hdr[i];
78+ }
79+ reserved = tmp;
80+ tzh_ttisutcnt = (hdr[20 ] << 24 ) | (hdr[21 ] << 16 ) | (hdr[22 ] << 8 ) | hdr[23 ];
81+ tzh_ttisstdcnt = (hdr[24 ] << 24 ) | (hdr[25 ] << 16 ) | (hdr[26 ] << 8 ) | hdr[27 ];
82+ tzh_leapcnt = (hdr[28 ] << 24 ) | (hdr[29 ] << 16 ) | (hdr[30 ] << 8 ) | hdr[31 ];
83+ tzh_timecnt = (hdr[32 ] << 24 ) | (hdr[33 ] << 16 ) | (hdr[34 ] << 8 ) | hdr[35 ];
84+ tzh_typecnt = (hdr[36 ] << 24 ) | (hdr[37 ] << 16 ) | (hdr[38 ] << 8 ) | hdr[39 ];
85+ tzh_charcnt = (hdr[40 ] << 24 ) | (hdr[41 ] << 16 ) | (hdr[42 ] << 8 ) | hdr[43 ];
86+ (void )tzh_ttisutcnt;
87+ (void )tzh_ttisstdcnt;
88+ (void )tzh_leapcnt;
89+ (void )tzh_typecnt;
90+ (void )tzh_charcnt;
91+
92+ if (magic != 0x545A6966 ) {
93+ return 0 ;
94+ }
95+
96+ // currently only supporting tzfile v2
97+ if (version != 0x32 ) {
98+ return 0 ;
99+ }
100+
101+ // according to `tzfile`, 15 bytes should be 0
102+ if ((reserved ^ 0x00 ) != 0 ) {
103+ return 0 ;
104+ }
105+
106+ for (i = 0 ; i < (size_t )tzh_timecnt; i++) {
107+ uint8_t buf[4 ];
108+ bytes = read (fd, buf, 4 );
109+ if (bytes != 4 ) {
110+ continue ;
111+ }
112+
113+ int32_t transition = (buf[0 ] << 24 ) | (buf[1 ] << 16 ) | (buf[2 ] << 8 ) | buf[3 ];
114+ transition = ((transition & 0xFF000000 ) >> 24 ) |
115+ ((transition & 0x00FF0000 ) >> 8 ) |
116+ ((transition & 0x0000FF00 ) << 8 ) |
117+ ((transition & 0x000000FF ) << 24 );
118+ printf (" transition %d: %d\n " , i, transition);
119+ }
120+
121+ close (fd);
122+
20123 return 0 ;
21124}
22125
0 commit comments