#!/usr/bin/python # Run with no arguments from any directory, with no special setup required. import ftplib import hashlib import os import re import shutil import string import subprocess import sys import tarfile import tempfile # Find the bionic directory, searching upward from this script. bionic_libc_tools_zoneinfo_dir = os.path.realpath(os.path.dirname(sys.argv[0])) bionic_libc_tools_dir = os.path.dirname(bionic_libc_tools_zoneinfo_dir) bionic_libc_dir = os.path.dirname(bionic_libc_tools_dir) bionic_dir = os.path.dirname(bionic_libc_dir) bionic_libc_zoneinfo_dir = '%s/libc/zoneinfo' % bionic_dir if not os.path.isdir(bionic_libc_tools_zoneinfo_dir) or not os.path.isdir(bionic_libc_zoneinfo_dir): print "Couldn't find bionic/libc/tools/zoneinfo!" sys.exit(1) print 'Found bionic in %s...' % bionic_dir regions = ['africa', 'antarctica', 'asia', 'australasia', 'backward', 'etcetera', 'europe', 'northamerica', 'southamerica'] def current_tzdata_version(): return open('%s/zoneinfo.version' % bionic_libc_zoneinfo_dir).readline().rstrip('\n') def md5_file(filename): md5 = hashlib.md5() f = open(filename, 'rb') while True: data = f.read(8192) if not data: break md5.update(data) return md5.hexdigest() def upgrade_to(ftp, filename): version = re.search('tzdata(.+)\.tar\.gz', filename).group(1) # Switch to a temporary directory. tmp_dir = tempfile.mkdtemp('-tzdata') os.chdir(tmp_dir) print 'Created temporary directory "%s"...' % tmp_dir print 'Downloading %s...' % filename ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write) print 'MD5: %s' % md5_file(filename) print 'Extracting...' os.mkdir('extracted') tar = tarfile.open(filename, 'r') tar.extractall('extracted') print 'Calling zic(1)...' os.mkdir('data') for region in regions: if region != 'backward': subprocess.check_call(['zic', '-d', 'data', 'extracted/%s' % region]) # Collect the data ZoneCompactor needs. links = [] zones = [] for region in regions: for line in open('extracted/%s' % region).readlines(): fields = string.split(line) if len(fields) == 0: continue elif fields[0] == 'Link': links.append('%s %s %s\n' % (fields[0], fields[1], fields[2])) zones.append(fields[2]) elif fields[0] == 'Zone': zones.append(fields[1]) zones.sort() # Write it into the "setup" file. setup = open('setup', 'w') for link in links: setup.write(link) for zone in zones: setup.write('%s\n' % zone) setup.close() print 'Calling ZoneCompactor...' subprocess.check_call(['javac', '-d', '.', '%s/ZoneCompactor.java' % bionic_libc_tools_zoneinfo_dir, '%s/ZoneInfo.java' % bionic_libc_tools_zoneinfo_dir]) subprocess.check_call(['java', 'ZoneCompactor', 'setup', 'data']) print 'Updating bionic from %s to %s...' % (current_tzdata_version(), version) # Move the .dat and .idx files... os.remove('%s/zoneinfo.dat' % bionic_libc_zoneinfo_dir) shutil.move('zoneinfo.dat', bionic_libc_zoneinfo_dir) os.remove('%s/zoneinfo.idx' % bionic_libc_zoneinfo_dir) shutil.move('zoneinfo.idx', bionic_libc_zoneinfo_dir) # Write the .version file... zoneinfo_version = open('%s/zoneinfo.version' % bionic_libc_zoneinfo_dir, 'wb+') zoneinfo_version.write('%s\n' % version) zoneinfo_version.close() # URL from "Sources for Time Zone and Daylight Saving Time Data" # http://www.twinsun.com/tz/tz-link.htm print 'Looking for new tzdata...' ftp = ftplib.FTP('ftp.iana.org') ftp.login() ftp.cwd('tz/releases') tzdata_filenames = [] for filename in ftp.nlst(): if filename.startswith('tzdata20'): tzdata_filenames.append(filename) tzdata_filenames.sort() # If you're several releases behind, we'll walk you through the upgrades one by one. current_version = current_tzdata_version() current_filename = 'tzdata%s.tar.gz' % current_version for filename in tzdata_filenames: if filename > current_filename: upgrade_to(ftp, filename) sys.exit(0) print 'You already have the latest tzdata (%s)!' % current_version sys.exit(0)