#include "dietfeatures.h" #include #include #include #include #include #include /* This code appears to be subtly wrong depending on the date. * However, the documentation I found about the tzfile layout are not * sufficient to debug this. */ char* tzname[2]={"GMT","GMT"}; #ifdef WANT_TZFILE_PARSER static unsigned char *tzfile; 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) { close(fd); return; } close(fd); if (len<44 || ntohl(*(int*)tzfile) != 0x545a6966) { munmap(tzfile,len); tzfile=0; return; } tzlen=len; } static int32_t __myntohl(const unsigned char* c) { return (((uint32_t)c[0])<<24) + (((uint32_t)c[1])<<16) + (((uint32_t)c[2])<<8) + ((uint32_t)c[3]); } time_t __tzfile_map(time_t t, int *isdst, int forward); time_t __tzfile_map(time_t t, int *isdst, int forward) { /* "TZif" plus 16 reserved bytes. */ unsigned 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; i0); if (forward) { for (i=0; i= t) { unsigned 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_typecnt*6; tmp+=i*6; /* printf("(%lu,%d,%d)\n",ntohl(*(int*)tmp),tmp[4],tmp[5]); */ *isdst=tmp[4]; tzname[0]=(char*)(tz+tmp[5]); timezone=__myntohl(tmp); return t+timezone; } } } else { /* reverse map, for mktime */ time_t nexttz=0,lastval=0; // printf("tzh_timecnt: %d\n",tzh_timecnt); for (i=1; i t) { // printf("FOUND!1!! Offset %d\n",nexttz); return t-nexttz; } lastval=k; } } return t; } void tzset(void) { int isdst; __maplocaltime(); __tzfile_map(time(0),&isdst,1); } #else void tzset(void) { } #endif