1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include "dietfeatures.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <netinet/in.h>
#include <time.h>
/* #include <stdio.h> */
char* tzname[2]={"GMT","GMT"};
#ifdef WANT_TZFILE_PARSER
static char *tzfile=0;
static int tzlen=-1;
void __maplocaltime(void);
void __maplocaltime(void) {
int fd;
unsigned int len;
if (tzlen>=0) return;
tzlen=0;
if ((fd=open("/etc/localtime",O_RDONLY))<0) return;
len=lseek(fd,0,SEEK_END);
if ((tzfile=mmap(0,len,PROT_READ,MAP_PRIVATE,fd,0))==MAP_FAILED) return;
close(fd);
if (ntohl(*(int*)tzfile) != 0x545a6966) return;
tzlen=len;
}
static unsigned long __myntohl(const unsigned char* c) {
return (((unsigned long)c[0])<<24) +
(((unsigned long)c[1])<<16) +
(((unsigned long)c[2])<<8) +
((unsigned long)c[3]);
}
time_t __tzfile_map(time_t t, int *isdst);
time_t __tzfile_map(time_t t, int *isdst) {
/* "TZif" plus 16 reserved bytes. */
char *tmp;
int i;
int tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt, tzh_timecnt, tzh_typecnt, tzh_charcnt;
*isdst=0;
if (!tzfile) return t;
tzh_ttisgmtcnt=ntohl(*(int*)(tzfile+20));
tzh_ttisstdcnt=ntohl(*(int*)(tzfile+24));
tzh_leapcnt=ntohl(*(int*)(tzfile+28));
tzh_timecnt=ntohl(*(int*)(tzfile+32));
tzh_typecnt=ntohl(*(int*)(tzfile+36));
tzh_charcnt=ntohl(*(int*)(tzfile+40));
#if 0
tmp=tzfile+20+6*4;
printf("ttisgmtcnt %d ttisstdcnt %d leapcnt %d timecnt %d typecnt %d charcnt %d\n",tzh_ttisgmtcnt,tzh_ttisstdcnt, tzh_leapcnt, tzh_timecnt, tzh_typecnt, tzh_charcnt);
printf("transition times: ");
for (i=0; i<tzh_timecnt; ++i) {
printf("%s%lu",i?", ":"",ntohl(*(int*)tmp)); tmp+=4;
}
printf("\n");
printf("indices: ");
for (i=0; i<tzh_timecnt; ++i) {
printf("%s%d",i?", ":"",*tmp); ++tmp;
}
printf("\n");
printf("transition times: ");
for (i=0; i<tzh_typecnt; ++i) {
printf("%s(%lu,%d,%d)",i?", ":"",ntohl(*(int*)tmp),tmp[4],tmp[5]); tmp+=6;
}
printf("\n");
for (i=0; i<tzh_charcnt; ++i) {
printf("%s\"%s\"",i?", ":"",tmp);
tmp+=strlen(tmp);
}
printf("\n");
#endif
tmp=tzfile+20+6*4;
daylight=(tzh_timecnt>0);
for (i=0; i<tzh_timecnt; ++i) {
if ((time_t)__myntohl(tmp+i*4) >= t) {
char* tz=tmp;
/* printf("match at %d\n",i); */
tmp+=tzh_timecnt*4;
i=tmp[i-1];
/* printf("using index %d\n",i); */
tmp+=tzh_timecnt;
tz+=tzh_timecnt*5+tzh_leapcnt*4+tzh_typecnt*6;
tmp+=i*6;
/* printf("(%lu,%d,%d)\n",ntohl(*(int*)tmp),tmp[4],tmp[5]); */
*isdst=tmp[4];
tzname[0]=tz+tmp[5];
timezone=-(__myntohl(tmp));
return t-timezone;
}
}
return t;
}
void tzset(void) {
int isdst;
__maplocaltime();
__tzfile_map(time(0),&isdst);
}
#else
void tzset(void) __attribute__((weak,alias("__nop")));
#endif
|