diff --git a/libc/tools/zoneinfo/ZoneCompactor.java b/libc/tools/zoneinfo/ZoneCompactor.java
new file mode 100644
index 0000000..b657748
--- /dev/null
+++ b/libc/tools/zoneinfo/ZoneCompactor.java
@@ -0,0 +1,166 @@
+
+import java.io.*;
+import java.util.*;
+
+// usage: java ZoneCompiler <setup file> <top-level directory>
+//
+// Compile a set of tzfile-formatted files into a single file plus
+// an index file.
+//
+// The compilation is controlled by a setup file, which is provided as a
+// command-line argument.  The setup file has the form:
+//
+// Link <toName> <fromName>
+// ...
+// <zone filename>
+// ...
+//
+// Note that the links must be declared prior to the zone names.  A
+// zone name is a filename relative to the source directory such as
+// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
+//
+// Use the 'zic' command-line tool to convert from flat files
+// (e.g., 'africa', 'northamerica') into a suitable source directory
+// hierarchy for this tool (e.g., 'data/Africa/Abidjan').
+//
+// Example:
+//     zic -d data tz2007h
+//     javac ZoneCompactor.java
+//     java ZoneCompactor setup data
+//     <produces zoneinfo.dat and zoneinfo.idx>
+
+public class ZoneCompactor {
+
+    // Zone name synonyms
+    Map<String,String> links = new HashMap<String,String>();
+
+    // File starting bytes by zone name
+    Map<String,Integer> starts = new HashMap<String,Integer>();
+
+    // File lengths by zone name
+    Map<String,Integer> lengths = new HashMap<String,Integer>();
+
+    // Raw GMT offsets by zone name
+    Map<String,Integer> offsets = new HashMap<String,Integer>();
+    int start = 0;
+
+    // Maximum number of characters in a zone name, including '\0' terminator
+    private static final int MAXNAME = 40;
+
+    // Concatenate the contents of 'inFile' onto 'out'
+    // and return the contents as a byte array.
+    private static byte[] copyFile(File inFile, OutputStream out)
+        throws Exception {
+        byte[] ret = new byte[0];
+
+        InputStream in = new FileInputStream(inFile);
+        byte[] buf = new byte[8192];
+        while (true) {
+            int nbytes = in.read(buf);
+            if (nbytes == -1) {
+                break;
+            }
+            out.write(buf, 0, nbytes);
+
+            byte[] nret = new byte[ret.length + nbytes];
+            System.arraycopy(ret, 0, nret, 0, ret.length);
+            System.arraycopy(buf, 0, nret, ret.length, nbytes);
+            ret = nret;
+        }
+        out.flush();
+        return ret;
+    }
+    
+    // Write a 32-bit integer in network byte order
+    private void writeInt(OutputStream os, int x) throws IOException {
+        os.write((x >> 24) & 0xff);
+        os.write((x >> 16) & 0xff);
+        os.write((x >>  8) & 0xff);
+        os.write( x        & 0xff);
+    }
+
+    public ZoneCompactor(String setupFilename, String dirName)
+        throws Exception {
+        File zoneInfoFile = new File("zoneinfo.dat");
+        zoneInfoFile.delete();
+        OutputStream zoneInfo = new FileOutputStream(zoneInfoFile);
+
+        BufferedReader rdr = new BufferedReader(new FileReader(setupFilename));
+    
+        String s;
+        while ((s = rdr.readLine()) != null) {
+            s = s.trim();
+            if (s.startsWith("Link")) {
+                StringTokenizer st = new StringTokenizer(s);
+                st.nextToken();
+                String to = st.nextToken();
+                String from = st.nextToken();
+                links.put(from, to);
+            } else {
+                String link = links.get(s);
+                if (link == null) {
+                    File f = new File(dirName, s);
+                    long length = f.length();
+                    starts.put(s, new Integer(start));
+                    lengths.put(s, new Integer((int)length));
+
+                    start += length;
+                    byte[] data = copyFile(f, zoneInfo);
+
+                    TimeZone tz = ZoneInfo.make(s, data);
+                    int gmtOffset = tz.getRawOffset();
+                    offsets.put(s, new Integer(gmtOffset));
+                }
+            }
+        }
+        zoneInfo.close();
+
+        // Fill in fields for links
+        Iterator<String> iter = links.keySet().iterator();
+        while (iter.hasNext()) {
+            String from = iter.next();
+            String to = links.get(from);
+
+            starts.put(from, starts.get(to));
+            lengths.put(from, lengths.get(to));
+            offsets.put(from, offsets.get(to));
+        }
+
+        File idxFile = new File("zoneinfo.idx");
+        idxFile.delete();
+        FileOutputStream idx = new FileOutputStream(idxFile);
+
+        ArrayList<String> l = new ArrayList<String>();
+        l.addAll(starts.keySet());
+        Collections.sort(l);
+        Iterator<String> ziter = l.iterator();
+        while (ziter.hasNext()) {
+            String zname = ziter.next();
+            if (zname.length() >= MAXNAME) {
+                System.err.println("Error - zone filename exceeds " +
+                                   (MAXNAME - 1) + " characters!");
+            }
+
+            byte[] znameBuf = new byte[MAXNAME];
+            for (int i = 0; i < zname.length(); i++) {
+                znameBuf[i] = (byte)zname.charAt(i);
+            }
+            idx.write(znameBuf);
+            writeInt(idx, starts.get(zname).intValue());
+            writeInt(idx, lengths.get(zname).intValue());
+            writeInt(idx, offsets.get(zname).intValue());
+        }
+        idx.close();
+
+        // System.out.println("maxLength = " + maxLength);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length != 2) {
+            System.err.println("usage: java ZoneCompactor <setup> <data dir>");
+            System.exit(0);
+        }
+        new ZoneCompactor(args[0], args[1]);
+    }
+
+}
