#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
