diff --git a/libc/tools/zoneinfo/generate b/libc/tools/zoneinfo/generate index 3e21d0b9f..2059abd15 100755 --- a/libc/tools/zoneinfo/generate +++ b/libc/tools/zoneinfo/generate @@ -1,82 +1,131 @@ -#!/bin/bash +#!/usr/bin/python # Run with no arguments from any directory, with no special setup required. -# Abort if any command returns an error exit status, or if an undefined -# variable is used. -set -e -set -u +import ftplib +import hashlib +import os +import re +import shutil +import string +import subprocess +import sys +import tarfile +import tempfile -echo "Looking for bionic..." -bionic_dir=$(cd $(dirname $0)/../../.. && pwd) -bionic_zoneinfo_dir=$bionic_dir/libc/zoneinfo -bionic_zoneinfo_tools_dir=$bionic_dir/libc/tools/zoneinfo -if [[ ! -d "$bionic_zoneinfo_dir" || ! -d "$bionic_zoneinfo_tools_dir" ]]; then - echo "Can't find bionic's zoneinfo directories!" - exit 1 -fi +# 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', 'factory', '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() -echo "Switching to temporary directory..." -temp_dir=`mktemp -d` -cd $temp_dir -trap "rm -rf $temp_dir; exit" INT TERM EXIT # URL from "Sources for Time Zone and Daylight Saving Time Data" # http://www.twinsun.com/tz/tz-link.htm -echo "Looking for new tzdata..." -wget -N --no-verbose 'ftp://munnari.oz.au/pub/tzdata*.tar.gz' -zoneinfo_version_file=$bionic_zoneinfo_dir/zoneinfo.version -if [ -f "$zoneinfo_version_file" ]; then - current_version=tzdata`sed s/\n// < $zoneinfo_version_file` -else - current_version=missing -fi -latest_archive=`ls -r -v tzdata*.tar.gz | head -n1` -latest_version=`basename $latest_archive .tar.gz` -if [ "$current_version" == "$latest_version" ]; then - echo "You already have the latest tzdata ($latest_version)!" - exit 1 -fi -md5_sum=`md5sum $latest_archive` -echo "MD5: $md5_sum" +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() -echo "Extracting $latest_version..." -mkdir $latest_version -tar -C $latest_version -zxf $latest_archive +# 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) -echo "Compiling $latest_version..." -mkdir data -for i in \ - africa \ - antarctica \ - asia \ - australasia \ - etcetera \ - europe \ - factory \ - northamerica \ - solar87 \ - solar88 \ - solar89 \ - southamerica -do - zic -d data $latest_version/$i -done - -echo "Compacting $latest_version..." -( - cat $latest_version/* | grep '^Link' | awk '{print $1, $2, $3}' - ( - cat $latest_version/* | grep '^Zone' | awk '{print $2}' - cat $latest_version/* | grep '^Link' | awk '{print $3}' - ) | LC_ALL="C" sort -) | grep -v Riyadh8 > setup - -javac -d . \ - $bionic_zoneinfo_tools_dir/ZoneCompactor.java \ - $bionic_zoneinfo_tools_dir/ZoneInfo.java -java ZoneCompactor setup data - -echo "Updating bionic to $latest_version..." -mv zoneinfo.dat zoneinfo.idx $bionic_zoneinfo_dir -echo $latest_version | sed 's/tzdata//' > $bionic_zoneinfo_dir/zoneinfo.version +print 'You already have the latest tzdata (%s)!' % current_version +sys.exit(0) diff --git a/libc/zoneinfo/zoneinfo.dat b/libc/zoneinfo/zoneinfo.dat index cc1cb389d..779925595 100644 Binary files a/libc/zoneinfo/zoneinfo.dat and b/libc/zoneinfo/zoneinfo.dat differ diff --git a/libc/zoneinfo/zoneinfo.idx b/libc/zoneinfo/zoneinfo.idx index 0483c285f..507ae7a38 100644 Binary files a/libc/zoneinfo/zoneinfo.idx and b/libc/zoneinfo/zoneinfo.idx differ diff --git a/libc/zoneinfo/zoneinfo.version b/libc/zoneinfo/zoneinfo.version index 9412b94ca..e60676198 100644 --- a/libc/zoneinfo/zoneinfo.version +++ b/libc/zoneinfo/zoneinfo.version @@ -1 +1 @@ -2012c +2012d