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
|
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
// #define TZ_MMAP
static unsigned char *T;
static int L=-1;
static time_t left, right, tz;
static time_t parse(unsigned char *x)
{return (x[0]<<24) | (x[1]<<16) | (x[2]<<8) | x[3];}
static time_t parse_localtime(time_t t) {
unsigned char *tmp,*x,tzh_typecnt;
int i,tzh_timecnt;
if (!T || L<44 || parse(T) != 1415211366) goto ready;
tzh_timecnt = parse(T+32) & 0xfff;
tzh_typecnt = parse(T+36);
i = 44 + 4*tzh_timecnt;
if (i + tzh_timecnt + 6*tzh_typecnt > L) goto ready;
x =T +i;
tmp =x;
for (i=tzh_timecnt; 0<i;) {
i--;
tmp -= 4;
left =parse(tmp);
if (t < left) {
right = left;
continue;
}
if (x[i] >= tzh_typecnt) goto ready;
tz = parse(x +tzh_timecnt +6*x[i]);
return tz;
}
ready:
right=left;
return 0;
}
#ifndef TZ_MMAP
#include <alloca.h>
#include <sys/stat.h>
#include "scan_defs.h"
#include "opts__defs.h"
time_t get_tz(time_t t) /*EXTRACT_INCL*/{
struct stat st;
int fd;
char *tzfile = Oo[Otz];
if (*tzfile != '/') return x_atoi(tzfile);
if (left <= t && t < right) return tz;
fd=open(tzfile,O_RDONLY);
if (fd>=0) {
if (fstat(fd, &st)) goto error;
L = st.st_size;
T = alloca(L);
if (!T) goto error;
if (const_io((int(*)())read,fd,T,L))
{ error: close(fd); return 0; }
close(fd);
}
return parse_localtime(t);
}
#else
#include <sys/mman.h>
time_t get_tz(time_t t) {
int fd;
if (left <= t && t < right) return tz;
if (!T) {
char *map;
if ((fd=open("/etc/localtime",O_RDONLY))>=0) {
L=lseek(fd,0,SEEK_END);
map=mmap(0,L,PROT_READ,MAP_SHARED,fd,0);
if (map==(char*)-1) map=0;
close(fd);
T=(unsigned char *)map;
}
}
return parse_localtime(t);
}
#endif
|