1#!/usr/bin/python
2# Run with no arguments from any directory, with no special setup required.
3
4import ftplib
5import hashlib
6import os
7import re
8import shutil
9import string
10import subprocess
11import sys
12import tarfile
13import tempfile
14
15# Find the bionic directory, searching upward from this script.
16bionic_libc_tools_zoneinfo_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
17bionic_libc_tools_dir = os.path.dirname(bionic_libc_tools_zoneinfo_dir)
18bionic_libc_dir = os.path.dirname(bionic_libc_tools_dir)
19bionic_dir = os.path.dirname(bionic_libc_dir)
20bionic_libc_zoneinfo_dir = '%s/libc/zoneinfo' % bionic_dir
21if not os.path.isdir(bionic_libc_tools_zoneinfo_dir) or not os.path.isdir(bionic_libc_zoneinfo_dir):
22  print "Couldn't find bionic/libc/tools/zoneinfo!"
23  sys.exit(1)
24print 'Found bionic in %s...' % bionic_dir
25
26
27regions = ['africa', 'antarctica', 'asia', 'australasia', 'backward', 'etcetera', 'europe', 'northamerica', 'southamerica']
28
29
30def current_tzdata_version():
31  return open('%s/zoneinfo.version' % bionic_libc_zoneinfo_dir).readline().rstrip('\n')
32
33
34def md5_file(filename):
35  md5 = hashlib.md5()
36  f = open(filename, 'rb')
37  while True:
38    data = f.read(8192)
39    if not data:
40      break
41    md5.update(data)
42  return md5.hexdigest()
43
44
45def upgrade_to(ftp, filename):
46  version = re.search('tzdata(.+)\.tar\.gz', filename).group(1)
47
48  # Switch to a temporary directory.
49  tmp_dir = tempfile.mkdtemp('-tzdata')
50  os.chdir(tmp_dir)
51  print 'Created temporary directory "%s"...' % tmp_dir
52
53  print 'Downloading %s...' % filename
54  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
55  print 'MD5: %s' % md5_file(filename)
56
57  print 'Extracting...'
58  os.mkdir('extracted')
59  tar = tarfile.open(filename, 'r')
60  tar.extractall('extracted')
61
62  print 'Calling zic(1)...'
63  os.mkdir('data')
64  for region in regions:
65    if region != 'backward':
66      subprocess.check_call(['zic', '-d', 'data', 'extracted/%s' % region])
67
68  # Collect the data ZoneCompactor needs.
69  links = []
70  zones = []
71  for region in regions:
72    for line in open('extracted/%s' % region).readlines():
73      fields = string.split(line)
74      if len(fields) == 0:
75        continue
76      elif fields[0] == 'Link':
77        links.append('%s %s %s\n' % (fields[0], fields[1], fields[2]))
78        zones.append(fields[2])
79      elif fields[0] == 'Zone':
80        zones.append(fields[1])
81  zones.sort()
82
83  # Write it into the "setup" file.
84  setup = open('setup', 'w')
85  for link in links:
86    setup.write(link)
87  for zone in zones:
88    setup.write('%s\n' % zone)
89  setup.close()
90
91  print 'Calling ZoneCompactor...'
92  subprocess.check_call(['javac', '-d', '.',
93                         '%s/ZoneCompactor.java' % bionic_libc_tools_zoneinfo_dir,
94                         '%s/ZoneInfo.java' % bionic_libc_tools_zoneinfo_dir])
95  subprocess.check_call(['java', 'ZoneCompactor', 'setup', 'data'])
96
97  print 'Updating bionic from %s to %s...' % (current_tzdata_version(), version)
98  # Move the .dat and .idx files...
99  os.remove('%s/zoneinfo.dat' % bionic_libc_zoneinfo_dir)
100  shutil.move('zoneinfo.dat', bionic_libc_zoneinfo_dir)
101  os.remove('%s/zoneinfo.idx' % bionic_libc_zoneinfo_dir)
102  shutil.move('zoneinfo.idx', bionic_libc_zoneinfo_dir)
103  # Write the .version file...
104  zoneinfo_version = open('%s/zoneinfo.version' % bionic_libc_zoneinfo_dir, 'wb+')
105  zoneinfo_version.write('%s\n' % version)
106  zoneinfo_version.close()
107
108
109# URL from "Sources for Time Zone and Daylight Saving Time Data"
110# http://www.twinsun.com/tz/tz-link.htm
111
112print 'Looking for new tzdata...'
113ftp = ftplib.FTP('ftp.iana.org')
114ftp.login()
115ftp.cwd('tz/releases')
116tzdata_filenames = []
117for filename in ftp.nlst():
118  if filename.startswith('tzdata20'):
119    tzdata_filenames.append(filename)
120tzdata_filenames.sort()
121
122# If you're several releases behind, we'll walk you through the upgrades one by one.
123current_version = current_tzdata_version()
124current_filename = 'tzdata%s.tar.gz' % current_version
125for filename in tzdata_filenames:
126  if filename > current_filename:
127    upgrade_to(ftp, filename)
128    sys.exit(0)
129
130print 'You already have the latest tzdata (%s)!' % current_version
131sys.exit(0)
132